Skip to content

Commit

Permalink
Add StringMatcher interface
Browse files Browse the repository at this point in the history
Include two implementations regex and string.

Signed-off-by: Appu Goundan <[email protected]>
  • Loading branch information
loosebazooka committed Jun 10, 2024
1 parent c563aaf commit 21d977e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2024 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.strings;

/** Check exception wrapper around {@link java.util.regex.PatternSyntaxException}. */
public class RegexSyntaxException extends Exception {
public RegexSyntaxException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.strings;

import java.util.Objects;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
* An interface for allowing direct string matching or regular expressions. Use the static factory
* {@link #string(String)} or {@link #regex(String)} to instantiate the appropriate matcher. Custom
* implementations should override {@link Object#toString} for better error reporting.
*/
public interface StringMatcher extends Predicate<String> {

/** Create a matcher for string equality. */
static StringMatcher string(String string) {
Objects.requireNonNull(string, "string matcher cannot be initialized with null string");
return new StringMatcher() {
@Override
public boolean test(String target) {
return string.equals(target);
}

@Override
public String toString() {
return "'String: " + string + "'";
}
};
}

/**
* Create a matcher using regular expressions. Regex matching ignores null values and returns
* false instead of erroring.
*
* @param string the input pattern
* @return a regex based instance
* @throws RegexSyntaxException if the input pattern is not valid regex. This is a runtime
* exception and probably should be handled
*/
static StringMatcher regex(String string) throws RegexSyntaxException {
Objects.requireNonNull(string, "string matcher cannot be initialized with null regex");
Pattern pattern;
try {
pattern = Pattern.compile(string);
} catch (PatternSyntaxException ex) {
throw new RegexSyntaxException("Could not parse regex: '" + string + "'", ex);
}
return new StringMatcher() {
@Override
public boolean test(String target) {
if (target == null) {
return false;
}
return pattern.matcher(target).matches();
}

@Override
public String toString() {
return "'RegEx: " + pattern + "'";
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2024 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore.strings;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class StringMatcherTest {

@Test
public void testString() {
var testMatcher = StringMatcher.string("testtest");
Assertions.assertEquals("'String: testtest'", testMatcher.toString());

Assertions.assertTrue(testMatcher.test("testtest"));
Assertions.assertFalse(testMatcher.test("testtest1"));
Assertions.assertFalse(testMatcher.test(""));
Assertions.assertFalse(testMatcher.test(null));
}

@Test
public void testRegex() throws Exception {
var testMatcher = StringMatcher.regex("abc...xyz");
Assertions.assertEquals("'RegEx: abc...xyz'", testMatcher.toString());

Assertions.assertTrue(testMatcher.test("abc888xyz"));
Assertions.assertFalse(testMatcher.test("abc888xyzEXTRA"));
Assertions.assertFalse(testMatcher.test("abcxyz"));
Assertions.assertFalse(testMatcher.test(""));
Assertions.assertFalse(testMatcher.test(null));
}

@Test
public void testRegex_initFailure() {
Assertions.assertThrows(RegexSyntaxException.class, () -> StringMatcher.regex("asdf\\"));
}
}

0 comments on commit 21d977e

Please sign in to comment.