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;
+ }
+
+}