[KARAF-3405] Support for "mostly static" karaf instances

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/3bae561f
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/3bae561f
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/3bae561f

Branch: refs/heads/master
Commit: 3bae561f09d00cb10d9c865b39ab22fb40de2e6a
Parents: 0575750
Author: Guillaume Nodet <gno...@gmail.com>
Authored: Thu Dec 11 00:00:29 2014 +0100
Committer: Guillaume Nodet <gno...@gmail.com>
Committed: Thu Dec 11 00:02:09 2014 +0100

----------------------------------------------------------------------
 demos/profiles/pom.xml                          |   1 +
 demos/profiles/static/pom.xml                   | 147 +++++++++++++++++
 .../static/src/main/resources/features.xml      |  29 ++++
 pom.xml                                         |   5 +
 services/pom.xml                                |   1 +
 services/staticcm/pom.xml                       |  92 +++++++++++
 .../karaf/services/staticcm/Activator.java      |  60 +++++++
 .../karaf/services/staticcm/Configurations.java |  92 +++++++++++
 .../staticcm/StaticConfigAdminImpl.java         | 157 +++++++++++++++++++
 .../staticcm/StaticConfigurationImpl.java       |  83 ++++++++++
 10 files changed, 667 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/demos/profiles/pom.xml
----------------------------------------------------------------------
diff --git a/demos/profiles/pom.xml b/demos/profiles/pom.xml
index fdc5621..10055f9 100644
--- a/demos/profiles/pom.xml
+++ b/demos/profiles/pom.xml
@@ -36,6 +36,7 @@
     <modules>
         <module>registry</module>
         <module>dynamic</module>
