diff --git a/bundles/apidocs/pom.xml b/bundles/apidocs/pom.xml
index cf8cc5277a..3ac78a5243 100644
--- a/bundles/apidocs/pom.xml
+++ b/bundles/apidocs/pom.xml
@@ -276,7 +276,7 @@
org.glassfish.jersey.*:*
- *.internal.*
+ *.internal.*:*.innate.*
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalConfigurationProviderImpl.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalConfigurationProviderImpl.java
new file mode 100644
index 0000000000..8377e63349
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalConfigurationProviderImpl.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+import org.glassfish.jersey.spi.ExternalConfigurationProvider;
+
+import java.util.Map;
+
+public class ExternalConfigurationProviderImpl implements ExternalConfigurationProvider {
+
+ protected final ExternalConfigurationModel> model;
+
+ protected ExternalConfigurationProviderImpl(ExternalConfigurationModel> model) {
+ this.model = model;
+ }
+
+ @Override
+ public Map getProperties() {
+ return model.getProperties();
+ }
+
+ @Override
+ public ExternalConfigurationModel getConfiguration() {
+ return model;
+ }
+
+ @Override
+ public ExternalConfigurationModel merge(ExternalConfigurationModel input) {
+ return input == null ? model : model.mergeProperties(input.getProperties());
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java
index 9e0105b288..f5c2bd7e76 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -32,6 +32,7 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.function.BiConsumer;
/**
* Factory for external properties providers
@@ -50,12 +51,20 @@ public class ExternalPropertiesConfigurationFactory {
* @return map of merged properties from all found/plugged providers
*/
static Map readExternalPropertiesMap() {
+ return readExternalPropertiesMap(EXTERNAL_CONFIGURATION_PROVIDERS);
+ }
- final ExternalConfigurationProvider provider = mergeConfigs(EXTERNAL_CONFIGURATION_PROVIDERS);
+ /**
+ * Map of merged properties from all given providers
+ *
+ * @param externalConfigProviders list of providers to use
+ * @return map of merged properties from {@code externalConfigProviders} providers
+ */
+ private static Map readExternalPropertiesMap(List externalConfigProviders) {
+ final ExternalConfigurationProvider provider = mergeConfigs(externalConfigProviders);
return provider == null ? Collections.emptyMap() : provider.getProperties();
}
-
/**
* Input Configurable object shall be provided in order to be filled with all found properties
*
@@ -64,14 +73,28 @@ static Map readExternalPropertiesMap() {
*/
public static boolean configure(Configurable config) {
+ return configure((k, v) -> config.property(k, v), EXTERNAL_CONFIGURATION_PROVIDERS);
+ }
+ /**
+ * Key Value pairs gathered by {@link ExternalConfigurationProvider}s are applied to a given {@code config}. The
+ * {@code config} can be for instance {@code (k,v) -> configurable.property(k,v)} of a
+ * {@link Configurable#property(String, Object) Configurable structure}, or {@code (k,v) -> properties.put(k,v)} of a
+ * {@link java.util.Properties#put(Object, Object) Properties structure}.
+ *
+ * @param config
+ * @param externalConfigurationProviders the providers to grab the properties from it.
+ * @return true if configured false otherwise.
+ */
+ public static boolean configure(BiConsumer config,
+ List externalConfigurationProviders) {
if (config instanceof ExternalConfigurationModel) {
return false; //shall not configure itself
}
- final Map properties = readExternalPropertiesMap();
+ final Map properties = readExternalPropertiesMap(externalConfigurationProviders);
- properties.forEach((k, v) -> config.property(k, v));
+ properties.forEach((k, v) -> config.accept(k, v));
return true;
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/JerseySystemPropertiesConfigurationModel.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/JerseySystemPropertiesConfigurationModel.java
new file mode 100644
index 0000000000..4d9606b352
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/JerseySystemPropertiesConfigurationModel.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import java.util.Arrays;
+import java.util.List;
+
+class JerseySystemPropertiesConfigurationModel extends SystemPropertiesConfigurationModel {
+
+ static final List PROPERTY_CLASSES = Arrays.asList(
+ "org.glassfish.jersey.CommonProperties",
+ "org.glassfish.jersey.ExternalProperties",
+ "org.glassfish.jersey.server.ServerProperties",
+ "org.glassfish.jersey.client.ClientProperties",
+ "org.glassfish.jersey.servlet.ServletProperties",
+ "org.glassfish.jersey.message.MessageProperties",
+ "org.glassfish.jersey.apache.connector.ApacheClientProperties",
+ "org.glassfish.jersey.helidon.connector.HelidonClientProperties",
+ "org.glassfish.jersey.jdk.connector.JdkConnectorProperties",
+ "org.glassfish.jersey.jetty.connector.JettyClientProperties",
+ "org.glassfish.jersey.netty.connector.NettyClientProperties",
+ "org.glassfish.jersey.media.multipart.MultiPartProperties",
+ "org.glassfish.jersey.server.oauth1.OAuth1ServerProperties");
+
+ JerseySystemPropertiesConfigurationModel() {
+ super(PROPERTY_CLASSES);
+ }
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
index 7056d04dfd..13a4baf61c 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -27,6 +27,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.logging.Logger;
@@ -39,36 +40,39 @@
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.jersey.spi.ExternalConfigurationModel;
+/**
+ * The External Configuration Model that supports {@code System} properties. The properties are listed in a property class
+ * in a form of {@code public static final String} property name. The {@code String} value of the property name is searched
+ * among the {@code System} properties. The property scan is performed only when
+ * {@link CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER} is set to {@code true}.
+ */
+public class SystemPropertiesConfigurationModel implements ExternalConfigurationModel {
-class SystemPropertiesConfigurationModel implements ExternalConfigurationModel {
-
- private static final Logger log = Logger.getLogger(SystemPropertiesConfigurationModel.class.getName());
- static final List PROPERTY_CLASSES = Arrays.asList(
- "org.glassfish.jersey.ExternalProperties",
- "org.glassfish.jersey.server.ServerProperties",
- "org.glassfish.jersey.client.ClientProperties",
- "org.glassfish.jersey.servlet.ServletProperties",
- "org.glassfish.jersey.message.MessageProperties",
- "org.glassfish.jersey.apache.connector.ApacheClientProperties",
- "org.glassfish.jersey.helidon.connector.HelidonClientProperties",
- "org.glassfish.jersey.jdk.connector.JdkConnectorProperties",
- "org.glassfish.jersey.jetty.connector.JettyClientProperties",
- "org.glassfish.jersey.netty.connector.NettyClientProperties",
- "org.glassfish.jersey.media.multipart.MultiPartProperties",
- "org.glassfish.jersey.server.oauth1.OAuth1ServerProperties");
-
+ private static final Logger LOGGER = Logger.getLogger(SystemPropertiesConfigurationModel.class.getName());
private static final Map converters = new HashMap<>();
+ private final Map properties = new HashMap<>();
+ private final AtomicBoolean gotProperties = new AtomicBoolean(false);
+ private final List propertyClassNames;
static {
converters.put(String.class, (Function) s -> s);
converters.put(Integer.class, (Function) s -> Integer.valueOf(s));
+ converters.put(Long.class, (Function) s -> Long.parseLong(s));
converters.put(Boolean.class, (Function) s -> s.equalsIgnoreCase("1")
? true
: Boolean.parseBoolean(s));
}
- private String getSystemProperty(String name) {
- return AccessController.doPrivileged(PropertiesHelper.getSystemProperty(name));
+ /**
+ * Create new {@link ExternalConfigurationModel} for properties defined by classes in {@code propertyClassNames} list.
+ * @param propertyClassNames List of property defining class names.
+ */
+ public SystemPropertiesConfigurationModel(List propertyClassNames) {
+ this.propertyClassNames = propertyClassNames;
+ }
+
+ protected List getPropertyClassNames() {
+ return propertyClassNames;
}
@Override
@@ -76,13 +80,10 @@ public T as(String name, Class clazz) {
if (converters.get(clazz) == null) {
throw new IllegalArgumentException("Unsupported class type");
}
- return (name != null && clazz != null && isProperty(name))
+ return (name != null && clazz != null && hasProperty(name))
? clazz.cast(converters.get(clazz).apply(getSystemProperty(name)))
: null;
}
-
-
-
@Override
public Optional getOptionalProperty(String name, Class clazz) {
return Optional.of(as(name, clazz));
@@ -90,6 +91,7 @@ public Optional getOptionalProperty(String name, Class clazz) {
@Override
public ExternalConfigurationModel mergeProperties(Map inputProperties) {
+ inputProperties.forEach((k, v) -> properties.put(k, v));
return this;
}
@@ -100,11 +102,11 @@ public Void getConfig() {
@Override
public boolean isProperty(String name) {
- return Optional.ofNullable(
- AccessController.doPrivileged(
- PropertiesHelper.getSystemProperty(name)
- )
- ).isPresent();
+ String property = getSystemProperty(name);
+ return property != null && (
+ "0".equals(property) || "1".equals(property)
+ || "true".equalsIgnoreCase(property) || "false".equalsIgnoreCase(property)
+ );
}
@Override
@@ -114,30 +116,29 @@ public RuntimeType getRuntimeType() {
@Override
public Map getProperties() {
- final Map result = new HashMap<>();
-
final Boolean allowSystemPropertiesProvider = as(
CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER, Boolean.class
);
if (!Boolean.TRUE.equals(allowSystemPropertiesProvider)) {
- log.finer(LocalizationMessages.WARNING_PROPERTIES());
- return result;
+ LOGGER.finer(LocalizationMessages.WARNING_PROPERTIES());
+ return properties;
}
- try {
- AccessController.doPrivileged(PropertiesHelper.getSystemProperties())
- .forEach((k, v) -> result.put(String.valueOf(k), v));
- } catch (SecurityException se) {
- log.warning(LocalizationMessages.SYSTEM_PROPERTIES_WARNING());
- return getExpectedSystemProperties();
+ if (gotProperties.compareAndSet(false, true)) {
+ try {
+ AccessController.doPrivileged(PropertiesHelper.getSystemProperties())
+ .forEach((k, v) -> properties.put(String.valueOf(k), v));
+ } catch (SecurityException se) {
+ LOGGER.warning(LocalizationMessages.SYSTEM_PROPERTIES_WARNING());
+ return getExpectedSystemProperties();
+ }
}
- return result;
+ return properties;
}
private Map getExpectedSystemProperties() {
final Map result = new HashMap<>();
- mapFieldsToProperties(result, CommonProperties.class);
- for (String propertyClass : PROPERTY_CLASSES) {
+ for (String propertyClass : getPropertyClassNames()) {
mapFieldsToProperties(result,
AccessController.doPrivileged(
ReflectionHelper.classForNamePA(propertyClass)
@@ -148,7 +149,7 @@ private Map getExpectedSystemProperties() {
return result;
}
- private void mapFieldsToProperties(Map properties, Class clazz) {
+ private static void mapFieldsToProperties(Map properties, Class clazz) {
if (clazz == null) {
return;
}
@@ -170,17 +171,21 @@ private void mapFieldsToProperties(Map properties, Class
}
}
- private String getPropertyNameByField(Field field) {
+ private static String getPropertyNameByField(Field field) {
return AccessController.doPrivileged((PrivilegedAction) () -> {
try {
return (String) field.get(null);
} catch (IllegalAccessException e) {
- log.warning(e.getLocalizedMessage());
+ LOGGER.warning(e.getLocalizedMessage());
}
return null;
});
}
+ private static String getSystemProperty(String name) {
+ return AccessController.doPrivileged(PropertiesHelper.getSystemProperty(name));
+ }
+
@Override
public Object getProperty(String name) {
return getSystemProperty(name);
@@ -188,7 +193,7 @@ public Object getProperty(String name) {
@Override
public Collection getPropertyNames() {
- return PropertiesHelper.getSystemProperties().run().stringPropertyNames();
+ return AccessController.doPrivileged(PropertiesHelper.getSystemProperties()).stringPropertyNames();
}
@Override
@@ -225,4 +230,9 @@ public Set> getClasses() {
public Set