11/* 
2-  * Copyright 2002-2014  the original author or authors. 
2+  * Copyright 2002-2015  the original author or authors. 
33 * 
44 * Licensed under the Apache License, Version 2.0 (the "License"); 
55 * you may not use this file except in compliance with the License. 
2626import  java .util .regex .Pattern ;
2727
2828/** 
29-  * PathMatcher implementation for Ant-style path patterns. Examples are provided below . 
29+  * {@link  PathMatcher}  implementation for Ant-style path patterns. 
3030 * 
3131 * <p>Part of this mapping code has been kindly borrowed from <a href="http://ant.apache.org">Apache Ant</a>. 
3232 * 
33-  * <p>The mapping matches URLs using the following rules:<br> <ul> <li>? matches one character</li> <li>* matches zero 
34-  * or more characters</li> <li>** matches zero or more 'directories' in a path</li> </ul> 
33+  * <p>The mapping matches URLs using the following rules:<br> 
34+  * <ul> 
35+  * <li>{@code ?} matches one character</li> 
36+  * <li>{@code *} matches zero or more characters</li> 
37+  * <li>{@code **} matches zero or more <em>directories</em> in a path</li> 
38+  * </ul> 
3539 * 
36-  * <p>Some examples:<br> <ul> <li>{@code com/t?st.jsp} - matches {@code com/test.jsp} but also 
37-  * {@code com/tast.jsp} or {@code com/txst.jsp}</li> <li>{@code com/*.jsp} - matches all 
38-  * {@code .jsp} files in the {@code com} directory</li> <li>{@code com/**/test.jsp} - matches all 
39-  * {@code test.jsp} files underneath the {@code com} path</li> <li>{@code org/springframework/**/*.jsp} 
40-  * - matches all {@code .jsp} files underneath the {@code org/springframework} path</li> 
41-  * <li>{@code org/**/servlet/bla.jsp} - matches {@code org/springframework/servlet/bla.jsp} but also 
42-  * {@code org/springframework/testing/servlet/bla.jsp} and {@code org/servlet/bla.jsp}</li> </ul> 
40+  * <h3>Examples</h3> 
41+  * <ul> 
42+  * <li>{@code com/t?st.jsp} — matches {@code com/test.jsp} but also 
43+  * {@code com/tast.jsp} or {@code com/txst.jsp}</li> 
44+  * <li>{@code com/*.jsp} — matches all {@code .jsp} files in the 
45+  * {@code com} directory</li> 
46+  * <li><code>com/**/test.jsp</code> — matches all {@code test.jsp} 
47+  * files underneath the {@code com} path</li> 
48+  * <li><code>org/springframework/**/*.jsp</code> — matches all 
49+  * {@code .jsp} files underneath the {@code org/springframework} path</li> 
50+  * <li><code>org/**/servlet/bla.jsp</code> — matches 
51+  * {@code org/springframework/servlet/bla.jsp} but also 
52+  * {@code org/springframework/testing/servlet/bla.jsp} and {@code org/servlet/bla.jsp}</li> 
53+  * </ul> 
4354 * 
4455 * @author Alef Arendsen 
4556 * @author Juergen Hoeller 
4657 * @author Rob Harrop 
4758 * @author Arjen Poutsma 
4859 * @author Rossen Stoyanchev 
60+  * @author Sam Brannen 
4961 * @since 16.07.2003 
5062 */ 
5163public  class  AntPathMatcher  implements  PathMatcher  {
@@ -80,7 +92,7 @@ public AntPathMatcher() {
8092	}
8193
8294	/** 
83- 	 * A convenience  alternative constructor to use with a custom path separator. 
95+ 	 * A convenient,  alternative constructor to use with a custom path separator. 
8496	 * @param pathSeparator the path separator to use, must not be {@code null}. 
8597	 * @since 4.1 
8698	 */ 
@@ -93,7 +105,7 @@ public AntPathMatcher(String pathSeparator) {
93105
94106	/** 
95107	 * Set the path separator to use for pattern parsing. 
96- 	 * Default is "/", as in Ant. 
108+ 	 * <p> Default is "/", as in Ant. 
97109	 */ 
98110	public  void  setPathSeparator (String  pathSeparator ) {
99111		this .pathSeparator  = (pathSeparator  != null  ? pathSeparator  : DEFAULT_PATH_SEPARATOR );
@@ -102,7 +114,7 @@ public void setPathSeparator(String pathSeparator) {
102114
103115	/** 
104116	 * Specify whether to trim tokenized paths and patterns. 
105- 	 * Default is {@code true}. 
117+ 	 * <p> Default is {@code true}. 
106118	 */ 
107119	public  void  setTrimTokens (boolean  trimTokens ) {
108120		this .trimTokens  = trimTokens ;
@@ -116,7 +128,7 @@ public void setTrimTokens(boolean trimTokens) {
116128	 * <p>Default is for the cache to be on, but with the variant to automatically 
117129	 * turn it off when encountering too many patterns to cache at runtime 
118130	 * (the threshold is 65536), assuming that arbitrary permutations of patterns 
119- 	 * are coming in, with little chance for encountering a reoccurring  pattern. 
131+ 	 * are coming in, with little chance for encountering a recurring  pattern. 
120132	 * @see #getStringMatcher(String) 
121133	 */ 
122134	public  void  setCachePatterns (boolean  cachePatterns ) {
@@ -317,7 +329,7 @@ protected String[] tokenizePath(String path) {
317329	}
318330
319331	/** 
320- 	 * Tests  whether or not a string matches against a pattern. 
332+ 	 * Test  whether or not a string matches against a pattern. 
321333	 * @param pattern the pattern to match against (never {@code null}) 
322334	 * @param str the String which must be matched against the pattern (never {@code null}) 
323335	 * @return {@code true} if the string matches against the pattern, or {@code false} otherwise 
@@ -331,10 +343,10 @@ private boolean matchStrings(String pattern, String str, Map<String, String> uri
331343	 * <p>The default implementation checks this AntPathMatcher's internal cache 
332344	 * (see {@link #setCachePatterns}), creating a new AntPathStringMatcher instance 
333345	 * if no cached copy is found. 
334- 	 * When encountering too many patterns to cache at runtime (the threshold is 65536), 
346+ 	 * <p> When encountering too many patterns to cache at runtime (the threshold is 65536), 
335347	 * it turns the default cache off, assuming that arbitrary permutations of patterns 
336- 	 * are coming in, with little chance for encountering a reoccurring  pattern. 
337- 	 * <p>This method may get  overridden to implement a custom cache strategy. 
348+ 	 * are coming in, with little chance for encountering a recurring  pattern. 
349+ 	 * <p>This method may be  overridden to implement a custom cache strategy. 
338350	 * @param pattern the pattern to match against (never {@code null}) 
339351	 * @return a corresponding AntPathStringMatcher (never {@code null}) 
340352	 * @see #setCachePatterns 
@@ -406,23 +418,35 @@ public Map<String, String> extractUriTemplateVariables(String pattern, String pa
406418	}
407419
408420	/** 
409- 	 * Combines two patterns into a new pattern that is returned. 
410- 	 * <p>This implementation simply concatenates the two patterns, unless the first pattern 
411- 	 * contains a file extension match (such as {@code *.html}. In that case, the second pattern 
412- 	 * should be included in the first, or an {@code IllegalArgumentException} is thrown. 
413- 	 * <p>For example: <table> 
414- 	 * <tr><th>Pattern 1</th><th>Pattern 2</th><th>Result</th></tr> <tr><td>/hotels</td><td>{@code 
415- 	 * null}</td><td>/hotels</td></tr> <tr><td>{@code null}</td><td>/hotels</td><td>/hotels</td></tr> 
416- 	 * <tr><td>/hotels</td><td>/bookings</td><td>/hotels/bookings</td></tr> <tr><td>/hotels</td><td>bookings</td><td>/hotels/bookings</td></tr> 
417- 	 * <tr><td>/hotels/*</td><td>/bookings</td><td>/hotels/bookings</td></tr> <tr><td>/hotels/**</td><td>/bookings</td><td>/hotels/**/bookings</td></tr> 
418- 	 * <tr><td>/hotels</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr> <tr><td>/hotels/*</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr> 
421+ 	 * Combine two patterns into a new pattern. 
422+ 	 * 
423+ 	 * <p>This implementation simply concatenates the two patterns, unless 
424+ 	 * the first pattern contains a file extension match (e.g., {@code *.html}). 
425+ 	 * In that case, the second pattern will be merged into the first. Otherwise, 
426+ 	 * an {@code IllegalArgumentException} will be thrown. 
427+ 	 * 
428+ 	 * <h3>Examples</h3> 
429+ 	 * <table border="1"> 
430+ 	 * <tr><th>Pattern 1</th><th>Pattern 2</th><th>Result</th></tr> 
431+ 	 * <tr><td>{@code null}</td><td>{@code null}</td><td> </td></tr> 
432+ 	 * <tr><td>/hotels</td><td>{@code null}</td><td>/hotels</td></tr> 
433+ 	 * <tr><td>{@code null}</td><td>/hotels</td><td>/hotels</td></tr> 
434+ 	 * <tr><td>/hotels</td><td>/bookings</td><td>/hotels/bookings</td></tr> 
435+ 	 * <tr><td>/hotels</td><td>bookings</td><td>/hotels/bookings</td></tr> 
436+ 	 * <tr><td>/hotels/*</td><td>/bookings</td><td>/hotels/bookings</td></tr> 
437+ 	 * <tr><td>/hotels/**</td><td>/bookings</td><td>/hotels/**/bookings</td></tr> 
438+ 	 * <tr><td>/hotels</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr> 
439+ 	 * <tr><td>/hotels/*</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr> 
419440	 * <tr><td>/hotels/**</td><td>{hotel}</td><td>/hotels/**/{hotel}</td></tr> 
420- 	 * <tr><td>/*.html</td><td>/hotels.html</td><td>/hotels.html</td></tr> <tr><td>/*.html</td><td>/hotels</td><td>/hotels.html</td></tr> 
421- 	 * <tr><td>/*.html</td><td>/*.txt</td><td>IllegalArgumentException</td></tr> </table> 
441+ 	 * <tr><td>/*.html</td><td>/hotels.html</td><td>/hotels.html</td></tr> 
442+ 	 * <tr><td>/*.html</td><td>/hotels</td><td>/hotels.html</td></tr> 
443+ 	 * <tr><td>/*.html</td><td>/*.txt</td><td>{@code IllegalArgumentException}</td></tr> 
444+ 	 * </table> 
445+ 	 * 
422446	 * @param pattern1 the first pattern 
423447	 * @param pattern2 the second pattern 
424448	 * @return the combination of the two patterns 
425- 	 * @throws IllegalArgumentException when  the two patterns cannot be combined 
449+ 	 * @throws IllegalArgumentException if  the two patterns cannot be combined 
426450	 */ 
427451	@ Override 
428452	public  String  combine (String  pattern1 , String  pattern2 ) {
@@ -469,10 +493,18 @@ public String combine(String pattern1, String pattern2) {
469493	}
470494
471495	private  String  concat (String  path1 , String  path2 ) {
472- 		if  (path1 .endsWith (this .pathSeparator ) || path2 .startsWith (this .pathSeparator )) {
496+ 		boolean  path1EndsWithSeparator  = path1 .endsWith (this .pathSeparator );
497+ 		boolean  path2StartsWithSeparator  = path2 .startsWith (this .pathSeparator );
498+ 
499+ 		if  (path1EndsWithSeparator  && path2StartsWithSeparator ) {
500+ 			return  path1  + path2 .substring (1 );
501+ 		}
502+ 		else  if  (path1EndsWithSeparator  || path2StartsWithSeparator ) {
473503			return  path1  + path2 ;
474504		}
475- 		return  path1  + this .pathSeparator  + path2 ;
505+ 		else  {
506+ 			return  path1  + this .pathSeparator  + path2 ;
507+ 		}
476508	}
477509
478510	/** 
0 commit comments