null.
+ */
+ public LaunchException(String message) {
+ super(message);
+ }
+
+}
Index: main/src/net/sourceforge/cruisecontrol/launch/Launcher.java
===================================================================
RCS file: main/src/net/sourceforge/cruisecontrol/launch/Launcher.java
diff -N main/src/net/sourceforge/cruisecontrol/launch/Launcher.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ main/src/net/sourceforge/cruisecontrol/launch/Launcher.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,293 @@
+/********************************************************************************
+ * CruiseControl, a Continuous Integration Toolkit
+ * Copyright (c) 2001, ThoughtWorks, Inc.
+ * 651 W Washington Ave. Suite 600
+ * Chicago, IL 60661 USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * + Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * + Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************/
+/*
+ * Copyright 2003-2005 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 net.sourceforge.cruisecontrol.launch;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.cruisecontrol.launch.util.Locator;
+
+/**
+ * Provides the means to launch CruiseControl with the appropriate classpath.
+ * This code is based heavily on (some parts taken directly from) the Apache
+ * Ant project.
+ *
+ * @author file: URI.
+ *
+ * Will be an absolute path if the given URI is absolute.
+ * + *Swallows '%' that are not followed by two characters, + * doesn't deal with non-ASCII characters.
+ * + * @param uri the URI designating a file in the local filesystem. + * @return the local file system path for the file. + * @since Ant 1.6 + */ + public static String fromURI(String uri) { + URL url = null; + try { + url = new URL(uri); + } catch (MalformedURLException emYouEarlEx) { + // Ignore malformed exception + } + if (url == null || !("file".equals(url.getProtocol()))) { + throw new IllegalArgumentException("Can only handle valid file: URIs"); + } + StringBuffer buf = new StringBuffer(url.getHost()); + if (buf.length() > 0) { + buf.insert(0, File.separatorChar).insert(0, File.separatorChar); + } + String file = url.getFile(); + int queryPos = file.indexOf('?'); + buf.append((queryPos < 0) ? file : file.substring(0, queryPos)); + + uri = buf.toString().replace('/', File.separatorChar); + + if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2 + && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { + uri = uri.substring(1); + } + String path = decodeUri(uri); + return path; + } + + /** + * Decodes an Uri with % characters. + * @param uri String with the uri possibly containing % characters. + * @return The decoded Uri + */ + private static String decodeUri(String uri) { + if (uri.indexOf('%') == -1) { + return uri; + } + StringBuffer sb = new StringBuffer(); + CharacterIterator iter = new StringCharacterIterator(uri); + for (char c = iter.first(); c != CharacterIterator.DONE; + c = iter.next()) { + if (c == '%') { + char c1 = iter.next(); + if (c1 != CharacterIterator.DONE) { + int i1 = Character.digit(c1, 16); + char c2 = iter.next(); + if (c2 != CharacterIterator.DONE) { + int i2 = Character.digit(c2, 16); + sb.append((char) ((i1 << 4) + i2)); + } + } + } else { + sb.append(c); + } + } + String path = sb.toString(); + return path; + } + + /** + * Get the File necessary to load the Sun compiler tools. If the classes + * are available to this class, then no additional URL is required and + * null is returned. This may be because the classes are explicitly in the + * class path or provided by the JVM directly. + * + * @return the tools jar as a File if required, null otherwise. + */ + public static File getToolsJar() { + // firstly check if the tools jar is already in the classpath + boolean toolsJarAvailable = false; + try { + // just check whether this throws an exception + Class.forName("com.sun.tools.javac.Main"); + toolsJarAvailable = true; + } catch (Exception e) { + try { + Class.forName("sun.tools.javac.Main"); + toolsJarAvailable = true; + } catch (Exception e2) { + // ignore + } + } + if (toolsJarAvailable) { + return null; + } + // couldn't find compiler - try to find tools.jar + // based on java.home setting + String javaHome = System.getProperty("java.home"); + if (javaHome.toLowerCase(Locale.US).endsWith("jre")) { + javaHome = javaHome.substring(0, javaHome.length() - 4); + } + File toolsJar = new File(javaHome + "/lib/tools.jar"); + if (!toolsJar.exists()) { + System.out.println("Unable to locate tools.jar. " + + "Expected to find it in " + toolsJar.getPath()); + return null; + } + return toolsJar; + } + + /** + * Get an array of URLs representing all of the jar files in the + * given location. If the location is a file, it is returned as the only + * element of the array. If the location is a directory, it is scanned for + * jar files. + * + * @param location the location to scan for Jars. + * + * @return an array of URLs for all jars in the given location. + * + * @exception MalformedURLException if the URLs for the jars cannot be + * formed. + */ + public static URL[] getLocationURLs(File location) + throws MalformedURLException { + return getLocationURLs(location, new String[]{".jar"}); + } + + /** + * Get an array of URLs representing all of the files of a given set of + * extensions in the given location. If the location is a file, it is + * returned as the only element of the array. If the location is a + * directory, it is scanned for matching files. + * + * @param location + * the location to scan for files. + * @param extensions + * an array of extension that are to match in the directory + * search. + * + * @return an array of URLs of matching files. + * @exception MalformedURLException + * if the URLs for the files cannot be formed. + */ + public static URL[] getLocationURLs(File location, + final String[] extensions) + throws MalformedURLException { + + URL[] urls = new URL[0]; + + if (!location.exists()) { + return urls; + } + if (!location.isDirectory()) { + urls = new URL[1]; + String path = location.getPath(); + for (int i = 0; i < extensions.length; ++i) { + if (path.toLowerCase().endsWith(extensions[i])) { + urls[0] = location.toURL(); + break; + } + } + return urls; + } + File[] matches = location.listFiles( + new FilenameFilter() { + public boolean accept(File dir, String name) { + for (int i = 0; i < extensions.length; ++i) { + if (name.toLowerCase().endsWith(extensions[i])) { + return true; + } + } + return false; + } + }); + urls = new URL[matches.length]; + for (int i = 0; i < matches.length; ++i) { + urls[i] = matches[i].toURL(); + } + return urls; + } +} +