+        <module>static</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/demos/profiles/static/pom.xml
----------------------------------------------------------------------
diff --git a/demos/profiles/static/pom.xml b/demos/profiles/static/pom.xml
new file mode 100644
index 0000000..039ef21
--- /dev/null
+++ b/demos/profiles/static/pom.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf.demos</groupId>
+        <artifactId>demos</artifactId>
+        <version>4.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.demos.profiles</groupId>
+    <artifactId>static</artifactId>
+    <packaging>pom</packaging>
+    <name>Apache Karaf :: Demos :: Profiles :: Static Assembly</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.karaf.features</groupId>
+            <artifactId>framework</artifactId>
+            <type>kar</type>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.features</groupId>
+            <artifactId>standard</artifactId>
+            <classifier>features</classifier>
+            <type>xml</type>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.features</groupId>
+            <artifactId>spring</artifactId>
+            <classifier>features</classifier>
+            <type>xml</type>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${project.basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>${project.basedir}/../..</directory>
+                <filtering>false</filtering>
+                <includes>
+                    <include>README</include>
+                    <include>RELEASE*</include>
+                    <include>LICENSE</include>
+                    <include>NOTICE</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>process-resources</id>
+                        <goals>
+                            <goal>resources</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>process-resources</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>install-kars</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>package</id>
+                        <goals>
+                            <goal>instance-create-archive</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <useReferenceUrls>true</useReferenceUrls>
+                    <!--
+                    <profilesArtifact>
+                        
org.apache.karaf.demo.profiles:org.apache.karaf.demo.profiles.registry
+                    </profilesArtifact>
+                    -->
+                    <profilesDirectory>
+                        ${basedir}/../registry/src/main/resources
+                    </profilesDirectory>
+                    <startupRepositories>
+                        
<repository>${project.build.outputDirectory}/features.xml</repository>
+                    </startupRepositories>
+                    <startupFeatures>
+                        <feature>static-framework</feature>
+                    </startupFeatures>
+                    <startupProfiles>
+                        <profile>karaf</profile>
+                        <profile>example-loanbroker-bank1</profile>
+                        <profile>example-loanbroker-bank2</profile>
+                        <profile>example-loanbroker-bank3</profile>
+                        <profile>example-loanbroker-broker</profile>
+                        <profile>activemq-broker</profile>
+                    </startupProfiles>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/demos/profiles/static/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/demos/profiles/static/src/main/resources/features.xml 
b/demos/profiles/static/src/main/resources/features.xml
new file mode 100644
index 0000000..86d2f23
--- /dev/null
+++ b/demos/profiles/static/src/main/resources/features.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+      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.
+-->
+<features name="static-framework-${project.version}" 
xmlns="http://karaf.apache.org/xmlns/features/v1.2.1"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.1 
http://karaf.apache.org/xmlns/features/v1.2.1";>
+
+    <feature version="${project.version}" description="Karaf core feature" 
name="static-framework">
+        <!-- logging -->
+        <bundle start="true" 
start-level="8">mvn:org.ops4j.pax.logging/pax-logging-api/${pax.logging.version}</bundle>
+        <bundle start="true" 
start-level="8">mvn:org.ops4j.pax.logging/pax-logging-service/${pax.logging.version}</bundle>
+        <!-- static config admin -->
+        <bundle start="true" 
start-level="10">mvn:org.apache.karaf.services/org.apache.karaf.services.staticcm/${project.version}</bundle>
+    </feature>
+
+</features>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 84342d3..c4dca1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -678,6 +678,11 @@
 
             <dependency>
                 <groupId>org.apache.karaf.services</groupId>
+                <artifactId>org.apache.karaf.services.staticcm</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.karaf.services</groupId>
                 <artifactId>org.apache.karaf.services.eventadmin</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/pom.xml
----------------------------------------------------------------------
diff --git a/services/pom.xml b/services/pom.xml
index ddcb15a..1fadd54 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -36,6 +36,7 @@
     <modules>
         <module>coordinator</module>
         <module>eventadmin</module>
+        <module>staticcm</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/staticcm/pom.xml
----------------------------------------------------------------------
diff --git a/services/staticcm/pom.xml b/services/staticcm/pom.xml
new file mode 100644
index 0000000..d42e8c8
--- /dev/null
+++ b/services/staticcm/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>karaf</artifactId>
+        <groupId>org.apache.karaf</groupId>
+        <version>4.0.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.services</groupId>
+    <artifactId>org.apache.karaf.services.staticcm</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: OSGi Services :: Static ConfigAdmin</name>
+    <description>Static ConfigAdmin Service</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>
+                            ${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Bundle-Activator>
+                            org.apache.karaf.services.staticcm.Activator
+                        </Bundle-Activator>
+                        <Bundle-Vendor>The Apache Software 
Foundation</Bundle-Vendor>
+                        <DynamicImport-Package>
+                            org.osgi.service.log;version="[1.3,2)"
+                        </DynamicImport-Package>
+                        <Import-Package>
+                            org.osgi.service.cm,
+                            *
+                        </Import-Package>
+                        <Export-Package>org.osgi.service.cm</Export-Package>
+                        <Private-Package>
+                            org.apache.karaf.services.staticcm,
+                            org.apache.felix.utils.properties
+                        </Private-Package>
+                        <Import-Service>
+                        </Import-Service>
+                        <Export-Service>
+                            org.osgi.service.cm.ConfigurationAdmin
+                        </Export-Service>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Activator.java
----------------------------------------------------------------------
diff --git 
a/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Activator.java
 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Activator.java
new file mode 100644
index 0000000..6154509
--- /dev/null
+++ 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Activator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.karaf.services.staticcm;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class Activator implements BundleActivator {
+
+    public static final String CONFIG_DIRS = 
"org.apache.karaf.services.staticcm.ConfigDirs";
+
+    ServiceRegistration<ConfigurationAdmin> registration;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        List<Configuration> configs = new ArrayList<>();
+
+        String cfgDirs = context.getProperty(CONFIG_DIRS);
+        if (cfgDirs == null) {
+            cfgDirs = System.getProperty("karaf.etc");
+        }
+        for (String dir : cfgDirs.split(",")) {
+            List<Configuration> cfgs = 
Configurations.loadConfigurations(context, new File(dir.trim()));
+            configs.addAll(cfgs);
+        }
+
+        StaticConfigAdminImpl cm = new StaticConfigAdminImpl(context, configs);
+        registration = context.registerService(ConfigurationAdmin.class, cm, 
null);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        if (registration != null) {
+            registration.unregister();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Configurations.java
----------------------------------------------------------------------
diff --git 
a/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Configurations.java
 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Configurations.java
new file mode 100644
index 0000000..6b4c11c
--- /dev/null
+++ 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/Configurations.java
@@ -0,0 +1,92 @@
+/*
+ * 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.karaf.services.staticcm;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.felix.utils.properties.InterpolationHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.Configuration;
+
+public class Configurations {
+
+    public static List<Configuration> loadConfigurations(BundleContext 
context, File directory) throws IOException {
+        Map<String, Map<String, String>> configs = new HashMap<>();
+        File[] files = directory.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.getName().endsWith(".cfg")) {
+                    try (InputStream in = new BufferedInputStream(new 
FileInputStream(file))) {
+                        final Properties p = new Properties();
+                        in.mark(1);
+                        boolean isXml = in.read() == '<';
+                        in.reset();
+                        if (isXml) {
+                            p.loadFromXML(in);
+                        } else {
+                            p.load(in);
+                        }
+                        Map<String, String> strMap = new HashMap<>();
+                        for (Object k : p.keySet()) {
+                            strMap.put(k.toString(), 
p.getProperty(k.toString()));
+                        }
+                        configs.put(file.getName(), strMap);
+                    }
+                }
+            }
+        }
+        return createConfigurations(context, configs);
+    }
+
+    public static List<Configuration> createConfigurations(BundleContext 
context, Map<String, Map<String, String>> configs) {
+        List<Configuration> configurations = new ArrayList<>();
+        for (Map.Entry<String, Map<String, String>> entry : 
configs.entrySet()) {
+            String pid[] = parsePid(entry.getKey());
+            Map<String, String> cfg = entry.getValue();
+            InterpolationHelper.performSubstitution(cfg, context);
+            cfg.put(Constants.SERVICE_PID, pid[0]);
+            configurations.add(new StaticConfigurationImpl(pid[0], pid[1], new 
Hashtable<String, Object>(cfg)));
+        }
+        return configurations;
+    }
+
+    private static String[] parsePid(String path) {
+        String pid = path.substring(0, path.lastIndexOf('.'));
+        int n = pid.indexOf('-');
+        if (n > 0) {
+            String factoryPid = pid.substring(n + 1);
+            pid = pid.substring(0, n);
+            return new String[] { pid, factoryPid };
+        } else {
+            return new String[] { pid, null };
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigAdminImpl.java
----------------------------------------------------------------------
diff --git 
a/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigAdminImpl.java
 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigAdminImpl.java
new file mode 100644
index 0000000..d6e8d92
--- /dev/null
+++ 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigAdminImpl.java
@@ -0,0 +1,157 @@
+/*
+ * 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.karaf.services.staticcm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class StaticConfigAdminImpl implements ConfigurationAdmin {
+    private final BundleContext context;
+    private final List<Configuration> configurations;
+
+    public StaticConfigAdminImpl(BundleContext context, List<Configuration> 
configs) throws IOException {
+        Objects.requireNonNull(configs, "configs");
+        this.context = context;
+        this.configurations = configs;
+        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;
+                    boolean found = false;
+                    for (Configuration config : configurations) {
+                        if (config.getPid().equals(pid) && 
config.getFactoryPid() == null) {
+                            try {
+                                found = true;
+                                service.updated(config.getProperties());
+                            } catch (ConfigurationException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                    if (!found) {
+                        try {
+                            service.updated(null);
+                        } catch (ConfigurationException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                } else {
+                    System.err.println("Unsupported pid: " + pidObj);
+                }
+                return service;
+            }
+
+            @Override
+            public void removedService(ServiceReference<ManagedService> 
reference, ManagedService service) {
+                context.ungetService(reference);
+            }
+        };
+        serviceTracker.open();
+
+        ServiceTracker<ManagedServiceFactory, ManagedServiceFactory> 
factoryTracker
+                = new ServiceTracker<ManagedServiceFactory, 
ManagedServiceFactory>(context, ManagedServiceFactory.class, null) {
+            @Override
+            public ManagedServiceFactory 
addingService(ServiceReference<ManagedServiceFactory> reference) {
+                ManagedServiceFactory factory = context.getService(reference);
+                Object pidObj = reference.getProperty(Constants.SERVICE_PID);
+                if (pidObj instanceof String) {
+                    String pid = (String) pidObj;
+                    for (Configuration config : configurations) {
+                        if (config.getPid().equals(pid) && 
config.getFactoryPid() != null) {
+                            try {
+                                factory.updated(config.getFactoryPid(), 
config.getProperties());
+                            } catch (ConfigurationException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                } else {
+                    System.err.println("Unsupported pid: " + pidObj);
+                }
+                return factory;
+            }
+
+            @Override
+            public void removedService(ServiceReference<ManagedServiceFactory> 
reference, ManagedServiceFactory service) {
+                super.removedService(reference, service);
+            }
+        };
+        factoryTracker.open();
+    }
+
+    @Override
+    public Configuration createFactoryConfiguration(String factoryPid) throws 
IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Configuration createFactoryConfiguration(String factoryPid, String 
location) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Configuration getConfiguration(String pid, String location) throws 
IOException {
+        return getConfiguration(pid);
+    }
+
+    @Override
+    public Configuration getConfiguration(String pid) throws IOException {
+        for (Configuration config : configurations) {
+            if (config.getPid().equals(pid) && config.getFactoryPid() == null) 
{
+                return config;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Configuration[] listConfigurations(String filter) throws 
IOException, InvalidSyntaxException {
+        List<Configuration> configs;
+        if (filter == null) {
+            configs = configurations;
+        } else {
+            configs = new ArrayList<>();
+            Filter flt = context.createFilter(filter);
+            for (Configuration config : configurations) {
+                if (flt.match(config.getProperties())) {
+                    configs.add(config);
+                }
+            }
+        }
+        return configs.isEmpty() ? null : configs.toArray(new 
Configuration[configs.size()]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/3bae561f/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigurationImpl.java
----------------------------------------------------------------------
diff --git 
a/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigurationImpl.java
 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigurationImpl.java
new file mode 100644
index 0000000..b7d3fe6
--- /dev/null
+++ 
b/services/staticcm/src/main/java/org/apache/karaf/services/staticcm/StaticConfigurationImpl.java
@@ -0,0 +1,83 @@
+/*
+ * 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.karaf.services.staticcm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.osgi.service.cm.Configuration;
+
+public class StaticConfigurationImpl implements Configuration {
+    private final String pid;
+    private final String factoryPid;
+    private final Map<String, Object> properties;
+
+    public StaticConfigurationImpl(String pid, String factoryPid, Map<String, 
Object> properties) {
+        this.pid = pid;
+        this.factoryPid = factoryPid;
+        this.properties = properties;
+    }
+
+    @Override
+    public String getPid() {
+        return pid;
+    }
+
+    @Override
+    public Dictionary<String, Object> getProperties() {
+        return new Hashtable<>(properties);
+    }
+
+    @Override
+    public void update(Dictionary<String, ?> properties) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void delete() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getFactoryPid() {
+        return factoryPid;
+    }
+
+    @Override
+    public void update() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setBundleLocation(String location) {
+    }
+
+    @Override
+    public String getBundleLocation() {
+        return null;
+    }
+
+    @Override
+    public long getChangeCount() {
+        return 0;
+    }
+
+}

Reply via email to