Adds a new artifact visibility "Deploy" (in addition to existing
"Public" and "Private"), for artifacts that should be deployed to
the server but not ever served to a client.
Patch by: jat
Review by: unnurg
Review at http://gwt-code-reviews.appspot.com/1055802
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9162 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java b/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java
index 4bb578a..067c238 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/EmittedArtifact.java
@@ -37,17 +37,98 @@
*/
public abstract class EmittedArtifact extends Artifact<EmittedArtifact> {
+ /**
+ * Describes the visibility of an artifact.
+ */
+ public enum Visibility {
+
+ /**
+ * A public artifact is something that may be served to clients.
+ */
+ Public,
+
+ /**
+ * A private artifact is something that is only used during the build
+ * process.
+ */
+ Private {
+ @Override
+ public boolean matches(Visibility visibility) {
+ switch (visibility) {
+ case LegacyDeploy:
+ case Private:
+ return true;
+ default:
+ return false;
+ }
+ }
+ },
+
+ /**
+ * A deploy artifact is deployed to the server but is never served to the
+ * client.
+ */
+ Deploy {
+ @Override
+ public boolean matches(Visibility visibility) {
+ switch (visibility) {
+ case Deploy:
+ case LegacyDeploy:
+ return true;
+ default:
+ return false;
+ }
+ }
+ },
+
+ /**
+ * For legacy use only - used for artifacts that were previously marked as
+ * private because they should not be delivered to the client, but actually
+ * should be visible to the server. These artifacts will now be treated as
+ * both Private and Deploy, so that existing build tools that expect to find
+ * them in the output directory for Private artifacts will find them.
+ *
+ * New code should use Deploy instead.
+ */
+ LegacyDeploy {
+ @Override
+ public boolean matches(Visibility visibility) {
+ switch (visibility) {
+ case Deploy:
+ case LegacyDeploy:
+ case Private:
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ /**
+ * Returns true if this visibility matches the requested visibility level,
+ * dealing with the fact that {@link #LegacyDeploy} matches both
+ * {@link #Private} and {@link #Deploy}.
+ *
+ * @param visibility
+ * @return true if this visibility matches the requested level
+ */
+ public boolean matches(Visibility visibility) {
+ return this == visibility;
+ }
+ }
+
private final String partialPath;
/**
* This is mutable because it has no effect on identity.
*/
- private boolean isPrivate;
+ private Visibility visibility;
protected EmittedArtifact(Class<? extends Linker> linker, String partialPath) {
super(linker);
assert partialPath != null;
this.partialPath = partialPath;
+ visibility = Visibility.Public;
}
/**
@@ -78,6 +159,13 @@
return partialPath;
}
+ /**
+ * @return the visibility
+ */
+ public Visibility getVisibility() {
+ return visibility;
+ }
+
@Override
public final int hashCode() {
return getPartialPath().hashCode();
@@ -96,16 +184,31 @@
* Private EmittedArtifacts are intended for resources that generally should
* not be deployed to the server in the same location as the module
* compilation artifacts.
+ *
+ * @deprecated use {@link #getVisibility()} instead
*/
+ @Deprecated
public boolean isPrivate() {
- return isPrivate;
+ return visibility == Visibility.Private;
}
/**
* Sets the private attribute of the EmittedResource.
+ *
+ * @param isPrivate true if this artifact is private
+ *
+ * @deprecated use {@link #setVisibility(Visibility)} instead
*/
+ @Deprecated
public void setPrivate(boolean isPrivate) {
- this.isPrivate = isPrivate;
+ this.visibility = isPrivate ? Visibility.Private : Visibility.Public;
+ }
+
+ /**
+ * @param visibility the visibility to set
+ */
+ public void setVisibility(Visibility visibility) {
+ this.visibility = visibility;
}
@Override
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/BinaryOnlyArtifactWrapper.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/BinaryOnlyArtifactWrapper.java
index b3c868b..787c11d 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/BinaryOnlyArtifactWrapper.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/BinaryOnlyArtifactWrapper.java
@@ -31,7 +31,7 @@
public BinaryOnlyArtifactWrapper(String path, EmittedArtifact artifact) {
super(path);
- setPrivate(artifact.isPrivate());
+ setVisibility(artifact.getVisibility());
this.underlyingArtifact = artifact;
}
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
index e638de0..220456a 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.PublicResource;
import com.google.gwt.core.ext.linker.SelectionProperty;
@@ -467,26 +468,26 @@
*
* @param logger where to log progress
* @param artifacts the artifacts to emit
- * @param emitPrivates whether to emit the private artifacts only, vs. the
- * public artifacts only
+ * @param visibility the level of visibility of artifacts to output
* @param out where to emit the artifact contents
*/
public void produceOutput(TreeLogger logger, ArtifactSet artifacts,
- boolean emitPrivates, OutputFileSet out) throws UnableToCompleteException {
- String publicness = emitPrivates ? "private" : "public";
- logger = logger.branch(TreeLogger.TRACE, "Linking " + publicness
+ Visibility visibility, OutputFileSet out) throws UnableToCompleteException {
+ logger = logger.branch(TreeLogger.TRACE, "Linking " + visibility
+ " artifacts into " + out.getPathDescription(), null);
for (EmittedArtifact artifact : artifacts.find(EmittedArtifact.class)) {
TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG,
"Emitting resource " + artifact.getPartialPath(), null);
- if (artifact.isPrivate() != emitPrivates) {
+ if (!artifact.getVisibility().matches(visibility)) {
continue;
}
String partialPath = artifact.getPartialPath();
- if (artifact.isPrivate()) {
+ if (artifact.getVisibility() != Visibility.Public) {
+ // Any non-public linker will have their artifacts stored in a directory
+ // named after the linker.
partialPath = getExtraPathForLinker(artifact.getLinker(), partialPath);
if (partialPath.startsWith("/")) {
partialPath = partialPath.substring(1);
diff --git a/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java b/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
index 2c00afa..1b84ea8 100644
--- a/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
+++ b/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.linker.Shardable;
@@ -237,7 +238,8 @@
try {
serializedMap = emitString(logger, mappingArtifact.getSerialized(),
"compilation-mappings.txt");
- serializedMap.setPrivate(false);
+ // TODO(unnurg): make this Deploy
+ serializedMap.setVisibility(Visibility.Public);
toReturn.add(serializedMap);
} catch (UnableToCompleteException e) {
e.printStackTrace();
diff --git a/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java b/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
index bdc8c40..eadeb71 100644
--- a/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
+++ b/dev/core/src/com/google/gwt/core/linker/SoycReportLinker.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
@@ -172,7 +173,8 @@
*/
private void buildCompilerMetricsXml(ArtifactSet artifacts) {
ModuleMetricsArtifact moduleMetrics = null;
- Set<ModuleMetricsArtifact> moduleMetricsSet = artifacts.find(ModuleMetricsArtifact.class);
+ Set<ModuleMetricsArtifact> moduleMetricsSet = artifacts.find(
+ ModuleMetricsArtifact.class);
if (!moduleMetricsSet.isEmpty()) {
for (ModuleMetricsArtifact metrics : moduleMetricsSet) {
moduleMetrics = metrics;
@@ -186,10 +188,11 @@
return;
}
- byte[] xmlResult = CompilerMetricsXmlFormatter.writeMetricsAsXml(artifacts, moduleMetrics);
- EmittedArtifact metricsArtifact = new SyntheticArtifact(SoycReportLinker.class,
- "compilerMetrics.xml", xmlResult);
- metricsArtifact.setPrivate(true);
+ byte[] xmlResult = CompilerMetricsXmlFormatter.writeMetricsAsXml(
+ artifacts, moduleMetrics);
+ EmittedArtifact metricsArtifact = new SyntheticArtifact(
+ SoycReportLinker.class, "compilerMetrics.xml", xmlResult);
+ metricsArtifact.setVisibility(Visibility.Private);
artifacts.add(metricsArtifact);
}
@@ -197,7 +200,8 @@
ArtifactSet artifacts) {
ArtifactsOutputDirectory out = new ArtifactsOutputDirectory();
try {
- new SoycDashboard(out).generateCrossPermutationFiles(extractPermutationDescriptions(artifacts));
+ new SoycDashboard(out).generateCrossPermutationFiles(
+ extractPermutationDescriptions(artifacts));
} catch (IOException e) {
logger.log(TreeLogger.ERROR,
"Error while generating a Story of Your Compile", e);
@@ -221,9 +225,12 @@
private Map<String, List<String>> extractPermutationDescriptions(
ArtifactSet artifacts) {
- Map<String, List<String>> permDescriptions = new TreeMap<String, List<String>>();
- for (PermDescriptionArtifact art : artifacts.find(PermDescriptionArtifact.class)) {
- permDescriptions.put(Integer.toString(art.getPermId()), art.getPermDesc());
+ Map<String, List<String>> permDescriptions = new TreeMap<String,
+ List<String>>();
+ for (PermDescriptionArtifact art : artifacts.find(
+ PermDescriptionArtifact.class)) {
+ permDescriptions.put(Integer.toString(art.getPermId()),
+ art.getPermDesc());
}
return permDescriptions;
}
diff --git a/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java b/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java
index 321c29e..5dc937e 100644
--- a/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java
+++ b/dev/core/src/com/google/gwt/core/linker/SymbolMapsLinker.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.Shardable;
@@ -120,7 +121,8 @@
throws UnableToCompleteException {
EmittedArtifact symbolMapArtifact = emitBytes(logger, out.toByteArray(),
result.getStrongName() + STRONG_NAME_SUFFIX);
- symbolMapArtifact.setPrivate(true);
+ // TODO: change to Deploy when possible
+ symbolMapArtifact.setVisibility(Visibility.LegacyDeploy);
artifacts.add(symbolMapArtifact);
}
diff --git a/dev/core/src/com/google/gwt/dev/Compiler.java b/dev/core/src/com/google/gwt/dev/Compiler.java
index 82cd22d..3eb5ce2 100644
--- a/dev/core/src/com/google/gwt/dev/Compiler.java
+++ b/dev/core/src/com/google/gwt/dev/Compiler.java
@@ -30,6 +30,7 @@
import com.google.gwt.dev.util.FileBackedObject;
import com.google.gwt.dev.util.Memory;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
@@ -59,6 +60,7 @@
registerHandler(new ArgHandlerWorkDirOptional(options));
registerHandler(new ArgHandlerWarDir(options));
+ registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerExtraDir(options));
}
@@ -87,6 +89,10 @@
localWorkers = other.getLocalWorkers();
}
+ public File getDeployDir() {
+ return linkOptions.getDeployDir();
+ }
+
public File getExtraDir() {
return linkOptions.getExtraDir();
}
@@ -104,6 +110,10 @@
return linkOptions.getWarDir();
}
+ public void setDeployDir(File extraDir) {
+ linkOptions.setDeployDir(extraDir);
+ }
+
public void setExtraDir(File extraDir) {
linkOptions.setExtraDir(extraDir);
}
@@ -234,7 +244,7 @@
}
Link.link(logger.branch(TreeLogger.TRACE, logMessage), module,
generatedArtifacts, allPerms, resultFiles, options.getWarDir(),
- options.getExtraDir(), precompileOptions);
+ options.getDeployDir(), options.getExtraDir(), precompileOptions);
linkEvent.end();
long compileDone = System.currentTimeMillis();
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index 32aaca4..8bcdcca 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -20,6 +20,7 @@
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.jetty.JettyLauncher;
@@ -30,6 +31,7 @@
import com.google.gwt.dev.util.OutputFileSet;
import com.google.gwt.dev.util.OutputFileSetOnDirectory;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
@@ -167,6 +169,7 @@
registerHandler(new ArgHandlerServer(options));
registerHandler(new ArgHandlerStartupURLs(options));
registerHandler(new ArgHandlerWarDir(options));
+ registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerWorkDirOptional(options));
registerHandler(new ArgHandlerModuleName(options) {
@@ -207,6 +210,15 @@
private ServletContainerLauncher scl;
private String sclArgs;
private File warDir;
+ private File deployDir;
+
+ /**
+ * @return the deploy directory.
+ */
+ public File getDeployDir() {
+ return (deployDir == null) ? new File(warDir, "WEB-INF/deploy")
+ : deployDir;
+ }
public File getExtraDir() {
return extraDir;
@@ -233,6 +245,15 @@
return warDir;
}
+ /**
+ * Set the deploy directory.
+ *
+ * @param deployDir the deployDir to set
+ */
+ public void setDeployDir(File deployDir) {
+ this.deployDir = deployDir;
+ }
+
public void setExtraDir(File extraDir) {
this.extraDir = extraDir;
}
@@ -491,16 +512,23 @@
OutputFileSetOnDirectory outFileSet = new OutputFileSetOnDirectory(
options.getWarDir(), module.getName() + "/");
+ OutputFileSetOnDirectory deployFileSet = new OutputFileSetOnDirectory(
+ options.getDeployDir(), module.getName() + "/");
OutputFileSet extraFileSet = new NullOutputFileSet();
if (options.getExtraDir() != null) {
extraFileSet = new OutputFileSetOnDirectory(options.getExtraDir(),
module.getName() + "/");
}
- linkerStack.produceOutput(linkLogger, artifacts, false, outFileSet);
- linkerStack.produceOutput(linkLogger, artifacts, true, extraFileSet);
+ linkerStack.produceOutput(linkLogger, artifacts, Visibility.Public,
+ outFileSet);
+ linkerStack.produceOutput(linkLogger, artifacts, Visibility.Deploy,
+ deployFileSet);
+ linkerStack.produceOutput(linkLogger, artifacts, Visibility.Private,
+ extraFileSet);
outFileSet.close();
+ deployFileSet.close();
try {
extraFileSet.close();
} catch (IOException e) {
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index 601e63d..98cd955 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -18,6 +18,7 @@
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;
@@ -224,7 +225,8 @@
outputDir.mkdirs();
OutputFileSetOnDirectory outFileSet = new OutputFileSetOnDirectory(
outputDir, "");
- linkerStack.produceOutput(logger, artifacts, false, outFileSet);
+ linkerStack.produceOutput(logger, artifacts, Visibility.Public,
+ outFileSet);
outFileSet.close();
}
}
diff --git a/dev/core/src/com/google/gwt/dev/Link.java b/dev/core/src/com/google/gwt/dev/Link.java
index 5a38bfe..9c46fc3 100644
--- a/dev/core/src/com/google/gwt/dev/Link.java
+++ b/dev/core/src/com/google/gwt/dev/Link.java
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.linker.Artifact;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.impl.BinaryOnlyArtifactWrapper;
import com.google.gwt.core.ext.linker.impl.JarEntryEmittedArtifact;
@@ -42,8 +43,10 @@
import com.google.gwt.dev.util.OutputFileSetOnDirectory;
import com.google.gwt.dev.util.OutputFileSetOnJar;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
+import com.google.gwt.dev.util.arg.OptionDeployDir;
import com.google.gwt.dev.util.arg.OptionExtraDir;
import com.google.gwt.dev.util.arg.OptionOutDir;
import com.google.gwt.dev.util.arg.OptionWarDir;
@@ -80,7 +83,7 @@
* Options for Link.
*/
public interface LinkOptions extends CompileTaskOptions, OptionExtraDir,
- OptionWarDir, LegacyLinkOptions {
+ OptionWarDir, OptionDeployDir, LegacyLinkOptions {
}
static class ArgProcessor extends CompileArgProcessor {
@@ -89,6 +92,7 @@
super(options);
registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerWarDir(options));
+ registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerOutDirDeprecated(options));
}
@@ -104,6 +108,7 @@
static class LinkOptionsImpl extends CompileTaskOptionsImpl implements
LinkOptions {
+ private File deployDir;
private File extraDir;
private File outDir;
private File warDir;
@@ -117,11 +122,17 @@
public void copyFrom(LinkOptions other) {
super.copyFrom(other);
+ setDeployDir(other.getDeployDir());
setExtraDir(other.getExtraDir());
setWarDir(other.getWarDir());
setOutDir(other.getOutDir());
}
+ public File getDeployDir() {
+ return (deployDir == null) ? new File(warDir, "WEB-INF/deploy")
+ : deployDir;
+ }
+
public File getExtraDir() {
return extraDir;
}
@@ -135,6 +146,10 @@
return warDir;
}
+ public void setDeployDir(File dir) {
+ deployDir = dir;
+ }
+
public void setExtraDir(File extraDir) {
this.extraDir = extraDir;
}
@@ -160,23 +175,35 @@
linkerContext, generatedArtifacts, permutations, resultFiles);
OutputFileSet outFileSet = chooseOutputFileSet(outDir, module.getName()
+ "/");
+ OutputFileSet deployFileSet = chooseOutputFileSet(outDir, module.getName()
+ + "-deploy/");
OutputFileSet extraFileSet = chooseOutputFileSet(outDir, module.getName()
+ "-aux/");
- doProduceOutput(logger, artifacts, linkerContext, outFileSet, extraFileSet);
+ doProduceOutput(logger, artifacts, linkerContext, outFileSet, deployFileSet,
+ extraFileSet);
}
public static void link(TreeLogger logger, ModuleDef module,
ArtifactSet generatedArtifacts, Permutation[] permutations,
List<FileBackedObject<PermutationResult>> resultFiles, File outDir,
- File extrasDir, JJSOptions precompileOptions)
+ File deployDir, File extrasDir, JJSOptions precompileOptions)
throws UnableToCompleteException, IOException {
StandardLinkerContext linkerContext = new StandardLinkerContext(logger,
module, precompileOptions);
ArtifactSet artifacts = doSimulatedShardingLink(logger, module,
linkerContext, generatedArtifacts, permutations, resultFiles);
+ OutputFileSet extrasFileSet = chooseOutputFileSet(extrasDir,
+ module.getName() + "/");
+ // allow -deploy and -extra to point to the same directory/jar
+ OutputFileSet deployFileSet;
+ if (deployDir.equals(extrasDir)) {
+ deployFileSet = extrasFileSet;
+ } else {
+ deployFileSet = chooseOutputFileSet(deployDir,
+ module.getName() + "/");
+ }
doProduceOutput(logger, artifacts, linkerContext, chooseOutputFileSet(
- outDir, module.getName() + "/"), chooseOutputFileSet(extrasDir,
- module.getName() + "/"));
+ outDir, module.getName() + "/"), deployFileSet, extrasFileSet);
}
/**
@@ -215,17 +242,12 @@
// Write the data of emitted artifacts
for (EmittedArtifact art : linkedArtifacts.find(EmittedArtifact.class)) {
- String jarEntryPath;
- if (art.isPrivate()) {
- String pathWithLinkerName = linkerContext.getExtraPathForLinker(
- art.getLinker(), art.getPartialPath());
- if (pathWithLinkerName.startsWith("/")) {
- // This happens if the linker has no extra path
- pathWithLinkerName = pathWithLinkerName.substring(1);
- }
- jarEntryPath = "aux/" + pathWithLinkerName;
+ Visibility visibility = art.getVisibility();
+ String jarEntryPath = visibility.name() + "/";
+ if (visibility == Visibility.Public) {
+ jarEntryPath += art.getPartialPath();
} else {
- jarEntryPath = "target/" + art.getPartialPath();
+ jarEntryPath += prefixArtifactPath(art, linkerContext);
}
ZipEntry ze = new ZipEntry(jarEntryPath);
ze.setTime(art.getLastModified());
@@ -331,8 +353,8 @@
}
String name = dirOrJar.getName();
- if (!dirOrJar.isDirectory()
- && (name.endsWith(".war") || name.endsWith(".jar") || name.endsWith(".zip"))) {
+ if (!dirOrJar.isDirectory() && (name.endsWith(".war")
+ || name.endsWith(".jar") || name.endsWith(".zip"))) {
return new OutputFileSetOnJar(dirOrJar, pathPrefix);
} else {
Util.recursiveDelete(new File(dirOrJar, pathPrefix), true);
@@ -389,11 +411,18 @@
*/
private static void doProduceOutput(TreeLogger logger, ArtifactSet artifacts,
StandardLinkerContext linkerContext, OutputFileSet outFileSet,
- OutputFileSet extraFileSet) throws UnableToCompleteException, IOException {
- linkerContext.produceOutput(logger, artifacts, false, outFileSet);
- linkerContext.produceOutput(logger, artifacts, true, extraFileSet);
+ OutputFileSet deployFileSet, OutputFileSet extraFileSet)
+ throws UnableToCompleteException, IOException {
+
+ linkerContext.produceOutput(logger, artifacts, Visibility.Public,
+ outFileSet);
+ linkerContext.produceOutput(logger, artifacts, Visibility.Deploy,
+ deployFileSet);
+ linkerContext.produceOutput(logger, artifacts, Visibility.Private,
+ extraFileSet);
outFileSet.close();
+ deployFileSet.close();
extraFileSet.close();
logger.log(TreeLogger.INFO, "Link succeeded");
@@ -456,12 +485,8 @@
private static String getFullArtifactPath(EmittedArtifact emittedArtifact,
StandardLinkerContext context) {
String path = emittedArtifact.getPartialPath();
- if (emittedArtifact.isPrivate()) {
- path = context.getExtraPathForLinker(emittedArtifact.getLinker(), path);
- if (path.startsWith("/")) {
- // This happens if the linker has no extra path
- path = path.substring(1);
- }
+ if (emittedArtifact.getVisibility() != Visibility.Public) {
+ path = prefixArtifactPath(emittedArtifact, context);
}
return path;
}
@@ -490,6 +515,25 @@
+ javaScript[0].length() + " and total script size of " + totalSize);
}
+ /**
+ * Prefix an artifact's partial path with the linker name and make sure it is
+ * a relative pathname.
+ *
+ * @param art
+ * @param linkerContext
+ * @return prefixed path
+ */
+ private static String prefixArtifactPath(
+ EmittedArtifact art, StandardLinkerContext linkerContext) {
+ String pathWithLinkerName = linkerContext.getExtraPathForLinker(
+ art.getLinker(), art.getPartialPath());
+ if (pathWithLinkerName.startsWith("/")) {
+ // This happens if the linker has no extra path
+ pathWithLinkerName = pathWithLinkerName.substring(1);
+ }
+ return pathWithLinkerName;
+ }
+
private static ArtifactSet scanCompilePermResults(TreeLogger logger,
List<File> resultFiles) throws IOException, UnableToCompleteException {
final ArtifactSet artifacts = new ArtifactSet();
@@ -504,18 +548,10 @@
}
String path;
- Artifact<?> artForEntry;
+ Artifact<?> artForEntry = null;
- if (entry.getName().startsWith("target/")) {
- path = entry.getName().substring("target/".length());
- artForEntry = new JarEntryEmittedArtifact(path, resultFile, entry);
- } else if (entry.getName().startsWith("aux/")) {
- path = entry.getName().substring("aux/".length());
- JarEntryEmittedArtifact jarArtifact = new JarEntryEmittedArtifact(
- path, resultFile, entry);
- jarArtifact.setPrivate(true);
- artForEntry = jarArtifact;
- } else if (entry.getName().startsWith("arts/")) {
+ String entryName = entry.getName();
+ if (entryName.startsWith("arts/")) {
try {
artForEntry = Util.readStreamAsObject(new BufferedInputStream(
jarFile.getInputStream(entry)), Artifact.class);
@@ -526,7 +562,21 @@
throw new UnableToCompleteException();
}
} else {
- continue;
+ int slash = entryName.indexOf('/');
+ if (slash >= 0) {
+ try {
+ Visibility visibility = Visibility.valueOf(entryName.substring(0,
+ slash));
+ path = entryName.substring(slash + 1);
+ JarEntryEmittedArtifact jarArtifact = new JarEntryEmittedArtifact(
+ path, resultFile, entry);
+ jarArtifact.setVisibility(visibility);
+ artForEntry = jarArtifact;
+ } catch (IllegalArgumentException e) {
+ // silently ignore paths with invalid visibilities
+ continue;
+ }
+ }
}
artifacts.add(artForEntry);
@@ -596,8 +646,8 @@
try {
link(branch, module, precomp.getGeneratedArtifacts(), perms,
- resultFiles, options.getWarDir(), options.getExtraDir(),
- precomp.getUnifiedAst().getOptions());
+ resultFiles, options.getWarDir(), options.getDeployDir(),
+ options.getExtraDir(), precomp.getUnifiedAst().getOptions());
} catch (IOException e) {
logger.log(TreeLogger.ERROR,
"Unexpected exception while producing output", e);
@@ -638,13 +688,21 @@
module.getName() + "/");
OutputFileSet extraFileSet = chooseOutputFileSet(options.getExtraDir(),
module.getName() + "/");
+ // allow -deploy and -extra to point to the same directory/jar
+ OutputFileSet deployFileSet;
+ if (options.getDeployDir().equals(options.getExtraDir())) {
+ deployFileSet = extraFileSet;
+ } else {
+ deployFileSet = chooseOutputFileSet(options.getDeployDir(),
+ module.getName() + "/");
+ }
ArtifactSet artifacts = scanCompilePermResults(logger, resultFiles);
artifacts.addAll(linkerContext.getArtifactsForPublicResources(logger,
module));
artifacts = linkerContext.invokeFinalLink(logger, artifacts);
doProduceOutput(logger, artifacts, linkerContext, outFileSet,
- extraFileSet);
+ deployFileSet, extraFileSet);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Exception during final linking", e);
throw new UnableToCompleteException();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 722431b..53f4d53 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -25,6 +25,7 @@
import com.google.gwt.core.ext.linker.CompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.SymbolData;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
@@ -1184,7 +1185,7 @@
// Set all of the main SOYC artifacts private.
for (SyntheticArtifact soycArtifact : soycArtifacts) {
- soycArtifact.setPrivate(true);
+ soycArtifact.setVisibility(Visibility.Private);
}
if (sizeBreakdowns != null) {
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
index 04bff20..d0de937 100644
--- a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
+++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
@@ -35,6 +35,12 @@
return pathsSeen.contains(path);
}
+ /**
+ * No more output will be sent to this OutputFileSet. It is safe to call
+ * {@link #close()} on an already-closed instance.
+ *
+ * @throws IOException
+ */
public abstract void close() throws IOException;
/**
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnJar.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnJar.java
index 132c5bb..5d8eaad 100644
--- a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnJar.java
+++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnJar.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.util;
+import com.google.gwt.dev.util.NullOutputFileSet.NullOutputStream;
import com.google.gwt.dev.util.collect.HashSet;
import java.io.File;
@@ -67,6 +68,8 @@
private final JarOutputStream jar;
private final String pathPrefix;
+
+ private final Set<String> seenEntries = new HashSet<String>();
public OutputFileSetOnJar(File jarFile, String pathPrefix) throws IOException {
super(jarFile.getAbsolutePath());
@@ -83,9 +86,14 @@
@Override
public OutputStream createNewOutputStream(String path, long lastModifiedTime)
throws IOException {
- mkzipDirs(getParentPath(pathPrefix + path));
+ String fullPath = pathPrefix + path;
+ if (seenEntries.contains(fullPath)) {
+ return new NullOutputStream();
+ }
+ seenEntries.add(fullPath);
+ mkzipDirs(getParentPath(fullPath));
- ZipEntry zipEntry = new ZipEntry(pathPrefix + path);
+ ZipEntry zipEntry = new ZipEntry(fullPath);
if (lastModifiedTime >= 0) {
zipEntry.setTime(lastModifiedTime);
}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDeployDir.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDeployDir.java
new file mode 100644
index 0000000..60079c6
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDeployDir.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 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.util.arg;
+
+import com.google.gwt.util.tools.ArgHandlerDir;
+
+import java.io.File;
+
+/**
+ * Argument handler for processing the deploy directory flag.
+ */
+public class ArgHandlerDeployDir extends ArgHandlerDir {
+ // The default argument is handled in LinkOptionsImpl since it is relative
+ // to the war directory.
+
+ private final OptionDeployDir option;
+
+ public ArgHandlerDeployDir(OptionDeployDir option) {
+ this.option = option;
+ }
+
+ @Override
+ public String getPurpose() {
+ return "The directory into which deployable but not servable output files"
+ + " will be written (defaults to 'WEB-INF/deploy' under the -war "
+ + "directory/jar, and may be the same as the -extra directory/jar)";
+ }
+
+ @Override
+ public String getTag() {
+ return "-deploy";
+ }
+
+ @Override
+ public void setDir(File dir) {
+ option.setDeployDir(dir);
+ }
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionDeployDir.java b/dev/core/src/com/google/gwt/dev/util/arg/OptionDeployDir.java
new file mode 100644
index 0000000..376a588
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionDeployDir.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 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.util.arg;
+
+import java.io.File;
+
+/**
+ * Option to set the base directory for artifacts of visibility "Deploy".
+ */
+public interface OptionDeployDir {
+
+ /**
+ * Returns the deploy directory.
+ */
+ File getDeployDir();
+
+ /**
+ * Sets the deploy directory.
+ */
+ void setDeployDir(File dir);
+}
diff --git a/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java b/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
index dac00a5..9cf9dea 100644
--- a/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
+++ b/dev/core/src/com/google/gwt/soyc/io/ArtifactsOutputDirectory.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.soyc.io;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
import com.google.gwt.core.linker.SoycReportLinker;
@@ -51,7 +52,7 @@
SyntheticArtifact newArtifact = new SyntheticArtifact(
SoycReportLinker.class, COMPILE_REPORT_DIRECTORY + "/" + path,
baos.toByteArray());
- newArtifact.setPrivate(true);
+ newArtifact.setVisibility(Visibility.Private);
artifacts.add(newArtifact);
baos = null;
}
diff --git a/user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java b/user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java
index 920d2b3..f4053d5 100644
--- a/user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java
+++ b/user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.SelectionProperty;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
@@ -226,7 +227,8 @@
msgWriter.write(branch, locale.toString(), resourceList, out,
targetClass);
out.flush();
- context.commitResource(logger, outStr).setPrivate(true);
+ context.commitResource(logger, outStr).setVisibility(
+ Visibility.Private);
} catch (UnableToCompleteException e) {
// msgWriter should have already logged an error message.
// Keep going for now so we can find other errors.
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 122e0ef..05ec38f 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -31,6 +31,7 @@
import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.shell.CheckForUpdates;
import com.google.gwt.dev.shell.jetty.JettyLauncher;
+import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
import com.google.gwt.dev.util.arg.ArgHandlerDisableCastChecking;
import com.google.gwt.dev.util.arg.ArgHandlerDisableClassMetadata;
@@ -168,6 +169,7 @@
return super.getDefaultArgs();
}
});
+ registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerWorkDirOptional(options));
// DISABLE: ArgHandlerModuleName
diff --git a/user/src/com/google/gwt/precompress/linker/PrecompressLinker.java b/user/src/com/google/gwt/precompress/linker/PrecompressLinker.java
index e219763..7803152 100644
--- a/user/src/com/google/gwt/precompress/linker/PrecompressLinker.java
+++ b/user/src/com/google/gwt/precompress/linker/PrecompressLinker.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
@@ -130,7 +131,8 @@
ArtifactSet updated = new ArtifactSet(artifacts);
for (EmittedArtifact art : artifacts.find(EmittedArtifact.class)) {
- if (art.isPrivate()) {
+ if (art.getVisibility() != Visibility.Public) {
+ // only compress things that will be served to the client
continue;
}
if (art.getPartialPath().endsWith(".gz")) {
diff --git a/user/src/com/google/gwt/user/linker/rpc/RpcLogLinker.java b/user/src/com/google/gwt/user/linker/rpc/RpcLogLinker.java
index 58c70e7..91c58d5 100644
--- a/user/src/com/google/gwt/user/linker/rpc/RpcLogLinker.java
+++ b/user/src/com/google/gwt/user/linker/rpc/RpcLogLinker.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
@@ -59,7 +60,7 @@
EmittedArtifact art = emitInputStream(logger,
logArt.getContents(logger), logArt.getQualifiedSourceName() + "-"
+ policyStrongName + ".rpc.log");
- art.setPrivate(true);
+ art.setVisibility(Visibility.Private);
toReturn.add(art);
}
}
diff --git a/user/src/com/google/gwt/user/linker/rpc/RpcPolicyManifestLinker.java b/user/src/com/google/gwt/user/linker/rpc/RpcPolicyManifestLinker.java
index 8adb7f4..8c84dd3 100644
--- a/user/src/com/google/gwt/user/linker/rpc/RpcPolicyManifestLinker.java
+++ b/user/src/com/google/gwt/user/linker/rpc/RpcPolicyManifestLinker.java
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.linker.AbstractLinker;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
@@ -72,7 +73,7 @@
ArtifactSet toReturn = new ArtifactSet(artifacts);
SyntheticArtifact manifestArt = emitString(logger,
generateManifest(context), MANIFEST_TXT);
- manifestArt.setPrivate(true);
+ manifestArt.setVisibility(Visibility.LegacyDeploy);
toReturn.add(manifestArt);
return toReturn;
}
diff --git a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
index 94c083d..3da97e0 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
@@ -23,6 +23,7 @@
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.GeneratedResource;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
@@ -762,7 +763,8 @@
os.write(manifestBytes);
GeneratedResource resource = context.commitResource(logger, os);
- resource.setPrivate(true);
+ // TODO: change to Deploy when possible
+ resource.setVisibility(Visibility.LegacyDeploy);
} catch (UnsupportedEncodingException e) {
logger.log(TreeLogger.ERROR,
SerializationPolicyLoader.SERIALIZATION_POLICY_FILE_ENCODING
diff --git a/user/test/com/google/gwt/module/NoDeployTest.gwt.xml b/user/test/com/google/gwt/module/NoDeployTest.gwt.xml
index a6af83f..8b37ca4 100644
--- a/user/test/com/google/gwt/module/NoDeployTest.gwt.xml
+++ b/user/test/com/google/gwt/module/NoDeployTest.gwt.xml
@@ -18,4 +18,7 @@
<generate-with class="com.google.gwt.module.rebind.NoDeployGenerator" >
<when-type-assignable class="com.google.gwt.module.client.NoDeployTest.NoDeploy" />
</generate-with>
+
+ <!-- servlet for test for deployed but not servable files -->
+ <servlet path='/deploy' class='com.google.gwt.module.server.DeployServlet'/>
</module>
diff --git a/user/test/com/google/gwt/module/client/NoDeployTest.java b/user/test/com/google/gwt/module/client/NoDeployTest.java
index d8c9d7f..75f2e4a 100644
--- a/user/test/com/google/gwt/module/client/NoDeployTest.java
+++ b/user/test/com/google/gwt/module/client/NoDeployTest.java
@@ -24,10 +24,8 @@
import com.google.gwt.junit.client.GWTTestCase;
/**
- * Ensure that generated resources in the no-deploy directory aren't in the
- * output. This validates that the
- * {@link com.google.gwt.dev.linker.NoDeployResourcesShim} is being loaded and
- * operating correctly.
+ * Ensure that generated resources are deployed properly according to their
+ * visibility.
*/
public class NoDeployTest extends GWTTestCase {
@@ -37,24 +35,69 @@
private static class NoDeploy {
}
- public static final String TEST_TEXT = "Hello world!";
-
/**
* The maximum amount of time to wait for an RPC response in milliseconds.
*/
- private static final int RESPONSE_DELAY = 5000;
+ private static final int RESPONSE_DELAY = 5000;
+ private static final String DEPLOY_PREFIX = "deploy?com.google.gwt.module.NoDeployTest.JUnit/";
@Override
public String getModuleName() {
return "com.google.gwt.module.NoDeployTest";
}
- public void testDeploy() throws RequestException {
+ /**
+ * Verify that a no-deploy directory in the public path will be deployed.
+ */
+ public void testPublicNoDeployPath() throws RequestException {
+ assertFileIsPublic("no-deploy/", "inPublic.txt");
+ }
+
+ public void testVisibilityDeployHttp() throws RequestException {
+ assertFileIsNotPublic("", "deployFile.txt");
+ }
+
+ public void testVisibilityDeployServer() throws RequestException {
+ assertFileIsDeployed("deployFile.txt");
+ }
+
+ public void testVisibilityLegacyDeployHttp() throws RequestException {
+ assertFileIsNotPublic("", "legacyFile.txt");
+ }
+
+ public void testVisibilityLegacyDeployServer() throws RequestException {
+ assertFileIsDeployed("legacyFile.txt");
+ }
+
+ public void testVisibilityPrivateHttp() throws RequestException {
+ assertFileIsNotPublic("", "privateFile.txt");
+ }
+
+ public void testVisibilityPrivateServer() throws RequestException {
+ assertFileIsNotDeployed("privateFile.txt");
+ }
+
+ public void testVisibilityPublicHttp() throws RequestException {
+ assertFileIsPublic("", "publicFile.txt");
+ }
+
+ public void testVisibilityPublicServer() throws RequestException {
+ assertFileIsNotDeployed("publicFile.txt");
+ }
+
+ /**
+ * Fetch a file from a servlet to make sure it is deployed.
+ * @param path
+ *
+ * @throws RequestException
+ */
+ private void assertFileIsDeployed(final String path)
+ throws RequestException {
GWT.create(NoDeploy.class);
- // Try fetching a file that should exist
+ // Try fetching a file that should be publicly accessible
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- GWT.getHostPageBaseURL() + "publicFile.txt");
+ GWT.getHostPageBaseURL() + DEPLOY_PREFIX + path);
delayTestFinish(RESPONSE_DELAY);
builder.sendRequest("", new RequestCallback() {
@@ -63,28 +106,31 @@
}
public void onResponseReceived(Request request, Response response) {
- assertEquals(TEST_TEXT, response.getText());
+ assertEquals(200, response.getStatusCode());
+ assertEquals(path, response.getText());
finishTest();
}
});
}
- public void testNoDeploy() throws RequestException {
- if (!GWT.isScript()) {
- // Linkers aren't used in hosted-mode
- return;
- }
-
+ /**
+ * Fetch a file from a servlet to make sure it is not deployed.
+ * @param path
+ *
+ * @throws RequestException
+ */
+ private void assertFileIsNotDeployed(final String path)
+ throws RequestException {
GWT.create(NoDeploy.class);
- // Try fetching a file that shouldn't exist
+ // Try fetching a file that should be publicly accessible
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- GWT.getHostPageBaseURL() + "privateFile.txt");
+ GWT.getHostPageBaseURL() + DEPLOY_PREFIX + path);
delayTestFinish(RESPONSE_DELAY);
builder.sendRequest("", new RequestCallback() {
public void onError(Request request, Throwable exception) {
- fail();
+ throw new RuntimeException(exception);
}
public void onResponseReceived(Request request, Response response) {
@@ -95,14 +141,47 @@
}
/**
- * Verify that a no-deploy directory in the public path will be deployed.
+ * Fetch a file from the HTTP server that should not be publicly accessible.
+ *
+ * @param prefix
+ * @param path
+ * @throws RequestException
*/
- public void testNoDeployInPublic() throws RequestException {
+ private void assertFileIsNotPublic(final String prefix, final String path)
+ throws RequestException {
GWT.create(NoDeploy.class);
- // Try fetching a file that shouldn't exist
+ // Try fetching a file that should be publicly accessible
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- GWT.getHostPageBaseURL() + "no-deploy/inPublic.txt");
+ GWT.getHostPageBaseURL() + prefix + path);
+ delayTestFinish(RESPONSE_DELAY);
+ builder.sendRequest("", new RequestCallback() {
+
+ public void onError(Request request, Throwable exception) {
+ throw new RuntimeException(exception);
+ }
+
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(404, response.getStatusCode());
+ finishTest();
+ }
+ });
+ }
+
+ /**
+ * Fetch a file from the HTTP server that should be publicly accessible.
+ *
+ * @param prefix
+ * @param path
+ * @throws RequestException
+ */
+ private void assertFileIsPublic(String prefix, final String path)
+ throws RequestException {
+ GWT.create(NoDeploy.class);
+
+ // Try fetching a file that should be publicly accessible
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ GWT.getHostPageBaseURL() + prefix + path);
delayTestFinish(RESPONSE_DELAY);
builder.sendRequest("", new RequestCallback() {
@@ -111,7 +190,8 @@
}
public void onResponseReceived(Request request, Response response) {
- assertEquals(TEST_TEXT, response.getText());
+ assertEquals(200, response.getStatusCode());
+ assertEquals(path, response.getText().trim());
finishTest();
}
});
diff --git a/user/test/com/google/gwt/module/public/no-deploy/inPublic.txt b/user/test/com/google/gwt/module/public/no-deploy/inPublic.txt
index 6769dd6..a529bb3 100644
--- a/user/test/com/google/gwt/module/public/no-deploy/inPublic.txt
+++ b/user/test/com/google/gwt/module/public/no-deploy/inPublic.txt
@@ -1 +1 @@
-Hello world!
\ No newline at end of file
+inPublic.txt
diff --git a/user/test/com/google/gwt/module/rebind/NoDeployGenerator.java b/user/test/com/google/gwt/module/rebind/NoDeployGenerator.java
index d5b86f1..22850ee 100644
--- a/user/test/com/google/gwt/module/rebind/NoDeployGenerator.java
+++ b/user/test/com/google/gwt/module/rebind/NoDeployGenerator.java
@@ -19,14 +19,15 @@
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.dev.util.Util;
-import com.google.gwt.module.client.NoDeployTest;
import java.io.IOException;
import java.io.OutputStream;
/**
- * Creates two files in the generated output directory.
+ * Creates three files in the generated output directory with different
+ * visibility.
*/
public class NoDeployGenerator extends Generator {
@@ -35,8 +36,10 @@
String typeName) throws UnableToCompleteException {
try {
- createFile(logger, context, "publicFile.txt", false);
- createFile(logger, context, "privateFile.txt", true);
+ createFile(logger, context, "publicFile.txt", Visibility.Public);
+ createFile(logger, context, "deployFile.txt", Visibility.Deploy);
+ createFile(logger, context, "privateFile.txt", Visibility.Private);
+ createFile(logger, context, "legacyFile.txt", Visibility.LegacyDeploy);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Unable to create test file", e);
throw new UnableToCompleteException();
@@ -46,7 +49,7 @@
}
private void createFile(TreeLogger logger, GeneratorContext context,
- String path, boolean isPrivate) throws UnableToCompleteException,
+ String path, Visibility visibility) throws UnableToCompleteException,
IOException {
OutputStream out = context.tryCreateResource(logger, path);
@@ -54,7 +57,7 @@
return;
}
- out.write(Util.getBytes(NoDeployTest.TEST_TEXT));
- context.commitResource(logger, out).setPrivate(isPrivate);
+ out.write(Util.getBytes(path));
+ context.commitResource(logger, out).setVisibility(visibility);
}
}
diff --git a/user/test/com/google/gwt/module/server/DeployServlet.java b/user/test/com/google/gwt/module/server/DeployServlet.java
new file mode 100644
index 0000000..853beb9
--- /dev/null
+++ b/user/test/com/google/gwt/module/server/DeployServlet.java
@@ -0,0 +1,69 @@
+/*
+ * 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.module.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * A servlet that returns files in the WEB-INF/deploy directory.
+ */
+public class DeployServlet extends HttpServlet {
+
+ @Override
+ public void init() throws ServletException {
+ getServletContext().log("DeployServlet initialized");
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws IOException {
+ String path = req.getQueryString();
+ ServletContext context = getServletContext();
+ context.log("DeployServlet get: " + path);
+ InputStream istr = null;
+ ServletOutputStream ostr = null;
+ try {
+ istr = context.getResourceAsStream("/WEB-INF/deploy/" + path);
+ if (istr == null) {
+ res.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ res.setStatus(HttpServletResponse.SC_OK);
+ res.setContentType("text/plain");
+ ostr = res.getOutputStream();
+ byte[] buf = new byte[4096];
+ int n;
+ while ((n = istr.read(buf)) >= 0) {
+ ostr.write(buf, 0, n);
+ }
+ } finally {
+ if (istr != null) {
+ istr.close();
+ }
+ if (ostr != null) {
+ ostr.flush();
+ }
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/precompress/linker/PrecompressLinkerTest.java b/user/test/com/google/gwt/precompress/linker/PrecompressLinkerTest.java
index ddd9a53..6d58363 100644
--- a/user/test/com/google/gwt/precompress/linker/PrecompressLinkerTest.java
+++ b/user/test/com/google/gwt/precompress/linker/PrecompressLinkerTest.java
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
@@ -180,7 +181,7 @@
private static SyntheticArtifact emitPrivate(String string, String contents) {
SyntheticArtifact art = emit(string, contents);
- art.setPrivate(true);
+ art.setVisibility(Visibility.Private);
return art;
}