提交 1ac8e48e 编写于 作者: J Juergen Hoeller

Polishing (backported from several master changes)

上级 d4f4225e
...@@ -139,7 +139,7 @@ public abstract class BeanFactoryUtils { ...@@ -139,7 +139,7 @@ public abstract class BeanFactoryUtils {
* @param type the type that beans must match * @param type the type that beans must match
* @return the array of matching bean names, or an empty array if none * @return the array of matching bean names, or an empty array if none
*/ */
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class type) { public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type) {
Assert.notNull(lbf, "ListableBeanFactory must not be null"); Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type); String[] result = lbf.getBeanNamesForType(type);
if (lbf instanceof HierarchicalBeanFactory) { if (lbf instanceof HierarchicalBeanFactory) {
...@@ -181,7 +181,7 @@ public abstract class BeanFactoryUtils { ...@@ -181,7 +181,7 @@ public abstract class BeanFactoryUtils {
* @return the array of matching bean names, or an empty array if none * @return the array of matching bean names, or an empty array if none
*/ */
public static String[] beanNamesForTypeIncludingAncestors( public static String[] beanNamesForTypeIncludingAncestors(
ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) { ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
Assert.notNull(lbf, "ListableBeanFactory must not be null"); Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit); String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
......
...@@ -130,7 +130,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application ...@@ -130,7 +130,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) { protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) {
Class<? extends ApplicationEvent> eventType = event.getClass(); Class<? extends ApplicationEvent> eventType = event.getClass();
Object source = event.getSource(); Object source = event.getSource();
Class sourceType = (source == null ? null : source.getClass()); Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType); ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
ListenerRetriever retriever = this.retrieverCache.get(cacheKey); ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) { if (retriever != null) {
...@@ -193,11 +193,11 @@ public abstract class AbstractApplicationEventMulticaster implements Application ...@@ -193,11 +193,11 @@ public abstract class AbstractApplicationEventMulticaster implements Application
*/ */
private static class ListenerCacheKey { private static class ListenerCacheKey {
private final Class eventType; private final Class<?> eventType;
private final Class sourceType; private final Class<?> sourceType;
public ListenerCacheKey(Class eventType, Class sourceType) { public ListenerCacheKey(Class<?> eventType, Class<?> sourceType) {
this.eventType = eventType; this.eventType = eventType;
this.sourceType = sourceType; this.sourceType = sourceType;
} }
...@@ -208,14 +208,13 @@ public abstract class AbstractApplicationEventMulticaster implements Application ...@@ -208,14 +208,13 @@ public abstract class AbstractApplicationEventMulticaster implements Application
return true; return true;
} }
ListenerCacheKey otherKey = (ListenerCacheKey) other; ListenerCacheKey otherKey = (ListenerCacheKey) other;
return ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) return ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) &&
&& ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType); ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.eventType) * 29 return ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
+ ObjectUtils.nullSafeHashCode(this.sourceType);
} }
} }
......
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -48,7 +48,7 @@ import java.util.concurrent.locks.ReentrantLock; ...@@ -48,7 +48,7 @@ import java.util.concurrent.locks.ReentrantLock;
* references at any time, so it may appear that an unknown thread is silently removing * references at any time, so it may appear that an unknown thread is silently removing
* entries. * entries.
* *
* <p>If not explicitly specified this implementation will use * <p>If not explicitly specified, this implementation will use
* {@linkplain SoftReference soft entry references}. * {@linkplain SoftReference soft entry references}.
* *
* @param <K> The key type * @param <K> The key type
...@@ -56,8 +56,7 @@ import java.util.concurrent.locks.ReentrantLock; ...@@ -56,8 +56,7 @@ import java.util.concurrent.locks.ReentrantLock;
* @author Phillip Webb * @author Phillip Webb
* @since 3.2 * @since 3.2
*/ */
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
ConcurrentMap<K, V> {
private static final int DEFAULT_INITIAL_CAPACITY = 16; private static final int DEFAULT_INITIAL_CAPACITY = 16;
...@@ -82,6 +81,9 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -82,6 +81,9 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
*/ */
private final float loadFactor; private final float loadFactor;
/**
* The reference type: SOFT or WEAK.
*/
private final ReferenceType referenceType; private final ReferenceType referenceType;
/** /**
...@@ -99,8 +101,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -99,8 +101,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* Create a new {@code ConcurrentReferenceHashMap} instance. * Create a new {@code ConcurrentReferenceHashMap} instance.
*/ */
public ConcurrentReferenceHashMap() { public ConcurrentReferenceHashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL, this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL, DEFAULT_REFERENCE_TYPE);
DEFAULT_REFERENCE_TYPE);
} }
/** /**
...@@ -108,8 +109,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -108,8 +109,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* @param initialCapacity the initial capacity of the map * @param initialCapacity the initial capacity of the map
*/ */
public ConcurrentReferenceHashMap(int initialCapacity) { public ConcurrentReferenceHashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL, this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL, DEFAULT_REFERENCE_TYPE);
DEFAULT_REFERENCE_TYPE);
} }
/** /**
...@@ -119,45 +119,44 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -119,45 +119,44 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* exceeds this value resize will be attempted * exceeds this value resize will be attempted
*/ */
public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor) { public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor) {
this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL, this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL, DEFAULT_REFERENCE_TYPE);
DEFAULT_REFERENCE_TYPE);
} }
/** /**
* Create a new {@code ConcurrentReferenceHashMap} instance. * Create a new {@code ConcurrentReferenceHashMap} instance.
* @param initialCapacity the initial capacity of the map * @param initialCapacity the initial capacity of the map
* @param concurrencyLevel the expected number of threads that will concurrently write * @param concurrencyLevel the expected number of threads that will concurrently
* to the map * write to the map
*/ */
public ConcurrentReferenceHashMap(int initialCapacity, int concurrencyLevel) { public ConcurrentReferenceHashMap(int initialCapacity, int concurrencyLevel) {
this(initialCapacity, DEFAULT_LOAD_FACTOR, concurrencyLevel, this(initialCapacity, DEFAULT_LOAD_FACTOR, concurrencyLevel, DEFAULT_REFERENCE_TYPE);
DEFAULT_REFERENCE_TYPE);
} }
/** /**
* Create a new {@code ConcurrentReferenceHashMap} instance. * Create a new {@code ConcurrentReferenceHashMap} instance.
* @param initialCapacity the initial capacity of the map * @param initialCapacity the initial capacity of the map
* @param loadFactor the load factor. When the average number of references per table * @param loadFactor the load factor. When the average number of references per
* exceeds this value resize will be attempted * table exceeds this value, resize will be attempted.
* @param concurrencyLevel the expected number of threads that will concurrently write * @param concurrencyLevel the expected number of threads that will concurrently
* to the map * write to the map
*/ */
public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
int concurrencyLevel) {
this(initialCapacity, loadFactor, concurrencyLevel, DEFAULT_REFERENCE_TYPE); this(initialCapacity, loadFactor, concurrencyLevel, DEFAULT_REFERENCE_TYPE);
} }
/** /**
* Create a new {@code ConcurrentReferenceHashMap} instance. * Create a new {@code ConcurrentReferenceHashMap} instance.
* @param initialCapacity the initial capacity of the map * @param initialCapacity the initial capacity of the map
* @param loadFactor the load factor. When the average number of references per table * @param loadFactor the load factor. When the average number of references per
* exceeds this value resize will be attempted * table exceeds this value, resize will be attempted.
* @param concurrencyLevel the expected number of threads that will concurrently write * @param concurrencyLevel the expected number of threads that will concurrently
* to the map * write to the map
* @param referenceType the reference type used for entries * @param referenceType the reference type used for entries
*/ */
public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, @SuppressWarnings("unchecked")
int concurrencyLevel, ReferenceType referenceType) { public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel,
ReferenceType referenceType) {
Assert.isTrue(concurrencyLevel > 0, "ConcurrencyLevel must be positive"); Assert.isTrue(concurrencyLevel > 0, "ConcurrencyLevel must be positive");
Assert.isTrue(initialCapacity >= 0, "InitialCapacity must not be negative"); Assert.isTrue(initialCapacity >= 0, "InitialCapacity must not be negative");
Assert.isTrue(loadFactor > 0f, "LoadFactor must be positive"); Assert.isTrue(loadFactor > 0f, "LoadFactor must be positive");
...@@ -167,17 +166,12 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -167,17 +166,12 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
int size = 1 << this.shift; int size = 1 << this.shift;
this.referenceType = referenceType; this.referenceType = referenceType;
int roundedUpSegmentCapactity = (int) ((initialCapacity + size - 1L) / size); int roundedUpSegmentCapactity = (int) ((initialCapacity + size - 1L) / size);
this.segments = createSegmentsArray(size); this.segments = (Segment[]) Array.newInstance(Segment.class, size);
for (int i = 0; i < this.segments.length; i++) { for (int i = 0; i < this.segments.length; i++) {
this.segments[i] = new Segment(roundedUpSegmentCapactity); this.segments[i] = new Segment(roundedUpSegmentCapactity);
} }
} }
@SuppressWarnings("unchecked")
private Segment[] createSegmentsArray(int size) {
return (Segment[]) Array.newInstance(Segment.class, size);
}
protected final float getLoadFactor() { protected final float getLoadFactor() {
return this.loadFactor; return this.loadFactor;
...@@ -222,7 +216,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -222,7 +216,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public V get(Object key) { public V get(Object key) {
Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY); Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY);
Entry<K, V> entry = (reference == null ? null : reference.get()); Entry<K, V> entry = (reference == null ? null : reference.get());
return (entry == null ? null : entry.getValue()); return (entry != null ? entry.getValue() : null);
} }
@Override @Override
...@@ -388,7 +382,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -388,7 +382,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
/** /**
* Use {@link WeakReference}s. * Use {@link WeakReference}s.
*/ */
WEAK; WEAK
} }
...@@ -421,14 +415,12 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -421,14 +415,12 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
*/ */
private int resizeThreshold; private int resizeThreshold;
public Segment(int initialCapacity) { public Segment(int initialCapacity) {
this.referenceManager = createReferenceManager(); this.referenceManager = createReferenceManager();
this.initialSize = 1 << calculateShift(initialCapacity, MAXIMUM_SEGMENT_SIZE); this.initialSize = 1 << calculateShift(initialCapacity, MAXIMUM_SEGMENT_SIZE);
setReferences(createReferenceArray(this.initialSize)); setReferences(createReferenceArray(this.initialSize));
} }
public Reference<K, V> getReference(Object key, int hash, Restructure restructure) { public Reference<K, V> getReference(Object key, int hash, Restructure restructure) {
if (restructure == Restructure.WHEN_NECESSARY) { if (restructure == Restructure.WHEN_NECESSARY) {
restructureIfNecessary(false); restructureIfNecessary(false);
...@@ -452,17 +444,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -452,17 +444,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* @return the result of the operation * @return the result of the operation
*/ */
public <T> T doTask(final int hash, final Object key, final Task<T> task) { public <T> T doTask(final int hash, final Object key, final Task<T> task) {
boolean resize = task.hasOption(TaskOption.RESIZE); boolean resize = task.hasOption(TaskOption.RESIZE);
if (task.hasOption(TaskOption.RESTRUCTURE_BEFORE)) { if (task.hasOption(TaskOption.RESTRUCTURE_BEFORE)) {
restructureIfNecessary(resize); restructureIfNecessary(resize);
} }
if (task.hasOption(TaskOption.SKIP_IF_EMPTY) && (this.count == 0)) { if (task.hasOption(TaskOption.SKIP_IF_EMPTY) && (this.count == 0)) {
return task.execute(null, null, null); return task.execute(null, null, null);
} }
lock(); lock();
try { try {
final int index = getIndex(hash, this.references); final int index = getIndex(hash, this.references);
...@@ -480,7 +468,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -480,7 +468,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
} }
}; };
return task.execute(reference, entry, entries); return task.execute(reference, entry, entries);
} finally { }
finally {
unlock(); unlock();
if (task.hasOption(TaskOption.RESTRUCTURE_AFTER)) { if (task.hasOption(TaskOption.RESTRUCTURE_AFTER)) {
restructureIfNecessary(resize); restructureIfNecessary(resize);
...@@ -569,8 +558,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -569,8 +558,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
} }
} }
private Reference<K, V> findInChain(Reference<K, V> reference, Object key, private Reference<K, V> findInChain(Reference<K, V> reference, Object key, int hash) {
int hash) {
while (reference != null) { while (reference != null) {
if (reference.getHash() == hash) { if (reference.getHash() == hash) {
Entry<K, V> entry = reference.get(); Entry<K, V> entry = reference.get();
...@@ -752,6 +740,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -752,6 +740,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* Various options supported by a {@link Task}. * Various options supported by a {@link Task}.
*/ */
private static enum TaskOption { private static enum TaskOption {
RESTRUCTURE_BEFORE, RESTRUCTURE_AFTER, SKIP_IF_EMPTY, RESIZE RESTRUCTURE_BEFORE, RESTRUCTURE_AFTER, SKIP_IF_EMPTY, RESIZE
} }
...@@ -783,8 +772,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -783,8 +772,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean contains(Object o) { public boolean contains(Object o) {
if (o != null && o instanceof Map.Entry<?, ?>) { if (o != null && o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (java.util.Map.Entry<?, ?>) o; Map.Entry<?, ?> entry = (java.util.Map.Entry<?, ?>) o;
Reference<K, V> reference = ConcurrentReferenceHashMap.this.getReference( Reference<K, V> reference = ConcurrentReferenceHashMap.this.getReference(entry.getKey(), Restructure.NEVER);
entry.getKey(), Restructure.NEVER);
Entry<K, V> other = (reference == null ? null : reference.get()); Entry<K, V> other = (reference == null ? null : reference.get());
if (other != null) { if (other != null) {
return ObjectUtils.nullSafeEquals(entry.getValue(), other.getValue()); return ObjectUtils.nullSafeEquals(entry.getValue(), other.getValue());
...@@ -797,8 +785,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -797,8 +785,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean remove(Object o) { public boolean remove(Object o) {
if (o instanceof Map.Entry<?, ?>) { if (o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
return ConcurrentReferenceHashMap.this.remove(entry.getKey(), return ConcurrentReferenceHashMap.this.remove(entry.getKey(), entry.getValue());
entry.getValue());
} }
return false; return false;
} }
...@@ -897,6 +884,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -897,6 +884,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* The types of restructuring that can be performed. * The types of restructuring that can be performed.
*/ */
protected static enum Restructure { protected static enum Restructure {
WHEN_NECESSARY, NEVER WHEN_NECESSARY, NEVER
} }
...@@ -916,8 +904,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -916,8 +904,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
* @param next the next reference in the chain or {@code null} * @param next the next reference in the chain or {@code null}
* @return a new {@link Reference} * @return a new {@link Reference}
*/ */
public Reference<K, V> createReference(Entry<K, V> entry, int hash, public Reference<K, V> createReference(Entry<K, V> entry, int hash, Reference<K, V> next) {
Reference<K, V> next) {
if (ConcurrentReferenceHashMap.this.referenceType == ReferenceType.WEAK) { if (ConcurrentReferenceHashMap.this.referenceType == ReferenceType.WEAK) {
return new WeakEntryReference<K, V>(entry, hash, next, this.queue); return new WeakEntryReference<K, V>(entry, hash, next, this.queue);
} }
...@@ -941,15 +928,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -941,15 +928,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
/** /**
* Internal {@link Reference} implementation for {@link SoftReference}s. * Internal {@link Reference} implementation for {@link SoftReference}s.
*/ */
private static final class SoftEntryReference<K, V> extends private static final class SoftEntryReference<K, V> extends SoftReference<Entry<K, V>> implements Reference<K, V> {
SoftReference<Entry<K, V>> implements Reference<K, V> {
private final int hash; private final int hash;
private final Reference<K, V> nextReference; private final Reference<K, V> nextReference;
public SoftEntryReference(Entry<K, V> entry, int hash, Reference<K, V> next, public SoftEntryReference(Entry<K, V> entry, int hash, Reference<K, V> next, ReferenceQueue<Entry<K, V>> queue) {
ReferenceQueue<Entry<K, V>> queue) {
super(entry, queue); super(entry, queue);
this.hash = hash; this.hash = hash;
this.nextReference = next; this.nextReference = next;
...@@ -973,15 +958,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -973,15 +958,13 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
/** /**
* Internal {@link Reference} implementation for {@link WeakReference}s. * Internal {@link Reference} implementation for {@link WeakReference}s.
*/ */
private static final class WeakEntryReference<K, V> extends private static final class WeakEntryReference<K, V> extends WeakReference<Entry<K, V>> implements Reference<K, V> {
WeakReference<Entry<K, V>> implements Reference<K, V> {
private final int hash; private final int hash;
private final Reference<K, V> nextReference; private final Reference<K, V> nextReference;
public WeakEntryReference(Entry<K, V> entry, int hash, Reference<K, V> next, public WeakEntryReference(Entry<K, V> entry, int hash, Reference<K, V> next, ReferenceQueue<Entry<K, V>> queue) {
ReferenceQueue<Entry<K, V>> queue) {
super(entry, queue); super(entry, queue);
this.hash = hash; this.hash = hash;
this.nextReference = next; this.nextReference = next;
...@@ -1000,4 +983,5 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen ...@@ -1000,4 +983,5 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
clear(); clear();
} }
} }
} }
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -51,12 +51,12 @@ import org.springframework.util.StringUtils; ...@@ -51,12 +51,12 @@ import org.springframework.util.StringUtils;
* an {@code XMLEventReader}, and calls the corresponding methods on the SAX callback interfaces. * an {@code XMLEventReader}, and calls the corresponding methods on the SAX callback interfaces.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 3.0
* @see XMLEventReader * @see XMLEventReader
* @see #setContentHandler(org.xml.sax.ContentHandler) * @see #setContentHandler(org.xml.sax.ContentHandler)
* @see #setDTDHandler(org.xml.sax.DTDHandler) * @see #setDTDHandler(org.xml.sax.DTDHandler)
* @see #setEntityResolver(org.xml.sax.EntityResolver) * @see #setEntityResolver(org.xml.sax.EntityResolver)
* @see #setErrorHandler(org.xml.sax.ErrorHandler) * @see #setErrorHandler(org.xml.sax.ErrorHandler)
* @since 3.0
*/ */
class StaxEventXMLReader extends AbstractStaxXMLReader { class StaxEventXMLReader extends AbstractStaxXMLReader {
...@@ -70,11 +70,11 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { ...@@ -70,11 +70,11 @@ class StaxEventXMLReader extends AbstractStaxXMLReader {
private String encoding; private String encoding;
/** /**
* Constructs a new instance of the {@code StaxEventXmlReader} that reads from the given * Constructs a new instance of the {@code StaxEventXmlReader} that reads from the given
* {@code XMLEventReader}. The supplied event reader must be in {@code XMLStreamConstants.START_DOCUMENT} or * {@code XMLEventReader}. The supplied event reader must be in {@code XMLStreamConstants.START_DOCUMENT} or
* {@code XMLStreamConstants.START_ELEMENT} state. * {@code XMLStreamConstants.START_ELEMENT} state.
*
* @param reader the {@code XMLEventReader} to read from * @param reader the {@code XMLEventReader} to read from
* @throws IllegalStateException if the reader is not at the start of a document or element * @throws IllegalStateException if the reader is not at the start of a document or element
*/ */
...@@ -89,17 +89,17 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { ...@@ -89,17 +89,17 @@ class StaxEventXMLReader extends AbstractStaxXMLReader {
catch (XMLStreamException ex) { catch (XMLStreamException ex) {
throw new IllegalStateException("Could not read first element: " + ex.getMessage()); throw new IllegalStateException("Could not read first element: " + ex.getMessage());
} }
this.reader = reader; this.reader = reader;
} }
@Override @Override
protected void parseInternal() throws SAXException, XMLStreamException { protected void parseInternal() throws SAXException, XMLStreamException {
boolean documentStarted = false; boolean documentStarted = false;
boolean documentEnded = false; boolean documentEnded = false;
int elementDepth = 0; int elementDepth = 0;
while (reader.hasNext() && elementDepth >= 0) { while (this.reader.hasNext() && elementDepth >= 0) {
XMLEvent event = reader.nextEvent(); XMLEvent event = this.reader.nextEvent();
if (!event.isStartDocument() && !event.isEndDocument() && !documentStarted) { if (!event.isStartDocument() && !event.isEndDocument() && !documentStarted) {
handleStartDocument(event); handleStartDocument(event);
documentStarted = true; documentStarted = true;
...@@ -165,36 +165,28 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { ...@@ -165,36 +165,28 @@ class StaxEventXMLReader extends AbstractStaxXMLReader {
this.encoding = startDocument.getCharacterEncodingScheme(); this.encoding = startDocument.getCharacterEncodingScheme();
} }
} }
if (getContentHandler() != null) { if (getContentHandler() != null) {
final Location location = event.getLocation(); final Location location = event.getLocation();
getContentHandler().setDocumentLocator(new Locator2() { getContentHandler().setDocumentLocator(new Locator2() {
public int getColumnNumber() { public int getColumnNumber() {
return location != null ? location.getColumnNumber() : -1; return (location != null ? location.getColumnNumber() : -1);
} }
public int getLineNumber() { public int getLineNumber() {
return location != null ? location.getLineNumber() : -1; return (location != null ? location.getLineNumber() : -1);
} }
public String getPublicId() { public String getPublicId() {
return location != null ? location.getPublicId() : null; return (location != null ? location.getPublicId() : null);
} }
public String getSystemId() { public String getSystemId() {
return location != null ? location.getSystemId() : null; return (location != null ? location.getSystemId() : null);
} }
public String getXMLVersion() { public String getXMLVersion() {
return xmlVersion; return xmlVersion;
} }
public String getEncoding() { public String getEncoding() {
return encoding; return encoding;
} }
}); });
getContentHandler().startDocument(); getContentHandler().startDocument();
} }
} }
...@@ -311,7 +303,6 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { ...@@ -311,7 +303,6 @@ class StaxEventXMLReader extends AbstractStaxXMLReader {
private Attributes getAttributes(StartElement event) { private Attributes getAttributes(StartElement event) {
AttributesImpl attributes = new AttributesImpl(); AttributesImpl attributes = new AttributesImpl();
for (Iterator i = event.getAttributes(); i.hasNext();) { for (Iterator i = event.getAttributes(); i.hasNext();) {
Attribute attribute = (Attribute) i.next(); Attribute attribute = (Attribute) i.next();
QName qName = attribute.getName(); QName qName = attribute.getName();
...@@ -323,8 +314,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { ...@@ -323,8 +314,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader {
if (type == null) { if (type == null) {
type = "CDATA"; type = "CDATA";
} }
attributes attributes.addAttribute(namespace, qName.getLocalPart(), toQualifiedName(qName), type, attribute.getValue());
.addAttribute(namespace, qName.getLocalPart(), toQualifiedName(qName), type, attribute.getValue());
} }
if (hasNamespacePrefixesFeature()) { if (hasNamespacePrefixesFeature()) {
for (Iterator i = event.getNamespaces(); i.hasNext();) { for (Iterator i = event.getNamespaces(); i.hasNext();) {
......
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -31,16 +31,16 @@ import org.springframework.util.Assert; ...@@ -31,16 +31,16 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* SAX {@code XMLReader} that reads from a StAX {@code XMLStreamReader}. Reads from an * SAX {@code XMLReader} that reads from a StAX {@code XMLStreamReader}. Reads from an
* {@code XMLStreamReader}, and calls the corresponding methods on the SAX callback interfaces. * {@code XMLStreamReader}, and calls the corresponding methods on the SAX callback interfaces.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 3.0
* @see XMLStreamReader * @see XMLStreamReader
* @see #setContentHandler(org.xml.sax.ContentHandler) * @see #setContentHandler(org.xml.sax.ContentHandler)
* @see #setDTDHandler(org.xml.sax.DTDHandler) * @see #setDTDHandler(org.xml.sax.DTDHandler)
* @see #setEntityResolver(org.xml.sax.EntityResolver) * @see #setEntityResolver(org.xml.sax.EntityResolver)
* @see #setErrorHandler(org.xml.sax.ErrorHandler) * @see #setErrorHandler(org.xml.sax.ErrorHandler)
* @since 3.0
*/ */
class StaxStreamXMLReader extends AbstractStaxXMLReader { class StaxStreamXMLReader extends AbstractStaxXMLReader {
...@@ -52,11 +52,11 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -52,11 +52,11 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
private String encoding; private String encoding;
/** /**
* Constructs a new instance of the {@code StaxStreamXmlReader} that reads from the given * Construct a new instance of the {@code StaxStreamXmlReader} that reads from the given
* {@code XMLStreamReader}. The supplied stream reader must be in {@code XMLStreamConstants.START_DOCUMENT} * {@code XMLStreamReader}. The supplied stream reader must be in {@code XMLStreamConstants.START_DOCUMENT}
* or {@code XMLStreamConstants.START_ELEMENT} state. * or {@code XMLStreamConstants.START_ELEMENT} state.
*
* @param reader the {@code XMLEventReader} to read from * @param reader the {@code XMLEventReader} to read from
* @throws IllegalStateException if the reader is not at the start of a document or element * @throws IllegalStateException if the reader is not at the start of a document or element
*/ */
...@@ -69,12 +69,13 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -69,12 +69,13 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
this.reader = reader; this.reader = reader;
} }
@Override @Override
protected void parseInternal() throws SAXException, XMLStreamException { protected void parseInternal() throws SAXException, XMLStreamException {
boolean documentStarted = false; boolean documentStarted = false;
boolean documentEnded = false; boolean documentEnded = false;
int elementDepth = 0; int elementDepth = 0;
int eventType = reader.getEventType(); int eventType = this.reader.getEventType();
while (true) { while (true) {
if (eventType != XMLStreamConstants.START_DOCUMENT && eventType != XMLStreamConstants.END_DOCUMENT && if (eventType != XMLStreamConstants.START_DOCUMENT && eventType != XMLStreamConstants.END_DOCUMENT &&
!documentStarted) { !documentStarted) {
...@@ -118,8 +119,8 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -118,8 +119,8 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
handleEntityReference(); handleEntityReference();
break; break;
} }
if (reader.hasNext() && elementDepth >= 0) { if (this.reader.hasNext() && elementDepth >= 0) {
eventType = reader.next(); eventType = this.reader.next();
} }
else { else {
break; break;
...@@ -131,66 +132,58 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -131,66 +132,58 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
} }
private void handleStartDocument() throws SAXException { private void handleStartDocument() throws SAXException {
if (XMLStreamConstants.START_DOCUMENT == reader.getEventType()) { if (XMLStreamConstants.START_DOCUMENT == this.reader.getEventType()) {
String xmlVersion = reader.getVersion(); String xmlVersion = this.reader.getVersion();
if (StringUtils.hasLength(xmlVersion)) { if (StringUtils.hasLength(xmlVersion)) {
this.xmlVersion = xmlVersion; this.xmlVersion = xmlVersion;
} }
this.encoding = reader.getCharacterEncodingScheme(); this.encoding = this.reader.getCharacterEncodingScheme();
} }
if (getContentHandler() != null) { if (getContentHandler() != null) {
final Location location = reader.getLocation(); final Location location = this.reader.getLocation();
getContentHandler().setDocumentLocator(new Locator2() { getContentHandler().setDocumentLocator(new Locator2() {
public int getColumnNumber() { public int getColumnNumber() {
return location != null ? location.getColumnNumber() : -1; return (location != null ? location.getColumnNumber() : -1);
} }
public int getLineNumber() { public int getLineNumber() {
return location != null ? location.getLineNumber() : -1; return (location != null ? location.getLineNumber() : -1);
} }
public String getPublicId() { public String getPublicId() {
return location != null ? location.getPublicId() : null; return (location != null ? location.getPublicId() : null);
} }
public String getSystemId() { public String getSystemId() {
return location != null ? location.getSystemId() : null; return (location != null ? location.getSystemId() : null);
} }
public String getXMLVersion() { public String getXMLVersion() {
return xmlVersion; return xmlVersion;
} }
public String getEncoding() { public String getEncoding() {
return encoding; return encoding;
} }
}); });
getContentHandler().startDocument(); getContentHandler().startDocument();
if (reader.standaloneSet()) { if (this.reader.standaloneSet()) {
setStandalone(reader.isStandalone()); setStandalone(this.reader.isStandalone());
} }
} }
} }
private void handleStartElement() throws SAXException { private void handleStartElement() throws SAXException {
if (getContentHandler() != null) { if (getContentHandler() != null) {
QName qName = reader.getName(); QName qName = this.reader.getName();
if (hasNamespacesFeature()) { if (hasNamespacesFeature()) {
for (int i = 0; i < reader.getNamespaceCount(); i++) { for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
startPrefixMapping(reader.getNamespacePrefix(i), reader.getNamespaceURI(i)); startPrefixMapping(this.reader.getNamespacePrefix(i), this.reader.getNamespaceURI(i));
} }
for (int i = 0; i < reader.getAttributeCount(); i++) { for (int i = 0; i < this.reader.getAttributeCount(); i++) {
String prefix = reader.getAttributePrefix(i); String prefix = this.reader.getAttributePrefix(i);
String namespace = reader.getAttributeNamespace(i); String namespace = this.reader.getAttributeNamespace(i);
if (StringUtils.hasLength(namespace)) { if (StringUtils.hasLength(namespace)) {
startPrefixMapping(prefix, namespace); startPrefixMapping(prefix, namespace);
} }
} }
getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName), getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(),
getAttributes()); toQualifiedName(qName), getAttributes());
} }
else { else {
getContentHandler().startElement("", "", toQualifiedName(qName), getAttributes()); getContentHandler().startElement("", "", toQualifiedName(qName), getAttributes());
...@@ -200,11 +193,11 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -200,11 +193,11 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
private void handleEndElement() throws SAXException { private void handleEndElement() throws SAXException {
if (getContentHandler() != null) { if (getContentHandler() != null) {
QName qName = reader.getName(); QName qName = this.reader.getName();
if (hasNamespacesFeature()) { if (hasNamespacesFeature()) {
getContentHandler().endElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName)); getContentHandler().endElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName));
for (int i = 0; i < reader.getNamespaceCount(); i++) { for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
String prefix = reader.getNamespacePrefix(i); String prefix = this.reader.getNamespacePrefix(i);
if (prefix == null) { if (prefix == null) {
prefix = ""; prefix = "";
} }
...@@ -218,31 +211,33 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -218,31 +211,33 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
} }
private void handleCharacters() throws SAXException { private void handleCharacters() throws SAXException {
if (getContentHandler() != null && reader.isWhiteSpace()) { if (getContentHandler() != null && this.reader.isWhiteSpace()) {
getContentHandler() getContentHandler().ignorableWhitespace(this.reader.getTextCharacters(),
.ignorableWhitespace(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength()); this.reader.getTextStart(), this.reader.getTextLength());
return; return;
} }
if (XMLStreamConstants.CDATA == reader.getEventType() && getLexicalHandler() != null) { if (XMLStreamConstants.CDATA == this.reader.getEventType() && getLexicalHandler() != null) {
getLexicalHandler().startCDATA(); getLexicalHandler().startCDATA();
} }
if (getContentHandler() != null) { if (getContentHandler() != null) {
getContentHandler().characters(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength()); getContentHandler().characters(this.reader.getTextCharacters(),
this.reader.getTextStart(), this.reader.getTextLength());
} }
if (XMLStreamConstants.CDATA == reader.getEventType() && getLexicalHandler() != null) { if (XMLStreamConstants.CDATA == this.reader.getEventType() && getLexicalHandler() != null) {
getLexicalHandler().endCDATA(); getLexicalHandler().endCDATA();
} }
} }
private void handleComment() throws SAXException { private void handleComment() throws SAXException {
if (getLexicalHandler() != null) { if (getLexicalHandler() != null) {
getLexicalHandler().comment(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength()); getLexicalHandler().comment(this.reader.getTextCharacters(),
this.reader.getTextStart(), this.reader.getTextLength());
} }
} }
private void handleDtd() throws SAXException { private void handleDtd() throws SAXException {
if (getLexicalHandler() != null) { if (getLexicalHandler() != null) {
javax.xml.stream.Location location = reader.getLocation(); javax.xml.stream.Location location = this.reader.getLocation();
getLexicalHandler().startDTD(null, location.getPublicId(), location.getSystemId()); getLexicalHandler().startDTD(null, location.getPublicId(), location.getSystemId());
} }
if (getLexicalHandler() != null) { if (getLexicalHandler() != null) {
...@@ -252,10 +247,10 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -252,10 +247,10 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
private void handleEntityReference() throws SAXException { private void handleEntityReference() throws SAXException {
if (getLexicalHandler() != null) { if (getLexicalHandler() != null) {
getLexicalHandler().startEntity(reader.getLocalName()); getLexicalHandler().startEntity(this.reader.getLocalName());
} }
if (getLexicalHandler() != null) { if (getLexicalHandler() != null) {
getLexicalHandler().endEntity(reader.getLocalName()); getLexicalHandler().endEntity(this.reader.getLocalName());
} }
} }
...@@ -267,29 +262,28 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { ...@@ -267,29 +262,28 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
private void handleProcessingInstruction() throws SAXException { private void handleProcessingInstruction() throws SAXException {
if (getContentHandler() != null) { if (getContentHandler() != null) {
getContentHandler().processingInstruction(reader.getPITarget(), reader.getPIData()); getContentHandler().processingInstruction(this.reader.getPITarget(), this.reader.getPIData());
} }
} }
private Attributes getAttributes() { private Attributes getAttributes() {
AttributesImpl attributes = new AttributesImpl(); AttributesImpl attributes = new AttributesImpl();
for (int i = 0; i < this.reader.getAttributeCount(); i++) {
for (int i = 0; i < reader.getAttributeCount(); i++) { String namespace = this.reader.getAttributeNamespace(i);
String namespace = reader.getAttributeNamespace(i);
if (namespace == null || !hasNamespacesFeature()) { if (namespace == null || !hasNamespacesFeature()) {
namespace = ""; namespace = "";
} }
String type = reader.getAttributeType(i); String type = this.reader.getAttributeType(i);
if (type == null) { if (type == null) {
type = "CDATA"; type = "CDATA";
} }
attributes.addAttribute(namespace, reader.getAttributeLocalName(i), attributes.addAttribute(namespace, this.reader.getAttributeLocalName(i),
toQualifiedName(reader.getAttributeName(i)), type, reader.getAttributeValue(i)); toQualifiedName(this.reader.getAttributeName(i)), type, this.reader.getAttributeValue(i));
} }
if (hasNamespacePrefixesFeature()) { if (hasNamespacePrefixesFeature()) {
for (int i = 0; i < reader.getNamespaceCount(); i++) { for (int i = 0; i < this.reader.getNamespaceCount(); i++) {
String prefix = reader.getNamespacePrefix(i); String prefix = this.reader.getNamespacePrefix(i);
String namespaceUri = reader.getNamespaceURI(i); String namespaceUri = this.reader.getNamespaceURI(i);
String qName; String qName;
if (StringUtils.hasLength(prefix)) { if (StringUtils.hasLength(prefix)) {
qName = "xmlns:" + prefix; qName = "xmlns:" + prefix;
......
/* /*
* Copyright 2002-2011 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -25,7 +25,6 @@ import java.util.Iterator; ...@@ -25,7 +25,6 @@ import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
...@@ -54,6 +53,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -54,6 +53,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
private final List<String> fileExtensions = new ArrayList<String>(); private final List<String> fileExtensions = new ArrayList<String>();
/** /**
* Creates a new instance with the given URL patterns. * Creates a new instance with the given URL patterns.
* Each pattern that is not empty and does not start with "/" is prepended with "/". * Each pattern that is not empty and does not start with "/" is prepended with "/".
...@@ -66,7 +66,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -66,7 +66,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
/** /**
* Additional constructor with flags for using suffix pattern (.*) and * Additional constructor with flags for using suffix pattern (.*) and
* trailing slash matches. * trailing slash matches.
*
* @param patterns the URL patterns to use; if 0, the condition will match to every request. * @param patterns the URL patterns to use; if 0, the condition will match to every request.
* @param urlPathHelper for determining the lookup path of a request * @param urlPathHelper for determining the lookup path of a request
* @param pathMatcher for path matching with patterns * @param pathMatcher for path matching with patterns
...@@ -98,7 +97,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -98,7 +97,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
/** /**
* Private constructor accepting a collection of patterns. * Private constructor accepting a collection of patterns.
* @param fileExtensionResolver
*/ */
private PatternsRequestCondition(Collection<String> patterns, UrlPathHelper urlPathHelper, private PatternsRequestCondition(Collection<String> patterns, UrlPathHelper urlPathHelper,
PathMatcher pathMatcher, boolean useSuffixPatternMatch, boolean useTrailingSlashMatch, PathMatcher pathMatcher, boolean useSuffixPatternMatch, boolean useTrailingSlashMatch,
...@@ -119,8 +117,9 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -119,8 +117,9 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
} }
} }
private static List<String> asList(String... patterns) { private static List<String> asList(String... patterns) {
return patterns != null ? Arrays.asList(patterns) : Collections.<String>emptyList(); return (patterns != null ? Arrays.asList(patterns) : Collections.<String>emptyList());
} }
private static Set<String> prependLeadingSlash(Collection<String> patterns) { private static Set<String> prependLeadingSlash(Collection<String> patterns) {
...@@ -188,7 +187,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -188,7 +187,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
* Checks if any of the patterns match the given request and returns an instance * Checks if any of the patterns match the given request and returns an instance
* that is guaranteed to contain matching patterns, sorted via * that is guaranteed to contain matching patterns, sorted via
* {@link PathMatcher#getPatternComparator(String)}. * {@link PathMatcher#getPatternComparator(String)}.
*
* <p>A matching pattern is obtained by making checks in the following order: * <p>A matching pattern is obtained by making checks in the following order:
* <ul> * <ul>
* <li>Direct match * <li>Direct match
...@@ -196,12 +194,10 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -196,12 +194,10 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
* <li>Pattern match * <li>Pattern match
* <li>Pattern match with "/" appended if the pattern doesn't already end in "/" * <li>Pattern match with "/" appended if the pattern doesn't already end in "/"
* </ul> * </ul>
*
* @param request the current request * @param request the current request
*
* @return the same instance if the condition contains no patterns; * @return the same instance if the condition contains no patterns;
* or a new condition with sorted matching patterns; * or a new condition with sorted matching patterns;
* or {@code null} if no patterns match. * or {@code null} if no patterns match.
*/ */
@Override @Override
public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) { public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) {
...@@ -210,9 +206,8 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -210,9 +206,8 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
} }
String lookupPath = this.pathHelper.getLookupPathForRequest(request); String lookupPath = this.pathHelper.getLookupPathForRequest(request);
List<String> matches = new ArrayList<String>(); List<String> matches = new ArrayList<String>();
for (String pattern : patterns) { for (String pattern : this.patterns) {
String match = getMatchingPattern(pattern, lookupPath); String match = getMatchingPattern(pattern, lookupPath);
if (match != null) { if (match != null) {
matches.add(match); matches.add(match);
...@@ -260,7 +255,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -260,7 +255,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
* {@link PathMatcher#getPatternComparator(String)}. If all compared * {@link PathMatcher#getPatternComparator(String)}. If all compared
* patterns match equally, but one instance has more patterns, it is * patterns match equally, but one instance has more patterns, it is
* considered a closer match. * considered a closer match.
*
* <p>It is assumed that both instances have been obtained via * <p>It is assumed that both instances have been obtained via
* {@link #getMatchingCondition(HttpServletRequest)} to ensure they * {@link #getMatchingCondition(HttpServletRequest)} to ensure they
* contain only patterns that match the request and are sorted with * contain only patterns that match the request and are sorted with
...@@ -271,7 +265,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat ...@@ -271,7 +265,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
String lookupPath = this.pathHelper.getLookupPathForRequest(request); String lookupPath = this.pathHelper.getLookupPathForRequest(request);
Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(lookupPath); Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(lookupPath);
Iterator<String> iterator = patterns.iterator(); Iterator<String> iterator = this.patterns.iterator();
Iterator<String> iteratorOther = other.patterns.iterator(); Iterator<String> iteratorOther = other.patterns.iterator();
while (iterator.hasNext() && iteratorOther.hasNext()) { while (iterator.hasNext() && iteratorOther.hasNext()) {
int result = patternComparator.compare(iterator.next(), iteratorOther.next()); int result = patternComparator.compare(iterator.next(), iteratorOther.next());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册