Author: johnh
Date: Thu Jan 31 15:56:48 2008
New Revision: 617309

URL: http://svn.apache.org/viewvc?rev=617309&view=rev
Log:
Views support for Shindig.

This implements SHINDIG-41, conforming to the canonical Gadget XSD. View ID 
semantics are
that view IDs are split on commas, and each view ID found appends to the 
content for that view.
This allows for code sharing between views and provides a relatively clean 
implementation.

A blank or nonexistent view maps to ID "default".

Changes are made to be backwards-compatible, maintaining the old parameter-less
GadgetSpec.getContentData() API. TBD: whether to deprecate this method.

Also: Updating pom.*xml to Caja r422 (further updates should be done soon).


Modified:
    incubator/shindig/trunk/java/gadgets/pom.jar.xml
    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/GadgetException.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpec.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
    incubator/shindig/trunk/javascript/samplecontainer/samplecontainer.html

Modified: incubator/shindig/trunk/java/gadgets/pom.jar.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.jar.xml?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.jar.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.jar.xml Thu Jan 31 15:56:48 2008
@@ -108,7 +108,7 @@
     <dependency>
       <groupId>caja</groupId>
       <artifactId>caja</artifactId>
-      <version>r394</version>
+      <version>r422</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>

Modified: incubator/shindig/trunk/java/gadgets/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.xml Thu Jan 31 15:56:48 2008
@@ -100,7 +100,7 @@
     <dependency>
       <groupId>caja</groupId>
       <artifactId>caja</artifactId>
-      <version>r394</version>
+      <version>r422</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>

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=617309&r1=617308&r2=617309&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
 Thu Jan 31 15:56:48 2008
@@ -284,7 +284,16 @@
    * @throws IllegalStateException if contentType is not HTML.
    */
   public String getContentData() {
-    return substitutions.substitute(baseSpec.getContentData());
+    return getContentData(null);
+  }
+  
+  /**
+   * @param view ID of the view whose content to retrieve
+   * @return Gadget contents for the given view with all substitutions applied
+   * @throws IllegalStateException if contentType is not HTML
+   */
+  public String getContentData(String view) {
+    return substitutions.substitute(baseSpec.getContentData(view));
   }
 
   private MessageBundle currentMessageBundle = MessageBundle.EMPTY;

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
 Thu Jan 31 15:56:48 2008
@@ -48,6 +48,9 @@
 
     // Caja error
     MALFORMED_FOR_SAFE_INLINING,
+    
+    // View errors
+    UNKNOWN_VIEW_SPECIFIED,
 
     // Blacklisting
     BLACKLISTED_GADGET

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpec.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpec.java?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpec.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpec.java
 Thu Jan 31 15:56:48 2008
