merging mavenized branch changes from revision 382466 to the current head
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@383566 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.daemon/pom.xml b/org.apache.felix.daemon/pom.xml
new file mode 100644
index 0000000..18d382e
--- /dev/null
+++ b/org.apache.felix.daemon/pom.xml
@@ -0,0 +1,23 @@
+<project>
+ <parent>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>felix</artifactId>
+ <version>0.8-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>jar</packaging>
+ <name>Apache Felix Daemon</name>
+ <artifactId>org.apache.felix.daemon</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.directory.daemon</groupId>
+ <artifactId>daemon-bootstrappers</artifactId>
+ <version>1.0-RC1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/FelixLayout.java b/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/FelixLayout.java
new file mode 100644
index 0000000..b27bf35
--- /dev/null
+++ b/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/FelixLayout.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.felix.daemon;
+
+
+import java.io.File;
+import org.apache.directory.daemon.InstallationLayout;
+
+
+/**
+ * A felix specific installation layout.
+ *
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class FelixLayout extends InstallationLayout
+{
+ public FelixLayout( InstallationLayout layout )
+ {
+ super( layout.getBaseDirectory() );
+ }
+
+
+ public FelixLayout( File baseDirectory )
+ {
+ super( baseDirectory );
+ }
+
+
+ public FelixLayout( String baseDirectoryPath )
+ {
+ super( baseDirectoryPath );
+ }
+
+
+ public File getBundleDirectory()
+ {
+ return new File( super.baseDirectory, "bundle" );
+ }
+
+
+ public File getConfigurationFile()
+ {
+ return super.getConfigurationFile( "config.properties" );
+ }
+
+
+ public File getSystemPropertiesFile()
+ {
+ return new File( super.baseDirectory, "system.properties" );
+ }
+}
diff --git a/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/Service.java b/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/Service.java
new file mode 100644
index 0000000..f2da2c9
--- /dev/null
+++ b/org.apache.felix.daemon/src/main/java/org/apache/felix/daemon/Service.java
@@ -0,0 +1,268 @@
+package org.apache.felix.daemon;
+
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.apache.directory.daemon.DaemonApplication;
+import org.apache.directory.daemon.InstallationLayout;
+
+import org.apache.felix.framework.Felix;
+import org.apache.felix.framework.cache.DefaultBundleCache;
+import org.apache.felix.framework.util.MutablePropertyResolverImpl;
+import org.apache.felix.framework.util.StringMap;
+
+
+/**
+ * NOTE: Does not set system properties which are done via a daemon ui, some
+ * init script, or a main() application entry point.
+ */
+public class Service implements DaemonApplication
+{
+ /**
+ * The system property name used to specify an URL to the configuration
+ * property file to be used for the created the framework instance.
+ */
+ public static final String CONFIG_PROPERTIES_PROP = "felix.config.properties";
+ /** The default name used for the configuration properties file. */
+ public static final String CONFIG_PROPERTIES_FILE_VALUE = "config.properties";
+ /** the default profile if no profile name or path is specified */
+ public static final String DEFAULT_PRODUCTION_PROFILE = "production";
+
+ /** the instance of Felix managed by this daemon/service */
+ private Felix instance;
+ /** the configuration properties loaded from the configuration file */
+ private Properties configationProperties;
+ /** the felix installation layout */
+ private FelixLayout layout;
+
+
+ public void init( InstallationLayout suppliedLayout, String[] args ) throws Exception
+ {
+ if ( !( suppliedLayout instanceof FelixLayout ) )
+ {
+ this.layout = new FelixLayout( suppliedLayout );
+ }
+ else
+ {
+ this.layout = ( FelixLayout ) suppliedLayout;
+ }
+
+ instance = new Felix();
+ configationProperties = readConfigProperties();
+ }
+
+
+ public void start()
+ {
+ // See if the profile name property was specified.
+ String profileName = configationProperties.getProperty( DefaultBundleCache.CACHE_PROFILE_PROP );
+
+ // See if the profile directory property was specified.
+ String profileDirName = configationProperties.getProperty( DefaultBundleCache.CACHE_PROFILE_DIR_PROP );
+
+ // If no profile or profile directory is specified in the properties, then set the
+ // name to the default production mode profile name since this is not started from main()
+ if ( ( profileName == null ) && ( profileDirName == null ) )
+ {
+ configationProperties.setProperty( DefaultBundleCache.CACHE_PROFILE_PROP, DEFAULT_PRODUCTION_PROFILE );
+ }
+
+ // start up the instance using the loaded and possibly altered configuration
+ instance.start( new MutablePropertyResolverImpl( new StringMap( configationProperties, false ) ), null );
+ }
+
+
+ public void stop( String[] arg0 ) throws Exception
+ {
+ instance.shutdown();
+ }
+
+
+ public void destroy()
+ {
+ }
+
+
+ /**
+ * Exposes configuration properties for potential alteration between load
+ * time at init() and start() by the managing framework or by the main().
+ *
+ * @return the configuration properties loaded by default from conf/config.properties
+ */
+ public Properties getConfigurationProperties()
+ {
+ return configationProperties;
+ }
+
+
+ /**
+ * <p>
+ * Reads the configuration properties in the configuration property
+ * file associated with the framework installation; these properties are
+ * only accessible to the framework and are intended for configuration
+ * purposes. By default, the configuration property file is located in
+ * the same directory as the <tt>felix.jar</tt> file and is called
+ * "<tt>config.properties</tt>". This may be changed by setting the
+ * "<tt>felix.config.properties</tt>" system property to an
+ * arbitrary URL.
+ * </p>
+ * @return A <tt>Properties</tt> instance or <tt>null</tt> if there was an error.
+ */
+ private Properties readConfigProperties()
+ {
+ // The config properties file is either present in a default
+ // location using the layout, or is specified by a system property
+ // Try to load it from one of these places.
+
+ // See if the property URL was specified as a property.
+ URL propURL = null;
+ String custom = System.getProperty( CONFIG_PROPERTIES_PROP );
+ if ( custom != null )
+ {
+ try
+ {
+ propURL = new URL( custom );
+ }
+ catch ( MalformedURLException ex )
+ {
+ System.err.print( "Main: " + ex );
+ return null;
+ }
+ }
+ else
+ {
+ try
+ {
+ propURL = layout.getConfigurationFile().toURL();
+ }
+ catch ( MalformedURLException ex )
+ {
+ System.err.print( "Main: " + ex );
+ return null;
+ }
+ }
+
+ // Read the properties file.
+ Properties props = new Properties();
+ InputStream is = null;
+ try
+ {
+ is = propURL.openConnection().getInputStream();
+ props.load( is );
+ is.close();
+ }
+ catch ( FileNotFoundException ex )
+ {
+ // Ignore file not found.
+ }
+ catch ( Exception ex )
+ {
+ System.err.println( "Error loading config properties from " + propURL );
+ System.err.println( "Main: " + ex );
+
+ try
+ {
+ if ( is != null )
+ {
+ is.close();
+ }
+ }
+ catch ( IOException ex2 )
+ {
+ // Nothing we can do.
+ }
+
+ return null;
+ }
+
+ // Perform variable substitution for system properties.
+ for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); /* EMPTY */ )
+ {
+ String name = ( String ) e.nextElement();
+ props.setProperty( name, substVars( ( String ) props.getProperty( name ) ) );
+ }
+
+ return props;
+ }
+
+
+ private static final String DELIM_START = "${";
+ private static final char DELIM_STOP = '}';
+ private static final int DELIM_START_LEN = 2;
+ private static final int DELIM_STOP_LEN = 1;
+
+
+ /**
+ * <p>
+ * This method performs system property variable substitution on the
+ * specified string value. If the specified string contains the syntax
+ * <tt>${<system-prop-name>}</tt>, then the corresponding system
+ * property value is substituted for the marker.
+ * </p>
+ *
+ * @param val
+ * The string on which to perform system property substitution.
+ * @return The value of the specified string after system property
+ * substitution.
+ * @throws IllegalArgumentException
+ * If there was a syntax error in the system property variable
+ * marker syntax.
+ */
+ public static String substVars( String val ) throws IllegalArgumentException
+ {
+ StringBuffer sbuf = new StringBuffer();
+
+ if ( val == null )
+ {
+ return val;
+ }
+
+ int i = 0;
+ int j, k;
+
+ while ( true )
+ {
+ j = val.indexOf( DELIM_START, i );
+ if ( j == -1 )
+ {
+ if ( i == 0 )
+ {
+ return val;
+ }
+ else
+ {
+ sbuf.append( val.substring( i, val.length() ) );
+ return sbuf.toString();
+ }
+ }
+ else
+ {
+ sbuf.append( val.substring( i, j ) );
+ k = val.indexOf( DELIM_STOP, j );
+ if ( k == -1 )
+ {
+ throw new IllegalArgumentException( '"' + val
+ + "\" has no closing brace. Opening brace at position " + j + '.' );
+ }
+ else
+ {
+ j += DELIM_START_LEN;
+ String key = val.substring( j, k );
+ // Try system properties.
+ String replacement = System.getProperty( key, null );
+ if ( replacement != null )
+ {
+ sbuf.append( replacement );
+ }
+ i = k + DELIM_STOP_LEN;
+ }
+ }
+ }
+ }
+}