Rev 18 |
View as "text/plain" |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
1
/**
*
*/
package de.pointedears.converter.net;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
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.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.content.Intent;
import android.util.Log;
import de.pointedears.converter.app.CurrenciesActivity;
import de.pointedears.converter.db.ConversionData;
import de.pointedears.converter.helpers.ConverterThread;
import de.pointedears.converter.helpers.UpdateService;
/**
* @author pelinux
*
*/
public class RatesUpdater
implements Runnable
{
/*
* XML markup attributes
*/
private static final String ATTR_RATE =
"rate"; //$NON-NLS-1$
private static final String ATTR_CURRENCY =
"currency"; //$NON-NLS-1$
private static final String ATTR_TIME =
"time"; //$NON-NLS-1$
private static final String URL_ECB =
"http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$
private ConverterThread updateThread =
null;
private final UpdateService service
;
/**
* @param activityContext
* The activityContext for this updater.
* FIXME: Required only for database access
* @param updateService
* The service that started this updater
*/
public RatesUpdater
(UpdateService updateService
)
{
this.
service = updateService
;
}
/**
* @return the updateThread
*/
public ConverterThread getUpdateThread
()
{
return this.
updateThread;
}
/**
* @param updateThread
* the thread that this updater is running in
*/
public void setUpdateThread
(ConverterThread updateThread
)
{
this.
updateThread = updateThread
;
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@
Override
public void run
()
{
int len =
0;
DateFormat df =
new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
Date updated =
new Date();
if (this.
getUpdateThread() !=
null)
{
// TextView textUpdating =
// (TextView) this.activityContext
// .findViewById(R.id.currencies_text_updating);
// textUpdating.setVisibility(View.VISIBLE);
DocumentBuilderFactory documentBuilderFactory =
DocumentBuilderFactory.
newInstance();
documentBuilderFactory.
setNamespaceAware(true);
DocumentBuilder builder
;
try
{
builder = documentBuilderFactory.
newDocumentBuilder();
Document doc
;
try
{
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?
*/
@
SuppressWarnings("nls")
XPathExpression expr =
xpath
.
compile("./*[local-name() = 'Cube']/*[local-name() = 'Cube']");
NodeList nodes =
(NodeList)
expr.
evaluate(doc.
getDocumentElement(),
XPathConstants.
NODESET);
Element parentCube =
(Element) nodes.
item(0);
if (parentCube ==
null)
{
return;
}
try
{
updated =
df.
parse(parentCube.
getAttribute(RatesUpdater.
ATTR_TIME));
}
catch (ParseException e
)
{
Log.
e(this.
getClass().
toString(),
"Could not parse the `time' attribute into a Date", e
); //$NON-NLS-1$
}
expr =
xpath
.
compile("./*[local-name()='Cube' and (@currency='CHF' or @currency='USD')]"); //$NON-NLS-1$
nodes =
(NodeList) expr.
evaluate(parentCube,
XPathConstants.
NODESET);
NodeList childCubes = nodes
;
len = childCubes.
getLength();
HashMap<String, ConversionData
> conversionRates =
CurrenciesActivity.
getConversionRates();
for (int i =
0; i
< len
; ++i
)
{
Element item =
(Element) childCubes.
item(i
);
String currency = item.
getAttribute(RatesUpdater.
ATTR_CURRENCY);
try
{
Double rate =
Double.
parseDouble(item.
getAttribute(RatesUpdater.
ATTR_RATE));
conversionRates
.
put(currency,
new ConversionData
(rate, updated
));
}
catch (NumberFormatException e
)
{
}
}
CurrenciesActivity.
getDatabase().
writeConversionsToDatabase(null);
}
catch (XPathExpressionException e
)
{
Log.
e(this.
getClass().
toString(),
"Error in XPath expression", e
); //$NON-NLS-1$
}
}
catch (SAXException e
)
{
Log.
e(this.
getClass().
toString(),
"Exception while parsing external XML resource", e
); //$NON-NLS-1$
}
catch (IOException e
)
{
Log.
e(this.
getClass().
toString(),
"I/O exception while parsing external XML resource", e
); //$NON-NLS-1$
}
}
catch (ParserConfigurationException e
)
{
Log.
e(this.
getClass().
toString(),
"Document builder cannot be created", e
); //$NON-NLS-1$
}
if (len
> 0)
{
/*
* Notify the activity that we are done (causes a notification to be
* shown)
*/
Intent intent =
new Intent
(UpdateService.
ACTION_UPDATE);
intent.
putExtra(UpdateService.
EXTRA_NUM_RATES, len
);
intent.
putExtra(UpdateService.
EXTRA_DATE, updated
);
this.
service.
sendBroadcast(intent
);
}
// textUpdating.setVisibility(View.GONE);
}
}
}