Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.equinox.cm/META-INF/MANIFEST.MF10
-rw-r--r--bundles/org.eclipse.equinox.cm/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java18
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java25
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java4
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java287
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java16
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java9
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java9
-rw-r--r--bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java63
10 files changed, 364 insertions, 79 deletions
diff --git a/bundles/org.eclipse.equinox.cm/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
index 7419ee795..b9171b099 100644
--- a/bundles/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.cm/META-INF/MANIFEST.MF
@@ -4,10 +4,10 @@ Bundle-Name: %bundleName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.equinox.cm
-Bundle-Version: 1.3.100.qualifier
+Bundle-Version: 1.4.0.qualifier
Bundle-Activator: org.eclipse.equinox.internal.cm.Activator
Import-Package: org.osgi.framework;version="1.7.0",
- org.osgi.service.cm;version="[1.5,1.6)",
+ org.osgi.service.cm;version="[1.6,1.7)",
org.osgi.service.log;version="1.3.0",
org.osgi.service.event;version="1.0"; resolution:=optional,
org.osgi.util.tracker;version="1.3.1"
@@ -15,5 +15,9 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Provide-Capability:
osgi.service;
objectClass:List<String>="org.osgi.service.cm.ConfigurationAdmin";
- uses:="org.osgi.service.cm"
+ uses:="org.osgi.service.cm",
+ osgi.implementation;
+ osgi.implementation="osgi.cm";
+ uses:="org.osgi.service.cm";
+ version:Version="1.6"
Automatic-Module-Name: org.eclipse.equinox.cm
diff --git a/bundles/org.eclipse.equinox.cm/pom.xml b/bundles/org.eclipse.equinox.cm/pom.xml
index 0959f5b4a..648411b7b 100644
--- a/bundles/org.eclipse.equinox.cm/pom.xml
+++ b/bundles/org.eclipse.equinox.cm/pom.xml
@@ -19,6 +19,6 @@
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.cm</artifactId>
- <version>1.3.100-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java
index 7d8139af8..72cec99ff 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2018 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -28,6 +28,7 @@ import org.osgi.service.cm.ConfigurationPermission;
public class ConfigurationAdminFactory implements ServiceFactory<ConfigurationAdmin>, BundleListener {
static private final Permission allConfigurationPermission = new ConfigurationPermission("*", ConfigurationPermission.CONFIGURE); //$NON-NLS-1$
+ static private final Permission allAttributePermission = new ConfigurationPermission("*", ConfigurationPermission.ATTRIBUTE); //$NON-NLS-1$
private final EventDispatcher eventDispatcher;
private final PluginManager pluginManager;
private final LogTracker log;
@@ -105,6 +106,17 @@ public class ConfigurationAdminFactory implements ServiceFactory<ConfigurationAd
return true;
}
+ public void checkAttributePermission(String location) throws SecurityException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (location == null) {
+ sm.checkPermission(allAttributePermission);
+ } else {
+ sm.checkPermission(new ConfigurationPermission(location, ConfigurationPermission.ATTRIBUTE));
+ }
+ }
+ }
+
void log(int level, String message) {
log.log(level, message);
}
@@ -139,7 +151,7 @@ public class ConfigurationAdminFactory implements ServiceFactory<ConfigurationAd
}
}
- void modifyConfiguration(ServiceReference<?> reference, Dictionary<String, Object> properties) {
- pluginManager.modifyConfiguration(reference, properties);
+ Dictionary<String, Object> modifyConfiguration(ServiceReference<?> reference, ConfigurationImpl config) {
+ return pluginManager.modifyConfiguration(reference, config);
}
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java
index 083e7cb5b..1cb31fb26 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationAdminImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2018 Cognos Incorporated, IBM Corporation and others..
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others..
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -39,32 +39,41 @@ class ConfigurationAdminImpl implements ConfigurationAdmin {
@Override
public Configuration createFactoryConfiguration(String factoryPid) {
- return internalGetConfiguration(factoryPid, bundleLocation, true, true);
-
+ return internalGetConfiguration(factoryPid, bundleLocation, true, true, null);
}
@Override
public Configuration createFactoryConfiguration(String factoryPid, String location) {
- return internalGetConfiguration(factoryPid, location, true, false);
+ return internalGetConfiguration(factoryPid, location, true, false, null);
}
@Override
public Configuration getConfiguration(String pid) {
- return internalGetConfiguration(pid, bundleLocation, false, true);
+ return internalGetConfiguration(pid, bundleLocation, false, true, null);
}
@Override
public Configuration getConfiguration(String pid, String location) {
- return internalGetConfiguration(pid, location, false, false);
+ return internalGetConfiguration(pid, location, false, false, null);
+ }
+
+ @Override
+ public Configuration getFactoryConfiguration(String factoryPid, String name) {
+ return internalGetConfiguration(factoryPid, bundleLocation, true, true, name);
+ }
+
+ @Override
+ public Configuration getFactoryConfiguration(String factoryPid, String name, String location) {
+ return internalGetConfiguration(factoryPid, location, true, false, name);
}
- private Configuration internalGetConfiguration(String pid, String location, boolean factory, boolean bind) {
+ private Configuration internalGetConfiguration(String pid, String location, boolean factory, boolean bind, String name) {
checkPID(pid);
this.configurationAdminFactory.checkConfigurePermission(location, bundleLocation);
ConfigurationImpl config;
if (factory) {
- config = configurationStore.createFactoryConfiguration(pid, location, bind);
+ config = configurationStore.getFactoryConfiguration(pid, location, bind, name);
} else {
config = configurationStore.getConfiguration(pid, location, bind);
}
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java
index cb9a21432..3465f73e2 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationDictionary.java
@@ -146,8 +146,8 @@ public class ConfigurationDictionary extends Dictionary<String, Object> implemen
Object copyOfArray = Array.newInstance(value.getClass().getComponentType(), arrayLength);
System.arraycopy(value, 0, copyOfArray, 0, arrayLength);
result.configurationProperties.put(key, copyOfArray);
- } else if (value instanceof Vector)
- result.configurationProperties.put(key, ((Vector<?>) value).clone());
+ } else if (value instanceof Collection)
+ result.configurationProperties.put(key, new ArrayList<>((Collection<?>) value));
else
result.configurationProperties.put(key, value);
}
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java
index d9664d315..e9c36f1c1 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2018 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -19,8 +19,7 @@ import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
+import org.osgi.framework.*;
import org.osgi.service.cm.*;
/**
@@ -32,22 +31,26 @@ class ConfigurationImpl implements Configuration {
final static String LOCATION_BOUND = "org.eclipse.equinox.cm.location.bound"; //$NON-NLS-1$
final static String PROPERTIES_NULL = "org.eclipse.equinox.cm.properties.null"; //$NON-NLS-1$
final static String CHANGE_COUNT = "org.eclipse.equinox.cm.change.count"; //$NON-NLS-1$
+ final static String READ_ONLY = "org.eclipse.equinox.cm.readonly"; //$NON-NLS-1$
private final ConfigurationAdminFactory configurationAdminFactory;
private final ConfigurationStore configurationStore;
- /** @GuardedBy this*/
- private String bundleLocation;
private final String factoryPid;
private final String pid;
+ /** @GuardedBy lock*/
+ private String bundleLocation;
+ /** @GuardedBy lock*/
private ConfigurationDictionary dictionary;
- /** @GuardedBy this*/
+ /** @GuardedBy lock*/
private boolean deleted = false;
- /** @GuardedBy this*/
+ /** @GuardedBy lock*/
private boolean bound = false;
- /** @GuardedBy this*/
+ /** @GuardedBy lock*/
private long changeCount;
- /** @GuardedBy this*/
+ /** @GuardedBy lock*/
private Object storageToken;
+ /** @GuardedBy lock*/
+ private boolean readOnly = false;
private final ReentrantLock lock = new ReentrantLock();
public ConfigurationImpl(ConfigurationAdminFactory configurationAdminFactory, ConfigurationStore configurationStore, String factoryPid, String pid, String bundleLocation, boolean bind) {
@@ -70,6 +73,8 @@ class ConfigurationImpl implements Configuration {
this.bound = boundProp == null ? false : boundProp.booleanValue();
Long changeCountProp = (Long) dictionary.remove(CHANGE_COUNT);
this.changeCount = changeCountProp == null ? 0 : changeCountProp.longValue();
+ Boolean readOnlyProp = (Boolean) dictionary.remove(READ_ONLY);
+ this.readOnly = readOnlyProp == null ? false : readOnlyProp.booleanValue();
Boolean nullProps = (Boolean) dictionary.remove(PROPERTIES_NULL);
if (nullProps == null || !nullProps.booleanValue()) {
updateDictionary(dictionary);
@@ -91,8 +96,8 @@ class ConfigurationImpl implements Configuration {
}
boolean bind(String callerLocation) {
+ lock();
try {
- lock();
if (bundleLocation == null) {
bundleLocation = callerLocation;
bound = true;
@@ -111,8 +116,8 @@ class ConfigurationImpl implements Configuration {
}
boolean isBound() {
+ lock();
try {
- lock();
return bound;
} finally {
unlock();
@@ -120,8 +125,8 @@ class ConfigurationImpl implements Configuration {
}
void unbind(Bundle bundle) {
+ lock();
try {
- lock();
String callerLocation = ConfigurationAdminImpl.getLocation(bundle);
if (bound && callerLocation.equals(bundleLocation)) {
bundleLocation = null;
@@ -143,9 +148,10 @@ class ConfigurationImpl implements Configuration {
@Override
public void delete() {
Object deleteToken;
+ lock();
try {
- lock();
checkDeleted();
+ checkReadOnly();
deleted = true;
configurationAdminFactory.notifyConfigurationDeleted(this, factoryPid != null);
configurationAdminFactory.dispatchEvent(ConfigurationEvent.CM_DELETED, factoryPid, pid);
@@ -162,9 +168,15 @@ class ConfigurationImpl implements Configuration {
throw new IllegalStateException("deleted"); //$NON-NLS-1$
}
+ private void checkReadOnly() {
+ if (readOnly) {
+ throw new ReadOnlyConfigurationException("read only"); //$NON-NLS-1$
+ }
+ }
+
String getLocation() {
+ lock();
try {
- lock();
return bundleLocation;
} finally {
unlock();
@@ -173,8 +185,8 @@ class ConfigurationImpl implements Configuration {
@Override
public String getBundleLocation() {
+ lock();
try {
- lock();
checkDeleted();
configurationAdminFactory.checkConfigurePermission(bundleLocation, null);
if (bundleLocation != null)
@@ -186,8 +198,8 @@ class ConfigurationImpl implements Configuration {
}
String getFactoryPid(boolean checkDeleted) {
+ lock();
try {
- lock();
if (checkDeleted)
checkDeleted();
return factoryPid;
@@ -202,8 +214,8 @@ class ConfigurationImpl implements Configuration {
}
String getPid(boolean checkDeleted) {
+ lock();
try {
- lock();
if (checkDeleted)
checkDeleted();
return pid;
@@ -219,8 +231,8 @@ class ConfigurationImpl implements Configuration {
@Override
public Dictionary<String, Object> getProperties() {
+ lock();
try {
- lock();
checkDeleted();
if (dictionary == null)
return null;
@@ -234,8 +246,8 @@ class ConfigurationImpl implements Configuration {
}
Dictionary<String, Object> getAllProperties(boolean includeStorageKeys) {
+ lock();
try {
- lock();
if (deleted)
return null;
Dictionary<String, Object> copy = getProperties();
@@ -252,17 +264,21 @@ class ConfigurationImpl implements Configuration {
}
}
- private static void fileAutoProperties(Dictionary<String, Object> dictionary, ConfigurationImpl config, boolean includeLoc, boolean includeStorageKey) {
+ static void fileAutoProperties(Dictionary<String, Object> dictionary, ConfigurationImpl config, boolean includeLoc, boolean includeStorageKey) {
dictionary.put(Constants.SERVICE_PID, config.getPid(false));
String factoryPid = config.getFactoryPid(false);
if (factoryPid != null) {
dictionary.put(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid);
+ } else {
+ dictionary.remove(ConfigurationAdmin.SERVICE_FACTORYPID);
}
if (includeLoc) {
String loc = config.getLocation();
if (loc != null) {
dictionary.put(ConfigurationAdmin.SERVICE_BUNDLELOCATION, loc);
}
+ } else {
+ dictionary.remove(ConfigurationAdmin.SERVICE_BUNDLELOCATION);
}
if (includeStorageKey) {
if (config.dictionary == null) {
@@ -272,13 +288,14 @@ class ConfigurationImpl implements Configuration {
if (config.isBound()) {
dictionary.put(LOCATION_BOUND, Boolean.TRUE);
}
+ dictionary.put(READ_ONLY, Boolean.valueOf(config.readOnly));
}
}
@Override
public void setBundleLocation(String bundleLocation) {
+ lock();
try {
- lock();
checkDeleted();
configurationAdminFactory.checkConfigurePermission(this.bundleLocation, null);
configurationAdminFactory.checkConfigurePermission(bundleLocation, null);
@@ -300,9 +317,10 @@ class ConfigurationImpl implements Configuration {
@Override
public void update() throws IOException {
+ lock();
try {
- lock();
checkDeleted();
+ checkReadOnly();
if (dictionary == null)
dictionary = new ConfigurationDictionary();
changeCount++;
@@ -315,19 +333,176 @@ class ConfigurationImpl implements Configuration {
@Override
public void update(Dictionary<String, ?> properties) throws IOException {
+ lock();
try {
- lock();
- checkDeleted();
- updateDictionary(properties);
- changeCount++;
- save();
- configurationAdminFactory.notifyConfigurationUpdated(this, factoryPid != null);
- configurationAdminFactory.dispatchEvent(ConfigurationEvent.CM_UPDATED, factoryPid, pid);
+ doUpdate(properties, false);
+ } finally {
+ unlock();
+ }
+ }
+
+ @Override
+ public boolean updateIfDifferent(Dictionary<String, ?> properties) throws IOException {
+ lock();
+ try {
+ return doUpdate(properties, true);
} finally {
unlock();
}
}
+ private boolean same(Dictionary<String, ?> properties) {
+ if (dictionary == null) {
+ return false;
+ }
+ if (dictionary.size() != properties.size()) {
+ return false;
+ }
+
+ Enumeration<String> keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ if (dictionary.get(key) == null) {
+ return false;
+ }
+ Object current = dictionary.get(key);
+ Object newValue = properties.get(key);
+ if (current.getClass().isArray()) {
+ if (!newValue.getClass().isArray()) {
+ return false;
+ }
+ if (!current.getClass().getComponentType().equals(newValue.getClass().getComponentType())) {
+ current = convertIfPossible(current);
+ newValue = convertIfPossible(newValue);
+ if (!current.getClass().getComponentType().equals(newValue.getClass().getComponentType())) {
+ return false;
+ }
+ }
+ Class<?> currentComponentType = current.getClass().getComponentType();
+ if (long.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((long[]) current, (long[]) newValue)) {
+ return false;
+ }
+ } else if (int.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((int[]) current, (int[]) newValue)) {
+ return false;
+ }
+ } else if (short.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((short[]) current, (short[]) newValue)) {
+ return false;
+ }
+ } else if (char.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((char[]) current, (char[]) newValue)) {
+ return false;
+ }
+ } else if (byte.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((byte[]) current, (byte[]) newValue)) {
+ return false;
+ }
+ } else if (double.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((double[]) current, (double[]) newValue)) {
+ return false;
+ }
+ } else if (float.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((float[]) current, (float[]) newValue)) {
+ return false;
+ }
+ } else if (boolean.class.isAssignableFrom(currentComponentType)) {
+ if (!Arrays.equals((boolean[]) current, (boolean[]) newValue)) {
+ return false;
+ }
+ } else {
+ if (!Arrays.equals((Object[]) current, (Object[]) newValue)) {
+ return false;
+ }
+ }
+
+ } else {
+ if (!current.equals(newValue)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private Object convertIfPossible(Object array) {
+ Class<?> componentType = array.getClass().getComponentType();
+ if (Long.class.isAssignableFrom(componentType)) {
+ Long[] original = (Long[]) array;
+ long[] converted = new long[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Integer.class.isAssignableFrom(componentType)) {
+ Integer[] original = (Integer[]) array;
+ int[] converted = new int[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Short.class.isAssignableFrom(componentType)) {
+ Short[] original = (Short[]) array;
+ short[] converted = new short[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Character.class.isAssignableFrom(componentType)) {
+ Character[] original = (Character[]) array;
+ char[] converted = new char[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Byte.class.isAssignableFrom(componentType)) {
+ Byte[] original = (Byte[]) array;
+ byte[] converted = new byte[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Double.class.isAssignableFrom(componentType)) {
+ Double[] original = (Double[]) array;
+ double[] converted = new double[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Float.class.isAssignableFrom(componentType)) {
+ Float[] original = (Float[]) array;
+ float[] converted = new float[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+ } else if (Boolean.class.isAssignableFrom(componentType)) {
+ Boolean[] original = (Boolean[]) array;
+ boolean[] converted = new boolean[original.length];
+ for (int i = 0; i < original.length; i++) {
+ converted[i] = original[i];
+ }
+ return converted;
+
+ }
+ return array;
+ }
+
+ private boolean doUpdate(Dictionary<String, ?> properties, boolean checkSame) throws IOException {
+ checkDeleted();
+ checkReadOnly();
+ if (checkSame && same(properties)) {
+ return false;
+ }
+ updateDictionary(properties);
+ changeCount++;
+ save();
+ configurationAdminFactory.notifyConfigurationUpdated(this, factoryPid != null);
+ configurationAdminFactory.dispatchEvent(ConfigurationEvent.CM_UPDATED, factoryPid, pid);
+ return true;
+ }
+
private void save() throws IOException {
checkLocked();
storageToken = configurationStore.saveConfiguration(pid, this, this.storageToken);
@@ -370,8 +545,8 @@ class ConfigurationImpl implements Configuration {
}
boolean isDeleted() {
+ lock();
try {
- lock();
return deleted;
} finally {
unlock();
@@ -380,12 +555,62 @@ class ConfigurationImpl implements Configuration {
@Override
public long getChangeCount() {
+ lock();
try {
- lock();
checkDeleted();
return changeCount;
} finally {
unlock();
}
}
+
+ @Override
+ public Dictionary<String, Object> getProcessedProperties(ServiceReference<?> reference) {
+ return configurationAdminFactory.modifyConfiguration(reference, this);
+ }
+
+ @Override
+ public void addAttributes(ConfigurationAttribute... attrs) throws IOException {
+ lock();
+ try {
+ configurationAdminFactory.checkAttributePermission(bundleLocation);
+ for (ConfigurationAttribute attr : attrs) {
+ if (ConfigurationAttribute.READ_ONLY.equals(attr)) {
+ readOnly = true;
+ }
+ }
+ save();
+ } finally {
+ unlock();
+ }
+ }
+
+ @Override
+ public Set<ConfigurationAttribute> getAttributes() {
+ lock();
+ try {
+ if (readOnly) {
+ return EnumSet.of(ConfigurationAttribute.READ_ONLY);
+ }
+ return Collections.emptySet();
+ } finally {
+ unlock();
+ }
+ }
+
+ @Override
+ public void removeAttributes(ConfigurationAttribute... attrs) throws IOException {
+ lock();
+ try {
+ configurationAdminFactory.checkAttributePermission(bundleLocation);
+ for (ConfigurationAttribute attr : attrs) {
+ if (ConfigurationAttribute.READ_ONLY.equals(attr)) {
+ readOnly = false;
+ }
+ }
+ save();
+ } finally {
+ unlock();
+ }
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java
index 38dd965dd..08e04544e 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ConfigurationStore.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2018 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -177,8 +177,18 @@ class ConfigurationStore {
return config;
}
- public synchronized ConfigurationImpl createFactoryConfiguration(String factoryPid, String location, boolean bind) {
- String pid = factoryPid + "-" + new Date().getTime() + "-" + createdPidCount++; //$NON-NLS-1$ //$NON-NLS-2$
+ public synchronized ConfigurationImpl getFactoryConfiguration(String factoryPid, String location, boolean bind, String name) {
+ String pid;
+ if (name == null) {
+ pid = factoryPid + "-" + new Date().getTime() + "-" + createdPidCount++; //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ pid = factoryPid + "~" + name; //$NON-NLS-1$
+ ConfigurationImpl config = configurations.get(pid);
+ if (config != null) {
+ return config;
+ }
+ }
+
ConfigurationImpl config = new ConfigurationImpl(configurationAdminFactory, this, factoryPid, pid, location, bind);
configurations.put(pid, config);
return config;
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java
index 5d710393a..04bea731b 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceFactoryTracker.java
@@ -74,8 +74,7 @@ class ManagedServiceFactoryTracker extends ServiceTracker<ManagedServiceFactory,
ManagedServiceFactory serviceFactory = getService(ref);
if (hasLocPermission && serviceFactory != null) {
if (isMultiple || config.bind(ConfigurationAdminImpl.getLocation(ref.getBundle()))) {
- Dictionary<String, Object> properties = config.getProperties();
- configurationAdminFactory.modifyConfiguration(ref, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(ref, config);
asynchUpdated(serviceFactory, config.getPid(), properties);
}
}
@@ -120,8 +119,7 @@ class ManagedServiceFactoryTracker extends ServiceTracker<ManagedServiceFactory,
if (delete) {
asynchDeleted(serviceFactory, config.getPid());
} else if (update) {
- Dictionary<String, Object> properties = config.getProperties();
- configurationAdminFactory.modifyConfiguration(ref, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(ref, config);
asynchUpdated(serviceFactory, config.getPid(), properties);
}
// do not break on !isMultiple since we need to check if the other refs apply no matter what
@@ -218,8 +216,7 @@ class ManagedServiceFactoryTracker extends ServiceTracker<ManagedServiceFactory,
boolean hasLocPermission = configurationAdminFactory.checkTargetPermission(location, reference);
if (hasLocPermission) {
if (shouldBind && configs[i].bind(ConfigurationAdminImpl.getLocation(reference.getBundle())) || !shouldBind) {
- Dictionary<String, Object> properties = configs[i].getProperties();
- configurationAdminFactory.modifyConfiguration(reference, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(reference, configs[i]);
asynchUpdated(serviceFactory, configs[i].getPid(), properties);
foundConfig = true;
} else {
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java
index 2665cae74..32d3d2547 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/ManagedServiceTracker.java
@@ -78,8 +78,7 @@ class ManagedServiceTracker extends ServiceTracker<ManagedService, ManagedServic
ManagedService service = getService(ref);
if (hasLocPermission && service != null) {
if (isMultiple || config.bind(ConfigurationAdminImpl.getLocation(ref.getBundle()))) {
- Dictionary<String, Object> properties = config.getProperties();
- configurationAdminFactory.modifyConfiguration(ref, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(ref, config);
asynchUpdated(service, properties);
}
}
@@ -129,8 +128,7 @@ class ManagedServiceTracker extends ServiceTracker<ManagedService, ManagedServic
}
updateManagedService(qualifiedPidLists, ref, service);
} else if (update) {
- Dictionary<String, Object> properties = config.getProperties();
- configurationAdminFactory.modifyConfiguration(ref, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(ref, config);
asynchUpdated(service, properties);
}
// do not break on !isMultiple since we need to check if the other refs apply no matter what
@@ -226,8 +224,7 @@ class ManagedServiceTracker extends ServiceTracker<ManagedService, ManagedServic
boolean hasLocPermission = configurationAdminFactory.checkTargetPermission(location, reference);
if (hasLocPermission) {
if ((shouldBind && config.bind(ConfigurationAdminImpl.getLocation(reference.getBundle()))) || !shouldBind) {
- Dictionary<String, Object> properties = config.getProperties();
- configurationAdminFactory.modifyConfiguration(reference, properties);
+ Dictionary<String, Object> properties = configurationAdminFactory.modifyConfiguration(reference, config);
asynchUpdated(service, properties);
foundConfig = true;
break qualifiedPids;
diff --git a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java
index c2bb06750..0704b9367 100644
--- a/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java
+++ b/bundles/org.eclipse.equinox.cm/src/org/eclipse/equinox/internal/cm/PluginManager.java
@@ -15,7 +15,8 @@
package org.eclipse.equinox.internal.cm;
import java.util.*;
-import org.osgi.framework.*;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationPlugin;
import org.osgi.util.tracker.ServiceTracker;
@@ -37,26 +38,63 @@ public class PluginManager {
pluginTracker.close();
}
- public void modifyConfiguration(ServiceReference<?> managedReference, Dictionary<String, Object> properties) {
+ public Dictionary<String, Object> modifyConfiguration(ServiceReference<?> managedReference, ConfigurationImpl config) {
+ Dictionary<String, Object> properties = config.getProperties();
if (properties == null)
- return;
+ return null;
ServiceReference<ConfigurationPlugin>[] references = pluginTracker.getServiceReferences();
for (int i = 0; i < references.length; ++i) {
- String[] pids = (String[]) references[i].getProperty(ConfigurationPlugin.CM_TARGET);
+ Collection<?> pids = getStringProperty(references[i].getProperty(ConfigurationPlugin.CM_TARGET));
if (pids != null) {
- String pid = (String) properties.get(Constants.SERVICE_PID);
- if (!Arrays.asList(pids).contains(pid))
+ String pid = config.getFactoryPid();
+ if (pid == null) {
+ pid = config.getPid();
+ }
+ if (!pids.contains(pid))
continue;
}
ConfigurationPlugin plugin = pluginTracker.getService(references[i]);
- if (plugin != null)
- plugin.modifyConfiguration(managedReference, properties);
+ if (plugin != null) {
+ int rank = getRank(references[i]);
+ if (rank < 0 || rank > 1000) {
+ plugin.modifyConfiguration(managedReference, ((ConfigurationDictionary) properties).copy());
+ } else {
+ plugin.modifyConfiguration(managedReference, properties);
+ ConfigurationImpl.fileAutoProperties(properties, config, false, false);
+ }
+ }
+ }
+ return properties;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Collection<Object> getStringProperty(Object value) {
+ if (value == null)
+ return null;
+ if (value instanceof String) {
+ return Collections.singleton(value);
+ }
+ if (value instanceof String[]) {
+ return Arrays.asList((Object[]) value);
}
+ if (value instanceof Collection) {
+ return (Collection<Object>) value;
+ }
+ return null;
+ }
+
+ static final Integer ZERO = Integer.valueOf(0);
+
+ static Integer getRank(ServiceReference<ConfigurationPlugin> ref) {
+ Object ranking = ref.getProperty(ConfigurationPlugin.CM_RANKING);
+ if (ranking == null || !(ranking instanceof Integer))
+ return ZERO;
+ return ((Integer) ranking);
}
private static class PluginTracker extends ServiceTracker<ConfigurationPlugin, ConfigurationPlugin> {
- final Integer ZERO = Integer.valueOf(0);
+
private TreeSet<ServiceReference<ConfigurationPlugin>> serviceReferences = new TreeSet<>(new Comparator<ServiceReference<ConfigurationPlugin>>() {
@Override
public int compare(ServiceReference<ConfigurationPlugin> s1, ServiceReference<ConfigurationPlugin> s2) {
@@ -68,13 +106,6 @@ public class PluginManager {
// we reverse the order which means services with higher service.ranking properties are called first
return -(s1.compareTo(s2));
}
-
- private Integer getRank(ServiceReference<ConfigurationPlugin> ref) {
- Object ranking = ref.getProperty(ConfigurationPlugin.CM_RANKING);
- if (ranking == null || !(ranking instanceof Integer))
- return ZERO;
- return ((Integer) ranking);
- }
});
public PluginTracker(BundleContext context) {

Back to the top