aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarsSommer <[email protected]>2013-12-17 11:04:55 +0100
committerLarsSommer <[email protected]>2013-12-17 11:04:55 +0100
commita0ac49c69bea92df5d8054cc07e1f57817c0fa4f (patch)
tree5e75850baad21dc6c04a4593fc3da34fd920ecb2
parentf89c0a958b01ae732ac16c1dfdae15a9715f735a (diff)
Added Regex for exclusion and inclusion of classes
-rwxr-xr-xapi/src/main/java/org/semver/jardiff/DifferenceAccumulatingHandler.java93
-rw-r--r--api/src/test/java/org/semver/jardiff/DifferenceAccumulatingHandlerTest.java299
2 files changed, 375 insertions, 17 deletions
diff --git a/api/src/main/java/org/semver/jardiff/DifferenceAccumulatingHandler.java b/api/src/main/java/org/semver/jardiff/DifferenceAccumulatingHandler.java
index 4cf6cc3..e78c5ea 100755
--- a/api/src/main/java/org/semver/jardiff/DifferenceAccumulatingHandler.java
+++ b/api/src/main/java/org/semver/jardiff/DifferenceAccumulatingHandler.java
@@ -20,6 +20,8 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.osjava.jardiff.AbstractDiffHandler;
import org.osjava.jardiff.ClassInfo;
@@ -209,23 +211,80 @@ public final class DifferenceAccumulatingHandler extends AbstractDiffHandler {
*
* @return
*/
- private boolean isClassConsidered(final String className) {
- for (final String exclude : this.excludes) {
- if (className.startsWith(exclude)) {
- return false;
- }
- }
-
- if (!this.includes.isEmpty()) {
- for (final String include : this.includes) {
- if (className.startsWith(include)) {
- return true;
- }
- }
- return false;
- }
- return true;
- }
+ protected boolean isClassConsidered( final String className ) {
+ for ( String exclude : this.excludes ) {
+ if ( exclude.contains( "/**/" ) ) {
+ exclude = exclude.replaceAll( "/\\*\\*/", "{0,1}**/" );
+ }
+ if ( exclude.contains( "/*/" ) ) {
+ exclude = exclude.replaceAll( "/\\*/", "{0,1}*/{0,1}" );
+ }
+ Pattern excludePattern = simplifyRegularExpression( exclude, false );
+
+ Matcher excludeMatcher = excludePattern.matcher( className );
+
+ while ( excludeMatcher.find() ) {
+ return false;
+ }
+ }
+ if ( !this.includes.isEmpty() ) {
+ for ( String include : this.includes ) {
+ if ( include.contains( "/**/" ) ) {
+ include = include.replaceAll( "/\\*\\*/", "{0,1}**/" );
+ }
+ if ( include.contains( "/*/" ) ) {
+ include = include.replaceAll( "/\\*/", "{0,1}*/{0,1}" );
+ }
+ Pattern includePattern = simplifyRegularExpression( include, false );
+ Matcher includeMatcher = includePattern.matcher( className );
+
+ while ( includeMatcher.find() ) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ *
+ * Simplifies the given regular expression by the following pattern:<br>
+ * All substrings not containing "{0,1}", "*" and "?" get surrounded by "\\Q" and "\\E". Then all occurrences of
+ * "**" are replaced by ".*", "*" with "[^/]*" and all occurrences of "?" are replaced by "." In the end a "$" will
+ * be appended.
+ *
+ * @param regEx the regular expression which is in a simple form.
+ * @return the simple regular expression converted to a normal regular expression.
+ */
+ private static Pattern simplifyRegularExpression( final String regEx, final boolean caseSensitive ) {
+ final StringBuilder strBuild = new StringBuilder();
+ final Pattern p = Pattern.compile( "\\{0,1\\}|\\*|\\?|[[^*^?^{^}]|^]+", Pattern.CASE_INSENSITIVE );
+ final Matcher m = p.matcher( regEx );
+
+ while ( m.find() ) {
+ final String token = m.group();
+ if ( token.equals( "*" ) || token.equals( "?" ) ) { //$NON-NLS-1$ //$NON-NLS-2$
+ strBuild.append( token );
+ } else if ( token.equals( "{0,1}" ) ) {
+ strBuild.append( "/" );
+ strBuild.append( token );
+ } else {
+ // Surround all tokens that are not "*" or "?" with "\\Q" and \\E"
+ strBuild.append( "\\Q" ).append( token ).append( "\\E" ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ // Replace all "*" and "?" with .* and .+
+ strBuild.append( "$" );
+ String result = strBuild.toString();
+ result = result.replaceAll( "(?<!\\*)\\*(?!\\*)", "[^/]*" );
+ result = result.replaceAll( "[\\*][\\s]*[\\*]", ".\\*" );
+ result = result.replaceAll( "\\?", "." );
+ if ( caseSensitive ) {
+ return Pattern.compile( result );
+ } else {
+ return Pattern.compile( result, Pattern.CASE_INSENSITIVE );
+ }
+ }
public Delta getDelta() {
return new Delta(this.differences);
diff --git a/api/src/test/java/org/semver/jardiff/DifferenceAccumulatingHandlerTest.java b/api/src/test/java/org/semver/jardiff/DifferenceAccumulatingHandlerTest.java
new file mode 100644
index 0000000..47b1247
--- /dev/null
+++ b/api/src/test/java/org/semver/jardiff/DifferenceAccumulatingHandlerTest.java
@@ -0,0 +1,299 @@
+/**
+ * Copyright 2012 Julien Eluard This project includes software developed by Julien Eluard: https://github.com/jeluard/
+ *
+ * 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 org.semver.jardiff;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class DifferenceAccumulatingHandlerTest {
+
+ @Test
+ public void shouldClassBeNotConsideredWithTwoPlaceholdersBeforeAndBehind() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "**/java/**" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithOnePlaceholderBeforeAndBehind() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "*/java/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeNotConsideredWithTwoPlaceholderAfter() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/**" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithTwoPlaceholderBefore() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "**/java" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithOnePlaceholderAfter() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithOnePlaceholderBefore() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "*/java" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeNotConsideredWithTwoPlaceholderInside() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "de/**/java/**" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeNotConsideredWithOnePlaceholderInside() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "de/*/java/**" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithOnePlaceholderInside() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "de/*/classImpl" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithTwoPlaceholderInsideAndSpecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/**/Impl" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithOnePlaceholderInsideAndSpecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/*/*Impl" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithOnePlaceholderInsideAndSpecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "test/*/*Impl" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithTwoPlaceholderInsidePlusHashAndUnspecificEnd3() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "test/*/*Impl/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/Impl2/code" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithTwoPlaceholderInsidePlusHashAndUnspecificEnd2() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/*/*Impl/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl/code" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithTwoPlaceholderInsidePlusHashAndUnspecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "test/*/*Impl/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl/code/Implem" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithTwoPlaceholderInsidePlusHashAndUnspecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/*/*Impl/*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl/code" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithOnePlaceholderInsideAndUnspecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/*/*Impl*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/classImpl2" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithTwoPlaceholderInsideAndUnspecificEnd() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "java/**/Impl*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/Impl" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithTwoPlaceholderInsideAndUnspecificEndWithNoUseOfPlaceholders() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "regex/**/Impl*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/Impl" ) );
+ }
+
+ @Test
+ public void shouldClassBeConsideredWithTwoPlaceholderInsideAndUnspecificEndWithNoUseOfPlaceholders() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "regex/**/Impl*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should be considered: ", true, new DifferenceAccumulatingHandler( inclusionSet,
+ exclusionSet ).isClassConsidered( "de/test/java/regex/test" ) );
+ }
+
+ @Test
+ public void shouldClassNotBeConsideredWithTwoPlaceholderInsideAndUnspecificEndWith() {
+
+ List<String> inclusions = new ArrayList<String>();
+ Set<String> inclusionSet = new HashSet<String>( inclusions );
+ List<String> exclusions = new ArrayList<String>();
+ exclusions.add( "test/**/Impl*" );
+ Set<String> exclusionSet = new HashSet<String>( exclusions );
+
+ Assert.assertEquals( "Class should not be considered: ", false, new DifferenceAccumulatingHandler(
+ inclusionSet, exclusionSet ).isClassConsidered( "de/test/java/regex/Impl" ) );
+ }
+}