Author: kkolinko Date: Wed Apr 28 08:21:32 2010 New Revision: 938814 URL: http://svn.apache.org/viewvc?rev=938814&view=rev Log: Use a helper class to manage the filter mappings. Fix ArrayIndexOutOfBoundsException in addFilterMapBefore as reported in re: r937975 thread.
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=938814&r1=938813&r2=938814&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Wed Apr 28 08:21:32 2010 @@ -383,21 +383,7 @@ public class StandardContext * added via the {...@link ServletContext} possibly both before and after those * defined in the deployment descriptor. */ - private FilterMap filterMaps[] = new FilterMap[0]; - - private final Object filterMapsLock = new Object(); - - - /** - * Filter mappings added via {...@link ServletContext} may have to be inserted - * before the mappings in the deployment descriptor but must be inserted in - * the order the {...@link ServletContext} methods are called. This isn't an - * issue for the mappings added after the deployment descriptor - they are - * just added to the end - but correctly the adding mappings before the - * deployment descriptor mappings requires knowing where the last 'before' - * mapping was added. - */ - private int filterMapInsertPoint = 0; + private final ContextFilterMaps filterMaps = new ContextFilterMaps(); /** * Ignore annotations. @@ -2590,15 +2576,9 @@ public class StandardContext * is malformed */ public void addFilterMap(FilterMap filterMap) { - validateFilterMap(filterMap); // Add this filter mapping to our registered set - synchronized (filterMapsLock) { - FilterMap results[] = Arrays.copyOf(filterMaps, - filterMaps.length + 1); - results[filterMaps.length] = filterMap; - filterMaps = results; - } + filterMaps.add(filterMap); fireContainerEvent("addFilterMap", filterMap); } @@ -2614,22 +2594,9 @@ public class StandardContext * is malformed */ public void addFilterMapBefore(FilterMap filterMap) { - validateFilterMap(filterMap); - // Add this filter mapping to our registered set - synchronized (filterMapsLock) { - FilterMap results[] = new FilterMap[filterMaps.length + 1]; - System.arraycopy(filterMaps, 0, results, 0, filterMapInsertPoint); - results[filterMapInsertPoint] = filterMap; - System.arraycopy(filterMaps, filterMapInsertPoint, results, - filterMaps.length - (filterMapInsertPoint + 1), - filterMaps.length - filterMapInsertPoint); - - filterMapInsertPoint++; - - filterMaps = results; - } + filterMaps.addBefore(filterMap); fireContainerEvent("addFilterMap", filterMap); } @@ -3139,9 +3106,7 @@ public class StandardContext * Return the set of filter mappings for this Context. */ public FilterMap[] findFilterMaps() { - - return (filterMaps); - + return filterMaps.asArray(); } @@ -3711,35 +3676,9 @@ public class StandardContext * @param filterMap The filter mapping to be removed */ public void removeFilterMap(FilterMap filterMap) { - - synchronized (filterMapsLock) { - - // Make sure this filter mapping is currently present - int n = -1; - for (int i = 0; i < filterMaps.length; i++) { - if (filterMaps[i] == filterMap) { - n = i; - break; - } - } - if (n < 0) - return; - - // Remove the specified filter mapping - FilterMap results[] = new FilterMap[filterMaps.length - 1]; - System.arraycopy(filterMaps, 0, results, 0, n); - System.arraycopy(filterMaps, n + 1, results, n, - (filterMaps.length - 1) - n); - if (n < filterMapInsertPoint) { - filterMapInsertPoint--; - } - filterMaps = results; - - } - + filterMaps.remove(filterMap); // Inform interested listeners fireContainerEvent("removeFilterMap", filterMap); - } @@ -4104,6 +4043,116 @@ public class StandardContext return null; } + + /** + * A helper class to manage the filter mappings in a Context. + */ + private static final class ContextFilterMaps { + private final Object lock = new Object(); + + /** + * The set of filter mappings for this application, in the order they + * were defined in the deployment descriptor with additional mappings + * added via the {...@link ServletContext} possibly both before and after + * those defined in the deployment descriptor. + */ + private FilterMap[] array = new FilterMap[0]; + + /** + * Filter mappings added via {...@link ServletContext} may have to be + * inserted before the mappings in the deployment descriptor but must be + * inserted in the order the {...@link ServletContext} methods are called. + * This isn't an issue for the mappings added after the deployment + * descriptor - they are just added to the end - but correctly the + * adding mappings before the deployment descriptor mappings requires + * knowing where the last 'before' mapping was added. + */ + private int insertPoint = 0; + + /** + * Reset the set to the initial state. + */ + public void clear() { + synchronized (lock) { + array = new FilterMap[0]; + insertPoint = 0; + } + } + + /** + * Return the set of filter mappings. + */ + public FilterMap[] asArray() { + synchronized (lock) { + return array; + } + } + + /** + * Add a filter mapping at the end of the current set of filter + * mappings. + * + * @param filterMap + * The filter mapping to be added + */ + public void add(FilterMap filterMap) { + synchronized (lock) { + FilterMap results[] = Arrays.copyOf(array, array.length + 1); + results[array.length] = filterMap; + array = results; + } + } + + /** + * Add a filter mapping before the mappings defined in the deployment + * descriptor but after any other mappings added via this method. + * + * @param filterMap + * The filter mapping to be added + */ + public void addBefore(FilterMap filterMap) { + synchronized (lock) { + FilterMap results[] = new FilterMap[array.length + 1]; + System.arraycopy(array, 0, results, 0, insertPoint); + System.arraycopy(array, insertPoint, results, insertPoint + 1, + array.length - insertPoint); + results[insertPoint] = filterMap; + array = results; + insertPoint++; + } + } + + /** + * Remove a filter mapping. + * + * @param filterMap The filter mapping to be removed + */ + public void remove(FilterMap filterMap) { + synchronized (lock) { + // Make sure this filter mapping is currently present + int n = -1; + for (int i = 0; i < array.length; i++) { + if (array[i] == filterMap) { + n = i; + break; + } + } + if (n < 0) + return; + + // Remove the specified filter mapping + FilterMap results[] = new FilterMap[array.length - 1]; + System.arraycopy(array, 0, results, 0, n); + System.arraycopy(array, n + 1, results, n, (array.length - 1) + - n); + array = results; + if (n < insertPoint) { + insertPoint--; + } + } + } + } + // --------------------------------------------------------- Public Methods --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org