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:
parent
69bf4432a6
commit
e1139be0ff
3 changed files with 25 additions and 4 deletions
|
@ -17,6 +17,7 @@
|
||||||
package helma.objectmodel.dom;
|
package helma.objectmodel.dom;
|
||||||
|
|
||||||
import helma.objectmodel.INode;
|
import helma.objectmodel.INode;
|
||||||
|
import helma.objectmodel.db.WrappedNodeManager;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
@ -45,11 +46,13 @@ public final class XmlReader extends DefaultHandler implements XmlConstants {
|
||||||
private String elementName = null;
|
private String elementName = null;
|
||||||
private StringBuffer charBuffer = null;
|
private StringBuffer charBuffer = null;
|
||||||
boolean parsingHopObject;
|
boolean parsingHopObject;
|
||||||
|
WrappedNodeManager nmgr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new XmlReader object.
|
* 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;
|
String key = idref + "-" + prototyperef;
|
||||||
INode n = (INode) convertedNodes.get(key);
|
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 (n != null) {
|
||||||
if ("hop:child".equals(qName)) {
|
if ("hop:child".equals(qName)) {
|
||||||
// add an already parsed node as child to current node
|
// add an already parsed node as child to current node
|
||||||
|
|
|
@ -20,6 +20,7 @@ package helma.objectmodel.dom;
|
||||||
import helma.objectmodel.INode;
|
import helma.objectmodel.INode;
|
||||||
import helma.objectmodel.IProperty;
|
import helma.objectmodel.IProperty;
|
||||||
import helma.objectmodel.TransientNode;
|
import helma.objectmodel.TransientNode;
|
||||||
|
import helma.objectmodel.INodeState;
|
||||||
import helma.objectmodel.db.DbMapping;
|
import helma.objectmodel.db.DbMapping;
|
||||||
import helma.objectmodel.db.Node;
|
import helma.objectmodel.db.Node;
|
||||||
import helma.util.HtmlEncoder;
|
import helma.util.HtmlEncoder;
|
||||||
|
@ -43,7 +44,10 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
|
||||||
private SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
|
private SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT);
|
||||||
private boolean dbmode = true;
|
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.
|
// the platform's standard encoding.
|
||||||
private String explicitEncoding;
|
private String explicitEncoding;
|
||||||
|
|
||||||
|
@ -182,6 +186,7 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
|
||||||
* the cache of already converted nodes.
|
* the cache of already converted nodes.
|
||||||
*/
|
*/
|
||||||
public boolean write(INode node) throws IOException {
|
public boolean write(INode node) throws IOException {
|
||||||
|
rootState = node.getState();
|
||||||
convertedNodes = new Vector();
|
convertedNodes = new Vector();
|
||||||
|
|
||||||
if (explicitEncoding == null) {
|
if (explicitEncoding == null) {
|
||||||
|
@ -228,6 +233,13 @@ public class XmlWriter extends OutputStreamWriter implements XmlConstants {
|
||||||
|
|
||||||
if (convertedNodes.contains(node)) {
|
if (convertedNodes.contains(node)) {
|
||||||
writeReferenceTag(node, elementName, propName);
|
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 {
|
} else {
|
||||||
convertedNodes.addElement(node);
|
convertedNodes.addElement(node);
|
||||||
writeTagOpen(node, elementName, propName);
|
writeTagOpen(node, elementName, propName);
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class XmlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
XmlReader reader = new XmlReader();
|
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
|
||||||
INode result = reader.read(new File(file), node);
|
INode result = reader.read(new File(file), node);
|
||||||
|
|
||||||
return core.getNodeWrapper(result);
|
return core.getNodeWrapper(result);
|
||||||
|
@ -188,7 +188,7 @@ public class XmlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
XmlReader reader = new XmlReader();
|
XmlReader reader = new XmlReader(core.app.getWrappedNodeManager());
|
||||||
INode result = reader.read(new StringReader(str), node);
|
INode result = reader.read(new StringReader(str), node);
|
||||||
|
|
||||||
return core.getNodeWrapper(result);
|
return core.getNodeWrapper(result);
|
||||||
|
|
Loading…
Add table
Reference in a new issue