0,0 → 1,179 |
/** |
* |
*/ |
package de.pointedears.converter.net; |
|
import java.io.IOException; |
|
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.XPathExpression; |
import javax.xml.xpath.XPathExpressionException; |
import javax.xml.xpath.XPathFactory; |
|
import org.w3c.dom.Document; |
import org.w3c.dom.NamedNodeMap; |
import org.w3c.dom.Node; |
import org.w3c.dom.NodeList; |
import org.xml.sax.SAXException; |
|
import android.app.Notification; |
import android.app.NotificationManager; |
import android.app.PendingIntent; |
import android.content.Context; |
import android.content.Intent; |
import de.pointedears.converter.R; |
import de.pointedears.converter.helpers.ConverterThread; |
|
/** |
* @author pelinux |
* |
*/ |
public class RatesUpdater implements Runnable |
{ |
private static final String URL_ECB = |
"http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$ |
|
private final Context activityContext; |
private ConverterThread updateThread = null; |
|
/** |
* |
*/ |
public RatesUpdater(Context activityContext) |
{ |
this.activityContext = activityContext; |
} |
|
/** |
* @return the updateThread |
*/ |
public ConverterThread getUpdateThread() |
{ |
return this.updateThread; |
} |
|
/** |
* @param updateThread |
*/ |
public void setUpdateThread(ConverterThread updateThread) |
{ |
this.updateThread = updateThread; |
} |
|
/* |
* (non-Javadoc) |
* |
* @see java.lang.Runnable#run() |
*/ |
@Override |
public void run() |
{ |
if (this.getUpdateThread() != null) |
{ |
// CurrenciesActivity.this.editValue1.setText("42"); |
|
DocumentBuilderFactory documentBuilderFactory = |
DocumentBuilderFactory.newInstance(); |
documentBuilderFactory.setNamespaceAware(true); |
try |
{ |
DocumentBuilder builder = |
documentBuilderFactory.newDocumentBuilder(); |
try |
{ |
Document doc = builder.parse(RatesUpdater.URL_ECB); |
XPathFactory xpathFactory = XPathFactory.newInstance(); |
XPath xpath = xpathFactory.newXPath(); |
// NamespaceContextHelper namespaceContext = |
// new NamespaceContextHelper(); |
// namespaceContext.add("gesmes", |
// "http://www.gesmes.org/xml/2002-08-01"); |
// xpath.setNamespaceContext(namespaceContext); |
|
try |
{ |
/* |
* FIXME: Why doesn't a simple "./Cube/Cube/Cube" work even with a |
* namespace resolver? |
*/ |
XPathExpression expr = |
xpath |
.compile("./*[local-name() = 'Cube']/*[local-name() = 'Cube']/*[local-name() = 'Cube']"); //$NON-NLS-1$ |
Object result = |
expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET); |
NodeList nodes = (NodeList) result; |
|
int len = nodes.getLength(); |
|
String ns = Context.NOTIFICATION_SERVICE; |
NotificationManager mNotificationManager = |
(NotificationManager) this.activityContext |
.getSystemService(ns); |
|
int icon = R.drawable.icon; |
CharSequence tickerText = "Found " + len + " nodes!"; |
long when = System.currentTimeMillis(); |
|
Notification notification = |
new Notification(icon, tickerText, when); |
|
Context applicationContext = |
this.activityContext.getApplicationContext(); |
CharSequence contentTitle = "Converter"; |
CharSequence contentText = "Found " + len + " nodes!"; |
Intent notificationIntent = |
new Intent(this.activityContext, this.activityContext.getClass()); |
PendingIntent contentIntent = |
PendingIntent.getActivity(this.activityContext, 0, |
notificationIntent, 0); |
|
notification.setLatestEventInfo(applicationContext, contentTitle, |
contentText, |
contentIntent); |
|
// private static final int HELLO_ID = 1; |
|
mNotificationManager.notify(1, notification); |
|
for (int i = 0; i < len; ++i) |
{ |
Node item = nodes.item(i); |
NamedNodeMap attributes = item.getAttributes(); |
String currency = |
attributes |
.getNamedItem("currency").getNodeValue(); //$NON-NLS-1$ |
String rate = attributes.getNamedItem("rate").getNodeValue(); //$NON-NLS-1$ |
|
/* TODO: Update UI */ |
System.out.println(currency + ": " + rate); //$NON-NLS-1$ |
} |
} |
catch (XPathExpressionException e) |
{ |
// TODO Auto-generated catch block |
e.printStackTrace(); |
} |
} |
catch (SAXException e) |
{ |
// TODO Auto-generated catch block |
e.printStackTrace(); |
} |
catch (IOException e) |
{ |
// TODO Auto-generated catch block |
e.printStackTrace(); |
} |
} |
catch (ParserConfigurationException e) |
{ |
// TODO Auto-generated catch block |
e.printStackTrace(); |
} |
} |
} |
} |
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: com/nwalsh/namespace/NamespaceContextHelper.java |
=================================================================== |
--- com/nwalsh/namespace/NamespaceContextHelper.java (nonexistent) |
+++ com/nwalsh/namespace/NamespaceContextHelper.java (revision 16) |
@@ -0,0 +1,394 @@ |
+/* |
+ * The contents of this file are subject to the terms |
+ * of the Common Development and Distribution License |
+ * (the "License"). You may not use this file except |
+ * in compliance with the License. |
+ * |
+ * You can obtain a copy of the license at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html. |
+ * See the License for the specific language governing |
+ * permissions and limitations under the License. |
+ * |
+ * When distributing Covered Code, include this CDDL |
+ * HEADER in each file and include the License file at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html |
+ * If applicable add the following below this CDDL HEADER |
+ * with the fields enclosed by brackets "[]" replaced with |
+ * your own identifying information: Portions Copyright |
+ * [year] [name of copyright owner] |
+ */ |
+ |
+/* |
+ * $Id: NamespaceContextHelper.java,v 1.2 2006-03-28 20:54:02 ndw Exp $ |
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. |
+ * Portions Copyright 2010 Thomas 'PointedEars' Lahn |
+ */ |
+ |
+package com.nwalsh.namespace; |
+ |
+import java.util.Enumeration; |
+import java.util.Hashtable; |
+import java.util.Iterator; |
+ |
+import javax.xml.namespace.NamespaceContext; |
+ |
+/* |
+ * NOTE: Skip XML 1.1 validity tests because we don't want to recompile |
+ * org.apache.xerces for Android -- PointedEars |
+ */ |
+// import org.apache.xerces.util.XML11Char; |
+ |
+/** |
+ * Helper implementation of the javax.xml.namespace.NamespaceContext interface. |
+ * |
+ * <p> |
+ * This class implements the JAXP (1.3+) |
+ * {@link javax.xml.namespace.NamespaceContext} interface. This is the interface |
+ * used by the JAXP XPath APIs to establish namespace bindings for XPath |
+ * expressions. |
+ * <p> |
+ * |
+ * <p> |
+ * There are two errors (in retrospect) with respect to the namespace context in |
+ * the XPath API. First, there's no way to construct a new one. Given an XPath |
+ * you can find out what context it is using, but if you want to construct a new |
+ * expression, there's no standard class that you can instantiate to build a new |
+ * context. Second, the {@link javax.xml.namespace.NamespaceContext} interface |
+ * is obviously (again, in retrospect) missing a method that returns an iterator |
+ * that will allow you to find <emph>all</emph> the namespace URIs (and/or |
+ * prefixes, which would be equivalent) in the context. |
+ * </p> |
+ * |
+ * <p> |
+ * This class addresses the first error by providing an object that you can |
+ * instantiate that implements the {@link javax.xml.namespace.NamespaceContext} |
+ * interface. It's not a <emph>standard</emph> class, but it at least saves you |
+ * the trouble of writing it yourself. (Feel free to move it into your own |
+ * package, of course.) |
+ * </p> |
+ * |
+ * <p> |
+ * There's really no way to address the second error. An interface, like |
+ * {@link javax.xml.namespace.NamespaceContext}, is immutable once released into |
+ * the wild in the Java platform. (This is a consequence of backwards |
+ * compatibility rules.) To really address the problem, we'll have to invent a |
+ * new interface or provide an alternative abstract class that implementations |
+ * will be required to use, or something. However, as an experiment, this class |
+ * implements a couple of extra methods that we might wish had been in the |
+ * interface. These methods are carefully identified as non-standard. Having |
+ * them here really isn't all that useful because your underlying XPath |
+ * implementation isn't likely to return instances of this class. |
+ * </p> |
+ * |
+ * <p> |
+ * There are three ways to instantiate this class: |
+ * </p> |
+ * |
+ * <ol> |
+ * <li>The no-argument constructor produces an initially empty namespace |
+ * context.</li> |
+ * <li>Another constructor takes a prefix and URI and produces a namespace |
+ * context with that binding.</li> |
+ * <li>Finally, there's a constructor that takes a hash of namespace/uri pairs |
+ * and produces a namespace context with those initial bindings.</li> |
+ * <li>The obvious constructor, one that takes an existing |
+ * {@link javax.xml.namespace.NamespaceContext} so that you can extend it, isn't |
+ * there because you can't get the current bindings from that interface; see the |
+ * aforementioned bug.</li> |
+ * </ol> |
+ * |
+ * <p> |
+ * After the object has been instantiated, you can call the |
+ * {@link #add(String,String)} method to add additional bindings to the |
+ * namespace context. Because I'm not sure how and where the XPath API |
+ * implementations might save pointers to the context object, I've imposed a |
+ * number of rules designed to make sure that the context remains coherent: |
+ * </p> |
+ * |
+ * <ul> |
+ * <li>Namespace bindings can only be added, not removed.</li> |
+ * <li>Once a prefix is bound, its binding cannot be changed.</li> |
+ * <li>The XML restrictions on the 'xml' prefix, the 'xmlns' prefix, and their |
+ * respective namespace URIs are enforced.</li> |
+ * <li>Namespace prefixes must be valid NCNames (or "" for the default |
+ * namespace). Note that unprefixed element and attribute names in an XPath |
+ * expression can <em>never</em> match a name that's in a namespace. In |
+ * particular, setting the default namespace won't have that effect.</li> |
+ * </ul> |
+ * |
+ * <p> |
+ * Even with these rules, you can't assume that the context is thread safe. |
+ * Don't allow it to be changed while someone else is reading it. |
+ * </p> |
+ * |
+ * <p> |
+ * <b>Other notes:</b> |
+ * </p> |
+ * |
+ * <ul> |
+ * <li>There's no <code>getNamespaceURIs(String prefix)</code> method because |
+ * there can be at most one URI bound to any given prefix. Wrapping an interator |
+ * around the mapping available with {@link #getNamespaceURI(String)} seemed |
+ * silly.</li> |
+ * <li>This class relies on {@link org.apache.xerces.util.XML11Char} to test |
+ * that the prefixes are valid NCNames. Note that this means that they're valid |
+ * XML 1.1 names. XML 1.1 names are a superset of XML 1.0 names and it didn't |
+ * seem worth the extra effort that would be required to allow the user to |
+ * choose XML 1.0 or XML 1.1. You might not think it's worth the effort to check |
+ * at all. Fair enough.</li> |
+ * <li>I've used generics here and there to make the JDK 1.5 compiler stop |
+ * complaining. Just delete them for JDK 1.4 and everything should work fine.</li> |
+ * </ul> |
+ * |
+ * @author <a href="mailto:Norman.Walsh@Sun.COM">Norman Walsh</a> |
+ * @version $Revision: 1.2 $, $Date: 2006-03-28 20:54:02 $ |
+ * @see <a href="http://jaxp.dev.java.net/">Java API for XML Processing</a> |
+ * @see <a href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames"> Namespaces |
+ * in XML</a> |
+ * @see <a href="http://www.w3.org/XML/xml-names-19990114-errata"> Namespaces in |
+ * XML Errata</a> |
+ */ |
+public class NamespaceContextHelper implements NamespaceContext |
+{ |
+ private final Hashtable<String, String> ns = new Hashtable<String, String>(); |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates an empty namespace context. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper() |
+ { |
+ } |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates a namespace context with the bindings specified in |
+ * <code>initialNamespaces</code>. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper(Hashtable initialNamespaces) |
+ { |
+ Enumeration keys = initialNamespaces.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String prefix = (String) keys.nextElement(); |
+ String uri = (String) initialNamespaces.get(prefix); |
+ |
+ this.add(prefix, uri); |
+ } |
+ } |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates a namespace context with the specified <code>prefix</code> bound to |
+ * <code>uri</code>. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper(String prefix, String uri) |
+ { |
+ this.add(prefix, uri); |
+ } |
+ |
+ /** |
+ * Adds a new prefix/uri binding to the namespace context. |
+ * |
+ * @throws NullPointerException |
+ * if the <code>prefix</code> or <code>uri</code> is |
+ * <code>null</code>. |
+ * @throws IllegalArgumentException |
+ * if the caller attempts to change the binding of |
+ * <code>prefix</code>, if the caller attempts to bind the prefix " |
+ * <code>xml</code>" |
+ * or the namespace " |
+ * <code>http://www.w3.org/XML/1998/namespace</code>" incorrectly, |
+ * if the caller attempts to bind the prefix "<code>xmlns</code>" or |
+ * the namespace |
+ * "<code>http://www.w3.org/2000/xmlns</code>", or if the |
+ * <code>prefix</code> is |
+ * not a valid NCName. |
+ */ |
+ public void add(String prefix, String uri) |
+ { |
+ if (prefix == null || uri == null) |
+ { |
+ throw new NullPointerException( |
+ "Null prefix or uri passed to NamespaceContextHelper"); |
+ } |
+ |
+ if (this.ns.containsKey(prefix)) |
+ { |
+ String curURI = this.ns.get(prefix); |
+ if (uri.equals(curURI)) |
+ { |
+ return; |
+ } |
+ throw new IllegalArgumentException( |
+ "Attempt to change binding in NamespaceContextHelper"); |
+ } |
+ |
+ if ("xml".equals(prefix) |
+ && !"http://www.w3.org/XML/1998/namespace".equals(uri)) |
+ { |
+ throw new IllegalArgumentException( |
+ "The prefix 'xml' can only be bound to 'http://www.w3.org/XML/1998/namespace' in NamespaceContextHelper"); |
+ } |
+ |
+ if ("http://www.w3.org/XML/1998/namespace".equals(uri) |
+ && !"xml".equals(prefix)) |
+ { |
+ throw new IllegalArgumentException( |
+ "The namespace 'http://www.w3.org/XML/1998/namespace' can only have the prefix 'xml' in NamespaceContextHelper"); |
+ } |
+ |
+ if ("xmlns".equals(prefix) |
+ || "http://www.w3.org/2000/xmlns".equals(uri)) |
+ { |
+ throw new IllegalArgumentException( |
+ "Neither the prefix 'xmlns' nor the URI 'http://www.w3.org/2000/xmlns' can be bound in NamespaceContextHelper"); |
+ } |
+ |
+ if ("".equals(prefix)) |
+ { |
+ this.ns.put(prefix, uri); |
+ } |
+ else |
+ { |
+ /* |
+ * NOTE: Skip XML 1.1 validity tests because we don't want to recompile |
+ * org.apache.xerces for Android -- PointedEars |
+ */ |
+ // if (XML11Char.isXML11ValidNCName (prefix)) { |
+ this.ns.put(prefix, uri); |
+ // } else { |
+ // throw new IllegalArgumentException |
+ // ("Prefix is not a valid NCName in NamespaceContextHelper"); |
+ // } |
+ } |
+ } |
+ |
+ /** Implements the NamespaceContext getNamespaceURI method. */ |
+ public String getNamespaceURI(String prefix) |
+ { |
+ return this.ns.get(prefix); |
+ } |
+ |
+ /** Implements the NamespaceContext getPrefix method. */ |
+ public String getPrefix(String namespaceURI) |
+ { |
+ if (this.ns.containsValue(namespaceURI)) |
+ { |
+ Enumeration<String> keys = this.ns.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String pfx = keys.nextElement(); |
+ String uri = this.ns.get(pfx); |
+ if (namespaceURI.equals(uri)) |
+ { |
+ return pfx; |
+ } |
+ } |
+ } |
+ return null; |
+ } |
+ |
+ /** |
+ * Implements a <emph>NON STANDARD</emph> method for finding all of the |
+ * prefixes |
+ * in the namespace context. |
+ * |
+ * <p> |
+ * Returns an iterator over all of the prefixes in the namespace context. Note |
+ * that multiple prefixes may be bound to the same URI. |
+ * </p> |
+ */ |
+ public Iterator getPrefixes() |
+ { |
+ return this.getPrefixes(null); |
+ } |
+ |
+ /** Implements the NamespaceContext getPrefixes method. */ |
+ public Iterator getPrefixes(String namespaceURI) |
+ { |
+ return new NSIterator(this.ns, namespaceURI); |
+ } |
+ |
+ /** |
+ * Implements a <emph>NON STANDARD</emph> method for finding all of the |
+ * namespace URIs |
+ * in the namespace context. |
+ * |
+ * <p> |
+ * Returns an iterator over all of the namespace URIs in the namespace |
+ * context. Note that each namespace URI is returned exactly once, even if it |
+ * is bound to several different prefixes. |
+ * </p> |
+ */ |
+ public Iterator getNamespaceURIs() |
+ { |
+ // Make sure each URI is returned at most once... |
+ Hashtable<String, String> uriHash = new Hashtable<String, String>(); |
+ Enumeration<String> keys = this.ns.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String pfx = keys.nextElement(); |
+ String uri = this.ns.get(pfx); |
+ if (!uriHash.containsKey(uri)) |
+ { |
+ uriHash.put(uri, pfx); |
+ } |
+ } |
+ |
+ return new NSIterator(uriHash, null); |
+ } |
+ |
+ /** Implements the Iterator interface over namespace bindings. */ |
+ private class NSIterator implements Iterator |
+ { |
+ private Enumeration<String> keys; |
+ |
+ public NSIterator(Hashtable<String, String> hash, String value) |
+ { |
+ this.keys = hash.keys(); |
+ if (value != null) |
+ { |
+ // We have to copy the hash to get only the keys that have the specified |
+ // value |
+ Hashtable<String, String> vHash = new Hashtable<String, String>(); |
+ while (this.keys.hasMoreElements()) |
+ { |
+ String key = this.keys.nextElement(); |
+ String val = hash.get(key); |
+ if (val.equals(value)) |
+ { |
+ vHash.put(key, val); |
+ } |
+ } |
+ this.keys = vHash.keys(); |
+ } |
+ } |
+ |
+ public boolean hasNext() |
+ { |
+ return this.keys.hasMoreElements(); |
+ } |
+ |
+ public String next() |
+ { |
+ return this.keys.nextElement(); |
+ } |
+ |
+ public void remove() |
+ { |
+ throw new UnsupportedOperationException( |
+ "Cannot remove prefix in NamespaceContextHelper"); |
+ } |
+ } |
+ |
+} |