/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author: hannes $
* $Revision: 9327 $
* $Date: 2008-10-17 18:06:43 +0200 (Fre, 17. Okt 2008) $
*/
package helma.scripting.rhino.extensions;
import helma.scripting.rhino.*;
import helma.objectmodel.INode;
import helma.objectmodel.db.Node;
import helma.objectmodel.dom.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
/**
* This class provides methods for converting HopObjects to XML and back.
*
* @see <http://helma.org/development/rfc/xmlconversion/>
*/
public class XmlObject {
RhinoCore core;
/**
* Creates a new XmlObject object.
*
* @param core ...
*/
public XmlObject(RhinoCore core) {
this.core = core;
}
/**
* Writes a HopObject to an XML file
*
* @param node the HopObject to encode
* @param file the file to write to
* @return true
* @throws IOException if something went wrong along the way
*/
public boolean write(INode node, String file) throws IOException {
return write(node, file, false);
}
/**
* Writes a HopObject to an XML file, optionally using shallow/db mode
*
* @param node the HopObject to encode
* @param file the file to write to
* @param dbmode whether to write a shallow copy
* @return true
* @throws IOException if something went wrong along the way
*/
public boolean write(INode node, String file, boolean dbmode)
throws IOException {
// we definitly need a node
if (node == null) {
throw new RuntimeException("First argument in Xml.write() is not an hopobject");
}
if (file == null) {
throw new RuntimeException("Second argument file name must not be null");
}
File tmpFile = new File(file + ".tmp." + XmlWriter.generateID());
XmlWriter writer = new XmlWriter(tmpFile, "UTF-8");
writer.setDatabaseMode(dbmode);
writer.write(node);
writer.close();
File finalFile = new File(file);
if (finalFile.exists()) {
finalFile.delete();
}
tmpFile.renameTo(finalFile);
core.getApplication().logEvent("wrote xml to " + finalFile.getAbsolutePath());
return true;
}
/**
* Transforms a HopObject to XML and returns the result as string
*
* @param node the HopObject to encode
* @return the XML representing the HopObject
* @throws IOException if something went wrong along the way
*/
public String writeToString(INode node) throws IOException {
return writeToString(node, false);
}
/**
* Transforms a HopObject to XML and returns the result as string,
* optionally using shallow/db mode
*
* @param node the HopObject to encode
* @return the XML representing the HopObject
* @param dbmode whether to write a shallow copy
* @throws IOException if something went wrong
*/
public String writeToString(INode node, boolean dbmode) throws IOException {
// we definitly need a node
if (node == null) {
throw new RuntimeException("First argument in Xml.write() is not an hopobject");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
XmlWriter writer = new XmlWriter(out, "UTF-8");
// in case we ever want to limit serialization depth...
// if (arguments.length > 1 && arguments[1] instanceof ESNumber)
// writer.setMaxLevels(arguments[1].toInt32());
writer.setDatabaseMode(dbmode);
writer.write(node);
writer.flush();
return out.toString("UTF-8");
}
/**
* Reads an XML document from a file and creates a HopObject out of it
*
* @param file the file name
* @return the HopObject
* @throws RuntimeException ...
*/
public Object read(String file) throws RuntimeException {
return read(file, null);
}
/**
* Reads an XML document from a file and reads it into the HopObject argument
*
* @param file the file name
* @param node the HopObject to use for conversion
* @return the HopObject
*/
public Object read(String file, INode node) throws RuntimeException {
if (file == null) {
throw new RuntimeException("Missing arguments in Xml.read()");
}
if (node == null) {
// make sure we have a node, even if 2nd arg doesn't exist or is not a node
node = new Node(null, null, core.getApplication().getWrappedNodeManager());
}
try {
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
INode result = reader.read(new File(file), node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load XML parser:" + e);
} catch (Exception f) {
throw new RuntimeException(f.toString());
}
}
/**
* Reads an XML document from an XML literal and creates a HopObject out of it
*
* @param str the XML string
* @return the HopObject
* @throws RuntimeException ...
*/
public Object readFromString(String str) throws RuntimeException {
return readFromString(str, null);
}
/**
* Reads an XML document from an XML literal and creates a HopObject out of it
*
* @param str the XML string
* @param node the HopObject to use for conversion
* @return ...
* @throws RuntimeException ...
*/
public Object readFromString(String str, INode node)
throws RuntimeException {
if (str == null) {
throw new RuntimeException("Missing arguments in Xml.read()");
}
if (node == null) {
// make sure we have a node, even if 2nd arg doesn't exist or is not a node
node = new Node(null, null, core.getApplication().getWrappedNodeManager());
}
try {
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
INode result = reader.read(new StringReader(str), node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load XML parser:" + e);
} catch (Exception f) {
f.printStackTrace();
throw new RuntimeException(f.toString());
}
}
/**
* Retrieves an XML document from a given URL and transforms it into a HopObject
*
* @param url the URL containing the XML to be parsed
* @return a HopObject obtained from parsing the XML
*/
public Object get(String url) {
return get(url, null);
}
/**
* Retrieves an XML document from a given URL and transforms it into a HopObject
*
* @param url the URL containing the XML to be parsed
* @param conversionRules a file name pointing to the conversion rules
* @return a HopObject obtained from parsing the XML
* @see <http://helma.org/development/rfc/xmlconversion/>
*/
public Object get(String url, String conversionRules) {
if (url == null) {
throw new RuntimeException("Xml.get() needs a location as an argument");
}
try {
XmlConverter converter;
if (conversionRules != null) {
converter = new XmlConverter(conversionRules);
} else {
converter = new XmlConverter();
}
INode node = new Node(null, null,
core.getApplication().getWrappedNodeManager());
INode result = converter.convert(url, node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load dom-capable xml parser.");
}
}
/**
* Transforms a XML literal into a HopObject
*
* @param str an XML literal
* @return a HopObject obtained from parsing the XML
*/
public Object getFromString(String str) {
return getFromString(str, null);
}
/**
* Transforms a XML literal into a HopObject according to the rules specified in
* the file defined by conversionRules
*
* @param str an XML literal
* @param conversionRules a file name pointing to the conversion rules
* @return a HopObject obtained from parsing the XML
* @see <http://helma.org/development/rfc/xmlconversion/>
*/
public Object getFromString(String str, String conversionRules) {
if (str == null) {
throw new RuntimeException("Xml.getFromString() needs an XML string as parameter");
}
try {
XmlConverter converter;
if (conversionRules != null) {
converter = new XmlConverter(conversionRules);
} else {
converter = new XmlConverter();
}
INode node = new Node(null, null, core.getApplication().getWrappedNodeManager());
INode result = converter.convertFromString(str, node);
return core.getNodeWrapper(result);
} catch (NoClassDefFoundError e) {
throw new RuntimeException("Can't load dom-capable xml parser.");
}
}
}