1414import java .time .Instant ;
1515import java .time .temporal .ChronoField ;
1616import java .time .temporal .TemporalAccessor ;
17- import java .util .*;
17+ import java .util .HashMap ;
18+ import java .util .HashSet ;
19+ import java .util .Map ;
20+ import java .util .Objects ;
21+ import java .util .Optional ;
22+ import java .util .Set ;
1823
1924/**
2025 * Represents a general context of data targeting an item of type {@code Q}. Contexts are used to add arbitrary
@@ -40,7 +45,7 @@ public abstract class AbstractContext implements Serializable {
4045 /**
4146 * The data map containing all values.
4247 */
43- private final Map <Class <?>, Map < Object , Object > > data = new HashMap <>();
48+ final Map <Object , Object > data = new HashMap <>();
4449
4550 /**
4651 * Private constructor, used by {@link AbstractContextBuilder}.
@@ -49,59 +54,45 @@ public abstract class AbstractContext implements Serializable {
4954 */
5055 @ SuppressWarnings ("rawtypes" )
5156 protected AbstractContext (AbstractContextBuilder <?, ?> builder ) {
52- for (Map .Entry <Class , Map <Object , Object >> en : builder .data .entrySet ()) {
53- Map <Object , Object > presentMap = this .data .get (en .getKey ());
54- if (presentMap == null ) {
55- presentMap = new HashMap <>(en .getValue ());
56- this .data .put (en .getKey (), presentMap );
57- } else {
58- presentMap .putAll (en .getValue ());
59- }
60- }
61- }
57+ data .putAll (builder .data );
58+ }
6259
6360 /**
64- * Get the present keys for a given attribute type.
61+ * Get the present keys of all entries with a given type, checking hereby if assignable .
6562 *
6663 * @param type The attribute type, not null.
67- * @return all present keys of attributes of the (exact) given type, never null.
64+ * @return all present keys of attributes being assignable to the type, never null.
6865 */
6966 public Set <Object > getKeys (Class <?> type ) {
70- Map <Object , Object > values = this .data .get (type );
71- if (values != null ) {
72- return values .keySet ();
67+ Set <Object > keys = new HashSet <>();
68+ for (Map .Entry <Object , Object > val : data .entrySet ()) {
69+ if (type .isAssignableFrom (val .getValue ().getClass ())) {
70+ keys .add (val .getKey ());
71+ }
7372 }
74- return Collections . emptySet () ;
73+ return keys ;
7574 }
7675
7776 /**
78- * Get all currently present attribute types .
77+ * Get the current attribute type .
7978 *
80- * @return all currently present attribute types, never null.
79+ * @return the current attribute type, or null, if no such attribute exists .
8180 */
82- public Set <Class <?>> getTypes () {
83- return this .data .keySet ();
81+ public Class <?> getType (Object key ) {
82+ Object val = this .data .get (key );
83+ return val == null ? null : val .getClass ();
8484 }
8585
8686 /**
8787 * Access an attribute.
8888 *
8989 * @param type the attribute's type, not {@code null}
9090 * @param key the attribute's key, not {@code null}
91+ * @param defaultValue the default value, or {@code null}.
9192 * @return the attribute value, or {@code null}.
9293 */
93- // Type safe cast
94- @ SuppressWarnings ("unchecked" )
95- public <T > T getAny (Object key , Class <T > type , T defaultValue ) {
96- Map <Object , Object > values = this .data .get (type );
97- Object value = null ;
98- if (values != null ) {
99- value = values .get (key );
100- }
101- if (value != null ) {
102- return (T ) value ;
103- }
104- return defaultValue ;
94+ public <T > T get (Object key , Class <T > type , T defaultValue ) {
95+ return (T ) data .getOrDefault (key , defaultValue );
10596 }
10697
10798 /**
@@ -111,18 +102,18 @@ public <T> T getAny(Object key, Class<T> type, T defaultValue) {
111102 * @param key the attribute's key, not {@code null}
112103 * @return the attribute value, or {@code null}.
113104 */
114- public <T > T getAny (Object key , Class <T > type ) {
115- return getAny (key , type , null );
105+ public <T > T get (Object key , Class <T > type ) {
106+ return get (key , type , null );
116107 }
117108
118109 /**
119110 * Access an attribute, hereby using the class name as key.
120111 *
121- * @param type the attribute's type, not {@code null}
122- * @return the attribute value, or {@code null}.
112+ * @param type the type, not {@code null}
113+ * @return the type attribute value, or {@code null}.
123114 */
124- public <T > T get (Class <T > type ) {
125- return getAny (type , type );
115+ public <T > T getTyped (Class <T > type ) {
116+ return get (type , type );
126117 }
127118
128119 /**
@@ -133,8 +124,8 @@ public <T> T get(Class<T> type) {
133124 * @return the attribute's value, or the {@code defaultValue} passed, if no
134125 * such attribute is present.
135126 */
136- public <T > T get (Class <T > type , T defaultValue ) {
137- return Optional .ofNullable (get (type )).orElse (defaultValue );
127+ public <T > T getTyped (Class <T > type , T defaultValue ) {
128+ return Optional .ofNullable (getTyped (type )).orElse (defaultValue );
138129 }
139130
140131
@@ -156,7 +147,7 @@ public Long getLong(Object key) {
156147 * @return the value, or default value.
157148 */
158149 public Long getLong (Object key , Long defaultValue ) {
159- return getAny (key , Long .class , defaultValue );
150+ return get (key , Long .class , defaultValue );
160151 }
161152
162153
@@ -178,7 +169,7 @@ public Float getFloat(Object key) {
178169 * @return the value, or default value.
179170 */
180171 public Float getFloat (Object key , Float defaultValue ) {
181- return getAny (key , Float .class , defaultValue );
172+ return get (key , Float .class , defaultValue );
182173 }
183174
184175 /**
@@ -199,7 +190,7 @@ public Integer getInt(Object key) {
199190 * @return the value, or default value.
200191 */
201192 public Integer getInt (Object key , Integer defaultValue ) {
202- return getAny (key , Integer .class , defaultValue );
193+ return get (key , Integer .class , defaultValue );
203194 }
204195
205196 /**
@@ -220,7 +211,7 @@ public Boolean getBoolean(Object key) {
220211 * @return the value, or default value.
221212 */
222213 public Boolean getBoolean (Object key , Boolean defaultValue ) {
223- return getAny (key , Boolean .class , defaultValue );
214+ return get (key , Boolean .class , defaultValue );
224215 }
225216
226217 /**
@@ -241,7 +232,7 @@ public Double getDouble(Object key) {
241232 * @return the value, or default value.
242233 */
243234 public Double getDouble (Object key , Double defaultValue ) {
244- return getAny (key , Double .class , defaultValue );
235+ return get (key , Double .class , defaultValue );
245236 }
246237
247238 /**
@@ -262,7 +253,7 @@ public String getText(Object key) {
262253 * @return the value, or default value.
263254 */
264255 public String getText (Object key , String defaultValue ) {
265- return getAny (key , String .class , defaultValue );
256+ return get (key , String .class , defaultValue );
266257 }
267258
268259
@@ -284,91 +275,7 @@ public Character getChar(Object key) {
284275 * @return the value, or default value.
285276 */
286277 public Character getChar (Object key , Character defaultValue ) {
287- return getAny (key , Character .class , defaultValue );
288- }
289-
290- /**
291- * Access a Collection attribute.
292- *
293- * @param key the attribute's key, not null.
294- * @return the value, or null.
295- */
296- public Collection <?> getCollection (Object key ) {
297- return getCollection (key , null );
298- }
299-
300- /**
301- * Access a Collection attribute.
302- *
303- * @param key the attribute's key, not null.
304- * @param defaultValue the default value returned, if the attribute is not present.
305- * @return the value, or default value.
306- */
307- public <T > Collection <T > getCollection (Object key , Collection <T > defaultValue ) {
308- return getAny (key , Collection .class , defaultValue );
309- }
310-
311- /**
312- * Access a List attribute.
313- *
314- * @param key the attribute's key, not null.
315- * @return the value, or null.
316- */
317- public List <?> getList (Object key ) {
318- return getList (key , null );
319- }
320-
321- /**
322- * Access a Collection attribute.
323- *
324- * @param key the attribute's key, not null.
325- * @param defaultValue the default value returned, if the attribute is not present.
326- * @return the value, or default value.
327- */
328- public <T > List <T > getList (Object key , List <T > defaultValue ) {
329- return getAny (key , List .class , defaultValue );
330- }
331-
332- /**
333- * Access a Set attribute.
334- *
335- * @param key the attribute's key, not null.
336- * @return the value, or null.
337- */
338- public Set <?> getSet (Object key ) {
339- return getSet (key , null );
340- }
341-
342- /**
343- * Access a Set attribute.
344- *
345- * @param key the attribute's key, not null.
346- * @param defaultValue the default value returned, if the attribute is not present.
347- * @return the value, or default value.
348- */
349- public <T > Set <T > getSet (Object key , Set <T > defaultValue ) {
350- return getAny (key , Set .class , defaultValue );
351- }
352-
353- /**
354- * Access a Map attribute.
355- *
356- * @param key the attribute's key, not null.
357- * @return the value, or null.
358- */
359- public Map <?, ?> getMap (Object key ) {
360- return getMap (key , null );
361- }
362-
363- /**
364- * Access a Map attribute.
365- *
366- * @param key the attribute's key, not null.
367- * @param defaultValue the default value returned, if the attribute is not present.
368- * @return the value, or default value.
369- */
370- public <K , V > Map <K , V > getMap (Object key , Map <K , V > defaultValue ) {
371- return getAny (key , Map .class , defaultValue );
278+ return get (key , Character .class , defaultValue );
372279 }
373280
374281 /**
@@ -381,15 +288,15 @@ public String getProvider() {
381288 }
382289
383290 /**
384- * Get the current target timestamp of the query in UTC milliseconds. If not set it tries to of an
291+ * Get the current target timestamp of the query in UTC milliseconds. If not setTyped it tries to of an
385292 * UTC timestamp from #getTimestamp(). This allows to select historical roundings that were valid in the
386293 * past. Its implementation specific, to what extend historical roundings are available. By default if this
387- * property is not set always current {@link javax.money.MonetaryRounding} instances are provided.
294+ * property is not setTyped always current {@link javax.money.MonetaryRounding} instances are provided.
388295 *
389296 * @return the timestamp in millis, or null.
390297 */
391298 public Long getTimestampMillis () {
392- Long value = getAny (KEY_TIMESTAMP , Long .class , null );
299+ Long value = get (KEY_TIMESTAMP , Long .class , null );
393300 if (Objects .isNull (value )) {
394301 TemporalAccessor acc = getTimestamp ();
395302 if (Objects .nonNull (acc )) {
@@ -400,17 +307,17 @@ public Long getTimestampMillis() {
400307 }
401308
402309 /**
403- * Get the current target timestamp of the query. If not set it tries to of an Instant from
310+ * Get the current target timestamp of the query. If not setTyped it tries to of an Instant from
404311 * #getTimestampMillis(). This allows to select historical roundings that were valid in the
405312 * past. Its implementation specific, to what extend historical roundings are available. By default if this
406- * property is not set always current {@link javax.money.MonetaryRounding} instances are provided.
313+ * property is not setTyped always current {@link javax.money.MonetaryRounding} instances are provided.
407314 *
408315 * @return the current timestamp, or null.
409316 */
410317 public TemporalAccessor getTimestamp () {
411- TemporalAccessor acc = getAny (KEY_TIMESTAMP , TemporalAccessor .class , null );
318+ TemporalAccessor acc = get (KEY_TIMESTAMP , TemporalAccessor .class , null );
412319 if (Objects .isNull (acc )) {
413- Long value = getAny (KEY_TIMESTAMP , Long .class , null );
320+ Long value = get (KEY_TIMESTAMP , Long .class , null );
414321 if (Objects .nonNull (value )) {
415322 acc = Instant .ofEpochMilli (value );
416323 }
@@ -419,9 +326,9 @@ public TemporalAccessor getTimestamp() {
419326 }
420327
421328 /**
422- * Checks if the current instance has no attributes set . This is often the cases, when used in default cases.
329+ * Checks if the current instance has no attributes setTyped . This is often the cases, when used in default cases.
423330 *
424- * @return true, if no attributes are set .
331+ * @return true, if no attributes are setTyped .
425332 */
426333 public boolean isEmpty () {
427334 return this .data .isEmpty ();
@@ -438,13 +345,19 @@ public int hashCode() {
438345 }
439346
440347 /**
441- * Access all the values present.
348+ * Access all the key/ values present, filtered by the values that are assignable to the given type .
442349 *
443- * @param type the type used .
444- * @return
350+ * @param type the value type, not null .
351+ * @return return all key/values with values assignable to a given value type.
445352 */
446- public Map <Object , Object > getValues (Class <?> type ) {
447- return this .data .get (type );
353+ public <T > Map <Object , T > getValues (Class <T > type ) {
354+ Map <Object , T > result = new HashMap <>();
355+ for (Map .Entry <Object , Object > en : data .entrySet ()) {
356+ if (type .isAssignableFrom (en .getValue ().getClass ())) {
357+ result .put (en .getKey (), type .cast (en .getValue ()));
358+ }
359+ }
360+ return result ;
448361 }
449362
450363 /*
@@ -471,28 +384,6 @@ public boolean equals(Object obj) {
471384 */
472385 @ Override
473386 public String toString () {
474- StringBuilder attrsBuilder = new StringBuilder ();
475- for (Map .Entry <Class <?>, Map <Object , Object >> en : this .data .entrySet ()) {
476- Map <Object , Object > sortedMap = new TreeMap <>((o1 , o2 ) -> o1 .toString ().compareTo (o2 .toString ()));
477- sortedMap .putAll (en .getValue ());
478- for (Map .Entry <Object , Object > entry : sortedMap .entrySet ()) {
479- Object key = entry .getKey ();
480- attrsBuilder .append (" " );
481- if (key .getClass () == Class .class ) {
482- attrsBuilder .append (((Class <?>) key ).getName ());
483- } else {
484- attrsBuilder .append (key );
485- }
486- attrsBuilder .append ('[' );
487- if (en .getKey ().getName ().startsWith ("java.lang." )) {
488- attrsBuilder .append (en .getKey ().getName ().substring ("java.lang." .length ()));
489- } else {
490- attrsBuilder .append (en .getKey ().getName ());
491- }
492- attrsBuilder .append ("]=" );
493- attrsBuilder .append (entry .getValue ()).append ('\n' );
494- }
495- }
496- return getClass ().getSimpleName () + " (\n " + attrsBuilder .toString () + ')' ;
387+ return getClass ().getSimpleName () + " (\n " + data + ')' ;
497388 }
498389}
0 commit comments