Repository: incubator-tamaya-sandbox Updated Branches: refs/heads/master 487e924fe -> 2949a137a
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigAdminImpl.java ---------------------------------------------------------------------- diff --git a/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigAdminImpl.java b/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigAdminImpl.java new file mode 100644 index 0000000..7bf4da7 --- /dev/null +++ b/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigAdminImpl.java @@ -0,0 +1,196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.integration.osgi; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.cm.ManagedService; +import org.osgi.service.cm.ManagedServiceFactory; +import org.osgi.util.tracker.ServiceTracker; + +/** + * Tamaya based implementation of an OSGI {@link ConfigurationAdmin}. + */ +public class TamayaConfigAdminImpl implements ConfigurationAdmin { + /** the logger. */ + private static final Logger LOG = Logger.getLogger(TamayaConfigAdminImpl.class.getName()); + + /** The OSGI context. */ + private final BundleContext context; + /** THe optional OSGI parent service. */ + private ConfigurationAdmin parent; + /** The cached configurations. */ + private Map<String,Configuration> configs = new ConcurrentHashMap<>(); + /** The configuration section mapper. */ + private OSGIConfigRootMapper configRootMapper; + + /** + * Create a new config. + * @param context the OSGI context + */ + TamayaConfigAdminImpl(BundleContext context) { + this.context = context; + this.configRootMapper = loadConfigRootMapper(); + ServiceReference<ConfigurationAdmin> ref = context.getServiceReference(ConfigurationAdmin.class); + this.parent = ref!=null?context.getService(ref):null; + ServiceTracker<ManagedService, ManagedService> serviceTracker = new ServiceTracker<ManagedService, + ManagedService>(context, ManagedService.class, null) { + @Override + public ManagedService addingService(ServiceReference<ManagedService> reference) { + ManagedService service = context.getService(reference); + Object pidObj = reference.getProperty(Constants.SERVICE_PID); + if (pidObj instanceof String) { + String pid = (String) pidObj; + try { + Configuration config = getConfiguration(pid); + if(config==null){ + service.updated(null); + } else{ + service.updated(config.getProperties()); + } + } catch (Exception e) { + LOG.log(Level.WARNING, "Error configuring ManagedService: " + service, e); + } + } else { + LOG.log(Level.SEVERE, "Unsupported pid: " + pidObj); + } + return service; + } + + @Override + public void removedService(ServiceReference<ManagedService> reference, ManagedService service) { + context.ungetService(reference); + } + }; + serviceTracker.open(); + + ServiceTracker<ServiceFactory, ServiceFactory> factoryTracker + = new ServiceTracker<ServiceFactory, ServiceFactory>(context, ServiceFactory.class, null) { + @Override + public ServiceFactory addingService(ServiceReference<ServiceFactory> reference) { + ServiceFactory factory = context.getService(reference); + if(factory instanceof ManagedServiceFactory) { + Object pidObj = reference.getProperty(Constants.SERVICE_PID); + if (pidObj instanceof String) { + String pid = (String) pidObj; + try { + Configuration config = getConfiguration(pid); + if (config != null) { + ((ManagedServiceFactory) factory).updated(config.getFactoryPid(), config.getProperties()); + } + } catch (Exception e) { + LOG.log(Level.WARNING, "Error configuring ManagedServiceFactory: " + factory, e); + } + } else { + LOG.log(Level.SEVERE, "Unsupported pid: " + pidObj); + } + } + return factory; + } + + @Override + public void removedService(ServiceReference<ServiceFactory> reference, ServiceFactory service) { + super.removedService(reference, service); + } + }; + factoryTracker.open(); + } + + @Override + public Configuration createFactoryConfiguration(String factoryPid) throws IOException { + return createFactoryConfiguration(factoryPid, null); + } + + @Override + public Configuration createFactoryConfiguration(String factoryPid, String location) throws IOException { + return new TamayaConfigurationImpl(factoryPid, null, configRootMapper, this.parent); + } + + @Override + public Configuration getConfiguration(String pid, String location) throws IOException { + return getConfiguration(pid); + } + + @Override + public Configuration getConfiguration(String pid) throws IOException { + return new TamayaConfigurationImpl(pid, null, configRootMapper, this.parent); + } + + @Override + public Configuration[] listConfigurations(String filter) throws IOException, InvalidSyntaxException { + Collection<Configuration> result; + if (filter == null) { + result = this.configs.values(); + } else { + result = new ArrayList<>(); + Filter flt = context.createFilter(filter); + for (Configuration config : this.configs.values()) { + if (flt.match(config.getProperties())) { + result.add(config); + } + } + } + return result.isEmpty() ? null : result.toArray(new Configuration[configs.size()]); + } + + /** + * Loads the configuration toor mapper using the OSGIConfigRootMapper OSGI service resolving mechanism. If no + * such service is available it loads the default mapper. + * @return the mapper to be used, bever null. + */ + private OSGIConfigRootMapper loadConfigRootMapper() { + OSGIConfigRootMapper mapper = null; + ServiceReference<OSGIConfigRootMapper> ref = context.getServiceReference(OSGIConfigRootMapper.class); + if(ref!=null){ + mapper = context.getService(ref); + } + if(mapper==null){ + mapper = new OSGIConfigRootMapper() { + @Override + public String getTamayaConfigRoot(String pid, String factoryPid) { + if(pid!=null) { + return "[bundle:" + pid +']'; + } else{ + return "[bundle:" + factoryPid +']'; + } + } + @Override + public String toString(){ + return "Default OSGIConfigRootMapper(pid -> [bundle:pid], factoryPid -> [bundle:factoryPid]"; + } + }; + } + return mapper; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigurationImpl.java ---------------------------------------------------------------------- diff --git a/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigurationImpl.java b/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigurationImpl.java new file mode 100644 index 0000000..c7b0864 --- /dev/null +++ b/osgi/src/main/java/org/apache/tamaya/osgi/TamayaConfigurationImpl.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.integration.osgi; + +import java.io.IOException; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tamaya.ConfigurationProvider; +import org.apache.tamaya.functions.PropertyMatcher; +import org.apache.tamaya.functions.ConfigurationFunctions; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +/** + * Tamaya based implementation of an OSGI {@link Configuration}. + */ +public class TamayaConfigurationImpl implements Configuration { + private static final Logger LOG = Logger.getLogger(TamayaConfigurationImpl.class.getName()); + private final String pid; + private final String factoryPid; + private Map<String, String> properties = new HashMap<>(); + private org.apache.tamaya.Configuration config; + + /** + * Constructor. + * @param confPid the OSGI pid + * @param factoryPid the factory pid + * @param configRootMapper the mapper that maps the pids to a tamaya root section. + * @param parent the (optional delegating parent, used as default). + */ + TamayaConfigurationImpl(String confPid, String factoryPid, OSGIConfigRootMapper configRootMapper, + ConfigurationAdmin parent) { + this.pid = confPid; + this.factoryPid = factoryPid; + if(parent!=null){ + try { + Dictionary<String, Object> conf = parent.getConfiguration(confPid, factoryPid).getProperties(); + if(conf!=null) { + LOG.info("Configuration: Adding default parameters from parent: " + parent.getClass().getName()); + Enumeration<String> keys = conf.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + this.properties.put(key, conf.get(key).toString()); + } + } + } catch (IOException e) { + LOG.log(Level.WARNING, "Error reading parent OSGI config.", e); + } + } + this.config = ConfigurationProvider.getConfiguration(); + final String rootKey = configRootMapper.getTamayaConfigRoot(pid, factoryPid); + LOG.info("Configuration: Evaluating Tamaya configuration for '" + rootKey + "'."); + this.properties.putAll( + config.with(ConfigurationFunctions.section(rootKey, true)).getProperties()); + } + + @Override + public String getPid() { + return pid; + } + + @Override + public Dictionary<String, Object> getProperties() { + return new Hashtable<String, Object>(properties); + } + + @Override + public void update(Dictionary<String, ?> properties) throws IOException { + throw new UnsupportedOperationException("Nuatability not yet supported."); + // ConfigChangeProvider.createChangeRequest(this.config) + } + + @Override + public void delete() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public String getFactoryPid() { + return factoryPid; + } + + @Override + public void update() throws IOException { + this.config = ConfigurationProvider.getConfiguration(); + this.properties = config.with(ConfigurationFunctions.filter(new PropertyMatcher() { + @Override + public boolean test(String key, String value) { +// TODO define name space / SPI + return false; + } + })).getProperties(); + } + + @Override + public void setBundleLocation(String location) { + } + + @Override + public String getBundleLocation() { + return null; + } + + @Override + public long getChangeCount() { + return 0; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/osgi/src/test/resources/felix.properties ---------------------------------------------------------------------- diff --git a/osgi/src/test/resources/felix.properties b/osgi/src/test/resources/felix.properties index de50401..4630fa2 100644 --- a/osgi/src/test/resources/felix.properties +++ b/osgi/src/test/resources/felix.properties @@ -16,7 +16,7 @@ # under the License. # # org.osgi.service.cm;org.apache.felix.cm;org.apache.tamaya;org.apache.tamaya.spi; -org.osgi.framework.bootdelegation=org.apache.tamaya,org.apache.tamaya.integration.osgi,org.apache.tamaya.integration.osgi.test +org.osgi.framework.bootdelegation=org.apache.tamaya,org.apache.tamaya.osgi,org.apache.tamaya.osgi.test felix.log.level=4 #debug logging # felix.auto.deploy.dir=../test-bundles org.osgi.framework.storage=target/felix-cache http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/propertysources/bnd.bnd ---------------------------------------------------------------------- diff --git a/propertysources/bnd.bnd b/propertysources/bnd.bnd new file mode 100644 index 0000000..22420aa --- /dev/null +++ b/propertysources/bnd.bnd @@ -0,0 +1,2 @@ +Export-Package: \ + org.apache.tamaya.propertysources \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/remote/bnd.bnd ---------------------------------------------------------------------- diff --git a/remote/bnd.bnd b/remote/bnd.bnd new file mode 100644 index 0000000..0097b76 --- /dev/null +++ b/remote/bnd.bnd @@ -0,0 +1,2 @@ +Export-Package: \ + org.apache.tamaya.remote \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/server/bnd.bnd ---------------------------------------------------------------------- diff --git a/server/bnd.bnd b/server/bnd.bnd new file mode 100644 index 0000000..5e15dba --- /dev/null +++ b/server/bnd.bnd @@ -0,0 +1,3 @@ +Export-Package: \ + org.apache.tamaya.server,\ + org.apache.tamaya.server.spi \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/tamaya-sandbox.iml ---------------------------------------------------------------------- diff --git a/tamaya-sandbox.iml b/tamaya-sandbox.iml new file mode 100644 index 0000000..1e73e41 --- /dev/null +++ b/tamaya-sandbox.iml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/../tamaya/target/classes" /> + <output-test url="file://$MODULE_DIR$/../tamaya/target/test-classes" /> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/target" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="Maven: org.apache.geronimo.specs:geronimo-annotation_1.2_spec:1.0-alpha-1" level="project" /> + </component> +</module> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/usagetracker/bnd.bnd ---------------------------------------------------------------------- diff --git a/usagetracker/bnd.bnd b/usagetracker/bnd.bnd new file mode 100644 index 0000000..5aa0155 --- /dev/null +++ b/usagetracker/bnd.bnd @@ -0,0 +1,3 @@ +Export-Package: \ + org.apache.tamaya.usagetracker,\ + org.apache.tamaya.usagetracker.spi \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/2949a137/validation/bnd.bnd ---------------------------------------------------------------------- diff --git a/validation/bnd.bnd b/validation/bnd.bnd new file mode 100644 index 0000000..bb9e43a --- /dev/null +++ b/validation/bnd.bnd @@ -0,0 +1,3 @@ +Export-Package: \ + org.apache.tamaya.validation,\ + org.apache.tamaya.validation.spi \ No newline at end of file
