SLING-2976 :  Add support for instance name and description 

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1506410 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index c8273d4..36ed3d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,11 +62,8 @@
                 <configuration>
                     <instructions>
                         <Bundle-DocURL>
-                            http://sling.apache.org/site/sling-settings-orgapacheslingsettings.html
+                            http://sling.apache.org/documentation/bundles/sling-settings-orgapacheslingsettings.html
                         </Bundle-DocURL>
-                        <Export-Package>
-                            org.apache.sling.settings;version=1.2.0
-                        </Export-Package>
                         <Private-Package>
                             org.apache.sling.settings.impl
                         </Private-Package>
diff --git a/src/main/java/org/apache/sling/settings/SlingSettingsService.java b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
index 6c3dece..e9e1b08 100644
--- a/src/main/java/org/apache/sling/settings/SlingSettingsService.java
+++ b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
@@ -117,4 +117,29 @@
      */
     Set<String> getRunModes();
 
+    /**
+     * Return the optional name of the instance.
+     * @return The name of the instance or <code>null</code>.
+     * @see #setSlingName(String)
+     */
+    String getSlingName();
+
+    /**
+     * Set the name of the instance.
+     * @param value A new name.
+     */
+    void setSlingName(String value);
+
+    /**
+     * Return the optional description of the instance.
+     * @return The description of the instance or <code>null</code>.
+     * @see #setSlingDescrption(String)
+     */
+    String getSlingDescription();
+
+    /**
+     * Set the description of the instance.
+     * @param value A new description.
+     */
+    void setSlingDescrption(String value);
 }
diff --git a/src/main/java/org/apache/sling/settings/impl/SlingSettingsPrinter.java b/src/main/java/org/apache/sling/settings/impl/SlingSettingsPrinter.java
index bec99e8..0c1ad50 100644
--- a/src/main/java/org/apache/sling/settings/impl/SlingSettingsPrinter.java
+++ b/src/main/java/org/apache/sling/settings/impl/SlingSettingsPrinter.java
@@ -78,6 +78,12 @@
         pw.print("Sling ID = ");
         pw.print(this.settings.getSlingId());
         pw.println();
+        pw.print("Sling Name = ");
+        pw.print(this.settings.getSlingName());
+        pw.println();
+        pw.print("Sling Description = ");
+        pw.print(this.settings.getSlingDescription());
+        pw.println();
         pw.print("Sling Home = ");
         pw.print(this.settings.getSlingHomePath());
         pw.println();
diff --git a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
index 8836a57..c2c9be0 100644
--- a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
+++ b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
@@ -22,8 +22,10 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
 import java.io.Serializable;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -31,6 +33,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
 
