@@ -453,7 +453,7 @@ public synchronized Set<Map.Entry<Object,Object>> entrySet() {
453453 * @since 1.2
454454 */
455455 @ Override
456- public Set <Object > keySet () {
456+ public synchronized Set <Object > keySet () {
457457 checkInitialized ();
458458 return Collections .unmodifiableSet (super .keySet ());
459459 }
@@ -465,7 +465,7 @@ public Set<Object> keySet() {
465465 * @since 1.2
466466 */
467467 @ Override
468- public Collection <Object > values () {
468+ public synchronized Collection <Object > values () {
469469 checkInitialized ();
470470 return Collections .unmodifiableCollection (super .values ());
471471 }
@@ -696,7 +696,8 @@ public synchronized Enumeration<Object> elements() {
696696 }
697697
698698 // let javadoc show doc from superclass
699- public String getProperty (String key ) {
699+ @ Override
700+ public synchronized String getProperty (String key ) {
700701 checkInitialized ();
701702 return super .getProperty (key );
702703 }
@@ -763,8 +764,9 @@ private record MappingInfo(Service svc, ServiceKey algKey,
763764
764765 // Auxiliary set to determine if a service on the services map was added
765766 // with the Legacy API. The absence of a service key on this set is an
766- // indication that the service was either not added or added with the
767- // Current API. Only algorithm service keys are added to this set.
767+ // indication that the service was either not added to the services
768+ // map (any API) or was added with the Current API. Only algorithm
769+ // service keys are added to this set.
768770 private final Set <ServiceKey > legacySvcKeys ;
769771
770772 // Auxiliary map to keep track of the Properties map entries that
@@ -779,6 +781,9 @@ private record MappingInfo(Service svc, ServiceKey algKey,
779781 // added to this map.
780782 private final Map <ServiceKey , Map <UString , String >> serviceAttrProps ;
781783
784+ /*
785+ * Default constructor. Creates an empty services map for a Provider.
786+ */
782787 ServicesMap () {
783788 allowedSet = new AtomicReference <>();
784789 notAllowedSet = new AtomicReference <>();
@@ -1039,9 +1044,10 @@ private void resolveKeyConflict(ServiceKey key,
10391044 opSucceeded = removeAliasLegacy (miByKey .algKey , key ,
10401045 keysToBeKept );
10411046 } else {
1042- // The service was added with the Current API. Overwrite
1043- // the alias entry on the services map without modifying
1044- // the service that is currently using it.
1047+ // The service was added with the Current API. Once we
1048+ // return to putService, the alias entry on the services
1049+ // map will be overwritten without modifying the service
1050+ // that is currently associated with.
10451051
10461052 // Remove any Properties map key entry because, if no
10471053 // longer used as an alias, the entry would not be
@@ -1179,7 +1185,7 @@ boolean putClassNameLegacy(ServiceKey key, String className,
11791185 String canonicalPropKey = propKey ;
11801186 if (oldMi .svc != null ) {
11811187 // The service exists. Get its Properties map entry. Note:
1182- // Services added through an alias or an attribute may don't
1188+ // Services added through an alias or an attribute may not
11831189 // have one.
11841190 String oldPropKey = serviceProps .get (oldMi .algKey );
11851191 if (oldMi .algKey .equals (key )) {
@@ -1445,6 +1451,8 @@ private interface ServiceUpdateCallback {
14451451 * The updated version of the service is put on the services map.
14461452 * Algorithm and alias based entries pointing to the old version of the
14471453 * service are overwritten.
1454+ *
1455+ * This method is invoked from the Legacy API only.
14481456 */
14491457 private boolean updateSvc (ServiceKey key ,
14501458 ServiceUpdateCallback updateCb ) {
@@ -1618,9 +1626,9 @@ private void implClear() {
16181626 }
16191627
16201628 private Object implRemove (Object key ) {
1621- Object oldValue = super .get (key );
1622- return doLegacyOp (servicesMap , key , oldValue , null , OPType .REMOVE ) ==
1623- PropertiesMapAction .UPDATE ? super .remove (key ) : oldValue ;
1629+ Object value = super .get (key );
1630+ return doLegacyOp (servicesMap , key , value , null , OPType .REMOVE ) ==
1631+ PropertiesMapAction .UPDATE ? super .remove (key ) : value ;
16241632 }
16251633
16261634 private boolean implRemove (Object key , Object value ) {
@@ -1736,7 +1744,6 @@ private Object implPut(ServicesMap servicesMap, Object key, Object value) {
17361744 PropertiesMapAction .UPDATE ? super .put (key , value ) : oldValue ;
17371745 }
17381746
1739- // used as key in the serviceMap and legacyMap HashMaps
17401747 private static final class ServiceKey {
17411748 private final String type ;
17421749 private final String algorithm ;
@@ -2188,16 +2195,19 @@ public static class Service {
21882195 private Map <UString , String > attributes ;
21892196 private final EngineDescription engineDescription ;
21902197
2191- // For services added to a ServicesMap, their algorithm service key.
2192- // This value derives from the algorithm field. For services (still)
2193- // not added to a ServicesMap, value is null.
2198+ // This value is the algorithm service key when the service is added to
2199+ // the ServicesMap. Value is null otherwise.
21942200 private ServiceKey algKey ;
21952201
2196- // For services added to a ServicesMap, this is a map from alias service
2197- // keys to alias string values. Empty map if no aliases. While map
2198- // entries derive from the aliases field, keys are not repeated
2199- // (case-insensitive comparison) and not equal to the algorithm. For
2200- // services (still) not added to a ServicesMap, value is an empty map.
2202+ // This map is empty if the service has no aliases or has not been
2203+ // registered in the ServicesMap. When the service has aliases and is
2204+ // registered in the ServicesMap, this information maps the alias
2205+ // ServiceKey to the string alias as originally defined in the service.
2206+ //
2207+ // The purpose for this map is both to keep references to alias
2208+ // ServiceKeys for reuse (i.e. we don't have to construct them from
2209+ // strings multiple times) and to facilitate alias string updates with
2210+ // different casing from the Legacy API.
22012211 private Map <ServiceKey , String > aliasKeys ;
22022212
22032213 // Cache with the Providers filter decision for this service. Value is
@@ -2239,7 +2249,7 @@ public static class Service {
22392249 private static final Class <?>[] CLASS0 = new Class <?>[0 ];
22402250
22412251 /*
2242- * Constructor used from the ServicesMap Legacy API.
2252+ * Constructor used by the ServicesMap Legacy API.
22432253 */
22442254 private Service (Provider provider , ServiceKey algKey ) {
22452255 assert algKey .algorithm .intern () == algKey .algorithm :
@@ -2255,7 +2265,7 @@ private Service(Provider provider, ServiceKey algKey) {
22552265 }
22562266
22572267 /*
2258- * Copy constructor used from the ServicesMap Legacy API for the
2268+ * Copy constructor used by the ServicesMap Legacy API for the
22592269 * copy-on-write strategy. This constructor is invoked after every
22602270 * update to a service on the ServicesMap.
22612271 */
@@ -2279,7 +2289,6 @@ private Service(Service svc) {
22792289 attributes = new HashMap <>(svc .attributes );
22802290 }
22812291 isAllowed = svc .isAllowed ;
2282- registered = false ;
22832292 if (svc .cipherTransformsAllowed != null ) {
22842293 cipherTransformsAllowed = new ConcurrentHashMap <>(
22852294 svc .cipherTransformsAllowed );
@@ -2296,7 +2305,7 @@ private Service(Service svc) {
22962305 }
22972306
22982307 /*
2299- * Methods used from the ServicesMap Legacy API to update a service.
2308+ * Methods used by the ServicesMap Legacy API to update a service.
23002309 */
23012310
23022311 private void addAliasKey (ServiceKey aliasKey ) {
@@ -2375,37 +2384,14 @@ public Service(Provider provider, String type, String algorithm,
23752384 if (attributes == null ) {
23762385 this .attributes = Collections .emptyMap ();
23772386 } else {
2378- this .attributes = new HashMap <>();
2387+ this .attributes = new HashMap <>(attributes . size (), 1.0f );
23792388 for (Map .Entry <String , String > entry : attributes .entrySet ()) {
23802389 this .attributes .put (new UString (entry .getKey ()),
23812390 entry .getValue ());
23822391 }
23832392 }
23842393 }
23852394
2386- /*
2387- * When a Service is added to a ServicesMap with the Current API,
2388- * service and alias keys must be generated. Currently used by
2389- * ServicesMap::putService. Legacy API methods do not need to call:
2390- * they generated the algorithm key at construction time and alias
2391- * keys with Service::addAliasKey.
2392- */
2393- private void generateServiceKeys () {
2394- if (algKey == null ) {
2395- assert (Object )aliasKeys == Collections .emptyMap () :
2396- "aliasKeys expected to be the empty map." ;
2397- algKey = new ServiceKey (type , algorithm , true );
2398- aliasKeys = new HashMap <>(aliases .size ());
2399- for (String alias : aliases ) {
2400- ServiceKey aliasKey = new ServiceKey (type , alias , true );
2401- if (!aliasKey .equals (algKey )) {
2402- aliasKeys .put (aliasKey , alias );
2403- }
2404- }
2405- aliasKeys = Collections .unmodifiableMap (aliasKeys );
2406- }
2407- }
2408-
24092395 /*
24102396 * Returns whether the service is allowed or not according to the
24112397 * Providers filter. This decision is usually made when a service
@@ -2673,6 +2659,31 @@ public Object newInstance(Object constructorParameter)
26732659 }
26742660 }
26752661
2662+ /*
2663+ * When a Service is added to a ServicesMap with the Current API,
2664+ * service and alias keys must be generated. Currently used by
2665+ * ServicesMap::putService. Legacy API methods do not need to call:
2666+ * they generated the algorithm key at construction time and alias
2667+ * keys with Service::addAliasKey.
2668+ */
2669+ private void generateServiceKeys () {
2670+ if (algKey == null ) {
2671+ assert (Object )aliasKeys == Collections .emptyMap () :
2672+ "aliasKeys expected to be the empty map." ;
2673+ algKey = new ServiceKey (type , algorithm , true );
2674+ if (!aliases .isEmpty ()) {
2675+ aliasKeys = new HashMap <>(aliases .size ());
2676+ for (String alias : aliases ) {
2677+ ServiceKey aliasKey = new ServiceKey (type , alias , true );
2678+ if (!aliasKey .equals (algKey )) {
2679+ aliasKeys .put (aliasKey , alias );
2680+ }
2681+ }
2682+ aliasKeys = Collections .unmodifiableMap (aliasKeys );
2683+ }
2684+ }
2685+ }
2686+
26762687 private Object newInstanceOf () throws Exception {
26772688 Constructor <?> con = getDefaultConstructor ();
26782689 return con .newInstance (EMPTY );
0 commit comments