Subversion Repositories ES

Rev

Rev 17 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 17 Rev 18
1
/**
1
/**
2
 *
2
 *
3
 */
3
 */
4
package de.pointedears.converter.net;
4
package de.pointedears.converter.net;
5
5
6
import java.io.IOException;
6
import java.io.IOException;
7
import java.text.DateFormat;
7
import java.text.DateFormat;
8
import java.text.ParseException;
8
import java.text.ParseException;
9
import java.text.SimpleDateFormat;
9
import java.text.SimpleDateFormat;
10
import java.util.Date;
10
import java.util.Date;
11
import java.util.HashMap;
11
import java.util.HashMap;
12
12
13
import javax.xml.parsers.DocumentBuilder;
13
import javax.xml.parsers.DocumentBuilder;
14
import javax.xml.parsers.DocumentBuilderFactory;
14
import javax.xml.parsers.DocumentBuilderFactory;
15
import javax.xml.parsers.ParserConfigurationException;
15
import javax.xml.parsers.ParserConfigurationException;
16
import javax.xml.xpath.XPath;
16
import javax.xml.xpath.XPath;
17
import javax.xml.xpath.XPathConstants;
17
import javax.xml.xpath.XPathConstants;
18
import javax.xml.xpath.XPathExpression;
18
import javax.xml.xpath.XPathExpression;
19
import javax.xml.xpath.XPathExpressionException;
19
import javax.xml.xpath.XPathExpressionException;
20
import javax.xml.xpath.XPathFactory;
20
import javax.xml.xpath.XPathFactory;
21
21
22
import org.w3c.dom.Document;
22
import org.w3c.dom.Document;
23
import org.w3c.dom.Element;
23
import org.w3c.dom.Element;
24
import org.w3c.dom.NodeList;
24
import org.w3c.dom.NodeList;
25
import org.xml.sax.SAXException;
25
import org.xml.sax.SAXException;
26
26
27
import android.content.Intent;
27
import android.content.Intent;
28
import android.util.Log;
28
import android.util.Log;
29
import android.view.View;
29
import android.view.View;
30
import android.widget.TextView;
30
import android.widget.TextView;
31
import de.pointedears.converter.R;
31
import de.pointedears.converter.R;
32
import de.pointedears.converter.app.CurrenciesActivity;
32
import de.pointedears.converter.app.CurrenciesActivity;
33
import de.pointedears.converter.db.ConversionData;
33
import de.pointedears.converter.db.ConversionData;
34
import de.pointedears.converter.helpers.ConverterThread;
34
import de.pointedears.converter.helpers.ConverterThread;
35
import de.pointedears.converter.helpers.UpdateService;
35
import de.pointedears.converter.helpers.UpdateService;
36
36
37
/**
37
/**
38
 * @author pelinux
38
 * @author pelinux
39
 *
39
 *
40
 */
40
 */
