1
1
/*
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.
3
3
*
4
4
* This program and the accompanying materials are made available under the
5
5
* terms of the Eclipse Public License v. 2.0, which is available at
27
27
import java .util .Map ;
28
28
import java .util .Optional ;
29
29
import java .util .Set ;
30
+ import java .util .concurrent .atomic .AtomicBoolean ;
30
31
import java .util .function .Function ;
31
32
import java .util .logging .Logger ;
32
33
39
40
import org .glassfish .jersey .internal .util .ReflectionHelper ;
40
41
import org .glassfish .jersey .spi .ExternalConfigurationModel ;
41
42
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 > {
42
50
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 ());
60
52
61
53
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 ;
62
57
static {
63
58
converters .put (String .class , (Function <String , String >) s -> s );
64
59
converters .put (Integer .class , (Function <String , Integer >) s -> Integer .valueOf (s ));
60
+ converters .put (Long .class , (Function <String , Long >) s -> Long .parseLong (s ));
65
61
converters .put (Boolean .class , (Function <String , Boolean >) s -> s .equalsIgnoreCase ("1" )
66
62
? true
67
63
: Boolean .parseBoolean (s ));
68
64
}
69
65
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 ;
72
76
}
73
77
74
78
@ Override
75
79
public <T > T as (String name , Class <T > clazz ) {
76
80
if (converters .get (clazz ) == null ) {
77
81
throw new IllegalArgumentException ("Unsupported class type" );
78
82
}
79
- return (name != null && clazz != null && isProperty (name ))
83
+ return (name != null && clazz != null && hasProperty (name ))
80
84
? clazz .cast (converters .get (clazz ).apply (getSystemProperty (name )))
81
85
: null ;
82
86
}
83
-
84
-
85
-
86
87
@ Override
87
88
public <T > Optional <T > getOptionalProperty (String name , Class <T > clazz ) {
88
89
return Optional .of (as (name , clazz ));
89
90
}
90
91
91
92
@ Override
92
93
public ExternalConfigurationModel mergeProperties (Map <String , Object > inputProperties ) {
94
+ inputProperties .forEach ((k , v ) -> properties .put (k , v ));
93
95
return this ;
94
96
}
95
97
@@ -100,11 +102,11 @@ public Void getConfig() {
100
102
101
103
@ Override
102
104
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
+ );
108
110
}
109
111
110
112
@ Override
@@ -114,30 +116,29 @@ public RuntimeType getRuntimeType() {
114
116
115
117
@ Override
116
118
public Map <String , Object > getProperties () {
117
- final Map <String , Object > result = new HashMap <>();
118
-
119
119
final Boolean allowSystemPropertiesProvider = as (
120
120
CommonProperties .ALLOW_SYSTEM_PROPERTIES_PROVIDER , Boolean .class
121
121
);
122
122
if (!Boolean .TRUE .equals (allowSystemPropertiesProvider )) {
123
- log .finer (LocalizationMessages .WARNING_PROPERTIES ());
124
- return result ;
123
+ LOGGER .finer (LocalizationMessages .WARNING_PROPERTIES ());
124
+ return properties ;
125
125
}
126
126
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
+ }
133
135
}
134
- return result ;
136
+ return properties ;
135
137
}
136
138
137
139
private Map <String , Object > getExpectedSystemProperties () {
138
140
final Map <String , Object > result = new HashMap <>();
139
- mapFieldsToProperties (result , CommonProperties .class );
140
- for (String propertyClass : PROPERTY_CLASSES ) {
141
+ for (String propertyClass : getPropertyClassNames ()) {
141
142
mapFieldsToProperties (result ,
142
143
AccessController .doPrivileged (
143
144
ReflectionHelper .classForNamePA (propertyClass )
@@ -148,7 +149,7 @@ private Map<String, Object> getExpectedSystemProperties() {
148
149
return result ;
149
150
}
150
151
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 ) {
152
153
if (clazz == null ) {
153
154
return ;
154
155
}
@@ -170,25 +171,29 @@ private <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T>
170
171
}
171
172
}
172
173
173
- private String getPropertyNameByField (Field field ) {
174
+ private static String getPropertyNameByField (Field field ) {
174
175
return AccessController .doPrivileged ((PrivilegedAction <String >) () -> {
175
176
try {
176
177
return (String ) field .get (null );
177
178
} catch (IllegalAccessException e ) {
178
- log .warning (e .getLocalizedMessage ());
179
+ LOGGER .warning (e .getLocalizedMessage ());
179
180
}
180
181
return null ;
181
182
});
182
183
}
183
184
185
+ private static String getSystemProperty (String name ) {
186
+ return AccessController .doPrivileged (PropertiesHelper .getSystemProperty (name ));
187
+ }
188
+
184
189
@ Override
185
190
public Object getProperty (String name ) {
186
191
return getSystemProperty (name );
187
192
}
188
193
189
194
@ Override
190
195
public Collection <String > getPropertyNames () {
191
- return PropertiesHelper .getSystemProperties (). run ( ).stringPropertyNames ();
196
+ return AccessController . doPrivileged ( PropertiesHelper .getSystemProperties ()).stringPropertyNames ();
192
197
}
193
198
194
199
@ Override
@@ -225,4 +230,9 @@ public Set<Class<?>> getClasses() {
225
230
public Set <Object > getInstances () {
226
231
return null ;
227
232
}
233
+
234
+ // Jersey 2.x
235
+ private boolean hasProperty (String name ) {
236
+ return getProperty (name ) != null ;
237
+ }
228
238
}
0 commit comments