001: package net.sf.saxon.jdom;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.event.PipelineConfiguration;
005: import net.sf.saxon.event.Receiver;
006: import net.sf.saxon.expr.XPathContext;
007: import net.sf.saxon.om.DocumentInfo;
008: import net.sf.saxon.om.ExternalObjectModel;
009: import net.sf.saxon.om.NodeInfo;
010: import net.sf.saxon.trans.XPathException;
011: import net.sf.saxon.value.Value;
012: import net.sf.saxon.value.SequenceExtent;
013: import org.jdom.*;
014:
015: import javax.xml.transform.Result;
016: import javax.xml.transform.Source;
017: import java.io.Serializable;
018:
019: /**
020: * This interface must be implemented by any third-party object model that can
021: * be wrapped with a wrapper that implements the Saxon Object Model (the NodeInfo interface).
022: * This implementation of the interface supports wrapping of JDOM Documents.
023: */
024:
025: public class JDOMObjectModel implements ExternalObjectModel,
026: Serializable {
027:
028: public JDOMObjectModel() {
029: }
030:
031: /**
032: * Test whether this object model recognizes a given node as one of its own
033: */
034:
035: public boolean isRecognizedNode(Object object) {
036: return object instanceof Document || object instanceof Element
037: || object instanceof Attribute
038: || object instanceof Text || object instanceof CDATA
039: || object instanceof Comment
040: || object instanceof ProcessingInstruction
041: || object instanceof Namespace;
042: }
043:
044: /**
045: * Test whether this object model recognizes a given class as representing a
046: * node in that object model. This method will generally be called at compile time.
047: *
048: * @param nodeClass A class that possibly represents nodes
049: * @return true if the class is used to represent nodes in this object model
050: */
051:
052: public boolean isRecognizedNodeClass(Class nodeClass) {
053: return Document.class.isAssignableFrom(nodeClass)
054: || Element.class.isAssignableFrom(nodeClass)
055: || Attribute.class.isAssignableFrom(nodeClass)
056: || Text.class.isAssignableFrom(nodeClass)
057: || CDATA.class.isAssignableFrom(nodeClass)
058: || Comment.class.isAssignableFrom(nodeClass)
059: || ProcessingInstruction.class
060: .isAssignableFrom(nodeClass)
061: || Namespace.class.isAssignableFrom(nodeClass);
062: }
063:
064: /**
065: * Test whether this object model recognizes a given class as representing a
066: * list of nodes in that object model. This method will generally be called at compile time.
067: *
068: * @param nodeClass A class that possibly represents nodes
069: * @return true if the class is used to represent nodes in this object model
070: */
071:
072: public boolean isRecognizedNodeListClass(Class nodeClass) {
073: return false;
074: }
075:
076: /**
077: * Test whether this object model recognizes a particular kind of JAXP Result object,
078: * and if it does, return a Receiver that builds an instance of this data model from
079: * a sequence of events. If the Result is not recognised, return null.
080: */
081:
082: public Receiver getDocumentBuilder(Result result) {
083: return null; //To change body of implemented methods use File | Settings | File Templates.
084: }
085:
086: /**
087: * Test whether this object model recognizes a particular kind of JAXP Source object,
088: * and if it does, send the contents of the document to a supplied Receiver, and return true.
089: * Otherwise, return false.
090: */
091:
092: public boolean sendSource(Source source, Receiver receiver,
093: PipelineConfiguration pipe) throws XPathException {
094: return false; //To change body of implemented methods use File | Settings | File Templates.
095: }
096:
097: /**
098: * Wrap or unwrap a node using this object model to return the corresponding Saxon node. If the supplied
099: * source does not belong to this object model, return null
100: */
101:
102: public NodeInfo unravel(Source source, Configuration config) {
103: return null; //To change body of implemented methods use File | Settings | File Templates.
104: }
105:
106: /**
107: * Convert a Java object to an XPath value. If the supplied object is recognized as a representation
108: * of a value using this object model, the object model should convert the value to an XPath value
109: * and return this as the result. If not, it should return null. If the object is recognized but cannot
110: * be converted, an exception should be thrown
111: */
112:
113: public Value convertObjectToXPathValue(Object object,
114: Configuration config) throws XPathException {
115: return null; //To change body of implemented methods use File | Settings | File Templates.
116: }
117:
118: /**
119: * Convert an XPath value to an object in this object model. If the supplied value can be converted
120: * to an object in this model, of the specified class, then the conversion should be done and the
121: * resulting object returned. If the value cannot be converted, the method should return null. Note
122: * that the supplied class might be a List, in which case the method should inspect the contents of the
123: * Value to see whether they belong to this object model.
124: */
125:
126: public Object convertXPathValueToObject(Value value,
127: Class targetClass, XPathContext context) {
128: return null; //To change body of implemented methods use File | Settings | File Templates.
129: }
130:
131: /**
132: * Wrap a document node in the external object model in a document wrapper that implements
133: * the Saxon DocumentInfo interface
134: * @param node a node (any node) in the third party document
135: * @param baseURI the base URI of the node (supply "" if unknown)
136: * @param config the Saxon configuration (which among other things provides access to the NamePool)
137: * @return the wrapper, which must implement DocumentInfo
138: */
139:
140: public DocumentInfo wrapDocument(Object node, String baseURI,
141: Configuration config) {
142: Document documentNode = getDocumentRoot(node);
143: return new DocumentWrapper(documentNode, baseURI, config);
144: }
145:
146: /**
147: * Wrap a node within the external object model in a node wrapper that implements the Saxon
148: * VirtualNode interface (which is an extension of NodeInfo)
149: * @param document the document wrapper, as a DocumentInfo object
150: * @param node the node to be wrapped. This must be a node within the document wrapped by the
151: * DocumentInfo provided in the first argument
152: * @return the wrapper for the node, as an instance of VirtualNode
153: */
154:
155: public NodeInfo wrapNode(DocumentInfo document, Object node) {
156: return ((DocumentWrapper) document).wrap(node);
157: }
158:
159: /**
160: * Get the document root
161: */
162:
163: private Document getDocumentRoot(Object node) {
164: while (!(node instanceof Document)) {
165: if (node instanceof Element) {
166: if (((Element) node).isRootElement()) {
167: return ((Element) node).getDocument();
168: } else {
169: node = ((Element) node).getParent();
170: }
171: } else if (node instanceof Text) {
172: node = ((Text) node).getParent();
173: } else if (node instanceof Comment) {
174: node = ((Comment) node).getParent();
175: } else if (node instanceof ProcessingInstruction) {
176: node = ((ProcessingInstruction) node).getParent();
177: } else if (node instanceof Attribute) {
178: node = ((Attribute) node).getParent();
179: } else if (node instanceof Document) {
180: return (Document) node;
181: } else if (node instanceof Namespace) {
182: throw new UnsupportedOperationException(
183: "Cannot find parent of JDOM namespace node");
184: } else {
185: throw new IllegalStateException(
186: "Unknown JDOM node type " + node.getClass());
187: }
188: }
189: return (Document) node;
190: }
191:
192: /**
193: * Convert a sequence of values to a NODELIST, as defined in the JAXP XPath API spec. This method
194: * is used when the evaluate() request specifies the return type as NODELIST, regardless of the
195: * actual results of the expression. If the sequence contains things other than nodes, the fallback
196: * is to return the sequence as a Java List object. The method can return null to invoke fallback
197: * behaviour.
198: */
199:
200: public Object convertToNodeList(SequenceExtent extent) {
201: return null;
202: }
203: }
204:
205: //
206: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
207: // you may not use this file except in compliance with the License. You may obtain a copy of the
208: // License at http://www.mozilla.org/MPL/
209: //
210: // Software distributed under the License is distributed on an "AS IS" basis,
211: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
212: // See the License for the specific language governing rights and limitations under the License.
213: //
214: // The Original Code is: all this file.
215: //
216: // The Initial Developer of the Original Code is Michael H. Kay.
217: //
218: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
219: //
220: // Contributor(s): Gunther Schadow (changes to allow access to public fields; also wrapping
221: // of extensions and mapping of null to empty sequence).
222: //
|