30
30
import java .util .Map .Entry ;
31
31
import java .util .concurrent .locks .ReadWriteLock ;
32
32
import java .util .concurrent .locks .ReentrantReadWriteLock ;
33
+ import javax .annotation .Nullable ;
33
34
import javax .xml .transform .Source ;
34
35
import javax .xml .transform .sax .SAXSource ;
35
36
@@ -314,32 +315,82 @@ public synchronized ReentrantReadWriteLock getLock(final String contextMapName)
314
315
return lock ;
315
316
}
316
317
}
317
-
318
+
318
319
/**
319
- * Retrieves a previously stored Object from the Context of an XQuery.
320
+ * Stores an Object into the Context of an XQuery.
320
321
*
321
- * @param context The Context of the XQuery containing the Object
322
- * @param contextMapName DOCUMENT ME!
323
- * @param objectUID The UID of the Object to retrieve from the Context of the XQuery
324
- * @param <T> class of the object stored in the context
325
- * @return the object stored in the context or null
326
- */
327
- public static < T > T retrieveObjectFromContextMap ( XQueryContext context , String contextMapName , long objectUID ) {
328
- try (final ManagedLock < ReadWriteLock > readLock = ManagedLock . acquire ( contextMapLocks . getLock ( contextMapName ), LockMode . READ_LOCK )) {
329
- // get the existing object map from the context
330
- final Map < Long , T > map = ( HashMap < Long , T >) context . getAttribute ( contextMapName );
331
-
332
- if ( map == null ) {
333
- return null ;
322
+ * @param context The Context of the XQuery to store the Object in
323
+ * @param contextMapName The name of the context map
324
+ * @param o The Object to store
325
+ * @param <T> the type of the object being stored
326
+ *
327
+ * @return A unique ID representing the Object
328
+ */
329
+ public static < T > long storeObjectInContextMap (final XQueryContext context , final String contextMapName , final T o ) {
330
+ return modifyContextMap ( context , contextMapName , contextMap -> {
331
+ // get an id for the map
332
+ long uid = 0 ;
333
+ while ( uid == 0 || contextMap . keySet (). contains ( uid ) ) {
334
+ uid = getUID () ;
334
335
}
335
336
336
- // get the connection
337
- return map .get (objectUID );
338
- }
337
+ // place the object in the map
338
+ contextMap .put (uid , o );
339
+
340
+ return uid ;
341
+ });
339
342
}
340
-
341
- public static <T > void modifyContextMap (XQueryContext context , String contextMapName , ContextMapModifier <T > modifier ) {
342
- try (final ManagedLock <ReadWriteLock > writeLock = ManagedLock .acquire (contextMapLocks .getLock (contextMapName ), LockMode .WRITE_LOCK )) {
343
+
344
+ /**
345
+ * Retrieves a previously stored Object from the Context of an XQuery.
346
+ *
347
+ * @param context The Context of the XQuery containing the Object
348
+ * @param contextMapName The name of the context map
349
+ * @param objectUID The UID of the Object to retrieve from the Context of the XQuery
350
+ *
351
+ * @param <T> the type of the object being retrieved
352
+ *
353
+ * @return the object stored in the context or null
354
+ */
355
+ public static @ Nullable <T > T retrieveObjectFromContextMap (final XQueryContext context , final String contextMapName , final long objectUID ) {
356
+ return readContextMap (context , contextMapName , contextMap -> {
357
+ // get the object
358
+ return (T ) contextMap .get (objectUID );
359
+ });
360
+ }
361
+
362
+ /**
363
+ * Removes a previously stored Object from the Context of an XQuery.
364
+ *
365
+ * @param context The Context of the XQuery containing the Object
366
+ * @param contextMapName The name of the context map
367
+ * @param objectUID The UID of the Object to remove from the Context of the XQuery
368
+ *
369
+ * @param <T> the type of the object being removed
370
+ *
371
+ * @return the object that was removed from the context or null if there was no object for the UID
372
+ */
373
+ public static @ Nullable <T > T removeObjectFromContextMap (final XQueryContext context , final String contextMapName , final long objectUID ) {
374
+ return modifyContextMap (context , contextMapName , contextMap -> {
375
+ // get the object
376
+ return (T ) contextMap .remove (objectUID );
377
+ });
378
+ }
379
+
380
+ /**
381
+ * Modify a context map.
382
+ *
383
+ * @param context the XQuery context
384
+ * @param contextMapName The name of the context map
385
+ * @param modifier the modification function
386
+ *
387
+ * @param <T> the type of the value in the map
388
+ * @param <U> the type of the return value of the modifier function
389
+ *
390
+ * @return the result of the modification function
391
+ */
392
+ public static @ Nullable <T , U > U modifyContextMap (final XQueryContext context , final String contextMapName , final ContextMapModifier <T , U > modifier ) {
393
+ try (final ManagedLock <ReadWriteLock > writeLock = ManagedLock .acquire (contextMapLocks .getLock (contextMapName ), LockMode .WRITE_LOCK )) {
343
394
// get the existing map from the context
344
395
Map <Long , T > map = (Map <Long , T >)context .getAttribute (contextMapName );
345
396
if (map == null ) {
@@ -349,12 +400,24 @@ public static <T> void modifyContextMap(XQueryContext context, String contextMap
349
400
}
350
401
351
402
//modify the map
352
- modifier .modify (map );
403
+ return modifier .modify (map );
353
404
}
354
405
}
355
406
407
+ /**
408
+ * Read a context map.
409
+ *
410
+ * @param context the XQuery context
411
+ * @param contextMapName The name of the context map
412
+ * @param reader the reader function
413
+ *
414
+ * @param <T> the type of the value in the map
415
+ * @param <U> the type of the return value of the reader function
416
+ *
417
+ * @return the result of the reader function
418
+ */
356
419
public static <T , U > U readContextMap (final XQueryContext context , final String contextMapName , final ContextMapReader <T , U > reader ) {
357
- try (final ManagedLock <ReadWriteLock > readLock = ManagedLock .acquire (contextMapLocks .getLock (contextMapName ), LockMode .READ_LOCK )) {
420
+ try (final ManagedLock <ReadWriteLock > readLock = ManagedLock .acquire (contextMapLocks .getLock (contextMapName ), LockMode .READ_LOCK )) {
358
421
// get the existing map from the context
359
422
Map <Long , T > map = (Map <Long , T >)context .getAttribute (contextMapName );
360
423
if (map == null ) {
@@ -367,64 +430,37 @@ public static <T, U> U readContextMap(final XQueryContext context, final String
367
430
}
368
431
369
432
@ FunctionalInterface
370
- public interface ContextMapModifier <T > {
371
- void modify (Map <Long , T > map );
433
+ public interface ContextMapModifier <T , U > {
434
+ U modify (final Map <Long , T > map );
372
435
}
373
436
374
437
@ FunctionalInterface
375
- public interface ContextMapReader <T , U > {
376
- U read (Map <Long , T > map );
377
- }
378
-
379
- public static abstract class ContextMapEntryModifier <T > implements ContextMapModifier <T > {
380
-
438
+ public interface ContextMapModifierWithoutResult <T > extends ContextMapModifier <T , Void > {
381
439
@ Override
382
- public void modify (Map <Long , T > map ) {
383
- for (final Entry <Long , T > entry : map .entrySet ()) {
384
- modify (entry );
385
- }
440
+ default Void modify (final Map <Long , T > map ) {
441
+ modifyWithoutResult (map );
442
+ return null ;
386
443
}
387
-
388
- public abstract void modify (Entry <Long , T > entry );
389
- }
390
444
391
- /**
392
- * Stores an Object in the Context of an XQuery.
393
- *
394
- * @param context The Context of the XQuery to store the Object in
395
- * @param contextMapName The name of the context map
396
- * @param o The Object to store
397
- * @param <T> the class of the object being stored
398
- * @return A unique ID representing the Object
399
- */
400
- public static <T > long storeObjectInContextMap (final XQueryContext context , final String contextMapName , final T o ) {
401
-
402
- try (final ManagedLock <ReadWriteLock > writeLock = ManagedLock .acquire (contextMapLocks .getLock (contextMapName ), LockMode .WRITE_LOCK )) {
403
-
404
- // get the existing map from the context
405
- Map <Long , T > map = (Map <Long , T >)context .getAttribute (contextMapName );
445
+ void modifyWithoutResult (final Map <Long , T > map );
446
+ }
406
447
407
- if ( map == null ) {
408
- // if there is no map, create a new one
409
- map = new HashMap <>( );
410
- }
448
+ @ FunctionalInterface
449
+ public interface ContextMapReader < T , U > {
450
+ U read ( final Map < Long , T > map );
451
+ }
411
452
412
- // get an id for the map
413
- long uid = 0 ;
414
- while (uid == 0 || map .keySet ().contains (uid )) {
415
- uid = getUID ();
453
+ public static abstract class ContextMapEntryModifier <T > implements ContextMapModifierWithoutResult <T > {
454
+ @ Override
455
+ public void modifyWithoutResult (final Map <Long , T > map ) {
456
+ for (final Entry <Long , T > entry : map .entrySet ()) {
457
+ modifyEntry (entry );
416
458
}
417
-
418
- // place the object in the map
419
- map .put (uid , o );
420
-
421
- // store the map back in the context
422
- context .setAttribute (contextMapName , map );
423
-
424
- return uid ;
425
459
}
460
+
461
+ public abstract void modifyEntry (final Entry <Long , T > entry );
426
462
}
427
-
463
+
428
464
private static long getUID () {
429
465
final BigInteger bi = new BigInteger (64 , random );
430
466
return bi .longValue ();
0 commit comments