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>