/**
*
*/
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 android.view.View;
import android.widget.TextView;
import de.pointedears.converter.R;
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
{
private static final String URL_ECB =
"http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$
private final CurrenciesActivity activityContext
;
private ConverterThread updateThread =
null;
private final UpdateService service
;
/**
* @param updateService
*
*/
public RatesUpdater
(CurrenciesActivity activityContext,
UpdateService updateService
)
{
this.
activityContext = activityContext
;
this.
service = updateService
;
}
/**
* @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
()
{
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("time"));
}
catch (ParseException e
)
{
Log.
e(this.
getClass().
toString(),
"Could not parse the `time' attribute into a Date", e
);
}
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 =
this.
activityContext.
getConversionRates();
for (int i =
0; i
< len
; ++i
)
{
Element item =
(Element) childCubes.
item(i
);
String currency = item.
getAttribute("currency");
try
{
Double rate =
Double.
parseDouble(item.
getAttribute("rate")); //$NON-NLS-1$
conversionRates
.
put(currency,
new ConversionData
(rate, updated
));
}
catch (NumberFormatException e
)
{
}
}
this.
activityContext.
getDatabase().
writeConversionsToDatabase(null);
this.
activityContext.
fillTableRates();
}
catch (XPathExpressionException e
)
{
Log.
e(this.
getClass().
toString(),
"Error in XPath expression", e
);
}
}
catch (SAXException e
)
{
Log.
e(this.
getClass().
toString(),
"Exception while parsing external XML resource", e
);
}
catch (IOException e
)
{
Log.
e(this.
getClass().
toString(),
"I/O exception while parsing external XML resource", e
);
}
}
catch (ParserConfigurationException e
)
{
Log.
e(this.
getClass().
toString(),
"Document builder cannot be created", e
);
}
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);
}
}
}