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