Author: cschneider
Date: Tue Mar 13 15:09:20 2012
New Revision: 1300176

URL: http://svn.apache.org/viewvc?rev=1300176&view=rev
Log:
KARAF-963 restructuring of config to new module layout

Added:
    karaf/trunk/config/core/src/main/java/org/apache/karaf/config/
    karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/
    
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
    karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/
    
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java

Added: 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java?rev=1300176&view=auto
==============================================================================
--- 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
 (added)
+++ 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/ConfigRepository.java
 Tue Mar 13 15:09:20 2012
@@ -0,0 +1,37 @@
+package org.apache.karaf.config.core;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public interface ConfigRepository {
+
+    /**
+     * Saves config to storage or ConfigurationAdmin.
+     * @param pid
+     * @param props
+     * @param bypassStorage
+     * @throws IOException
+     */
+    @SuppressWarnings("rawtypes")
+    void update(String pid, Dictionary props, boolean bypassStorage) throws 
IOException;
+
+    /**
+     * Saves config to storage or ConfigurationAdmin.
+     * @param pid
+     * @param props
+     * @param bypassStorage
+     * @throws IOException
+     */
+    @SuppressWarnings("rawtypes")
+    void update(String pid, Dictionary props) throws IOException;
+
+    void delete(String pid) throws Exception;
+
+    @SuppressWarnings("rawtypes")
+    Dictionary getConfigProperties(String pid) throws IOException, 
InvalidSyntaxException;
+
+    ConfigurationAdmin getConfigAdmin();
+}

Added: 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java?rev=1300176&view=auto
==============================================================================
--- 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
 (added)
+++ 
karaf/trunk/config/core/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
 Tue Mar 13 15:09:20 2012
