Remove long-deprecated GWTShell and GWTCompiler tools. Change-Id: Ifa9eb9f20bfed18f4252e6d9841937ceb1d75743 Review-Link: https://gwt-review.googlesource.com/#/c/1030/ Review by: skybrian@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11411 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/build.xml b/dev/build.xml index 0ea5528..08677ef 100755 --- a/dev/build.xml +++ b/dev/build.xml
@@ -34,7 +34,6 @@ excludes="**/super/**"> <classpath> <pathelement location="${javac.out}" /> - <pathelement location="${gwt.tools.lib}/tomcat/servlet-api-2.5.jar" /> <pathelement location="${gwt.tools.lib}/junit/junit-4.8.2.jar" /> <pathelement location="${gwt.tools.lib}/jfreechart/jfreechart-1.0.3.jar" /> <pathelement location="${gwt.tools.lib}/selenium/selenium-java-client-driver.jar" /> @@ -63,33 +62,13 @@ <include name="jetty/jetty-6.1.11.jar" /> <include name="icu4j/4.4.2/icu4j.jar" /> <include name="protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar" /> - <include name="tomcat/ant-launcher-1.6.5.jar" /> - <include name="tomcat/catalina-1.0.jar" /> - <include name="tomcat/catalina-optional-1.0.jar" /> - <include name="tomcat/commons-beanutils-1.6.jar" /> - <include name="tomcat/commons-collections-3.1.jar" /> - <include name="tomcat/commons-digester-1.5.jar" /> + <!-- dependencies needed for JSP support in DevMode: BEGIN --> <include name="tomcat/commons-el-1.0.jar" /> - <include name="tomcat/commons-logging-1.0.jar" /> - <include name="tomcat/commons-modeler-1.1.jar" /> - <include name="tomcat/jakarta-regexp-1.3.jar" /> <include name="tomcat/jasper-compiler-1.0.jar" /> <include name="tomcat/jasper-runtime-1.0.jar" /> <include name="tomcat/jsp-api-2.0.jar" /> - <include name="tomcat/mx4j-jmx-1.1.jar" /> - <include name="tomcat/naming-common-1.0.jar" /> - <include name="tomcat/naming-factory-1.0.jar" /> - <include name="tomcat/naming-java-1.0.jar" /> - <include name="tomcat/naming-resources-1.0.jar" /> - <include name="tomcat/servlet-api-2.5.jar" /> - <include name="tomcat/servlet-api-2.4.jar" /> - <include name="tomcat/servlets-common-1.0.jar" /> - <include name="tomcat/servlets-default-1.0.jar" /> - <include name="tomcat/servlets-invoker-1.0.jar" /> - <include name="tomcat/tomcat-coyote-1.0.jar" /> - <include name="tomcat/tomcat-http11-1.0.jar" /> - <include name="tomcat/tomcat-jk2-2.1.jar" /> - <include name="tomcat/tomcat-util-5.1.jar" /> + <!-- dependencies needed for JSP support in DevMode: END --> + <include name="apache/commons/commons-collections-3.2.1.jar" /> <!-- htmlunit dependencies not already included: BEGIN --> <include name="apache/http/httpclient-4.1.2.jar" /> <include name="apache/http/httpcore-4.1.2.jar" /> @@ -131,33 +110,13 @@ <zipfileset src="${gwt.tools.lib}/jetty/jetty-6.1.11.jar" /> <zipfileset src="${gwt.tools.lib}/icu4j/4.4.2/icu4j.jar" /> <zipfileset src="${gwt.tools.lib}/protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/ant-launcher-1.6.5.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/catalina-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/catalina-optional-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/commons-beanutils-1.6.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/commons-collections-3.1.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/commons-digester-1.5.jar" /> + <!-- dependencies needed for JSP support in DevMode: BEGIN --> <zipfileset src="${gwt.tools.lib}/tomcat/commons-el-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/commons-logging-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/commons-modeler-1.1.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/jakarta-regexp-1.3.jar" /> <zipfileset src="${gwt.tools.lib}/tomcat/jasper-compiler-1.0.jar" /> <zipfileset src="${gwt.tools.lib}/tomcat/jasper-runtime-1.0.jar" /> <zipfileset src="${gwt.tools.lib}/tomcat/jsp-api-2.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/mx4j-jmx-1.1.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/naming-common-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/naming-factory-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/naming-java-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/naming-resources-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/servlet-api-2.5.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/servlet-api-2.4.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/servlets-common-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/servlets-default-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/servlets-invoker-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-coyote-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-http11-1.0.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-jk2-2.1.jar" /> - <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-util-5.1.jar" /> + <!-- dependencies needed for JSP support in DevMode: END --> + <zipfileset src="${gwt.tools.lib}/apache/commons/commons-collections-3.2.1.jar" /> <!-- htmlunit dependencies not already included: BEGIN --> <zipfileset src="${gwt.tools.lib}/apache/http/httpclient-4.1.2.jar" /> <zipfileset src="${gwt.tools.lib}/apache/http/httpcore-4.1.2.jar" /> @@ -220,7 +179,7 @@ <classpath> <pathelement location="${gwt.tools.lib}/apache/ant-1.6.5.jar" /> <pathelement location="${gwt.tools.lib}/eclipse/jdt-3.4.2_r894.jar" /> - <pathelement location="${gwt.tools.lib}/tomcat/commons-collections-3.1.jar" /> + <pathelement location="${gwt.tools.lib}/apache/commons/commons-collections-3.2.1.jar" /> <pathelement location="${gwt.tools.lib}/guava/guava-10.0.1/guava-10.0.1-rebased.jar" /> <pathelement location="${gwt.tools.lib}/jscomp/r1649/compiler-rebased.jar" /> </classpath>
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java b/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java index 7c65f6e..914713d 100644 --- a/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java +++ b/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
@@ -63,7 +63,7 @@ } }); - compilerThread.setName("GWTCompiler Thread"); + compilerThread.setName("GWT Compiler Thread"); compilerThread.start(); // TODO(jat): create an app frame for loggerWindow
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java deleted file mode 100644 index ef2e4ea..0000000 --- a/dev/core/src/com/google/gwt/dev/GWTCompiler.java +++ /dev/null
@@ -1,239 +0,0 @@ -/* - * 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.dev; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.core.ext.linker.ArtifactSet; -import com.google.gwt.dev.CompileTaskRunner.CompileTask; -import com.google.gwt.dev.cfg.ModuleDef; -import com.google.gwt.dev.cfg.ModuleDefLoader; -import com.google.gwt.dev.jjs.JJSOptions; -import com.google.gwt.dev.jjs.PermutationResult; -import com.google.gwt.dev.shell.CheckForUpdates; -import com.google.gwt.dev.shell.CheckForUpdates.UpdateResult; -import com.google.gwt.dev.util.FileBackedObject; -import com.google.gwt.dev.util.Util; -import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers; -import com.google.gwt.dev.util.arg.ArgHandlerOutDir; -import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional; -import com.google.gwt.dev.util.log.speedtracer.CompilerEventType; -import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger; -import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event; -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.List; -import java.util.concurrent.FutureTask; - -/** - * The main executable entry point for the GWT Java to JavaScript compiler. - * - * @deprecated Use {@link Compiler} instead - */ -@Deprecated -public class GWTCompiler { - - static final class ArgProcessor extends PrecompileTaskArgProcessor { - public ArgProcessor(LegacyCompilerOptions options) { - super(options); - - registerHandler(new ArgHandlerOutDir(options)); - - // Override the ArgHandlerWorkDirRequired in the super class. - registerHandler(new ArgHandlerWorkDirOptional(options)); - - registerHandler(new ArgHandlerLocalWorkers(options)); - } - - @Override - protected String getName() { - return GWTCompiler.class.getName(); - } - } - - /** - * Simple implementation of {@link LegacyCompilerOptions}. - */ - public static class GWTCompilerOptionsImpl extends PrecompileTaskOptionsImpl - implements LegacyCompilerOptions { - - private int localWorkers; - private File outDir; - - public GWTCompilerOptionsImpl() { - } - - public GWTCompilerOptionsImpl(LegacyCompilerOptions other) { - copyFrom(other); - } - - public void copyFrom(LegacyCompilerOptions other) { - super.copyFrom(other); - setLocalWorkers(other.getLocalWorkers()); - setOutDir(other.getOutDir()); - } - - @Override - public int getLocalWorkers() { - return localWorkers; - } - - @Override - public File getOutDir() { - return outDir; - } - - @Override - public void setLocalWorkers(int localWorkers) { - this.localWorkers = localWorkers; - } - - @Override - public void setOutDir(File outDir) { - this.outDir = outDir; - } - } - - public static void main(String[] args) { - ToolBase.legacyWarn(GWTCompiler.class, Compiler.class); - SpeedTracerLogger.init(); - Event compileEvent = SpeedTracerLogger.start(CompilerEventType.COMPILE); - - /* - * NOTE: main always exits with a call to System.exit to terminate any - * non-daemon threads that were started in Generators. Typically, this is to - * shutdown AWT related threads, since the contract for their termination is - * still implementation-dependent. - */ - final LegacyCompilerOptions options = new GWTCompilerOptionsImpl(); - boolean success = false; - if (new ArgProcessor(options).processArgs(args)) { - CompileTask task = new CompileTask() { - @Override - public boolean run(TreeLogger logger) throws UnableToCompleteException { - FutureTask<UpdateResult> updater = null; - if (!options.isUpdateCheckDisabled()) { - updater = CheckForUpdates.checkForUpdatesInBackgroundThread(logger, - CheckForUpdates.ONE_DAY); - } - boolean success = new GWTCompiler(options).run(logger); - if (success) { - CheckForUpdates.logUpdateAvailable(logger, updater); - } - return success; - } - }; - if (CompileTaskRunner.runWithAppropriateLogger(options, task)) { - // Exit w/ success code. - success = true; - } - } - - compileEvent.end(); - // Exit w/ non-success code. - System.exit(success ? 0 : 1); - } - - private final GWTCompilerOptionsImpl options; - - public GWTCompiler(LegacyCompilerOptions options) { - this.options = new GWTCompilerOptionsImpl(options); - } - - /** - * Compiles the set of modules specified in the options. - */ - public boolean run(TreeLogger logger) throws UnableToCompleteException { - ModuleDef[] modules = new ModuleDef[options.getModuleNames().size()]; - int i = 0; - for (String moduleName : options.getModuleNames()) { - modules[i++] = ModuleDefLoader.loadFromClassPath(logger, moduleName, true); - } - return run(logger, modules); - } - - /** - * Compiles a specific set of modules. - */ - public boolean run(TreeLogger logger, ModuleDef... modules) - throws UnableToCompleteException { - Event compileEvent = SpeedTracerLogger.start(CompilerEventType.COMPILE); - boolean tempWorkDir = false; - try { - if (options.getWorkDir() == null) { - options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc")); - tempWorkDir = true; - } - - for (ModuleDef module : modules) { - String moduleName = module.getName(); - - if (options.isValidateOnly()) { - if (!Precompile.validate(logger, options, module, options.getGenDir())) { - return false; - } - } else { - long compileStart = System.currentTimeMillis(); - logger = logger.branch(TreeLogger.INFO, "Compiling module " - + moduleName); - - // Optimize early since permutation compiles will run in process. - options.setOptimizePrecompile(true); - Precompilation precompilation = Precompile.precompile(logger, - options, module, options.getGenDir()); - - if (precompilation == null) { - return false; - } - Permutation[] allPerms = precompilation.getPermutations(); - List<FileBackedObject<PermutationResult>> resultFiles = CompilePerms.makeResultFiles( - options.getCompilerWorkDir(moduleName), allPerms); - CompilePerms.compile(logger, precompilation, allPerms, - options.getLocalWorkers(), resultFiles); - - ArtifactSet generatedArtifacts = precompilation.getGeneratedArtifacts(); - JJSOptions precompileOptions = precompilation.getUnifiedAst().getOptions(); - - precompilation = null; // No longer needed, so save the memory - - Link.legacyLink(logger.branch(TreeLogger.TRACE, "Linking into " - + options.getOutDir().getPath()), module, generatedArtifacts, - allPerms, resultFiles, options.getOutDir(), precompileOptions); - - long compileDone = System.currentTimeMillis(); - long delta = compileDone - compileStart; - if (logger.isLoggable(TreeLogger.INFO)) { - logger.log(TreeLogger.INFO, "Compilation succeeded -- " - + String.format("%.3f", delta / 1000d) + "s"); - } - } - } - } catch (IOException e) { - logger.log(TreeLogger.ERROR, "Unable to create compiler work directory", - e); - return false; - } finally { - compileEvent.end(); - if (tempWorkDir) { - Util.recursiveDelete(options.getWorkDir(), false); - } - } - return true; - } -}
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java deleted file mode 100644 index 77339ff..0000000 --- a/dev/core/src/com/google/gwt/dev/GWTShell.java +++ /dev/null
@@ -1,252 +0,0 @@ -/* - * 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.dev; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.core.ext.linker.ArtifactSet; -import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility; -import com.google.gwt.core.ext.linker.impl.StandardLinkerContext; -import com.google.gwt.dev.cfg.ModuleDef; -import com.google.gwt.dev.shell.WorkDirs; -import com.google.gwt.dev.shell.tomcat.EmbeddedTomcatServer; -import com.google.gwt.dev.util.OutputFileSetOnDirectory; -import com.google.gwt.dev.util.arg.ArgHandlerDisableUpdateCheck; -import com.google.gwt.dev.util.arg.ArgHandlerOutDir; -import com.google.gwt.util.tools.ArgHandlerExtra; - -import java.io.File; -import java.util.Locale; -import java.util.Set; - -/** - * The main executable class for the hosted mode shell. - */ -@Deprecated -public class GWTShell extends DevModeBase { - - /** - * Handles the list of startup urls that can be passed at the end of the - * command line. - */ - protected static class ArgHandlerStartupURLsExtra extends ArgHandlerExtra { - - private final OptionStartupURLs options; - - public ArgHandlerStartupURLsExtra(OptionStartupURLs options) { - this.options = options; - } - - @Override - public boolean addExtraArg(String arg) { - options.addStartupURL(arg); - return true; - } - - @Override - public String getPurpose() { - return "Automatically launches the specified URL"; - } - - @Override - public String[] getTagArgs() { - return new String[] {"url"}; - } - } - - /** - * The GWTShell argument processor. - */ - protected static class ArgProcessor extends DevModeBase.ArgProcessor { - public ArgProcessor(ShellOptionsImpl options, boolean forceServer, - boolean noURLs) { - super(options, forceServer); - if (!noURLs) { - registerHandler(new ArgHandlerStartupURLsExtra(options)); - } - registerHandler(new ArgHandlerOutDir(options)); - registerHandler(new ArgHandlerDisableUpdateCheck(options)); - } - - @Override - protected String getName() { - return GWTShell.class.getName(); - } - } - - /** - * Concrete class to implement all shell options. - */ - protected static class ShellOptionsImpl extends HostedModeBaseOptionsImpl - implements WorkDirs, LegacyCompilerOptions { - private int localWorkers; - private File outDir; - - public File getCompilerOutputDir(ModuleDef moduleDef) { - return new File(getOutDir(), moduleDef.getName()); - } - - public int getLocalWorkers() { - return localWorkers; - } - - public File getOutDir() { - return outDir; - } - - public File getShellPublicGenDir(ModuleDef moduleDef) { - File moduleWorkDir = new File(getWorkDir(), moduleDef.getName()); - return new File(moduleWorkDir, "public"); - } - - @Override - public File getWorkDir() { - return new File(getOutDir(), ".gwt-tmp"); - } - - public void setLocalWorkers(int localWorkers) { - this.localWorkers = localWorkers; - } - - public void setOutDir(File outDir) { - this.outDir = outDir; - } - } - - public static String checkHost(String hostUnderConsideration, - Set<String> hosts) { - hostUnderConsideration = hostUnderConsideration.toLowerCase(Locale.ENGLISH); - for (String rule : hosts) { - // match on lowercased regex - if (hostUnderConsideration.matches(".*" + rule + ".*")) { - return rule; - } - } - return null; - } - - public static String computeHostRegex(String url) { - // the entire URL up to the first slash not prefixed by a slash or colon. - String raw = url.split("(?<![:/])/")[0]; - // escape the dots and put a begin line specifier on the result - return "^" + raw.replaceAll("[.]", "[.]"); - } - - public static String formatRules(Set<String> invalidHttpHosts) { - StringBuffer out = new StringBuffer(); - for (String rule : invalidHttpHosts) { - out.append(rule); - out.append(" "); - } - return out.toString(); - } - - public static void main(String[] args) { - /* - * NOTE: main always exits with a call to System.exit to terminate any - * non-daemon threads that were started in Generators. Typically, this is to - * shutdown AWT related threads, since the contract for their termination is - * still implementation-dependent. - */ - GWTShell gwtShell = new GWTShell(); - ArgProcessor argProcessor = new ArgProcessor(gwtShell.options, false, false); - if (argProcessor.processArgs(args)) { - gwtShell.run(); - // Exit w/ success code. - System.exit(0); - } - // Exit w/ non-success code. - System.exit(-1); - } - - /** - * Hiding super field because it's actually the same object, just with a - * stronger type. - */ - @SuppressWarnings("hiding") - protected final ShellOptionsImpl options = (ShellOptionsImpl) super.options; - - protected File outDir; - - @SuppressWarnings("unused") - public void restartServer(TreeLogger logger) throws UnableToCompleteException { - // Unimplemented. - } - - @Override - protected HostedModeBaseOptions createOptions() { - return new ShellOptionsImpl(); - } - - @Override - protected void doShutDownServer() { - // Stop the HTTP server. - // - EmbeddedTomcatServer.stop(); - } - - @Override - protected boolean doStartup() { - File persistentCacheDir = new File(options.getWorkDir(), "gwt-unitCache"); - return super.doStartup(persistentCacheDir); - } - - @Override - protected int doStartUpServer() { - // TODO(jat): find a safe way to get an icon for Tomcat - TreeLogger logger = ui.getWebServerLogger("Tomcat", null); - // TODO(bruce): make tomcat work in terms of the modular launcher - String whyFailed = EmbeddedTomcatServer.start(isHeadless() ? getTopLogger() - : logger, getPort(), options, shouldAutoGenerateResources()); - - if (whyFailed != null) { - getTopLogger().log(TreeLogger.ERROR, "Starting Tomcat: " + whyFailed); - return -1; - } - return EmbeddedTomcatServer.getPort(); - } - - @Override - protected synchronized void produceOutput(TreeLogger logger, - StandardLinkerContext linkerStack, ArtifactSet artifacts, - ModuleDef module, boolean isRelink) throws UnableToCompleteException { - /* - * Legacy: in GWTShell we only copy generated artifacts into the public gen - * folder. Public files and "autogen" files have special handling (that - * needs to die). - */ - if (isRelink) { - File outputDir = options.getShellPublicGenDir(module); - outputDir.mkdirs(); - OutputFileSetOnDirectory outFileSet = new OutputFileSetOnDirectory( - outputDir, ""); - linkerStack.produceOutput(logger, artifacts, Visibility.Public, - outFileSet); - outFileSet.close(); - } - } - - protected boolean shouldAutoGenerateResources() { - return true; - } - - @Override - protected void warnAboutNoStartupUrls() { - getTopLogger().log(TreeLogger.WARN, - "No startup URLs were supplied -- add them to the end of the GWTShell" - + " command line"); - } -}
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java index 8d972e9..378ab1a 100644 --- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java +++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -466,9 +466,9 @@ } /** - * For convenience in hosted mode, servlets can be automatically loaded and - * delegated to via {@link com.google.gwt.dev.shell.GWTShellServlet}. If a - * servlet is already mapped to the specified path, it is replaced. + * For convenience in unit tests, servlets can be automatically loaded and + * mapped in the embedded web server. If a servlet is already mapped to the + * specified path, it is replaced. * * @param path the url path at which the servlet resides * @param servletClassName the name of the servlet to publish
diff --git a/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml b/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml deleted file mode 100644 index fee85f3..0000000 --- a/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml +++ /dev/null
@@ -1,566 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- A tweaked version of the default Tomcat web.xml to remove everything except the stuff we want to use --> -<web-app version="2.4"> - - <session-config> - <session-timeout>30</session-timeout> - </session-config> - - <mime-mapping> - <extension>abs</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ai</extension> - <mime-type>application/postscript</mime-type> - </mime-mapping> - <mime-mapping> - <extension>aif</extension> - <mime-type>audio/x-aiff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>aifc</extension> - <mime-type>audio/x-aiff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>aiff</extension> - <mime-type>audio/x-aiff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>aim</extension> - <mime-type>application/x-aim</mime-type> - </mime-mapping> - <mime-mapping> - <extension>art</extension> - <mime-type>image/x-jg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>asf</extension> - <mime-type>video/x-ms-asf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>asx</extension> - <mime-type>video/x-ms-asf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>au</extension> - <mime-type>audio/basic</mime-type> - </mime-mapping> - <mime-mapping> - <extension>avi</extension> - <mime-type>video/x-msvideo</mime-type> - </mime-mapping> - <mime-mapping> - <extension>avx</extension> - <mime-type>video/x-rad-screenplay</mime-type> - </mime-mapping> - <mime-mapping> - <extension>bcpio</extension> - <mime-type>application/x-bcpio</mime-type> - </mime-mapping> - <mime-mapping> - <extension>bin</extension> - <mime-type>application/octet-stream</mime-type> - </mime-mapping> - <mime-mapping> - <extension>bmp</extension> - <mime-type>image/bmp</mime-type> - </mime-mapping> - <mime-mapping> - <extension>body</extension> - <mime-type>text/html</mime-type> - </mime-mapping> - <mime-mapping> - <extension>cdf</extension> - <mime-type>application/x-cdf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>cer</extension> - <mime-type>application/x-x509-ca-cert</mime-type> - </mime-mapping> - <mime-mapping> - <extension>class</extension> - <mime-type>application/java</mime-type> - </mime-mapping> - <mime-mapping> - <extension>cpio</extension> - <mime-type>application/x-cpio</mime-type> - </mime-mapping> - <mime-mapping> - <extension>csh</extension> - <mime-type>application/x-csh</mime-type> - </mime-mapping> - <mime-mapping> - <extension>css</extension> - <mime-type>text/css</mime-type> - </mime-mapping> - <mime-mapping> - <extension>dib</extension> - <mime-type>image/bmp</mime-type> - </mime-mapping> - <mime-mapping> - <extension>doc</extension> - <mime-type>application/msword</mime-type> - </mime-mapping> - <mime-mapping> - <extension>dtd</extension> - <mime-type>text/plain</mime-type> - </mime-mapping> - <mime-mapping> - <extension>dv</extension> - <mime-type>video/x-dv</mime-type> - </mime-mapping> - <mime-mapping> - <extension>dvi</extension> - <mime-type>application/x-dvi</mime-type> - </mime-mapping> - <mime-mapping> - <extension>eps</extension> - <mime-type>application/postscript</mime-type> - </mime-mapping> - <mime-mapping> - <extension>etx</extension> - <mime-type>text/x-setext</mime-type> - </mime-mapping> - <mime-mapping> - <extension>exe</extension> - <mime-type>application/octet-stream</mime-type> - </mime-mapping> - <mime-mapping> - <extension>gif</extension> - <mime-type>image/gif</mime-type> - </mime-mapping> - <mime-mapping> - <extension>gtar</extension> - <mime-type>application/x-gtar</mime-type> - </mime-mapping> - <mime-mapping> - <extension>gz</extension> - <mime-type>application/x-gzip</mime-type> - </mime-mapping> - <mime-mapping> - <extension>hdf</extension> - <mime-type>application/x-hdf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>hqx</extension> - <mime-type>application/mac-binhex40</mime-type> - </mime-mapping> - <mime-mapping> - <extension>htc</extension> - <mime-type>text/x-component</mime-type> - </mime-mapping> - <mime-mapping> - <extension>htm</extension> - <mime-type>text/html</mime-type> - </mime-mapping> - <mime-mapping> - <extension>html</extension> - <mime-type>text/html</mime-type> - </mime-mapping> - <mime-mapping> - <extension>hqx</extension> - <mime-type>application/mac-binhex40</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ief</extension> - <mime-type>image/ief</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jad</extension> - <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jar</extension> - <mime-type>application/java-archive</mime-type> - </mime-mapping> - <mime-mapping> - <extension>java</extension> - <mime-type>text/plain</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jnlp</extension> - <mime-type>application/x-java-jnlp-file</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jpe</extension> - <mime-type>image/jpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jpeg</extension> - <mime-type>image/jpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jpg</extension> - <mime-type>image/jpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>js</extension> - <mime-type>text/javascript</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jsf</extension> - <mime-type>text/plain</mime-type> - </mime-mapping> - <mime-mapping> - <extension>jspf</extension> - <mime-type>text/plain</mime-type> - </mime-mapping> - <mime-mapping> - <extension>kar</extension> - <mime-type>audio/x-midi</mime-type> - </mime-mapping> - <mime-mapping> - <extension>latex</extension> - <mime-type>application/x-latex</mime-type> - </mime-mapping> - <mime-mapping> - <extension>m3u</extension> - <mime-type>audio/x-mpegurl</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mac</extension> - <mime-type>image/x-macpaint</mime-type> - </mime-mapping> - <mime-mapping> - <extension>man</extension> - <mime-type>application/x-troff-man</mime-type> - </mime-mapping> - <mime-mapping> - <extension>me</extension> - <mime-type>application/x-troff-me</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mid</extension> - <mime-type>audio/x-midi</mime-type> - </mime-mapping> - <mime-mapping> - <extension>midi</extension> - <mime-type>audio/x-midi</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mif</extension> - <mime-type>application/x-mif</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mov</extension> - <mime-type>video/quicktime</mime-type> - </mime-mapping> - <mime-mapping> - <extension>movie</extension> - <mime-type>video/x-sgi-movie</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mp1</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mp2</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mp3</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpa</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpe</extension> - <mime-type>video/mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpeg</extension> - <mime-type>video/mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpega</extension> - <mime-type>audio/x-mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpg</extension> - <mime-type>video/mpeg</mime-type> - </mime-mapping> - <mime-mapping> - <extension>mpv2</extension> - <mime-type>video/mpeg2</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ms</extension> - <mime-type>application/x-wais-source</mime-type> - </mime-mapping> - <mime-mapping> - <extension>nc</extension> - <mime-type>application/x-netcdf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>oda</extension> - <mime-type>application/oda</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pbm</extension> - <mime-type>image/x-portable-bitmap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pct</extension> - <mime-type>image/pict</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pdf</extension> - <mime-type>application/pdf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pgm</extension> - <mime-type>image/x-portable-graymap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pic</extension> - <mime-type>image/pict</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pict</extension> - <mime-type>image/pict</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pls</extension> - <mime-type>audio/x-scpls</mime-type> - </mime-mapping> - <mime-mapping> - <extension>png</extension> - <mime-type>image/png</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pnm</extension> - <mime-type>image/x-portable-anymap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>pnt</extension> - <mime-type>image/x-macpaint</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ppm</extension> - <mime-type>image/x-portable-pixmap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ppt</extension> - <mime-type>application/powerpoint</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ps</extension> - <mime-type>application/postscript</mime-type> - </mime-mapping> - <mime-mapping> - <extension>psd</extension> - <mime-type>image/x-photoshop</mime-type> - </mime-mapping> - <mime-mapping> - <extension>qt</extension> - <mime-type>video/quicktime</mime-type> - </mime-mapping> - <mime-mapping> - <extension>qti</extension> - <mime-type>image/x-quicktime</mime-type> - </mime-mapping> - <mime-mapping> - <extension>qtif</extension> - <mime-type>image/x-quicktime</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ras</extension> - <mime-type>image/x-cmu-raster</mime-type> - </mime-mapping> - <mime-mapping> - <extension>rgb</extension> - <mime-type>image/x-rgb</mime-type> - </mime-mapping> - <mime-mapping> - <extension>rm</extension> - <mime-type>application/vnd.rn-realmedia</mime-type> - </mime-mapping> - <mime-mapping> - <extension>roff</extension> - <mime-type>application/x-troff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>rtf</extension> - <mime-type>application/rtf</mime-type> - </mime-mapping> - <mime-mapping> - <extension>rtx</extension> - <mime-type>text/richtext</mime-type> - </mime-mapping> - <mime-mapping> - <extension>sh</extension> - <mime-type>application/x-sh</mime-type> - </mime-mapping> - <mime-mapping> - <extension>shar</extension> - <mime-type>application/x-shar</mime-type> - </mime-mapping> - <mime-mapping> - <extension>smf</extension> - <mime-type>audio/x-midi</mime-type> - </mime-mapping> - <mime-mapping> - <extension>sit</extension> - <mime-type>application/x-stuffit</mime-type> - </mime-mapping> - <mime-mapping> - <extension>snd</extension> - <mime-type>audio/basic</mime-type> - </mime-mapping> - <mime-mapping> - <extension>src</extension> - <mime-type>application/x-wais-source</mime-type> - </mime-mapping> - <mime-mapping> - <extension>sv4cpio</extension> - <mime-type>application/x-sv4cpio</mime-type> - </mime-mapping> - <mime-mapping> - <extension>sv4crc</extension> - <mime-type>application/x-sv4crc</mime-type> - </mime-mapping> - <mime-mapping> - <extension>swf</extension> - <mime-type>application/x-shockwave-flash</mime-type> - </mime-mapping> - <mime-mapping> - <extension>t</extension> - <mime-type>application/x-troff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tar</extension> - <mime-type>application/x-tar</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tcl</extension> - <mime-type>application/x-tcl</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tex</extension> - <mime-type>application/x-tex</mime-type> - </mime-mapping> - <mime-mapping> - <extension>texi</extension> - <mime-type>application/x-texinfo</mime-type> - </mime-mapping> - <mime-mapping> - <extension>texinfo</extension> - <mime-type>application/x-texinfo</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tif</extension> - <mime-type>image/tiff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tiff</extension> - <mime-type>image/tiff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tr</extension> - <mime-type>application/x-troff</mime-type> - </mime-mapping> - <mime-mapping> - <extension>tsv</extension> - <mime-type>text/tab-separated-values</mime-type> - </mime-mapping> - <mime-mapping> - <extension>txt</extension> - <mime-type>text/plain</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ulw</extension> - <mime-type>audio/basic</mime-type> - </mime-mapping> - <mime-mapping> - <extension>ustar</extension> - <mime-type>application/x-ustar</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xbm</extension> - <mime-type>image/x-xbitmap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xht</extension> - <mime-type>application/xhtml+xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xhtml</extension> - <mime-type>application/xhtml+xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xml</extension> - <mime-type>text/xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xpm</extension> - <mime-type>image/x-xpixmap</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xsl</extension> - <mime-type>text/xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>xwd</extension> - <mime-type>image/x-xwindowdump</mime-type> - </mime-mapping> - <mime-mapping> - <extension>wav</extension> - <mime-type>audio/x-wav</mime-type> - </mime-mapping> - <mime-mapping> - <extension>svg</extension> - <mime-type>image/svg+xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>svgz</extension> - <mime-type>image/svg+xml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>vsd</extension> - <mime-type>application/x-visio</mime-type> - </mime-mapping> - <mime-mapping> - <!-- Wireless Bitmap --> - <extension>wbmp</extension> - <mime-type>image/vnd.wap.wbmp</mime-type> - </mime-mapping> - <mime-mapping> - <!-- WML Source --> - <extension>wml</extension> - <mime-type>text/vnd.wap.wml</mime-type> - </mime-mapping> - <mime-mapping> - <!-- Compiled WML --> - <extension>wmlc</extension> - <mime-type>application/vnd.wap.wmlc</mime-type> - </mime-mapping> - <mime-mapping> - <!-- WML Script Source --> - <extension>wmls</extension> - <mime-type>text/vnd.wap.wmlscript</mime-type> - </mime-mapping> - <mime-mapping> - <!-- Compiled WML Script --> - <extension>wmlscriptc</extension> - <mime-type>application/vnd.wap.wmlscriptc</mime-type> - </mime-mapping> - <mime-mapping> - <extension>wrl</extension> - <mime-type>x-world/x-vrml</mime-type> - </mime-mapping> - <mime-mapping> - <extension>Z</extension> - <mime-type>application/x-compress</mime-type> - </mime-mapping> - <mime-mapping> - <extension>z</extension> - <mime-type>application/x-compress</mime-type> - </mime-mapping> - <mime-mapping> - <extension>zip</extension> - <mime-type>application/zip</mime-type> - </mime-mapping> -</web-app>
diff --git a/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml b/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml deleted file mode 100644 index e600b2f..0000000 --- a/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<web-app> - - <servlet> - <servlet-name>shell</servlet-name> - <servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class> - </servlet> - - <servlet-mapping> - <servlet-name>shell</servlet-name> - <url-pattern>/*</url-pattern> - </servlet-mapping> - -</web-app>
diff --git a/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java b/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java deleted file mode 100644 index 9e7ead7..0000000 --- a/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java +++ /dev/null
@@ -1,991 +0,0 @@ -/* - * 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.dev.shell; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.core.ext.linker.ArtifactSet; -import com.google.gwt.core.ext.linker.impl.HostedModeLinker; -import com.google.gwt.core.ext.linker.impl.StandardLinkerContext; -import com.google.gwt.dev.cfg.ModuleDef; -import com.google.gwt.dev.cfg.ModuleDefLoader; -import com.google.gwt.dev.jjs.JJSOptionsImpl; -import com.google.gwt.dev.resource.Resource; -import com.google.gwt.dev.shell.log.ServletContextTreeLogger; -import com.google.gwt.dev.util.HttpHeaders; -import com.google.gwt.dev.util.Util; -import com.google.gwt.thirdparty.guava.common.collect.MapMaker; -import com.google.gwt.util.tools.Utility; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Built-in servlet for convenient access to the public path of a specified - * module. - */ -public class GWTShellServlet extends HttpServlet { - - private static class RequestParts { - public final String moduleName; - - public final String partialPath; - - public RequestParts(HttpServletRequest request) - throws UnableToCompleteException { - String pathInfo = request.getPathInfo(); - if (pathInfo != null) { - int slash = pathInfo.indexOf('/', 1); - if (slash != -1) { - moduleName = pathInfo.substring(1, slash); - partialPath = pathInfo.substring(slash + 1); - return; - } else { - moduleName = pathInfo.substring(1); - partialPath = null; - return; - } - } - throw new UnableToCompleteException(); - } - } - - /** - * This the default cache time in seconds for files that aren't either - * *.cache.*, *.nocache.*. - */ - private static final int DEFAULT_CACHE_SECONDS = 5; - - private static final String XHTML_MIME_TYPE = "application/xhtml+xml"; - - /** - * Must keep only weak references to ModuleDefs else we permanently pin them. - */ - private final Map<String, ModuleDef> loadedModulesByName = new MapMaker().weakValues().makeMap(); - - /** - * The lifetime of the module pins the lifetime of the associated servlet; - * this is because the loaded servlet has a weak backRef to its live module - * through its context. When the module dies, the servlet needs to die also. - */ - private final Map<ModuleDef, Map<String, HttpServlet>> loadedServletsByModuleAndClassName = - new MapMaker().weakKeys().makeMap(); - - private final Map<String, String> mimeTypes = new HashMap<String, String>(); - - /** - * Only for backwards compatibility. Shouldn't we remove this now? - */ - private final Map<String, ModuleDef> modulesByServletPath = new MapMaker().weakValues().makeMap(); - - private int nextRequestId; - - private final Object requestIdLock = new Object(); - - private TreeLogger topLogger; - - private WorkDirs workDirs; - - public GWTShellServlet() { - initMimeTypes(); - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processFileRequest(request, response); - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processFileRequest(request, response); - } - - protected void processFileRequest(HttpServletRequest request, - HttpServletResponse response) throws IOException { - - String pathInfo = request.getPathInfo(); - if (pathInfo.length() == 0 || pathInfo.equals("/")) { - response.setContentType("text/html"); - PrintWriter writer = response.getWriter(); - writer.println("<html><body><basefont face='arial'>"); - writer.println("To launch an application, specify a URL of the form <code>/<i>module</i>/<i>file.html</i></code>"); - writer.println("</body></html>"); - return; - } - - TreeLogger logger = getLogger(); - - // Parse the request assuming it is module/resource. - // - RequestParts parts; - try { - parts = new RequestParts(request); - } catch (UnableToCompleteException e) { - sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, - "Don't know what to do with this URL: '" + pathInfo + "'"); - return; - } - - String partialPath = parts.partialPath; - String moduleName = parts.moduleName; - - // If the module is renamed, substitute the renamed module name - ModuleDef moduleDef = loadedModulesByName.get(moduleName); - if (moduleDef != null) { - moduleName = moduleDef.getName(); - } - - if (partialPath == null) { - // Redir back to the same URL but ending with a slash. - // - response.sendRedirect(moduleName + "/"); - return; - } else if (partialPath.length() > 0) { - // Both the module name and a resource. - // - doGetPublicFile(request, response, logger, partialPath, moduleName); - return; - } else { - // Was just the module name, ending with a slash. - // - doGetModule(request, response, logger, parts); - return; - } - } - - @Override - protected void service(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - TreeLogger logger = getLogger(); - int id = allocateRequestId(); - if (logger.isLoggable(TreeLogger.TRACE)) { - StringBuffer url = request.getRequestURL(); - - // Branch the logger in case we decide to log more below. - logger = logger.branch(TreeLogger.TRACE, "Request " + id + ": " + url, - null); - } - - String servletClassName = null; - ModuleDef moduleDef = null; - - try { - // Attempt to split the URL into module/path, which we'll use to see - // if we can map the request to a module's servlet. - RequestParts parts = new RequestParts(request); - - if ("favicon.ico".equalsIgnoreCase(parts.moduleName)) { - sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, - "Icon not available"); - return; - } - - // See if the request references a module we know. - moduleDef = getModuleDef(logger, parts.moduleName); - if (moduleDef != null) { - // Okay, we know this module. Do we know this servlet path? - // It is right to prepend the slash because (1) ModuleDefSchema requires - // every servlet path to begin with a slash and (2) RequestParts always - // rips off the leading slash. - String servletPath = "/" + parts.partialPath; - servletClassName = moduleDef.findServletForPath(servletPath); - - // Fall-through below, where we check servletClassName. - } else { - // Fall-through below, where we check servletClassName. - } - } catch (UnableToCompleteException e) { - // Do nothing, since it was speculative anyway. - } - - // BEGIN BACKWARD COMPATIBILITY - if (servletClassName == null) { - // Try to map a bare path that isn't preceded by the module name. - // This is no longer the recommended practice, so we warn. - String path = request.getPathInfo(); - moduleDef = modulesByServletPath.get(path); - if (moduleDef != null) { - // See if there is a servlet we can delegate to for the given url. - servletClassName = moduleDef.findServletForPath(path); - - if (servletClassName != null) { - TreeLogger branch = logger.branch(TreeLogger.WARN, - "Use of deprecated hosted mode servlet path mapping", null); - branch.log( - TreeLogger.WARN, - "The client code is invoking the servlet with a URL that is not module-relative: " - + path, null); - branch.log( - TreeLogger.WARN, - "Prepend GWT.getModuleBaseURL() to the URL in client code to create a module-relative URL: /" - + moduleDef.getName() + path, null); - branch.log( - TreeLogger.WARN, - "Using module-relative URLs ensures correct URL-independent behavior in external servlet containers", - null); - } - - // Fall-through below, where we check servletClassName. - } else { - // Fall-through below, where we check servletClassName. - } - } - // END BACKWARD COMPATIBILITY - - // Load/get the servlet if we found one. - if (servletClassName != null) { - HttpServlet delegatee = tryGetOrLoadServlet(logger, moduleDef, - servletClassName); - if (delegatee == null) { - logger.log(TreeLogger.ERROR, "Unable to dispatch request", null); - sendErrorResponse(response, - HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Unable to find/load mapped servlet class '" + servletClassName - + "'"); - return; - } - - // Delegate everything to the downstream servlet and we're done. - delegatee.service(request, response); - } else { - // Use normal default processing on this request, since we couldn't - // recognize it as anything special. - super.service(request, response); - } - } - - private int allocateRequestId() { - synchronized (requestIdLock) { - return nextRequestId++; - } - } - - /** - * Handle auto-generated resources. - * - * @return <code>true</code> if a resource was generated - */ - private boolean autoGenerateResources(HttpServletRequest request, - HttpServletResponse response, TreeLogger logger, String partialPath, - String moduleName) throws IOException { - - if (partialPath.equals(moduleName + ".nocache.js")) { - if (request.getParameter("compiled") == null) { - // Generate the .js file. - try { - String js = genSelectionScript(logger, moduleName); - setResponseCacheHeaders(response, 0); // do not cache selection script - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("text/javascript"); - response.getWriter().println(js); - return true; - } catch (UnableToCompleteException e) { - // The error will have already been logged. Continue, since this could - // actually be a request for a static file that happens to have an - // unfortunately confusing name. - } - } - } else if (partialPath.equals("hosted.html")) { - String html = HostedModeLinker.getHostedHtml(); - setResponseCacheHeaders(response, DEFAULT_CACHE_SECONDS); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("text/html"); - response.getWriter().println(html); - return true; - } - - return false; - } - - private void doGetModule(HttpServletRequest request, - HttpServletResponse response, TreeLogger logger, RequestParts parts) - throws IOException { - - // Generate a generic empty host page. - // - String msg = "The development shell servlet received a request to generate a host page for module '" - + parts.moduleName + "' "; - - logger = logger.branch(TreeLogger.TRACE, msg, null); - - try { - // Try to load the module just to make sure it'll work. - getModuleDef(logger, parts.moduleName); - } catch (UnableToCompleteException e) { - sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, - "Unable to find/load module '" + Util.escapeXml(parts.moduleName) - + "' (see server log for details)"); - return; - } - - response.setContentType("text/html"); - PrintWriter writer = response.getWriter(); - writer.println("<html><head>"); - writer.print("<script language='javascript' src='"); - writer.print(parts.moduleName); - writer.println(".nocache.js'></script>"); - - // Create a property for each query param. - Map<String, String[]> params = getParameterMap(request); - for (Map.Entry<String, String[]> entry : params.entrySet()) { - String[] values = entry.getValue(); - if (values.length > 0) { - writer.print("<meta name='gwt:property' content='"); - writer.print(entry.getKey()); - writer.print("="); - writer.print(values[values.length - 1]); - writer.println("'>"); - } - } - - writer.println("</head><body>"); - writer.println("<iframe src=\"javascript:''\" id='__gwt_historyFrame' " - + "style='position:absolute;width:0;height:0;border:0'></iframe>"); - writer.println("<noscript>"); - writer.println(" <div style=\"width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif\">"); - writer.println(" Your web browser must have JavaScript enabled"); - writer.println(" in order for this application to display correctly."); - writer.println(" </div>"); - writer.println("</noscript>"); - writer.println("</body></html>"); - - // Done. - } - - /** - * Fetch a file and return it as the HTTP response, setting the cache-related - * headers according to the name of the file (see - * {@link #getCacheTime(String)}). This function honors If-Modified-Since to - * minimize the impact of limiting caching of files for development. - * - * @param request the HTTP request - * @param response the HTTP response - * @param logger a TreeLogger to use for debug output - * @param partialPath the path within the module - * @param moduleName the name of the module - * @throws IOException - */ - @SuppressWarnings("deprecation") - private void doGetPublicFile(HttpServletRequest request, - HttpServletResponse response, TreeLogger logger, String partialPath, - String moduleName) throws IOException { - - // Create a logger branch for this request. - logger = logger.branch(TreeLogger.TRACE, - "The development shell servlet received a request for '" - + partialPath + "' in module '" + moduleName + ".gwt.xml' ", null); - - // Handle auto-generation of resources. - if (shouldAutoGenerateResources()) { - if (autoGenerateResources(request, response, logger, partialPath, - moduleName)) { - return; - } - } - - URL foundResource = null; - try { - // Look for the requested file on the public path. - // - ModuleDef moduleDef = getModuleDef(logger, moduleName); - if (shouldAutoGenerateResources()) { - Resource publicResource = moduleDef.findPublicFile(partialPath); - if (publicResource != null) { - foundResource = publicResource.getURL(); - } - - if (foundResource == null) { - // Look for public generated files - File shellDir = getShellWorkDirs().getShellPublicGenDir(moduleDef); - File requestedFile = new File(shellDir, partialPath); - if (requestedFile.exists()) { - try { - foundResource = requestedFile.toURI().toURL(); - } catch (MalformedURLException e) { - // ignore since it was speculative anyway - } - } - } - } - - /* - * If the user is coming from compiled web-mode, check the linker output - * directory for the real bootstrap file. - */ - if (foundResource == null) { - File moduleDir = getShellWorkDirs().getCompilerOutputDir(moduleDef); - File requestedFile = new File(moduleDir, partialPath); - if (requestedFile.exists()) { - try { - foundResource = requestedFile.toURI().toURL(); - } catch (MalformedURLException e) { - // ignore since it was speculative anyway - } - } - } - - if (foundResource == null) { - String msg; - if ("gwt.js".equals(partialPath)) { - msg = "Loading the old 'gwt.js' bootstrap script is no longer supported; please load '" - + moduleName + ".nocache.js' directly"; - } else { - msg = "Resource not found: " + partialPath + "; " - + "(could a file be missing from the public path or a <servlet> " - + "tag misconfigured in module " + moduleName + ".gwt.xml ?)"; - } - logger.log(TreeLogger.WARN, msg, null); - throw new UnableToCompleteException(); - } - } catch (UnableToCompleteException e) { - sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, - "Cannot find resource '" + partialPath - + "' in the public path of module '" + moduleName + "'"); - return; - } - - // Get the MIME type. - String path = foundResource.toExternalForm(); - String mimeType = null; - try { - mimeType = getServletContext().getMimeType(path); - } catch (UnsupportedOperationException e) { - // Certain minimalist servlet containers throw this. - // Fall through to guess the type. - } - - if (mimeType == null) { - mimeType = guessMimeType(path); - if (logger.isLoggable(TreeLogger.TRACE)) { - logger.log(TreeLogger.TRACE, "Guessed MIME type '" + mimeType + "'", null); - } - } - - maybeIssueXhtmlWarning(logger, mimeType, partialPath); - - long cacheSeconds = getCacheTime(path); - - InputStream is = null; - try { - // Check for up-to-datedness. - URLConnection conn = foundResource.openConnection(); - long lastModified = conn.getLastModified(); - if (isNotModified(request, lastModified)) { - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - setResponseCacheHeaders(response, cacheSeconds); - return; - } - - // Set up headers to really send it. - response.setStatus(HttpServletResponse.SC_OK); - long now = new Date().getTime(); - response.setHeader(HttpHeaders.DATE, - HttpHeaders.toInternetDateFormat(now)); - response.setContentType(mimeType); - String lastModifiedStr = HttpHeaders.toInternetDateFormat(lastModified); - response.setHeader(HttpHeaders.LAST_MODIFIED, lastModifiedStr); - - // Expiration header. Either immediately stale (requiring an - // "If-Modified-Since") or infinitely cacheable (not requiring even a - // freshness check). - setResponseCacheHeaders(response, cacheSeconds); - - // Content length. - int contentLength = conn.getContentLength(); - if (contentLength >= 0) { - response.setHeader(HttpHeaders.CONTENT_LENGTH, - Integer.toString(contentLength)); - } - - // Send the bytes. - is = conn.getInputStream(); - streamOut(is, response.getOutputStream(), 1024 * 8); - } finally { - Utility.close(is); - } - } - - /** - * Generates a module.js file on the fly. Note that the nocache file that is - * generated that can only be used for hosted mode. It cannot produce a web - * mode version, since this servlet doesn't know strong names, since by - * definition of "hosted mode" JavaScript hasn't been compiled at this point. - */ - private String genSelectionScript(TreeLogger logger, String moduleName) - throws UnableToCompleteException { - if (logger.isLoggable(TreeLogger.TRACE)) { - logger.log(TreeLogger.TRACE, - "Generating a script selection script for module " + moduleName); - } - ModuleDef module = getModuleDef(logger, moduleName); - StandardLinkerContext context = new StandardLinkerContext(logger, module, - new JJSOptionsImpl()); - ArtifactSet artifacts = context.getArtifactsForPublicResources(logger, - module); - HostedModeLinker linker = new HostedModeLinker(); - return linker.generateSelectionScript(logger, context, artifacts); - } - - /** - * Get the length of time a given file should be cacheable. If the path - * contains *.nocache.*, it is never cacheable; if it contains *.cache.*, it - * is infinitely cacheable; anything else gets a default time. - * - * @return cache time in seconds, or 0 if the file is not cacheable at all - */ - private long getCacheTime(String path) { - int lastDot = path.lastIndexOf('.'); - if (lastDot >= 0) { - String prefix = path.substring(0, lastDot); - if (prefix.endsWith(".cache")) { - // RFC2616 says to never give a cache time of more than a year - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 - return HttpHeaders.SEC_YR; - } else if (prefix.endsWith(".nocache")) { - return 0; - } - } - return DEFAULT_CACHE_SECONDS; - } - - private synchronized TreeLogger getLogger() { - if (topLogger == null) { - ServletContext servletContext = getServletContext(); - final String attr = "com.google.gwt.dev.shell.logger"; - topLogger = (TreeLogger) servletContext.getAttribute(attr); - if (topLogger == null) { - // No shell available, so wrap the regular servlet context logger. - // - topLogger = new ServletContextTreeLogger(servletContext); - } - } - return topLogger; - } - - /** - * We don't actually log this on purpose since the client does anyway. - */ - private ModuleDef getModuleDef(TreeLogger logger, String moduleName) - throws UnableToCompleteException { - synchronized (loadedModulesByName) { - ModuleDef moduleDef = loadedModulesByName.get(moduleName); - if (moduleDef == null) { - moduleDef = ModuleDefLoader.loadFromClassPath(logger, moduleName, false); - loadedModulesByName.put(moduleName, moduleDef); - loadedModulesByName.put(moduleDef.getName(), moduleDef); - - // BEGIN BACKWARD COMPATIBILITY - // The following map of servlet path to module is included only - // for backward-compatibility. We are going to remove this functionality - // when we go out of beta. The new behavior is that the client should - // specify the module name as part of the URL and construct it using - // getModuleBaseURL(). - String[] servletPaths = moduleDef.getServletPaths(); - for (int i = 0; i < servletPaths.length; i++) { - modulesByServletPath.put(servletPaths[i], moduleDef); - } - // END BACKWARD COMPATIBILITY - } - return moduleDef; - } - } - - @SuppressWarnings("unchecked") - private Map<String, String[]> getParameterMap(HttpServletRequest request) { - return request.getParameterMap(); - } - - private synchronized WorkDirs getShellWorkDirs() { - if (workDirs == null) { - ServletContext servletContext = getServletContext(); - final String attr = "com.google.gwt.dev.shell.workdirs"; - workDirs = (WorkDirs) servletContext.getAttribute(attr); - assert (workDirs != null); - } - return workDirs; - } - - private String guessMimeType(String fullPath) { - int dot = fullPath.lastIndexOf('.'); - if (dot != -1) { - String ext = fullPath.substring(dot + 1); - String mimeType = mimeTypes.get(ext); - if (mimeType != null) { - return mimeType; - } - - // Otherwise, fall through. - // - } - - // Last resort. - // - return "application/octet-stream"; - } - - private void initMimeTypes() { - mimeTypes.put("abs", "audio/x-mpeg"); - mimeTypes.put("ai", "application/postscript"); - mimeTypes.put("aif", "audio/x-aiff"); - mimeTypes.put("aifc", "audio/x-aiff"); - mimeTypes.put("aiff", "audio/x-aiff"); - mimeTypes.put("aim", "application/x-aim"); - mimeTypes.put("art", "image/x-jg"); - mimeTypes.put("asf", "video/x-ms-asf"); - mimeTypes.put("asx", "video/x-ms-asf"); - mimeTypes.put("au", "audio/basic"); - mimeTypes.put("avi", "video/x-msvideo"); - mimeTypes.put("avx", "video/x-rad-screenplay"); - mimeTypes.put("bcpio", "application/x-bcpio"); - mimeTypes.put("bin", "application/octet-stream"); - mimeTypes.put("bmp", "image/bmp"); - mimeTypes.put("body", "text/html"); - mimeTypes.put("cdf", "application/x-cdf"); - mimeTypes.put("cer", "application/x-x509-ca-cert"); - mimeTypes.put("class", "application/java"); - mimeTypes.put("cpio", "application/x-cpio"); - mimeTypes.put("csh", "application/x-csh"); - mimeTypes.put("css", "text/css"); - mimeTypes.put("dib", "image/bmp"); - mimeTypes.put("doc", "application/msword"); - mimeTypes.put("dtd", "text/plain"); - mimeTypes.put("dv", "video/x-dv"); - mimeTypes.put("dvi", "application/x-dvi"); - mimeTypes.put("eps", "application/postscript"); - mimeTypes.put("etx", "text/x-setext"); - mimeTypes.put("exe", "application/octet-stream"); - mimeTypes.put("gif", "image/gif"); - mimeTypes.put("gtar", "application/x-gtar"); - mimeTypes.put("gz", "application/x-gzip"); - mimeTypes.put("hdf", "application/x-hdf"); - mimeTypes.put("hqx", "application/mac-binhex40"); - mimeTypes.put("htc", "text/x-component"); - mimeTypes.put("htm", "text/html"); - mimeTypes.put("html", "text/html"); - mimeTypes.put("hqx", "application/mac-binhex40"); - mimeTypes.put("ief", "image/ief"); - mimeTypes.put("jad", "text/vnd.sun.j2me.app-descriptor"); - mimeTypes.put("jar", "application/java-archive"); - mimeTypes.put("java", "text/plain"); - mimeTypes.put("jnlp", "application/x-java-jnlp-file"); - mimeTypes.put("jpe", "image/jpeg"); - mimeTypes.put("jpeg", "image/jpeg"); - mimeTypes.put("jpg", "image/jpeg"); - mimeTypes.put("js", "text/javascript"); - mimeTypes.put("jsf", "text/plain"); - mimeTypes.put("jspf", "text/plain"); - mimeTypes.put("kar", "audio/x-midi"); - mimeTypes.put("latex", "application/x-latex"); - mimeTypes.put("m3u", "audio/x-mpegurl"); - mimeTypes.put("mac", "image/x-macpaint"); - mimeTypes.put("man", "application/x-troff-man"); - mimeTypes.put("me", "application/x-troff-me"); - mimeTypes.put("mid", "audio/x-midi"); - mimeTypes.put("midi", "audio/x-midi"); - mimeTypes.put("mif", "application/x-mif"); - mimeTypes.put("mov", "video/quicktime"); - mimeTypes.put("movie", "video/x-sgi-movie"); - mimeTypes.put("mp1", "audio/x-mpeg"); - mimeTypes.put("mp2", "audio/x-mpeg"); - mimeTypes.put("mp3", "audio/x-mpeg"); - mimeTypes.put("mpa", "audio/x-mpeg"); - mimeTypes.put("mpe", "video/mpeg"); - mimeTypes.put("mpeg", "video/mpeg"); - mimeTypes.put("mpega", "audio/x-mpeg"); - mimeTypes.put("mpg", "video/mpeg"); - mimeTypes.put("mpv2", "video/mpeg2"); - mimeTypes.put("ms", "application/x-wais-source"); - mimeTypes.put("nc", "application/x-netcdf"); - mimeTypes.put("oda", "application/oda"); - mimeTypes.put("pbm", "image/x-portable-bitmap"); - mimeTypes.put("pct", "image/pict"); - mimeTypes.put("pdf", "application/pdf"); - mimeTypes.put("pgm", "image/x-portable-graymap"); - mimeTypes.put("pic", "image/pict"); - mimeTypes.put("pict", "image/pict"); - mimeTypes.put("pls", "audio/x-scpls"); - mimeTypes.put("png", "image/png"); - mimeTypes.put("pnm", "image/x-portable-anymap"); - mimeTypes.put("pnt", "image/x-macpaint"); - mimeTypes.put("ppm", "image/x-portable-pixmap"); - mimeTypes.put("ppt", "application/powerpoint"); - mimeTypes.put("ps", "application/postscript"); - mimeTypes.put("psd", "image/x-photoshop"); - mimeTypes.put("qt", "video/quicktime"); - mimeTypes.put("qti", "image/x-quicktime"); - mimeTypes.put("qtif", "image/x-quicktime"); - mimeTypes.put("ras", "image/x-cmu-raster"); - mimeTypes.put("rgb", "image/x-rgb"); - mimeTypes.put("rm", "application/vnd.rn-realmedia"); - mimeTypes.put("roff", "application/x-troff"); - mimeTypes.put("rtf", "application/rtf"); - mimeTypes.put("rtx", "text/richtext"); - mimeTypes.put("sh", "application/x-sh"); - mimeTypes.put("shar", "application/x-shar"); - mimeTypes.put("smf", "audio/x-midi"); - mimeTypes.put("sit", "application/x-stuffit"); - mimeTypes.put("snd", "audio/basic"); - mimeTypes.put("src", "application/x-wais-source"); - mimeTypes.put("sv4cpio", "application/x-sv4cpio"); - mimeTypes.put("sv4crc", "application/x-sv4crc"); - mimeTypes.put("swf", "application/x-shockwave-flash"); - mimeTypes.put("t", "application/x-troff"); - mimeTypes.put("tar", "application/x-tar"); - mimeTypes.put("tcl", "application/x-tcl"); - mimeTypes.put("tex", "application/x-tex"); - mimeTypes.put("texi", "application/x-texinfo"); - mimeTypes.put("texinfo", "application/x-texinfo"); - mimeTypes.put("tif", "image/tiff"); - mimeTypes.put("tiff", "image/tiff"); - mimeTypes.put("tr", "application/x-troff"); - mimeTypes.put("tsv", "text/tab-separated-values"); - mimeTypes.put("txt", "text/plain"); - mimeTypes.put("ulw", "audio/basic"); - mimeTypes.put("ustar", "application/x-ustar"); - mimeTypes.put("xbm", "image/x-xbitmap"); - mimeTypes.put("xht", "application/xhtml+xml"); - mimeTypes.put("xhtml", "application/xhtml+xml"); - mimeTypes.put("xml", "text/xml"); - mimeTypes.put("xpm", "image/x-xpixmap"); - mimeTypes.put("xsl", "text/xml"); - mimeTypes.put("xwd", "image/x-xwindowdump"); - mimeTypes.put("wav", "audio/x-wav"); - mimeTypes.put("svg", "image/svg+xml"); - mimeTypes.put("svgz", "image/svg+xml"); - mimeTypes.put("vsd", "application/x-visio"); - mimeTypes.put("wbmp", "image/vnd.wap.wbmp"); - mimeTypes.put("wml", "text/vnd.wap.wml"); - mimeTypes.put("wmlc", "application/vnd.wap.wmlc"); - mimeTypes.put("wmls", "text/vnd.wap.wmlscript"); - mimeTypes.put("wmlscriptc", "application/vnd.wap.wmlscriptc"); - mimeTypes.put("wrl", "x-world/x-vrml"); - mimeTypes.put("Z", "application/x-compress"); - mimeTypes.put("z", "application/x-compress"); - mimeTypes.put("zip", "application/zip"); - } - - /** - * Checks to see whether or not a client's file is out of date relative to the - * original. - */ - private boolean isNotModified(HttpServletRequest request, long ageOfServerCopy) { - // The age of the server copy *must* have the milliseconds truncated. - // Since milliseconds isn't part of the GMT format, failure to truncate - // will leave the file in a state where it appears constantly out of date - // and yet it can never get in sync because the Last-Modified date keeps - // truncating off the milliseconds part on its way out. - // - ageOfServerCopy -= (ageOfServerCopy % 1000); - - long ageOfClientCopy = 0; - String ifModifiedSince = request.getHeader("If-Modified-Since"); - if (ifModifiedSince != null) { - // Rip off any additional stuff at the end, such as "; length=" - // (IE does add this). - // - int lastSemi = ifModifiedSince.lastIndexOf(';'); - if (lastSemi != -1) { - ifModifiedSince = ifModifiedSince.substring(0, lastSemi); - } - ageOfClientCopy = HttpHeaders.fromInternetDateFormat(ifModifiedSince); - } - - if (ageOfClientCopy >= ageOfServerCopy) { - // The client already has a good copy. - // - return true; - } else { - // The client needs a fresh copy of the requested file. - // - return false; - } - } - - private void maybeIssueXhtmlWarning(TreeLogger logger, String mimeType, - String path) { - if (!XHTML_MIME_TYPE.equals(mimeType)) { - return; - } - - String msg = "File was returned with content-type of \"" + mimeType - + "\". GWT requires browser features that are not available to " - + "documents with this content-type."; - - int ix = path.lastIndexOf('.'); - if (ix >= 0 && ix < path.length()) { - String base = path.substring(0, ix); - msg += " Consider renaming \"" + path + "\" to \"" + base + ".html\"."; - } - - logger.log(TreeLogger.WARN, msg, null); - } - - private void sendErrorResponse(HttpServletResponse response, int statusCode, - String msg) throws IOException { - response.setContentType("text/html"); - response.getWriter().println(msg); - response.setStatus(statusCode); - } - - /** - * Sets the Cache-control and Expires headers in the response based on the - * supplied cache time. - * - * Expires is used in addition to Cache-control for older clients or proxies - * which may not properly understand Cache-control. - * - * @param response the HttpServletResponse to update - * @param cacheTime non-negative number of seconds to cache the response; 0 - * means specifically do not allow caching at all. - * @throws IllegalArgumentException if cacheTime is negative - */ - private void setResponseCacheHeaders(HttpServletResponse response, - long cacheTime) { - long expires; - if (cacheTime < 0) { - throw new IllegalArgumentException("cacheTime of " + cacheTime - + " is negative"); - } - if (cacheTime > 0) { - // Expire the specified seconds in the future. - expires = new Date().getTime() + cacheTime * HttpHeaders.MS_SEC; - } else { - // Prevent caching by using a time in the past for cache expiration. - // Use January 2, 1970 00:00:00, to account for timezone changes - // in case a browser tries to convert to a local timezone first - // 0=Jan 1, so add 1 day's worth of milliseconds to get Jan 2 - expires = HttpHeaders.SEC_DAY * HttpHeaders.MS_SEC; - } - response.setHeader(HttpHeaders.CACHE_CONTROL, - HttpHeaders.CACHE_CONTROL_MAXAGE + cacheTime); - String expiresString = HttpHeaders.toInternetDateFormat(expires); - response.setHeader(HttpHeaders.EXPIRES, expiresString); - } - - private boolean shouldAutoGenerateResources() { - ServletContext servletContext = getServletContext(); - final String attr = "com.google.gwt.dev.shell.shouldAutoGenerateResources"; - Boolean attrValue = (Boolean) servletContext.getAttribute(attr); - if (attrValue == null) { - return true; - } - return attrValue; - } - - private void streamOut(InputStream in, OutputStream out, int bufferSize) - throws IOException { - assert (bufferSize >= 0); - - byte[] buffer = new byte[bufferSize]; - int bytesRead = 0; - while (true) { - bytesRead = in.read(buffer); - if (bytesRead >= 0) { - // Copy the bytes out. - out.write(buffer, 0, bytesRead); - } else { - // End of input stream. - out.flush(); - return; - } - } - } - - private HttpServlet tryGetOrLoadServlet(TreeLogger logger, - ModuleDef moduleDef, String className) { - - // Maps className to live servlet for this module. - Map<String, HttpServlet> moduleServlets; - synchronized (loadedServletsByModuleAndClassName) { - moduleServlets = loadedServletsByModuleAndClassName.get(moduleDef); - if (moduleServlets == null) { - moduleServlets = new HashMap<String, HttpServlet>(); - loadedServletsByModuleAndClassName.put(moduleDef, moduleServlets); - } - } - - synchronized (moduleServlets) { - HttpServlet servlet = moduleServlets.get(className); - if (servlet != null) { - // Found it. - // - return servlet; - } - - // Try to load and instantiate it. - // - Throwable caught = null; - try { - Class<?> servletClass = Class.forName(className); - Object newInstance = servletClass.newInstance(); - if (!(newInstance instanceof HttpServlet)) { - logger.log(TreeLogger.ERROR, - "Not compatible with HttpServlet: " + className - + " (does your service extend RemoteServiceServlet?)", null); - return null; - } - - // Success. Hang onto the instance so we can reuse it. - // - servlet = (HttpServlet) newInstance; - - // We create proxies for ServletContext and ServletConfig to enable - // RemoteServiceServlets to load public and generated resources via - // ServletContext.getResourceAsStream() - // - ServletContext context = new HostedModeServletContextProxy( - getServletContext(), moduleDef, getShellWorkDirs()); - ServletConfig config = new HostedModeServletConfigProxy( - getServletConfig(), context); - - servlet.init(config); - - moduleServlets.put(className, servlet); - return servlet; - } catch (ClassNotFoundException e) { - caught = e; - } catch (InstantiationException e) { - caught = e; - } catch (IllegalAccessException e) { - caught = e; - } catch (ServletException e) { - caught = e; - } - String msg = "Unable to instantiate '" + className + "'"; - logger.log(TreeLogger.ERROR, msg, caught); - return null; - } - } -}
diff --git a/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java b/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java deleted file mode 100644 index d6b321e..0000000 --- a/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java +++ /dev/null
@@ -1,338 +0,0 @@ -/* - * Copyright 2007 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.dev.shell; - -import com.google.gwt.dev.cfg.ModuleDef; -import com.google.gwt.dev.resource.Resource; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.WeakReference; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Enumeration; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -/** - * ServletContext proxy that implements the getResource and getResourceAsStream - * members so that they can work with the {@link GWTShellServlet}. - */ -class HostedModeServletContextProxy implements ServletContext { - private final ServletContext context; - /** - * Avoid pinning my moduleDef. - */ - private final WeakReference<ModuleDef> moduleDefRef; - private final WorkDirs workDirs; - - HostedModeServletContextProxy(ServletContext context, ModuleDef moduleDef, - WorkDirs workDirs) { - this.context = context; - this.moduleDefRef = new WeakReference<ModuleDef>(moduleDef); - this.workDirs = workDirs; - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getAttribute(java.lang.String) - */ - public Object getAttribute(String arg0) { - return context.getAttribute(arg0); - } - - /** - * @return - * @see javax.servlet.ServletContext#getAttributeNames() - */ - @SuppressWarnings("unchecked") - public Enumeration<String> getAttributeNames() { - return context.getAttributeNames(); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getContext(java.lang.String) - */ - public ServletContext getContext(String arg0) { - return context.getContext(arg0); - } - - public String getContextPath() { - return context.getContextPath(); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getInitParameter(java.lang.String) - */ - public String getInitParameter(String arg0) { - return context.getInitParameter(arg0); - } - - /** - * @return - * @see javax.servlet.ServletContext#getInitParameterNames() - */ - public Enumeration<?> getInitParameterNames() { - return context.getInitParameterNames(); - } - - /** - * @return - * @see javax.servlet.ServletContext#getMajorVersion() - */ - public int getMajorVersion() { - return context.getMajorVersion(); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getMimeType(java.lang.String) - */ - public String getMimeType(String arg0) { - return context.getMimeType(arg0); - } - - /** - * @return - * @see javax.servlet.ServletContext#getMinorVersion() - */ - public int getMinorVersion() { - return context.getMinorVersion(); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String) - */ - public RequestDispatcher getNamedDispatcher(String arg0) { - return context.getNamedDispatcher(arg0); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getRealPath(java.lang.String) - */ - public String getRealPath(String arg0) { - return context.getRealPath(arg0); - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String) - */ - public RequestDispatcher getRequestDispatcher(String arg0) { - return context.getRequestDispatcher(arg0); - } - - /** - * @param arg0 - * @return - * @throws MalformedURLException - * @see javax.servlet.ServletContext#getResource(java.lang.String) - */ - @SuppressWarnings("deprecation") - public URL getResource(String path) throws MalformedURLException { - ModuleDef moduleDef = moduleDefRef.get(); - assert (moduleDef != null) : "GWTShellServlet should have guaranteed that a" - + " live servlet will never process a request for a dead module; if you" - + " are using this servlet outside the context of processing a call," - + " then don't do that"; - - String moduleContext = "/" + moduleDef.getName() + "/"; - if (!path.startsWith(moduleContext)) { - // Check for a renamed module - moduleContext = "/" + moduleDef.getCanonicalName() + "/"; - if (!path.startsWith(moduleContext)) { - // This path is in a different context; just return null - return null; - } - } - - String partialPath = path.substring(moduleContext.length()); - - // Try to get the resource from the application's public path - Resource publicResource = moduleDef.findPublicFile(partialPath); - if (publicResource != null) { - return publicResource.getURL(); - } - - // Otherwise try the path in the shell's public generated directory - File shellDir = workDirs.getShellPublicGenDir(moduleDef); - File requestedFile = new File(shellDir, partialPath); - if (requestedFile.exists()) { - return requestedFile.toURI().toURL(); - } - - /* - * If the user is coming from compiled web-mode, check the linker output - * directory for the file. We'll default to using the output directory of - * the first linker defined in the <set-linker> tab. - */ - File linkDir = workDirs.getCompilerOutputDir(moduleDef); - requestedFile = new File(linkDir, partialPath); - if (requestedFile.exists()) { - try { - return requestedFile.toURI().toURL(); - } catch (MalformedURLException e) { - // ignore since it was speculative anyway - } - } - - return null; - } - - /** - * @param arg0 - * @return - * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String) - */ - public InputStream getResourceAsStream(String arg0) { - URL url; - try { - url = getResource(arg0); - if (url != null) { - return url.openStream(); - } - } catch (MalformedURLException e) { - // Ignore the exception; return null - } catch (IOException e) { - // Ignore the exception; return null - } - - return null; - } - - /** - * - * @param path - * @return - * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String) - */ - @SuppressWarnings("unchecked") - public Set<String> getResourcePaths(String path) { - return context.getResourcePaths(path); - } - - /** - * @return - * @see javax.servlet.ServletContext#getServerInfo() - */ - public String getServerInfo() { - return context.getServerInfo(); - } - - /** - * @param arg0 - * @return - * @throws ServletException - * @deprecated - * @see javax.servlet.ServletContext#getServlet(java.lang.String) - */ - @Deprecated - public Servlet getServlet(String arg0) throws ServletException { - return context.getServlet(arg0); - } - - /** - * @return - * @see javax.servlet.ServletContext#getServletContextName() - */ - public String getServletContextName() { - return context.getServletContextName(); - } - - /** - * @return - * @deprecated - * @see javax.servlet.ServletContext#getServletNames() - */ - @Deprecated - @SuppressWarnings("unchecked") - public Enumeration<String> getServletNames() { - return context.getServletNames(); - } - - /** - * @return - * @deprecated - * @see javax.servlet.ServletContext#getServlets() - */ - @Deprecated - @SuppressWarnings("unchecked") - public Enumeration<Servlet> getServlets() { - return context.getServlets(); - } - - /** - * @param arg0 - * @param arg1 - * @deprecated - * @see javax.servlet.ServletContext#log(java.lang.Exception, - * java.lang.String) - */ - @Deprecated - public void log(Exception arg0, String arg1) { - context.log(arg0, arg1); - } - - /** - * @param arg0 - * @see javax.servlet.ServletContext#log(java.lang.String) - */ - public void log(String arg0) { - context.log(arg0); - } - - /** - * @param arg0 - * @param arg1 - * @see javax.servlet.ServletContext#log(java.lang.String,java.lang.Throwable) - */ - public void log(String arg0, Throwable arg1) { - context.log(arg0, arg1); - } - - /** - * @param arg0 - * @see javax.servlet.ServletContext#removeAttribute(java.lang.String) - */ - public void removeAttribute(String arg0) { - context.removeAttribute(arg0); - } - - /** - * @param arg0 - * @param arg1 - * @see javax.servlet.ServletContext#setAttribute(java.lang.String,java.lang.Object) - */ - public void setAttribute(String arg0, Object arg1) { - context.setAttribute(arg0, arg1); - } -}
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java deleted file mode 100644 index 9cf2d95..0000000 --- a/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java +++ /dev/null
@@ -1,75 +0,0 @@ -/* - * Copyright 2006 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.dev.shell.tomcat; - -import com.google.gwt.core.ext.TreeLogger; - -import org.apache.catalina.logger.LoggerBase; - -class CatalinaLoggerAdapter extends LoggerBase { - - private final TreeLogger logger; - - public CatalinaLoggerAdapter(TreeLogger logger) { - this.logger = logger; - } - - @Override - public void log(Exception exception, String msg) { - logger.log(TreeLogger.WARN, msg, exception); - } - - @Override - public void log(String msg) { - logger.log(TreeLogger.INFO, msg, null); - } - - @Override - public void log(String message, int verbosity) { - TreeLogger.Type type = mapVerbosityToLogType(verbosity); - logger.log(type, message, null); - } - - @Override - public void log(String msg, Throwable throwable) { - logger.log(TreeLogger.WARN, msg, throwable); - } - - @Override - public void log(String message, Throwable throwable, int verbosity) { - TreeLogger.Type type = mapVerbosityToLogType(verbosity); - logger.log(type, message, throwable); - } - - private TreeLogger.Type mapVerbosityToLogType(int verbosity) { - switch (verbosity) { - case LoggerBase.FATAL: - case LoggerBase.ERROR: - case LoggerBase.WARNING: - return TreeLogger.WARN; - - case LoggerBase.INFORMATION: - return TreeLogger.DEBUG; - case LoggerBase.DEBUG: - return TreeLogger.SPAM; - - default: - // really, this was an unexpected type - return TreeLogger.WARN; - } - } - -} \ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java deleted file mode 100644 index d071d2a..0000000 --- a/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java +++ /dev/null
@@ -1,119 +0,0 @@ -/* - * Copyright 2006 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.dev.shell.tomcat; - -import com.google.gwt.core.ext.TreeLogger; - -/** - * Maps Tomcat's commons logger onto the GWT shell's tree logger. - */ -public class CommonsLoggerAdapter implements org.apache.commons.logging.Log { - - private TreeLogger log; - - /** - * @param name unused - */ - public CommonsLoggerAdapter(String name) { - // NOTE: this is ugly, but I don't know of any other way to get a - // non-static log to which we can delegate. - // - log = EmbeddedTomcatServer.sTomcat.getLogger(); - } - - public void debug(Object message) { - doLog(TreeLogger.SPAM, message, null); - } - - public void debug(Object message, Throwable t) { - doLog(TreeLogger.SPAM, message, t); - } - - public void error(Object message) { - doLog(TreeLogger.WARN, message, null); - } - - public void error(Object message, Throwable t) { - doLog(TreeLogger.WARN, message, t); - } - - public void fatal(Object message) { - doLog(TreeLogger.WARN, message, null); - } - - public void fatal(Object message, Throwable t) { - doLog(TreeLogger.WARN, message, t); - } - - public void info(Object message) { - // Intentionally low-level to us. - doLog(TreeLogger.TRACE, message, null); - } - - public void info(Object message, Throwable t) { - // Intentionally low-level to us. - doLog(TreeLogger.TRACE, message, t); - } - - public boolean isDebugEnabled() { - return log.isLoggable(TreeLogger.SPAM); - } - - public boolean isErrorEnabled() { - return log.isLoggable(TreeLogger.WARN); - } - - public boolean isFatalEnabled() { - return log.isLoggable(TreeLogger.WARN); - } - - public boolean isInfoEnabled() { - // Intentionally low-level to us. - return log.isLoggable(TreeLogger.TRACE); - } - - public boolean isTraceEnabled() { - // Intentionally low-level to us. - return log.isLoggable(TreeLogger.SPAM); - } - - public boolean isWarnEnabled() { - return log.isLoggable(TreeLogger.WARN); - } - - public void trace(Object message) { - // Intentionally low-level to us. - doLog(TreeLogger.DEBUG, message, null); - } - - public void trace(Object message, Throwable t) { - // Intentionally low-level to us. - doLog(TreeLogger.DEBUG, message, t); - } - - public void warn(Object message) { - doLog(TreeLogger.WARN, message, null); - } - - public void warn(Object message, Throwable t) { - doLog(TreeLogger.WARN, message, t); - } - - private void doLog(TreeLogger.Type type, Object message, Throwable t) { - String msg = message.toString(); - log.log(type, msg, t); - } -} \ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java deleted file mode 100644 index e7d27ac..0000000 --- a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java +++ /dev/null
@@ -1,436 +0,0 @@ -/* - * Copyright 2006 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.dev.shell.tomcat; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.dev.resource.Resource; -import com.google.gwt.dev.resource.impl.ClassPathEntry; -import com.google.gwt.dev.resource.impl.PathPrefix; -import com.google.gwt.dev.resource.impl.PathPrefixSet; -import com.google.gwt.dev.resource.impl.ResourceOracleImpl; -import com.google.gwt.dev.shell.WorkDirs; -import com.google.gwt.dev.util.Util; - -import org.apache.catalina.Connector; -import org.apache.catalina.ContainerEvent; -import org.apache.catalina.ContainerListener; -import org.apache.catalina.Engine; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Logger; -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.core.StandardHost; -import org.apache.catalina.startup.Embedded; -import org.apache.catalina.startup.HostConfig; -import org.apache.coyote.tomcat5.CoyoteConnector; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Wraps an instance of the Tomcat web server used in hosted mode. - */ -public class EmbeddedTomcatServer { - - static EmbeddedTomcatServer sTomcat; - - public static int getPort() { - return sTomcat.port; - } - - public static String start(TreeLogger topLogger, int port, WorkDirs workDirs) { - return start(topLogger, port, workDirs, true); - } - - public static synchronized String start(TreeLogger topLogger, int port, - WorkDirs workDirs, boolean shouldAutoGenerateResources) { - if (sTomcat != null) { - throw new IllegalStateException("Embedded Tomcat is already running"); - } - - try { - new EmbeddedTomcatServer(topLogger, port, workDirs, - shouldAutoGenerateResources); - return null; - } catch (LifecycleException e) { - String msg = e.getMessage(); - if (msg != null && msg.indexOf("already in use") != -1) { - msg = "Port " - + port - + " is already is use; you probably still have another session active"; - } else { - msg = "Unable to start the embedded Tomcat server; double-check that your configuration is valid"; - } - return msg; - } - } - - // Stop the embedded Tomcat server. - // - public static synchronized void stop() { - if (sTomcat != null) { - try { - sTomcat.catEmbedded.stop(); - } catch (LifecycleException e) { - // There's nothing we can really do about this and the logger is - // gone in many scenarios, so we just ignore it. - // - } finally { - sTomcat = null; - } - } - } - - /** - * Returns what local port the Tomcat connector is running on. - * - * When starting Tomcat with port 0 (i.e. choose an open port), there is just - * no way to figure out what port it actually chose. So we're using pure - * hackery to steal the port via reflection. The only works because we bundle - * Tomcat with GWT and know exactly what version it is. - */ - private static int computeLocalPort(Connector connector) { - Throwable caught = null; - try { - Field phField = CoyoteConnector.class.getDeclaredField("protocolHandler"); - phField.setAccessible(true); - Object protocolHandler = phField.get(connector); - - Field epField = protocolHandler.getClass().getDeclaredField("ep"); - epField.setAccessible(true); - Object endPoint = epField.get(protocolHandler); - - Field ssField = endPoint.getClass().getDeclaredField("serverSocket"); - ssField.setAccessible(true); - ServerSocket serverSocket = (ServerSocket) ssField.get(endPoint); - - return serverSocket.getLocalPort(); - } catch (SecurityException e) { - caught = e; - } catch (NoSuchFieldException e) { - caught = e; - } catch (IllegalArgumentException e) { - caught = e; - } catch (IllegalAccessException e) { - caught = e; - } - throw new RuntimeException( - "Failed to retrieve the startup port from Embedded Tomcat", caught); - } - - private Embedded catEmbedded; - - private Engine catEngine; - - private StandardHost catHost = null; - - private int port; - - private final TreeLogger startupBranchLogger; - - private EmbeddedTomcatServer(final TreeLogger topLogger, int listeningPort, - final WorkDirs workDirs, final boolean shouldAutoGenerateResources) - throws LifecycleException { - if (topLogger == null) { - throw new NullPointerException("No logger specified"); - } - - final TreeLogger logger = topLogger.branch(TreeLogger.INFO, - "Starting HTTP on port " + listeningPort, null); - - startupBranchLogger = logger; - - // Make myself the one static instance. - // NOTE: there is only one small implementation reason that this has - // to be a singleton, which is that the commons logger LogFactory insists - // on creating your logger class which must have a constructor with - // exactly one String argument, and since we want LoggerAdapter to delegate - // to the logger instance available through instance host, there is no - // way I can think of to delegate without accessing a static field. - // An inner class is almost right, except there's no outer instance. - // - sTomcat = this; - - // Assume the working directory is simply the user's current directory. - // - File topWorkDir = new File(System.getProperty("user.dir")); - - // Tell Tomcat its base directory so that it won't complain. - // - String catBase = System.getProperty("catalina.base"); - if (catBase == null) { - // we (briefly) supported catalina.base.create, so let's not cut support - // until the deprecated sunset - catBase = System.getProperty("catalina.base.create"); - if (catBase != null) { - logger.log(TreeLogger.WARN, "catalina.base.create is deprecated. " + - "Use catalina.base, and it will be created if necessary."); - topWorkDir = new File(catBase); - } - catBase = generateDefaultCatalinaBase(logger, topWorkDir); - System.setProperty("catalina.base", catBase); - } - - // Some debug messages for ourselves. - // - if (logger.isLoggable(TreeLogger.DEBUG)) { - logger.log(TreeLogger.DEBUG, "catalina.base = " + catBase, null); - } - - // Set up the logger that will be returned by the Commons logging factory. - // - String adapterClassName = CommonsLoggerAdapter.class.getName(); - System.setProperty("org.apache.commons.logging.Log", adapterClassName); - - // And set up an adapter that will work with the Catalina logger family. - // - Logger catalinaLogger = new CatalinaLoggerAdapter(topLogger); - - // Create an embedded server. - // - catEmbedded = new Embedded(); - catEmbedded.setDebug(0); - catEmbedded.setLogger(catalinaLogger); - - // The embedded engine is called "gwt". - // - catEngine = catEmbedded.createEngine(); - catEngine.setName("gwt"); - catEngine.setDefaultHost("localhost"); - catEngine.setParentClassLoader(this.getClass().getClassLoader()); - - // It answers localhost requests. - // - // String appBase = fCatalinaBaseDir.getAbsolutePath(); - String appBase = catBase + "/webapps"; - catHost = (StandardHost) catEmbedded.createHost("localhost", appBase); - - // Hook up a host config to search for and pull in webapps. - // - HostConfig hostConfig = new HostConfig(); - catHost.addLifecycleListener(hostConfig); - - // Hook pre-install events so that we can add attributes to allow loaded - // instances to find their development instance host. - // - catHost.addContainerListener(new ContainerListener() { - public void containerEvent(ContainerEvent event) { - if (StandardHost.PRE_INSTALL_EVENT.equals(event.getType())) { - StandardContext webapp = (StandardContext) event.getData(); - publishShellLoggerAttribute(logger, topLogger, webapp); - publishShellWorkDirsAttribute(logger, workDirs, webapp); - publishShouldAutoGenerateResourcesAttribute(logger, - shouldAutoGenerateResources, webapp); - } - } - }); - - // Tell the engine about the host. - // - catEngine.addChild(catHost); - catEngine.setDefaultHost(catHost.getName()); - - // Tell the embedded manager about the engine. - // - catEmbedded.addEngine(catEngine); - InetAddress nullAddr = null; - Connector connector = catEmbedded.createConnector(nullAddr, listeningPort, - false); - catEmbedded.addConnector(connector); - - // start up! - catEmbedded.start(); - port = computeLocalPort(connector); - - if (port != listeningPort) { - if (logger.isLoggable(TreeLogger.INFO)) { - logger.log(TreeLogger.INFO, "HTTP listening on port " + port, null); - } - } - } - - public TreeLogger getLogger() { - return startupBranchLogger; - } - - /* - * Assumes that the leaf is a file (not a directory). - */ - private void copyFileNoOverwrite(TreeLogger logger, String srcResName, - Resource srcRes, File catBase) { - - File dest = new File(catBase, srcResName); - try { - // Only copy if src is newer than desc. - long srcLastModified = srcRes.getLastModified(); - long dstLastModified = dest.lastModified(); - - if (srcLastModified < dstLastModified) { - // Don't copy over it. - if (logger.isLoggable(TreeLogger.SPAM)) { - logger.log(TreeLogger.SPAM, "Source is older than existing: " - + dest.getAbsolutePath(), null); - } - return; - } else if (srcLastModified == dstLastModified) { - // Exact same time; quietly don't overwrite. - return; - } else if (dest.exists()) { - // Warn about the overwrite - logger.log(TreeLogger.WARN, "Overwriting existing file '" - + dest.getAbsolutePath() + "' with '" + srcRes.getLocation() - + "', which has a newer timestamp"); - } - - // Make dest directories as required. - File destParent = dest.getParentFile(); - if (destParent != null) { - // No need to check mkdirs result because IOException later anyway. - destParent.mkdirs(); - } - - Util.copy(srcRes.openContents(), new FileOutputStream(dest)); - dest.setLastModified(srcLastModified); - - if (logger.isLoggable(TreeLogger.TRACE)) { - logger.log(TreeLogger.TRACE, "Wrote: " + dest.getAbsolutePath(), null); - } - } catch (IOException e) { - logger.log(TreeLogger.WARN, "Failed to write: " + dest.getAbsolutePath(), - e); - } - } - - /** - * Extracts a valid catalina base instance from the classpath. Does not - * overwrite any existing files. - */ - private String generateDefaultCatalinaBase(TreeLogger logger, File workDir) { - logger = logger.branch( - TreeLogger.TRACE, - "Property 'catalina.base' not specified; checking for a standard catalina base image instead", - null); - - // Recursively copies out files and directories - String tomcatEtcDir = "com/google/gwt/dev/etc/tomcat/"; - Map<String, Resource> resourceMap = null; - Throwable caught = null; - try { - resourceMap = getResourcesFor(logger, tomcatEtcDir); - } catch (URISyntaxException e) { - caught = e; - } catch (IOException e) { - caught = e; - } - - File catBase = new File(workDir, "tomcat"); - if (resourceMap == null || resourceMap.isEmpty()) { - logger.log(TreeLogger.WARN, "Could not find " + tomcatEtcDir, caught); - } else { - for (Entry<String, Resource> entry : resourceMap.entrySet()) { - copyFileNoOverwrite(logger, entry.getKey(), entry.getValue(), catBase); - } - } - - return catBase.getAbsolutePath(); - } - - /** - * Hacky, but fast. - */ - private Map<String, Resource> getResourcesFor(TreeLogger logger, - String tomcatEtcDir) throws URISyntaxException, IOException { - ClassLoader contextClassLoader = this.getClass().getClassLoader(); - URL url = contextClassLoader.getResource(tomcatEtcDir); - if (url == null) { - return null; - } - String prefix = ""; - String urlString = url.toString(); - if (urlString.startsWith("jar:")) { - assert urlString.toLowerCase(Locale.ENGLISH).contains(".jar!/" - + tomcatEtcDir); - urlString = urlString.substring(4, urlString.indexOf('!')); - url = new URL(urlString); - prefix = tomcatEtcDir; - } else if (urlString.startsWith("zip:")) { - assert urlString.toLowerCase(Locale.ENGLISH).contains(".zip!/" - + tomcatEtcDir); - urlString = urlString.substring(4, urlString.indexOf('!')); - url = new URL(urlString); - prefix = tomcatEtcDir; - } - ClassPathEntry entry = ResourceOracleImpl.createEntryForUrl(logger, url); - assert (entry != null); - ResourceOracleImpl resourceOracle = new ResourceOracleImpl( - Collections.singletonList(entry)); - PathPrefixSet pathPrefixSet = new PathPrefixSet(); - PathPrefix pathPrefix = new PathPrefix(prefix, null, true); - pathPrefixSet.add(pathPrefix); - resourceOracle.setPathPrefixes(pathPrefixSet); - ResourceOracleImpl.refresh(logger, resourceOracle); - Map<String, Resource> resourceMap = resourceOracle.getResourceMap(); - return resourceMap; - } - - private void publishAttributeToWebApp(TreeLogger logger, - StandardContext webapp, String attrName, Object attrValue) { - if (logger.isLoggable(TreeLogger.TRACE)) { - logger.log(TreeLogger.TRACE, "Adding attribute '" + attrName - + "' to web app '" + webapp.getName() + "'", null); - } - webapp.getServletContext().setAttribute(attrName, attrValue); - } - - /** - * Publish the shell's tree logger as an attribute. This attribute is used to - * find the logger out of the thin air within the shell servlet. - */ - private void publishShellLoggerAttribute(TreeLogger logger, - TreeLogger loggerToPublish, StandardContext webapp) { - final String attr = "com.google.gwt.dev.shell.logger"; - publishAttributeToWebApp(logger, webapp, attr, loggerToPublish); - } - - /** - * Publish the shell's work dir as an attribute. This attribute is used to - * find it out of the thin air within the shell servlet. - */ - private void publishShellWorkDirsAttribute(TreeLogger logger, - WorkDirs workDirs, StandardContext webapp) { - final String attr = "com.google.gwt.dev.shell.workdirs"; - publishAttributeToWebApp(logger, webapp, attr, workDirs); - } - - /** - * Publish to the web app whether it should automatically generate resources. - */ - private void publishShouldAutoGenerateResourcesAttribute(TreeLogger logger, - boolean shouldAutoGenerateResources, StandardContext webapp) { - publishAttributeToWebApp(logger, webapp, - "com.google.gwt.dev.shell.shouldAutoGenerateResources", - shouldAutoGenerateResources); - } -}
diff --git a/dev/core/src/org/apache/COPYING b/dev/core/src/org/apache/COPYING deleted file mode 100644 index d9a10c0..0000000 --- a/dev/core/src/org/apache/COPYING +++ /dev/null
@@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS
diff --git a/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java b/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java deleted file mode 100644 index f941fad..0000000 --- a/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java +++ /dev/null
@@ -1,2169 +0,0 @@ -/* - * Copyright 1999,2004 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. - */ -// Modified by Google. - -package org.apache.catalina.loader; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilePermission; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.security.AccessControlException; -import java.security.AccessController; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Policy; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Vector; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.jar.Attributes.Name; - -import javax.naming.NameClassPair; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; - -import org.apache.catalina.Lifecycle; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.util.StringManager; -import org.apache.naming.JndiPermission; -import org.apache.naming.resources.Resource; -import org.apache.naming.resources.ResourceAttributes; -import org.apache.tomcat.util.compat.JdkCompat; - -/** - * Specialized web application class loader. - * <p> - * This class loader is a full reimplementation of the - * <code>URLClassLoader</code> from the JDK. It is desinged to be fully - * compatible with a normal <code>URLClassLoader</code>, although its internal - * behavior may be completely different. - * <p> - * <strong>IMPLEMENTATION NOTE</strong> - This class loader faithfully follows - * the delegation model recommended in the specification. The system class - * loader will be queried first, then the local repositories, and only then - * delegation to the parent class loader will occur. This allows the web - * application to override any shared class except the classes from J2SE. - * Special handling is provided from the JAXP XML parser interfaces, the JNDI - * interfaces, and the classes from the servlet API, which are never loaded - * from the webapp repository. - * <p> - * <strong>IMPLEMENTATION NOTE</strong> - Due to limitations in Jasper - * compilation technology, any repository which contains classes from - * the servlet API will be ignored by the class loader. - * <p> - * <strong>IMPLEMENTATION NOTE</strong> - The class loader generates source - * URLs which include the full JAR URL when a class is loaded from a JAR file, - * which allows setting security permission at the class level, even when a - * class is contained inside a JAR. - * <p> - * <strong>IMPLEMENTATION NOTE</strong> - Local repositories are searched in - * the order they are added via the initial constructor and/or any subsequent - * calls to <code>addRepository()</code> or <code>addJar()</code>. - * <p> - * <strong>IMPLEMENTATION NOTE</strong> - No check for sealing violations or - * security is made unless a security manager is present. - * - * @author Remy Maucherat - * @author Craig R. McClanahan - * @version $Revision: 1.34 $ $Date: 2004/05/26 15:47:40 $ - */ -public class WebappClassLoader - extends URLClassLoader - implements Reloader, Lifecycle - { - - private static org.apache.commons.logging.Log log= - org.apache.commons.logging.LogFactory.getLog( WebappClassLoader.class ); - - protected class PrivilegedFindResource - implements PrivilegedAction { - - private File file; - private String path; - - PrivilegedFindResource(File file, String path) { - this.file = file; - this.path = path; - } - - public Object run() { - return findResourceInternal(file, path); - } - - } - - - // ------------------------------------------------------- Static Variables - - - /** - * The set of trigger classes that will cause a proposed repository not - * to be added if this class is visible to the class loader that loaded - * this factory class. Typically, trigger classes will be listed for - * components that have been integrated into the JDK for later versions, - * but where the corresponding JAR files are required to run on - * earlier versions. - */ - private static final String[] triggers = { - "javax.servlet.Servlet" // Servlet API - }; - - /** - * Jdk Compatibility Support. - */ - private static JdkCompat jdkCompat = JdkCompat.getJdkCompat(); - - /** - * Set of package names which are not allowed to be loaded from a webapp - * class loader without delegating first. - */ - private static final String[] packageTriggers = { - "javax", // Java extensions - "org.xml.sax", // SAX 1 & 2 - "org.w3c.dom", // DOM 1 & 2 - "org.apache.xerces", // Xerces 1 & 2 - "org.apache.xalan" // Xalan - }; - - - /** - * The string manager for this package. - */ - protected static final StringManager sm = - StringManager.getManager(Constants.Package); - - - // ----------------------------------------------------------- Constructors - - - /** - * Construct a new ClassLoader with no defined repositories and no - * parent ClassLoader. - */ - public WebappClassLoader() { - - super(new URL[0]); - this.parent = getParent(); - system = getSystemClassLoader(); - securityManager = System.getSecurityManager(); - - if (securityManager != null) { - refreshPolicy(); - } - - } - - - /** - * Construct a new ClassLoader with no defined repositories and no - * parent ClassLoader. - */ - public WebappClassLoader(ClassLoader parent) { - - super(new URL[0], parent); - - this.parent = getParent(); - - system = getSystemClassLoader(); - securityManager = System.getSecurityManager(); - - if (securityManager != null) { - refreshPolicy(); - } - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * Associated directory context giving access to the resources in this - * webapp. - */ - protected DirContext resources = null; - - - /** - * The cache of ResourceEntry for classes and resources we have loaded, - * keyed by resource name. - */ - protected HashMap resourceEntries = new HashMap(); - - - /** - * The list of not found resources. - */ - protected HashMap notFoundResources = new HashMap(); - - - /** - * The debugging detail level of this component. - */ - protected int debug = 0; - - - /** - * Should this class loader delegate to the parent class loader - * <strong>before</strong> searching its own repositories (i.e. the - * usual Java2 delegation model)? If set to <code>false</code>, - * this class loader will search its own repositories first, and - * delegate to the parent only if the class or resource is not - * found locally. - */ - protected boolean delegate = false; - - - /** - * Last time a JAR was accessed. - */ - protected long lastJarAccessed = 0L; - - - /** - * The list of local repositories, in the order they should be searched - * for locally loaded classes or resources. - */ - protected String[] repositories = new String[0]; - - - /** - * Repositories URLs, used to cache the result of getURLs. - */ - protected URL[] repositoryURLs = null; - - - /** - * Repositories translated as path in the work directory (for Jasper - * originally), but which is used to generate fake URLs should getURLs be - * called. - */ - protected File[] files = new File[0]; - - - /** - * The list of JARs, in the order they should be searched - * for locally loaded classes or resources. - */ - protected JarFile[] jarFiles = new JarFile[0]; - - - /** - * The list of JARs, in the order they should be searched - * for locally loaded classes or resources. - */ - protected File[] jarRealFiles = new File[0]; - - - /** - * The path which will be monitored for added Jar files. - */ - protected String jarPath = null; - - - /** - * The list of JARs, in the order they should be searched - * for locally loaded classes or resources. - */ - protected String[] jarNames = new String[0]; - - - /** - * The list of JARs last modified dates, in the order they should be - * searched for locally loaded classes or resources. - */ - protected long[] lastModifiedDates = new long[0]; - - - /** - * The list of resources which should be checked when checking for - * modifications. - */ - protected String[] paths = new String[0]; - - - /** - * A list of read File and Jndi Permission's required if this loader - * is for a web application context. - */ - private ArrayList permissionList = new ArrayList(); - - - /** - * Path where resources loaded from JARs will be extracted. - */ - private File loaderDir = null; - - - /** - * The PermissionCollection for each CodeSource for a web - * application context. - */ - private HashMap loaderPC = new HashMap(); - - - /** - * Instance of the SecurityManager installed. - */ - private SecurityManager securityManager = null; - - - /** - * The parent class loader. - */ - private ClassLoader parent = null; - - - /** - * The system class loader. - */ - private ClassLoader system = null; - - - /** - * Has this component been started? - */ - protected boolean started = false; - - - /** - * Has external repositories. - */ - protected boolean hasExternalRepositories = false; - - - /** - * All permission. - */ - private Permission allPermission = new java.security.AllPermission(); - - - // ------------------------------------------------------------- Properties - - - /** - * Get associated resources. - */ - public DirContext getResources() { - - return this.resources; - - } - - - /** - * Set associated resources. - */ - public void setResources(DirContext resources) { - - this.resources = resources; - - } - - - /** - * Return the debugging detail level for this component. - */ - public int getDebug() { - - return (this.debug); - - } - - - /** - * Set the debugging detail level for this component. - * - * @param debug The new debugging detail level - */ - public void setDebug(int debug) { - - this.debug = debug; - - } - - - /** - * Return the "delegate first" flag for this class loader. - */ - public boolean getDelegate() { - - return (this.delegate); - - } - - - /** - * Set the "delegate first" flag for this class loader. - * - * @param delegate The new "delegate first" flag - */ - public void setDelegate(boolean delegate) { - - this.delegate = delegate; - - } - - - /** - * If there is a Java SecurityManager create a read FilePermission - * or JndiPermission for the file directory path. - * - * @param path file directory path - */ - public void addPermission(String path) { - if (path == null) { - return; - } - - if (securityManager != null) { - Permission permission = null; - if( path.startsWith("jndi:") || path.startsWith("jar:jndi:") ) { - if (!path.endsWith("/")) { - path = path + "/"; - } - permission = new JndiPermission(path + "*"); - addPermission(permission); - } else { - if (!path.endsWith(File.separator)) { - permission = new FilePermission(path, "read"); - addPermission(permission); - path = path + File.separator; - } - permission = new FilePermission(path + "-", "read"); - addPermission(permission); - } - } - } - - - /** - * If there is a Java SecurityManager create a read FilePermission - * or JndiPermission for URL. - * - * @param url URL for a file or directory on local system - */ - public void addPermission(URL url) { - if (url != null) { - addPermission(url.toString()); - } - } - - - /** - * If there is a Java SecurityManager create a Permission. - * - * @param url URL for a file or directory on local system - */ - public void addPermission(Permission permission) { - if ((securityManager != null) && (permission != null)) { - permissionList.add(permission); - } - } - - - /** - * Return the JAR path. - */ - public String getJarPath() { - - return this.jarPath; - - } - - - /** - * Change the Jar path. - */ - public void setJarPath(String jarPath) { - - this.jarPath = jarPath; - - } - - - /** - * Change the work directory. - */ - public void setWorkDir(File workDir) { - this.loaderDir = new File(workDir, "loader"); - } - - - // ------------------------------------------------------- Reloader Methods - - - /** - * Add a new repository to the set of places this ClassLoader can look for - * classes to be loaded. - * - * @param repository Name of a source of classes to be loaded, such as a - * directory pathname, a JAR file pathname, or a ZIP file pathname - * - * @exception IllegalArgumentException if the specified repository is - * invalid or does not exist - */ - public void addRepository(String repository) { - - // Ignore any of the standard repositories, as they are set up using - // either addJar or addRepository - if (repository.startsWith("/WEB-INF/lib") - || repository.startsWith("/WEB-INF/classes")) - return; - - // Add this repository to our underlying class loader - try { - URL url = new URL(repository); - super.addURL(url); - hasExternalRepositories = true; - repositoryURLs = null; - } catch (MalformedURLException e) { - IllegalArgumentException iae = new IllegalArgumentException - ("Invalid repository: " + repository); - jdkCompat.chainException(iae, e); - throw iae; - } - - } - - - /** - * Add a new repository to the set of places this ClassLoader can look for - * classes to be loaded. - * - * @param repository Name of a source of classes to be loaded, such as a - * directory pathname, a JAR file pathname, or a ZIP file pathname - * - * @exception IllegalArgumentException if the specified repository is - * invalid or does not exist - */ - synchronized void addRepository(String repository, File file) { - - // Note : There should be only one (of course), but I think we should - // keep this a bit generic - - if (repository == null) - return; - - if (log.isDebugEnabled()) - log.debug("addRepository(" + repository + ")"); - - int i; - - // Add this repository to our internal list - String[] result = new String[repositories.length + 1]; - for (i = 0; i < repositories.length; i++) { - result[i] = repositories[i]; - } - result[repositories.length] = repository; - repositories = result; - - // Add the file to the list - File[] result2 = new File[files.length + 1]; - for (i = 0; i < files.length; i++) { - result2[i] = files[i]; - } - result2[files.length] = file; - files = result2; - - } - - - synchronized void addJar(String jar, JarFile jarFile, File file) - throws IOException { - - if (jar == null) - return; - if (jarFile == null) - return; - if (file == null) - return; - - if (log.isDebugEnabled()) - log.debug("addJar(" + jar + ")"); - - int i; - - if ((jarPath != null) && (jar.startsWith(jarPath))) { - - String jarName = jar.substring(jarPath.length()); - while (jarName.startsWith("/")) - jarName = jarName.substring(1); - - String[] result = new String[jarNames.length + 1]; - for (i = 0; i < jarNames.length; i++) { - result[i] = jarNames[i]; - } - result[jarNames.length] = jarName; - jarNames = result; - - } - - try { - - // Register the JAR for tracking - - long lastModified = - ((ResourceAttributes) resources.getAttributes(jar)) - .getLastModified(); - - String[] result = new String[paths.length + 1]; - for (i = 0; i < paths.length; i++) { - result[i] = paths[i]; - } - result[paths.length] = jar; - paths = result; - - long[] result3 = new long[lastModifiedDates.length + 1]; - for (i = 0; i < lastModifiedDates.length; i++) { - result3[i] = lastModifiedDates[i]; - } - result3[lastModifiedDates.length] = lastModified; - lastModifiedDates = result3; - - } catch (NamingException e) { - // Ignore - } - - // If the JAR currently contains invalid classes, don't actually use it - // for classloading - if (!validateJarFile(file)) - return; - - JarFile[] result2 = new JarFile[jarFiles.length + 1]; - for (i = 0; i < jarFiles.length; i++) { - result2[i] = jarFiles[i]; - } - result2[jarFiles.length] = jarFile; - jarFiles = result2; - - // Add the file to the list - File[] result4 = new File[jarRealFiles.length + 1]; - for (i = 0; i < jarRealFiles.length; i++) { - result4[i] = jarRealFiles[i]; - } - result4[jarRealFiles.length] = file; - jarRealFiles = result4; - } - - - /** - * Return a String array of the current repositories for this class - * loader. If there are no repositories, a zero-length array is - * returned.For security reason, returns a clone of the Array (since - * String are immutable). - */ - public String[] findRepositories() { - - return ((String[])repositories.clone()); - - } - - - /** - * Have one or more classes or resources been modified so that a reload - * is appropriate? - */ - public boolean modified() { - - if (log.isDebugEnabled()) - log.debug("modified()"); - - // Checking for modified loaded resources - int length = paths.length; - - // A rare race condition can occur in the updates of the two arrays - // It's totally ok if the latest class added is not checked (it will - // be checked the next time - int length2 = lastModifiedDates.length; - if (length > length2) - length = length2; - - for (int i = 0; i < length; i++) { - try { - long lastModified = - ((ResourceAttributes) resources.getAttributes(paths[i])) - .getLastModified(); - if (lastModified != lastModifiedDates[i]) { - if( log.isDebugEnabled() ) - log.debug(" Resource '" + paths[i] - + "' was modified; Date is now: " - + new java.util.Date(lastModified) + " Was: " - + new java.util.Date(lastModifiedDates[i])); - return (true); - } - } catch (NamingException e) { - log.error(" Resource '" + paths[i] + "' is missing"); - return (true); - } - } - - length = jarNames.length; - - // Check if JARs have been added or removed - if (getJarPath() != null) { - - try { - NamingEnumeration enum_ = resources.listBindings(getJarPath()); - int i = 0; - while (enum_.hasMoreElements() && (i < length)) { - NameClassPair ncPair = (NameClassPair) enum_.nextElement(); - String name = ncPair.getName(); - // Ignore non JARs present in the lib folder - if (!name.endsWith(".jar")) - continue; - if (!name.equals(jarNames[i])) { - // Missing JAR - log.info(" Additional JARs have been added : '" - + name + "'"); - return (true); - } - i++; - } - if (enum_.hasMoreElements()) { - while (enum_.hasMoreElements()) { - NameClassPair ncPair = - (NameClassPair) enum_.nextElement(); - String name = ncPair.getName(); - // Additional non-JAR files are allowed - if (name.endsWith(".jar")) { - // There was more JARs - log.info(" Additional JARs have been added"); - return (true); - } - } - } else if (i < jarNames.length) { - // There was less JARs - log.info(" Additional JARs have been added"); - return (true); - } - } catch (NamingException e) { - if (log.isDebugEnabled()) - log.debug(" Failed tracking modifications of '" - + getJarPath() + "'"); - } catch (ClassCastException e) { - log.error(" Failed tracking modifications of '" - + getJarPath() + "' : " + e.getMessage()); - } - - } - - // No classes have been modified - return (false); - - } - - - /** - * Render a String representation of this object. - */ - public String toString() { - - StringBuffer sb = new StringBuffer("WebappClassLoader\r\n"); - sb.append(" delegate: "); - sb.append(delegate); - sb.append("\r\n"); - sb.append(" repositories:\r\n"); - if (repositories != null) { - for (int i = 0; i < repositories.length; i++) { - sb.append(" "); - sb.append(repositories[i]); - sb.append("\r\n"); - } - } - if (this.parent != null) { - sb.append("----------> Parent Classloader:\r\n"); - sb.append(this.parent.toString()); - sb.append("\r\n"); - } - return (sb.toString()); - - } - - - // ---------------------------------------------------- ClassLoader Methods - - - /** - * Add the specified URL to the classloader. - */ - protected void addURL(URL url) { - super.addURL(url); - hasExternalRepositories = true; - repositoryURLs = null; - } - - - /** - * Find the specified class in our local repositories, if possible. If - * not found, throw <code>ClassNotFoundException</code>. - * - * @param name Name of the class to be loaded - * - * @exception ClassNotFoundException if the class was not found - */ - public Class findClass(String name) throws ClassNotFoundException { - - if (log.isDebugEnabled()) - log.debug(" findClass(" + name + ")"); - - // (1) Permission to define this class when using a SecurityManager - if (securityManager != null) { - int i = name.lastIndexOf('.'); - if (i >= 0) { - try { - if (log.isTraceEnabled()) - log.trace(" securityManager.checkPackageDefinition"); - securityManager.checkPackageDefinition(name.substring(0,i)); - } catch (Exception se) { - if (log.isTraceEnabled()) - log.trace(" -->Exception-->ClassNotFoundException", se); - throw new ClassNotFoundException(name, se); - } - } - } - - // Ask our superclass to locate this class, if possible - // (throws ClassNotFoundException if it is not found) - Class clazz = null; - try { - if (log.isTraceEnabled()) - log.trace(" findClassInternal(" + name + ")"); - try { - clazz = findClassInternal(name); - } catch(ClassNotFoundException cnfe) { - if (!hasExternalRepositories) { - throw cnfe; - } - } catch(AccessControlException ace) { - throw new ClassNotFoundException(name, ace); - } catch (RuntimeException e) { - if (log.isTraceEnabled()) - log.trace(" -->RuntimeException Rethrown", e); - throw e; - } - if ((clazz == null) && hasExternalRepositories) { - try { - clazz = super.findClass(name); - } catch(AccessControlException ace) { - throw new ClassNotFoundException(name, ace); - } catch (RuntimeException e) { - if (log.isTraceEnabled()) - log.trace(" -->RuntimeException Rethrown", e); - throw e; - } - } - if (clazz == null) { - if (log.isDebugEnabled()) - log.debug(" --> Returning ClassNotFoundException"); - throw new ClassNotFoundException(name); - } - } catch (ClassNotFoundException e) { - if (log.isTraceEnabled()) - log.trace(" --> Passing on ClassNotFoundException"); - throw e; - } - - // Return the class we have located - if (log.isTraceEnabled()) - log.debug(" Returning class " + clazz); - if ((log.isTraceEnabled()) && (clazz != null)) - log.debug(" Loaded by " + clazz.getClassLoader()); - return (clazz); - - } - - - /** - * Find the specified resource in our local repository, and return a - * <code>URL</code> refering to it, or <code>null</code> if this resource - * cannot be found. - * - * @param name Name of the resource to be found - */ - public URL findResource(final String name) { - - if (log.isDebugEnabled()) - log.debug(" findResource(" + name + ")"); - - URL url = null; - - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - if (entry == null) { - entry = findResourceInternal(name, name); - } - if (entry != null) { - url = entry.source; - } - - if ((url == null) && hasExternalRepositories) - url = super.findResource(name); - - if (log.isDebugEnabled()) { - if (url != null) - log.debug(" --> Returning '" + url.toString() + "'"); - else - log.debug(" --> Resource not found, returning null"); - } - return (url); - - } - - - /** - * Return an enumeration of <code>URLs</code> representing all of the - * resources with the given name. If no resources with this name are - * found, return an empty enumeration. - * - * @param name Name of the resources to be found - * - * @exception IOException if an input/output error occurs - */ - public Enumeration findResources(String name) throws IOException { - - if (log.isDebugEnabled()) - log.debug(" findResources(" + name + ")"); - - Vector result = new Vector(); - - int jarFilesLength = jarFiles.length; - int repositoriesLength = repositories.length; - - int i; - - // Looking at the repositories - for (i = 0; i < repositoriesLength; i++) { - try { - String fullPath = repositories[i] + name; - resources.lookup(fullPath); - // Note : Not getting an exception here means the resource was - // found - try { - result.addElement(getURI(new File(files[i], name))); - } catch (MalformedURLException e) { - // Ignore - } - } catch (NamingException e) { - } - } - - // Looking at the JAR files - synchronized (jarFiles) { - openJARs(); - for (i = 0; i < jarFilesLength; i++) { - JarEntry jarEntry = jarFiles[i].getJarEntry(name); - if (jarEntry != null) { - try { - String jarFakeUrl = getURI(jarRealFiles[i]).toString(); - jarFakeUrl = "jar:" + jarFakeUrl + "!/" + name; - result.addElement(new URL(jarFakeUrl)); - } catch (MalformedURLException e) { - // Ignore - } - } - } - } - - // Adding the results of a call to the superclass - if (hasExternalRepositories) { - - Enumeration otherResourcePaths = super.findResources(name); - - while (otherResourcePaths.hasMoreElements()) { - result.addElement(otherResourcePaths.nextElement()); - } - - } - - return result.elements(); - - } - - - /** - * Find the resource with the given name. A resource is some data - * (images, audio, text, etc.) that can be accessed by class code in a - * way that is independent of the location of the code. The name of a - * resource is a "/"-separated path name that identifies the resource. - * If the resource cannot be found, return <code>null</code>. - * <p> - * This method searches according to the following algorithm, returning - * as soon as it finds the appropriate URL. If the resource cannot be - * found, returns <code>null</code>. - * <ul> - * <li>If the <code>delegate</code> property is set to <code>true</code>, - * call the <code>getResource()</code> method of the parent class - * loader, if any.</li> - * <li>Call <code>findResource()</code> to find this resource in our - * locally defined repositories.</li> - * <li>Call the <code>getResource()</code> method of the parent class - * loader, if any.</li> - * </ul> - * - * @param name Name of the resource to return a URL for - */ - public URL getResource(String name) { - - if (log.isDebugEnabled()) - log.debug("getResource(" + name + ")"); - URL url = null; - - // (1) Delegate to parent if requested - if (delegate) { - if (log.isDebugEnabled()) - log.debug(" Delegating to parent classloader " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - url = loader.getResource(name); - if (url != null) { - if (log.isDebugEnabled()) - log.debug(" --> Returning '" + url.toString() + "'"); - return (url); - } - } - - // (2) Search local repositories - url = findResource(name); - if (url != null) { - // Locating the repository for special handling in the case - // of a JAR - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - try { - String repository = entry.codeBase.toString(); - if ((repository.endsWith(".jar")) - && (!(name.endsWith(".class")))) { - // Copy binary content to the work directory if not present - File resourceFile = new File(loaderDir, name); - url = resourceFile.toURL(); - } - } catch (Exception e) { - // Ignore - } - if (log.isDebugEnabled()) - log.debug(" --> Returning '" + url.toString() + "'"); - return (url); - } - - // (3) Delegate to parent unconditionally if not already attempted - if( !delegate ) { - ClassLoader loader = parent; - if (loader == null) - loader = system; - url = loader.getResource(name); - if (url != null) { - if (log.isDebugEnabled()) - log.debug(" --> Returning '" + url.toString() + "'"); - return (url); - } - } - - // (4) Resource was not found - if (log.isDebugEnabled()) - log.debug(" --> Resource not found, returning null"); - return (null); - - } - - - /** - * Find the resource with the given name, and return an input stream - * that can be used for reading it. The search order is as described - * for <code>getResource()</code>, after checking to see if the resource - * data has been previously cached. If the resource cannot be found, - * return <code>null</code>. - * - * @param name Name of the resource to return an input stream for - */ - public InputStream getResourceAsStream(String name) { - - if (log.isDebugEnabled()) - log.debug("getResourceAsStream(" + name + ")"); - InputStream stream = null; - - // (0) Check for a cached copy of this resource - stream = findLoadedResource(name); - if (stream != null) { - if (log.isDebugEnabled()) - log.debug(" --> Returning stream from cache"); - return (stream); - } - - // (1) Delegate to parent if requested - if (delegate) { - if (log.isDebugEnabled()) - log.debug(" Delegating to parent classloader " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - stream = loader.getResourceAsStream(name); - if (stream != null) { - // FIXME - cache??? - if (log.isDebugEnabled()) - log.debug(" --> Returning stream from parent"); - return (stream); - } - } - - // (2) Search local repositories - if (log.isDebugEnabled()) - log.debug(" Searching local repositories"); - URL url = findResource(name); - if (url != null) { - // FIXME - cache??? - if (log.isDebugEnabled()) - log.debug(" --> Returning stream from local"); - stream = findLoadedResource(name); - try { - if (hasExternalRepositories && (stream == null)) - stream = url.openStream(); - } catch (IOException e) { - ; // Ignore - } - if (stream != null) - return (stream); - } - - // (3) Delegate to parent unconditionally - if (!delegate) { - if (log.isDebugEnabled()) - log.debug(" Delegating to parent classloader unconditionally " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - stream = loader.getResourceAsStream(name); - if (stream != null) { - // FIXME - cache??? - if (log.isDebugEnabled()) - log.debug(" --> Returning stream from parent"); - return (stream); - } - } - - // (4) Resource was not found - if (log.isDebugEnabled()) - log.debug(" --> Resource not found, returning null"); - return (null); - - } - - - /** - * Load the class with the specified name. This method searches for - * classes in the same manner as <code>loadClass(String, boolean)</code> - * with <code>false</code> as the second argument. - * - * @param name Name of the class to be loaded - * - * @exception ClassNotFoundException if the class was not found - */ - public Class loadClass(String name) throws ClassNotFoundException { - - return (loadClass(name, false)); - - } - - - /** - * Load the class with the specified name, searching using the following - * algorithm until it finds and returns the class. If the class cannot - * be found, returns <code>ClassNotFoundException</code>. - * <ul> - * <li>Call <code>findLoadedClass(String)</code> to check if the - * class has already been loaded. If it has, the same - * <code>Class</code> object is returned.</li> - * <li>If the <code>delegate</code> property is set to <code>true</code>, - * call the <code>loadClass()</code> method of the parent class - * loader, if any.</li> - * <li>Call <code>findClass()</code> to find this class in our locally - * defined repositories.</li> - * <li>Call the <code>loadClass()</code> method of our parent - * class loader, if any.</li> - * </ul> - * If the class was found using the above steps, and the - * <code>resolve</code> flag is <code>true</code>, this method will then - * call <code>resolveClass(Class)</code> on the resulting Class object. - * - * @param name Name of the class to be loaded - * @param resolve If <code>true</code> then resolve the class - * - * @exception ClassNotFoundException if the class was not found - */ - public Class loadClass(String name, boolean resolve) - throws ClassNotFoundException { - - if (log.isDebugEnabled()) - log.debug("loadClass(" + name + ", " + resolve + ")"); - Class clazz = null; - - // Don't load classes if class loader is stopped - if (!started) { - log.info(sm.getString("webappClassLoader.stopped")); - throw new ThreadDeath(); - } - - // (0) Check our previously loaded local class cache - clazz = findLoadedClass0(name); - if (clazz != null) { - if (log.isDebugEnabled()) - log.debug(" Returning class from cache"); - if (resolve) - resolveClass(clazz); - return (clazz); - } - - // (0.1) Check our previously loaded class cache - clazz = findLoadedClass(name); - if (clazz != null) { - if (log.isDebugEnabled()) - log.debug(" Returning class from cache"); - if (resolve) - resolveClass(clazz); - return (clazz); - } - - // (0.2) Try loading the class with the system class loader, to prevent - // the webapp from overriding J2SE classes - // GOOGLE: use the bootstrap loader, not the system loader; it breaks - // embedding. - try { - // clazz = system.loadClass(name); - clazz = Class.forName(name, false, null); - if (clazz != null) { - if (resolve) - resolveClass(clazz); - return (clazz); - } - } catch (ClassNotFoundException e) { - // Ignore - } - - // (0.5) Permission to access this class when using a SecurityManager - if (securityManager != null) { - int i = name.lastIndexOf('.'); - if (i >= 0) { - try { - securityManager.checkPackageAccess(name.substring(0,i)); - } catch (SecurityException se) { - String error = "Security Violation, attempt to use " + - "Restricted Class: " + name; - log.info(error, se); - throw new ClassNotFoundException(error, se); - } - } - } - - boolean delegateLoad = delegate || filter(name); - - // (1) Delegate to our parent if requested - if (delegateLoad) { - if (log.isDebugEnabled()) - log.debug(" Delegating to parent classloader1 " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - try { - clazz = loader.loadClass(name); - if (clazz != null) { - if (log.isDebugEnabled()) - log.debug(" Loading class from parent"); - if (resolve) - resolveClass(clazz); - return (clazz); - } - } catch (ClassNotFoundException e) { - ; - } - } - - // (2) Search local repositories - if (log.isDebugEnabled()) - log.debug(" Searching local repositories"); - try { - clazz = findClass(name); - if (clazz != null) { - if (log.isDebugEnabled()) - log.debug(" Loading class from local repository"); - if (resolve) - resolveClass(clazz); - return (clazz); - } - } catch (ClassNotFoundException e) { - ; - } - - // (3) Delegate to parent unconditionally - if (!delegateLoad) { - if (log.isDebugEnabled()) - log.debug(" Delegating to parent classloader at end: " + parent); - ClassLoader loader = parent; - if (loader == null) - loader = system; - try { - clazz = loader.loadClass(name); - if (clazz != null) { - if (log.isDebugEnabled()) - log.debug(" Loading class from parent"); - if (resolve) - resolveClass(clazz); - return (clazz); - } - } catch (ClassNotFoundException e) { - ; - } - } - - throw new ClassNotFoundException(name); - } - - - /** - * Get the Permissions for a CodeSource. If this instance - * of WebappClassLoader is for a web application context, - * add read FilePermission or JndiPermissions for the base - * directory (if unpacked), - * the context URL, and jar file resources. - * - * @param codeSource where the code was loaded from - * @return PermissionCollection for CodeSource - */ - protected PermissionCollection getPermissions(CodeSource codeSource) { - - String codeUrl = codeSource.getLocation().toString(); - PermissionCollection pc; - if ((pc = (PermissionCollection)loaderPC.get(codeUrl)) == null) { - pc = super.getPermissions(codeSource); - if (pc != null) { - Iterator perms = permissionList.iterator(); - while (perms.hasNext()) { - Permission p = (Permission)perms.next(); - pc.add(p); - } - loaderPC.put(codeUrl,pc); - } - } - return (pc); - - } - - - /** - * Returns the search path of URLs for loading classes and resources. - * This includes the original list of URLs specified to the constructor, - * along with any URLs subsequently appended by the addURL() method. - * @return the search path of URLs for loading classes and resources. - */ - public URL[] getURLs() { - - if (repositoryURLs != null) { - return repositoryURLs; - } - - URL[] external = super.getURLs(); - - int filesLength = files.length; - int jarFilesLength = jarRealFiles.length; - int length = filesLength + jarFilesLength + external.length; - int i; - - try { - - URL[] urls = new URL[length]; - for (i = 0; i < length; i++) { - if (i < filesLength) { - urls[i] = getURL(files[i]); - } else if (i < filesLength + jarFilesLength) { - urls[i] = getURL(jarRealFiles[i - filesLength]); - } else { - urls[i] = external[i - filesLength - jarFilesLength]; - } - } - - repositoryURLs = urls; - - } catch (MalformedURLException e) { - repositoryURLs = new URL[0]; - } - - return repositoryURLs; - - } - - - // ------------------------------------------------------ Lifecycle Methods - - - /** - * Add a lifecycle event listener to this component. - * - * @param listener The listener to add - */ - public void addLifecycleListener(LifecycleListener listener) { - } - - - /** - * Get the lifecycle listeners associated with this lifecycle. If this - * Lifecycle has no listeners registered, a zero-length array is returned. - */ - public LifecycleListener[] findLifecycleListeners() { - return new LifecycleListener[0]; - } - - - /** - * Remove a lifecycle event listener from this component. - * - * @param listener The listener to remove - */ - public void removeLifecycleListener(LifecycleListener listener) { - } - - - /** - * Start the class loader. - * - * @exception LifecycleException if a lifecycle error occurs - */ - public void start() throws LifecycleException { - - started = true; - - } - - - /** - * Stop the class loader. - * - * @exception LifecycleException if a lifecycle error occurs - */ - public void stop() throws LifecycleException { - - started = false; - - int length = files.length; - for (int i = 0; i < length; i++) { - files[i] = null; - } - - length = jarFiles.length; - for (int i = 0; i < length; i++) { - try { - if (jarFiles[i] != null) { - jarFiles[i].close(); - } - } catch (IOException e) { - // Ignore - } - jarFiles[i] = null; - } - - notFoundResources.clear(); - resourceEntries.clear(); - resources = null; - repositories = null; - repositoryURLs = null; - files = null; - jarFiles = null; - jarRealFiles = null; - jarPath = null; - jarNames = null; - lastModifiedDates = null; - paths = null; - hasExternalRepositories = false; - parent = null; - - permissionList.clear(); - loaderPC.clear(); - - if (loaderDir != null) { - deleteDir(loaderDir); - } - - org.apache.commons.logging.LogFactory.release(this); - - } - - - /** - * Used to periodically signal to the classloader to release - * JAR resources. - */ - public void closeJARs(boolean force) { - if (jarFiles.length > 0) { - try { - synchronized (jarFiles) { - if (force || (System.currentTimeMillis() - > (lastJarAccessed + 90000))) { - for (int i = 0; i < jarFiles.length; i++) { - if (jarFiles[i] != null) { - jarFiles[i].close(); - jarFiles[i] = null; - } - } - } - } - } catch (IOException e) { - log("Failed to close JAR", e); - } - } - } - - - // ------------------------------------------------------ Protected Methods - - - /** - * Used to periodically signal to the classloader to release JAR resources. - */ - protected void openJARs() { - if (started && (jarFiles.length > 0)) { - lastJarAccessed = System.currentTimeMillis(); - if (jarFiles[0] == null) { - try { - for (int i = 0; i < jarFiles.length; i++) { - jarFiles[i] = new JarFile(jarRealFiles[i]); - } - } catch (IOException e) { - log("Failed to open JAR", e); - } - } - } - } - - - /** - * Find specified class in local repositories. - * - * @return the loaded class, or null if the class isn't found - */ - protected Class findClassInternal(String name) - throws ClassNotFoundException { - - if (!validate(name)) - throw new ClassNotFoundException(name); - - String tempPath = name.replace('.', '/'); - String classPath = tempPath + ".class"; - - ResourceEntry entry = null; - - entry = findResourceInternal(name, classPath); - - if ((entry == null) || (entry.binaryContent == null)) - throw new ClassNotFoundException(name); - - Class clazz = entry.loadedClass; - if (clazz != null) - return clazz; - - // Looking up the package - String packageName = null; - int pos = name.lastIndexOf('.'); - if (pos != -1) - packageName = name.substring(0, pos); - - Package pkg = null; - - if (packageName != null) { - - pkg = getPackage(packageName); - - // Define the package (if null) - if (pkg == null) { - if (entry.manifest == null) { - definePackage(packageName, null, null, null, null, null, - null, null); - } else { - definePackage(packageName, entry.manifest, entry.codeBase); - } - } - - } - - // Create the code source object - CodeSource codeSource = - new CodeSource(entry.codeBase, entry.certificates); - - if (securityManager != null) { - - // Checking sealing - if (pkg != null) { - boolean sealCheck = true; - if (pkg.isSealed()) { - sealCheck = pkg.isSealed(entry.codeBase); - } else { - sealCheck = (entry.manifest == null) - || !isPackageSealed(packageName, entry.manifest); - } - if (!sealCheck) - throw new SecurityException - ("Sealing violation loading " + name + " : Package " - + packageName + " is sealed."); - } - - } - - if (entry.loadedClass == null) { - synchronized (this) { - if (entry.loadedClass == null) { - clazz = defineClass(name, entry.binaryContent, 0, - entry.binaryContent.length, - codeSource); - entry.loadedClass = clazz; - entry.binaryContent = null; - entry.source = null; - entry.codeBase = null; - entry.manifest = null; - entry.certificates = null; - } else { - clazz = entry.loadedClass; - } - } - } else { - clazz = entry.loadedClass; - } - - return clazz; - - } - - /** - * Find specified resource in local repositories. This block - * will execute under an AccessControl.doPrivilege block. - * - * @return the loaded resource, or null if the resource isn't found - */ - private ResourceEntry findResourceInternal(File file, String path){ - ResourceEntry entry = new ResourceEntry(); - try { - entry.source = getURI(new File(file, path)); - entry.codeBase = getURL(new File(file, path)); - } catch (MalformedURLException e) { - return null; - } - return entry; - } - - - /** - * Find specified resource in local repositories. - * - * @return the loaded resource, or null if the resource isn't found - */ - protected ResourceEntry findResourceInternal(String name, String path) { - - if (!started) { - log.info(sm.getString("webappClassLoader.stopped")); - return null; - } - - if ((name == null) || (path == null)) - return null; - - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - if (entry != null) - return entry; - - int contentLength = -1; - InputStream binaryStream = null; - - int jarFilesLength = jarFiles.length; - int repositoriesLength = repositories.length; - - int i; - - Resource resource = null; - - for (i = 0; (entry == null) && (i < repositoriesLength); i++) { - try { - - String fullPath = repositories[i] + path; - - Object lookupResult = resources.lookup(fullPath); - if (lookupResult instanceof Resource) { - resource = (Resource) lookupResult; - } - - // Note : Not getting an exception here means the resource was - // found - if (securityManager != null) { - PrivilegedAction dp = - new PrivilegedFindResource(files[i], path); - entry = (ResourceEntry)AccessController.doPrivileged(dp); - } else { - entry = findResourceInternal(files[i], path); - } - - ResourceAttributes attributes = - (ResourceAttributes) resources.getAttributes(fullPath); - contentLength = (int) attributes.getContentLength(); - entry.lastModified = attributes.getLastModified(); - - if (resource != null) { - - try { - binaryStream = resource.streamContent(); - } catch (IOException e) { - return null; - } - - // Register the full path for modification checking - // Note: Only syncing on a 'constant' object is needed - synchronized (allPermission) { - - int j; - - long[] result2 = - new long[lastModifiedDates.length + 1]; - for (j = 0; j < lastModifiedDates.length; j++) { - result2[j] = lastModifiedDates[j]; - } - result2[lastModifiedDates.length] = entry.lastModified; - lastModifiedDates = result2; - - String[] result = new String[paths.length + 1]; - for (j = 0; j < paths.length; j++) { - result[j] = paths[j]; - } - result[paths.length] = fullPath; - paths = result; - - } - - } - - } catch (NamingException e) { - } - } - - if ((entry == null) && (notFoundResources.containsKey(name))) - return null; - - JarEntry jarEntry = null; - - synchronized (jarFiles) { - - openJARs(); - for (i = 0; (entry == null) && (i < jarFilesLength); i++) { - - jarEntry = jarFiles[i].getJarEntry(path); - - if (jarEntry != null) { - - entry = new ResourceEntry(); - try { - entry.codeBase = getURL(jarRealFiles[i]); - String jarFakeUrl = getURI(jarRealFiles[i]).toString(); - jarFakeUrl = "jar:" + jarFakeUrl + "!/" + path; - entry.source = new URL(jarFakeUrl); - entry.lastModified = jarRealFiles[i].lastModified(); - } catch (MalformedURLException e) { - return null; - } - contentLength = (int) jarEntry.getSize(); - try { - entry.manifest = jarFiles[i].getManifest(); - binaryStream = jarFiles[i].getInputStream(jarEntry); - } catch (IOException e) { - return null; - } - - // Extract resources contained in JAR to the workdir - if (!(path.endsWith(".class"))) { - byte[] buf = new byte[1024]; - File resourceFile = new File - (loaderDir, jarEntry.getName()); - if (!resourceFile.exists()) { - Enumeration entries = jarFiles[i].entries(); - while (entries.hasMoreElements()) { - JarEntry jarEntry2 = - (JarEntry) entries.nextElement(); - if (!(jarEntry2.isDirectory()) - && (!jarEntry2.getName().endsWith - (".class"))) { - resourceFile = new File - (loaderDir, jarEntry2.getName()); - // No need to check mkdirs result because an - // IOException will occur anyway - resourceFile.getParentFile().mkdirs(); - FileOutputStream os = null; - InputStream is = null; - try { - is = jarFiles[i].getInputStream - (jarEntry2); - os = new FileOutputStream - (resourceFile); - while (true) { - int n = is.read(buf); - if (n <= 0) { - break; - } - os.write(buf, 0, n); - } - } catch (IOException e) { - // Ignore - } finally { - try { - if (is != null) { - is.close(); - } - } catch (IOException e) { - } - try { - if (os != null) { - os.close(); - } - } catch (IOException e) { - } - } - } - } - } - } - - } - - } - - if (entry == null) { - synchronized (notFoundResources) { - notFoundResources.put(name, name); - } - return null; - } - - if (binaryStream != null) { - - byte[] binaryContent = new byte[contentLength]; - - try { - int pos = 0; - - while (true) { - int n = binaryStream.read(binaryContent, pos, - binaryContent.length - pos); - if (n <= 0) - break; - pos += n; - } - binaryStream.close(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - - entry.binaryContent = binaryContent; - - // The certificates are only available after the JarEntry - // associated input stream has been fully read - if (jarEntry != null) { - entry.certificates = jarEntry.getCertificates(); - } - - } - - } - - // Add the entry in the local resource repository - synchronized (resourceEntries) { - // Ensures that all the threads which may be in a race to load - // a particular class all end up with the same ResourceEntry - // instance - ResourceEntry entry2 = (ResourceEntry) resourceEntries.get(name); - if (entry2 == null) { - resourceEntries.put(name, entry); - } else { - entry = entry2; - } - } - - return entry; - - } - - - /** - * Returns true if the specified package name is sealed according to the - * given manifest. - */ - protected boolean isPackageSealed(String name, Manifest man) { - - String path = name + "/"; - Attributes attr = man.getAttributes(path); - String sealed = null; - if (attr != null) { - sealed = attr.getValue(Name.SEALED); - } - if (sealed == null) { - if ((attr = man.getMainAttributes()) != null) { - sealed = attr.getValue(Name.SEALED); - } - } - return "true".equalsIgnoreCase(sealed); - - } - - - /** - * Finds the resource with the given name if it has previously been - * loaded and cached by this class loader, and return an input stream - * to the resource data. If this resource has not been cached, return - * <code>null</code>. - * - * @param name Name of the resource to return - */ - protected InputStream findLoadedResource(String name) { - - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - if (entry != null) { - if (entry.binaryContent != null) - return new ByteArrayInputStream(entry.binaryContent); - } - return (null); - - } - - - /** - * Finds the class with the given name if it has previously been - * loaded and cached by this class loader, and return the Class object. - * If this class has not been cached, return <code>null</code>. - * - * @param name Name of the resource to return - */ - protected Class findLoadedClass0(String name) { - - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - if (entry != null) { - return entry.loadedClass; - } - return (null); // FIXME - findLoadedResource() - - } - - - /** - * Refresh the system policy file, to pick up eventual changes. - */ - protected void refreshPolicy() { - - try { - // The policy file may have been modified to adjust - // permissions, so we're reloading it when loading or - // reloading a Context - Policy policy = Policy.getPolicy(); - policy.refresh(); - } catch (AccessControlException e) { - // Some policy files may restrict this, even for the core, - // so this exception is ignored - } - - } - - - /** - * Filter classes. - * - * @param name class name - * @return true if the class should be filtered - */ - protected boolean filter(String name) { - - if (name == null) - return false; - - // Looking up the package - String packageName = null; - int pos = name.lastIndexOf('.'); - if (pos != -1) - packageName = name.substring(0, pos); - else - return false; - - for (int i = 0; i < packageTriggers.length; i++) { - if (packageName.startsWith(packageTriggers[i])) - return true; - } - - return false; - - } - - - /** - * Validate a classname. As per SRV.9.7.2, we must restict loading of - * classes from J2SE (java.*) and classes of the servlet API - * (javax.servlet.*). That should enhance robustness and prevent a number - * of user error (where an older version of servlet.jar would be present - * in /WEB-INF/lib). - * - * @param name class name - * @return true if the name is valid - */ - protected boolean validate(String name) { - - if (name == null) - return false; - if (name.startsWith("java.")) - return false; - - return true; - - } - - - /** - * Check the specified JAR file, and return <code>true</code> if it does - * not contain any of the trigger classes. - * - * @param jarfile The JAR file to be checked - * - * @exception IOException if an input/output error occurs - */ - private boolean validateJarFile(File jarfile) - throws IOException { - - if (triggers == null) - return (true); - JarFile jarFile = new JarFile(jarfile); - for (int i = 0; i < triggers.length; i++) { - Class clazz = null; - try { - if (parent != null) { - clazz = parent.loadClass(triggers[i]); - } else { - clazz = Class.forName(triggers[i]); - } - } catch (Throwable t) { - clazz = null; - } - if (clazz == null) - continue; - String name = triggers[i].replace('.', '/') + ".class"; - if (log.isDebugEnabled()) - log.debug(" Checking for " + name); - JarEntry jarEntry = jarFile.getJarEntry(name); - if (jarEntry != null) { - log.info("validateJarFile(" + jarfile + - ") - jar not loaded. See Servlet Spec 2.3, " - + "section 9.7.2. Offending class: " + name); - jarFile.close(); - return (false); - } - } - jarFile.close(); - return (true); - - } - - - /** - * Get URL. - */ - protected URL getURL(File file) - throws MalformedURLException { - - File realFile = file; - try { - realFile = realFile.getCanonicalFile(); - } catch (IOException e) { - // Ignore - } - return realFile.toURL(); - - } - - - /** - * Get URL. - */ - protected URL getURI(File file) - throws MalformedURLException { - - return jdkCompat.getURI(file); - - } - - - /** - * Delete the specified directory, including all of its contents and - * subdirectories recursively. - * - * @param dir File object representing the directory to be deleted - */ - protected static void deleteDir(File dir) { - - String files[] = dir.list(); - if (files == null) { - files = new String[0]; - } - for (int i = 0; i < files.length; i++) { - File file = new File(dir, files[i]); - if (file.isDirectory()) { - deleteDir(file); - } else { - file.delete(); - } - } - dir.delete(); - - } - - - /** - * Log a debugging output message. - * - * @param message Message to be logged - */ - private void log(String message) { - - System.out.println("WebappClassLoader: " + message); - - } - - - /** - * Log a debugging output message with an exception. - * - * @param message Message to be logged - * @param throwable Exception to be logged - */ - private void log(String message, Throwable throwable) { - - System.out.println("WebappClassLoader: " + message); - throwable.printStackTrace(System.out); - - } - -}
diff --git a/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java b/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java deleted file mode 100644 index 8955714..0000000 --- a/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java +++ /dev/null
@@ -1,78 +0,0 @@ -/* - * Copyright 2009 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.dev; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.dev.GWTCompiler.GWTCompilerOptionsImpl; -import com.google.gwt.dev.jjs.JsOutputOption; - -import java.io.File; - -/** - * Test for deprecated {@link GWTShell}. - */ -@SuppressWarnings("deprecation") -public class GWTCompilerTest extends ArgProcessorTestBase { - - private final GWTCompiler.ArgProcessor argProcessor; - private final GWTCompilerOptionsImpl options = new GWTCompilerOptionsImpl(); - - public GWTCompilerTest() { - argProcessor = new GWTCompiler.ArgProcessor(options); - } - - public void testAllValidArgs() { - assertProcessSuccess(argProcessor, "-logLevel", "DEBUG", "-style", - "PRETTY", "-ea", "-XdisableAggressiveOptimization", "-out", "myWww", - "-gen", "myGen", "c.g.g.h.H", "my.Module"); - - assertEquals(new File("myGen").getAbsoluteFile(), - options.getGenDir().getAbsoluteFile()); - assertEquals(new File("myWww"), options.getOutDir()); - - assertEquals(TreeLogger.DEBUG, options.getLogLevel()); - assertEquals(JsOutputOption.PRETTY, options.getOutput()); - assertTrue(options.isEnableAssertions()); - assertFalse(options.isAggressivelyOptimize()); - - assertEquals(2, options.getModuleNames().size()); - assertEquals("c.g.g.h.H", options.getModuleNames().get(0)); - assertEquals("my.Module", options.getModuleNames().get(1)); - } - - public void testDefaultArgs() { - assertProcessSuccess(argProcessor, "c.g.g.h.H"); - - assertEquals(null, options.getGenDir()); - assertEquals(new File("").getAbsoluteFile(), - options.getOutDir().getAbsoluteFile()); - - assertEquals(TreeLogger.INFO, options.getLogLevel()); - assertEquals(JsOutputOption.OBFUSCATED, options.getOutput()); - assertFalse(options.isEnableAssertions()); - assertTrue(options.isAggressivelyOptimize()); - - assertEquals(1, options.getModuleNames().size()); - assertEquals("c.g.g.h.H", options.getModuleNames().get(0)); - } - - public void testForbiddenArgs() { - assertProcessFailure(argProcessor, "-localWorkers", "2"); - assertProcessFailure(argProcessor, "-extra", "extra"); - assertProcessFailure(argProcessor, "-war", "war"); - assertProcessFailure(argProcessor, "-work", "work"); - } -}
diff --git a/dev/core/test/com/google/gwt/dev/GWTShellTest.java b/dev/core/test/com/google/gwt/dev/GWTShellTest.java deleted file mode 100644 index 557189e..0000000 --- a/dev/core/test/com/google/gwt/dev/GWTShellTest.java +++ /dev/null
@@ -1,99 +0,0 @@ -/* - * Copyright 2009 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.dev; - -import com.google.gwt.core.ext.TreeLogger; -import com.google.gwt.dev.GWTShell.ShellOptionsImpl; -import com.google.gwt.dev.HostedModeTest.MySCL; -import com.google.gwt.dev.jjs.JsOutputOption; -import com.google.gwt.dev.shell.BrowserWidgetHostChecker; - -import java.io.File; - -/** - * Test for deprecated {@link GWTShell}. - */ -@SuppressWarnings("deprecation") -public class GWTShellTest extends ArgProcessorTestBase { - - private final GWTShell.ArgProcessor argProcessor; - private final ShellOptionsImpl options = new ShellOptionsImpl(); - - public GWTShellTest() { - argProcessor = new GWTShell.ArgProcessor(options, false, false); - } - - public void testAllValidArgs() { - assertProcessSuccess(argProcessor, "-port", "8080", "-whitelist", "white", - "-blacklist", "black", "-logLevel", "DEBUG", "-noserver", "-out", - "myWww", "-gen", "myGen", "http://www.google.com/", "foo"); - - assertNotNull(BrowserWidgetHostChecker.matchWhitelisted("white")); - assertNotNull(BrowserWidgetHostChecker.matchBlacklisted("black")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88/")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88/foo")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88/")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88/foo")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org/")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org/foo")); - assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://www.evildomain.org/foo?http://localhost")); - assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1")); - assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88")); - assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88/")); - assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88/foo")); - - assertEquals(new File("myGen").getAbsoluteFile(), - options.getGenDir().getAbsoluteFile()); - assertEquals(new File("myWww"), options.getOutDir()); - - assertEquals(TreeLogger.DEBUG, options.getLogLevel()); - - assertEquals(8080, options.getPort()); - assertTrue(options.isNoServer()); - assertEquals(2, options.getStartupURLs().size()); - assertEquals("http://www.google.com/", options.getStartupURLs().get(0)); - assertEquals("foo", options.getStartupURLs().get(1)); - } - - public void testDefaultArgs() { - assertProcessSuccess(argProcessor); - - assertEquals(null, options.getGenDir()); - assertEquals(new File("").getAbsoluteFile(), - options.getOutDir().getAbsoluteFile()); - - assertEquals(TreeLogger.INFO, options.getLogLevel()); - assertEquals(JsOutputOption.OBFUSCATED, options.getOutput()); - assertFalse(options.isEnableAssertions()); - assertTrue(options.isAggressivelyOptimize()); - - assertEquals(8888, options.getPort()); - assertFalse(options.isNoServer()); - assertEquals(0, options.getStartupURLs().size()); - } - - public void testForbiddenArgs() { - assertProcessFailure(argProcessor, "-localWorkers", "2"); - assertProcessFailure(argProcessor, "-extra", "extra"); - assertProcessFailure(argProcessor, "-war", "war"); - assertProcessFailure(argProcessor, "-work", "work"); - assertProcessFailure(argProcessor, "-server", MySCL.class.getName()); - } -}
diff --git a/eclipse/dev/.classpath b/eclipse/dev/.classpath index fa17a0d..4b1f5b4 100644 --- a/eclipse/dev/.classpath +++ b/eclipse/dev/.classpath
@@ -12,35 +12,16 @@ <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/ant-launcher-1.6.5.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/catalina-1.0.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/catalina-optional-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-beanutils-1.6.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-collections-3.1.jar" sourcepath="/GWT_TOOLS/lib/tomcat/commons-collections-3.1-src.zip"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-digester-1.5.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-el-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-logging-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-modeler-1.1.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jakarta-regexp-1.3.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jasper-compiler-1.0.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jasper-runtime-1.0.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jsp-api-2.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/mx4j-jmx-1.1.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-common-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-factory-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-java-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-resources-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlet-api-2.5.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlet-api-2.4.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-common-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-default-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-invoker-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-coyote-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-http11-1.0.jar" sourcepath="/GWT_TOOLS/lib/tomcat/tomcat-http11-1.0.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-jk2-2.1.jar"/> - <classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-util-5.1.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-core-js-2.9.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-core-js-2.9-sources.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-2.9.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-2.9-sources.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/guava/guava-10.0.1/guava-10.0.1-rebased.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/jscomp/sourcemap-rebased.jar"/> <classpathentry kind="var" path="GWT_TOOLS/lib/jscomp/r1649/compiler-rebased.jar"/> + <classpathentry kind="var" path="GWT_TOOLS/lib/apache/commons/commons-collections-3.2.1.jar"/> <classpathentry kind="output" path="bin"/> </classpath>