From 0ed2c1124cf1b9e49a2ec1fa0126a8df09f9e758 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 7 Oct 2014 09:18:11 +0200 Subject: Repackage to org.cristalise --- .../kernel/persistency/outcome/Outcome.java | 290 +++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 src/main/java/org/cristalise/kernel/persistency/outcome/Outcome.java (limited to 'src/main/java/org/cristalise/kernel/persistency/outcome/Outcome.java') diff --git a/src/main/java/org/cristalise/kernel/persistency/outcome/Outcome.java b/src/main/java/org/cristalise/kernel/persistency/outcome/Outcome.java new file mode 100644 index 0000000..95f3e6b --- /dev/null +++ b/src/main/java/org/cristalise/kernel/persistency/outcome/Outcome.java @@ -0,0 +1,290 @@ +/** + * This file is part of the CRISTAL-iSE kernel. + * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * http://www.fsf.org/licensing/licenses/lgpl.html + */ +package org.cristalise.kernel.persistency.outcome; +import java.io.StringReader; +import java.util.StringTokenizer; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.cristalise.kernel.common.InvalidDataException; +import org.cristalise.kernel.common.ObjectNotFoundException; +import org.cristalise.kernel.common.PersistencyException; +import org.cristalise.kernel.entity.C2KLocalObject; +import org.cristalise.kernel.persistency.ClusterStorage; +import org.cristalise.kernel.utils.LocalObjectLoader; +import org.cristalise.kernel.utils.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.InputSource; + + +public class Outcome implements C2KLocalObject { + Integer mID; + String mData; + String mSchemaType; + int mSchemaVersion; + Document dom; + static DocumentBuilder parser; + static DOMImplementationLS impl; + static XPath xpath; + + static { + // Set up parser + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(false); + dbf.setNamespaceAware(false); + try { + parser = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + Logger.error(e); + Logger.die("Cannot function without XML parser"); + } + + // Set up serialiser + try { + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); + } catch (Exception e) { + Logger.error(e); + Logger.die("Cannot function without XML serialiser"); + } + + XPathFactory xPathFactory = XPathFactory.newInstance(); + xpath = xPathFactory.newXPath(); + } + + //id is the eventID + public Outcome(int id, String data, String schemaType, int schemaVersion) { + mID = id; + mData = data; + mSchemaType = schemaType; + mSchemaVersion = schemaVersion; + } + + public Outcome(String path, String data) throws PersistencyException { + // derive all the meta data from the path + StringTokenizer tok = new StringTokenizer(path,"/"); + if (tok.countTokens() != 3 && !(tok.nextToken().equals(ClusterStorage.OUTCOME))) + throw new PersistencyException("Outcome() - Outcome path must have three components: "+path); + mSchemaType = tok.nextToken(); + String verstring = tok.nextToken(); + String objId = tok.nextToken(); + try { + mSchemaVersion = Integer.parseInt(verstring); + } catch (NumberFormatException ex) { + throw new PersistencyException("Outcome() - Outcome version was an invalid number: "+verstring); + } + try { + mID = Integer.valueOf(objId); + } catch (NumberFormatException ex) { + mID = null; + } + mData = data; + } + + public void setID(Integer ID) { + mID = ID; + } + + public Integer getID() { + return mID; + } + + @Override + public void setName(String name) { + try { + mID = Integer.valueOf(name); + } catch (NumberFormatException e) { + Logger.error("Invalid id set on Outcome:"+name); + } + } + + @Override + public String getName() { + return mID.toString(); + } + + public void setData(String data) { + mData = data; + dom = null; + } + + public void setData(Document data) { + dom = data; + mData = null; + } + + public String getFieldByXPath(String xpath) throws XPathExpressionException, InvalidDataException { + Node field = getNodeByXPath(xpath); + if (field == null) + throw new InvalidDataException(xpath); + + else if (field.getNodeType()==Node.TEXT_NODE || field.getNodeType()==Node.CDATA_SECTION_NODE) + return field.getNodeValue(); + + else if (field.getNodeType()==Node.ELEMENT_NODE) { + NodeList fieldChildren = field.getChildNodes(); + if (fieldChildren.getLength() == 0) + throw new InvalidDataException("No child node for element"); + + else if (fieldChildren.getLength() == 1) { + Node child = fieldChildren.item(0); + if (child.getNodeType()==Node.TEXT_NODE || child.getNodeType()==Node.CDATA_SECTION_NODE) + return child.getNodeValue(); + else + throw new InvalidDataException("Can't get data from child node of type "+child.getNodeName()); + } + else + throw new InvalidDataException("Element "+xpath+" has too many children"); + } + else if (field.getNodeType()==Node.ATTRIBUTE_NODE) + return field.getNodeValue(); + else + throw new InvalidDataException("Don't know what to do with node "+field.getNodeName()); + } + + public void setFieldByXPath(String xpath, String data) throws XPathExpressionException, InvalidDataException { + Node field = getNodeByXPath(xpath); + if (field == null) + throw new InvalidDataException(xpath); + + else if (field.getNodeType()==Node.ELEMENT_NODE) { + NodeList fieldChildren = field.getChildNodes(); + if (fieldChildren.getLength() == 0) { + field.appendChild(dom.createTextNode(data)); + } + else if (fieldChildren.getLength() == 1) { + Node child = fieldChildren.item(0); + switch (child.getNodeType()) { + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + child.setNodeValue(data); + break; + default: + throw new InvalidDataException("Can't set child node of type "+child.getNodeName()); + } + } + else + throw new InvalidDataException("Element "+xpath+" has too many children"); + } + else if (field.getNodeType()==Node.ATTRIBUTE_NODE) + field.setNodeValue(data); + else + throw new InvalidDataException("Don't know what to do with node "+field.getNodeName()); + } + + + public String getData() { + if (mData == null && dom != null) { + mData = serialize(dom, false); + } + return mData; + } + + public Schema getSchema() throws ObjectNotFoundException { + return LocalObjectLoader.getSchema(mSchemaType, mSchemaVersion); + } + + public void setSchemaType(String schemaType) { + mSchemaType = schemaType; + } + + public String getSchemaType() { + return mSchemaType; + } + + public int getSchemaVersion() { + return mSchemaVersion; + } + + public void setSchemaVersion(int schVer) { + mSchemaVersion = schVer; + } + + @Override + public String getClusterType() { + return ClusterStorage.OUTCOME; + } + + // special script API methods + + /** + * Parses the outcome into a DOM tree + * @return a DOM Document + */ + public Document getDOM() { + if (dom == null) + try { + synchronized (parser) { + if (mData!=null) + dom = parser.parse(new InputSource(new StringReader(mData))); + else + dom = parser.newDocument(); + } + } catch (Exception e) { + Logger.error(e); + return null; + } + return dom; + } + + public String getField(String name) { + NodeList elements = getDOM().getDocumentElement().getElementsByTagName(name); + if (elements.getLength() == 1 && elements.item(0).hasChildNodes() && elements.item(0).getFirstChild() instanceof Text) + return ((Text)elements.item(0).getFirstChild()).getData(); + else + return null; + } + + public NodeList getNodesByXPath(String xpathExpr) throws XPathExpressionException { + + XPathExpression expr = xpath.compile(xpathExpr); + return (NodeList)expr.evaluate(getDOM(), XPathConstants.NODESET); + + } + + public Node getNodeByXPath(String xpathExpr) throws XPathExpressionException { + + XPathExpression expr = xpath.compile(xpathExpr); + return (Node)expr.evaluate(getDOM(), XPathConstants.NODE); + + } + + static public String serialize(Document doc, boolean prettyPrint) + { + LSSerializer writer = impl.createLSSerializer(); + writer.getDomConfig().setParameter("format-pretty-print", prettyPrint); + writer.getDomConfig().setParameter("xml-declaration", false); + return writer.writeToString(doc); + } +} -- cgit v1.2.3