@@ -0,0 +1,252 @@
+/*
+ * 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.config.core.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.fileinstall.ArtifactInstaller;
+import org.apache.felix.utils.properties.Properties;
+import org.apache.karaf.config.core.ConfigRepository;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigRepositoryImpl implements ConfigRepository {
+    private static final Logger LOG = 
LoggerFactory.getLogger(ConfigRepositoryImpl.class);
+    private static final String 
FILEINSTALL_FILE_NAME="felix.fileinstall.filename";
+
+    private static final String PID_FILTER="(service.pid=%s*)";
+    private static final String FILE_PREFIX="file:";
+    private static final String CONFIG_SUFFIX=".cfg";
+    private static final String FACTORY_SEPARATOR = "-";
+
+    private ConfigurationAdmin configAdmin;
+    
+    private File storage;
+    private List<ArtifactInstaller> artifactInstallers;
+
+    public ConfigRepositoryImpl(File storage, ConfigurationAdmin configAdmin, 
List<ArtifactInstaller> artifactInstallers) {
+        this.storage = storage;
+        this.configAdmin = configAdmin;
+        this.artifactInstallers = artifactInstallers;
+    }
+    
+    /**
+     * <p>
+     * Returns the Configuration object of the given (felix fileinstall) file 
name.
+     * </p>
+     * @param fileName
+     * @return
+     */
+    @SuppressWarnings("rawtypes")
+    public Configuration findConfigurationByFileName(String fileName) throws 
IOException, InvalidSyntaxException {
+        if (fileName != null && fileName.contains(FACTORY_SEPARATOR)) {
+            String factoryPid = fileName.substring(0, 
fileName.lastIndexOf(FACTORY_SEPARATOR));
+            String absoluteFileName = FILE_PREFIX +storage.getAbsolutePath() + 
File.separator + fileName + CONFIG_SUFFIX;
+            Configuration[] configurations = 
this.configAdmin.listConfigurations(String.format(PID_FILTER, factoryPid));
+            if (configurations != null) {
+                for (Configuration configuration : configurations) {
+                    Dictionary dictionary = configuration.getProperties();
+                    if (dictionary != null) {
+                        String fileInstallFileName = (String) 
dictionary.get(FILEINSTALL_FILE_NAME);
+                        if (absoluteFileName.equals(fileInstallFileName)) {
+                            return configuration;
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see 
org.apache.karaf.shell.config.impl.ConfigRepository#update(java.lang.String, 
java.util.Dictionary, boolean)
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public void update(String pid, Dictionary props, boolean bypassStorage) 
throws IOException {
+        if (!bypassStorage && storage != null) {
+            persistConfiguration(pid, props);
+        } else {
+            updateConfiguration(pid, props);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see 
org.apache.karaf.shell.config.impl.ConfigRepository#update(java.lang.String, 
java.util.Dictionary)
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public void update(String pid, Dictionary props) throws IOException {
+        update(pid, props, false);
+    }
+
+    /**
+     * Persists configuration to storage.
+     * @param admin
+     * @param pid
+     * @param props
+     * @throws IOException
+     */
+    @SuppressWarnings("rawtypes")
+    private void persistConfiguration(String pid, Dictionary props) throws 
IOException {
+        File storageFile = new File(storage, pid + ".cfg");
+        Configuration cfg = this.configAdmin.getConfiguration(pid, null);
+        if (cfg != null && cfg.getProperties() != null) {
+            Object val = cfg.getProperties().get(FILEINSTALL_FILE_NAME);
+            if (val instanceof String) {
+                if (((String) val).startsWith("file:")) {
+                    val = ((String) val).substring("file:".length());
+                }
+                storageFile = new File((String) val);
+            }
+        }
+        Properties p = new Properties(storageFile);
+        for (Enumeration keys = props.keys(); keys.hasMoreElements();) {
+            Object key = keys.nextElement();
+            if (shouldPersist(key)) {
+                p.put((String) key, (String) props.get(key));
+            }
+        }
+        // remove "removed" properties from the file
+        ArrayList<String> propertiesToRemove = new ArrayList<String>();
+        for (Object key : p.keySet()) {
+            if (props.get(key) == null
+                    && shouldPersist(key)) {
+                propertiesToRemove.add(key.toString());
+            }
+        }
+        for (String key : propertiesToRemove) {
+            p.remove(key);
+        }
+        // save the cfg file
+        storage.mkdirs();
+        p.save();
+        updateFileInstall(storageFile);
+    }
+    
+    /**
+     * Trigger felix fileinstall to update the config so there is no delay 
till it polls the file
+     * 
+     * @param storageFile
+     * @throws Exception
+     */
+    private void updateFileInstall(File storageFile) {
+        if (artifactInstallers != null) {
+            for (ArtifactInstaller installer : artifactInstallers) {
+                if (installer.canHandle(storageFile)) {
+                    try {
+                        installer.update(storageFile);
+                    } catch (Exception e) {
+                        LOG.warn("Error updating config " + storageFile + " in 
felix fileinstall" + e.getMessage(), e);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean shouldPersist(Object key) {
+        return !Constants.SERVICE_PID.equals(key)
+                && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
+                && !FILEINSTALL_FILE_NAME.equals(key);
+    }
+
+    /**
+     * Updates the configuration to the {@link ConfigurationAdmin} service.
+     * @param pid
+     * @param props
+     * @throws IOException
+     */
+    @SuppressWarnings("rawtypes")
+    public void updateConfiguration(String pid, Dictionary props) throws 
IOException {
+        Configuration cfg = this.configAdmin.getConfiguration(pid, null);
+        if (cfg.getProperties() == null) {
+            PidParts pidParts = parsePid(pid);
+            if (pidParts.factoryPid != null) {
+                cfg = 
this.configAdmin.createFactoryConfiguration(pidParts.pid, null);
+            }
+        }
+        if (cfg.getBundleLocation() != null) {
+            cfg.setBundleLocation(null);
+        }
+        cfg.update(props);
+    }
+
+    private PidParts parsePid(String sourcePid) {
+        PidParts pidParts = new PidParts();
+        int n = sourcePid.indexOf('-');
+        if (n > 0) {
+            pidParts.factoryPid = sourcePid.substring(n + 1);
+            pidParts.pid = sourcePid.substring(0, n);
+        } else {
+            pidParts.pid = sourcePid;
+        }
+        return pidParts;
+    }
+    
+    private class PidParts {
+        String pid;
+        String factoryPid;
+    }
+    
+    /* (non-Javadoc)
+     * @see 
org.apache.karaf.shell.config.impl.ConfigRepository#delete(java.lang.String)
+     */
+    @Override
+    public void delete(String pid) throws Exception {
+        Configuration configuration = this.configAdmin.getConfiguration(pid);
+        configuration.delete();
+        deleteStorage(pid);
+    }
+    
+    protected void deleteStorage(String pid) throws Exception {
+        if (storage != null) {
+            File cfgFile = new File(storage, pid + ".cfg");
+            cfgFile.delete();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see 
org.apache.karaf.shell.config.impl.ConfigRepository#getConfigProperties(java.lang.String)
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public Dictionary getConfigProperties(String pid) throws IOException, 
InvalidSyntaxException {
+        if(pid != null && configAdmin != null) {
+            Configuration configuration = 
this.configAdmin.getConfiguration(pid);
+            if(configuration != null) {
+                Dictionary props = configuration.getProperties();
+                return (props != null) ? props : new Hashtable<String, 
String>();
+            }
+        }
+        return null;
+    }
+
+    public ConfigurationAdmin getConfigAdmin() {
+        return this.configAdmin;
+    }
+
+}


Reply via email to