initial checkin xml/dom-extension

This commit is contained in:
stefanp 2002-04-19 15:54:14 +00:00
parent 8e96f6fee8
commit ddf1a9a88e
6 changed files with 900 additions and 0 deletions

View file

@ -0,0 +1,8 @@
package helma.objectmodel.dom;
public interface XmlConstants {
public final String NAMESPACE = "http://www.helma.org/";
public final String DATEFORMAT = "dd.MM.yyyy HH:mm:ss z";
}

View file

@ -0,0 +1,239 @@
package helma.objectmodel.dom;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import helma.objectmodel.*;
import helma.util.SystemProperties;
public class XmlConverter implements XmlConstants {
private boolean DEBUG=false;
private Properties props;
private char defaultSeparator = '_';
private int offset = 0;
public XmlConverter() {
props = new SystemProperties();
}
public XmlConverter(String propFile) {
props = new SystemProperties(propFile);
extractProperties(props);
}
public XmlConverter(File propFile) {
this ( propFile.getAbsolutePath() );
}
public XmlConverter(Properties props) {
this.props = props;
extractProperties(props);
}
public INode convert( String desc ) {
return convert(desc, new TransientNode() );
}
public INode convert( String desc, INode helmaNode ) throws RuntimeException {
try {
return convert( new URL(desc), helmaNode );
} catch ( MalformedURLException notanurl ) {
try {
return convert( new File(desc), helmaNode );
} catch ( FileNotFoundException notfound ) {
throw new RuntimeException( "couldn't read xml: " + desc );
}
} catch ( IOException ioerror ) {
throw new RuntimeException( "couldn't read xml: " + desc );
}
}
public INode convert( File file, INode helmaNode ) throws RuntimeException, FileNotFoundException {
return convert( new FileInputStream(file), helmaNode );
}
public INode convert( URL url, INode helmaNode ) throws RuntimeException, IOException, MalformedURLException {
return convert( url.openConnection().getInputStream(), helmaNode );
}
public INode convert( InputStream in, INode helmaNode ) throws RuntimeException {
Document document = XmlUtil.parse (in);
if ( document!=null && document.getDocumentElement()!=null ) {
return convert( document.getDocumentElement(), helmaNode );
} else {
return helmaNode;
}
}
public INode convert( Element element, INode helmaNode ) {
offset++;
if (DEBUG) debug("reading " + element.getNodeName() );
helmaNode.setName( element.getNodeName() );
String prototype = (String)props.get(element.getNodeName().toLowerCase()+".prototype");
if ( prototype == null )
prototype = "HopObject";
helmaNode.setPrototype( prototype );
attributes(element, helmaNode);
if ( element.hasChildNodes() ) {
children(element, helmaNode);
}
offset--;
return helmaNode;
}
/**
* parse xml children and create hopobject-children
*/
private INode children( Element element, helma.objectmodel.INode helmaNode ) {
NodeList list = element.getChildNodes();
int len = list.getLength();
StringBuffer textcontent = new StringBuffer();
String domKey, helmaKey;
for ( int i=0; i<len; i++ ) {
// loop through the list of children
org.w3c.dom.Node childNode = list.item(i);
// if it's text content of this element -> append to StringBuffer
if ( childNode.getNodeType()==org.w3c.dom.Node.TEXT_NODE ) {
textcontent.append( childNode.getNodeValue().trim() );
continue;
}
// it's some kind of element (property or child)
if ( childNode.getNodeType()==org.w3c.dom.Node.ELEMENT_NODE ) {
Element childElement = (Element)childNode;
// get the basic key we have to look for in the properties-table
domKey = (element.getNodeName()+"."+childElement.getNodeName()).toLowerCase();
// is there a childtext-2-property mapping?
if ( props!=null && props.containsKey(domKey+"._text") ) {
helmaKey = (String)props.get(domKey+"._text");
if( helmaKey.equals("") )
// if property is set but without value, read elementname for this mapping
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
if (DEBUG) debug("childtext-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey );
if ( helmaNode.getString(helmaKey,false)==null ) {
helmaNode.setString( helmaKey, XmlUtil.getTextContent(childNode) );
if (DEBUG) debug("childtext-2-property mapping, setting " + helmaKey + " as string" );
}
continue;
}
//
// is there a simple child-2-property mapping?
// (lets the user define to use only one element and make this a property
// and simply ignore other elements of the same name)
if ( props!=null && props.containsKey(domKey+"._property") ) {
helmaKey = (String)props.get(domKey+"._property");
// if property is set but without value, read elementname for this mapping:
if ( helmaKey.equals("") )
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
if (DEBUG) debug("child-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey);
if ( helmaNode.getNode(helmaKey,false)==null ) {
convert( childElement, helmaNode.createNode(helmaKey) );
if (DEBUG) debug( "read " + childElement.toString() + helmaNode.getNode(helmaKey,false).toString() );
}
continue;
}
//
// map it to one of the children-lists
helma.objectmodel.INode newHelmaNode = null;
String childrenMapping = (String)props.get(element.getNodeName().toLowerCase()+"._children");
// do we need a mapping directly among _children of helmaNode?
// can either be through property elname._children=_all or elname._children=childname
if( childrenMapping!=null && ( childrenMapping.equals("_all") || childrenMapping.equals(childElement.getNodeName()) ) ) {
newHelmaNode = convert(childElement, helmaNode.createNode(null) );
}
// which name to choose for a virtual subnode:
helmaKey = (String)props.get(domKey);
if ( helmaKey==null ) {
helmaKey = childElement.getNodeName().replace(':',defaultSeparator);
}
// try to get the virtual node
helma.objectmodel.INode worknode = helmaNode.getNode( helmaKey, false );
if ( worknode==null ) {
// if virtual node doesn't exist, create it
worknode = helmaNode.createNode( helmaKey );
}
if (DEBUG) debug( "mounting child "+ childElement.getNodeName() + " at worknode " + worknode.toString() );
// now mount it, possibly re-using the helmaNode that's been created before
if ( newHelmaNode!=null ) {
worknode.addNode(newHelmaNode);
} else {
convert( childElement, worknode.createNode( null ) );
}
}
// forget about other types (comments etc)
continue;
}
// if there's some text content for this element, map it:
if ( textcontent.length()>0 ) {
helmaKey = (String)props.get(element.getNodeName().toLowerCase()+"._text");
if ( helmaKey==null )
helmaKey = "text";
helmaNode.setString(helmaKey, textcontent.toString().trim() );
}
return helmaNode;
}
/**
* set element's attributes as properties of helmaNode
*/
private INode attributes( Element element, INode helmaNode ) {
NamedNodeMap nnm = element.getAttributes();
int len = nnm.getLength();
for ( int i=0; i<len; i++ ) {
org.w3c.dom.Node attr = nnm.item(i);
if ( attr.getNodeName().equals("_prototype") ) {
helmaNode.setPrototype( attr.getNodeValue() );
} else if ( attr.getNodeName().equals("_name") ) {
helmaNode.setName( attr.getNodeValue() );
} else {
String helmaKey = (String)props.get(element.getNodeName().toLowerCase()+".attributes."+attr.getNodeName().toLowerCase());
if ( helmaKey==null )
helmaKey = attr.getNodeName().replace(':',defaultSeparator);
helmaNode.setString( helmaKey, attr.getNodeValue() );
}
}
return helmaNode;
}
/**
* utility function
*/
private void extractProperties( Properties props ) {
if ( props.containsKey("separator") ) {
defaultSeparator = ((String)props.get("separator")).charAt(0);
}
}
/** for testing */
void debug(Object msg) {
for ( int i=0; i<offset; i++ ) {
System.out.print(" ");
}
System.out.println(msg.toString());
}
public static void main ( String args[] ) {
}
}

View file

@ -0,0 +1,157 @@
package helma.objectmodel.dom;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import helma.objectmodel.*;
public class XmlReader implements XmlConstants {
private int offset = 0;
private HashMap convertedNodes;
public XmlReader() {
}
public INode read( String desc ) {
return read(desc, new TransientNode() );
}
public INode read( String desc, INode helmaNode ) throws RuntimeException {
try {
return read( new File(desc), helmaNode );
} catch ( FileNotFoundException notfound ) {
throw new RuntimeException( "couldn't find xml-file: " + desc );
} catch ( IOException ioerror ) {
throw new RuntimeException( "couldn't read xml: " + desc );
}
}
public INode read( File file, INode helmaNode ) throws RuntimeException, FileNotFoundException {
return read( new FileInputStream(file), helmaNode );
}
public INode read( InputStream in, INode helmaNode ) throws RuntimeException {
Document document = XmlUtil.parse(in);
if ( document!=null && document.getDocumentElement()!=null ) {
Node tmp = document.getDocumentElement().getFirstChild();
Element workelement = null;
while( tmp!=null ) {
tmp = tmp.getNextSibling();
if ( tmp.getNodeType()==Node.ELEMENT_NODE ) {
workelement = (Element) tmp;
break;
}
}
return startConversion( helmaNode, workelement );
} else {
return helmaNode;
}
}
public INode startConversion( INode helmaNode, Element element ) {
convertedNodes = new HashMap();
INode convertedNode = convert(helmaNode, element );
convertedNodes = null;
return convertedNode;
}
public INode convert( INode helmaNode, Element element ) {
offset++;
String idref = element.getAttributeNS(NAMESPACE, "idref");
String key = idref + "-" + element.getAttributeNS(NAMESPACE, "prototyperef");
if( idref!=null && !idref.equals("") ) {
if( convertedNodes.containsKey(key) ) {
offset--;
return (INode)convertedNodes.get(key);
}
}
key = element.getAttributeNS(NAMESPACE, "id") + "-" + element.getAttributeNS(NAMESPACE, "prototype");
convertedNodes.put( key, helmaNode );
// FIXME: import id on persistent nodes
String prototype = element.getAttributeNS(NAMESPACE, "prototype");
if( !prototype.equals("") && !prototype.equals("hopobject") ) {
helmaNode.setPrototype( prototype );
}
children(helmaNode, element);
offset--;
return helmaNode;
}
private INode children( INode helmaNode, Element element ) {
NodeList list = element.getChildNodes();
int len = list.getLength();
Element childElement;
for ( int i=0; i<len; i++ ) {
try {
childElement = (Element)list.item(i);
} catch( ClassCastException e ) {
continue;
}
INode workNode = null;
if ( childElement.getTagName().equals("hop:child") ) {
convert( helmaNode.createNode(null), childElement );
} else if ( !"".equals(childElement.getAttributeNS(NAMESPACE,"id")) || !"".equals(childElement.getAttributeNS(NAMESPACE,"idref")) ) {
// we've got an object!
helmaNode.setNode( childElement.getTagName(), convert( helmaNode.createNode(childElement.getTagName()), childElement ) );
} else {
String type = childElement.getAttribute("hop:type");
String key = childElement.getTagName();
String content = XmlUtil.getTextContent(childElement);
if ( type.equals("boolean") ) {
if ( content.equals("true") ) {
helmaNode.setBoolean(key,true);
} else {
helmaNode.setBoolean(key,false);
}
} else if ( type.equals("date") ) {
SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT );
try {
Date date = format.parse(content);
helmaNode.setDate(key, date);
} catch ( ParseException e ) {
helmaNode.setString(key,content);
}
} else if ( type.equals("float") ) {
helmaNode.setFloat(key, (new Double(content)).doubleValue() );
} else if ( type.equals("integer") ) {
helmaNode.setInteger(key, (new Long(content)).longValue() );
} else {
helmaNode.setString(key,content);
}
}
}
return helmaNode;
}
/** for testing */
public static void main ( String args[] ) throws Exception {
try {
XmlReader x = new XmlReader ();
INode node = x.read("test.xml");
} catch ( Exception e ) {
System.out.println("exception " + e.toString() );
throw new RuntimeException(e.toString());
}
}
/** for testing */
void debug(Object msg) {
for ( int i=0; i<offset; i++ ) {
System.out.print(" ");
}
System.out.println(msg.toString());
}
}

View file

@ -0,0 +1,74 @@
package helma.objectmodel.dom;
import java.io.InputStream;
import java.io.IOException;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import helma.objectmodel.INode;
import helma.objectmodel.TransientNode;
public class XmlUtil {
private static final DocumentBuilderFactory domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
private static final HashMap domBuilders = new HashMap();
private static synchronized DocumentBuilder getDocumentBuilder() {
if ( domBuilders.containsKey (Thread.currentThread()) ) {
return (DocumentBuilder)domBuilders.get (Thread.currentThread());
} else {
try {
DocumentBuilder d = domBuilderFactory.newDocumentBuilder();
domBuilders.put (Thread.currentThread(),d);
return d;
} catch ( ParserConfigurationException e ) {
throw new RuntimeException ("Cannot build parser: "+e.toString());
}
}
}
public static Document newDocument() {
DocumentBuilder d = getDocumentBuilder();
return d.newDocument();
}
public static Document parse (InputStream in) throws RuntimeException {
DocumentBuilder d = getDocumentBuilder();
try {
Document doc = d.parse (in);
doc.normalize();
return doc;
} catch (SAXException e) {
throw new RuntimeException ("Bad xml-code: "+e.toString());
} catch (IOException f) {
throw new RuntimeException ("Could not read Xml: "+f.toString());
}
}
/**
* return the text content of an element
*/
public static String getTextContent( org.w3c.dom.Node element ) {
StringBuffer childtext = new StringBuffer();
NodeList childlist = element.getChildNodes();
int ct = childlist.getLength();
for ( int j=0; j<ct; j++ ) {
org.w3c.dom.Node childNode = childlist.item(j);
if ( childNode.getNodeType()==org.w3c.dom.Node.TEXT_NODE ) {
childtext.append(childNode.getNodeValue().trim() );
}
}
return childtext.toString();
}
}

View file

@ -0,0 +1,259 @@
package helma.objectmodel.dom;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import helma.objectmodel.*;
import helma.util.HtmlEncoder;
public class XmlWriter extends OutputStreamWriter implements XmlConstants {
private final static String LINESEPARATOR = System.getProperty("line.separator");
private Vector convertedNodes;
private int maxLevels = 3;
private String indent = " ";
private StringBuffer prefix = new StringBuffer();
private static int fileid;
/**
* create ids that can be used for temporary files.
*/
public static int generateID() {
return fileid++;
}
/**
* empty constructor, will use System.out as outputstream.
*/
public XmlWriter () {
super(System.out);
}
public XmlWriter (OutputStream out) {
super(out);
}
public XmlWriter (String desc) throws FileNotFoundException {
super (new FileOutputStream (desc));
}
public XmlWriter (File file) throws FileNotFoundException {
super (new FileOutputStream (file));
}
/**
* by default writing only descends 50 levels into the node tree to prevent
* infite loops. number can be changed here.
*/
public void setMaxLevels (int levels) {
maxLevels = levels;
}
/**
* set the number of space chars
*/
public void setIndent (int ct) {
StringBuffer tmp = new StringBuffer ();
for ( int i=0; i<ct; i++ ) {
tmp.append(" ");
}
indent = tmp.toString();
}
/**
* starting point for printing a node tree.
* creates document header too and initializes
* the cache of already converted nodes.
*/
public boolean write( INode node ) throws IOException {
convertedNodes = new Vector();
writeln ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
writeln ("<!-- printed by helma object publisher -->");
writeln ("<!-- created " + (new Date()).toString() + " -->" );
write ("<xmlroot xmlns:hop=\"");
write (NAMESPACE);
writeln ("\">");
write (node,null,0);
writeln ("</xmlroot>");
convertedNodes = null;
return true;
}
/**
* write a hopobject and print all its properties and children.
* if node has already been fully printed, just make a reference here.
*/
public void write (INode node, String name, int level) throws IOException {
if ( ++level>maxLevels )
return;
prefix.append(indent);
if ( convertedNodes.contains(node) ) {
writeReferenceTag (node, name);
} else {
convertedNodes.addElement (node);
writeTagOpen (node,name);
writeProperties (node,level);
writeChildren (node,level);
writeTagClose (node,name);
}
prefix = prefix.delete( prefix.length()-indent.length(), Integer.MAX_VALUE );
}
/**
* loop through properties and print them with their property-name
* as elementname
*/
private void writeProperties (INode node, int level) throws IOException {
Enumeration e = node.properties();
while ( e.hasMoreElements() ) {
String key = (String)e.nextElement();
IProperty prop = node.get(key,false);
if ( prop!=null ) {
int type = prop.getType();
if( type==IProperty.NODE ) {
write (node.getNode(key,false), key, level);
} else {
writeProperty (node.get(key,false));
}
}
}
}
public void writeNullProperty (String key) throws IOException {
write (prefix.toString());
write (indent);
write ("<");
write (key);
write (" hop:type=\"null\"/>");
write (LINESEPARATOR);
}
/**
* write a single property, set attribute type according to type,
* apply xml-encoding.
*/
public void writeProperty (IProperty property) throws IOException {
write (prefix.toString());
write (indent);
write ("<");
write (property.getName());
switch (property.getType()) {
case IProperty.BOOLEAN:
write (" hop:type=\"boolean\"");
break;
case IProperty.FLOAT:
write (" hop:type=\"float\"");
break;
case IProperty.INTEGER:
write (" hop:type=\"integer\"");
break;
}
if ( property.getType()==IProperty.DATE ) {
write (" hop:type=\"date\"");
SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT );
write (">");
write ( format.format (property.getDateValue()) );
} else {
write (">");
write ( HtmlEncoder.encodeXml (property.getStringValue()) );
}
write ("</");
write (property.getName());
write (">");
write (LINESEPARATOR);
}
/**
* loop through the children-array and print them as <hop:child>
*/
private void writeChildren (INode node, int level) throws IOException {
Enumeration e = node.getSubnodes();
while (e.hasMoreElements()) {
INode nextNode = (INode)e.nextElement();
write (nextNode, "hop:child", level);
}
}
/**
* write an opening tag for a node. Include id and prototype, use a
* name if parameter is non-empty.
*/
public void writeTagOpen (INode node, String name) throws IOException {
write (prefix.toString());
write ("<");
write ( (name==null)?"hopobject" : name);
write (" hop:id=\"");
write (getNodeIdentifier(node));
write ("\" hop:prototype=\"");
write (getNodePrototype(node));
write ("\"");
write (">");
write (LINESEPARATOR);
}
/**
* write a closing tag for a node
* e.g. </root>
*/
public void writeTagClose (INode node, String name) throws IOException {
write (prefix.toString());
write ("</");
write ( (name==null)?"hopobject" : name);
write (">");
write (LINESEPARATOR);
}
/**
* write a tag holding a reference to an element that has
* been dumped before.
* e.g. <parent hop:idref="t35" hop:prototyperef="hopobject"/>
*/
public void writeReferenceTag (INode node, String name) throws IOException {
write (prefix.toString());
write ("<");
write ( (name==null)?"hopobject" : name);
write ( " hop:idref=\"");
write (getNodeIdentifier(node));
write ("\" hop:prototyperef=\"");
write (getNodePrototype(node));
write ("\"");
write ("/>");
write (LINESEPARATOR);
}
/**
* retrieve prototype-string of a node, defaults to "hopobject"
*/
private String getNodePrototype( INode node ) {
if ( node.getPrototype()==null || "".equals(node.getPrototype()) ) {
return "hopobject";
} else {
return node.getPrototype();
}
}
/**
* TransientNode produces a different ID each time we call the getID()-method
* this is a workaround and uses hashCode if INode stands for a TransientNode.
*/
private String getNodeIdentifier( INode node ) {
try {
TransientNode tmp = (TransientNode)node;
return Integer.toString( tmp.hashCode() );
} catch ( ClassCastException e ) {
return node.getID();
}
}
public void writeln(String str) throws IOException {
write (str);
write (LINESEPARATOR);
}
}

