diff options
author | Thomas Watson | 2019-01-15 23:20:24 +0000 |
---|---|---|
committer | Thomas Watson | 2019-01-17 04:18:10 +0000 |
commit | cc9182802aa5b83dce8d5f0f720f98353a4436d2 (patch) | |
tree | f1cd6270c55acb0dbff8a8fb0f32aa7ec9f2efb2 | |
parent | 6e46f2e63d5db3f5bf017e22c9449d42bfbdbb3f (diff) | |
download | rt.equinox.bundles-cc9182802aa5b83dce8d5f0f720f98353a4436d2.tar.gz rt.equinox.bundles-cc9182802aa5b83dce8d5f0f720f98353a4436d2.tar.xz rt.equinox.bundles-cc9182802aa5b83dce8d5f0f720f98353a4436d2.zip |
Bug 538717 - Implement ConfigAdmin version 1.6I20190121-1415I20190120-1800I20190119-1800I20190118-1800I20190117-2335
Change-Id: I61152d0aeec13440535a64758022ed2e13d2fa62
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
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) { |