Author: lindner
Date: Mon Dec 7 18:58:24 2009
New Revision: 888082
URL: http://svn.apache.org/viewvc?rev=888082&view=rev
Log:
SHINDIG-1227 | Patch from chirag shah | Allow JavaScript features required by a
gadget to be externalized on demand
Modified:
incubator/shindig/trunk/java/common/conf/shindig.properties
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
Modified: incubator/shindig/trunk/java/common/conf/shindig.properties
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/conf/shindig.properties?rev=888082&r1=888081&r2=888082&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/conf/shindig.properties (original)
+++ incubator/shindig/trunk/java/common/conf/shindig.properties Mon Dec 7
18:58:24 2009
@@ -63,6 +63,10 @@
#shindig.gadget-rewrite.default-forced-libs=core:core.io
shindig.gadget-rewrite.default-forced-libs=
+#
+# Allow supported JavaScript features required by a gadget to be externalized
on demand
+shindig.gadget-rewrite.externalize-feature-libs=false
+
# Configuration for image rewriter
shindig.image-rewrite.max-inmem-bytes = 1048576
shindig.image-rewrite.max-palette-size = 256
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=888082&r1=888081&r2=888082&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
Mon Dec 7 18:58:24 2009
@@ -41,6 +41,7 @@
import org.apache.shindig.gadgets.spec.ModulePrefs;
import org.apache.shindig.gadgets.spec.UserPref;
import org.apache.shindig.gadgets.spec.View;
+import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -99,6 +100,8 @@
protected final RpcServiceLookup rpcServiceLookup;
protected Set<String> defaultExternLibs = ImmutableSet.of();
+ protected Boolean externalizeFeatures = false;
+
/**
* @param messageBundleFactory Used for injecting message bundles into
gadget output.
*/
@@ -117,11 +120,16 @@
@Inject
public void
setDefaultForcedLibs(@Named("shindig.gadget-rewrite.default-forced-libs")String
forcedLibs) {
- if (forcedLibs != null && forcedLibs.length() > 0) {
+ if (StringUtils.isNotBlank(forcedLibs)) {
defaultExternLibs =
ImmutableSortedSet.copyOf(Arrays.asList(forcedLibs.split(":")));
}
}
+ @Inject(optional = true)
+ public void
setExternalizeFeatureLibs(@Named("shindig.gadget-rewrite.externalize-feature-libs")Boolean
externalizeFeatures) {
+ this.externalizeFeatures = externalizeFeatures;
+ }
+
public void rewrite(Gadget gadget, MutableContent mutableContent) throws
RewritingException {
// Don't touch sanitized gadgets.
if (gadget.sanitizeOutput()) {
@@ -215,40 +223,37 @@
// TODO: If there isn't any js in the document, we can skip this.
Unfortunately, that means
// both script tags (easy to detect) and event handlers (much more
complex).
GadgetContext context = gadget.getContext();
- String externParam = context.getParameter("libs");
- // List of extern libraries we need
- Set<String> extern;
+ // Set of extern libraries requested by the container
+ Set<String> externForcedLibs = defaultExternLibs;
// gather the libraries we'll need to generate the extern libs
- if (externParam == null || externParam.length() == 0) {
- // Don't bother making a mutable copy if the list is empty
- extern = (defaultExternLibs.isEmpty()) ? defaultExternLibs :
- Sets.newTreeSet(defaultExternLibs);
- } else {
- extern = Sets.newTreeSet(Arrays.asList(externParam.split(":")));
+ String externParam = context.getParameter("libs");
+ if (StringUtils.isNotBlank(externParam)) {
+ externForcedLibs =
Sets.newTreeSet(Arrays.asList(externParam.split(":")));
}
-
- if (!extern.isEmpty()) {
- String jsUrl = urlGenerator.getBundledJsUrl(extern, context);
+
+ if (!externForcedLibs.isEmpty()) {
+ String jsUrl = urlGenerator.getBundledJsUrl(externForcedLibs, context);
Element libsTag = headTag.getOwnerDocument().createElement("script");
libsTag.setAttribute("src", jsUrl);
headTag.appendChild(libsTag);
}
-
+
List<String> unsupported = Lists.newLinkedList();
- List<FeatureResource> externResources =
- featureRegistry.getFeatureResources(gadget.getContext(), extern,
unsupported);
+
+ List<FeatureResource> externForcedResources =
+ featureRegistry.getFeatureResources(context, externForcedLibs,
unsupported);
if (!unsupported.isEmpty()) {
LOG.info("Unknown feature(s) in extern &libs=: " +
unsupported.toString());
unsupported.clear();
}
-
+
// Get all resources requested by the gadget's requires/optional features.
Map<String, Feature> featureMap =
gadget.getSpec().getModulePrefs().getFeatures();
List<String> gadgetFeatureKeys =
Lists.newArrayList(gadget.getDirectFeatureDeps());
List<FeatureResource> gadgetResources =
- featureRegistry.getFeatureResources(gadget.getContext(),
gadgetFeatureKeys, unsupported);
+ featureRegistry.getFeatureResources(context, gadgetFeatureKeys,
unsupported);
if (!unsupported.isEmpty()) {
List<String> requiredUnsupported = Lists.newLinkedList();
for (String notThere : unsupported) {
@@ -260,13 +265,33 @@
if (!requiredUnsupported.isEmpty()) {
throw new UnsupportedFeatureException(requiredUnsupported.toString());
}
+ }
+
+ // Inline or externalize the gadgetFeatureKeys
+ List<FeatureResource> inlineResources = Lists.newArrayList();
+ List<String> allRequested = Lists.newArrayList(gadgetFeatureKeys);
+
+ if (externalizeFeatures) {
+ Set<String> externGadgetLibs =
Sets.newTreeSet(featureRegistry.getFeatures(gadgetFeatureKeys));
+ externGadgetLibs.removeAll(externForcedLibs);
+
+ if (!externGadgetLibs.isEmpty()) {
+ String jsUrl = urlGenerator.getBundledJsUrl(externGadgetLibs, context);
+ Element libsTag = headTag.getOwnerDocument().createElement("script");
+ libsTag.setAttribute("src", jsUrl);
+ headTag.appendChild(libsTag);
+ }
+ } else {
+ inlineResources.addAll(gadgetResources);
}
-
+
// Calculate inlineResources as all resources that are needed by the
gadget to
// render, minus all those included through externResources.
// TODO: profile and if needed, optimize this a bit.
- List<FeatureResource> inlineResources =
Lists.newArrayList(gadgetResources);
- inlineResources.removeAll(externResources);
+ if (!externForcedLibs.isEmpty()) {
+ allRequested.addAll(externForcedLibs);
+ inlineResources.removeAll(externForcedResources);
+ }
// Precalculate the maximum length in order to avoid excessive garbage
generation.
int size = 0;
@@ -280,8 +305,6 @@
}
}
- List<String> allRequested = Lists.newArrayList(gadgetFeatureKeys);
- allRequested.addAll(extern);
String libraryConfig =
getLibraryConfig(gadget, featureRegistry.getFeatures(allRequested));
@@ -348,8 +371,7 @@
}
addHasFeatureConfig(gadget, config);
- addOsapiSystemListMethodsConfig(gadget.getContext().getContainer(),
config,
- gadget.getContext().getHost());
+ addOsapiSystemListMethodsConfig(context.getContainer(), config,
context.getHost());
addSecurityTokenConfig(context, config);
return "gadgets.config.init(" + JsonSerializer.serialize(config) + ");\n";
}