View file

@ -0,0 +1,163 @@
package helma.scripting.fesi.extensions;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import FESI.Data.*;
import FESI.Exceptions.*;
import FESI.Extensions.*;
import FESI.Interpreter.*;
import helma.framework.core.Application;
import helma.framework.core.RequestEvaluator;
import helma.objectmodel.INode;
import helma.objectmodel.db.Node;
import helma.objectmodel.dom.*;
import helma.scripting.fesi.ESNode;
public class DomExtension extends Extension {
private transient Evaluator evaluator = null;
public DomExtension() {
super();
}
public void initializeExtension(Evaluator evaluator) throws EcmaScriptException {
this.evaluator = evaluator;
GlobalObject go = evaluator.getGlobalObject();
ObjectPrototype op = (ObjectPrototype) evaluator.getObjectPrototype();
FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
ESObject globalXml = new GlobalObjectXml("Xml", evaluator, fp);
globalXml.putHiddenProperty ("length",new ESNumber(1));
globalXml.putHiddenProperty ("load", new XmlLoad ("load", evaluator, fp));
globalXml.putHiddenProperty ("save", new XmlSave ("save", evaluator, fp));
globalXml.putHiddenProperty ("create", new XmlCreate ("create", evaluator, fp));
globalXml.putHiddenProperty ("get", new XmlGet ("get", evaluator, fp));
go.putHiddenProperty ("Xml", globalXml);
}
class GlobalObjectXml extends BuiltinFunctionObject {
GlobalObjectXml(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
return doConstruct(thisObject, arguments);
}
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
throw new EcmaScriptException("Xml can't be instanced");
}
}
class XmlSave extends BuiltinFunctionObject {
XmlSave(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length<2 )
throw new EcmaScriptException("not enough arguments");
INode node = null;
try {
node = ((ESNode)arguments[1]).getNode();
} catch ( Exception e ) {
// we definitly need a node
throw new EcmaScriptException("argument is not an hopobject");
}
try {
File tmpFile = new File(arguments[0].toString()+".tmp."+XmlWriter.generateID());
XmlWriter writer = new XmlWriter (tmpFile);
boolean result = writer.write(node);
writer.close();
File finalFile = new File(arguments[0].toString());
tmpFile.renameTo (finalFile);
this.evaluator.reval.app.logEvent("wrote xml to " + finalFile.getAbsolutePath() );
} catch (IOException io) {
throw new EcmaScriptException (io.toString());
}
return ESBoolean.makeBoolean(true);
}
}
class XmlCreate extends BuiltinFunctionObject {
XmlCreate(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length==0 )
throw new EcmaScriptException("not enough arguments");
INode node = null;
try {
node = ((ESNode)arguments[0]).getNode();
} catch ( Exception e ) {
// we definitly need a node
throw new EcmaScriptException("argument is not an hopobject");
}
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XmlWriter writer = new XmlWriter (out);
boolean result = writer.write(node);
writer.flush();
return new ESString (out.toString());
} catch (IOException io) {
throw new EcmaScriptException (io.toString());
}
}
}
class XmlLoad extends BuiltinFunctionObject {
XmlLoad(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length==0 )
throw new EcmaScriptException("no arguments for Xml.load()");
INode node = null;
try {
node = ((ESNode)arguments[1]).getNode();
} catch ( Exception e ) { //classcast, arrayindex etc
// make sure we have a node, even if 2nd arg doesn't exist or is not a node
node = new Node ( (String)null, (String)null, this.evaluator.reval.app.getWrappedNodeManager() );
}
try {
XmlReader reader = new XmlReader ();
INode result = reader.read (arguments[0].toString(),node);
return this.evaluator.reval.getNodeWrapper (result);
} catch ( NoClassDefFoundError e ) {
throw new EcmaScriptException ("Can't load dom-capable xml parser.");
} catch ( RuntimeException f ) {
throw new EcmaScriptException (f.toString());
}
}
}
class XmlGet extends BuiltinFunctionObject {
XmlGet(String name, Evaluator evaluator, FunctionPrototype fp) {
super(fp, evaluator, name, 1);
}
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if ( arguments==null || arguments.length==0 )
throw new EcmaScriptException("Xml.get() needs a location as an argument");
try {
XmlConverter converter;
if ( arguments.length>1 ) {
converter = new XmlConverter (arguments[1].toString());
} else {
converter = new XmlConverter ();
}
INode node = new helma.objectmodel.db.Node ( (String)null, (String)null, this.evaluator.reval.app.getWrappedNodeManager() );
INode result = converter.convert (arguments[0].toString(),node);
return this.evaluator.reval.getNodeWrapper(result);
} catch ( NoClassDefFoundError e ) {
throw new EcmaScriptException("Can't load dom-capable xml parser.");
} catch ( RuntimeException f ) {
throw new EcmaScriptException(f.toString());
}
}
}
}