decodes.tsdb.xml.CompXio 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$
*
* Open Source Software
*
* $Log$
* Revision 1.5 2016/11/03 19:07:16 mmaloney
* Don't reread group members. The cache already has complete groups.
*
* Revision 1.4 2016/03/24 19:22:56 mmaloney
* Added support for algorithm scripts.
*
* Revision 1.3 2015/05/14 13:52:18 mmaloney
* RC08 prep
*
* Revision 1.2 2014/12/15 20:39:10 mmaloney
* writeTsGrp for Site List, must use site.getUniqueName, not getDisplayName.
*
* Revision 1.1.1.1 2014/05/19 15:28:59 mmaloney
* OPENDCS 6.0 Initial Checkin
*
* Revision 1.18 2013/07/12 13:06:24 mmaloney
* Fix bug whereby LoadingApplication nodes was not saving or reading properties.
*
* Revision 1.17 2013/03/21 18:27:40 mmaloney
* DbKey Implementation
*
*/
package decodes.tsdb.xml;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import opendcs.dai.TsGroupDAI;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import ilex.util.HasProperties;
import ilex.util.Logger;
import ilex.util.TextUtil;
import ilex.xml.DomHelper;
import ilex.xml.TaggedStringOwner;
import ilex.xml.TaggedStringSetter;
import ilex.xml.XmlHierarchyParser;
import ilex.xml.XmlObjectParser;
import ilex.xml.XmlOutputStream;
import decodes.sql.DbKey;
import decodes.tsdb.*;
import decodes.db.Constants;
import decodes.db.SiteName;
import decodes.db.DataType;
/**
XML Input/Output for Computational Meta Data.
*/
public class CompXio
implements XmlObjectParser, TaggedStringOwner
{
private static final org.slf4j.Logger log = LoggerFactory.getLogger(CompXio.class);
private String module;
private String filename;
private TimeSeriesDb theDb = null;
private static final int propertyTag = 0;
private static final int commentTag = 1;
private CompAppInfo workingObject = null;
private String propName = null;
/** Default constructor. */
public CompXio(String module, TimeSeriesDb theDb)
{
this.module = module;
this.theDb = theDb;
}
public ArrayList readStream(InputStream stream) throws DbXmlException
{
this.filename = "Provided Stream";
Document doc;
try
{
doc = DomHelper.readStream(module, stream);
}
catch(ilex.util.ErrorException ex)
{
throw new DbXmlException(ex.toString());
}
ArrayList metadata = new ArrayList();
Node rootel = doc.getDocumentElement();
if (rootel.getNodeName().equalsIgnoreCase(CompXioTags.loadingApplication))
{
addLoadingApplication(metadata, rootel);
return metadata;
}
else if (!rootel.getNodeName().equalsIgnoreCase(CompXioTags.compMetaData))
{
String s = module
+ ": Wrong type of configuration file -- Cannot initialize. "
+ "Root element is not '" + CompXioTags.compMetaData + "'.";
Logger.instance().failure(s);
throw new DbXmlException(s);
}
NodeList children = rootel.getChildNodes();
for(int i=0; children != null && i readFile(String filename) throws DbXmlException
{
Logger.instance().info("CompXio.readFile(" + filename + ")");
this.filename = filename;
File file = new File(filename);
try (InputStream in = new FileInputStream(file))
{
return this.readStream(in);
}
catch(IOException ex)
{
throw new DbXmlException("Unable to process " + filename, ex);
}
}
private void addAlgorithm(ArrayList metadata, Node node)
{
// Get number and host attributes.
Element elem = (Element)node;
//System.out.println("addAlgorithm nodename=" + node.getNodeName());
String name = DomHelper.findAttr(elem, CompXioTags.name);
if (name == null)
{
Logger.instance().warning(module + ": " + filename
+ " Algorithm element without name attribute -- ignored.");
return;
}
DbCompAlgorithm algo = new DbCompAlgorithm(Constants.undefinedId,
name, null, null);
NodeList children = node.getChildNodes();
for(int i=0; children != null && i 0)
lineb.insert(0, ' ');
scriptBuilder.append(lineb);
scriptBuilder.append("\n");
// Add the indent
}
else
{
Logger.instance().warning("Algorithm '" + name
+ "' has an " + CompXioTags.algoScriptLine
+ " element with null content -- ignored.");
}
}
}
DbCompAlgorithmScript newScript = new DbCompAlgorithmScript(algo,
ScriptType.fromDbChar(scriptTypeStr.charAt(0)));
newScript.addToText(scriptBuilder.toString());
algo.putScript(newScript);
}
else
Logger.instance().warning("Unrecognized element '"
+ nn + "' ignored DRGS Config.");
}
}
Logger.instance().debug2(module + " Adding algorithm " + name);
metadata.add(algo);
}
private void addComputation(ArrayList metadata, Node node)
{
// Get number and host attributes.
Element elem = (Element)node;
String name = DomHelper.findAttr(elem, CompXioTags.name);
if (name == null)
{
Logger.instance().warning(module + ": " + filename
+ " Computation element without name attribute -- ignored.");
return;
}
DbComputation comp = new DbComputation(Constants.undefinedId, name);
NodeList children = node.getChildNodes();
for(int i=0; children != null && i 0 )
// {
// for (DbKey j: tsGrp.getDataTypeIdList())
// {
// DataType dataType = DataType.getDataType(j);
// if ((dataType.getStandard() == DomHelper.findAttr((Element)childNode, CompXioTags.standard)) &&
// (dataType.getCode() == DomHelper.findAttr((Element)childNode, CompXioTags.code))) {
// foundDataTypeId = true;
// break;
// }
// }
// }
// if (!foundDataTypeId) {
// String dataTypeStd = DomHelper.findAttr((Element)childNode, CompXioTags.standard);
// String dataTypeCod = DomHelper.findAttr((Element)childNode, CompXioTags.code);
// if (dataTypeCod == null) {
// dataTypeCod = DomHelper.getTextContent((Element)childNode);
// }
// DataType dataType = DataType.getDataType(dataTypeStd, dataTypeCod);
//
// tsGrp.addDataTypeId(dataType.getId());
// }
// }
// else if (nodeName.equalsIgnoreCase(CompXioTags.member)) {
// String memberTyp = DomHelper.findAttr((Element)childNode, CompXioTags.type);
// String memberVal = DomHelper.findAttr((Element)childNode, CompXioTags.value);
// if (memberVal == null) {
// memberVal = DomHelper.getTextContent((Element)childNode);
// }
//
// tsGrp.addOtherMember(memberTyp, memberVal);
// }
// }
// }
//
// // Load TsGroup to theDb
// if (tsGrp.getGroupId() == Constants.undefinedId)
// {
// TsGroupDAI groupDAO = theDb.makeTsGroupDAO();
// try
// {
// groupDAO.writeTsGroup(tsGrp);
// }
// catch (Exception E)
// {
// System.out.println(E.toString());
// }
// finally
// {
// groupDAO.close();
// }
// }
//
// // Set TsGroup to the computation
// comp.setGroup(tsGrp);
// }
/**
* @param metadata
* @param node
*/
private void addTsGroup(ArrayList metadata, Node node)
{
// Find the Group Name
Element elem = (Element)node;
String groupName = DomHelper.findAttr(elem, CompXioTags.name);
if (groupName == null)
{
Logger.instance().warning(module + ": " + filename
+ " " + CompXioTags.tsGroup + " element without "
+ CompXioTags.name + " attribute -- ignored.");
return;
}
// Declare the tsGrp object
TsGroup tsGrp = new TsGroup();
tsGrp.setGroupName(groupName);
// Reset the parameters of the tsGrp
String nodeName;
Node childNode;
NodeList children = elem.getChildNodes();
for(int i=0; children != null && i metadata, Node node)
{
// Get name attribute.
Element elem = (Element)node;
String name = DomHelper.findAttr(elem, CompXioTags.name);
if (name == null)
{
Logger.instance().warning(module + ": " + filename
+ " " + CompXioTags.loadingApplication
+ " element without name attribute -- ignored.");
return;
}
CompAppInfo info = new CompAppInfo(Constants.undefinedId);
info.setAppName(name);
Node commentNode = DomHelper.findNode(elem, CompXioTags.comment,
Node.ELEMENT_NODE);
if (commentNode != null)
info.setComment(
TextUtil.collapseWhitespace(
DomHelper.getTextContent(commentNode)));
NodeList children = node.getChildNodes();
for(int i=0; children != null && i metadata,
String algoName)
{
for(CompMetaData obj : metadata)
{
if (obj instanceof DbCompAlgorithm)
{
DbCompAlgorithm algo = (DbCompAlgorithm)obj;
if (algoName.equalsIgnoreCase(algo.getName()))
return algo;
}
}
return null;
}
/**
* Creates or overwrites the specified file, writing all of the objects
* found in 'metadata'.
* @param metadata the computational meta-data objects to write.
* @param filename the file name to write to.
*/
public void writeFile(ArrayList metadata, String filename)
throws IOException
{
// Open an output stream wrapped by an XmlOutputStream
FileOutputStream fos = new FileOutputStream(filename);
XmlOutputStream xos =
new XmlOutputStream(fos, CompXioTags.compMetaData);
xos.writeXmlHeader();
xos.startElement(CompXioTags.compMetaData);
for(CompMetaData mdObject : metadata)
{
if (mdObject instanceof DbComputation)
writeComp(xos, (DbComputation)mdObject);
else if (mdObject instanceof DbCompAlgorithm)
writeAlgo(xos, (DbCompAlgorithm)mdObject);
else if (mdObject instanceof CompAppInfo)
writeApp(xos, (CompAppInfo)mdObject);
else if (mdObject instanceof TsGroup)
writeTsGrp(xos, (TsGroup)mdObject);
}
xos.endElement(CompXioTags.compMetaData);
fos.close();
}
private void writeAlgo(XmlOutputStream xos, DbCompAlgorithm algo)
throws IOException
{
xos.startElement(CompXioTags.algorithm,
CompXioTags.name, algo.getName());
String s = algo.getComment();
if (s != null)
xos.writeElement(CompXioTags.comment, s);
s = algo.getExecClass();
if (s != null)
xos.writeElement(CompXioTags.execClass, s);
for(Enumeration en = algo.getPropertyNames(); en.hasMoreElements(); )
{
String propname = (String)en.nextElement();
xos.writeElement(CompXioTags.algoProperty,
CompXioTags.name, propname, algo.getProperty(propname));
}
for(Iterator it = algo.getParms(); it.hasNext(); )
{
DbAlgoParm dap = it.next();
xos.startElement(CompXioTags.algoParm,
CompXioTags.roleName, dap.getRoleName());
xos.writeElement(CompXioTags.parmType, dap.getParmType());
xos.endElement(CompXioTags.algoParm);
}
for(ScriptType st : ScriptType.values())
{
DbCompAlgorithmScript script = algo.getScript(st);
// Temporarily set width very wide to prevent script lines from wrapping
// and inserting awkward spacing when read back in.
int w = xos.width;
xos.width = 200;
if (script != null)
{
xos.startElement(CompXioTags.algoScript, CompXioTags.algoScriptType, ""+st.getDbChar());
String scriptText = script.getText();
BufferedReader bufReader = new BufferedReader(new StringReader(scriptText));
String line = null;
while((line = bufReader.readLine()) != null)
{
int indent = 0;
for(int idx=0; idx it = comp.getParms(); it.hasNext(); )
{
DbCompParm dcp = it.next();
xos.startElement(CompXioTags.compParm,
CompXioTags.roleName, dcp.getRoleName());
xos.startElement(CompXioTags.siteDataType);
for(SiteName sn : dcp.getSiteNames())
xos.writeElement(CompXioTags.siteName,
CompXioTags.nameType, sn.getNameType(),
sn.getNameValue());
DataType dataType = dcp.getDataType();
if (dataType != null)
{
xos.writeElement(CompXioTags.dataType,
CompXioTags.standard, dataType.getStandard(),
CompXioTags.code, dataType.getCode(), null);
}
else Logger.instance().warning("Role '"
+ dcp.getRoleName() + "' has no data type.");
xos.endElement(CompXioTags.siteDataType);
s = dcp.getInterval();
if (s != null)
xos.writeElement(CompXioTags.interval, s);
s = dcp.getTableSelector();
if (s != null)
xos.writeElement(CompXioTags.tableSelector, s);
int dt = dcp.getDeltaT();
xos.writeElement(CompXioTags.deltaT, "" + dt);
String dtu = dcp.getDeltaTUnits();
if (dtu != null && dtu.trim().length() > 0)
xos.writeElement(CompXioTags.deltaTUnits, dtu);
int mid = dcp.getModelId();
if (mid != Constants.undefinedIntKey)
xos.writeElement(CompXioTags.modelId, "" + mid);
xos.endElement(CompXioTags.compParm);
}
xos.endElement(CompXioTags.computation);
}
/**
* Write the TsGroup block into XML file if it exists
*
* @param xos
* @param tsgrp
*/
private void writeTsGrp(XmlOutputStream xos, TsGroup tsgrp)
throws IOException
{
if (tsgrp == null) { return; }
//Expand the group members for each TS group
// try
// {
// theDb.readTsGroupMembers(tsgrp);
// }
// catch (Exception E) {
// System.out.println(E.toString());
// }
//Write the group elements for each TS group
xos.startElement(CompXioTags.tsGroup, CompXioTags.name, tsgrp.getGroupName());
xos.writeElement(CompXioTags.groupType, tsgrp.getGroupType());
xos.writeElement(CompXioTags.description, tsgrp.getDescription());
// xos.writeElement(CompXioTags.officeId, tsgrp.getDbOfficeId());
for (TimeSeriesIdentifier tsId: tsgrp.getTsMemberList())
xos.writeElement(CompXioTags.timeSeries, tsId.getUniqueString());
for (DbKey i: tsgrp.getSiteIdList())
{
try
{
xos.writeElement(CompXioTags.siteName, (theDb.getSiteById(i)).getUniqueName());
}
catch (Exception E) {
System.out.println(E.toString());
}
}
DataType dataType;
for (DbKey j: tsgrp.getDataTypeIdList())
{
dataType = DataType.getDataType(j);
xos.writeElement(CompXioTags.dataType,
CompXioTags.standard, dataType.getStandard(),
CompXioTags.code, dataType.getCode(), null);
}
for (TsGroupMember mem: tsgrp.getOtherMembers())
{
xos.writeElement(CompXioTags.member,
CompXioTags.type, mem.getMemberType(),
CompXioTags.value, mem.getMemberValue(), null);
}
for (TsGroup tsGrpId: tsgrp.getIncludedSubGroups())
xos.writeElement(CompXioTags.subGroup,
CompXioTags.combine, "add", tsGrpId.getGroupName());
for (TsGroup tsGrpId: tsgrp.getExcludedSubGroups())
xos.writeElement(CompXioTags.subGroup,
CompXioTags.combine, "subtract", tsGrpId.getGroupName());
for (TsGroup tsGrpId: tsgrp.getIntersectedGroups())
xos.writeElement(CompXioTags.subGroup,
CompXioTags.combine, "intersect", tsGrpId.getGroupName());
xos.endElement(CompXioTags.tsGroup);
}
@Override
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 LoadingApplication");
}
@Override
public void startElement(XmlHierarchyParser hier, String namespaceURI,
String localName, String qname, Attributes atts) throws SAXException
{
if (localName.equalsIgnoreCase(CompXioTags.comment))
hier.pushObjectParser(new TaggedStringSetter(this, commentTag));
else if (localName.equalsIgnoreCase(CompXioTags.appProperty))
{
propName = atts.getValue(CompXioTags.name);
if (propName == null)
throw new SAXException(CompXioTags.appProperty
+ " without " + CompXioTags.name +" attribute");
hier.pushObjectParser(new TaggedStringSetter(this, propertyTag));
}
}
@Override
public void endElement(XmlHierarchyParser hier, String namespaceURI,
String localName, String qname) throws SAXException
{
if (localName.equalsIgnoreCase(CompXioTags.loadingApplication))
hier.popObjectParser();
else
throw new SAXException(
"Parse stack corrupted: got end tag for " + localName
+ ", expected " + CompXioTags.loadingApplication);
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException
{
}
@Override
public void set(int tag, String value) throws SAXException
{
switch(tag)
{
case propertyTag:
workingObject.getProperties().setProperty(propName, value);
break;
case commentTag:
workingObject.setComment(value);
break;
}
}
/**
* When parsing a decodes database image with embedded LoadingApplication elements,
* the caller must set a working object for the SAX methods above.
* @param workingObject
*/
public void setWorkingObject(CompAppInfo workingObject)
{
this.workingObject = workingObject;
}
}