@@ -47,6 +50,12 @@
 public class SlingSettingsServiceImpl
     implements SlingSettingsService {
 
+    /** Property containing the sling name. */
+    private static final String SLING_NAME = "sling.name";
+
+    /** Property containing the sling description. */
+    private static final String SLING_DESCRIPTION = "sling.description";
+
     /** The logger */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -56,17 +65,25 @@
     /** The sling home */
     private String slingHome;
 
+    /** The sling properties */
+    private Properties slingProps;
+
     /** The sling home url */
     private URL slingHomeUrl;
 
     private Set<String> runModes;
 
+    /** The name of the data file holding additional properties. */
+    private static final String PROPS_FILE = "sling.props.file";
+
     /** The name of the data file holding the sling id. */
-    private static final String DATA_FILE = "sling.id.file";
+    private static final String ID_FILE = "sling.id.file";
 
     /** The name of the data file holding install run mode options */
     private static final String OPTIONS_FILE = "sling.options.file";
 
+    private File slingPropsFile;
+
     /**
      * Create the service and search the Sling home urls and
      * get/create a sling id.
@@ -75,6 +92,7 @@
      */
     public SlingSettingsServiceImpl(final BundleContext context,
             final StartupHandler handler) {
+        this.setupSlingProps(context);
         this.setupSlingHome(context);
         this.setupSlingId(context);
 
@@ -105,7 +123,7 @@
      */
     private void setupSlingId(final BundleContext context) {
         // try to read the id from the id file first
-        final File idFile = context.getDataFile(DATA_FILE);
+        final File idFile = context.getDataFile(ID_FILE);
         if ( idFile == null ) {
             // the osgi framework does not support storing something in the file system
             throw new RuntimeException("Unable to read from bundle data file.");
@@ -119,6 +137,41 @@
         }
     }
 
+    /**
+     * Get / create sling id
+     */
+    private void setupSlingProps(final BundleContext context) {
+        // try to read the props from the file
+        this.slingPropsFile = context.getDataFile(PROPS_FILE);
+        if ( this.slingPropsFile == null ) {
+            // the OSGi framework does not support storing something in the file system
+            throw new RuntimeException("Unable to read from bundle data file.");
+        }
+        this.slingProps = new Properties();
+        if ( this.slingPropsFile.exists() ) {
+            InputStream reader = null;
+            try {
+                reader = new FileInputStream(this.slingPropsFile);
+                this.slingProps.load(reader);
+
+            } catch ( final IOException ioe ) {
+                logger.error("Unable to read properties file " + this.slingPropsFile + " : " + ioe.getMessage(), ioe);
+            } finally {
+                if ( reader != null ) {
+                    try {
+                        reader.close();
+                    } catch (final IOException ignore) {}
+                }
+            }
+        }
+        if ( this.slingProps.getProperty(SLING_NAME) == null && context.getProperty(SLING_NAME) != null ) {
+            this.slingProps.setProperty(SLING_NAME, context.getProperty(SLING_NAME));
+        }
+        if ( this.slingProps.getProperty(SLING_DESCRIPTION) == null && context.getProperty(SLING_DESCRIPTION) != null ) {
+            this.slingProps.setProperty(SLING_DESCRIPTION, context.getProperty(SLING_DESCRIPTION));
+        }
+    }
+
     private static final class Options implements Serializable {
         private static final long serialVersionUID = 1L;
         String[] modes;
@@ -159,7 +212,6 @@
     /**
      * Set up run modes.
      */
-    @SuppressWarnings("unchecked")
     private void setupRunModes(final BundleContext context,
             final StartupMode startupMode) {
         final Set<String> modesSet = new HashSet<String>();
@@ -346,4 +398,69 @@
     public Set<String> getRunModes() {
         return this.runModes;
     }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#getSlingName()
+     */
+    public String getSlingName() {
+        String name = this.slingProps.getProperty(SLING_NAME);
+        if ( name == null ) {
+            name = "Instance " + this.slingId; // default
+        }
+        return name;
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#setSlingName(java.lang.String)
+     */
+    public void setSlingName(final String value) {
+        if ( value == null ) {
+            this.slingProps.setProperty(SLING_NAME, "");
+        } else {
+            this.slingProps.setProperty(SLING_NAME, value);
+        }
+        this.writeSlingProps();
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#getSlingDescription()
+     */
+    public String getSlingDescription() {
+        String desc = this.slingProps.getProperty(SLING_DESCRIPTION);
+        if ( desc == null ) {
+            desc = "Instance with id " + this.slingId + " and run modes " + this.getRunModes(); // default
+        }
+        return desc;
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#setSlingDescrption(java.lang.String)
+     */
+    public void setSlingDescrption(final String value) {
+        if ( value == null ) {
+            this.slingProps.setProperty(SLING_DESCRIPTION, "");
+        } else {
+            this.slingProps.setProperty(SLING_DESCRIPTION, value);
+        }
+        this.writeSlingProps();
+    }
+
+    private void writeSlingProps() {
+        if ( this.slingPropsFile != null ) {
+            OutputStream writer = null;
+            try {
+                writer = new FileOutputStream(this.slingPropsFile);
+                this.slingProps.store(writer, null);
+            } catch ( final IOException ioe ) {
+                logger.error("Unable to write properties file " + this.slingPropsFile + " : " + ioe.getMessage(), ioe);
+            } finally {
+                if ( writer != null ) {
+                    try {
+                        writer.close();
+                    } catch (final IOException ignore) {}
+                }
+            }
+
+        }
+    }
 }
diff --git a/src/main/java/org/apache/sling/settings/package-info.java b/src/main/java/org/apache/sling/settings/package-info.java
new file mode 100644
index 0000000..852dd27
--- /dev/null
+++ b/src/main/java/org/apache/sling/settings/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @version 1.3.0
+ */
+@Version("1.3.0")
+package org.apache.sling.settings;
+
+import aQute.bnd.annotation.Version;
+