Subversion Repositories ES

Compare Revisions

Last modification

Ignore whitespace Rev 16 → Rev 15

/trunk/src/com/nwalsh/namespace/package.html
File deleted
Property changes:
Deleted: svn:mime-type
## -1 +0,0 ##
-text/plain
\ No newline at end of property
Index: trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java
===================================================================
--- trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java (revision 16)
+++ trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java (nonexistent)
@@ -1,394 +0,0 @@
-/*
- * 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");
- }
- }
-
-}
/trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java
Property changes:
Deleted: svn:mime-type
## -1 +0,0 ##
-text/plain
\ No newline at end of property
Index: trunk/src/de/pointedears/converter/net/RatesUpdater.java
===================================================================
--- trunk/src/de/pointedears/converter/net/RatesUpdater.java (revision 16)
+++ trunk/src/de/pointedears/converter/net/RatesUpdater.java (nonexistent)
@@ -1,179 +0,0 @@
-/**
- *
- */
-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();
- }
- }
- }
-}
/trunk/src/de/pointedears/converter/net/RatesUpdater.java
Property changes:
Deleted: svn:mime-type
## -1 +0,0 ##
-text/plain
\ No newline at end of property
Index: trunk/src/de/pointedears/converter/app/CurrenciesActivity.java
===================================================================
--- trunk/src/de/pointedears/converter/app/CurrenciesActivity.java (revision 16)
+++ trunk/src/de/pointedears/converter/app/CurrenciesActivity.java (revision 15)
@@ -5,7 +5,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.os.Handler;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.Menu;
@@ -24,8 +23,7 @@
import android.widget.TextView;
import de.pointedears.converter.R;
import de.pointedears.converter.db.CurrenciesDatabase;
-import de.pointedears.converter.helpers.ConverterThread;
-import de.pointedears.converter.net.RatesUpdater;
+import de.pointedears.converter.helpers.CurrenciesUpdateThread;
/**
* Activity that implements currency conversion
@@ -60,12 +58,8 @@
private Spinner spinnerUnit2;
private CurrenciesDatabase db;
- private HashMap<String, Double> conversionRates;
- private ConverterThread updateThread;
- private Handler handler;
+ private HashMap<String, HashMap<String, Double>> conversionRates;
- private RatesUpdater updateRates;
-
/** Called when the activity is first created. */
@Override
@@ -192,13 +186,6 @@
editValue2.setText("");
}
});
-
- if (this.handler == null)
- {
- this.handler = new Handler();
- }
-
- this.updateThread = null;
}
/**
@@ -209,19 +196,27 @@
TableLayout tableRates =
(TableLayout) this.findViewById(R.id.currencies_table_rates);
- for (Entry<String, Double> factorEntry : this.conversionRates.entrySet())
+ for (String key : this.conversionRates.keySet())
{
- TableRow row = new TableRow(this);
+ for (Entry<String, Double> factorEntry : this.conversionRates.get(key)
+ .entrySet())
+ {
+ TableRow row = new TableRow(this);
- TextView columnCurrency1 = new TextView(this);
- columnCurrency1.setText(factorEntry.getKey());
- row.addView(columnCurrency1);
+ TextView columnCurrency1 = new TextView(this);
+ columnCurrency1.setText(key);
+ row.addView(columnCurrency1);
- TextView columnRate = new TextView(this);
- columnRate.setText(factorEntry.getValue().toString());
- row.addView(columnRate);
+ TextView columnCurrency2 = new TextView(this);
+ columnCurrency2.setText(factorEntry.getKey());
+ row.addView(columnCurrency2);
- tableRates.addView(row);
+ TextView columnRate = new TextView(this);
+ columnRate.setText(factorEntry.getValue().toString());
+ row.addView(columnRate);
+
+ tableRates.addView(row);
+ }
}
}
@@ -247,34 +242,17 @@
Double newValue = value;
- /*
- * NOTE: Had to do it the complicated way because somehow the Android SDK
- * won't get it another way
- */
- Double factorToEuro = null;
- if (selectedItemValue1 != null)
+ HashMap<String, Double> mapForCurrency =
+ this.conversionRates.get(selectedItemValue1);
+ if (mapForCurrency != null)
{
- factorToEuro = this.conversionRates.get(selectedItemValue1);
+ Double conversionFactor = mapForCurrency.get(selectedItemValue2);
+ if (conversionFactor != null)
+ {
+ newValue *= conversionFactor;
+ }
}
- if (factorToEuro == null)
- {
- factorToEuro = 1.0;
- }
-
- Double factorFromEuro = null;
- if (selectedItemValue2 != null)
- {
- factorFromEuro = this.conversionRates.get(selectedItemValue2);
- }
-
- if (factorFromEuro == null)
- {
- factorFromEuro = 1.0;
- }
-
- newValue = newValue / factorToEuro * factorFromEuro;
-
return newValue.toString();
}
@@ -308,45 +286,10 @@
switch (item.getItemId())
{
case R.id.item_options_update:
- if (this.updateThread == null)
- {
- this.updateRates = new RatesUpdater(this);
- this.updateThread =
- new ConverterThread(this.updateRates, this.handler);
- this.updateRates.setUpdateThread(this.updateThread);
- }
-
- try
- {
- this.updateThread.start();
- // this.editValue1.setText("Gestartet!");
- }
- catch (IllegalThreadStateException e)
- {
- // this.editValue1.setText("Bereits gestartet!");
- }
+ Thread updateThread = new CurrenciesUpdateThread();
+ updateThread.start();
return true;
- case R.id.item_options_quit:
- if (this.updateThread != null)
- {
- try
- {
- this.updateThread.join();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- }
-
- // this.editValue1.setText("Gestoppt -> Warten auf Start");
- }
- else
- {
- // this.editValue1.setText("Bereits gestoppt -> Warten auf Start");
- }
- return true;
-
default:
return super.onOptionsItemSelected(item);
}
/trunk/src/de/pointedears/converter/helpers/ConverterThread.java
File deleted
Property changes:
Deleted: svn:mime-type
## -1 +0,0 ##
-text/plain
\ No newline at end of property
Index: trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java
===================================================================
--- trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java (revision 16)
+++ trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java (nonexistent)
@@ -1,58 +0,0 @@
-package de.pointedears.converter.helpers;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-
-/**
- * @author pelinux
- *
- */
-public final class ConverterNamespaceContext implements NamespaceContext
-{
- private final HashMap<String, String> namespaces =
- new HashMap<String, String>();
-
- public void add(String prefix, String uri)
- {
- this.namespaces.put(prefix, uri);
- }
-
- @Override
- public Iterator getPrefixes(String namespaceURI)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getPrefix(String namespaceURI)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getNamespaceURI(String prefix)
- {
- if (prefix == null)
- {
- throw new NullPointerException("Null prefix");
- }
- else
- {
- if ("xml".equals(prefix))
- {
- return XMLConstants.XML_NS_URI;
- }
-
- String storedPrefix = this.namespaces.get(prefix);
- if (storedPrefix != null)
- {
- return storedPrefix;
- }
-
- return XMLConstants.NULL_NS_URI;
- }
- }
-}
\ No newline at end of file
/trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java
Property changes:
Deleted: svn:mime-type
## -1 +0,0 ##
-text/plain
\ No newline at end of property
Index: trunk/src/de/pointedears/converter/helpers/CurrenciesUpdateThread.java
===================================================================
--- trunk/src/de/pointedears/converter/helpers/CurrenciesUpdateThread.java (nonexistent)
+++ trunk/src/de/pointedears/converter/helpers/CurrenciesUpdateThread.java (revision 15)
@@ -0,0 +1,105 @@
+/**
+ * Defines a class to update table rates in the background
+ */
+package de.pointedears.converter.helpers;
+
+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;
+
+/**
+ * @author pelinux
+ *
+ */
+public class CurrenciesUpdateThread extends Thread
+{
+ private static final String URL_ECB =
+ "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$
+
+ /**
+ * Default constructor which sets the runnable
+ *
+ * @param runnable
+ */
+ private CurrenciesUpdateThread(Runnable runnable)
+ {
+ super(runnable);
+ }
+
+ /**
+ * Default constructor
+ */
+ public CurrenciesUpdateThread()
+ {
+ this(new Runnable() {
+ @Override
+ public void run()
+ {
+ DocumentBuilderFactory documentBuilderFactory =
+ DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ try
+ {
+ DocumentBuilder builder =
+ documentBuilderFactory.newDocumentBuilder();
+ try
+ {
+ Document doc = builder.parse(CurrenciesUpdateThread.URL_ECB);
+ XPathFactory xpathFactory = XPathFactory.newInstance();
+ XPath xpath = xpathFactory.newXPath();
+ try
+ {
+ XPathExpression expr = xpath.compile("/Cube/Cube//Cube"); //$NON-NLS-1$
+ Object result = expr.evaluate(doc, XPathConstants.NODESET);
+ NodeList nodes = (NodeList) result;
+ for (int i = 0, len = nodes.getLength(); 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").toString(); //$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();
+ }
+ }
+ });
+ }
+}
/trunk/src/de/pointedears/converter/helpers/CurrenciesUpdateThread.java
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java
===================================================================
--- trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java (revision 16)
+++ trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java (revision 15)
@@ -20,22 +20,36 @@
public class CurrenciesDatabase extends SQLiteOpenHelper
{
private static final String DATABASE_NAME = "currency.db"; //$NON-NLS-1$
- private static final int DATABASE_VERSION = 3;
+ private static final int DATABASE_VERSION = 2;
private static final String TABLE = "currency"; //$NON-NLS-1$
- private static final String COLUMN_CURRENCY = "currency1"; //$NON-NLS-1$
+ private static final String COLUMN_CURRENCY1 = "currency1"; //$NON-NLS-1$
+ private static final String COLUMN_CURRENCY2 = "currency2"; //$NON-NLS-1$
private static final String COLUMN_FACTOR = "factor"; //$NON-NLS-1$
- private static HashMap<String, Double> conversionRates =
- new HashMap<String, Double>();
+ private static HashMap<String, HashMap<String, Double>> conversionRates =
+ new HashMap<String, HashMap<String, Double>>();
static
{
- /* Default conversion rates from Euro (EUR) to other currencies */
- CurrenciesDatabase.conversionRates
- .put(CurrenciesActivity.VALUE_CHF, 1.3013);
- CurrenciesDatabase.conversionRates
- .put(CurrenciesActivity.VALUE_USD, 1.3521);
+ HashMap<String, Double> conversionFactors = new HashMap<String, Double>();
+ conversionFactors.put(CurrenciesActivity.VALUE_EUR, 0.767842293);
+ conversionFactors.put(CurrenciesActivity.VALUE_USD, 1.03413);
+ CurrenciesDatabase.conversionRates.put(CurrenciesActivity.VALUE_CHF,
+ conversionFactors);
+
+ conversionFactors = new HashMap<String, Double>();
+ conversionFactors.put(CurrenciesActivity.VALUE_CHF, 1.30235077);
+ conversionFactors.put(CurrenciesActivity.VALUE_USD, 1.3468);
+ CurrenciesDatabase.conversionRates.put(CurrenciesActivity.VALUE_EUR,
+ conversionFactors);
+
+ conversionFactors = new HashMap<String, Double>();
+ conversionFactors.put(CurrenciesActivity.VALUE_CHF, 0.966996412);
+ conversionFactors.put(CurrenciesActivity.VALUE_EUR, 0.742500743);
+ CurrenciesDatabase.conversionRates.put(CurrenciesActivity.VALUE_USD,
+ conversionFactors);
}
+ private final CurrenciesActivity context;
/**
* @param context
@@ -45,6 +59,7 @@
{
super(context, CurrenciesDatabase.DATABASE_NAME, null,
CurrenciesDatabase.DATABASE_VERSION);
+ this.context = context;
this.readConversionsFromDatabase();
}
@@ -60,21 +75,28 @@
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE IF NOT EXISTS " + CurrenciesDatabase.TABLE
- + " (" + CurrenciesDatabase.COLUMN_CURRENCY + " TEXT, "
+ + " (" + CurrenciesDatabase.COLUMN_CURRENCY1 + " TEXT, "
+ + CurrenciesDatabase.COLUMN_CURRENCY2 + " TEXT, "
+ CurrenciesDatabase.COLUMN_FACTOR
+ " NUMERIC"
+ ", CONSTRAINT unique_currency_pair UNIQUE ("
- + CurrenciesDatabase.COLUMN_CURRENCY + "))");
+ + CurrenciesDatabase.COLUMN_CURRENCY1 + ", "
+ + CurrenciesDatabase.COLUMN_CURRENCY2 + "))");
- HashMap<String, Double> currencyConversions =
+ HashMap<String, HashMap<String, Double>> currencyConversions =
this.getConversionRates();
- for (Entry<String, Double> factorEntry : currencyConversions.entrySet())
+ for (String key : currencyConversions.keySet())
{
- ContentValues values = new ContentValues();
- values.put(CurrenciesDatabase.COLUMN_CURRENCY, factorEntry.getKey());
- values.put(CurrenciesDatabase.COLUMN_FACTOR, factorEntry.getValue());
- db.insert(CurrenciesDatabase.TABLE, CurrenciesDatabase.COLUMN_FACTOR,
- values);
+ for (Entry<String, Double> factorEntry : currencyConversions.get(key)
+ .entrySet())
+ {
+ ContentValues values = new ContentValues();
+ values.put(CurrenciesDatabase.COLUMN_CURRENCY1, key);
+ values.put(CurrenciesDatabase.COLUMN_CURRENCY2, factorEntry.getKey());
+ values.put(CurrenciesDatabase.COLUMN_FACTOR, factorEntry.getValue());
+ db.insert(CurrenciesDatabase.TABLE, CurrenciesDatabase.COLUMN_FACTOR,
+ values);
+ }
}
}
@@ -97,7 +119,7 @@
/**
* @return
*/
- public HashMap<String, Double> getConversionRates()
+ public HashMap<String, HashMap<String, Double>> getConversionRates()
{
return CurrenciesDatabase.conversionRates;
}
@@ -113,9 +135,11 @@
/* Get database connection, but upgrade database first if necessary! */
SQLiteDatabase dbConn = this.getWritableDatabase();
+ @SuppressWarnings("nls")
Cursor cursor =
dbConn.query(true, CurrenciesDatabase.TABLE, null, null, null, null,
- null, CurrenciesDatabase.COLUMN_CURRENCY, null);
+ null, CurrenciesDatabase.COLUMN_CURRENCY1 + ","
+ + CurrenciesDatabase.COLUMN_CURRENCY2, null);
if (cursor != null)
{
@@ -123,7 +147,10 @@
{
int currency1Id =
cursor
- .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY);
+ .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY1);
+ int currency2Id =
+ cursor
+ .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY2);
int factorId =
cursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_FACTOR);
@@ -130,17 +157,58 @@
/* NOTE: Don't change the default values if the table is empty */
if (cursor.moveToFirst())
{
- HashMap<String, Double> newCurrencyConversions =
- new HashMap<String, Double>();
+ HashMap<String, HashMap<String, Double>> newCurrencyConversions =
+ new HashMap<String, HashMap<String, Double>>();
+ HashMap<String, Double> mapForCurrency = null;
+ String lastCurrency1Str = null;
+ String currency1Str;
do
{
- String currencyStr = cursor.getString(currency1Id);
+ currency1Str = cursor.getString(currency1Id);
+ String currency2Str = cursor.getString(currency2Id);
Double factor = cursor.getDouble(factorId);
- newCurrencyConversions.put(currencyStr, factor);
+
+ if (lastCurrency1Str == null
+ || !lastCurrency1Str.equals(currency1Str))
+ {
+ /*
+ * NOTE: Update outer map when we see a new currency;
+ * ORDER BY ensures we don't see a currency1 twice except
+ * consecutively
+ */
+ if (mapForCurrency != null)
+ {
+ newCurrencyConversions.put(lastCurrency1Str, mapForCurrency);
+ }
+
+ lastCurrency1Str = new String(currency1Str);
+
+ /* NOTE: New currency1: Reset inner map */
+ mapForCurrency = newCurrencyConversions.get(currency1Str);
+ }
+
+ /* If we did not see this currency1 before */
+ if (mapForCurrency == null)
+ {
+ mapForCurrency = new HashMap<String, Double>();
+ }
+
+ /*
+ * NOTE: Update inner map after each table row; assignment to
+ * mapForCurrency above ensures we are putting the factor
+ * into the correct map.
+ */
+ mapForCurrency.put(currency2Str, factor);
}
while (cursor.moveToNext());
+ /*
+ * NOTE: Update from last table row; cursor not empty, so we can
+ * skip the test for null
+ */
+ newCurrencyConversions.put(currency1Str, mapForCurrency);
+
CurrenciesDatabase.conversionRates = newCurrencyConversions;
}
}
@@ -169,9 +237,11 @@
{
SQLiteDatabase dbConn = this.getReadableDatabase();
+ @SuppressWarnings("nls")
Cursor myCursor =
dbConn.query(true, CurrenciesDatabase.TABLE, null, null, null, null,
- null, CurrenciesDatabase.COLUMN_CURRENCY, null);
+ null, CurrenciesDatabase.COLUMN_CURRENCY1 + ","
+ + CurrenciesDatabase.COLUMN_CURRENCY2, null);
@SuppressWarnings({ "unused", "nls" })
String queryResult = "";
@@ -181,7 +251,10 @@
{
int currency1Id =
myCursor
- .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY);
+ .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY1);
+ int currency2Id =
+ myCursor
+ .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY2);
int factorId =
myCursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_FACTOR);
@@ -189,12 +262,13 @@
{
do
{
- String currencyStr = myCursor.getString(currency1Id);
+ String currency1Str = myCursor.getString(currency1Id);
+ String currency2Str = myCursor.getString(currency2Id);
Double factor = myCursor.getDouble(factorId);
/* DEBUG */
queryResult +=
- "EUR --> " + currencyStr + ": " + factor + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ currency1Str + " --> " + currency2Str + ": " + factor + "\n";
}
while (myCursor.moveToNext());
}
/trunk/bin/Converter.apk
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/bin/resources.ap_
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/bin/classes.dex
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/res/values/strings.xml
10,8 → 10,9
<string name="temperatures_off_scale"><sup>*</sup> Theoretical value off the scale</string>
 
