incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1209095 - in /sling/trunk/launchpad/base/src: main/java/org/apache/sling/launchpad/app/ main/java/org/apache/sling/launchpad/base/app/ main/java/org/apache/sling/launchpad/base/impl/ main/java/org/apache/sling/launchpad/base/shared/ main/j...
Date Thu, 01 Dec 2011 14:09:39 GMT
Author: cziegeler
Date: Thu Dec  1 14:09:34 2011
New Revision: 1209095

URL: http://svn.apache.org/viewvc?rev=1209095&view=rev
Log:
SLING-2203 : Allow for better configuration of sling home folder

Modified:
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/app/MainDelegate.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/SharedConstants.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/webapp/SlingServletDelegate.java
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
    sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java Thu
Dec  1 14:09:34 2011
@@ -293,7 +293,9 @@ public class Main {
         // The Loader helper
         Loader loaderTmp = null;
         try {
-            loaderTmp = new Loader(slingHome) {
+            final File launchpadHome = getLaunchpadHome(slingHome,
+                commandLineArgs);
+            loaderTmp = new Loader(launchpadHome) {
                 @Override
                 protected void info(String msg) {
                     Main.info(msg, null);
@@ -461,6 +463,39 @@ public class Main {
         return slingHome;
     }
 
+    /**
+     * Define the sling.launchpad parameter implementing the algorithme defined
+     * on the wiki page to find the setting according to this algorithm:
+     * <ol>
+     * <li>Configuration property <code>sling.launchpad</code>. This path
is
+     * resolved against the <code>slingHome</code> folder if relative.</li>
+     * <li>Default to same as <code>sling.home</code></li>
+     * </ol>
+     *
+     * @param slingHome The absolute path to the Sling Home folder (aka the
+     *            <code>sling.home</code>.
+     * @param commandLineArgs The configuration properties from where to get the
+     *            <code>sling.launchpad</code> property.
+     * @return The absolute <code>File</code> indicating the launchpad folder.
+     */
+    private static File getLaunchpadHome(final String slingHome,
+            final Map<String, String> commandLineArgs) {
+        String launchpadHomeParam = commandLineArgs.get(SharedConstants.SLING_LAUNCHPAD);
+        if (launchpadHomeParam == null || launchpadHomeParam.length() == 0) {
+            commandLineArgs.put(SharedConstants.SLING_LAUNCHPAD, slingHome);
+            return new File(slingHome);
+        }
+
+        File launchpadHome = new File(launchpadHomeParam);
+        if (!launchpadHome.isAbsolute()) {
+            launchpadHome = new File(slingHome, launchpadHomeParam);
+        }
+
+        commandLineArgs.put(SharedConstants.SLING_LAUNCHPAD,
+            launchpadHome.getAbsolutePath());
+        return launchpadHome;
+    }
+
     private void startupFailure(String message, Throwable cause) {
         error("Launcher JAR access failure: " + message, cause);
         error("Shutting Down", null);
@@ -567,7 +602,7 @@ public class Main {
         if (args.remove("h") != null) {
             System.out.println("usage: "
                 + Main.class.getName()
-                + " [ start | stop | status ] [ -j adr ] [ -l loglevel ] [ -f logfile ] [
-c slinghome ] [ -i launchpadhome ] [ -a address ] [ -p port ] [ -h ]");
+                + " [ start | stop | status ] [ -j adr ] [ -l loglevel ] [ -f logfile ] [
-c slinghome ] [ -i launchpadhome ] [ -a address ] [ -p port ] { -D n=v } [ -h ]");
 
             System.out.println("    start         listen for control connection (uses -j)");
             System.out.println("    stop          terminate running Apache Sling (uses -j)");
@@ -579,6 +614,7 @@ public class Main {
             System.out.println("    -i launchpadhome  the launchpad directory (default slinghome)");
             System.out.println("    -a address    the interfact to bind to (use 0.0.0.0 for
any) (not supported yet)");
             System.out.println("    -p port       the port to listen to (default 8080)");
+            System.out.println("    -D n=v        sets property n to value v");
             System.out.println("    -h            prints this usage message");
 
             return true;
@@ -633,6 +669,15 @@ public class Main {
                         props.put(SharedConstants.SLING_HOME, value);
                         break;
 
+                    case 'i':
+                        if (value == arg.getKey()) {
+                            errorArg("-i", "Missing launchpad directory value");
+                            errorArg = true;
+                            continue;
+                        }
+                        props.put(SharedConstants.SLING_LAUNCHPAD, value);
+                        break;
+
                     case 'a':
                         if (value == arg.getKey()) {
                             errorArg("-a", "Missing address value");
@@ -660,6 +705,17 @@ public class Main {
                         }
                         break;
 
+                    case 'D':
+                        if (value == arg.getKey()) {
+                            errorArg("-D", "Missing property assignment");
+                            errorArg = true;
+                            continue;
+                        }
+                        String[] parts = value.split("=");
+                        int valueIdx = (parts.length > 1) ? 1 : 0;
+                        props.put(parts[0], parts[valueIdx]);
+                        break;
+
                     default:
                         errorArg("-" + arg.getKey(), "Unrecognized option");
                         errorArg = true;

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/app/MainDelegate.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/app/MainDelegate.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/app/MainDelegate.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/app/MainDelegate.java
Thu Dec  1 14:09:34 2011
@@ -136,6 +136,17 @@ public class MainDelegate implements Lau
                 commandLine.get(SharedConstants.SLING_HOME));
         }
 
+        // ensure sling.launchpad is set
+        if (!commandLine.containsKey(SharedConstants.SLING_LAUNCHPAD)) {
+            commandLine.put(SharedConstants.SLING_LAUNCHPAD, slingHome);
+        }
+
+        // check sling.properties in the command line
+        final String slingPropertiesProp = commandLine.remove(SharedConstants.SLING_PROPERTIES);
+        if (slingPropertiesProp != null) {
+            props.put(SharedConstants.SLING_PROPERTIES, slingPropertiesProp);
+        }
+
         // set up and configure Felix Logger
         int logLevel;
         if (!commandLine.containsKey(PROP_LOG_LEVEL)) {

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
Thu Dec  1 14:09:34 2011
@@ -171,11 +171,15 @@ class BootstrapInstaller {
      */
     boolean install() throws IOException {
 
-        String slingHome = bundleContext.getProperty(SharedConstants.SLING_HOME);
-        File slingStartupDir = getSlingStartupDir(slingHome);
+        String launchpadHome = bundleContext.getProperty(SharedConstants.SLING_LAUNCHPAD);
+        if (launchpadHome == null) {
+            launchpadHome = bundleContext.getProperty(SharedConstants.SLING_HOME);
+        }
+        File slingStartupDir = getSlingStartupDir(launchpadHome);
 
         // execute bootstrap commands, if needed
-        final BootstrapCommandFile cmd = new BootstrapCommandFile(logger, new File(slingHome,
BOOTSTRAP_CMD_FILENAME));
+        final BootstrapCommandFile cmd = new BootstrapCommandFile(logger,
+            new File(launchpadHome, BOOTSTRAP_CMD_FILENAME));
         boolean requireRestart = cmd.execute(bundleContext);
 
         boolean shouldInstall = false;

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java
Thu Dec  1 14:09:34 2011
@@ -394,7 +394,7 @@ public class Sling {
         // Try to load it from one of these places.
         final Map<String, String> staticProps = new HashMap<String, String>();
 
-        // Read the properties file.
+        // Read the embedded (default) properties file.
         this.load(staticProps, CONFIG_PROPERTIES);
 
         // resolve inclusions (and remove property)
@@ -418,7 +418,7 @@ public class Sling {
 
         // overlay with ${sling.home}/sling.properties
         this.logger.log(Logger.LOG_INFO, "Starting Apache Sling in " + slingHome);
-        File propFile = new File(slingHome, CONFIG_PROPERTIES);
+        File propFile = getSlingProperties(slingHome, staticProps);
         this.load(staticProps, propFile);
 
         // migrate old properties to new properties
@@ -545,6 +545,7 @@ public class Sling {
 
             // remove properties where overlay makes no sense
             tmp.remove(SharedConstants.SLING_HOME);
+            tmp.remove(SharedConstants.SLING_LAUNCHPAD);
             tmp.remove(SharedConstants.SLING_PROPERTIES);
 
             tmp.store(os, "Overlay properties for configuration");
@@ -771,6 +772,20 @@ public class Sling {
     // ---------- Property file support ----------------------------------------
 
     /**
+     * Returns the abstract path name to the <code>sling.properties</code> file.
+     */
+    private File getSlingProperties(final String slingHome,
+            final Map<String, String> properties) {
+        final String prop = properties.get(SharedConstants.SLING_PROPERTIES);
+        if (prop == null) {
+            return new File(slingHome, CONFIG_PROPERTIES);
+        }
+
+        final File propFile = new File(prop);
+        return propFile.isAbsolute() ? propFile : new File(slingHome, prop);
+    }
+
+    /**
      * Looks for <code>sling.include</code> and <code>sling.include.*</code>
      * properties in the <code>props</code> and loads properties form the
      * respective locations.
@@ -1054,8 +1069,8 @@ public class Sling {
             OutputStream os = null;
             try {
                 final long lastModified = url.openConnection().getLastModified();
-                final File slingHome = new File(props.get(SharedConstants.SLING_HOME));
-                final File cmdFile = new File(slingHome, BootstrapInstaller.BOOTSTRAP_CMD_FILENAME);
+                final File launchpadHome = new File(props.get(SharedConstants.SLING_LAUNCHPAD));
+                final File cmdFile = new File(launchpadHome, BootstrapInstaller.BOOTSTRAP_CMD_FILENAME);
                 boolean copyFile = true;
                 if ( cmdFile.exists() && cmdFile.lastModified() >= lastModified
) {
                     copyFile = false;

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java
Thu Dec  1 14:09:34 2011
@@ -33,7 +33,7 @@ public class SlingFelix extends Felix {
 
     private final Notifiable notifiable;
 
-    private Notifier notifierThread;
+    private Thread notifierThread;
 
     public SlingFelix(Notifiable notifiable, Map<?, ?> props) throws Exception {
         super(props);
@@ -47,8 +47,17 @@ public class SlingFelix extends Felix {
 
     @Override
     public void update(InputStream is) throws BundleException {
-        // get the update file
-        startNotifier(true, is);
+        // get the update file and make sure, the stream is closed
+        try {
+            startNotifier(true, is);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
 
         // just stop the framework now
         super.stop();
@@ -67,20 +76,20 @@ public class SlingFelix extends Felix {
 
     private synchronized void startNotifier(boolean restart, InputStream ins) {
         if (notifierThread == null) {
-            notifierThread = new Notifier(restart, ins);
+            notifierThread = new Thread(new Notifier(restart, ins),
+                "Sling Notifier");
             notifierThread.setDaemon(false);
             notifierThread.start();
         }
     }
 
-    private class Notifier extends Thread {
+    private class Notifier implements Runnable {
 
         private final boolean restart;
 
         private final File updateFile;
 
         private Notifier(boolean restart, InputStream ins) {
-            super("Sling Notifier");
             this.restart = restart;
 
             if (ins != null) {
@@ -92,25 +101,24 @@ public class SlingFelix extends Felix {
                     // TOOD: log
                     tmpFile = null;
                 }
-                updateFile = tmpFile;
+                this.updateFile = tmpFile;
             } else {
-                updateFile = null;
+                this.updateFile = null;
             }
         }
 
-        @Override
         public void run() {
 
             try {
-                waitForStop(0);
+                SlingFelix.this.waitForStop(0);
             } catch (InterruptedException ie) {
                 // TODO: log
             }
 
             if (restart) {
-                notifiable.updated(updateFile);
+                SlingFelix.this.notifiable.updated(updateFile);
             } else {
-                notifiable.stopped();
+                SlingFelix.this.notifiable.stopped();
             }
         }
     }

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
Thu Dec  1 14:09:34 2011
@@ -46,32 +46,37 @@ import org.apache.sling.commons.osgi.bun
 public class Loader {
 
     /**
-     * The Sling home folder set by the constructor
+     * The launchpad home folder set by the constructor
      */
-    private final File slingHome;
+    private final File launchpadHome;
 
     /**
-     * Creates a loader instance to load from the given Sling home folder.
-     * Besides ensuring the existence of the Sling home folder, the constructor
-     * also removes all but the most recent launcher JAR files from the Sling
-     * home folder (thus cleaning up from previous upgrades).
+     * Creates a loader instance to load from the given launchpad home folder.
+     * Besides ensuring the existence of the launchpad home folder, the
+     * constructor also removes all but the most recent launcher JAR files from
+     * the Sling home folder (thus cleaning up from previous upgrades).
      *
-     * @param slingHome The Sling home folder. If this is <code>null</code> the
-     *            default value {@link SharedConstants#SLING_HOME_DEFAULT} is
-     *            assumed.
-     * @throws IllegalArgumentException If the Sling home folder exists but is
-     *             not a directory or if the Sling home folder cannot be
-     *             created.
+     * @param launchpadHome The launchpad home folder. This must not be
+     *            <code>null</code> or an empty string.
+     * @throws IllegalArgumentException If the <code>launchpadHome</code>
+     *             argument is <code>null</code> or an empty string or if the
+     *             launchpad home folder exists but is not a directory or if the
+     *             Sling home folder cannot be created.
      */
-    public Loader(final String slingHome) throws IllegalArgumentException {
-        this.slingHome = getSlingHomeFile(slingHome);
+    public Loader(final File launchpadHome) {
+        if (launchpadHome == null) {
+            throw new IllegalArgumentException(
+                "Launchpad Home folder must not be null or empty");
+        }
+
+        this.launchpadHome = getLaunchpadHomeFile(launchpadHome);
         removeOldLauncherJars();
     }
 
     /**
      * Creates an URLClassLoader from a _launcher JAR_ file in the given
-     * slingHome directory and loads and returns the launcher class identified
-     * by the launcherClassName.
+     * launchpadHome directory and loads and returns the launcher class
+     * identified by the launcherClassName.
      *
      * @param launcherClassName The fully qualified name of a class implementing
      *            the Launcher interface. This class must have a public
@@ -123,7 +128,6 @@ public class Loader {
      * </ul>
      * <p>
      * This method must be called when the notifier is called.
-     *
      */
     public void cleanupVM() {
 
@@ -138,35 +142,36 @@ public class Loader {
 
     /**
      * Copies the contents of the launcher JAR as indicated by the URL to the
-     * sling home directory. If the existing file is is a more recent bundle version 
-     * than the supplied launcher JAR file, it is is not replaced.
+     * sling home directory. If the existing file is is a more recent bundle
+     * version than the supplied launcher JAR file, it is is not replaced.
      *
      * @return <code>true</code> if the launcher JAR file has been installed
or
      *         updated, <code>false</code> otherwise.
      * @throws IOException If an error occurrs transferring the contents
      */
     public boolean installLauncherJar(URL launcherJar) throws IOException {
+        info("Checking launcher JAR in folder " + launchpadHome);
         final File currentLauncherJarFile = getLauncherJarFile();
 
         // Copy the new launcher jar to a temporary file, and
         // extract bundle version info
         final URLConnection launcherJarConn = launcherJar.openConnection();
         launcherJarConn.setUseCaches(false);
-        final File tmp = new File(slingHome, "Loader_tmp_" + System.currentTimeMillis() +
SharedConstants.LAUNCHER_JAR_REL_PATH);
+        final File tmp = new File(launchpadHome, "Loader_tmp_" + System.currentTimeMillis()
+ SharedConstants.LAUNCHER_JAR_REL_PATH);
         spool(launcherJarConn.getInputStream(), tmp);
         final FileBundleVersionInfo newVi = new FileBundleVersionInfo(tmp);
         boolean installNewLauncher = true;
-        
+
         try {
             if(!newVi.isBundle()) {
                 throw new IllegalArgumentException("New launcher jar is not a bundle, cannot
get version info:" + launcherJar);
             }
-            
+
             // Compare versions to decide whether to use the existing or new launcher jar
             if (currentLauncherJarFile.exists()) {
                 final FileBundleVersionInfo currentVi = new FileBundleVersionInfo(currentLauncherJarFile);
                 if(!currentVi.isBundle()) {
-                    throw new IllegalArgumentException("Existing launcher jar is not a bundle,
cannot get version info:" 
+                    throw new IllegalArgumentException("Existing launcher jar is not a bundle,
cannot get version info:"
                             + currentLauncherJarFile.getAbsolutePath());
                 }
 
@@ -178,9 +183,9 @@ public class Loader {
                     info = "more recent than ours";
                     installNewLauncher = false;
                 }
-                
+
                 if(info != null) {
-                    info("Existing launcher is " + info + ", using it: " 
+                    info("Existing launcher is " + info + ", using it: "
                             + getBundleInfo(currentVi) + " (" + currentLauncherJarFile.getName()
+ ")");
                 }
             }
@@ -200,7 +205,7 @@ public class Loader {
 
         return installNewLauncher;
     }
-    
+
     /** Return relevant bundle version info for logging */
     static String getBundleInfo(BundleVersionInfo<?> v) {
         final StringBuilder sb = new StringBuilder();
@@ -216,13 +221,13 @@ public class Loader {
      * Removes old candidate launcher JAR files leaving the most recent one as
      * the launcher JAR file to use on next Sling startup.
      *
-     * @param slingHome The Sling home directory location containing the
+     * @param launchpadHome The Sling home directory location containing the
      *            candidate launcher JAR files.
      */
     private void removeOldLauncherJars() {
         final File[] launcherJars = getLauncherJarFiles();
         if (launcherJars != null && launcherJars.length > 0) {
-            
+
             // Remove all files except current one
             final File current = getLauncherJarFile();
             for(File f : launcherJars) {
@@ -241,7 +246,7 @@ public class Loader {
 
             // And ensure the current file has the standard launcher name
             if (!SharedConstants.LAUNCHER_JAR_REL_PATH.equals(current.getName())) {
-                info("Renaming current launcher jar " + current.getName() 
+                info("Renaming current launcher jar " + current.getName()
                         + " to " + SharedConstants.LAUNCHER_JAR_REL_PATH);
                 File launcherFileName = new File(
                         current.getParentFile(),
@@ -296,7 +301,7 @@ public class Loader {
         if (launcherJars == null || launcherJars.length == 0) {
 
             // return a non-existing file naming the desired primary name
-            result = new File(slingHome,
+            result = new File(launchpadHome,
                 SharedConstants.LAUNCHER_JAR_REL_PATH);
 
         } else {
@@ -308,28 +313,28 @@ public class Loader {
     }
 
     /**
-     * Returns all files in the <code>slingHome</code> directory which may be
-     * considered as launcher JAR files, sorted based on their bundle version
+     * Returns all files in the <code>launchpadHome</code> directory which may
+     * be considered as launcher JAR files, sorted based on their bundle version
      * information, most recent last. These files all start with the
      * {@link SharedConstants#LAUNCHER_JAR_REL_PATH}. This list may be empty if
      * the launcher JAR file has not been installed yet.
      *
-     * @param slingHome The sling home directory where the launcher JAR files
-     *            are stored
+     * @param launchpadHome The sling home directory where the launcher JAR
+     *            files are stored
      * @return The list of candidate launcher JAR files, which may be empty.
      *         <code>null</code> is returned if an IO error occurs trying to
      *         list the files.
      */
     private File[] getLauncherJarFiles() {
         // Get list of files with names starting with our prefix
-        final File[] rawList = slingHome.listFiles(new FileFilter() {
+        final File[] rawList = launchpadHome.listFiles(new FileFilter() {
             public boolean accept(File pathname) {
                 return pathname.isFile()
                     && pathname.getName().startsWith(
                         SharedConstants.LAUNCHER_JAR_REL_PATH);
             }
         });
-        
+
         // Keep only those which have valid Bundle headers, and
         // sort them according to the bundle version numbers
         final List<FileBundleVersionInfo> list = new ArrayList<FileBundleVersionInfo>();
@@ -355,34 +360,29 @@ public class Loader {
     }
 
     /**
-     * Returns the <code>slingHome</code> path as a directory. If the directory
-     * does not exist it is created. If creation fails or if
-     * <code>slingHome</code> exists but is not a directory a
+     * Returns the <code>launchpadHome</code> path as a directory. If the
+     * directory does not exist it is created. If creation fails or if
+     * <code>launchpadHome</code> exists but is not a directory a
      * <code>IllegalArgumentException</code> is thrown.
      *
-     * @param slingHome The sling home directory where the launcher JAR files
-     *            are stored
+     * @param launchpadHome The sling home directory where the launcher JAR
+     *            files are stored
      * @return The Sling home directory
-     * @throws IllegalArgumentException if <code>slingHome</code> exists and
is
-     *             not a directory or cannot be created as a directory.
+     * @throws IllegalArgumentException if <code>launchpadHome</code> exists
and
+     *             is not a directory or cannot be created as a directory.
      */
-    private static File getSlingHomeFile(String slingHome) {
-        if (slingHome == null) {
-            slingHome = SharedConstants.SLING_HOME_DEFAULT;
-        }
-
-        File slingDir = new File(slingHome).getAbsoluteFile();
-        if (slingDir.exists()) {
-            if (!slingDir.isDirectory()) {
-                throw new IllegalArgumentException("Sling Home " + slingDir
+    private static File getLaunchpadHomeFile(File launchpadHome) {
+        if (launchpadHome.exists()) {
+            if (!launchpadHome.isDirectory()) {
+                throw new IllegalArgumentException("Sling Home " + launchpadHome
                     + " exists but is not a directory");
             }
-        } else if (!slingDir.mkdirs()) {
-            throw new IllegalArgumentException("Sling Home " + slingDir
+        } else if (!launchpadHome.mkdirs()) {
+            throw new IllegalArgumentException("Sling Home " + launchpadHome
                 + " cannot be created as a directory");
         }
 
-        return slingDir;
+        return launchpadHome;
     }
 
     private static void closeLauncherJarFile(final File launcherJar) {

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/SharedConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/SharedConstants.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/SharedConstants.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/SharedConstants.java
Thu Dec  1 14:09:34 2011
@@ -108,4 +108,11 @@ public interface SharedConstants {
      */
     public static final String SLING_PROPERTIES_URL = "sling.properties.url";
 
+    /**
+     * The name of the configuration property defining the location for the
+     * Sling launchpad JAR file and the startup folder containing bundles
+     * to be installed by the Bootstrap Installer (value is "sling.launchpad").
+     * @since 2.4.0
+     */
+    public static final String SLING_LAUNCHPAD = "sling.launchpad";
 }

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/webapp/SlingServletDelegate.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/webapp/SlingServletDelegate.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/webapp/SlingServletDelegate.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/webapp/SlingServletDelegate.java
Thu Dec  1 14:09:34 2011
@@ -46,7 +46,6 @@ import org.apache.sling.launchpad.base.s
 import org.apache.sling.launchpad.base.shared.SharedConstants;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -153,6 +152,8 @@ public class SlingServletDelegate extend
 
     private Notifiable notifiable;
 
+    private Map<String, String> properties;
+
     private String slingHome;
 
     public void setNotifiable(Notifiable notifiable) {
@@ -160,7 +161,7 @@ public class SlingServletDelegate extend
     }
 
     public void setCommandLine(Map<String, String> args) {
-        // ignore this for now
+        this.properties = args;
     }
 
     public void setSlingHome(String slingHome) {
@@ -343,20 +344,24 @@ public class SlingServletDelegate extend
         // prevent system properties from being considered
         props.put(Sling.SLING_IGNORE_SYSTEM_PROPERTIES, "true");
 
-        // copy context init parameters
-        @SuppressWarnings("unchecked")
-        Enumeration<String> cpe = getServletContext().getInitParameterNames();
-        while (cpe.hasMoreElements()) {
-            String name = cpe.nextElement();
-            props.put(name, getServletContext().getInitParameter(name));
-        }
+        if (this.properties != null) {
+            props.putAll(this.properties);
+        } else {
+            // copy context init parameters
+            @SuppressWarnings("unchecked")
+            Enumeration<String> cpe = getServletContext().getInitParameterNames();
+            while (cpe.hasMoreElements()) {
+                String name = cpe.nextElement();
+                props.put(name, getServletContext().getInitParameter(name));
+            }
 
-        // copy servlet init parameters
-        @SuppressWarnings("unchecked")
-        Enumeration<String> pe = getInitParameterNames();
-        while (pe.hasMoreElements()) {
-            String name = pe.nextElement();
-            props.put(name, getInitParameter(name));
+            // copy servlet init parameters
+            @SuppressWarnings("unchecked")
+            Enumeration<String> pe = getInitParameterNames();
+            while (pe.hasMoreElements()) {
+                String name = pe.nextElement();
+                props.put(name, getInitParameter(name));
+            }
         }
 
         // ensure the Felix Logger loglevel matches the Sling log level
@@ -376,6 +381,11 @@ public class SlingServletDelegate extend
         // set sling home
         props.put(SharedConstants.SLING_HOME, slingHome);
 
+        // ensure sling.launchpad is set
+        if (!props.containsKey(SharedConstants.SLING_LAUNCHPAD)) {
+            props.put(SharedConstants.SLING_LAUNCHPAD, slingHome);
+        }
+
         return props;
     }
 

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
Thu Dec  1 14:09:34 2011
@@ -22,6 +22,7 @@ import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -80,6 +81,8 @@ public class SlingServlet extends Generi
      */
     private static final String SLING_HOME_PREFIX_DEFAULT = "sling/";
 
+    private Map<String, String> properties;
+
     private String slingHome;
 
     private Loader loader;
@@ -107,9 +110,10 @@ public class SlingServlet extends Generi
      */
     @Override
     public void init() {
+        this.properties = collectInitParameters();
 
-        slingHome = getSlingHome(null);
-        if (slingHome != null) {
+        this.slingHome = getSlingHome(null);
+        if (this.slingHome != null) {
             startSling();
         } else {
             log("Apache Sling cannot be started yet, because sling.home is not defined yet");
@@ -260,13 +264,11 @@ public class SlingServlet extends Generi
     private void startSling(final ServletRequest request) {
         if (startingSling == null) {
             slingHome = getSlingHome((HttpServletRequest) request);
-            Thread starter = new Thread("SlingStarter_"
-                + System.currentTimeMillis()) {
-                @Override
+            Thread starter = new Thread(new Runnable() {
                 public void run() {
                     startSling();
                 }
-            };
+            }, "SlingStarter_" + System.currentTimeMillis());
 
             starter.setDaemon(true);
             starter.start();
@@ -280,7 +282,8 @@ public class SlingServlet extends Generi
     private void startSling() {
 
         try {
-            this.loader = new Loader(slingHome) {
+            File launchpadHome = getLaunchpadHome(slingHome);
+            this.loader = new Loader(launchpadHome) {
                 @Override
                 protected void info(String msg) {
                     log(msg);
@@ -350,6 +353,7 @@ public class SlingServlet extends Generi
             if (sling instanceof Launcher) {
                 Launcher slingLauncher = (Launcher) sling;
                 slingLauncher.setNotifiable(this);
+                slingLauncher.setCommandLine(properties);
                 slingLauncher.setSlingHome(slingHome);
             }
 
@@ -386,6 +390,9 @@ public class SlingServlet extends Generi
      * does not provide the Servlet API 2.5
      * <code>ServletContext.getContextPath()</code> method and the
      * <code>request</code> parameter is <code>null</code>.
+     * <p>
+     * If <code>sling.home</code> can be retrieved, it is returned as an
+     * absolute path.
      *
      * @param args The command line arguments
      * @return The value to use for sling.home or <code>null</code> if the value
@@ -395,6 +402,8 @@ public class SlingServlet extends Generi
 
         String source = null;
 
+        // access config and context to be able to log the sling.home source
+
         // 1. servlet config parameter
         String slingHome = getServletConfig().getInitParameter(
             SharedConstants.SLING_HOME);
@@ -440,13 +449,50 @@ public class SlingServlet extends Generi
             }
         }
 
-        slingHome = substVars(slingHome, null, null, null);
+        // substitute any ${...} references and make absolute
+        slingHome = substVars(slingHome);
+        slingHome = new File(slingHome).getAbsolutePath();
 
         log("Setting sling.home=" + slingHome + " (" + source + ")");
         return slingHome;
     }
 
     /**
+     * Define the sling.launchpad parameter implementing the algorithme defined
+     * on the wiki page to find the setting according to this algorithm:
+     * <ol>
+     * <li>Servlet init parameter <code>sling.launchpad</code>. This path
is
+     * resolved against the <code>slingHome</code> folder if relative.</li>
+     * <li>Servlet context init parameter <code>sling.launchpad</code>.
This
+     * path is resolved against the <code>slingHome</code> folder if relative.</li>
+     * <li>Default to same as <code>sling.home</code></li>
+     * </ol>
+     * <p>
+     * The absolute path of the returned file is stored as the
+     * <code>sling.launchpad</code> property in the {@link #properties} map.
+     *
+     * @param slingHome The absolute path to the Sling Home folder (aka the
+     *            <code>sling.home</code>.
+     * @return The absolute <code>File</code> indicating the launchpad folder.
+     */
+    private File getLaunchpadHome(final String slingHome) {
+        String launchpadHomeParam = properties.get(SharedConstants.SLING_LAUNCHPAD);
+        if (launchpadHomeParam == null || launchpadHomeParam.length() == 0) {
+            properties.put(SharedConstants.SLING_LAUNCHPAD, slingHome);
+            return new File(slingHome);
+        }
+
+        File launchpadHome = new File(launchpadHomeParam);
+        if (!launchpadHome.isAbsolute()) {
+            launchpadHome = new File(slingHome, launchpadHomeParam);
+        }
+
+        properties.put(SharedConstants.SLING_LAUNCHPAD,
+            launchpadHome.getAbsolutePath());
+        return launchpadHome;
+    }
+
+    /**
      * Converts the servlet context path to a path used for the sling.home
      * property. The servlet context path is converted to a simple name by
      * replacing all slash characters in the path with underscores (or a single
@@ -497,6 +543,19 @@ public class SlingServlet extends Generi
 
     // ---------- Property file variable substition support --------------------
 
+    private Map<String, String> collectInitParameters() {
+        HashMap<String, String> props = new HashMap<String, String>();
+        for (Enumeration<String> keys = getServletContext().getInitParameterNames();
keys.hasMoreElements();) {
+            String key = keys.nextElement();
+            props.put(key, getServletContext().getInitParameter(key));
+        }
+        for (Enumeration<String> keys = getServletConfig().getInitParameterNames();
keys.hasMoreElements();) {
+            String key = keys.nextElement();
+            props.put(key, getServletConfig().getInitParameter(key));
+        }
+        return props;
+    }
+
     /**
      * The starting delimiter of variable names (value is "${").
      */
@@ -507,6 +566,14 @@ public class SlingServlet extends Generi
      */
     private static final String DELIM_STOP = "}";
 
+    private String substVars(final String val) {
+        if (val.contains(DELIM_START)) {
+            return substVars(val, null, null, properties);
+        }
+
+        return val;
+    }
+
     /**
      * This method performs property variable substitution on the specified
      * value. If the specified value contains the syntax

Modified: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java?rev=1209095&r1=1209094&r2=1209095&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java
(original)
+++ sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java
Thu Dec  1 14:09:34 2011
@@ -271,6 +271,25 @@ public class MainTest extends TestCase {
         assertNull(props2);
     }
 
+    public void test_converCommandLineArgs_i() {
+        Map<String, String> props = Main.convertCommandLineArgs(new HashMap<String,
String>() {
+            {
+                put("i", "launchpad");
+            }
+        });
+        assertNotNull(props);
+        assertEquals(1, props.size());
+        assertEquals("launchpad", props.get(SharedConstants.SLING_LAUNCHPAD));
+
+        Map<String, String> props2 = Main.convertCommandLineArgs(new HashMap<String,
String>() {
+            {
+                final String i = "i";
+                put(i, i);
+            }
+        });
+        assertNull(props2);
+    }
+
     public void test_converCommandLineArgs_a() {
         Map<String, String> props = Main.convertCommandLineArgs(new HashMap<String,
String>() {
             {
@@ -306,4 +325,32 @@ public class MainTest extends TestCase {
         });
         assertNull(props2);
     }
+
+    public void test_converCommandLineArgs_D() {
+        Map<String, String> props = Main.convertCommandLineArgs(new HashMap<String,
String>() {
+            {
+                put("D", "name=value");
+            }
+        });
+        assertNotNull(props);
+        assertEquals(1, props.size());
+        assertEquals("value", props.get("name"));
+
+        Map<String, String> props2 = Main.convertCommandLineArgs(new HashMap<String,
String>() {
+            {
+                put("D", "flag");
+            }
+        });
+        assertNotNull(props2);
+        assertEquals(1, props2.size());
+        assertEquals("flag", props2.get("flag"));
+
+        Map<String, String> props1 = Main.convertCommandLineArgs(new HashMap<String,
String>() {
+            {
+                final String d = "D";
+                put(d, d);
+            }
+        });
+        assertNull(props1);
+    }
 }



Mime
View raw message