Subversion Repositories ES

Rev

Rev 18 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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