41
public class RatesUpdater implements Runnable
41
public class RatesUpdater implements Runnable
42
{
42
{
-
 
43
  /*
-
 
44
   * XML markup attributes
-
 
45
   */
-
 
46
  private static final String ATTR_RATE = "rate"; //$NON-NLS-1$
-
 
47
  private static final String ATTR_CURRENCY = "currency"; //$NON-NLS-1$
-
 
48
  private static final String ATTR_TIME = "time"; //$NON-NLS-1$
-
 
49
43
  private static final String URL_ECB =
50
  private static final String URL_ECB =
44
    "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$
51
    "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$
45
52
46
  private final CurrenciesActivity activityContext;
53
  private final CurrenciesActivity activityContext;
47
  private ConverterThread updateThread = null;
54
  private ConverterThread updateThread = null;
48
55
49
  private final UpdateService service;
56
  private final UpdateService service;
50
57
51
  /**
58
  /**
-
 
59
   * @param activityContext
-
 
60
   *          The activityContext for this updater.
-
 
61
   *          FIXME: Required only for database access
52
   * @param updateService
62
   * @param updateService
53
   *
63
   *          The service that started this updater
54
   */
64
   */
55
  public RatesUpdater(CurrenciesActivity activityContext,
65
  public RatesUpdater(CurrenciesActivity activityContext,
56
    UpdateService updateService)
66
    UpdateService updateService)
57
  {
67
  {
58
    this.activityContext = activityContext;
68
    this.activityContext = activityContext;
59
    this.service = updateService;
69
    this.service = updateService;
60
  }
70
  }
61
71
62
  /**
72
  /**
63
   * @return the updateThread
73
   * @return the updateThread
64
   */
74
   */
65
  public ConverterThread getUpdateThread()
75
  public ConverterThread getUpdateThread()
66
  {
76
  {
67
    return this.updateThread;
77
    return this.updateThread;
68
  }
78
  }
69
79
70
  /**
80
  /**
71
   * @param updateThread
81
   * @param updateThread
-
 
82
   *          the thread that this updater is running in
72
   */
83
   */
73
  public void setUpdateThread(ConverterThread updateThread)
84
  public void setUpdateThread(ConverterThread updateThread)
74
  {
85
  {
75
    this.updateThread = updateThread;
86
    this.updateThread = updateThread;
76
  }
87
  }
77
88
78
  /*
89
  /*
79
   * (non-Javadoc)
90
   * (non-Javadoc)
80
   *
91
   *
81
   * @see java.lang.Runnable#run()
92
   * @see java.lang.Runnable#run()
82
   */
93
   */
83
  @Override
94
  @Override
84
  public void run()
95
  public void run()
85
  {
96
  {
86
    int len = 0;
97
    int len = 0;
87
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
98
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
88
    Date updated = new Date();
99
    Date updated = new Date();
89
100
90
    if (this.getUpdateThread() != null)
101
    if (this.getUpdateThread() != null)
91
    {
102
    {
92
      TextView textUpdating =
103
      TextView textUpdating =
93
        (TextView) this.activityContext
104
        (TextView) this.activityContext
94
          .findViewById(R.id.currencies_text_updating);
105
          .findViewById(R.id.currencies_text_updating);
95
      textUpdating.setVisibility(View.VISIBLE);
106
      textUpdating.setVisibility(View.VISIBLE);
96
107
97
      DocumentBuilderFactory documentBuilderFactory =
108
      DocumentBuilderFactory documentBuilderFactory =
98
        DocumentBuilderFactory.newInstance();
109
        DocumentBuilderFactory.newInstance();
99
      documentBuilderFactory.setNamespaceAware(true);
110
      documentBuilderFactory.setNamespaceAware(true);
100
      DocumentBuilder builder;
111
      DocumentBuilder builder;
101
      try
112
      try
102
      {
113
      {
103
        builder = documentBuilderFactory.newDocumentBuilder();
114
        builder = documentBuilderFactory.newDocumentBuilder();
104
        Document doc;
115
        Document doc;
105
        try
116
        try
106
        {
117
        {
107
          doc = builder.parse(RatesUpdater.URL_ECB);
118
          doc = builder.parse(RatesUpdater.URL_ECB);
108
          XPathFactory xpathFactory = XPathFactory.newInstance();
119
          XPathFactory xpathFactory = XPathFactory.newInstance();
109
          XPath xpath = xpathFactory.newXPath();
120
          XPath xpath = xpathFactory.newXPath();
110
          // NamespaceContextHelper namespaceContext =
121
          // NamespaceContextHelper namespaceContext =
111
          // new NamespaceContextHelper();
122
          // new NamespaceContextHelper();
112
          // namespaceContext.add("gesmes",
123
          // namespaceContext.add("gesmes",
113
          // "http://www.gesmes.org/xml/2002-08-01");
124
          // "http://www.gesmes.org/xml/2002-08-01");
114
          // xpath.setNamespaceContext(namespaceContext);
125
          // xpath.setNamespaceContext(namespaceContext);
115
126
116
          try
127
          try
117
          {
128
          {
118
            /*
129
            /*
119
             * FIXME: Why doesn't a simple "./Cube/Cube/Cube" work even with a
130
             * FIXME: Why doesn't a simple "./Cube/Cube/Cube" work even with a
120
             * namespace resolver?
131
             * namespace resolver?
121
             */
132
             */
122
            @SuppressWarnings("nls")
133
            @SuppressWarnings("nls")
123
            XPathExpression expr =
134
            XPathExpression expr =
124
              xpath
135
              xpath
125
                .compile("./*[local-name() = 'Cube']/*[local-name() = 'Cube']");
136
                .compile("./*[local-name() = 'Cube']/*[local-name() = 'Cube']");
126
            NodeList nodes = (NodeList)
137
            NodeList nodes = (NodeList)
127
              expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET);
138
              expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET);
128
            Element parentCube = (Element) nodes.item(0);
139
            Element parentCube = (Element) nodes.item(0);
129
            if (parentCube == null)
140
            if (parentCube == null)
130
            {
141
            {
131
              return;
142
              return;
132
            }
143
            }
133
144
134
            try
145
            try
135
            {
146
            {
-
 
147
              updated =
136
              updated = df.parse(parentCube.getAttribute("time"));
148
                df.parse(parentCube.getAttribute(RatesUpdater.ATTR_TIME));
137
            }
149
            }
138
            catch (ParseException e)
150
            catch (ParseException e)
139
            {
151
            {
140
              Log.e(this.getClass().toString(),
152
              Log.e(this.getClass().toString(),
141
                "Could not parse the `time' attribute into a Date", e);
153
                "Could not parse the `time' attribute into a Date", e); //$NON-NLS-1$
142
            }
154
            }
143
155
144
            expr =
156
            expr =
145
              xpath
157
              xpath
146
                .compile("./*[local-name()='Cube' and (@currency='CHF' or @currency='USD')]"); //$NON-NLS-1$
158
                .compile("./*[local-name()='Cube' and (@currency='CHF' or @currency='USD')]"); //$NON-NLS-1$
147
            nodes =
159
            nodes =
148
              (NodeList) expr.evaluate(parentCube, XPathConstants.NODESET);
160
              (NodeList) expr.evaluate(parentCube, XPathConstants.NODESET);
149
            NodeList childCubes = nodes;
161
            NodeList childCubes = nodes;
150
162
151
            len = childCubes.getLength();
163
            len = childCubes.getLength();
152
164
153
            HashMap<String, ConversionData> conversionRates =
165
            HashMap<String, ConversionData> conversionRates =
154
              this.activityContext.getConversionRates();
166
              this.activityContext.getConversionRates();
155
            for (int i = 0; i < len; ++i)
167
            for (int i = 0; i < len; ++i)
156
            {
168
            {
157
              Element item = (Element) childCubes.item(i);
169
              Element item = (Element) childCubes.item(i);
158
              String currency = item.getAttribute("currency");
170
              String currency = item.getAttribute(RatesUpdater.ATTR_CURRENCY);
159
171
160
              try
172
              try
161
              {
173
              {
162
                Double rate =
174
                Double rate =
163
                  Double.parseDouble(item.getAttribute("rate")); //$NON-NLS-1$
175
                  Double.parseDouble(item.getAttribute(RatesUpdater.ATTR_RATE));
164
                conversionRates
176
                conversionRates
165
                  .put(currency, new ConversionData(rate, updated));
177
                  .put(currency, new ConversionData(rate, updated));
166
              }
178
              }
167
              catch (NumberFormatException e)
179
              catch (NumberFormatException e)
168
              {
180
              {
169
181
170
              }
182
              }
171
            }
183
            }
172
184
173
            this.activityContext.getDatabase().writeConversionsToDatabase(null);
185
            this.activityContext.getDatabase().writeConversionsToDatabase(null);
174
            this.activityContext.fillTableRates();
-
 
175
          }
186
          }
176
          catch (XPathExpressionException e)
187
          catch (XPathExpressionException e)
177
          {
188
          {
178
            Log.e(this.getClass().toString(), "Error in XPath expression", e);
189
            Log.e(this.getClass().toString(), "Error in XPath expression", e); //$NON-NLS-1$
179
          }
190
          }
180
        }
191
        }
181
        catch (SAXException e)
192
        catch (SAXException e)
182
        {
193
        {
183
          Log.e(this.getClass().toString(),
194
          Log.e(this.getClass().toString(),
184
            "Exception while parsing external XML resource", e);
195
            "Exception while parsing external XML resource", e); //$NON-NLS-1$
185
        }
196
        }
186
        catch (IOException e)
197
        catch (IOException e)
187
        {
198
        {
188
          Log.e(this.getClass().toString(),
199
          Log.e(this.getClass().toString(),
189
            "I/O exception while parsing external XML resource", e);
200
            "I/O exception while parsing external XML resource", e); //$NON-NLS-1$
190
        }
201
        }
191
      }
202
      }
192
      catch (ParserConfigurationException e)
203
      catch (ParserConfigurationException e)
193
      {
204
      {
194
        Log.e(this.getClass().toString(),
205
        Log.e(this.getClass().toString(),
195
          "Document builder cannot be created", e);
206
          "Document builder cannot be created", e); //$NON-NLS-1$
196
      }
207
      }
197
208
198
      if (len > 0)
209
      if (len > 0)
199
      {
210
      {
200
        /*
211
        /*
201
         * Notify the activity that we are done (causes a notification to be
212
         * Notify the activity that we are done (causes a notification to be
202
         * shown)
213
         * shown)
203
         */
214
         */
204
        Intent intent = new Intent(UpdateService.ACTION_UPDATE);
215
        Intent intent = new Intent(UpdateService.ACTION_UPDATE);
205
        intent.putExtra(UpdateService.EXTRA_NUM_RATES, len);
216
        intent.putExtra(UpdateService.EXTRA_NUM_RATES, len);
206
        intent.putExtra(UpdateService.EXTRA_DATE, updated);
217
        intent.putExtra(UpdateService.EXTRA_DATE, updated);
207
        this.service.sendBroadcast(intent);
218
        this.service.sendBroadcast(intent);
208
      }
219
      }
209
220
210
      textUpdating.setVisibility(View.GONE);
221
      textUpdating.setVisibility(View.GONE);
211
    }
222
    }
212
  }
223
  }
213
}
224
}
214
 
225