decodes.xml.PlatformConfigParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opendcs Show documentation
Show all versions of opendcs Show documentation
A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.
The newest version!
/*
* $Id$
*/
package decodes.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import java.util.ArrayList;
import java.util.Iterator;
import decodes.db.*;
import decodes.db.DecodesScript.DecodesScriptBuilder;
import ilex.util.TextUtil;
import ilex.util.AsciiUtil;
import ilex.util.Logger;
import java.io.IOException;
import java.util.List;
import ilex.xml.*;
/**
* This class maps the DECODES XML representation for PlatformConfig elements.
*/
public class PlatformConfigParser implements XmlObjectParser, XmlObjectWriter, TaggedStringOwner
{
private PlatformConfig platformConfig; // object that we will build.
/**
* Reference to the DecodesScriptBuilder so we can finalized after we've read it in.
*/
private List decodesScriptParserList = new ArrayList<>();
private List decodesScriptBuilderList = new ArrayList<>();
private static final int descriptionTag = 0;
/**
* @param platformConfig the object in which to store the data.
*/
public PlatformConfigParser( PlatformConfig platformConfig )
{
super();
this.platformConfig = platformConfig;
}
/**
* @return name of element parsed by this parser
*/
public String myName( ) { return XmlDbTags.PlatformConfig_el; }
/**
* @param ch Characters from file
* @param start start of characters
* @param length length of characters
*/
public void characters( char[] ch, int start, int length ) throws SAXException
{
if (!TextUtil.isAllWhitespace(new String(ch, start, length)))
throw new SAXException(
"No character data expected within PlatformConfig");
}
/**
* Called after start of new element for this parser is detected.
* @param hier the stack of parsers
* @param namespaceURI namespaceURI
* @param localName name of element
* @param qname ignored
* @param atts attributes for this element
* @throws SAXException on parse error
*/
public void startElement( XmlHierarchyParser hier, String namespaceURI, String localName, String qname, Attributes atts ) throws SAXException
{
if (localName.equalsIgnoreCase(XmlDbTags.description_el))
{
hier.pushObjectParser(new TaggedStringSetter(this, descriptionTag));
}
else if (localName.equalsIgnoreCase(XmlDbTags.EquipmentModel_el))
{
String nm = atts.getValue(XmlDbTags.name_at);
if (nm == null)
throw new SAXException(XmlDbTags.EquipmentModel_el + " without "
+ XmlDbTags.name_at +" attribute");
EquipmentModel eqm = new EquipmentModel(nm);
platformConfig.equipmentModel = eqm;
platformConfig.getDatabase().equipmentModelList.add(eqm);
hier.pushObjectParser(new EquipmentModelParser(eqm));
}
else if (localName.equalsIgnoreCase(XmlDbTags.ConfigSensor_el))
{
String ns = atts.getValue(XmlDbTags.sensorNumber_at);
int snum = -1;
try { snum = Integer.parseInt(ns); }
catch(NumberFormatException e)
{
throw new SAXException("Sensor number must be an integer");
}
ConfigSensor cs = new ConfigSensor(platformConfig, snum);
platformConfig.addSensor(cs);
hier.pushObjectParser(new ConfigSensorParser(cs));
}
// Installed Platform DCPML files will link from TransportMedium to
// DecodesScript. However, files created for archive will link from
// PlatformConfig to DecodesScript. Hence we parse here:
else if (localName.equalsIgnoreCase(XmlDbTags.DecodesScript_el))
{
String nm = atts.getValue(XmlDbTags.DecodesScript_scriptName_at);
if (nm == null)
throw new SAXException(XmlDbTags.DecodesScript_el + " without "
+ XmlDbTags.DecodesScript_scriptName_at +" attribute");
/**
* Since the script data hasn't been read in yet, we punt
* the creation and assignment of the decodes script to the endtag
* when it's all ready.
*/
DecodesScriptParser scriptParser = new DecodesScriptParser();
DecodesScriptBuilder scriptBuilder = DecodesScript.from(scriptParser)
.platformConfig(platformConfig)
.scriptName(nm);
decodesScriptParserList.add(scriptParser);
decodesScriptBuilderList.add(scriptBuilder);
hier.pushObjectParser(scriptParser);
}
else
{
Logger.instance().log(Logger.E_WARNING,
"Invalid element '" + localName + "' under " + myName()
+ " -- skipped.");
hier.pushObjectParser(new ElementIgnorer());
}
}
/**
* Signals the end of the current element.
* Causes parser to pop the stack in the hierarchy.
* @param hier the stack of parsers
* @param namespaceURI ignored
* @param localName element that is ending
* @param qname ignored
*/
public void endElement( XmlHierarchyParser hier, String namespaceURI, String localName, String qname ) throws SAXException
{
if (!localName.equalsIgnoreCase(myName()))
{
throw new SAXException(
"Parse stack corrupted: got end tag for " + localName
+ ", expected " + myName());
}
hier.popObjectParser();
try {
for (int i = 0; i < decodesScriptBuilderList.size(); i++) {
DecodesScriptBuilder sb = decodesScriptBuilderList.get(i);
DecodesScriptParser sp = decodesScriptParserList.get(i);
DecodesScript ds = sb.build();
ds.scriptType = sp.getType();
for (ScriptSensor s : sp.getSensors()) {
s.decodesScript = ds;
ds.scriptSensors.add(s);
}
ds.setDataOrder(sp.getDataOrder());
this.platformConfig.addScript(ds);
}
}catch (DecodesScriptException | IOException ex)
{
throw new SAXException("Failed to load Decodes Script",ex);
}
}
/**
* Allows an object to keep track of whitespace, if needed.
* @param ch the whitespace
* @param start the start of the whitespace
* @param length the length of the whitespace
*/
public void ignorableWhitespace( char[] ch, int start, int length ) throws SAXException
{
}
/**
* From TaggedStringOwner, called from TaggedStringSetter when string
* elements are parsed.
* @param tag the tag defined above
* @param str the string content of the element
* @throws SAXException if context or parse error
*/
public void set( int tag, String str ) throws SAXException
{
switch(tag)
{
case descriptionTag:
str = TextUtil.collapseWhitespace(str);
str = new String(AsciiUtil.ascii2bin(str));
platformConfig.description = str;
break;
}
}
/**
* Writes this object's data, along with subordinates, to an XML file.
* @param xos the output stream object
* @throws IOException on IO error
*/
public void writeXml( XmlOutputStream xos ) throws IOException
{
xos.startElement(myName(), XmlDbTags.PlatformConfig_configName_at,
platformConfig.configName);
if (platformConfig.description != null)
xos.writeElement(XmlDbTags.description_el,
AsciiUtil.bin2ascii(platformConfig.description.getBytes()));
if (platformConfig.equipmentModel != null)
{
EquipmentModelParser p = new EquipmentModelParser(
platformConfig.equipmentModel);
p.writeXml(xos);
}
for(Iterator it = platformConfig.getSensors(); it.hasNext(); )
{
ConfigSensor cs = (ConfigSensor)it.next();
ConfigSensorParser p = new ConfigSensorParser(cs);
p.writeXml(xos);
}
for(Iterator it = platformConfig.getScripts(); it.hasNext(); )
{
DecodesScriptParser p =
new DecodesScriptParser((DecodesScript)it.next());
p.writeXml(xos);
}
xos.endElement(myName());
}
}