285 * Returns an unmodifiable Collection view of the property values |
288 * Returns an unmodifiable Collection view of the property values |
286 * contained in this provider. |
289 * contained in this provider. |
287 * |
290 * |
288 * @since 1.2 |
291 * @since 1.2 |
289 */ |
292 */ |
|
293 @Override |
290 public Collection<Object> values() { |
294 public Collection<Object> values() { |
291 checkInitialized(); |
295 checkInitialized(); |
292 return Collections.unmodifiableCollection(super.values()); |
296 return Collections.unmodifiableCollection(super.values()); |
293 } |
297 } |
294 |
298 |
295 /** |
299 /** |
296 * Sets the {@code key} property to have the specified |
300 * Sets the {@code key} property to have the specified |
297 * {@code value}. |
301 * {@code value}. |
298 * |
302 * |
299 * <p>First, if there is a security manager, its |
303 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
300 * {@code checkSecurityAccess} method is called with the string |
304 * method is called with the string {@code "putProviderProperty."+name}, |
301 * {@code "putProviderProperty."+name}, where {@code name} is the |
305 * where {@code name} is the provider name, to see if it's ok to set this |
302 * provider name, to see if it's ok to set this provider's property values. |
306 * provider's property values. |
303 * If the default implementation of {@code checkSecurityAccess} |
|
304 * is used (that is, that method is not overriden), then this results in |
|
305 * a call to the security manager's {@code checkPermission} method |
|
306 * with a {@code SecurityPermission("putProviderProperty."+name)} |
|
307 * permission. |
|
308 * |
|
309 * @param key the property key. |
|
310 * |
|
311 * @param value the property value. |
|
312 * |
|
313 * @return the previous value of the specified property |
|
314 * ({@code key}), or null if it did not have one. |
|
315 * |
307 * |
316 * @throws SecurityException |
308 * @throws SecurityException |
317 * if a security manager exists and its {@link |
309 * if a security manager exists and its {@link |
318 * java.lang.SecurityManager#checkSecurityAccess} method |
310 * java.lang.SecurityManager#checkSecurityAccess} method |
319 * denies access to set property values. |
311 * denies access to set property values. |
320 * |
312 * |
321 * @since 1.2 |
313 * @since 1.2 |
322 */ |
314 */ |
|
315 @Override |
323 public synchronized Object put(Object key, Object value) { |
316 public synchronized Object put(Object key, Object value) { |
324 check("putProviderProperty."+name); |
317 check("putProviderProperty."+name); |
325 if (debug != null) { |
318 if (debug != null) { |
326 debug.println("Set " + name + " provider property [" + |
319 debug.println("Set " + name + " provider property [" + |
327 key + "/" + value +"]"); |
320 key + "/" + value +"]"); |
328 } |
321 } |
329 return implPut(key, value); |
322 return implPut(key, value); |
330 } |
323 } |
331 |
324 |
332 /** |
325 /** |
|
326 * If the specified key is not already associated with a value (or is mapped |
|
327 * to {@code null}) associates it with the given value and returns |
|
328 * {@code null}, else returns the current value. |
|
329 * |
|
330 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
331 * method is called with the string {@code "putProviderProperty."+name}, |
|
332 * where {@code name} is the provider name, to see if it's ok to set this |
|
333 * provider's property values. |
|
334 * |
|
335 * @throws SecurityException |
|
336 * if a security manager exists and its {@link |
|
337 * java.lang.SecurityManager#checkSecurityAccess} method |
|
338 * denies access to set property values. |
|
339 */ |
|
340 @Override |
|
341 public synchronized Object putIfAbsent(Object key, Object value) { |
|
342 check("putProviderProperty."+name); |
|
343 if (debug != null) { |
|
344 debug.println("Set " + name + " provider property [" + |
|
345 key + "/" + value +"]"); |
|
346 } |
|
347 return implPutIfAbsent(key, value); |
|
348 } |
|
349 |
|
350 /** |
333 * Removes the {@code key} property (and its corresponding |
351 * Removes the {@code key} property (and its corresponding |
334 * {@code value}). |
352 * {@code value}). |
335 * |
353 * |
336 * <p>First, if there is a security manager, its |
354 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
337 * {@code checkSecurityAccess} method is called with the string |
355 * method is called with the string {@code "removeProviderProperty."+name}, |
338 * {@code "removeProviderProperty."+name}, where {@code name} is |
356 * where {@code name} is the provider name, to see if it's ok to remove this |
339 * the provider name, to see if it's ok to remove this provider's |
357 * provider's properties. |
340 * properties. If the default implementation of |
|
341 * {@code checkSecurityAccess} is used (that is, that method is not |
|
342 * overriden), then this results in a call to the security manager's |
|
343 * {@code checkPermission} method with a |
|
344 * {@code SecurityPermission("removeProviderProperty."+name)} |
|
345 * permission. |
|
346 * |
|
347 * @param key the key for the property to be removed. |
|
348 * |
|
349 * @return the value to which the key had been mapped, |
|
350 * or null if the key did not have a mapping. |
|
351 * |
358 * |
352 * @throws SecurityException |
359 * @throws SecurityException |
353 * if a security manager exists and its {@link |
360 * if a security manager exists and its {@link |
354 * java.lang.SecurityManager#checkSecurityAccess} method |
361 * java.lang.SecurityManager#checkSecurityAccess} method |
355 * denies access to remove this provider's properties. |
362 * denies access to remove this provider's properties. |
356 * |
363 * |
357 * @since 1.2 |
364 * @since 1.2 |
358 */ |
365 */ |
|
366 @Override |
359 public synchronized Object remove(Object key) { |
367 public synchronized Object remove(Object key) { |
360 check("removeProviderProperty."+name); |
368 check("removeProviderProperty."+name); |
361 if (debug != null) { |
369 if (debug != null) { |
362 debug.println("Remove " + name + " provider property " + key); |
370 debug.println("Remove " + name + " provider property " + key); |
363 } |
371 } |
364 return implRemove(key); |
372 return implRemove(key); |
365 } |
373 } |
366 |
374 |
|
375 /** |
|
376 * Removes the entry for the specified key only if it is currently |
|
377 * mapped to the specified value. |
|
378 * |
|
379 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
380 * method is called with the string {@code "removeProviderProperty."+name}, |
|
381 * where {@code name} is the provider name, to see if it's ok to remove this |
|
382 * provider's properties. |
|
383 * |
|
384 * @throws SecurityException |
|
385 * if a security manager exists and its {@link |
|
386 * java.lang.SecurityManager#checkSecurityAccess} method |
|
387 * denies access to remove this provider's properties. |
|
388 */ |
|
389 @Override |
|
390 public synchronized boolean remove(Object key, Object value) { |
|
391 check("removeProviderProperty."+name); |
|
392 if (debug != null) { |
|
393 debug.println("Remove " + name + " provider property " + key); |
|
394 } |
|
395 return implRemove(key, value); |
|
396 } |
|
397 |
|
398 /** |
|
399 * Replaces the entry for the specified key only if currently |
|
400 * mapped to the specified value. |
|
401 * |
|
402 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
403 * method is called with the string {@code "putProviderProperty."+name}, |
|
404 * where {@code name} is the provider name, to see if it's ok to set this |
|
405 * provider's property values. |
|
406 * |
|
407 * @throws SecurityException |
|
408 * if a security manager exists and its {@link |
|
409 * java.lang.SecurityManager#checkSecurityAccess} method |
|
410 * denies access to set property values. |
|
411 */ |
|
412 @Override |
|
413 public synchronized boolean replace(Object key, Object oldValue, |
|
414 Object newValue) { |
|
415 check("putProviderProperty." + name); |
|
416 |
|
417 if (debug != null) { |
|
418 debug.println("Replace " + name + " provider property " + key); |
|
419 } |
|
420 return implReplace(key, oldValue, newValue); |
|
421 } |
|
422 |
|
423 /** |
|
424 * Replaces the entry for the specified key only if it is |
|
425 * currently mapped to some value. |
|
426 * |
|
427 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
428 * method is called with the string {@code "putProviderProperty."+name}, |
|
429 * where {@code name} is the provider name, to see if it's ok to set this |
|
430 * provider's property values. |
|
431 * |
|
432 * @throws SecurityException |
|
433 * if a security manager exists and its {@link |
|
434 * java.lang.SecurityManager#checkSecurityAccess} method |
|
435 * denies access to set property values. |
|
436 */ |
|
437 @Override |
|
438 public synchronized Object replace(Object key, Object value) { |
|
439 check("putProviderProperty." + name); |
|
440 |
|
441 if (debug != null) { |
|
442 debug.println("Replace " + name + " provider property " + key); |
|
443 } |
|
444 return implReplace(key, value); |
|
445 } |
|
446 |
|
447 /** |
|
448 * Replaces each entry's value with the result of invoking the given |
|
449 * function on that entry, in the order entries are returned by an entry |
|
450 * set iterator, until all entries have been processed or the function |
|
451 * throws an exception. |
|
452 * |
|
453 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
454 * method is called with the string {@code "putProviderProperty."+name}, |
|
455 * where {@code name} is the provider name, to see if it's ok to set this |
|
456 * provider's property values. |
|
457 * |
|
458 * @throws SecurityException |
|
459 * if a security manager exists and its {@link |
|
460 * java.lang.SecurityManager#checkSecurityAccess} method |
|
461 * denies access to set property values. |
|
462 */ |
|
463 @Override |
|
464 public synchronized void replaceAll(BiFunction<? super Object, ? super Object, ? extends Object> function) { |
|
465 check("putProviderProperty." + name); |
|
466 |
|
467 if (debug != null) { |
|
468 debug.println("ReplaceAll " + name + " provider property "); |
|
469 } |
|
470 implReplaceAll(function); |
|
471 } |
|
472 |
|
473 /** |
|
474 * Attempts to compute a mapping for the specified key and its |
|
475 * current mapped value (or {@code null} if there is no current |
|
476 * mapping). |
|
477 * |
|
478 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
479 * method is called with the strings {@code "putProviderProperty."+name} |
|
480 * and {@code "removeProviderProperty."+name}, where {@code name} is the |
|
481 * provider name, to see if it's ok to set this provider's property values |
|
482 * and remove this provider's properties. |
|
483 * |
|
484 * @throws SecurityException |
|
485 * if a security manager exists and its {@link |
|
486 * java.lang.SecurityManager#checkSecurityAccess} method |
|
487 * denies access to set property values or remove properties. |
|
488 */ |
|
489 @Override |
|
490 public synchronized Object compute(Object key, |
|
491 BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
492 check("putProviderProperty." + name); |
|
493 check("removeProviderProperty" + name); |
|
494 |
|
495 if (debug != null) { |
|
496 debug.println("Compute " + name + " provider property " + key); |
|
497 } |
|
498 return implCompute(key, remappingFunction); |
|
499 } |
|
500 |
|
501 /** |
|
502 * If the specified key is not already associated with a value (or |
|
503 * is mapped to {@code null}), attempts to compute its value using |
|
504 * the given mapping function and enters it into this map unless |
|
505 * {@code null}. |
|
506 * |
|
507 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
508 * method is called with the strings {@code "putProviderProperty."+name} |
|
509 * and {@code "removeProviderProperty."+name}, where {@code name} is the |
|
510 * provider name, to see if it's ok to set this provider's property values |
|
511 * and remove this provider's properties. |
|
512 * |
|
513 * @throws SecurityException |
|
514 * if a security manager exists and its {@link |
|
515 * java.lang.SecurityManager#checkSecurityAccess} method |
|
516 * denies access to set property values and remove properties. |
|
517 */ |
|
518 @Override |
|
519 public synchronized Object computeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) { |
|
520 check("putProviderProperty." + name); |
|
521 check("removeProviderProperty" + name); |
|
522 |
|
523 if (debug != null) { |
|
524 debug.println("ComputeIfAbsent " + name + " provider property " + |
|
525 key); |
|
526 } |
|
527 return implComputeIfAbsent(key, mappingFunction); |
|
528 } |
|
529 |
|
530 /** |
|
531 * If the value for the specified key is present and non-null, attempts to |
|
532 * compute a new mapping given the key and its current mapped value. |
|
533 * |
|
534 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
535 * method is called with the strings {@code "putProviderProperty."+name} |
|
536 * and {@code "removeProviderProperty."+name}, where {@code name} is the |
|
537 * provider name, to see if it's ok to set this provider's property values |
|
538 * and remove this provider's properties. |
|
539 * |
|
540 * @throws SecurityException |
|
541 * if a security manager exists and its {@link |
|
542 * java.lang.SecurityManager#checkSecurityAccess} method |
|
543 * denies access to set property values or remove properties. |
|
544 */ |
|
545 @Override |
|
546 public synchronized Object computeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
547 check("putProviderProperty." + name); |
|
548 check("removeProviderProperty" + name); |
|
549 |
|
550 if (debug != null) { |
|
551 debug.println("ComputeIfPresent " + name + " provider property " + |
|
552 key); |
|
553 } |
|
554 return implComputeIfPresent(key, remappingFunction); |
|
555 } |
|
556 |
|
557 /** |
|
558 * If the specified key is not already associated with a value or is |
|
559 * associated with null, associates it with the given value. Otherwise, |
|
560 * replaces the value with the results of the given remapping function, |
|
561 * or removes if the result is null. This method may be of use when |
|
562 * combining multiple mapped values for a key. |
|
563 * |
|
564 * <p>If a security manager is enabled, its {@code checkSecurityAccess} |
|
565 * method is called with the strings {@code "putProviderProperty."+name} |
|
566 * and {@code "removeProviderProperty."+name}, where {@code name} is the |
|
567 * provider name, to see if it's ok to set this provider's property values |
|
568 * and remove this provider's properties. |
|
569 * |
|
570 * @throws SecurityException |
|
571 * if a security manager exists and its {@link |
|
572 * java.lang.SecurityManager#checkSecurityAccess} method |
|
573 * denies access to set property values or remove properties. |
|
574 */ |
|
575 @Override |
|
576 public synchronized Object merge(Object key, Object value, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
577 check("putProviderProperty." + name); |
|
578 check("removeProviderProperty" + name); |
|
579 |
|
580 if (debug != null) { |
|
581 debug.println("Merge " + name + " provider property " + key); |
|
582 } |
|
583 return implMerge(key, value, remappingFunction); |
|
584 } |
|
585 |
367 // let javadoc show doc from superclass |
586 // let javadoc show doc from superclass |
|
587 @Override |
368 public Object get(Object key) { |
588 public Object get(Object key) { |
369 checkInitialized(); |
589 checkInitialized(); |
370 return super.get(key); |
590 return super.get(key); |
371 } |
591 } |
372 |
592 |
|
593 @Override |
|
594 public synchronized Object getOrDefault(Object key, Object defaultValue) { |
|
595 checkInitialized(); |
|
596 return super.getOrDefault(key, defaultValue); |
|
597 } |
|
598 |
|
599 @Override |
|
600 public synchronized void forEach(BiConsumer<? super Object, ? super Object> action) { |
|
601 checkInitialized(); |
|
602 super.forEach(action); |
|
603 } |
|
604 |
373 // let javadoc show doc from superclass |
605 // let javadoc show doc from superclass |
|
606 @Override |
374 public Enumeration<Object> keys() { |
607 public Enumeration<Object> keys() { |
375 checkInitialized(); |
608 checkInitialized(); |
376 return super.keys(); |
609 return super.keys(); |
377 } |
610 } |
378 |
611 |
379 // let javadoc show doc from superclass |
612 // let javadoc show doc from superclass |
|
613 @Override |
380 public Enumeration<Object> elements() { |
614 public Enumeration<Object> elements() { |
381 checkInitialized(); |
615 checkInitialized(); |
382 return super.elements(); |
616 return super.elements(); |
383 } |
617 } |
384 |
618 |
457 } |
704 } |
458 } |
705 } |
459 |
706 |
460 private Object implRemove(Object key) { |
707 private Object implRemove(Object key) { |
461 if (key instanceof String) { |
708 if (key instanceof String) { |
462 String keyString = (String)key; |
709 if (!checkLegacy(key)) { |
463 if (keyString.startsWith("Provider.")) { |
|
464 return null; |
710 return null; |
465 } |
711 } |
466 legacyChanged = true; |
712 legacyStrings.remove((String)key); |
467 if (legacyStrings == null) { |
|
468 legacyStrings = new LinkedHashMap<String,String>(); |
|
469 } |
|
470 legacyStrings.remove(keyString); |
|
471 } |
713 } |
472 return super.remove(key); |
714 return super.remove(key); |
|
715 } |
|
716 |
|
717 private boolean implRemove(Object key, Object value) { |
|
718 if (key instanceof String && value instanceof String) { |
|
719 if (!checkLegacy(key)) { |
|
720 return false; |
|
721 } |
|
722 legacyStrings.remove((String)key, value); |
|
723 } |
|
724 return super.remove(key, value); |
|
725 } |
|
726 |
|
727 private boolean implReplace(Object key, Object oldValue, Object newValue) { |
|
728 if ((key instanceof String) && (oldValue instanceof String) && |
|
729 (newValue instanceof String)) { |
|
730 if (!checkLegacy(key)) { |
|
731 return false; |
|
732 } |
|
733 legacyStrings.replace((String)key, (String)oldValue, |
|
734 (String)newValue); |
|
735 } |
|
736 return super.replace(key, oldValue, newValue); |
|
737 } |
|
738 |
|
739 private Object implReplace(Object key, Object value) { |
|
740 if ((key instanceof String) && (value instanceof String)) { |
|
741 if (!checkLegacy(key)) { |
|
742 return null; |
|
743 } |
|
744 legacyStrings.replace((String)key, (String)value); |
|
745 } |
|
746 return super.replace(key, value); |
|
747 } |
|
748 |
|
749 private void implReplaceAll(BiFunction<? super Object, ? super Object, ? extends Object> function) { |
|
750 legacyChanged = true; |
|
751 if (legacyStrings == null) { |
|
752 legacyStrings = new LinkedHashMap<String,String>(); |
|
753 } else { |
|
754 legacyStrings.replaceAll((BiFunction<? super String, ? super String, ? extends String>) function); |
|
755 } |
|
756 super.replaceAll(function); |
|
757 } |
|
758 |
|
759 |
|
760 private Object implMerge(Object key, Object value, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
761 if ((key instanceof String) && (value instanceof String)) { |
|
762 if (!checkLegacy(key)) { |
|
763 return null; |
|
764 } |
|
765 legacyStrings.merge((String)key, (String)value, |
|
766 (BiFunction<? super String, ? super String, ? extends String>) remappingFunction); |
|
767 } |
|
768 return super.merge(key, value, remappingFunction); |
|
769 } |
|
770 |
|
771 private Object implCompute(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
772 if (key instanceof String) { |
|
773 if (!checkLegacy(key)) { |
|
774 return null; |
|
775 } |
|
776 legacyStrings.computeIfAbsent((String) key, |
|
777 (Function<? super String, ? extends String>) remappingFunction); |
|
778 } |
|
779 return super.compute(key, remappingFunction); |
|
780 } |
|
781 |
|
782 private Object implComputeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) { |
|
783 if (key instanceof String) { |
|
784 if (!checkLegacy(key)) { |
|
785 return null; |
|
786 } |
|
787 legacyStrings.computeIfAbsent((String) key, |
|
788 (Function<? super String, ? extends String>) mappingFunction); |
|
789 } |
|
790 return super.computeIfAbsent(key, mappingFunction); |
|
791 } |
|
792 |
|
793 private Object implComputeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { |
|
794 if (key instanceof String) { |
|
795 if (!checkLegacy(key)) { |
|
796 return null; |
|
797 } |
|
798 legacyStrings.computeIfPresent((String) key, |
|
799 (BiFunction<? super String, ? super String, ? extends String>) remappingFunction); |
|
800 } |
|
801 return super.computeIfPresent(key, remappingFunction); |
473 } |
802 } |
474 |
803 |
475 private Object implPut(Object key, Object value) { |
804 private Object implPut(Object key, Object value) { |
476 if ((key instanceof String) && (value instanceof String)) { |
805 if ((key instanceof String) && (value instanceof String)) { |
477 String keyString = (String)key; |
806 if (!checkLegacy(key)) { |
478 if (keyString.startsWith("Provider.")) { |
|
479 return null; |
807 return null; |
480 } |
808 } |
481 legacyChanged = true; |
809 legacyStrings.put((String)key, (String)value); |
482 if (legacyStrings == null) { |
|
483 legacyStrings = new LinkedHashMap<String,String>(); |
|
484 } |
|
485 legacyStrings.put(keyString, (String)value); |
|
486 } |
810 } |
487 return super.put(key, value); |
811 return super.put(key, value); |
|
812 } |
|
813 |
|
814 private Object implPutIfAbsent(Object key, Object value) { |
|
815 if ((key instanceof String) && (value instanceof String)) { |
|
816 if (!checkLegacy(key)) { |
|
817 return null; |
|
818 } |
|
819 legacyStrings.putIfAbsent((String)key, (String)value); |
|
820 } |
|
821 return super.putIfAbsent(key, value); |
488 } |
822 } |
489 |
823 |
490 private void implClear() { |
824 private void implClear() { |
491 if (legacyStrings != null) { |
825 if (legacyStrings != null) { |
492 legacyStrings.clear(); |
826 legacyStrings.clear(); |