WEPSResidue.java [src/nodes] Revision: default  Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package nodes;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import static utils.Constants.CROPNAME;
import static utils.Constants.NAME;
import static utils.Constants.PARAM;
import static utils.Constants.WEPS_RES_PARAM_SET;
import static utils.Constants.XML_VALUE;
import utils.TranslatorException;

/**
 *
 * @author Brad
 */
public class WEPSResidue extends Residue {

  private final Map<String, String> parameters;

  private static final String CROPDTD = "../config/data/crop_db.dtd";

  public WEPSResidue() {
    parameters = new HashMap<>();
  }

  public WEPSResidue(String name) {
    parameters = new HashMap<>();
    this.name = name;
  }

  public WEPSResidue(String id, String name) {
    parameters = new HashMap<>();
    this.id = id;
    this.name = name;
  }

  public String getParameter(String param) {
    return parameters.get(param);

  }

  public void addParameter(String name, String value) {
    parameters.put(name, value);
  }

  @Override
  public void parseLMODData(JSONObject data) throws XMLStreamException, ParserConfigurationException, SAXException, IOException, TranslatorException, JSONException {

    XMLEvent event;
    StartElement startElement;
    EndElement endElement;
    boolean done = false;
    String param_name = null;
    String param_value = null;

    String xmlData = data.getString(WEPS_RES_PARAM_SET);

    InputStream stream = new ByteArrayInputStream(xmlData.getBytes());  //IOUtils.toInputStream(xmlData, Charset.defaultCharset());

    URL url = getClass().getResource(CROPDTD);
    xmlData = xmlData.replace("crop_db.dtd", url.toString());

    // Set up xml stream
    XMLInputFactory factory = XMLInputFactory.newInstance();

    XMLEventReader reader = factory.createXMLEventReader(stream);

    //validate the xml
    SAXParserFactory saxfactory = SAXParserFactory.newInstance();
    saxfactory.setValidating(true);
    SAXParser parser = saxfactory.newSAXParser();
    XMLReader validreader = parser.getXMLReader();

    validreader.setErrorHandler(
            new ErrorHandler() {
      @Override
      public void warning(SAXParseException e) throws SAXException {
        System.out.println("WARNING : " + e.getMessage()); // do nothing
      }

      @Override
      public void error(SAXParseException e) throws SAXException {
        System.out.println("ERROR : " + e.getMessage());
        throw e;
      }

      @Override
      public void fatalError(SAXParseException e) throws SAXException {
        System.out.println("FATAL : " + e.getMessage());
        throw e;
      }
    }
    );
    validreader.parse(new InputSource(new StringReader(xmlData)));

    // start parsing
    while (reader.hasNext()) {
      event = reader.nextEvent();

      switch (event.getEventType()) {
        case XMLStreamConstants.START_ELEMENT:
          startElement = event.asStartElement();
          if (startElement.getName().getLocalPart().equals(CROPNAME)) {
            if (!reader.getElementText().equals(name))
              throw new TranslatorException("Residue: " + name + " does not match the LMOD residue data.");

            break;
          }

          if (startElement.getName().getLocalPart().equals(PARAM)) {
            while (reader.hasNext() && !done) {
              event = reader.nextEvent();
              switch (event.getEventType()) {
                case XMLStreamConstants.START_ELEMENT:
                  startElement = event.asStartElement();
                  if (startElement.getName().getLocalPart().equals(NAME)) {
                    param_name = reader.getElementText();

                    break;
                  }

                  if (startElement.getName().getLocalPart().equals(XML_VALUE)) {
                    param_value = reader.getElementText();
                    done = true;
                    break;
                  }
              }
            }
            done = false;
          }
          break;

        case XMLStreamConstants.END_ELEMENT:
          endElement = event.asEndElement();
          if (endElement.getName().getLocalPart().equals(PARAM))
            parameters.put(param_name, param_value);
          break;
      }
    }
  }
}