package org.greengin.sciencetoolkit.common.model.serialize; import java.io.File; import java.util.Hashtable; import java.util.Map.Entry; import java.util.Scanner; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.greengin.sciencetoolkit.common.model.Model; import org.greengin.sciencetoolkit.common.model.ModelChangeListener; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import android.content.Context; import android.util.Log; public class ModelDeserializer { public static Hashtable<String, Model> xml2modelMap(ModelChangeListener listener, ModelVersionManager versionManager, Context applicationContext, String file) { try { Element rootElement = loadRootElement(applicationContext, file); Hashtable<String, Model> items = xml2modelMap(rootElement, listener); versionCheck(versionManager, rootElement, items); return items; } catch (Exception e) { e.printStackTrace(); return new Hashtable<String, Model>(); } } private static Element loadRootElement(Context applicationContext, String file) throws Exception { File fXmlFile = new File(applicationContext.getFilesDir(), file); Scanner scanner = new Scanner(fXmlFile); try { while(scanner.hasNextLine()) { Log.d("stk file", scanner.nextLine()); } } finally { scanner.close(); } DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(fXmlFile); doc.getDocumentElement().normalize(); Element rootElement = doc.getDocumentElement(); return rootElement; } private static void versionCheck(ModelVersionManager versionManager, Element rootElement, Hashtable<String, Model> items) { int modelVersion = getVersion(rootElement); int currentVersion = versionManager.getCurrentVersion(); if (currentVersion > modelVersion) { for (Entry<String, Model> entry : items.entrySet()) { versionManager.updateRootModel(entry.getKey(), entry.getValue(), modelVersion); } } } private static int getVersion(Element rootElement) { try { String vStr = rootElement.getAttribute("version").trim(); int v = Integer.parseInt(vStr); return v; } catch (Exception e) { return 0; } } private static Hashtable<String, Model> xml2modelMap(Element containerElement, ModelChangeListener listener) { Hashtable<String, Model> models = new Hashtable<String, Model>(); NodeList nList = containerElement.getChildNodes(); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; if ("item".equals(eElement.getTagName())) { String itemId = eElement.getAttribute("id"); Model model = xml2model(eElement, listener, null); models.put(itemId, model); } } } return models; } private static Model xml2model(Element modelElement, ModelChangeListener listener, Model parent) { Model model; if (parent == null) { model = new Model(listener); } else { model = new Model(parent); } NodeList nSubList = modelElement.getChildNodes(); for (int j = 0; j < nSubList.getLength(); j++) { Node nSubNode = nSubList.item(j); if (nSubNode.getNodeType() == Node.ELEMENT_NODE) { Element eSubElement = (Element) nSubNode; if ("entry".equals(eSubElement.getTagName())) { String type = eSubElement.getAttribute("type"); String entryId = eSubElement.getAttribute("id"); if ("model".equals(type)) { Node nValueNode = eSubElement.getFirstChild(); if (nValueNode != null && nValueNode.getNodeType() == Node.ELEMENT_NODE) { Model submodel = xml2model((Element) nValueNode, listener, model); model.setModel(entryId, submodel, true); } } else { String valueStr = eSubElement.getTextContent(); if ("bool".equals(type)) { boolean valueBool = Boolean.parseBoolean(valueStr); model.setBool(entryId, valueBool, true); } else if ("string".equals(type)) { model.setString(entryId, valueStr, true); } else if ("int".equals(type)) { try { int valueInt = Integer.parseInt(valueStr); model.setInt(entryId, valueInt, true); } catch (NumberFormatException e) { } } else if ("double".equals(type)) { try { double valueDbl = Double.parseDouble(valueStr); model.setDouble(entryId, valueDbl, true); } catch (NumberFormatException e) { } } else if ("long".equals(type)) { try { long valueLong = Long.parseLong(valueStr); model.setLong(entryId, valueLong, true); } catch (NumberFormatException e) { } } } } } } return model; } }