Fixes issue 1695
Adds the command line argumetns -addToClassPath and -addModule
(for applicationCreator) to:
- applicationCreator
- projectCreator
- junitCreator
To allow an external library to be added as a part of the initial specification
of a project. It does some checks to see that the library exists and that
the module exists somewhere within the classpath.
Suggested by: mmendez
Patch by: zundel
Review by: jat (desk check)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2904 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
index f61e01c..ffe772c 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
@@ -141,6 +141,11 @@
private final LoadStrategy strategy;
/**
+ * Filename suffix used for GWT Module XML files.
+ */
+ public static final String GWT_MODULE_XML_SUFFIX = ".gwt.xml";
+
+ /**
* Constructs a {@link ModuleDefLoader} that loads from the class path.
*/
private ModuleDefLoader() {
@@ -194,7 +199,7 @@
// Find the specified module using the classpath.
//
String slashedModuleName = moduleName.replace('.', '/');
- String resName = slashedModuleName + ".gwt.xml";
+ String resName = slashedModuleName + ModuleDefLoader.GWT_MODULE_XML_SUFFIX;
URL moduleURL = classLoader.getResource(resName);
if (moduleURL != null) {
diff --git a/user/src/com/google/gwt/junit/tools/JUnit-hosted.launchsrc b/user/src/com/google/gwt/junit/tools/JUnit-hosted.launchsrc
index e532de1..49a8345 100644
--- a/user/src/com/google/gwt/junit/tools/JUnit-hosted.launchsrc
+++ b/user/src/com/google/gwt/junit/tools/JUnit-hosted.launchsrc
@@ -10,6 +10,7 @@
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/@projectName/test" path="3" type="2"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento project="@projectName"/> </runtimeClasspathEntry> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry externalArchive="@gwtDevPath" path="3" type="2"/> "/>
+@eclipseExtraLaunchPaths
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="@projectName"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.args="-out www-test" -Xmx256M"/>
diff --git a/user/src/com/google/gwt/junit/tools/JUnit-web.launchsrc b/user/src/com/google/gwt/junit/tools/JUnit-web.launchsrc
index e8504eb..56f35ad 100644
--- a/user/src/com/google/gwt/junit/tools/JUnit-web.launchsrc
+++ b/user/src/com/google/gwt/junit/tools/JUnit-web.launchsrc
@@ -10,6 +10,7 @@
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/@projectName/test" path="3" type="2"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento project="@projectName"/> </runtimeClasspathEntry> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry externalArchive="@gwtDevPath" path="3" type="2"/> "/>
+@eclipseExtraLaunchPaths
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="@projectName"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.args="-web -out www-test" -Xmx256M"/>
diff --git a/user/src/com/google/gwt/junit/tools/JUnitCreator.java b/user/src/com/google/gwt/junit/tools/JUnitCreator.java
index 2fa2522..00fb599 100644
--- a/user/src/com/google/gwt/junit/tools/JUnitCreator.java
+++ b/user/src/com/google/gwt/junit/tools/JUnitCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
*
* 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
@@ -15,9 +15,11 @@
*/
package com.google.gwt.junit.tools;
+import com.google.gwt.user.tools.util.ArgHandlerAddToClassPath;
import com.google.gwt.user.tools.util.ArgHandlerEclipse;
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
+import com.google.gwt.user.tools.util.CreatorUtilities;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerOutDir;
import com.google.gwt.util.tools.ArgHandlerString;
@@ -27,6 +29,7 @@
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -116,19 +119,27 @@
* Application.
* @param outDir Where to put the output files
* @param eclipse The name of a project to attach a .launch config to
+ * @param extraClassPaths extra class path entries to add to the configuration
* @param overwrite Overwrite an existing files if they exist.
* @param ignore Ignore existing files if they exist.
* @throws IOException
*/
static void createTest(String junitPath, String moduleName,
- String fullClassName, File outDir, String eclipse, boolean overwrite,
- boolean ignore) throws IOException {
+ String fullClassName, File outDir, String eclipse,
+ List<String> extraClassPaths, boolean overwrite, boolean ignore)
+ throws IOException {
// Figure out the installation directory
String installPath = Utility.getInstallPath();
String gwtUserPath = installPath + '/' + "gwt-user.jar";
String gwtDevPath = installPath + '/' + Utility.getDevJarName();
+ // Check to see that the passed extra path/module arguments are valid.
+ if (!CreatorUtilities.validatePathsAndModules(gwtUserPath, extraClassPaths,
+ null)) {
+ return;
+ }
+
// Figure out what platform we're on
//
boolean isWindows = gwtDevPath.substring(gwtDevPath.lastIndexOf('/') + 1).indexOf(
@@ -198,6 +209,11 @@
replacements.put("@gwtUserPath", basePathEnv + gwtUserPath);
replacements.put("@gwtDevPath", basePathEnv + gwtDevPath);
replacements.put("@vmargs", isMacOsX ? "-XstartOnFirstThread" : "");
+ replacements.put("@eclipseExtraLaunchPaths",
+ CreatorUtilities.createEclipseExtraLaunchPaths(extraClassPaths));
+ replacements.put("@extraClassPathsColon", CreatorUtilities.appendPaths(":",
+ extraClassPaths));
+ replacements.put("@extraClassPathsSemicolon", CreatorUtilities.appendPaths(";", extraClassPaths));
{
// Create a skeleton Test class
@@ -213,6 +229,7 @@
if (eclipse != null) {
// Create an eclipse launch config
replacements.put("@projectName", eclipse);
+
File hostedConfig = Utility.createNormalFile(outDir, className
+ "-hosted.launch", overwrite, ignore);
if (hostedConfig != null) {
@@ -270,6 +287,7 @@
private String moduleName = null;
private File outDir;
private boolean overwrite = false;
+ private ArgHandlerAddToClassPath classPathHandler = new ArgHandlerAddToClassPath();
protected JUnitCreator() {
@@ -394,12 +412,13 @@
});
registerHandler(new ArgHandlerTestClass());
+ registerHandler(classPathHandler);
}
protected boolean run() {
try {
createTest(junitPath, moduleName, fullClassName, outDir, eclipse,
- overwrite, ignore);
+ classPathHandler.getExtraClassPathList(), overwrite, ignore);
return true;
} catch (IOException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
diff --git a/user/src/com/google/gwt/junit/tools/junit-hosted.cmdsrc b/user/src/com/google/gwt/junit/tools/junit-hosted.cmdsrc
index 9ed79bb..2e25daf 100644
--- a/user/src/com/google/gwt/junit/tools/junit-hosted.cmdsrc
+++ b/user/src/com/google/gwt/junit/tools/junit-hosted.cmdsrc
@@ -1 +1 @@
-@java -Dgwt.args="-out www-test" -Xmx256M -cp "%~dp0\src;%~dp0\test;%~dp0\bin;@junitPath;@gwtUserPath;@gwtDevPath" junit.textui.TestRunner @clientPackage.@className %*
\ No newline at end of file
+@java -Dgwt.args="-out www-test" -Xmx256M -cp "%~dp0\src;%~dp0\test;%~dp0\bin;@junitPath;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" junit.textui.TestRunner @clientPackage.@className %*
\ No newline at end of file
diff --git a/user/src/com/google/gwt/junit/tools/junit-hostedsrc b/user/src/com/google/gwt/junit/tools/junit-hostedsrc
index d050571..44c275b 100644
--- a/user/src/com/google/gwt/junit/tools/junit-hostedsrc
+++ b/user/src/com/google/gwt/junit/tools/junit-hostedsrc
@@ -1,3 +1,3 @@
#!/bin/sh
APPDIR=`dirname $0`;
-java @vmargs -Dgwt.args="-out www-test" -Xmx256M -cp "$APPDIR/src:$APPDIR/test:$APPDIR/bin:@junitPath:@gwtUserPath:@gwtDevPath" junit.textui.TestRunner @clientPackage.@className "$@";
+java @vmargs -Dgwt.args="-out www-test" -Xmx256M -cp "$APPDIR/src:$APPDIR/test:$APPDIR/bin:@junitPath:@gwtUserPath:@gwtDevPath@extraClassPathsColon" junit.textui.TestRunner @clientPackage.@className "$@";
diff --git a/user/src/com/google/gwt/junit/tools/junit-web.cmdsrc b/user/src/com/google/gwt/junit/tools/junit-web.cmdsrc
index e6940de..ac61775 100644
--- a/user/src/com/google/gwt/junit/tools/junit-web.cmdsrc
+++ b/user/src/com/google/gwt/junit/tools/junit-web.cmdsrc
@@ -1 +1 @@
-@java -Dgwt.args="-web -out www-test" -Xmx256M -cp "%~dp0\src;%~dp0\test;%~dp0\bin;@junitPath;@gwtUserPath;@gwtDevPath" junit.textui.TestRunner @clientPackage.@className %*
\ No newline at end of file
+@java -Dgwt.args="-web -out www-test" -Xmx256M -cp "%~dp0\src;%~dp0\test;%~dp0\bin;@junitPath;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" junit.textui.TestRunner @clientPackage.@className %*
\ No newline at end of file
diff --git a/user/src/com/google/gwt/junit/tools/junit-websrc b/user/src/com/google/gwt/junit/tools/junit-websrc
index 5b92d82..918b68a 100644
--- a/user/src/com/google/gwt/junit/tools/junit-websrc
+++ b/user/src/com/google/gwt/junit/tools/junit-websrc
@@ -1,3 +1,3 @@
#!/bin/sh
APPDIR=`dirname $0`;
-java @vmargs -Dgwt.args="-web -out www-test" -Xmx256M -cp "$APPDIR/src:$APPDIR/test:$APPDIR/bin:@junitPath:@gwtUserPath:@gwtDevPath" junit.textui.TestRunner @clientPackage.@className "$@";
+java @vmargs -Dgwt.args="-web -out www-test" -Xmx256M -cp "$APPDIR/src:$APPDIR/test:$APPDIR/bin:@junitPath:@gwtUserPath:@gwtDevPath@extraClassPathsColon" junit.textui.TestRunner @clientPackage.@className "$@";
diff --git a/user/src/com/google/gwt/user/tools/.classpathsrc b/user/src/com/google/gwt/user/tools/.classpathsrc
index af78a3f..5a43ea4 100644
--- a/user/src/com/google/gwt/user/tools/.classpathsrc
+++ b/user/src/com/google/gwt/user/tools/.classpathsrc
@@ -6,4 +6,5 @@
<classpathentry kind="lib" path="@gwtUserPath"/>
<classpathentry kind="var" path="JUNIT_HOME/junit.jar"/>
<classpathentry kind="output" path="bin"/>
+@eclipseClassPathEntries
</classpath>
diff --git a/user/src/com/google/gwt/user/tools/App.launchsrc b/user/src/com/google/gwt/user/tools/App.launchsrc
index 6ea991a..b35bd08 100644
--- a/user/src/com/google/gwt/user/tools/App.launchsrc
+++ b/user/src/com/google/gwt/user/tools/App.launchsrc
@@ -7,6 +7,7 @@
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/@projectName/src" path="3" type="2"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento project="@projectName"/> </runtimeClasspathEntry> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry externalArchive="@gwtDevPath" path="3" type="2"/> "/>
+@eclipseExtraLaunchPaths
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="@vmargs -Xmx256M"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www @startupUrl"/>
diff --git a/user/src/com/google/gwt/user/tools/ApplicationCreator.java b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
index efeaf0a..99948f9 100644
--- a/user/src/com/google/gwt/user/tools/ApplicationCreator.java
+++ b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
*
* 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
@@ -15,28 +15,82 @@
*/
package com.google.gwt.user.tools;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+import com.google.gwt.user.tools.util.ArgHandlerAddToClassPath;
import com.google.gwt.user.tools.util.ArgHandlerEclipse;
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
+import com.google.gwt.user.tools.util.CreatorUtilities;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerOutDir;
+import com.google.gwt.util.tools.ArgHandlerString;
import com.google.gwt.util.tools.ToolBase;
import com.google.gwt.util.tools.Utility;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
/**
- * Creates a GWT application.
- *
+ * Creates a GWT application skeleton.
*/
public final class ApplicationCreator extends ToolBase {
- /**
+ /*
* Arguments for the application creator.
- *
+ */
+
+ /**
+ * Add an extra module injection into the top level module file.
+ */
+ protected class ArgHandlerAddModule extends ArgHandlerString {
+ private List<String> extraModuleList = new ArrayList<String>();
+
+ public List<String> getExtraModuleList() {
+ return extraModuleList;
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Adds extra GWT modules to be inherited.";
+ }
+
+ @Override
+ public String getTag() {
+ return "-addModule";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[] {"module"};
+ }
+
+ @Override
+ public boolean setString(String str) {
+ // Parse out a comma separated list
+ StringTokenizer st = new StringTokenizer(str, ",");
+ while (st.hasMoreTokens()) {
+ String module = st.nextToken();
+
+ // Check className to see that it is a period separated string of words.
+ if (!module.matches("[\\w\\$]+(\\.[\\w\\$]+)+")) {
+ System.err.println("'" + module
+ + "' does not appear to be a valid fully-qualified module name");
+ return false;
+ }
+ extraModuleList.add(module);
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Specify the top level class name of the application to create.
*/
protected class ArgHandlerAppClass extends ArgHandlerExtra {
@@ -55,7 +109,6 @@
}
// Check out the class name.
- //
if (arg.indexOf('$') != -1) {
System.err.println("'" + arg
+ "': This version of the tool does not support nested classes");
@@ -119,13 +172,38 @@
* @throws IOException
*/
static void createApplication(String fullClassName, File outDir,
- String eclipse, boolean overwrite, boolean ignore) throws IOException {
+ String eclipse, boolean overwrite, boolean ignore)
+ throws IOException {
+ createApplication(fullClassName, outDir, eclipse, overwrite, ignore, null, null);
+ }
+
+ /**
+ * @param fullClassName Name of the fully-qualified Java class to create as an
+ * Application.
+ * @param outDir Where to put the output files
+ * @param eclipse The name of a project to attach a .launch config to
+ * @param overwrite Overwrite an existing files if they exist.
+ * @param ignore Ignore existing files if they exist.
+ * @param extraClassPaths A list of paths to append to the class path for
+ * launch configs.
+ * @param extraModules A list of GWT modules to add 'inherits' tags for.
+ * @throws IOException
+ */
+ static void createApplication(String fullClassName, File outDir,
+ String eclipse, boolean overwrite, boolean ignore,
+ List<String> extraClassPaths, List<String> extraModules)
+ throws IOException {
// Figure out the installation directory
String installPath = Utility.getInstallPath();
String gwtUserPath = installPath + '/' + "gwt-user.jar";
String gwtDevPath = installPath + '/' + Utility.getDevJarName();
+ // Validate the arguments for extra class path entries and modules.
+ if (!CreatorUtilities.validatePathsAndModules(gwtUserPath, extraClassPaths,
+ extraModules)) {
+ return;
+ }
// Figure out what platform we're on
//
boolean isWindows = gwtDevPath.substring(gwtDevPath.lastIndexOf('/') + 1).indexOf(
@@ -184,11 +262,18 @@
replacements.put("@compileClass", "com.google.gwt.dev.GWTCompiler");
replacements.put("@startupUrl", startupUrl);
replacements.put("@vmargs", isMacOsX ? "-XstartOnFirstThread" : "");
+ replacements.put("@eclipseExtraLaunchPaths",
+ CreatorUtilities.createEclipseExtraLaunchPaths(extraClassPaths));
+ replacements.put("@extraModuleInherits",
+ createExtraModuleInherits(extraModules));
+ replacements.put("@extraClassPathsColon", CreatorUtilities.appendPaths(":",
+ extraClassPaths));
+ replacements.put("@extraClassPathsSemicolon", CreatorUtilities.appendPaths(";", extraClassPaths));
{
// Create the module
File moduleXML = Utility.createNormalFile(basePackageDir, className
- + ".gwt.xml", overwrite, ignore);
+ + ModuleDefLoader.GWT_MODULE_XML_SUFFIX, overwrite, ignore);
if (moduleXML != null) {
String out = Utility.getFileFromClassPath(PACKAGE_PATH
+ "Module.gwt.xmlsrc");
@@ -287,9 +372,25 @@
}
}
+ private static String createExtraModuleInherits(List<String> modules) {
+ if (modules == null) {
+ return "";
+ }
+ // Create an <inherits> tag in the gwt.xml file for each extra module
+ StringBuilder buf = new StringBuilder();
+ for (String module : modules) {
+ buf.append(" <inherits name=\"");
+ buf.append(module);
+ buf.append("\" />\n");
+ }
+ return buf.toString();
+ }
+
+ private ArgHandlerAddToClassPath classPathHandler = new ArgHandlerAddToClassPath();
private String eclipse = null;
private String fullClassName = null;
private boolean ignore = false;
+ private ArgHandlerAddModule moduleHandler = new ArgHandlerAddModule();
private File outDir;
private boolean overwrite = false;
@@ -340,11 +441,15 @@
});
registerHandler(new ArgHandlerAppClass());
+ registerHandler(classPathHandler);
+ registerHandler(moduleHandler);
}
protected boolean run() {
try {
- createApplication(fullClassName, outDir, eclipse, overwrite, ignore);
+ createApplication(fullClassName, outDir, eclipse, overwrite, ignore,
+ classPathHandler.getExtraClassPathList(),
+ moduleHandler.getExtraModuleList());
return true;
} catch (IOException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
diff --git a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
index a930314..8f0ed45 100644
--- a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
@@ -10,6 +10,9 @@
<!-- <inherits name="com.google.gwt.user.theme.chrome.Chrome"/> -->
<!-- <inherits name="com.google.gwt.user.theme.dark.Dark"/> -->
+ <!-- Other module inherits -->
+@extraModuleInherits
+
<!-- Specify the app entry point class. -->
<entry-point class='@clientPackage.@className'/>
diff --git a/user/src/com/google/gwt/user/tools/ProjectCreator.java b/user/src/com/google/gwt/user/tools/ProjectCreator.java
index 6b6a558..0ea5d2b 100644
--- a/user/src/com/google/gwt/user/tools/ProjectCreator.java
+++ b/user/src/com/google/gwt/user/tools/ProjectCreator.java
@@ -15,17 +15,21 @@
*/
package com.google.gwt.user.tools;
+import com.google.gwt.user.tools.util.ArgHandlerAddToClassPath;
import com.google.gwt.user.tools.util.ArgHandlerEclipse;
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
+import com.google.gwt.user.tools.util.CreatorUtilities;
import com.google.gwt.util.tools.ArgHandlerOutDir;
import com.google.gwt.util.tools.ArgHandlerString;
import com.google.gwt.util.tools.ToolBase;
import com.google.gwt.util.tools.Utility;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -53,6 +57,8 @@
}
/**
+ * Create a set of project files.
+ *
* @param eclipse The name of project to create.
* @param ant The name of an ant file to create.
* @param outDir The directory to write into.
@@ -62,14 +68,37 @@
*/
static void createProject(String eclipse, String ant, File outDir,
boolean overwrite, boolean ignore) throws IOException {
+ createProject(eclipse, ant, outDir, overwrite, ignore, null);
+ }
+
+ /**
+ * Create a set of project files.
+ *
+ * @param eclipse The name of project to create.
+ * @param ant The name of an ant file to create.
+ * @param outDir The directory to write into.
+ * @param overwrite Overwrite an existing files if they exist.
+ * @param ignore Ignore existing files if they exist.
+ * @param extraClassPaths class path entries passed on the command line
+ * @throws IOException
+ */
+ static void createProject(String eclipse, String ant, File outDir,
+ boolean overwrite, boolean ignore, List<String> extraClassPaths)
+ throws IOException {
// Figure out the installation directory
String installPath = Utility.getInstallPath();
// Create a map of replacements.
- //
Map<String, String> replacements = new HashMap<String, String>();
- replacements.put("@gwtUserPath", installPath + '/' + "gwt-user.jar");
+ String userJarPath = installPath + '/' + "gwt-user.jar";
+ replacements.put("@gwtUserPath", userJarPath);
+
+ // Check to see that the passed extra path/module arguments are valid.
+ if (!CreatorUtilities.validatePathsAndModules(userJarPath, extraClassPaths,
+ null)) {
+ return;
+ }
Utility.getDirectory(outDir, "src", true);
Utility.getDirectory(outDir, "test", true);
@@ -77,6 +106,16 @@
if (ant != null) {
// Create an ant build file
replacements.put("@projectName", ant);
+
+ // Build the list of extra paths
+ StringBuilder buf = new StringBuilder();
+ if (extraClassPaths != null) {
+ for (String path : extraClassPaths) {
+ buf.append(" <pathelement path=\"" + path + "\"/>");
+ }
+ }
+ replacements.put("@extraAntPathElements", buf.toString());
+
File antXML = Utility.createNormalFile(outDir, ant + ".ant.xml",
overwrite, ignore);
if (antXML != null) {
@@ -96,6 +135,35 @@
Utility.writeTemplateFile(dotProject, out, replacements);
}
+ StringBuilder classpathEntries = new StringBuilder();
+ if (extraClassPaths != null) {
+ for (String path : extraClassPaths) {
+ File f = new File(path);
+
+ if (!f.exists()) {
+ throw new FileNotFoundException("extraClassPath: " + path
+ + " must be present before .launch file can be created.");
+ }
+ // Handle both .jar files and paths
+ String kindString;
+ if (f.isDirectory()) {
+ kindString = "output";
+ } else if (path.endsWith(".jar")) {
+ kindString = "lib";
+ } else {
+ throw new RuntimeException("Don't know how to handle path: " + path
+ + ". It doesn't appear to be a directory or a .jar file");
+ }
+ classpathEntries.append(" <classpathentry kind=\"");
+ classpathEntries.append(kindString);
+ classpathEntries.append("\" path=\"");
+ classpathEntries.append(path);
+ classpathEntries.append("\"/>\n");
+ }
+ }
+
+ replacements.put("@eclipseClassPathEntries", classpathEntries.toString());
+
// Create an eclipse classpath file
File dotClasspath = Utility.createNormalFile(outDir, ".classpath",
overwrite, ignore);
@@ -108,12 +176,11 @@
}
private String ant = null;
-
private String eclipse = null;
-
private boolean ignore = false;
private File outDir = null;
private boolean overwrite = false;
+ private ArgHandlerAddToClassPath classPathHandler = new ArgHandlerAddToClassPath();
protected ProjectCreator() {
@@ -185,6 +252,8 @@
return true;
}
});
+
+ registerHandler(classPathHandler);
}
protected boolean run() {
@@ -194,7 +263,8 @@
printHelp();
return false;
}
- createProject(eclipse, ant, outDir, overwrite, ignore);
+ createProject(eclipse, ant, outDir, overwrite, ignore,
+ classPathHandler.getExtraClassPathList());
return true;
} catch (IOException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
diff --git a/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc b/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc
index 9abaded..80f6e97 100644
--- a/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc
+++ b/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc
@@ -1 +1 @@
-@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath" @compileClass -out "%~dp0\www" %* @moduleName
\ No newline at end of file
+@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" @compileClass -out "%~dp0\www" %* @moduleName
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/tools/gwtcompilesrc b/user/src/com/google/gwt/user/tools/gwtcompilesrc
index 4318531..75064a8 100644
--- a/user/src/com/google/gwt/user/tools/gwtcompilesrc
+++ b/user/src/com/google/gwt/user/tools/gwtcompilesrc
@@ -1,3 +1,3 @@
#!/bin/sh
APPDIR=`dirname $0`;
-java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath" @compileClass -out "$APPDIR/www" "$@" @moduleName;
+java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath@extraClassPathsColon" @compileClass -out "$APPDIR/www" "$@" @moduleName;
diff --git a/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc b/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc
index 15a496a..dd14324 100644
--- a/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc
+++ b/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc
@@ -1 +1 @@
-@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath" @shellClass -out "%~dp0\www" %* @startupUrl
\ No newline at end of file
+@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" @shellClass -out "%~dp0\www" %* @startupUrl
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/tools/gwtshellsrc b/user/src/com/google/gwt/user/tools/gwtshellsrc
index 31a52df..195b443 100644
--- a/user/src/com/google/gwt/user/tools/gwtshellsrc
+++ b/user/src/com/google/gwt/user/tools/gwtshellsrc
@@ -1,3 +1,3 @@
#!/bin/sh
APPDIR=`dirname $0`;
-java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath" @shellClass -out "$APPDIR/www" "$@" @startupUrl;
+java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath@extraClassPathsColon" @shellClass -out "$APPDIR/www" "$@" @startupUrl;
diff --git a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
index 01535e8..942140d 100644
--- a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
@@ -9,6 +9,7 @@
<path id="project.class.path">
<pathelement path="${java.class.path}/"/>
<pathelement path="@gwtUserPath"/>
+@extraAntPathElements
<!-- Additional dependencies (such as junit) go here -->
</path>
diff --git a/user/src/com/google/gwt/user/tools/util/ArgHandlerAddToClassPath.java b/user/src/com/google/gwt/user/tools/util/ArgHandlerAddToClassPath.java
new file mode 100644
index 0000000..3833115
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/util/ArgHandlerAddToClassPath.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * 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 com.google.gwt.user.tools.util;
+
+import com.google.gwt.util.tools.ArgHandlerString;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Parse the -addToClassPath argument. Appends a .jar or classpath to the
+ * generated launch scripts.
+ */
+public class ArgHandlerAddToClassPath extends ArgHandlerString {
+ private List<String> extraClassPathList = new ArrayList<String>();
+
+ public List<String> getExtraClassPathList() {
+ return extraClassPathList;
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Adds extra elements to the class path.";
+ }
+
+ @Override
+ public String getTag() {
+ return "-addToClassPath";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[] {"classPathEntry"};
+ }
+
+ @Override
+ public boolean setString(String str) {
+
+ StringTokenizer st = new StringTokenizer(str, ",");
+ while (st.hasMoreTokens()) {
+ extraClassPathList.add(st.nextToken().trim());
+ }
+ return true;
+ }
+}
diff --git a/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java b/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java
new file mode 100644
index 0000000..f30b587
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * 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 com.google.gwt.user.tools.util;
+
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods shared by ApplicationCreator and ProjectCreator.
+ *
+ */
+public class CreatorUtilities {
+
+ /**
+ * Create a PATH style string separated by the specified delimiter (';' for
+ * windows, ':' for UNIX) Note that this method prepends the delimiter to the
+ * front of the string. There is an existing path we want to append to.
+ *
+ * @param delimiter The delimiter string to place between variables.
+ * @param paths The list of paths to concatenate together.
+ * @return the concatenated list of paths as a single string.
+ */
+ public static String appendPaths(String delimiter, List<String> paths) {
+ if (paths == null) {
+ return "";
+ }
+ StringBuilder buf = new StringBuilder();
+ for (String value : paths) {
+ buf.append(delimiter);
+ buf.append(value);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Create the extra path entries for an Eclipse '.launch' file in XML format.
+ *
+ * @param extraClassPaths a list of paths/.jar files to add to the class path
+ * @return A string formatted to include in the .launch file
+ */
+ public static String createEclipseExtraLaunchPaths(
+ List<String> extraClassPaths) throws FileNotFoundException {
+
+ if (extraClassPaths == null) {
+ return "";
+ }
+
+ // Create an entry for an Eclipse launch file additional classpath entry.
+ StringBuilder buf = new StringBuilder();
+ for (String path : extraClassPaths) {
+ File f = new File(path);
+
+ if (!f.exists()) {
+ throw new FileNotFoundException("extraClassPath: " + path
+ + "Must be present before .launch file can be created");
+ }
+
+ String lcPath = path.toLowerCase();
+
+ if (f.isDirectory()) {
+ // For a directory, we assume it contains compiled class files
+ buf.append("<listEntry value=\"<?xml version="1.0" ");
+ buf.append("encoding="UTF-8" standalone="no"");
+ buf.append("?> <runtimeClasspathEntry ");
+ buf.append("internalArchive="");
+ buf.append(path);
+ buf.append("" path="3" type="2"/> \"/>");
+ buf.append("\n");
+ } else if (lcPath.endsWith(".jar") || lcPath.endsWith(".zip")) {
+ // Any plain file we assume is an external library (e.g. a .jar file)
+ buf.append("<listEntry value=\"<?xml version="1.0" ");
+ buf.append("encoding="UTF-8"?> <runtimeClasspathEntry ");
+ buf.append("externalArchive="");
+ buf.append(path);
+ buf.append("" path="3" type="2"/> \"/>");
+ buf.append("\n");
+ } else {
+ throw new RuntimeException("Don't know how to handle path: " + path
+ + ". It doesn't appear to be a directory or a .jar/.zip file");
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Check to see that the userJar and pathList files all exist, and that the
+ * moduleList entries can be found within the jars.
+ *
+ * @param userJar The full path to gwt-user.jar
+ * @param pathList A list of jar files to add to the class path.
+ * @param moduleList A list of GWT module names to add as 'inherits' tags
+ * @return <code>true</code> if all validations pass.
+ */
+ public static boolean validatePathsAndModules(String userJar,
+ List<String> pathList, List<String> moduleList) {
+ List<URL> urlList = new ArrayList<URL>();
+
+ if (!addURL(urlList, userJar)) {
+ return false;
+ }
+ if (pathList != null) {
+ for (String path : pathList) {
+ if (!addURL(urlList, path)) {
+ return false;
+ }
+ }
+ }
+
+ /*
+ * Create a class loader from the extra class paths and the current class
+ * loader. The assumption is that if the userJar isn't available right now,
+ * that the current class loader will contain the same gwt.xml module def
+ * files.
+ */
+ URL urlArray[] = urlList.toArray(new URL[urlList.size()]);
+ URLClassLoader classLoader = new URLClassLoader(urlArray,
+ CreatorUtilities.class.getClassLoader());
+ if (moduleList != null) {
+ for (String module : moduleList) {
+ String modulePath = module.replace(".", "/")
+ + ModuleDefLoader.GWT_MODULE_XML_SUFFIX;
+ URL found = classLoader.getResource(modulePath);
+ if (found == null) {
+ System.err.println("Couldn't find module definition file "
+ + modulePath + " in class path.");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Append a path to a list of URLs.
+ *
+ * @param urls list to append to
+ * @param pathToAdd string to append as the last entry in the URL list.
+ * @return <code>true</code> on success. <code>false</code> if an error
+ * occurs (malformed URL or missing file.)
+ */
+ private static boolean addURL(List<URL> urls, String pathToAdd) {
+ File f = new File(pathToAdd);
+
+ // Ignore gwt-user.jar in the validation. This helps the build process
+ // get by when overriding the location of the .jar with -Dgwt.devjar
+ if (!pathToAdd.matches(".*gwt-user.jar") && !f.exists()) {
+ System.err.println("Couldn't find library file or path " + pathToAdd);
+ return false;
+ }
+ try {
+ urls.add(f.toURI().toURL());
+ } catch (MalformedURLException urlEx) {
+ urlEx.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+}