Author: etnu
Date: Sun Jun 1 06:20:34 2008
New Revision: 662212
URL: http://svn.apache.org/viewvc?rev=662212&view=rev
Log:
Cleaned up GadgetFeature mechanism by eliminating unused code and simplifying
the model.
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/UnsupportedFeatureException.java
Removed:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureFactory.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibraryFeatureFactory.java
Modified:
incubator/shindig/trunk/java/gadgets/pom.xml
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeature.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/UrlGenerator.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetFeatureRegistryTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsFeatureLoaderTest.java
Modified: incubator/shindig/trunk/java/gadgets/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.xml Sun Jun 1 06:20:34 2008
@@ -135,6 +135,10 @@
<artifactId>core</artifactId>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.google-collections</groupId>
+ <artifactId>google-collect</artifactId>
+ </dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<artifactId>guice</artifactId>
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
Sun Jun 1 06:20:34 2008
@@ -22,8 +22,8 @@
import org.apache.shindig.gadgets.spec.MessageBundle;
import org.apache.shindig.gadgets.spec.Preload;
+import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
@@ -52,8 +52,8 @@
return messageBundle;
}
- private final List<JsLibrary> jsLibraries;
- public List<JsLibrary> getJsLibraries() {
+ private final Collection<JsLibrary> jsLibraries;
+ public Collection<JsLibrary> getJsLibraries() {
return jsLibraries;
}
@@ -63,14 +63,8 @@
return preloads;
}
- /**
- * @param context
- * @param spec
- * @param messageBundle
- * @param jsLibraries
- */
public Gadget(GadgetContext context, GadgetSpec spec,
- MessageBundle messageBundle, List<JsLibrary> jsLibraries) {
+ MessageBundle messageBundle, Collection<JsLibrary> jsLibraries) {
this.context = context;
this.spec = spec;
this.messageBundle = messageBundle;
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeature.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeature.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeature.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeature.java
Sun Jun 1 06:20:34 2008
@@ -17,65 +17,119 @@
*/
package org.apache.shindig.gadgets;
+import com.google.common.collect.Maps;
+
+import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
-
+import java.util.Map;
/**
- * Base interface providing Gadget Server's primary extensibility mechanism.
- *
- * During processing of a [EMAIL PROTECTED] Gadget}, a tree of [EMAIL
PROTECTED] GadgetFeature}
- * objects is constructed based on the <Require> and <Optional>
- * tags declared in its [EMAIL PROTECTED] GadgetSpec}, and the dependencies
registered
- * for these in [EMAIL PROTECTED] GadgetFeatureRegistry}.
+ * Represents a feature available to gadget authors.
*
- * Each [EMAIL PROTECTED] GadgetFeature}'s process method is called -
potentially
- * in parallel with many others whose dependencies have also been satisfied.
+ * Features are registered declaratively in feature.xml files and loaded at
+ * server startup time.
*
- * To extend the Gadget Server's feature set, simply implement this interface
- * and register your class with [EMAIL PROTECTED] GadgetFeatureRegistry},
indicating
- * which other [EMAIL PROTECTED] GadgetFeature} features are needed before
yours can
- * operate successfully.
- *
- * Each feature <i>must</i> be instantiable by a no-argument constructor,
- * and will <i>always</i> be instantiated this way. As such, it is recommended
- * not to define a constructor for a feature at all.
+ * Some features may require server-side functionality. These features are
+ * triggered at different points throughout the code.
*/
-public abstract class GadgetFeature {
+public class GadgetFeature {
+
+ private final String name;
+ private final Map<RenderingContext, Map<String, List<JsLibrary>>> libraries;
+ private final Collection<String> dependencies;
/**
- * Performs processing required to handle this feature.
- * By default this does nothing.
- *
- * Only invoked if isJsOnly is false.
- *
- * @param gadget
- * @param context
- * @throws GadgetException
+ * @return The name of this feature.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return All dependencies of this feature.
*/
- @SuppressWarnings("unused")
- public void process(Gadget gadget, GadgetContext context)
- throws GadgetException {
- // By default we do nothing.
+ public Collection<String> getDependencies() {
+ return dependencies;
}
/**
- * This is used by various consumers to retrieve all javascript libraries
- * that this feature uses without necessarily processing them.
- * This is primarily used by features that simply pass-through libraries.
+ * Adds a new dependency to the graph.
+ */
+ public void addDependency(String dependency) {
+ synchronized (dependencies) {
+ dependencies.add(dependency);
+ }
+ }
+
+ /**
+ * Adds multiple new dependencies to the graph.
+ */
+ public void addDependencies(Collection<String> dependencies) {
+ synchronized (this.dependencies) {
+ this.dependencies.addAll(dependencies);
+ }
+ }
+
+ /**
+ * Provides javavscript libraries needed to satisfy the requirements for this
+ * feature.
*
- * @param context
- * @return A list of all libraries needed by this feature for the request.
+ * @param context The context in which the gadget is being used.
+ * @param container The container to get libraries for.
+ * @return The collection of libraries needed for the provided context.
*/
- public List<JsLibrary> getJsLibraries(GadgetContext context) {
- return Collections.emptyList();
+ public List<JsLibrary> getJsLibraries(RenderingContext context, String
container) {
+ List<JsLibrary> libs = null;
+
+ if (context == null) {
+ // For this special case we return all JS libraries in a single list.
+ // This is usually only used for debugging or at startup, so it's ok
+ // that we're creating new objects every time.
+ libs = new LinkedList<JsLibrary>();
+ for (Map<String, List<JsLibrary>> ctx : libraries.values()) {
+ for (List<JsLibrary> lib : ctx.values()) {
+ libs.addAll(lib);
+ }
+ }
+ } else {
+ Map<String, List<JsLibrary>> contextLibs = libraries.get(context);
+ if (contextLibs != null) {
+ libs = contextLibs.get(container);
+ if (libs == null) {
+ // Try default.
+ libs = contextLibs.get(ContainerConfig.DEFAULT_CONTAINER);
+ }
+ }
+ }
+
+ if (libs == null) {
+ return Collections.emptyList();
+ }
+ return libs;
}
/**
- * @return True if this feature only exists to satisfy javascript
dependencies
- * if this is true, there is no need to run prepare or process, and it
- * can be run serially.
+ * Simplified ctor that registers a set of libraries for all contexts and
+ * the default container. Used for testing.
*/
- public boolean isJsOnly() {
- return false;
+ GadgetFeature(String name, List<JsLibrary> libraries,
+ Collection<String> dependencies) {
+ this.name = name;
+ this.libraries = Maps.newEnumMap(RenderingContext.class);
+ for (RenderingContext context : RenderingContext.values()) {
+ Map<String, List<JsLibrary>> container = Maps.newHashMap();
+ container.put(ContainerConfig.DEFAULT_CONTAINER, libraries);
+ this.libraries.put(context, container);
+ }
+ this.dependencies = dependencies;
+ }
+
+ public GadgetFeature(String name,
+ Map<RenderingContext, Map<String, List<JsLibrary>>> libraries,
+ Collection<String> dependencies) {
+ this.name = name;
+ this.libraries = libraries;
+ this.dependencies = dependencies;
}
-}
+}
\ No newline at end of file
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
Sun Jun 1 06:20:34 2008
@@ -19,15 +19,16 @@
import org.apache.shindig.gadgets.http.HttpFetcher;
+import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.name.Named;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.logging.Logger;
/**
@@ -39,12 +40,12 @@
* registry.register("my-feature", null, new MyFeatureFactory());
*/
public class GadgetFeatureRegistry {
- private final Map<String, Entry> features;
- private final Map<String, Entry> core;
+ private final Map<String, GadgetFeature> features;
+ private final Map<String, GadgetFeature> core;
// Caches the transitive dependencies to enable faster lookups.
- private final Map<Set<String>, Set<Entry>> transitiveDeps
- = new HashMap<Set<String>, Set<Entry>>();
+ private final Map<Collection<String>, Collection<GadgetFeature>> cache
+ = Maps.newHashMap();
private boolean graphComplete = false;
@@ -61,8 +62,8 @@
@Inject
public GadgetFeatureRegistry(@Named("features.default") String featureFiles,
HttpFetcher httpFetcher) throws GadgetException {
- features = new HashMap<String, Entry>();
- core = new HashMap<String, Entry>();
+ features = new HashMap<String, GadgetFeature>();
+ core = new HashMap<String, GadgetFeature>();
if (featureFiles != null) {
JsFeatureLoader loader = new JsFeatureLoader(httpFetcher);
loader.loadFeatures(featureFiles, this);
@@ -70,185 +71,96 @@
}
/**
- * Register a [EMAIL PROTECTED] GadgetFeature} identified by [EMAIL
PROTECTED] name} which
- * depends on other [EMAIL PROTECTED] GadgetFeature}s listed in [EMAIL
PROTECTED] deps}
- * completing before this one does.
+ * Register a [EMAIL PROTECTED] GadgetFeature}.
*
- * Names are freeform, but it is strongly suggested that they are
- * namespaced, optionally (yet often usefully) in Java package-notation ie.
- * 'org.example.FooFeature'
- *
- * May never be invoked after calling getIncludedFeatures.
- *
- * @param name Name of the feature to register, ideally using the conventions
- * described
- * @param deps List of strings indicating features on which [EMAIL
PROTECTED] feature}
- * depends to operate correctly, which need to process the [EMAIL
PROTECTED] Gadget}
- * before it does
- * @param feature Class implementing the feature
+ * @param feature Class implementing the feature.
*/
- public Entry register(String name, List<String> deps,
- GadgetFeatureFactory feature) {
+ public void register(GadgetFeature feature) {
if (graphComplete) {
- throw new IllegalStateException("registerFeatures should never be " +
- "invoked after calling getIncludedFeatures");
+ throw new IllegalStateException("register should never be " +
+ "invoked after calling getLibraries");
}
- logger.info("Registering feature: " + name + " with deps " + deps);
- Entry entry = new Entry(name, deps, feature, this);
- if (isCore(entry)) {
- core.put(name, entry);
- for (Entry e : features.values()) {
- e.deps.add(name);
+ logger.info("Registering feature: " + feature.getName());
+ if (isCore(feature)) {
+ core.put(feature.getName(), feature);
+ for (GadgetFeature feat : features.values()) {
+ feat.addDependency(feature.getName());
}
} else {
- entry.deps.addAll(core.keySet());
+ feature.addDependencies(core.keySet());
}
- features.put(name, entry);
- return entry;
+ features.put(feature.getName(), feature);
}
/**
- * @param entry
* @return True if the entry is "core" (a dependency of all other features)
*/
- private boolean isCore(Entry entry) {
- return entry.name.startsWith("core");
- }
+ private boolean isCore(GadgetFeature feature) {
+ return feature.getName().startsWith("core");
+ }
/**
* @return All registered features.
*/
- public Map<String, Entry> getAllFeatures() {
- return Collections.unmodifiableMap(features);
+ public Collection<GadgetFeature> getAllFeatures() {
+ return Collections.unmodifiableCollection(features.values());
}
/**
- * Attempts to retrieve all the [EMAIL PROTECTED] GadgetFeature} classes
specified
- * in the [EMAIL PROTECTED] needed} list. Those that are found are returned
in
- * [EMAIL PROTECTED] resultsFound}, while the names of those that are
missing are
- * populated in [EMAIL PROTECTED] resultsMissing}.
- * @param needed Set of names identifying features to retrieve
- * @param resultsFound Set of feature entries found
- * @param resultsMissing Set of feature identifiers that could not be found
- * @return True if all features were retrieved
- */
- public boolean getIncludedFeatures(Set<String> needed,
- Set<Entry> resultsFound,
- Set<String> resultsMissing) {
+ * @return All [EMAIL PROTECTED] GadgetFeature} objects necessary for [EMAIL
PROTECTED] needed} in
+ * graph-dependent order.
+ */
+ public Collection<GadgetFeature> getFeatures(Collection<String> needed) {
+ return getFeatures(needed, null);
+ }
+
+ /**
+ * @param needed All features requested by the gadget.
+ * @param unsupported Populated with any unsupported features.
+ * @return All [EMAIL PROTECTED] GadgetFeature} objects necessary for [EMAIL
PROTECTED] needed} in
+ * graph-dependent order.
+ */
+ public Collection<GadgetFeature> getFeatures(Collection<String> needed,
+ Collection<String> unsupported)
{
graphComplete = true;
if (needed.isEmpty()) {
- // Shortcut for gadgets that don't have any explicit dependencies.
- resultsFound.addAll(core.values());
- return true;
+ needed = core.keySet();
}
// We use the cache only for situations where all needed are available.
// if any are missing, the result won't be cached.
- Set<Entry> cache = transitiveDeps.get(needed);
- if (cache != null) {
- resultsFound.addAll(cache);
- return true;
- } else {
- resultsFound.addAll(core.values());
- for (String featureName : needed) {
- Entry entry = features.get(featureName);
- if (entry == null) {
- resultsMissing.add(featureName);
- } else {
- addEntryToSet(resultsFound, entry);
+ Collection<GadgetFeature> libCache = cache.get(needed);
+ if (libCache != null) {
+ return libCache;
+ }
+ List<GadgetFeature> ret = new LinkedList<GadgetFeature>();
+ populateDependencies(needed, ret);
+ // Fill in anything that was optional but missing. These won't be cached.
+ if (unsupported != null) {
+ for (String feature : needed) {
+ if (!features.containsKey(feature)) {
+ unsupported.add(feature);
}
}
-
- if (resultsMissing.isEmpty()) {
- // Store to cache
- transitiveDeps.put(
- Collections.unmodifiableSet(new HashSet<String>(needed)),
- Collections.unmodifiableSet(new HashSet<Entry>(resultsFound)));
- return true;
- }
}
- return false;
- }
-
- /**
- * Recursively add all dependencies.
- * @param results
- * @param entry
- */
- private void addEntryToSet(Set<Entry> results, Entry entry) {
- for (String dep : entry.deps) {
- addEntryToSet(results, features.get(dep));
+ if (unsupported == null || unsupported.size() == 0) {
+ cache.put(needed, Collections.unmodifiableList(ret));
}
- results.add(entry);
+ return ret;
}
/**
- * Fetches an entry by name.
- * @param name
- * @return The entry, or null if it does not exist.
+ * Recursively populates [EMAIL PROTECTED] libraries} with libraries from
dependent
+ * features. This ensures that features will always be loaded in the order
+ * that they are declared.
*/
- Entry getEntry(String name) {
- return features.get(name);
- }
-
- /**
- * Ties together a [EMAIL PROTECTED] GadgetFeature} with its name and
dependencies.
- */
- public static class Entry {
- private final String name;
- private final Set<String> deps;
- private final Set<String> readDeps;
- private final GadgetFeatureFactory feature;
-
- private Entry(String name,
- List<String> deps,
- GadgetFeatureFactory feature,
- GadgetFeatureRegistry registry)
- throws IllegalStateException {
- this.name = name;
- this.deps = new HashSet<String>();
- this.readDeps = Collections.unmodifiableSet(this.deps);
- if (deps != null) {
- this.deps.addAll(deps);
- }
- this.feature = feature;
- }
-
- /**
- * @return Name identifier
- */
- public String getName() {
- return name;
- }
-
- /**
- * @return List of identifiers on which feature depends
- */
- public Set<String> getDependencies() {
- return readDeps;
- }
-
- @Override
- public boolean equals(Object rhs) {
- if (rhs == this) {
- return true;
- }
- if (rhs instanceof Entry) {
- Entry entry = (Entry)rhs;
- return name.equals(entry.name);
+ private void populateDependencies(Collection<String> needed,
+ List<GadgetFeature> deps) {
+ for (String feature : needed) {
+ GadgetFeature feat = features.get(feature);
+ if (feat != null && !deps.contains(feat)) {
+ populateDependencies(feat.getDependencies(), deps);
+ deps.add(feat);
}
- return false;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- /**
- * @return Class implementing the feature
- */
- public GadgetFeatureFactory getFeature() {
- return feature;
}
}
}
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
Sun Jun 1 06:20:34 2008
@@ -17,8 +17,6 @@
*/
package org.apache.shindig.gadgets;
-import com.google.inject.Inject;
-
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
@@ -29,10 +27,11 @@
import org.apache.shindig.gadgets.spec.MessageBundle;
import org.apache.shindig.gadgets.spec.Preload;
-import java.util.HashMap;
+import com.google.inject.Inject;
+
+import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -134,48 +133,18 @@
substituter, spec, context.getUserPrefs());
spec = spec.substitute(substituter, !context.getIgnoreCache());
- Set<GadgetFeatureRegistry.Entry> features = getFeatures(spec);
-
- List<JsLibrary> jsLibraries = new LinkedList<JsLibrary>();
- Set<String> done = new HashSet<String>(features.size());
-
- Map<GadgetFeatureRegistry.Entry, GadgetFeature> tasks
- = new HashMap<GadgetFeatureRegistry.Entry, GadgetFeature>();
-
- do {
- for (GadgetFeatureRegistry.Entry entry : features) {
- if (!done.contains(entry.getName())
- && done.containsAll(entry.getDependencies())) {
- GadgetFeature feature = entry.getFeature().create();
- jsLibraries.addAll(feature.getJsLibraries(context));
- if (!feature.isJsOnly()) {
- tasks.put(entry, feature);
- }
- done.add(entry.getName());
- }
- }
- } while (done.size() != features.size());
-
+ Collection<JsLibrary> jsLibraries = getLibraries(spec, context);
Gadget gadget = new Gadget(context, spec, bundle, jsLibraries);
-
- runTasks(gadget, tasks);
+ startPreloads(gadget);
return gadget;
}
/**
- * Processes tasks required for this gadget. Attempts to run as many tasks
- * in parallel as possible.
+ * Begins processing of preloaded data.
*
- * @param gadget
- * @param tasks
- * @throws GadgetException
+ * Preloads are processed in parallel.
*/
- private void runTasks(Gadget gadget,
- Map<GadgetFeatureRegistry.Entry, GadgetFeature> tasks)
- throws GadgetException {
-
- // Immediately enqueue all the preloads. We don't block on preloads because
- // we want them to run in parallel
+ private void startPreloads(Gadget gadget) throws GadgetException {
RenderingContext renderContext = gadget.getContext().getRenderingContext();
if (RenderingContext.GADGET.equals(renderContext)) {
CompletionService<HttpResponse> preloadProcessor
@@ -193,127 +162,31 @@
}
}
}
-
- // TODO: This seems pointless if nothing is actually using it.
- CompletionService<GadgetException> featureProcessor
- = new ExecutorCompletionService<GadgetException>(executor);
- // FeatureTask is OK has a hash key because we want actual instances, not
- // names.
- GadgetContext context = gadget.getContext();
- Set<FeatureTask> pending = new HashSet<FeatureTask>();
- for (Map.Entry<GadgetFeatureRegistry.Entry, GadgetFeature> entry
- : tasks.entrySet()) {
- FeatureTask task = new FeatureTask(entry.getKey().getName(),
- entry.getValue(), gadget, context, entry.getKey().getDependencies());
- pending.add(task);
- }
-
- Set<FeatureTask> running = new HashSet<FeatureTask>();
- Set<String> done = new HashSet<String>();
- do {
- for (FeatureTask task : pending) {
- if (task.depsDone(done)) {
- pending.remove(task);
- running.add(task);
- featureProcessor.submit(task);
- }
- }
-
- if (!running.isEmpty()) {
- try {
- Future<GadgetException> future;
- while ((future = featureProcessor.take()) != null) {
- GadgetException e = future.get();
- if (future.get() != null) {
- throw future.get();
- }
- }
- } catch (Exception e) {
- throw new GadgetException(
- GadgetException.Code.INTERNAL_SERVER_ERROR, e);
- }
- }
-
- for (FeatureTask task : running) {
- if (task.isDone()) {
- done.add(task.getName());
- running.remove(task);
- }
- }
- } while (!pending.isEmpty() || !running.isEmpty());
}
/**
* Constructs a set of dependencies from the given spec.
- *
- * @return The dependencies that are requested in the spec and are also
- * supported by this server.
- * @throws GadgetException If the spec requires a feature that is not
- * supported by this server.
*/
- private Set<GadgetFeatureRegistry.Entry> getFeatures(GadgetSpec spec)
- throws GadgetException {
+ private Collection<JsLibrary> getLibraries(GadgetSpec spec,
+ GadgetContext context) throws GadgetException {
// Check all required features for the gadget.
Map<String, Feature> features = spec.getModulePrefs().getFeatures();
-
- Set<GadgetFeatureRegistry.Entry> dependencies
- = new HashSet<GadgetFeatureRegistry.Entry>(features.size());
+ Set<String> needed = features.keySet();
Set<String> unsupported = new HashSet<String>();
- registry.getIncludedFeatures(features.keySet(), dependencies, unsupported);
-
- for (String missing : unsupported) {
- Feature feature = features.get(missing);
- if (feature.getRequired()) {
- throw new GadgetException(GadgetException.Code.UNSUPPORTED_FEATURE,
- missing);
+ Collection<GadgetFeature> feats = registry.getFeatures(needed,
unsupported);
+ if (unsupported.size() > 0) {
+ for (String missing : unsupported) {
+ if (features.get(missing).getRequired()) {
+ throw new UnsupportedFeatureException(missing);
+ }
}
}
-
- return dependencies;
- }
-}
-
-/**
- * Provides a task for processing non-trival features (anything that is not
- * js only)
- */
-class FeatureTask implements Callable<GadgetException> {
- private final Set<String> dependencies;
- public boolean depsDone(Set<String> deps) {
- return deps.containsAll(dependencies);
- }
- private final String name;
- public String getName() {
- return name;
- }
- private final GadgetFeature feature;
- private final Gadget gadget;
- private final GadgetContext context;
-
- private boolean done = false;
- public boolean isDone() {
- return done;
- }
-
- public GadgetException call() {
- try {
- feature.process(gadget, context);
- done = true;
- return null;
- } catch (GadgetException e) {
- return e;
- } catch (Exception e) {
- return new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR,
e);
+ Collection<JsLibrary> libraries = new LinkedList<JsLibrary>();
+ for (GadgetFeature feature : feats) {
+ libraries.addAll(feature.getJsLibraries(
+ context.getRenderingContext(), context.getContainer()));
}
- }
-
- public FeatureTask(String name, GadgetFeature feature, Gadget gadget,
- GadgetContext context, Set<String> dependencies) {
- this.name = name;
- this.feature = feature;
- this.gadget = gadget;
- this.context = context;
- this.dependencies = dependencies;
+ return libraries;
}
}
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
Sun Jun 1 06:20:34 2008
@@ -66,7 +66,8 @@
* be loaded. If res://*.txt is passed, we will look for named resources
* in the text file. If path is prefixed with res://, the file
* is treated as a resource, and all references are assumed to be
- * resources as well. Multiple locations may be specified by separating
them with a comma.
+ * resources as well. Multiple locations may be specified by separating
+ * them with a comma.
* @throws GadgetException If any of the files can't be read.
*/
public void loadFeatures(String path, GadgetFeatureRegistry registry)
@@ -94,9 +95,9 @@
}
for (ParsedFeature feature : features) {
- JsLibraryFeatureFactory factory
- = new JsLibraryFeatureFactory(feature.libraries);
- registry.register(feature.name, feature.deps, factory);
+ GadgetFeature gadgetFeature
+ = new GadgetFeature(feature.name, feature.libraries, feature.deps);
+ registry.register(gadgetFeature);
}
}
@@ -107,13 +108,13 @@
* @param xml
* @return The parsed feature.
*/
- public GadgetFeatureRegistry.Entry loadFeature(
- GadgetFeatureRegistry registry, String xml) throws GadgetException {
- ParsedFeature feature = parse(xml, "", false);
-
- JsLibraryFeatureFactory factory
- = new JsLibraryFeatureFactory(feature.libraries);
- return registry.register(feature.name, null, factory);
+ public GadgetFeature loadFeature(GadgetFeatureRegistry registry, String xml)
+ throws GadgetException {
+ ParsedFeature parsed = parse(xml, "", false);
+ GadgetFeature feature
+ = new GadgetFeature(parsed.name, parsed.libraries, parsed.deps);
+ registry.register(feature);
+ return feature;
}
/**
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
Sun Jun 1 06:20:34 2008
@@ -19,8 +19,8 @@
import org.apache.shindig.common.util.ResourceLoader;
import org.apache.shindig.gadgets.http.HttpFetcher;
-import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
import java.io.File;
import java.io.IOException;
@@ -32,8 +32,6 @@
/**
* Represents a javascript library, either as an external resource (url)
* or as an inline script.
- * TODO: pull in url type libraries and treat them the same as file, resource,
- * or inline scripts.
*/
public final class JsLibrary {
private final Type type;
@@ -116,7 +114,7 @@
* kept as a url reference, otherwise the file will be fetched and
treated
* as a FILE type.
* @return The newly created library.
- * @throws GadgetException
+ * @throws GadgetException
*/
public static JsLibrary create(Type type, String content, String feature,
HttpFetcher fetcher) throws GadgetException {
@@ -172,7 +170,7 @@
* @param url
* @param fetcher
* @return The contents of the JS file, or null if it can't be fetched.
- * @throws GadgetException
+ * @throws GadgetException
*/
private static String loadDataFromUrl(String url,
HttpFetcher fetcher) throws GadgetException {
@@ -241,6 +239,23 @@
}
}
+ @Override
+ public int hashCode() {
+ return content.hashCode() + type.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == this) {
+ return true;
+ }
+ if (rhs instanceof JsLibrary) {
+ JsLibrary lib = (JsLibrary)rhs;
+ return content.equals(lib.content) && type.equals(lib.type);
+ }
+ return false;
+ }
+
/**
* @param feature
* @param type
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/UnsupportedFeatureException.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/UnsupportedFeatureException.java?rev=662212&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/UnsupportedFeatureException.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/UnsupportedFeatureException.java
Sun Jun 1 06:20:34 2008
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets;
+
+
+/**
+ * Thrown whenever GadgetFeatureRegistry gets a request for a feature that is
+ * not registered.
+ */
+public class UnsupportedFeatureException extends GadgetException {
+ public UnsupportedFeatureException(String name) {
+ super(GadgetException.Code.UNSUPPORTED_FEATURE,
+ "Unsupported feature: " + name);
+ }
+}
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetRenderingTask.java
Sun Jun 1 06:20:34 2008
@@ -25,6 +25,7 @@
import org.apache.shindig.gadgets.GadgetContentFilter;
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetFeature;
import org.apache.shindig.gadgets.GadgetFeatureRegistry;
import org.apache.shindig.gadgets.GadgetServer;
import org.apache.shindig.gadgets.JsLibrary;
@@ -47,6 +48,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -246,11 +248,8 @@
// Transitive dependencies must be added. This will always include core
// so is therefore always "safe".
- Set<GadgetFeatureRegistry.Entry> deps
- = new HashSet<GadgetFeatureRegistry.Entry>();
- Set<String> dummy = new HashSet<String>();
- registry.getIncludedFeatures(libs, deps, dummy);
- for (GadgetFeatureRegistry.Entry dep : deps) {
+ Collection<GadgetFeature> features = registry.getFeatures(libs);
+ for (GadgetFeature dep : features) {
libs.add(dep.getName());
}
}
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
Sun Jun 1 06:20:34 2008
@@ -17,18 +17,18 @@
*/
package org.apache.shindig.gadgets.servlet;
-import org.apache.shindig.common.SecurityTokenDecoder;
import org.apache.shindig.common.servlet.InjectedServlet;
-import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.ContainerConfig;
import org.apache.shindig.gadgets.GadgetFeature;
-import org.apache.shindig.gadgets.GadgetFeatureFactory;
import org.apache.shindig.gadgets.GadgetFeatureRegistry;
import org.apache.shindig.gadgets.JsLibrary;
+import org.apache.shindig.gadgets.RenderingContext;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
@@ -47,12 +47,6 @@
this.registry = registry;
}
- private SecurityTokenDecoder tokenDecoder;
- @Inject
- public void setTokenDecoder(final SecurityTokenDecoder tokenDecoder) {
- this.tokenDecoder = tokenDecoder;
- }
-
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
@@ -83,36 +77,32 @@
needed.add(resourceName);
}
- Set<GadgetFeatureRegistry.Entry> found
- = new HashSet<GadgetFeatureRegistry.Entry>();
- Set<String> dummy = new HashSet<String>();
+ String debugStr = req.getParameter("debug");
+ String container = req.getParameter("container");
+ String containerStr = req.getParameter("c");
+
+ boolean debug = "1".equals(debugStr);
+ if (container == null) {
+ container = ContainerConfig.DEFAULT_CONTAINER;
+ }
+ RenderingContext context = "1".equals(containerStr) ?
+ RenderingContext.CONTAINER : RenderingContext.GADGET;
- registry.getIncludedFeatures(needed, found, dummy);
+ Collection<GadgetFeature> features = registry.getFeatures(needed);
StringBuilder jsData = new StringBuilder();
-
- // Probably incorrect to be using a context here...
- GadgetContext context = new HttpGadgetContext(req, tokenDecoder);
- Set<String> features = new HashSet<String>(found.size());
- do {
- for (GadgetFeatureRegistry.Entry entry : found) {
- if (!features.contains(entry.getName()) &&
- features.containsAll(entry.getDependencies())) {
- features.add(entry.getName());
- GadgetFeatureFactory factory = entry.getFeature();
- GadgetFeature feature = factory.create();
- for (JsLibrary lib : feature.getJsLibraries(context)) {
- if (!lib.getType().equals(JsLibrary.Type.URL)) {
- if (context.getDebug()) {
- jsData.append(lib.getDebugContent());
- } else {
- jsData.append(lib.getContent());
- }
- jsData.append(";\n");
- }
+ for (GadgetFeature feature : features) {
+ for (JsLibrary lib : feature.getJsLibraries(context, container)) {
+ if (!lib.getType().equals(JsLibrary.Type.URL)) {
+ if (debug) {
+ jsData.append(lib.getDebugContent());
+ } else {
+ jsData.append(lib.getContent());
}
+ jsData.append(";\n");
}
}
- } while (features.size() != found.size());
+ }
+
if (jsData.length() == 0) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/UrlGenerator.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/UrlGenerator.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/UrlGenerator.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/UrlGenerator.java
Sun Jun 1 06:20:34 2008
@@ -23,7 +23,6 @@
import org.apache.shindig.gadgets.Gadget;
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetFeature;
-import org.apache.shindig.gadgets.GadgetFeatureFactory;
import org.apache.shindig.gadgets.GadgetFeatureRegistry;
import org.apache.shindig.gadgets.JsLibrary;
import org.apache.shindig.gadgets.UserPrefs;
@@ -37,7 +36,6 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
-import java.util.Map;
import java.util.regex.Pattern;
/**
@@ -166,11 +164,8 @@
this.containerConfig = containerConfig;
StringBuilder jsBuf = new StringBuilder();
- for (Map.Entry<String, GadgetFeatureRegistry.Entry> entry :
- registry.getAllFeatures().entrySet()) {
- GadgetFeatureFactory factory = entry.getValue().getFeature();
- GadgetFeature feature = factory.create();
- for (JsLibrary library : feature.getJsLibraries(null)) {
+ for (GadgetFeature feature : registry.getAllFeatures()) {
+ for (JsLibrary library : feature.getJsLibraries(null, null)) {
jsBuf.append(library.getContent());
}
}
Modified:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetFeatureRegistryTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetFeatureRegistryTest.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetFeatureRegistryTest.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetFeatureRegistryTest.java
Sun Jun 1 06:20:34 2008
@@ -19,106 +19,88 @@
package org.apache.shindig.gadgets;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
-import java.util.Map;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
-public class GadgetFeatureRegistryTest extends TestCase {
+public class GadgetFeatureRegistryTest {
private GadgetFeatureRegistry registry;
- private static final GadgetFeatureFactory DUMMY_FEATURE
- = new GadgetFeatureFactory() {
- // Dummy feature.
- public GadgetFeature create() {
- return new GadgetFeature() {};
- }
- };
-
private static final String FEATURE_NAME = "feature";
private static final String DEP_NAME = "dependency";
+ private static final String CORE_NAME = "core.feature";
+ private static final String CONTENT = "var foo = 'bar'";
+ private static final String CORE_CONTENT = "var core = 'dependency'";
+ private static final String DEP_CONTENT = "var bar ='foo'";
private static final String[] FEATURE_LIST = new String[] {
"feature0", "feature1", "feature2", "feature3"
};
- private static final String UNREGISTERED_FEATURE = "unregistered";
- @Override
+
+ @Before
public void setUp() throws Exception {
// TODO: Add a mock fetcher here and add tests for retrieving remote files
- super.setUp();
registry = new GadgetFeatureRegistry(null, null);
+ registry.register(makeFeature(CORE_NAME, CORE_CONTENT, null));
}
- public void testDependencyChain() throws Exception {
- registry.register(FEATURE_NAME, Arrays.asList(DEP_NAME), DUMMY_FEATURE);
- registry.register(DEP_NAME, null, DUMMY_FEATURE);
-
- GadgetFeatureRegistry.Entry entry = registry.getEntry(FEATURE_NAME);
- // Object comparison is OK here.
- assertEquals(DUMMY_FEATURE, entry.getFeature());
- assertEquals(DEP_NAME, entry.getDependencies().iterator().next());
- }
-
- public void testGetAllFeatures() throws Exception {
- for (String feature : FEATURE_LIST) {
- registry.register(feature, Arrays.asList(DEP_NAME), DUMMY_FEATURE);
- }
-
- Map<String, GadgetFeatureRegistry.Entry> entries
- = registry.getAllFeatures();
-
- for (String feature : FEATURE_LIST) {
- GadgetFeatureRegistry.Entry entry = entries.get(feature);
- assertNotNull(entry);
- assertEquals(feature, entry.getName());
- assertEquals(DEP_NAME, entry.getDependencies().iterator().next());
+ private GadgetFeature makeFeature(String name, String content, String dep)
+ throws GadgetException {
+ JsLibrary lib = JsLibrary.create(JsLibrary.Type.INLINE, content, name,
null);
+ List<String> deps = new LinkedList<String>();
+ if (deps != null) {
+ deps.add(dep);
}
+ return new GadgetFeature(name, Arrays.asList(lib), deps);
}
- public void testGetIncluded() throws Exception {
- Set<String> requested = new HashSet<String>();
- for (String feature : FEATURE_LIST) {
- registry.register(feature, Arrays.asList(DEP_NAME), DUMMY_FEATURE);
- requested.add(feature);
- }
-
- registry.register(DEP_NAME, null, DUMMY_FEATURE);
-
- requested.add(UNREGISTERED_FEATURE);
-
- Set<GadgetFeatureRegistry.Entry> found
- = new HashSet<GadgetFeatureRegistry.Entry>();
- Set<String> missing = new HashSet<String>();
- registry.getIncludedFeatures(requested, found, missing);
+ @Test
+ public void getLibraries() throws Exception {
+ registry.register(makeFeature(DEP_NAME, DEP_CONTENT, null));
+ registry.register(makeFeature(FEATURE_NAME, CONTENT, DEP_NAME));
+
+ Collection<GadgetFeature> features
+ = registry.getFeatures(Arrays.asList(FEATURE_NAME));
+
+ assertEquals(3, features.size());
+ // Order must be preserved.
+ Iterator<GadgetFeature> i = features.iterator();
+ assertEquals(CORE_NAME, i.next().getName());
+ assertEquals(DEP_NAME, i.next().getName());
+ assertEquals(FEATURE_NAME, i.next().getName());
+ }
- assertEquals(1, missing.size());
- assertEquals(UNREGISTERED_FEATURE, missing.iterator().next());
+ @Test
+ public void getUnknownLibraries() throws GadgetException {
+ registry.register(makeFeature(FEATURE_NAME, CONTENT, DEP_NAME));
+ List<String> unsupported = new ArrayList<String>();
+ registry.getFeatures(Arrays.asList(FEATURE_NAME, "FAKE FAKE FAKE"),
+ unsupported);
+ assertEquals("FAKE FAKE FAKE", unsupported.get(0));
+ }
+ @Test
+ public void getAllFeatures() throws Exception {
for (String feature : FEATURE_LIST) {
- boolean contains = false;
- for (GadgetFeatureRegistry.Entry entry : found) {
- if (entry.getName().equals(feature)) {
- contains = true;
- }
- }
- if (!contains) {
- fail("Feature " + feature + " not included in needed set.");
- }
+ registry.register(makeFeature(feature, CONTENT, DEP_NAME));
}
- boolean contains = false;
- for (GadgetFeatureRegistry.Entry entry : found) {
- if (entry.getName().equals(DEP_NAME)) {
- contains = true;
- } else if (entry.getName().equals(UNREGISTERED_FEATURE)) {
- fail("Unregistered dependency included in needed set.");
- }
+ Set<String> found = new HashSet<String>();
+ for (GadgetFeature feature : registry.getAllFeatures()) {
+ found.add(feature.getName());
}
- if (!contains) {
- fail("Transitive dependency " + DEP_NAME + " not included in needed
set");
+ for (String feature : FEATURE_LIST) {
+ assertTrue(feature + " not returned.", found.contains(feature));
}
-
- assertEquals(UNREGISTERED_FEATURE, missing.iterator().next());
}
}
Modified:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsFeatureLoaderTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsFeatureLoaderTest.java?rev=662212&r1=662211&r2=662212&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsFeatureLoaderTest.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsFeatureLoaderTest.java
Sun Jun 1 06:20:34 2008
@@ -27,6 +27,8 @@
import java.io.File;
import java.io.FileWriter;
import java.net.URI;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -47,9 +49,9 @@
loader = new JsFeatureLoader(fetcher);
}
- private JsLibrary getJsLib(GadgetFeatureRegistry.Entry entry) {
- GadgetFeature feature = entry.getFeature().create();
- return feature.getJsLibraries(new GadgetContext()).get(0);
+ private JsLibrary getJsLib(GadgetFeature feature) {
+ return feature.getJsLibraries(
+ RenderingContext.GADGET, ContainerConfig.DEFAULT_CONTAINER).get(0);
}
public void testBasicLoading() throws Exception {
@@ -59,14 +61,12 @@
" <script>" + DEF_JS_CONTENT + "</script>" +
" </gadget>" +
"</feature>";
- GadgetFeatureRegistry.Entry entry = loader.loadFeature(registry, xml);
+ GadgetFeature feature = loader.loadFeature(registry, xml);
- assertEquals(FEATURE_NAME, entry.getName());
- GadgetFeature feature = entry.getFeature().create();
- List<JsLibrary> libs = feature.getJsLibraries(new GadgetContext());
- assertEquals(1, libs.size());
- assertEquals(JsLibrary.Type.INLINE, libs.get(0).getType());
- assertEquals(DEF_JS_CONTENT, libs.get(0).getContent());
+ assertEquals(FEATURE_NAME, feature.getName());
+ JsLibrary lib = getJsLib(feature);
+ assertEquals(JsLibrary.Type.INLINE, lib.getType());
+ assertEquals(DEF_JS_CONTENT, lib.getContent());
}
public void testMultiContainers() throws Exception {
@@ -79,12 +79,11 @@
" <script>" + ALT_JS_CONTENT + "</script>" +
" </gadget>" +
"</feature>";
- GadgetFeatureRegistry.Entry entry = loader.loadFeature(registry, xml);
- GadgetFeature feature = entry.getFeature().create();
+ GadgetFeature feature = loader.loadFeature(registry, xml);
List<JsLibrary> libs;
- libs = feature.getJsLibraries(new ContainerContext(CONT_A));
+ libs = feature.getJsLibraries(RenderingContext.GADGET, CONT_A);
assertEquals(DEF_JS_CONTENT, libs.get(0).getContent());
- libs = feature.getJsLibraries(new ContainerContext(CONT_B));
+ libs = feature.getJsLibraries(RenderingContext.GADGET, CONT_B);
assertEquals(ALT_JS_CONTENT, libs.get(0).getContent());
}
@@ -99,12 +98,10 @@
" <script src=\"" + temp.getPath() + "\"/>" +
" </gadget>" +
"</feature>";
- GadgetFeatureRegistry.Entry entry = loader.loadFeature(registry, xml);
- GadgetFeature feature = entry.getFeature().create();
- List<JsLibrary> libs = feature.getJsLibraries(new GadgetContext());
- assertEquals(1, libs.size());
- assertEquals(DEF_JS_CONTENT, libs.get(0).getContent());
- assertEquals(FEATURE_NAME, libs.get(0).getFeature());
+ GadgetFeature feature = loader.loadFeature(registry, xml);
+ JsLibrary lib = getJsLib(feature);
+ assertEquals(DEF_JS_CONTENT, lib.getContent());
+ assertEquals(FEATURE_NAME, lib.getFeature());
}
public void testUrlReferences() throws Exception {
@@ -119,13 +116,12 @@
= new HttpResponse(200, ALT_JS_CONTENT.getBytes(), null);
expect(fetcher.fetch(eq(request))).andReturn(response);
replay();
- GadgetFeatureRegistry.Entry entry = loader.loadFeature(registry, xml);
+ GadgetFeature feature = loader.loadFeature(registry, xml);
verify();
- GadgetFeature feature = entry.getFeature().create();
- List<JsLibrary> libs = feature.getJsLibraries(new GadgetContext());
- assertEquals(1, libs.size());
- assertEquals(ALT_JS_CONTENT, libs.get(0).getContent());
- assertEquals(FEATURE_NAME, libs.get(0).getFeature());
+
+ JsLibrary lib = getJsLib(feature);
+ assertEquals(ALT_JS_CONTENT, lib.getContent());
+ assertEquals(FEATURE_NAME, lib.getFeature());
}
private File makeFeatureFile(String name, String content) throws Exception {
@@ -150,25 +146,17 @@
loader.loadFeatures(file1.getAbsolutePath() +
JsFeatureLoader.FILE_SEPARATOR +
file2.getAbsolutePath(), registry);
- // TODO: This is too fragile. GadgetFeatureRegistry needs to be fixed.
- Map<String, GadgetFeatureRegistry.Entry> entries
- = registry.getAllFeatures();
+ Collection<GadgetFeature> features = registry.getAllFeatures();
+
+ Map<String, GadgetFeature> map = new HashMap<String, GadgetFeature>();
+ for (GadgetFeature feature : features) {
+ map.put(feature.getName(), feature);
+ }
- JsLibrary lib1 = getJsLib(entries.get(FEATURE_NAME));
+ JsLibrary lib1 = getJsLib(map.get(FEATURE_NAME));
assertEquals(DEF_JS_CONTENT, lib1.getContent());
- JsLibrary lib2 = getJsLib(entries.get(ALT_FEATURE_NAME));
+ JsLibrary lib2 = getJsLib(map.get(ALT_FEATURE_NAME));
assertEquals(ALT_JS_CONTENT, lib2.getContent());
}
-}
-
-class ContainerContext extends GadgetContext {
- private final String container;
- @Override
- public String getContainer() {
- return container;
- }
- public ContainerContext(String container) {
- this.container = container;
- }
-}
+}
\ No newline at end of file