You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/11/27 16:04:28 UTC

svn commit: r884890 - in /incubator/pivot/trunk: core/src/org/apache/pivot/xml/ demos/src/org/apache/pivot/demos/rss/

Author: gbrown
Date: Fri Nov 27 15:04:28 2009
New Revision: 884890

URL: http://svn.apache.org/viewvc?rev=884890&view=rev
Log:
Re-implement RSS demo using native Pivot XML support.

Added:
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSItemRenderer.java
Removed:
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/NodeListAdapter.java
Modified:
    incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSFeedDemo.java
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/rss_feed_demo.wtkx

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java?rev=884890&r1=884889&r2=884890&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java Fri Nov 27 15:04:28 2009
@@ -34,6 +34,7 @@
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 
+import org.apache.pivot.collections.ArrayList;
 import org.apache.pivot.collections.List;
 import org.apache.pivot.serialization.SerializationException;
 import org.apache.pivot.serialization.Serializer;
@@ -288,14 +289,131 @@
     }
 
     /**
-     * Returns all elements matching the given XPath expression.
-     * <p>
-     * NOTE This method is not yet implemented.
+     * Returns the first element matching the given path.
      *
+     * @param root
+     * @param path
+     */
+    public static Element getElement(Element root, String path) {
+        if (root == null) {
+            throw new IllegalArgumentException("root is null.");
+        }
+
+        if (path == null) {
+            throw new IllegalArgumentException("path is null.");
+        }
+
+        if (path.length() == 0) {
+            throw new IllegalArgumentException("path is empty.");
+        }
+
+        return getElement(root, new ArrayList<String>(path.split("/")));
+    }
+
+    /**
+     * Returns the first set of elements matching the given path.
+     *
+     * @param root
      * @param path
      */
     public static List<Element> getElements(Element root, String path) {
-        // TODO
-        return null;
+        if (root == null) {
+            throw new IllegalArgumentException("root is null.");
+        }
+
+        if (path == null) {
+            throw new IllegalArgumentException("path is null.");
+        }
+
+        if (path.length() == 0) {
+            throw new IllegalArgumentException("path is empty.");
+        }
+
+        ArrayList<Element> elements = new ArrayList<Element>();
+
+        ArrayList<String> tagNames = new ArrayList<String>(path.split("/"));
+        String tagName = tagNames.remove(tagNames.getLength() - 1, 1).get(0);
+        Element parent = getElement(root, tagNames);
+        if (parent != null) {
+            for (int i = 0, n = parent.getLength(); i < n; i++) {
+                Node node = parent.get(i);
+
+                if (node instanceof Element) {
+                    Element element = (Element)node;
+
+                    if (element.getName().equals(tagName)) {
+                        elements.add(element);
+                    }
+                }
+            }
+        }
+
+        return elements;
+    }
+
+    /**
+     * Returns the text content of the first element matching the given
+     * tag name.
+     *
+     * @param root
+     * @param path
+     */
+    public static String getText(Element root, String path) {
+        if (root == null) {
+            throw new IllegalArgumentException("root is null.");
+        }
+
+        if (path == null) {
+            throw new IllegalArgumentException("path is null.");
+        }
+
+        if (path.length() == 0) {
+            throw new IllegalArgumentException("path is empty.");
+        }
+
+        String text = null;
+
+        ArrayList<String> tagNames = new ArrayList<String>(path.split("/"));
+        Element element = getElement(root, tagNames);
+        if (element != null
+            && element.getLength() > 0) {
+            Node first = element.get(0);
+
+            if (first instanceof TextNode) {
+                TextNode textNode = (TextNode)first;
+                text = textNode.getText();
+            }
+        }
+
+        return text;
+    }
+
+    private static Element getElement(Element root, ArrayList<String> tagNames) {
+        Element current = root;
+
+        for (int i = 0, n = tagNames.getLength(); i < n; i++) {
+            String tagName = tagNames.get(i);
+
+            int j = 0;
+            for (Node node : current) {
+                if (node instanceof Element) {
+                    Element element = (Element)node;
+                    if (element.getName().equals(tagName)) {
+                        break;
+                    }
+                }
+
+                j++;
+            }
+
+            if (j < current.getLength()) {
+                current = (Element)current.get(j);
+            } else {
+                current = null;
+                break;
+            }
+        }
+
+        return current;
     }
 }

Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSFeedDemo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSFeedDemo.java?rev=884890&r1=884889&r2=884890&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSFeedDemo.java (original)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSFeedDemo.java Fri Nov 27 15:04:28 2009
@@ -15,200 +15,57 @@
  */
 package org.apache.pivot.demos.rss;
 
