Polishing
This commit is contained in:
@@ -252,7 +252,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||||||
}
|
}
|
||||||
catch (NoSuchBeanDefinitionException ex) {
|
catch (NoSuchBeanDefinitionException ex) {
|
||||||
throw new BeanCreationException(beanName,
|
throw new BeanCreationException(beanName,
|
||||||
"Cannot apply @Lookup to beans without corresponding bean definition");
|
"Cannot apply @Lookup to beans without corresponding bean definition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ class ConstructorResolver {
|
|||||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||||
* @return a BeanWrapper for the new instance
|
* @return a BeanWrapper for the new instance
|
||||||
*/
|
*/
|
||||||
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
|
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
|
||||||
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
|
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
|
||||||
|
|
||||||
BeanWrapperImpl bw = new BeanWrapperImpl();
|
BeanWrapperImpl bw = new BeanWrapperImpl();
|
||||||
this.beanFactory.initBeanWrapper(bw);
|
this.beanFactory.initBeanWrapper(bw);
|
||||||
@@ -326,7 +326,7 @@ class ConstructorResolver {
|
|||||||
* the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag.
|
* the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag.
|
||||||
* Called as the starting point for factory method determination.
|
* Called as the starting point for factory method determination.
|
||||||
*/
|
*/
|
||||||
private Method[] getCandidateMethods(final Class<?> factoryClass, final RootBeanDefinition mbd) {
|
private Method[] getCandidateMethods(Class<?> factoryClass, RootBeanDefinition mbd) {
|
||||||
if (System.getSecurityManager() != null) {
|
if (System.getSecurityManager() != null) {
|
||||||
return AccessController.doPrivileged((PrivilegedAction<Method[]>) () ->
|
return AccessController.doPrivileged((PrivilegedAction<Method[]>) () ->
|
||||||
(mbd.isNonPublicAccessAllowed() ?
|
(mbd.isNonPublicAccessAllowed() ?
|
||||||
@@ -354,7 +354,7 @@ class ConstructorResolver {
|
|||||||
* @return a BeanWrapper for the new instance
|
* @return a BeanWrapper for the new instance
|
||||||
*/
|
*/
|
||||||
public BeanWrapper instantiateUsingFactoryMethod(
|
public BeanWrapper instantiateUsingFactoryMethod(
|
||||||
final String beanName, final RootBeanDefinition mbd, @Nullable final Object[] explicitArgs) {
|
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
|
||||||
|
|
||||||
BeanWrapperImpl bw = new BeanWrapperImpl();
|
BeanWrapperImpl bw = new BeanWrapperImpl();
|
||||||
this.beanFactory.initBeanWrapper(bw);
|
this.beanFactory.initBeanWrapper(bw);
|
||||||
@@ -417,13 +417,13 @@ class ConstructorResolver {
|
|||||||
factoryClass = ClassUtils.getUserClass(factoryClass);
|
factoryClass = ClassUtils.getUserClass(factoryClass);
|
||||||
|
|
||||||
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
|
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
|
||||||
List<Method> candidateSet = new ArrayList<>();
|
List<Method> candidateList = new ArrayList<>();
|
||||||
for (Method candidate : rawCandidates) {
|
for (Method candidate : rawCandidates) {
|
||||||
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
|
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
|
||||||
candidateSet.add(candidate);
|
candidateList.add(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Method[] candidates = candidateSet.toArray(new Method[0]);
|
Method[] candidates = candidateList.toArray(new Method[0]);
|
||||||
AutowireUtils.sortFactoryMethods(candidates);
|
AutowireUtils.sortFactoryMethods(candidates);
|
||||||
|
|
||||||
ConstructorArgumentValues resolvedValues = null;
|
ConstructorArgumentValues resolvedValues = null;
|
||||||
@@ -456,7 +456,7 @@ class ConstructorResolver {
|
|||||||
if (paramTypes.length >= minNrOfArgs) {
|
if (paramTypes.length >= minNrOfArgs) {
|
||||||
ArgumentsHolder argsHolder;
|
ArgumentsHolder argsHolder;
|
||||||
|
|
||||||
if (explicitArgs != null){
|
if (explicitArgs != null) {
|
||||||
// Explicit arguments given -> arguments length must match exactly.
|
// Explicit arguments given -> arguments length must match exactly.
|
||||||
if (paramTypes.length != explicitArgs.length) {
|
if (paramTypes.length != explicitArgs.length) {
|
||||||
continue;
|
continue;
|
||||||
@@ -529,7 +529,7 @@ class ConstructorResolver {
|
|||||||
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
|
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (resolvedValues != null){
|
else if (resolvedValues != null) {
|
||||||
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
|
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
|
||||||
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
|
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
|
||||||
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
|
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 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.
|
||||||
@@ -38,8 +38,8 @@ public interface InstantiationStrategy {
|
|||||||
/**
|
/**
|
||||||
* Return an instance of the bean with the given name in this factory.
|
* Return an instance of the bean with the given name in this factory.
|
||||||
* @param bd the bean definition
|
* @param bd the bean definition
|
||||||
* @param beanName the name of the bean when it's created in this context.
|
* @param beanName the name of the bean when it is created in this context.
|
||||||
* The name can be {@code null} if we're autowiring a bean which doesn't
|
* The name can be {@code null} if we are autowiring a bean which doesn't
|
||||||
* belong to the factory.
|
* belong to the factory.
|
||||||
* @param owner the owning BeanFactory
|
* @param owner the owning BeanFactory
|
||||||
* @return a bean instance for this bean definition
|
* @return a bean instance for this bean definition
|
||||||
@@ -52,8 +52,8 @@ public interface InstantiationStrategy {
|
|||||||
* Return an instance of the bean with the given name in this factory,
|
* Return an instance of the bean with the given name in this factory,
|
||||||
* creating it via the given constructor.
|
* creating it via the given constructor.
|
||||||
* @param bd the bean definition
|
* @param bd the bean definition
|
||||||
* @param beanName the name of the bean when it's created in this context.
|
* @param beanName the name of the bean when it is created in this context.
|
||||||
* The name can be {@code null} if we're autowiring a bean which doesn't
|
* The name can be {@code null} if we are autowiring a bean which doesn't
|
||||||
* belong to the factory.
|
* belong to the factory.
|
||||||
* @param owner the owning BeanFactory
|
* @param owner the owning BeanFactory
|
||||||
* @param ctor the constructor to use
|
* @param ctor the constructor to use
|
||||||
@@ -68,8 +68,8 @@ public interface InstantiationStrategy {
|
|||||||
* Return an instance of the bean with the given name in this factory,
|
* Return an instance of the bean with the given name in this factory,
|
||||||
* creating it via the given factory method.
|
* creating it via the given factory method.
|
||||||
* @param bd the bean definition
|
* @param bd the bean definition
|
||||||
* @param beanName the name of the bean when it's created in this context.
|
* @param beanName the name of the bean when it is created in this context.
|
||||||
* The name can be {@code null} if we're autowiring a bean which doesn't
|
* The name can be {@code null} if we are autowiring a bean which doesn't
|
||||||
* belong to the factory.
|
* belong to the factory.
|
||||||
* @param owner the owning BeanFactory
|
* @param owner the owning BeanFactory
|
||||||
* @param factoryBean the factory bean instance to call the factory method on,
|
* @param factoryBean the factory bean instance to call the factory method on,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.springframework.cache.jcache;
|
package org.springframework.cache.jcache;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import javax.cache.Cache;
|
||||||
import javax.cache.processor.EntryProcessor;
|
import javax.cache.processor.EntryProcessor;
|
||||||
import javax.cache.processor.EntryProcessorException;
|
import javax.cache.processor.EntryProcessorException;
|
||||||
import javax.cache.processor.MutableEntry;
|
import javax.cache.processor.MutableEntry;
|
||||||
@@ -37,14 +38,14 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public class JCacheCache extends AbstractValueAdaptingCache {
|
public class JCacheCache extends AbstractValueAdaptingCache {
|
||||||
|
|
||||||
private final javax.cache.Cache<Object, Object> cache;
|
private final Cache<Object, Object> cache;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an {@link org.springframework.cache.jcache.JCacheCache} instance.
|
* Create an {@link org.springframework.cache.jcache.JCacheCache} instance.
|
||||||
* @param jcache backing JCache Cache instance
|
* @param jcache backing JCache Cache instance
|
||||||
*/
|
*/
|
||||||
public JCacheCache(javax.cache.Cache<Object, Object> jcache) {
|
public JCacheCache(Cache<Object, Object> jcache) {
|
||||||
this(jcache, true);
|
this(jcache, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
|
|||||||
* @param jcache backing JCache Cache instance
|
* @param jcache backing JCache Cache instance
|
||||||
* @param allowNullValues whether to accept and convert null values for this cache
|
* @param allowNullValues whether to accept and convert null values for this cache
|
||||||
*/
|
*/
|
||||||
public JCacheCache(javax.cache.Cache<Object, Object> jcache, boolean allowNullValues) {
|
public JCacheCache(Cache<Object, Object> jcache, boolean allowNullValues) {
|
||||||
super(allowNullValues);
|
super(allowNullValues);
|
||||||
Assert.notNull(jcache, "Cache must not be null");
|
Assert.notNull(jcache, "Cache must not be null");
|
||||||
this.cache = jcache;
|
this.cache = jcache;
|
||||||
@@ -66,7 +67,7 @@ public class JCacheCache extends AbstractValueAdaptingCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final javax.cache.Cache<Object, Object> getNativeCache() {
|
public final Cache<Object, Object> getNativeCache() {
|
||||||
return this.cache;
|
return this.cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.springframework.util.Assert;
|
|||||||
public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private javax.cache.CacheManager cacheManager;
|
private CacheManager cacheManager;
|
||||||
|
|
||||||
private boolean allowNullValues = true;
|
private boolean allowNullValues = true;
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
|
|||||||
/**
|
/**
|
||||||
* Set the backing JCache {@link javax.cache.CacheManager}.
|
* Set the backing JCache {@link javax.cache.CacheManager}.
|
||||||
*/
|
*/
|
||||||
public void setCacheManager(@Nullable javax.cache.CacheManager cacheManager) {
|
public void setCacheManager(@Nullable CacheManager cacheManager) {
|
||||||
this.cacheManager = cacheManager;
|
this.cacheManager = cacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ public class JCacheCacheManager extends AbstractTransactionSupportingCacheManage
|
|||||||
* Return the backing JCache {@link javax.cache.CacheManager}.
|
* Return the backing JCache {@link javax.cache.CacheManager}.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public javax.cache.CacheManager getCacheManager() {
|
public CacheManager getCacheManager() {
|
||||||
return this.cacheManager;
|
return this.cacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 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.
|
||||||
@@ -62,7 +62,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
|
private Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
|
||||||
Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false);
|
Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false);
|
||||||
if (ops != null && ops.size() > 1 && ae.getAnnotations().length > 0) {
|
if (ops != null && ops.size() > 1 && ae.getAnnotations().length > 0) {
|
||||||
// More than one operation found -> local declarations override interface-declared ones...
|
// More than one operation found -> local declarations override interface-declared ones...
|
||||||
@@ -88,6 +88,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
|||||||
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
|
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<CacheEvict> evicts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class) :
|
Collection<CacheEvict> evicts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class) :
|
||||||
AnnotatedElementUtils.findAllMergedAnnotations(ae, CacheEvict.class));
|
AnnotatedElementUtils.findAllMergedAnnotations(ae, CacheEvict.class));
|
||||||
if (!evicts.isEmpty()) {
|
if (!evicts.isEmpty()) {
|
||||||
@@ -96,6 +97,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
|||||||
ops.add(parseEvictAnnotation(ae, cachingConfig, evict));
|
ops.add(parseEvictAnnotation(ae, cachingConfig, evict));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<CachePut> puts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class) :
|
Collection<CachePut> puts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class) :
|
||||||
AnnotatedElementUtils.findAllMergedAnnotations(ae, CachePut.class));
|
AnnotatedElementUtils.findAllMergedAnnotations(ae, CachePut.class));
|
||||||
if (!puts.isEmpty()) {
|
if (!puts.isEmpty()) {
|
||||||
@@ -104,6 +106,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
|||||||
ops.add(parsePutAnnotation(ae, cachingConfig, put));
|
ops.add(parsePutAnnotation(ae, cachingConfig, put));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<Caching> cachings = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class) :
|
Collection<Caching> cachings = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class) :
|
||||||
AnnotatedElementUtils.findAllMergedAnnotations(ae, Caching.class));
|
AnnotatedElementUtils.findAllMergedAnnotations(ae, Caching.class));
|
||||||
if (!cachings.isEmpty()) {
|
if (!cachings.isEmpty()) {
|
||||||
@@ -313,7 +316,6 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
|||||||
builder.setCacheManager(this.cacheManager);
|
builder.setCacheManager(this.cacheManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader {
|
|||||||
|
|
||||||
private void handleDtd() throws SAXException {
|
private void handleDtd() throws SAXException {
|
||||||
if (getLexicalHandler() != null) {
|
if (getLexicalHandler() != null) {
|
||||||
javax.xml.stream.Location location = this.reader.getLocation();
|
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) {
|
||||||
|
|||||||
@@ -47,17 +47,19 @@ import org.springframework.util.MimeTypeUtils;
|
|||||||
import org.springframework.util.xml.StaxUtils;
|
import org.springframework.util.xml.StaxUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a {@link DataBuffer} stream into a stream of {@link XMLEvent}s.
|
* Decodes a {@link DataBuffer} stream into a stream of {@link XMLEvent XMLEvents}.
|
||||||
* That is, given the following XML:
|
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <p>Given the following XML:
|
||||||
* <root>
|
*
|
||||||
* <child>foo</child>
|
* <pre class="code">
|
||||||
* <child>bar</child>
|
* <root>
|
||||||
* </root>}
|
* <child>foo</child>
|
||||||
|
* <child>bar</child>
|
||||||
|
* </root>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* this method with result in a flux with the following events:
|
* this decoder will produce a {@link Flux} with the following events:
|
||||||
|
*
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>{@link javax.xml.stream.events.StartDocument}</li>
|
* <li>{@link javax.xml.stream.events.StartDocument}</li>
|
||||||
* <li>{@link javax.xml.stream.events.StartElement} {@code root}</li>
|
* <li>{@link javax.xml.stream.events.StartElement} {@code root}</li>
|
||||||
@@ -70,8 +72,8 @@ import org.springframework.util.xml.StaxUtils;
|
|||||||
* <li>{@link javax.xml.stream.events.EndElement} {@code root}</li>
|
* <li>{@link javax.xml.stream.events.EndElement} {@code root}</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* Note that this decoder is not registered by default but used internally
|
* <p>Note that this decoder is not registered by default but is used internally
|
||||||
* by other decoders who are there by default.
|
* by other decoders which are registered by default.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
@@ -97,7 +99,7 @@ public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
|||||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
|
|
||||||
Flux<DataBuffer> flux = Flux.from(inputStream);
|
Flux<DataBuffer> flux = Flux.from(inputStream);
|
||||||
if (useAalto) {
|
if (this.useAalto) {
|
||||||
AaltoDataBufferToXmlEvent aaltoMapper = new AaltoDataBufferToXmlEvent();
|
AaltoDataBufferToXmlEvent aaltoMapper = new AaltoDataBufferToXmlEvent();
|
||||||
return flux.flatMap(aaltoMapper)
|
return flux.flatMap(aaltoMapper)
|
||||||
.doFinally(signalType -> aaltoMapper.endOfInput());
|
.doFinally(signalType -> aaltoMapper.endOfInput());
|
||||||
@@ -135,15 +137,15 @@ public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
|||||||
@Override
|
@Override
|
||||||
public Publisher<? extends XMLEvent> apply(DataBuffer dataBuffer) {
|
public Publisher<? extends XMLEvent> apply(DataBuffer dataBuffer) {
|
||||||
try {
|
try {
|
||||||
streamReader.getInputFeeder().feedInput(dataBuffer.asByteBuffer());
|
this.streamReader.getInputFeeder().feedInput(dataBuffer.asByteBuffer());
|
||||||
List<XMLEvent> events = new ArrayList<>();
|
List<XMLEvent> events = new ArrayList<>();
|
||||||
while (true) {
|
while (true) {
|
||||||
if (streamReader.next() == AsyncXMLStreamReader.EVENT_INCOMPLETE) {
|
if (this.streamReader.next() == AsyncXMLStreamReader.EVENT_INCOMPLETE) {
|
||||||
// no more events with what currently has been fed to the reader
|
// no more events with what currently has been fed to the reader
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
XMLEvent event = eventAllocator.allocate(streamReader);
|
XMLEvent event = this.eventAllocator.allocate(this.streamReader);
|
||||||
events.add(event);
|
events.add(event);
|
||||||
if (event.isEndDocument()) {
|
if (event.isEndDocument()) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user