/ocr/ocrservice/src/com/googlecode/eyesfree/ocr/intent/XmlLoader.java

http://eyes-free.googlecode.com/ · Java · 249 lines · 177 code · 50 blank · 22 comment · 16 complexity · cc185d1ed9ae46c2bc20228a1a636129 MD5 · raw file

  1. /*
  2. * Copyright (C) 2011 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.googlecode.eyesfree.ocr.intent;
  17. import android.app.Activity;
  18. import android.app.ProgressDialog;
  19. import android.os.AsyncTask;
  20. import android.util.Log;
  21. import com.googlecode.eyesfree.ocr.R;
  22. import com.googlecode.eyesfree.ocr.client.Language;
  23. import com.googlecode.eyesfree.ocr.intent.LanguagesActivity.LanguageData;
  24. import org.w3c.dom.Document;
  25. import org.w3c.dom.NamedNodeMap;
  26. import org.w3c.dom.Node;
  27. import org.w3c.dom.NodeList;
  28. import org.xml.sax.InputSource;
  29. import org.xml.sax.SAXException;
  30. import java.io.ByteArrayOutputStream;
  31. import java.io.IOException;
  32. import java.io.StringReader;
  33. import java.net.HttpURLConnection;
  34. import java.net.MalformedURLException;
  35. import java.net.URL;
  36. import java.util.List;
  37. import java.util.TreeSet;
  38. import javax.xml.parsers.DocumentBuilder;
  39. import javax.xml.parsers.DocumentBuilderFactory;
  40. import javax.xml.parsers.ParserConfigurationException;
  41. import javax.xml.transform.Transformer;
  42. import javax.xml.transform.TransformerException;
  43. import javax.xml.transform.TransformerFactory;
  44. import javax.xml.transform.dom.DOMSource;
  45. import javax.xml.transform.stream.StreamResult;
  46. /**
  47. * @author alanv@google.com (Alan Viverette)
  48. */
  49. class XmlLoader extends AsyncTask<String, Integer, TreeSet<LanguageData>> {
  50. private static final String TAG = "XmlLoader";
  51. private static final String TYPE_LANGUAGE = "language";
  52. private static final int VERSION = 3;
  53. private final List<Language> mAvailable;
  54. private String mCachedXml;
  55. private ProgressDialog mDialog;
  56. public XmlLoader(Activity activity, List<Language> available) {
  57. mAvailable = available;
  58. mCachedXml = null;
  59. String message = activity.getString(R.string.manage_loading);
  60. mDialog = new ProgressDialog(activity);
  61. mDialog.setMax(100);
  62. mDialog.setProgress(0);
  63. mDialog.setIndeterminate(false);
  64. mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  65. mDialog.setMessage(message);
  66. mDialog.setCancelable(true);
  67. mDialog.setOwnerActivity(activity);
  68. }
  69. public XmlLoader setCachedXml(String cachedXml) {
  70. mCachedXml = cachedXml;
  71. return this;
  72. }
  73. protected String getCachedXml() {
  74. return mCachedXml;
  75. }
  76. @Override
  77. protected void onPreExecute() {
  78. mDialog.show();
  79. }
  80. @Override
  81. protected void onProgressUpdate(Integer... progress) {
  82. mDialog.setProgress(progress[0]);
  83. }
  84. @Override
  85. protected void onPostExecute(TreeSet<LanguageData> result) {
  86. mDialog.dismiss();
  87. }
  88. @Override
  89. protected TreeSet<LanguageData> doInBackground(String... urls) {
  90. Document xmldoc = null;
  91. if (mCachedXml != null) {
  92. xmldoc = loadFromCachedXML();
  93. } else {
  94. xmldoc = loadFromURL(urls[0]);
  95. }
  96. if (xmldoc == null) {
  97. return null;
  98. }
  99. Node languages = xmldoc.getFirstChild();
  100. if (languages == null || !languages.getNodeName().equals("languages")) {
  101. Log.e(TAG, "Missing languages node");
  102. return null;
  103. }
  104. NamedNodeMap attr = languages.getAttributes();
  105. Node node = attr.getNamedItem("version");
  106. // Check version of remote languages list
  107. int version = Integer.parseInt(node.getNodeValue());
  108. if (version != VERSION) {
  109. Log.e(TAG, "Incorrect version (is " + VERSION + ", should be " + version);
  110. return null;
  111. }
  112. // Load the ISO 639-2 name of each language into a set
  113. TreeSet<String> available6392 = new TreeSet<String>();
  114. for (Language lang : mAvailable) {
  115. available6392.add(lang.iso_639_2);
  116. }
  117. // Traverse the XML document and create LanguageData objects
  118. final TreeSet<LanguageData> displayLanguages = new TreeSet<LanguageData>();
  119. final NodeList nodes = languages.getChildNodes();
  120. final int count = nodes.getLength();
  121. for (int i = 0; i < count; i++) {
  122. publishProgress(100 * i / count);
  123. Node language = nodes.item(i);
  124. if (TYPE_LANGUAGE.equals(language.getNodeName())) {
  125. LanguageData data = inflateLanguage(language, available6392);
  126. // Display the language if it is installed or visible
  127. if (data.installed || !data.hidden) {
  128. displayLanguages.add(data);
  129. }
  130. }
  131. }
  132. return displayLanguages;
  133. }
  134. private Document loadFromCachedXML() {
  135. Document xmldoc = null;
  136. try {
  137. InputSource source = new InputSource(new StringReader(mCachedXml));
  138. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  139. DocumentBuilder builder = factory.newDocumentBuilder();
  140. xmldoc = builder.parse(source);
  141. } catch (MalformedURLException e) {
  142. e.printStackTrace();
  143. } catch (IOException e) {
  144. e.printStackTrace();
  145. } catch (ParserConfigurationException e) {
  146. e.printStackTrace();
  147. } catch (SAXException e) {
  148. e.printStackTrace();
  149. }
  150. mCachedXml = null;
  151. return xmldoc;
  152. }
  153. private Document loadFromURL(String url) {
  154. Document xmldoc = null;
  155. try {
  156. URL xmlUrl = new URL(url);
  157. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  158. DocumentBuilder builder = factory.newDocumentBuilder();
  159. HttpURLConnection http = (HttpURLConnection) xmlUrl.openConnection();
  160. xmldoc = builder.parse(http.getInputStream());
  161. DOMSource xmlSource = new DOMSource(xmldoc);
  162. ByteArrayOutputStream output = new ByteArrayOutputStream();
  163. StreamResult outputTarget = new StreamResult(output);
  164. try {
  165. Transformer transformer = TransformerFactory.newInstance().newTransformer();
  166. transformer.transform(xmlSource, outputTarget);
  167. mCachedXml = output.toString();
  168. } catch (TransformerException e) {
  169. e.printStackTrace();
  170. }
  171. } catch (MalformedURLException e) {
  172. e.printStackTrace();
  173. } catch (IOException e) {
  174. e.printStackTrace();
  175. } catch (ParserConfigurationException e) {
  176. e.printStackTrace();
  177. } catch (SAXException e) {
  178. e.printStackTrace();
  179. }
  180. return xmldoc;
  181. }
  182. private LanguageData inflateLanguage(Node language, TreeSet<String> available6392) {
  183. LanguageData data = new LanguageData();
  184. NamedNodeMap attr = language.getAttributes();
  185. Node node;
  186. node = attr.getNamedItem("size");
  187. data.size = node.getNodeValue();
  188. node = attr.getNamedItem("file");
  189. data.file = node.getNodeValue();
  190. node = attr.getNamedItem("iso6392");
  191. data.iso6392 = node.getNodeValue();
  192. node = attr.getNamedItem("name");
  193. data.name = node.getNodeValue();
  194. node = attr.getNamedItem("hidden");
  195. data.hidden = (node != null);
  196. data.installed = available6392.contains(data.iso6392);
  197. return data;
  198. }
  199. }