Skip to content

Commit 6ff7583

Browse files
committed
Merge branch '7.0.x'
2 parents ca9b26e + 8965d9b commit 6ff7583

5 files changed

Lines changed: 175 additions & 104 deletions

File tree

spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public V get(K key) {
102102
if (this.capacity == 0) {
103103
return this.generator.apply(key);
104104
}
105-
final Node<K, V> node = this.cache.get(key);
105+
Node<K, V> node = this.cache.get(key);
106106
if (node == null) {
107107
V value = this.generator.apply(key);
108108
put(key, value);
@@ -115,9 +115,9 @@ public V get(K key) {
115115
private void put(K key, V value) {
116116
Assert.notNull(key, "key must not be null");
117117
Assert.notNull(value, "value must not be null");
118-
final CacheEntry<V> cacheEntry = new CacheEntry<>(value, CacheEntryState.ACTIVE);
119-
final Node<K, V> node = new Node<>(key, cacheEntry);
120-
final Node<K, V> prior = this.cache.putIfAbsent(node.key, node);
118+
CacheEntry<V> cacheEntry = new CacheEntry<>(value, CacheEntryState.ACTIVE);
119+
Node<K, V> node = new Node<>(key, cacheEntry);
120+
Node<K, V> prior = this.cache.putIfAbsent(node.key, node);
121121
if (prior == null) {
122122
processWrite(new AddTask(node));
123123
}
@@ -128,7 +128,7 @@ private void put(K key, V value) {
128128

129129
private void processRead(Node<K, V> node) {
130130
boolean drainRequested = this.readOperations.recordRead(node);
131-
final DrainStatus status = this.drainStatus.get();
131+
DrainStatus status = this.drainStatus.get();
132132
if (status.shouldDrainBuffers(drainRequested)) {
133133
drainOperations();
134134
}
@@ -228,7 +228,7 @@ public boolean contains(K key) {
228228
* {@code false} if there was no matching key
229229
*/
230230
public boolean remove(K key) {
231-
final Node<K, V> node = this.cache.remove(key);
231+
Node<K, V> node = this.cache.remove(key);
232232
if (node == null) {
233233
return false;
234234
}
@@ -237,27 +237,29 @@ public boolean remove(K key) {
237237
return true;
238238
}
239239

240-
/*
240+
/**
241241
* Transition the node from the {@code active} state to the {@code pending removal} state,
242242
* if the transition is valid.
243243
*/
244244
private void markForRemoval(Node<K, V> node) {
245-
for (; ; ) {
246-
final CacheEntry<V> current = node.get();
245+
while (true) {
246+
CacheEntry<V> current = node.get();
247247
if (!current.isActive()) {
248248
return;
249249
}
250-
final CacheEntry<V> pendingRemoval = new CacheEntry<>(current.value, CacheEntryState.PENDING_REMOVAL);
250+
CacheEntry<V> pendingRemoval = new CacheEntry<>(current.value, CacheEntryState.PENDING_REMOVAL);
251251
if (node.compareAndSet(current, pendingRemoval)) {
252252
return;
253253
}
254254
}
255255
}
256256

257+
257258
/**
258259
* Write operation recorded when a new entry is added to the cache.
259260
*/
260261
private final class AddTask implements Runnable {
262+
261263
final Node<K, V> node;
262264

263265
AddTask(Node<K, V> node) {
@@ -275,22 +277,22 @@ public void run() {
275277

276278
private void evictEntries() {
277279
while (currentSize.get() > capacity) {
278-
final Node<K, V> node = evictionQueue.poll();
280+
Node<K, V> node = evictionQueue.poll();
279281
if (node == null) {
280282
return;
281283
}
282284
cache.remove(node.key, node);
283285
markAsRemoved(node);
284286
}
285287
}
286-
287288
}
288289

289290

290291
/**
291292
* Write operation recorded when an entry is removed to the cache.
292293
*/
293294
private final class RemovalTask implements Runnable {
295+
294296
final Node<K, V> node;
295297

296298
RemovalTask(Node<K, V> node) {
@@ -310,7 +312,7 @@ public void run() {
310312
*/
311313
private enum DrainStatus {
312314

313-
/*
315+
/**
314316
* No drain operation currently running.
315317
*/
316318
IDLE {
@@ -320,7 +322,7 @@ boolean shouldDrainBuffers(boolean delayable) {
320322
}
321323
},
322324

323-
/*
325+
/**
324326
* A drain operation is required due to a pending write modification.
325327
*/
326328
REQUIRED {
@@ -330,7 +332,7 @@ boolean shouldDrainBuffers(boolean delayable) {
330332
}
331333
},
332334

333-
/*
335+
/**
334336
* A drain operation is in progress.
335337
*/
336338
PROCESSING {
@@ -367,12 +369,6 @@ private static final class ReadOperations<K, V> {
367369

368370
private static final int BUFFER_COUNT = detectNumberOfBuffers();
369371

370-
private static int detectNumberOfBuffers() {
371-
int availableProcessors = Runtime.getRuntime().availableProcessors();
372-
int nextPowerOfTwo = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(availableProcessors - 1));
373-
return Math.min(4, nextPowerOfTwo);
374-
}
375-
376372
private static final int BUFFERS_MASK = BUFFER_COUNT - 1;
377373

378374
private static final int MAX_PENDING_OPERATIONS = 32;
@@ -383,30 +379,25 @@ private static int detectNumberOfBuffers() {
383379

384380
private static final int BUFFER_INDEX_MASK = BUFFER_SIZE - 1;
385381

386-
/*
387-
* Number of operations recorded, for each buffer
388-
*/
382+
// Number of operations recorded, for each buffer
389383
private final AtomicLongArray recordedCount = new AtomicLongArray(BUFFER_COUNT);
390384

391-
/*
392-
* Number of operations read, for each buffer
393-
*/
385+
// Number of operations read, for each buffer
394386
private final long[] readCount = new long[BUFFER_COUNT];
395387

396-
/*
397-
* Number of operations processed, for each buffer
398-
*/
388+
// Number of operations processed, for each buffer
399389
private final AtomicLongArray processedCount = new AtomicLongArray(BUFFER_COUNT);
400390

401391
@SuppressWarnings("rawtypes")
402392
private final AtomicReferenceArray<Node<K, V>>[] buffers = new AtomicReferenceArray[BUFFER_COUNT];
403393

404394
private final EvictionQueue<K, V> evictionQueue;
405395

396+
@SuppressWarnings("rawtypes")
406397
ReadOperations(EvictionQueue<K, V> evictionQueue) {
407398
this.evictionQueue = evictionQueue;
408399
for (int i = 0; i < BUFFER_COUNT; i++) {
409-
this.buffers[i] = new AtomicReferenceArray<>(BUFFER_SIZE);
400+
this.buffers[i] = new AtomicReferenceArray(BUFFER_SIZE);
410401
}
411402
}
412403

@@ -458,6 +449,12 @@ private void drainReadBuffer(int bufferIndex) {
458449
}
459450
this.processedCount.lazySet(bufferIndex, writeCount);
460451
}
452+
453+
private static int detectNumberOfBuffers() {
454+
int availableProcessors = Runtime.getRuntime().availableProcessors();
455+
int nextPowerOfTwo = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(availableProcessors - 1));
456+
return Math.min(4, nextPowerOfTwo);
457+
}
461458
}
462459

463460

@@ -536,10 +533,9 @@ private static final class EvictionQueue<K, V> {
536533
if (this.first == null) {
537534
return null;
538535
}
539-
final Node<K, V> f = this.first;
540-
final Node<K, V> next = f.getNext();
536+
Node<K, V> f = this.first;
537+
Node<K, V> next = f.getNext();
541538
f.setNext(null);
542-
543539
this.first = next;
544540
if (next == null) {
545541
this.last = null;
@@ -558,13 +554,12 @@ void add(Node<K, V> e) {
558554
}
559555

560556
private boolean contains(Node<K, V> e) {
561-
return (e.getPrevious() != null) || (e.getNext() != null) || (e == this.first);
557+
return (e.getPrevious() != null || e.getNext() != null || e == this.first);
562558
}
563559

564-
private void linkLast(final Node<K, V> e) {
565-
final Node<K, V> l = this.last;
560+
private void linkLast(Node<K, V> e) {
561+
Node<K, V> l = this.last;
566562
this.last = e;
567-
568563
if (l == null) {
569564
this.first = e;
570565
}
@@ -575,8 +570,8 @@ private void linkLast(final Node<K, V> e) {
575570
}
576571

577572
private void unlink(Node<K, V> e) {
578-
final Node<K, V> prev = e.getPrevious();
579-
final Node<K, V> next = e.getNext();
573+
Node<K, V> prev = e.getPrevious();
574+
Node<K, V> next = e.getNext();
580575
if (prev == null) {
581576
this.first = next;
582577
}

spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -892,26 +892,38 @@ else if (streamSource.getReader() != null) {
892892
// By default, Spring will prevent the processing of external entities.
893893
// This is a mitigation against XXE attacks.
894894
if (xmlReader == null) {
895-
SAXParserFactory saxParserFactory = this.sourceParserFactory;
896-
if (saxParserFactory == null) {
897-
saxParserFactory = SAXParserFactory.newInstance();
898-
saxParserFactory.setNamespaceAware(true);
899-
saxParserFactory.setFeature(
900-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
901-
saxParserFactory.setFeature(
902-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
903-
this.sourceParserFactory = saxParserFactory;
895+
SAXParserFactory factory = this.sourceParserFactory;
896+
if (factory == null) {
897+
factory = SAXParserFactory.newInstance();
898+
factory.setNamespaceAware(true);
899+
try {
900+
factory.setFeature(
901+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
902+
}
903+
catch (Exception ex) {
904+
// Xerces properties not recognized/supported - ignore
905+
}
906+
try {
907+
factory.setFeature(
908+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
909+
factory.setFeature(
910+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
911+
}
912+
catch (Exception ex) {
913+
// SAX properties not recognized/supported - ignore
914+
}
915+
this.sourceParserFactory = factory;
904916
}
905-
SAXParser saxParser = saxParserFactory.newSAXParser();
917+
SAXParser saxParser = factory.newSAXParser();
906918
xmlReader = saxParser.getXMLReader();
907919
}
908920
if (!isProcessExternalEntities()) {
909921
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
910922
}
911923
return new SAXSource(xmlReader, inputSource);
912924
}
913-
catch (SAXException | ParserConfigurationException ex) {
914-
logger.info("Processing of external entities could not be disabled", ex);
925+
catch (Exception ex) {
926+
logger.warn("Processing of external entities could not be disabled", ex);
915927
return source;
916928
}
917929
}

spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
7575
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
7676
(publicId, systemId) -> new InputSource(new StringReader(""));
7777

78+
7879
/** Logger available to subclasses. */
7980
protected final Log logger = LogFactory.getLog(getClass());
8081

@@ -165,8 +166,22 @@ protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserCon
165166
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
166167
factory.setValidating(false);
167168
factory.setNamespaceAware(true);
168-
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
169-
factory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
169+
try {
170+
factory.setFeature(
171+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
172+
}
173+
catch (Exception ex) {
174+
// Xerces properties not recognized/supported - ignore
175+
}
176+
try {
177+
factory.setFeature(
178+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
179+
factory.setFeature(
180+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
181+
}
182+
catch (Exception ex) {
183+
// SAX properties not recognized/supported - ignore
184+
}
170185
return factory;
171186
}
172187

@@ -195,17 +210,29 @@ protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
195210
* @throws ParserConfigurationException if thrown by JAXP methods
196211
*/
197212
protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException {
198-
SAXParserFactory parserFactory = this.saxParserFactory;
199-
if (parserFactory == null) {
200-
parserFactory = SAXParserFactory.newInstance();
201-
parserFactory.setNamespaceAware(true);
202-
parserFactory.setFeature(
203-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
204-
parserFactory.setFeature(
205-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
206-
this.saxParserFactory = parserFactory;
213+
SAXParserFactory factory = this.saxParserFactory;
214+
if (factory == null) {
215+
factory = SAXParserFactory.newInstance();
216+
factory.setNamespaceAware(true);
217+
try {
218+
factory.setFeature(
219+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
220+
}
221+
catch (Exception ex) {
222+
// Xerces properties not recognized/supported - ignore
223+
}
224+
try {
225+
factory.setFeature(
226+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
227+
factory.setFeature(
228+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
229+
}
230+
catch (Exception ex) {
231+
// SAX properties not recognized/supported - ignore
232+
}
233+
this.saxParserFactory = factory;
207234
}
208-
SAXParser saxParser = parserFactory.newSAXParser();
235+
SAXParser saxParser = factory.newSAXParser();
209236
XMLReader xmlReader = saxParser.getXMLReader();
210237
if (!isProcessExternalEntities()) {
211238
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
@@ -456,8 +483,7 @@ protected Object unmarshalSaxSource(SAXSource saxSource) throws XmlMappingExcept
456483
catch (NullPointerException ex) {
457484
if (!isSupportDtd()) {
458485
throw new UnmarshallingFailureException("NPE while unmarshalling. " +
459-
"This can happen on JDK 1.6 due to the presence of DTD " +
460-
"declarations, which are disabled.");
486+
"This can happen due to the presence of DTD declarations, which are disabled.");
461487
}
462488
throw ex;
463489
}

0 commit comments

Comments
 (0)