11/*
2- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
33 *
44 * This program and the accompanying materials are made available under the
55 * terms of the Eclipse Public License v. 2.0, which is available at
2727import java .util .Map ;
2828import java .util .Optional ;
2929import java .util .Set ;
30+ import java .util .concurrent .atomic .AtomicBoolean ;
3031import java .util .function .Function ;
3132import java .util .logging .Logger ;
3233
3940import org .glassfish .jersey .internal .util .ReflectionHelper ;
4041import org .glassfish .jersey .spi .ExternalConfigurationModel ;
4142
43+ /**
44+ * The External Configuration Model that supports {@code System} properties. The properties are listed in a property class
45+ * in a form of {@code public static final String} property name. The {@code String} value of the property name is searched
46+ * among the {@code System} properties. The property scan is performed only when
47+ * {@link CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER} is set to {@code true}.
48+ */
49+ public class SystemPropertiesConfigurationModel implements ExternalConfigurationModel <Void > {
4250
43- class SystemPropertiesConfigurationModel implements ExternalConfigurationModel <Void > {
44-
45- private static final Logger log = Logger .getLogger (SystemPropertiesConfigurationModel .class .getName ());
46- static final List <String > PROPERTY_CLASSES = Arrays .asList (
47- "org.glassfish.jersey.ExternalProperties" ,
48- "org.glassfish.jersey.server.ServerProperties" ,
49- "org.glassfish.jersey.client.ClientProperties" ,
50- "org.glassfish.jersey.servlet.ServletProperties" ,
51- "org.glassfish.jersey.message.MessageProperties" ,
52- "org.glassfish.jersey.apache.connector.ApacheClientProperties" ,
53- "org.glassfish.jersey.helidon.connector.HelidonClientProperties" ,
54- "org.glassfish.jersey.jdk.connector.JdkConnectorProperties" ,
55- "org.glassfish.jersey.jetty.connector.JettyClientProperties" ,
56- "org.glassfish.jersey.netty.connector.NettyClientProperties" ,
57- "org.glassfish.jersey.media.multipart.MultiPartProperties" ,
58- "org.glassfish.jersey.server.oauth1.OAuth1ServerProperties" );
59-
51+ private static final Logger LOGGER = Logger .getLogger (SystemPropertiesConfigurationModel .class .getName ());
6052
6153 private static final Map <Class , Function > converters = new HashMap <>();
54+ private final Map <String , Object > properties = new HashMap <>();
55+ private final AtomicBoolean gotProperties = new AtomicBoolean (false );
56+ private final List <String > propertyClassNames ;
6257 static {
6358 converters .put (String .class , (Function <String , String >) s -> s );
6459 converters .put (Integer .class , (Function <String , Integer >) s -> Integer .valueOf (s ));
60+ converters .put (Long .class , (Function <String , Long >) s -> Long .parseLong (s ));
6561 converters .put (Boolean .class , (Function <String , Boolean >) s -> s .equalsIgnoreCase ("1" )
6662 ? true
6763 : Boolean .parseBoolean (s ));
6864 }
6965
70- private String getSystemProperty (String name ) {
71- return AccessController .doPrivileged (PropertiesHelper .getSystemProperty (name ));
66+ /**
67+ * Create new {@link ExternalConfigurationModel} for properties defined by classes in {@code propertyClassNames} list.
68+ * @param propertyClassNames List of property defining class names.
69+ */
70+ public SystemPropertiesConfigurationModel (List <String > propertyClassNames ) {
71+ this .propertyClassNames = propertyClassNames ;
72+ }
73+
74+ protected List <String > getPropertyClassNames () {
75+ return propertyClassNames ;
7276 }
7377
7478 @ Override
7579 public <T > T as (String name , Class <T > clazz ) {
7680 if (converters .get (clazz ) == null ) {
7781 throw new IllegalArgumentException ("Unsupported class type" );
7882 }
79- return (name != null && clazz != null && isProperty (name ))
83+ return (name != null && clazz != null && hasProperty (name ))
8084 ? clazz .cast (converters .get (clazz ).apply (getSystemProperty (name )))
8185 : null ;
8286 }
83-
84-
85-
8687 @ Override
8788 public <T > Optional <T > getOptionalProperty (String name , Class <T > clazz ) {
8889 return Optional .of (as (name , clazz ));
8990 }
9091
9192 @ Override
9293 public ExternalConfigurationModel mergeProperties (Map <String , Object > inputProperties ) {
94+ inputProperties .forEach ((k , v ) -> properties .put (k , v ));
9395 return this ;
9496 }
9597
@@ -100,11 +102,11 @@ public Void getConfig() {
100102
101103 @ Override
102104 public boolean isProperty (String name ) {
103- return Optional . ofNullable (
104- AccessController . doPrivileged (
105- PropertiesHelper . getSystemProperty ( name )
106- )
107- ). isPresent () ;
105+ String property = getSystemProperty ( name );
106+ return property != null && (
107+ "0" . equals ( property ) || "1" . equals ( property )
108+ || "true" . equalsIgnoreCase ( property ) || "false" . equalsIgnoreCase ( property )
109+ );
108110 }
109111
110112 @ Override
@@ -114,30 +116,29 @@ public RuntimeType getRuntimeType() {
114116
115117 @ Override
116118 public Map <String , Object > getProperties () {
117- final Map <String , Object > result = new HashMap <>();
118-
119119 final Boolean allowSystemPropertiesProvider = as (
120120 CommonProperties .ALLOW_SYSTEM_PROPERTIES_PROVIDER , Boolean .class
121121 );
122122 if (!Boolean .TRUE .equals (allowSystemPropertiesProvider )) {
123- log .finer (LocalizationMessages .WARNING_PROPERTIES ());
124- return result ;
123+ LOGGER .finer (LocalizationMessages .WARNING_PROPERTIES ());
124+ return properties ;
125125 }
126126
127- try {
128- AccessController .doPrivileged (PropertiesHelper .getSystemProperties ())
129- .forEach ((k , v ) -> result .put (String .valueOf (k ), v ));
130- } catch (SecurityException se ) {
131- log .warning (LocalizationMessages .SYSTEM_PROPERTIES_WARNING ());
132- return getExpectedSystemProperties ();
127+ if (gotProperties .compareAndSet (false , true )) {
128+ try {
129+ AccessController .doPrivileged (PropertiesHelper .getSystemProperties ())
130+ .forEach ((k , v ) -> properties .put (String .valueOf (k ), v ));
131+ } catch (SecurityException se ) {
132+ LOGGER .warning (LocalizationMessages .SYSTEM_PROPERTIES_WARNING ());
133+ return getExpectedSystemProperties ();
134+ }
133135 }
134- return result ;
136+ return properties ;
135137 }
136138
137139 private Map <String , Object > getExpectedSystemProperties () {
138140 final Map <String , Object > result = new HashMap <>();
139- mapFieldsToProperties (result , CommonProperties .class );
140- for (String propertyClass : PROPERTY_CLASSES ) {
141+ for (String propertyClass : getPropertyClassNames ()) {
141142 mapFieldsToProperties (result ,
142143 AccessController .doPrivileged (
143144 ReflectionHelper .classForNamePA (propertyClass )
@@ -148,7 +149,7 @@ private Map<String, Object> getExpectedSystemProperties() {
148149 return result ;
149150 }
150151
151- private <T > void mapFieldsToProperties (Map <String , Object > properties , Class <T > clazz ) {
152+ private static <T > void mapFieldsToProperties (Map <String , Object > properties , Class <T > clazz ) {
152153 if (clazz == null ) {
153154 return ;
154155 }
@@ -170,25 +171,29 @@ private <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T>
170171 }
171172 }
172173
173- private String getPropertyNameByField (Field field ) {
174+ private static String getPropertyNameByField (Field field ) {
174175 return AccessController .doPrivileged ((PrivilegedAction <String >) () -> {
175176 try {
176177 return (String ) field .get (null );
177178 } catch (IllegalAccessException e ) {
178- log .warning (e .getLocalizedMessage ());
179+ LOGGER .warning (e .getLocalizedMessage ());
179180 }
180181 return null ;
181182 });
182183 }
183184
185+ private static String getSystemProperty (String name ) {
186+ return AccessController .doPrivileged (PropertiesHelper .getSystemProperty (name ));
187+ }
188+
184189 @ Override
185190 public Object getProperty (String name ) {
186191 return getSystemProperty (name );
187192 }
188193
189194 @ Override
190195 public Collection <String > getPropertyNames () {
191- return PropertiesHelper .getSystemProperties (). run ( ).stringPropertyNames ();
196+ return AccessController . doPrivileged ( PropertiesHelper .getSystemProperties ()).stringPropertyNames ();
192197 }
193198
194199 @ Override
@@ -225,4 +230,9 @@ public Set<Class<?>> getClasses() {
225230 public Set <Object > getInstances () {
226231 return null ;
227232 }
233+
234+ // Jersey 2.x
235+ private boolean hasProperty (String name ) {
236+ return getProperty (name ) != null ;
237+ }
228238}
0 commit comments