Fix references from transient nodes to persistent ones in Xml.read() and Xml.write().

* In XmlWriter generate reference tags when referencing a persistent node from a
   transient one.
* In XmlReader make sure we have the app's NodeManager to look up node
   references we don't know about.
Fixes bug 371: http://helma.org/bugs/show_bug.cgi?id=371
This commit is contained in:
hns 2004-06-28 16:36:33 +00:00
parent 69bf4432a6
commit e1139be0ff
3 changed files with 25 additions and 4 deletions

View file

@ -17,6 +17,7 @@
package helma.objectmodel.dom;
import helma.objectmodel.INode;
import helma.objectmodel.db.WrappedNodeManager;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -45,11 +46,13 @@ public final class XmlReader extends DefaultHandler implements XmlConstants {
private String elementName = null;
private StringBuffer charBuffer = null;
boolean parsingHopObject;
WrappedNodeManager nmgr;
/**
* Creates a new XmlReader object.
*/
public XmlReader() {
public XmlReader(WrappedNodeManager nmgr) {
this.nmgr = nmgr;
}
/**
@ -190,6 +193,12 @@ public final class XmlReader extends DefaultHandler implements XmlConstants {
String key = idref + "-" + prototyperef;
INode n = (INode) convertedNodes.get(key);
// if not a reference to a node we already read, try to
// resolve against the NodeManager.
if (n == null) {
n = nmgr.getNode(idref, nmgr.getDbMapping(prototyperef));
}
if (n != null) {
if ("hop:child".equals(qName)) {
// add an already parsed node as child to current node

View file

@ -20,6 +20,7 @@ package helma.objectmodel.dom;
import helma.objectmodel.INode;
import helma.objectmodel.IProperty;
import helma.objectmodel.TransientNode;
import helma.objectmodel.INodeState;
import helma.objectmodel.db.DbMapping;
import helma.objectmodel.db.Node;
import helma.util.HtmlEncoder;
@ -43,7 +44,10 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
private SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
private boolean dbmode = true;
// Only add encoding to XML declaration if it was explicitly set, not when we're using
// the helma.objectmodel.INodeState of the node we're writing
public int rootState;
// Only add encoding to XML declaration if it was explicitly set, not when we're using
// the platform's standard encoding.
private String explicitEncoding;
@ -182,6 +186,7 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
* the cache of already converted nodes.
*/
public boolean write(INode node) throws IOException {
rootState = node.getState();
convertedNodes = new Vector();
if (explicitEncoding == null) {
@ -228,6 +233,13 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
if (convertedNodes.contains(node)) {
writeReferenceTag(node, elementName, propName);
} else if (rootState == INodeState.TRANSIENT &&
node.getState() > INodeState.TRANSIENT) {
// if we are writing a transient node, and that node
// holds a reference to a persistent one, just write a
// reference tag to that persistent node.
writeReferenceTag(node, elementName, propName);
} else {
convertedNodes.addElement(node);
writeTagOpen(node, elementName, propName);

View file

@ -141,7 +141,7 @@ public class XmlObject {
}
try {
XmlReader reader = new XmlReader();
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
INode result = reader.read(new File(file), node);
return core.getNodeWrapper(result);
@ -188,7 +188,7 @@ public class XmlObject {
}
try {
XmlReader reader = new XmlReader();
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
INode result = reader.read(new StringReader(str), node);
return core.getNodeWrapper(result);