@@ -22,6 +22,8 @@
  * Represents a Gadget specification.
  */
 public interface GadgetSpec {
+  public static final String DEFAULT_VIEW = "default";
+  
   public String getTitle();
   public URI getTitleURI();
   public String getDirectoryTitle();
@@ -75,7 +77,7 @@
   public List<UserPref> getUserPrefs();
 
   public static enum ContentType {
-      HTML, URL
+    HTML, URL
   }
 
   public ContentType getContentType();
@@ -89,10 +91,18 @@
   public URI getContentHref();
 
   /**
-   * @return The HTML content for this gadget spec.
+   * @return The HTML content for the default view of this gadget spec.
    * @throws IllegalStateException if contentType is not HTML.
    */
   public String getContentData();
+  
+  /**
+   * @param view Identifier of the desired view to retrieve. 
+   * @return The HTML content for the specified view of this gadget spec,
+   *         or null if no such view was defined.
+   * @throws IllegalStateException if contentType is not HTML.
+   */
+  public String getContentData(String view);
 
   /**
    * @return A copy of the spec. This is NOT the same as clone().

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
 Thu Jan 31 15:56:48 2008
@@ -58,7 +58,7 @@
       throw new SpecParserException("Empty XML document.");
     }
 
-    Document doc  ;
+    Document doc;
     try {
       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       InputSource is = new InputSource(new Utf8InputStream(xml));
@@ -87,10 +87,8 @@
     }
 
     NodeList content = root.getElementsByTagName("Content");
-    if (content.getLength() != 1) {
-      throw new SpecParserException("Missing or duplicated <Content>");
-    } else {
-      processContent(spec, content.item(0));
+    for (int i = 0, j = content.getLength(); i < j; ++i) {
+      processContent(spec, content.item(i));
     }
 
     NodeList requires = root.getElementsByTagName("Require");
@@ -286,10 +284,15 @@
       }
     } else {
       spec.contentType = GadgetSpec.ContentType.HTML;
+      Node viewNode = attrs.getNamedItem("view");
+      String viewStr = (viewNode == null) ? "" : viewNode.getNodeValue();
+      String views[] = viewStr.split(",");
       Node child = content.getFirstChild();
       String contentData = content.getTextContent();
       if (contentData.length() > 0) {
-        spec.contentData = contentData;
+        for (String view : views) {
+          spec.addContent(view, contentData);
+        }
       } else {
         throw new SpecParserException("Empty or malformed <Content> section!");
       }
@@ -349,7 +352,8 @@
     private String directoryTitle;
     private ContentType contentType;
     private URI contentHref;
-    private String contentData;
+    private Map<String, StringBuilder> contentData
+        = new HashMap<String, StringBuilder>();
     private List<Icon> icons = new ArrayList<Icon>();
     private List<LocaleSpec> localeSpecs = new ArrayList<LocaleSpec>();
     private List<String> preloads = new ArrayList<String>();
@@ -370,7 +374,7 @@
       spec.directoryTitle = directoryTitle;
       spec.contentType = contentType;
       spec.contentHref = contentHref;
-      spec.contentData = contentData;
+      spec.contentData = new HashMap<String, StringBuilder>(contentData);
       spec.icons = new ArrayList<Icon>(icons);
       spec.localeSpecs = new ArrayList<LocaleSpec>(localeSpecs);
       spec.preloads = new ArrayList<String>(preloads);
@@ -542,9 +546,31 @@
     }
 
     public String getContentData() {
+      return getContentData(DEFAULT_VIEW);
+    }
+    
+    public String getContentData(String view) {
       Check.is(contentType == ContentType.HTML,
                "getContentData() requires contentType HTML");
-      return contentData;
+      if (view == null || view == "") {
+        view = DEFAULT_VIEW;
+      }
+      if (!contentData.containsKey(view)) {
+        return null;
+      }
+      return contentData.get(view).toString();
+    }
+    
+    public synchronized void addContent(String view, String content) {
+      if (view == null || view.equals("")) {
+        view = DEFAULT_VIEW;
+      }
+
+      if (!contentData.containsKey(view)) {
+        contentData.put(view, new StringBuilder());
+      }
+      
+      contentData.get(view).append(content);
     }
   }
 }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
 Thu Jan 31 15:56:48 2008
@@ -151,13 +151,15 @@
     }
 
     Gadget gadget = null;
+    String view = req.getParameter("view");
+    view = (view == null || view == "") ? GadgetSpec.DEFAULT_VIEW : view;
     try {
       gadget = gadgetServer.processGadget(gadgetId,
                                           getPrefsFromRequest(req),
                                           context.getLocale(),
                                           RenderingContext.GADGET,
                                           options);
-      outputGadget(gadget, options, contentFilters, resp);
+      outputGadget(gadget, view, options, contentFilters, resp);
     } catch (GadgetServer.GadgetProcessException e) {
       outputErrors(e, resp);
     }
@@ -167,6 +169,7 @@
    * Renders a successfully processed gadget.
    *
    * @param gadget
+   * @param view
    * @param options
    * @param contentFilters
    * @param resp
@@ -174,13 +177,14 @@
    * @throws GadgetServer.GadgetProcessException
    */
   private void outputGadget(Gadget gadget,
+                            String view,
                             ProcessingOptions options,
                             List<GadgetContentFilter> contentFilters,
                             HttpServletResponse resp)
       throws IOException, GadgetServer.GadgetProcessException {
     switch(gadget.getContentType()) {
     case HTML:
-      outputHtmlGadget(gadget, options, contentFilters, resp);
+      outputHtmlGadget(gadget, view, options, contentFilters, resp);
       break;
     case URL:
       outputUrlGadget(gadget, options, resp);
@@ -196,6 +200,7 @@
    * Handles type=html gadget output.
    *
    * @param gadget
+   * @param view
    * @param options
    * @param contentFilters
    * @param resp
@@ -203,6 +208,7 @@
    * @throws GadgetServer.GadgetProcessException
    */
   private void outputHtmlGadget(Gadget gadget,
+                                String view,
                                 ProcessingOptions options,
                                 List<GadgetContentFilter> contentFilters,
                                 HttpServletResponse resp)
@@ -256,14 +262,24 @@
     }
 
     List<GadgetException> gadgetExceptions = new LinkedList<GadgetException>();
-    String content = gadget.getContentData();
-    for (GadgetContentFilter filter : contentFilters) {
-      try {
-        content = filter.filter(content);
-      } catch (GadgetException e) {
-        gadgetExceptions.add(e);
+    String content = gadget.getContentData(view);
+    if (content == null) {
+      // unknown view
+      gadgetExceptions.add(
+          new GadgetException(
+              GadgetException.Code.UNKNOWN_VIEW_SPECIFIED,
+              "View: '" + view + "' invalid for gadget: " +
+              gadget.getId().getKey()));
+    } else {
+      for (GadgetContentFilter filter : contentFilters) {
+        try {
+          content = filter.filter(content);
+        } catch (GadgetException e) {
+          gadgetExceptions.add(e);
+        }
       }
     }
+    
     if (gadgetExceptions.size() > 0) {
       throw new GadgetServer.GadgetProcessException(gadgetExceptions);
     }

Modified: 
incubator/shindig/trunk/javascript/samplecontainer/samplecontainer.html
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/javascript/samplecontainer/samplecontainer.html?rev=617309&r1=617308&r2=617309&view=diff
==============================================================================
--- incubator/shindig/trunk/javascript/samplecontainer/samplecontainer.html 
(original)
+++ incubator/shindig/trunk/javascript/samplecontainer/samplecontainer.html Thu 
Jan 31 15:56:48 2008
@@ -33,7 +33,7 @@
 <script type="text/javascript" src="../container/gadgets.js"></script>
 <script type="text/javascript">
 
-var specUrl = 
'http://localhost:8080/gadgets/samplecontainer/examples/SocialHelloWorld.xml';
+var specUrl = 
'http://hosting.gmodules.com/ig/gadgets/file/117247905274371511495/SocialHelloWorld.xml';
 var useCaja = false;
 var useCache = true;
 var usePermissive = false;
@@ -102,7 +102,7 @@
       <input type="text" size="75" id="gadgetUrl"/>
       <input type="checkbox" id="useCajaCheckbox"/>use caja
       <input type="checkbox" id="usePermissiveCheckbox"/>use permissive
-      <div style="display:none"><input type="checkbox" id="useCacheCheckbox" 
checked="true"/>use cache</div>
+      <input type="checkbox" id="useCacheCheckbox" checked="true"/>use cache
       <input type="button" value="reset" onclick="changeGadgetUrl();"/>
     </div>
     <div style="clear:both; height: 1px;">&nbsp;</div>


Reply via email to