-import java.awt.Color;
 import java.awt.Desktop;
-import java.awt.Font;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
 
 import org.apache.pivot.collections.Map;
-import org.apache.pivot.io.IOTask;
 import org.apache.pivot.util.concurrent.Task;
-import org.apache.pivot.util.concurrent.TaskExecutionException;
 import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.web.GetQuery;
 import org.apache.pivot.wtk.Application;
 import org.apache.pivot.wtk.CardPane;
 import org.apache.pivot.wtk.Component;
 import org.apache.pivot.wtk.ComponentMouseButtonListener;
 import org.apache.pivot.wtk.DesktopApplicationContext;
 import org.apache.pivot.wtk.Display;
-import org.apache.pivot.wtk.BoxPane;
-import org.apache.pivot.wtk.Insets;
 import org.apache.pivot.wtk.Label;
 import org.apache.pivot.wtk.ListView;
 import org.apache.pivot.wtk.Mouse;
-import org.apache.pivot.wtk.Orientation;
 import org.apache.pivot.wtk.Window;
 import org.apache.pivot.wtkx.WTKXSerializer;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+import org.apache.pivot.xml.Element;
+import org.apache.pivot.xml.XMLSerializer;
 
-/**
- * RSS feed demo application.
- */
 public class RSSFeedDemo implements Application {
-    // Loads the feed in the background so the UI doesn't block
-    private class LoadFeedTask extends IOTask<NodeList> {
-        @Override
-        public NodeList execute() throws TaskExecutionException {
-            NodeList itemNodeList = null;
-
-            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-            DocumentBuilder documentBuilder;
-            try {
-                documentBuilder = documentBuilderFactory.newDocumentBuilder();
-            } catch(ParserConfigurationException exception) {
-                throw new TaskExecutionException(exception);
-            }
-
-            Document document;
-            try {
-                document = documentBuilder.parse(FEED_URI);
-            } catch(IOException exception) {
-                throw new TaskExecutionException(exception);
-            } catch(SAXException exception) {
-                throw new TaskExecutionException(exception);
-            }
-
-            try {
-                itemNodeList = (NodeList)xpath.evaluate("/rss/channel/item",
-                    document, XPathConstants.NODESET);
-            } catch(XPathExpressionException exception) {
-                // No-op
-            }
-
-            return itemNodeList;
-        }
-    }
-
-    // Prepares an RSS feed news item for presentation in a list view
-    private class RSSItemRenderer extends BoxPane implements ListView.ItemRenderer {
-        private Label titleLabel = new Label();
-        private Label categoriesHeadingLabel = new Label("subject:");
-        private Label categoriesLabel = new Label();
-        private Label submitterHeadingLabel = new Label("submitter:");
-        private Label submitterLabel = new Label();
-
-        public RSSItemRenderer() {
-            super(Orientation.VERTICAL);
-
-            getStyles().put("padding", new Insets(2, 2, 8, 2));
-
-            add(titleLabel);
-
-            BoxPane categoriesBoxPane = new BoxPane();
-            add(categoriesBoxPane);
-
-            categoriesBoxPane.add(categoriesHeadingLabel);
-            categoriesBoxPane.add(categoriesLabel);
-
-            BoxPane submitterBoxPane = new BoxPane();
-            add(submitterBoxPane);
-
-            submitterBoxPane.add(submitterHeadingLabel);
-            submitterBoxPane.add(submitterLabel);
-        }
-
-        @Override
-        public void setSize(int width, int height) {
-            super.setSize(width, height);
-
-            // Since this component doesn't have a parent, it won't be validated
-            // via layout; ensure that it is valid here
-            validate();
-        }
-
-        @Override
-        public void render(Object item, int index, ListView listView, boolean selected,
-            boolean checked, boolean highlighted, boolean disabled) {
-            if (item != null) {
-                Element itemElement = (Element)item;
-
-                try {
-                    String title = (String)xpath.evaluate("title", itemElement, XPathConstants.STRING);
-                    titleLabel.setText(title);
-
-                    String categories = "";
-                    NodeList categoryNodeList = (NodeList)xpath.evaluate("category", itemElement,
-                        XPathConstants.NODESET);
-                    for (int j = 0; j < categoryNodeList.getLength(); j++) {
-                        Element categoryElement = (Element)categoryNodeList.item(j);
-                        String category = categoryElement.getTextContent();
-                        if (j > 0) {
-                            categories += ", ";
-                        }
-
-                        categories += category;
-                    }
-
-                    categoriesLabel.setText(categories);
-
-                    String submitter = (String)xpath.evaluate("dz:submitter/dz:username", itemElement,
-                        XPathConstants.STRING);
-                    submitterLabel.setText(submitter);
-                } catch(XPathExpressionException exception) {
-                    System.err.println(exception);
-                }
-            }
+    private Window window = null;
+    private ListView feedListView = null;
+    private CardPane cardPane = null;
+    private Label statusLabel = null;
 
-            Font font = (Font)listView.getStyles().get("font");
-            Font largeFont = font.deriveFont(Font.BOLD, 14);
-            titleLabel.getStyles().put("font", largeFont);
-            categoriesLabel.getStyles().put("font", font);
-            submitterLabel.getStyles().put("font", font);
-
-            Color color;
-            if (listView.isEnabled() && !disabled) {
-                if (selected) {
-                    if (listView.isFocused()) {
-                        color = (Color)listView.getStyles().get("selectionColor");
-                    } else {
-                        color = (Color)listView.getStyles().get("inactiveSelectionColor");
-                    }
-                } else {
-                    color = (Color)listView.getStyles().get("color");
-                }
-            } else {
-                color = (Color)listView.getStyles().get("disabledColor");
-            }
+    @Override
+    public void startup(Display display, Map<String, String> properties)
+        throws Exception {
+        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+        window = (Window)wtkxSerializer.readObject(this, "rss_feed_demo.wtkx");
+        feedListView = (ListView)wtkxSerializer.get("feedListView");
+        cardPane = (CardPane)wtkxSerializer.get("cardPane");
+        statusLabel = (Label)wtkxSerializer.get("statusLabel");
 
-            titleLabel.getStyles().put("color", color);
-            categoriesHeadingLabel.getStyles().put("color", color);
-            categoriesLabel.getStyles().put("color", color);
-            submitterHeadingLabel.getStyles().put("color", color);
-            submitterLabel.getStyles().put("color", color);
-        }
-    }
+        feedListView.getComponentMouseButtonListeners().add(new ComponentMouseButtonListener.Adapter() {
+            private int index = -1;
 
-    // Handles double-clicks on the list view
-    private class FeedViewMouseButtonHandler extends ComponentMouseButtonListener.Adapter {
-        private int index = -1;
-
-        @Override
-        public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
-            if (count == 1) {
-                index = feedListView.getItemAt(y);
-            } else if (count == 2
-                && feedListView.getItemAt(y) == index) {
-                Element itemElement = (Element)feedListView.getListData().get(index);
+            @Override
+            public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+                if (count == 1) {
+                    index = feedListView.getItemAt(y);
+                } else if (count == 2
+                    && feedListView.getItemAt(y) == index) {
+                    Element itemElement = (Element)feedListView.getListData().get(index);
 
-                try {
-                    String link = (String)xpath.evaluate("link", itemElement, XPathConstants.STRING);
+                    String link = XMLSerializer.getText(itemElement, "link");
                     Desktop desktop = Desktop.getDesktop();
 
                     try {
@@ -220,76 +77,26 @@
                     } catch(IOException exception) {
                         System.out.println("Unable to open " + link + " in default browser.");
                     }
-                } catch(XPathExpressionException exception) {
-                    System.err.print(exception);
-                }
-            }
-
-            return false;
-        }
-    };
-
-    private XPath xpath;
-
-    private Window window = null;
-    private ListView feedListView = null;
-    private CardPane cardPane = null;
-    private Label statusLabel = null;
-
-    public static final String FEED_URI = "http://feeds.dzone.com/javalobby/frontpage?format=xml";
-
-    public RSSFeedDemo() {
-        // Create an XPath instance
-        xpath = XPathFactory.newInstance().newXPath();
-
-        // Set the namespace resolver
-        xpath.setNamespaceContext(new NamespaceContext() {
-            @Override
-            public String getNamespaceURI(String prefix) {
-                String namespaceURI;
-                if (prefix.equals("dz")) {
-                    namespaceURI = "http://www.developerzone.com/modules/dz/1.0";
-                } else {
-                    namespaceURI = XMLConstants.NULL_NS_URI;
                 }
 
-                return namespaceURI;
-            }
-
-            @Override
-            public String getPrefix(String uri) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Iterator<String> getPrefixes(String uri) {
-                throw new UnsupportedOperationException();
+                return false;
             }
         });
-    }
-
-    @Override
-    public void startup(Display display, Map<String, String> properties)
-        throws Exception {
-        WTKXSerializer wtkxSerializer = new WTKXSerializer();
-        window = (Window)wtkxSerializer.readObject(this, "rss_feed_demo.wtkx");
-        feedListView = (ListView)wtkxSerializer.get("feedListView");
-        cardPane = (CardPane)wtkxSerializer.get("cardPane");
-        statusLabel = (Label)wtkxSerializer.get("statusLabel");
 
-        feedListView.setItemRenderer(new RSSItemRenderer());
-        feedListView.getComponentMouseButtonListeners().add(new FeedViewMouseButtonHandler());
+        GetQuery getQuery = new GetQuery("feeds.dzone.com", "/javalobby/frontpage");
+        getQuery.setSerializer(new XMLSerializer());
+        getQuery.getParameters().put("format", "xml");
 
-        LoadFeedTask loadFeedTask = new LoadFeedTask();
-        loadFeedTask.execute(new TaskListener<NodeList>() {
+        getQuery.execute(new TaskListener<Object>() {
             @Override
-            public void taskExecuted(Task<NodeList> task) {
-                feedListView.setListData(new NodeListAdapter(task.getResult()));
+            public void taskExecuted(Task<Object> task) {
+                Element root = (Element)task.getResult();
+                feedListView.setListData(XMLSerializer.getElements(root, "channel/item"));
                 cardPane.setSelectedIndex(1);
             }
 
             @Override
-            public void executeFailed(Task<NodeList> task) {
+            public void executeFailed(Task<Object> task) {
                 statusLabel.setText(task.getFault().toString());
             }
         });

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSItemRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSItemRenderer.java?rev=884890&view=auto
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSItemRenderer.java (added)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/RSSItemRenderer.java Fri Nov 27 15:04:28 2009
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009 VMware, 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 org.apache.pivot.demos.rss;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import org.apache.pivot.collections.List;
+import org.apache.pivot.wtk.BoxPane;
+import org.apache.pivot.wtk.Insets;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.ListView;
+import org.apache.pivot.wtk.Orientation;
+import org.apache.pivot.xml.Element;
+import org.apache.pivot.xml.TextNode;
+import org.apache.pivot.xml.XMLSerializer;
+
+public class RSSItemRenderer extends BoxPane implements ListView.ItemRenderer {
+    private Label titleLabel = new Label();
+    private Label categoriesHeadingLabel = new Label("subject:");
+    private Label categoriesLabel = new Label();
+    private Label submitterHeadingLabel = new Label("submitter:");
+    private Label submitterLabel = new Label();
+
+    public RSSItemRenderer() {
+        super(Orientation.VERTICAL);
+
+        getStyles().put("padding", new Insets(2, 2, 8, 2));
+
+        add(titleLabel);
+
+        BoxPane categoriesBoxPane = new BoxPane();
+        add(categoriesBoxPane);
+
+        categoriesBoxPane.add(categoriesHeadingLabel);
+        categoriesBoxPane.add(categoriesLabel);
+
+        BoxPane submitterBoxPane = new BoxPane();
+        add(submitterBoxPane);
+
+        submitterBoxPane.add(submitterHeadingLabel);
+        submitterBoxPane.add(submitterLabel);
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        super.setSize(width, height);
+
+        // Since this component doesn't have a parent, it won't be validated
+        // via layout; ensure that it is valid here
+        validate();
+    }
+
+    @Override
+    public void render(Object item, int index, ListView listView, boolean selected,
+        boolean checked, boolean highlighted, boolean disabled) {
+        if (item != null) {
+            Element itemElement = (Element)item;
+
+            String title = XMLSerializer.getText(itemElement, "title");
+            titleLabel.setText(title);
+
+            String categories = "";
+            List<Element> categoryElements = XMLSerializer.getElements(itemElement, "category");
+            for (int i = 0, n = categoryElements.getLength(); i < n; i++) {
+                Element categoryElement = categoryElements.get(i);
+                TextNode categoryTextNode = (TextNode)categoryElement.get(0);
+                String category = categoryTextNode.getText();
+
+                if (i > 0) {
+                    categories += ", ";
+                }
+
+                categories += category;
+            }
+
+            categoriesLabel.setText(categories);
+
+            String submitter = XMLSerializer.getText(itemElement, "dz:submitter/dz:username");
+            submitterLabel.setText(submitter);
+        }
+
+        Font font = (Font)listView.getStyles().get("font");
+        Font largeFont = font.deriveFont(Font.BOLD, 14);
+        titleLabel.getStyles().put("font", largeFont);
+        categoriesLabel.getStyles().put("font", font);
+        submitterLabel.getStyles().put("font", font);
+
+        Color color;
+        if (listView.isEnabled() && !disabled) {
+            if (selected) {
+                if (listView.isFocused()) {
+                    color = (Color)listView.getStyles().get("selectionColor");
+                } else {
+                    color = (Color)listView.getStyles().get("inactiveSelectionColor");
+                }
+            } else {
+                color = (Color)listView.getStyles().get("color");
+            }
+        } else {
+            color = (Color)listView.getStyles().get("disabledColor");
+        }
+
+        titleLabel.getStyles().put("color", color);
+        categoriesHeadingLabel.getStyles().put("color", color);
+        categoriesLabel.getStyles().put("color", color);
+        submitterHeadingLabel.getStyles().put("color", color);
+        submitterLabel.getStyles().put("color", color);
+    }
+}

Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/rss_feed_demo.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/rss_feed_demo.wtkx?rev=884890&r1=884889&r2=884890&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/rss_feed_demo.wtkx (original)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/rss/rss_feed_demo.wtkx Fri Nov 27 15:04:28 2009
@@ -29,7 +29,11 @@
                         styles="{horizontalAlignment:'center', verticalAlignment:'center'}"/>
                     <ScrollPane horizontalScrollBarPolicy="fill_to_capacity">
                         <view>
-                            <ListView wtkx:id="feedListView"/>
+                            <ListView wtkx:id="feedListView">
+                                <itemRenderer>
+                                    <rss:RSSItemRenderer/>
+                                </itemRenderer>
+                            </ListView>
                         </view>
                     </ScrollPane>
                 </CardPane>