From f9a3bdab2a45a0d87277dd65b6e1d28b409313a4 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 18 Jun 2015 17:21:24 +1000 Subject: [PATCH] 469384 ClasspathPattern handles nested classes Bug: 469384 Treat classnames with $ in them as exact match or exact prefix --- .../jetty/webapp/ClasspathPattern.java | 55 +++------ .../jetty/webapp/ClasspathPatternTest.java | 109 ++++++++++++++++++ 2 files changed, 127 insertions(+), 37 deletions(-) create mode 100644 jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClasspathPatternTest.java diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java index 0604bd4d115..936556b8a23 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java @@ -25,6 +25,8 @@ import java.util.Arrays; import java.util.List; import java.util.ListIterator; +import org.eclipse.jetty.util.StringUtil; + /* ------------------------------------------------------------ */ /** * Classpath classes list performs sequential pattern matching of a class name @@ -216,48 +218,27 @@ public class ClasspathPattern extends AbstractList */ public boolean match(String name) { - boolean result=false; + name = name.replace('/','.'); - if (_entries != null) + for (Entry entry : _entries) { - name = name.replace('/','.'); - - int startIndex = 0; - - while(startIndex < name.length() && name.charAt(startIndex) == '.') { - startIndex++; - } - - int dollar = name.indexOf("$"); - - int endIndex = dollar != -1 ? dollar : name.length(); - - for (Entry entry : _entries) + if (entry==null) + continue; + if (entry._package) { - if (entry != null) - { - if (entry._package) - { - if (name.regionMatches(startIndex, entry._name, 0, entry._name.length())) - { - result = entry._inclusive; - break; - } - } - else - { - int regionLength = endIndex-startIndex; - if (regionLength == entry._name.length() - && name.regionMatches(startIndex, entry._name, 0, regionLength)) - { - result = entry._inclusive; - break; - } - } - } + if (name.startsWith(entry._name)) + return entry._inclusive; + } + else + { + if (name.equals(entry._name)) + return entry._inclusive; + + if (name.length()>entry._name.length() && '$'==name.charAt(entry._name.length()) && name.startsWith(entry._name)) + return entry._inclusive; } } - return result; + return false; } public void addAfter(String afterPattern,String... patterns) diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClasspathPatternTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClasspathPatternTest.java new file mode 100644 index 00000000000..1b41bc9b34e --- /dev/null +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClasspathPatternTest.java @@ -0,0 +1,109 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.webapp; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +public class ClasspathPatternTest +{ + private final ClasspathPattern pattern = new ClasspathPattern(); + + @Before + public void before() + { + pattern.clear(); + pattern.add("org.package."); + pattern.add("-org.excluded."); + pattern.add("org.example.FooBar"); + pattern.add("-org.example.Excluded"); + pattern.addAll(Arrays.asList(new String[]{"-org.example.Nested$Minus","org.example.Nested","org.example.Nested$Something"})); + } + + @Test + public void testClassMatch() + { + assertTrue(pattern.match("org.example.FooBar")); + assertTrue(pattern.match("org.example.Nested")); + + assertFalse(pattern.match("org.example.Unknown")); + assertFalse(pattern.match("org.example.FooBar.Unknown")); + } + + @Test + public void testPackageMatch() + { + assertTrue(pattern.match("org.package.Something")); + assertTrue(pattern.match("org.package.other.Something")); + + assertFalse(pattern.match("org.example.Unknown")); + assertFalse(pattern.match("org.example.FooBar.Unknown")); + assertFalse(pattern.match("org.example.FooBarElse")); + } + + @Test + public void testExplicitNestedMatch() + { + assertTrue(pattern.match("org.example.Nested$Something")); + + assertFalse(pattern.match("org.example.Nested$Minus")); + } + + @Test + public void testImplicitNestedMatch() + { + assertTrue(pattern.match("org.example.FooBar$Other")); + assertTrue(pattern.match("org.example.Nested$Other")); + } + + @Test + public void testAddBefore() + { + pattern.addBefore("-org.excluded.","org.excluded.ExceptionOne","org.excluded.ExceptionTwo"); + + assertTrue(pattern.match("org.excluded.ExceptionOne")); + assertTrue(pattern.match("org.excluded.ExceptionTwo")); + + assertFalse(pattern.match("org.example.Unknown")); + } + + @Test + public void testAddAfter() + { + pattern.addAfter("org.package.","org.excluded.ExceptionOne","org.excluded.ExceptionTwo"); + + assertTrue(pattern.match("org.excluded.ExceptionOne")); + assertTrue(pattern.match("org.excluded.ExceptionTwo")); + + assertFalse(pattern.match("org.example.Unknown")); + } + + @Test + public void testDoubledNested() + { + assertTrue(pattern.match("org.example.Nested$Something$Else")); + + assertFalse(pattern.match("org.example.Nested$Minus$Else")); + } +}