<string name="activity_currencies">Currencies</string>
<string name="currencies_currency"><b>Currency</b></string>
<string name="currencies_rate"><b>Rate (1 EUR = ?)</b></string>
<string name="currencies_currency1"><b>Currency 1</b></string>
<string name="currencies_currency2"><b>Currency 2</b></string>
<string name="currencies_rate"><b>Rate</b></string>
<string name="caption_update">Update table rates</string>
<string name="option_quit">Quit</string>
<!-- <string name="option_quit">Quit</string> -->
</resources>
/trunk/res/menu/options.xml
6,6 → 6,8
android:title="@string/caption_update" />
 
<!-- android:icon="@drawable/ic_quit" -->
<item android:id="@+id/item_options_quit"
<!--
<item android:id="@+id/quit"
android:title="@string/option_quit" />
-->
</menu>
/trunk/res/layout/activity_currencies.xml
33,11 → 33,12
android:layout_gravity="center_horizontal"></Button>
 
<TableLayout android:id="@+id/currencies_table_rates"
android:scrollbars="vertical" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:stretchColumns="*">
android:layout_height="fill_parent" android:layout_width="fill_parent"
android:scrollbars="vertical" android:stretchColumns="*">
<View android:layout_height="2dip" android:background="#FF909090" />
<TableRow>
<TextView android:text="@string/currencies_currency" />
<TextView android:text="@string/currencies_currency1" />
<TextView android:text="@string/currencies_currency2" />
<TextView android:text="@string/currencies_rate" />
</TableRow>
<View android:layout_height="1dip" android:background="#FF909090" />
/trunk/.classpath
1,6 → 1,6
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="com/nwalsh/namespace/" kind="src" path="src"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="output" path="bin"/>