Polishing (backported from several master changes)
This commit is contained in:
parent
d4f4225e53
commit
1ac8e48ebf
|
|
@ -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 {
|
||||||
* @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
|
||||||
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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
* 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;
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
* 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
|
||||||
* @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
|
||||||
* 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
|
||||||
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
|
||||||
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
|
||||||
/**
|
/**
|
||||||
* Use {@link WeakReference}s.
|
* Use {@link WeakReference}s.
|
||||||
*/
|
*/
|
||||||
WEAK;
|
WEAK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
* @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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
* 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
|
||||||
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
|
||||||
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
|
||||||
* 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
|
||||||
* @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
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
* 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 {
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
||||||
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 {
|
||||||
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();) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
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 {
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
* 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
|
||||||
* <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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
* {@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
|
||||||
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());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue