001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: XMLResourceImpl.java,v 1.1 2001/12/18 11:03:24 per_nyfelt Exp $
008:
009: package org.ozoneDB.xml.cli.resources;
010:
011: import java.io.StringReader;
012: import java.io.StringWriter;
013:
014: import org.ozoneDB.ExternalDatabase;
015: import org.ozoneDB.ExternalTransaction;
016: import org.ozoneDB.xml.core.XMLCollection;
017: import org.ozoneDB.xml.util.XMLContainer;
018:
019: import org.w3c.dom.Node;
020: import org.w3c.dom.Document;
021: import org.apache.xerces.parsers.DOMParser; //import org.apache.xerces.parsers.SAXParser;
022: import javax.xml.parsers.SAXParser;
023: import org.xml.sax.helpers.ParserAdapter;
024: import org.xml.sax.ContentHandler;
025: import org.xml.sax.InputSource;
026: import org.xml.sax.SAXException;
027: import org.xml.sax.XMLReader; //import org.xml.sax.helpers.XMLReaderFactory;
028: import javax.xml.parsers.SAXParserFactory;
029: import javax.xml.parsers.DocumentBuilderFactory;
030: import javax.xml.parsers.DocumentBuilder;
031:
032: import org.xmldb.api.base.Collection;
033: import org.xmldb.api.base.ErrorCodes;
034: import org.xmldb.api.base.XMLDBException;
035: import org.xmldb.api.modules.XMLResource;
036:
037: import org.apache.xml.serialize.XMLSerializer;
038: import org.apache.xml.serialize.OutputFormat;
039:
040: /**
041: * This is a database persistent XML class for XML:DB, possible of
042: * returning XML content back as DOM, SAX or String. Performance is
043: * best using DOM. Please note that getContent() is overridden to
044: * return a <code>String</code> back and can always be cast to a String.
045: *
046: * @author <a href="http://www.smb-tec.com">SMB</a>, Per Nyfelt
047: * @version $Revision: 1.1 $
048: */
049: public class XMLResourceImpl implements XMLResource {
050:
051: //
052: // data
053: //
054: // the SAX parser we use in setContent
055: private final SAXParserFactory parserFactory = new org.apache.xerces.jaxp.SAXParserFactoryImpl();
056: private ExternalDatabase database;
057: // the XML document this class operates on
058: private XMLContainer container;
059: // the Collection this resource resides in
060: private Collection collection;
061: // since there is no setId() in the interface we have to get the id in the construction
062: private String id;
063:
064: public XMLResourceImpl(String id, ExternalDatabase database,
065: Collection collection, XMLContainer container) {
066: System.out.println("XMLResourceImpl CREATED ***********");
067: this .database = database;
068: this .container = container;
069: this .collection = collection;
070: this .id = id;
071:
072: }
073:
074: /**
075: * Returns the <code>Collection</code> instance that this resource is
076: * associated with.
077: *
078: * @return the collection associated with the resource.
079: */
080: public Collection getParentCollection() throws XMLDBException {
081: return collection;
082: }
083:
084: /**
085: * Returns the unique id for this Resource or null if the resource has
086: * not yet been given one.
087: *
088: * @return the id for the Resource or null if no id exists.
089: */
090: public String getId() throws XMLDBException {
091: return id;
092: }
093:
094: /**
095: * Sets the content of the <code>Resource</code> using a either a
096: * String or a DOM Node as the source.
097: *
098: * @param content The new content value
099: */
100: public void setContent(Object value) throws XMLDBException {
101: if (value instanceof String) {
102: ExternalTransaction tx = database.newTransaction();
103: // we assume it's a valid XML doc and parse it
104: try {
105: StringReader in = new StringReader((String) value);
106: InputSource source = new InputSource(in);
107: SAXParser parser = parserFactory.newSAXParser();
108: ParserAdapter adapter = new ParserAdapter(parser
109: .getParser());
110: tx.begin();
111: adapter.setContentHandler(container.storeSAX());
112: adapter.parse(source);
113: tx.commit();
114: } catch (SAXException e) {
115: try {
116: if (tx.getStatus() == tx.STATUS_ACTIVE)
117: tx.rollback();
118: throw new XMLDBException(
119: ErrorCodes.INVALID_RESOURCE, e.getMessage());
120: } catch (Exception rollbackException) {
121: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
122: rollbackException.toString());
123: }
124: } catch (Exception e) {
125: try {
126: if (tx.getStatus() == tx.STATUS_ACTIVE)
127: tx.rollback();
128: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
129: .getMessage());
130: } catch (Exception rollbackException) {
131: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
132: rollbackException.toString());
133: }
134: }
135: } else if (value instanceof Node) {
136: setContentAsDOM((Node) value);
137: } else
138: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
139: ErrorCodes.UNKNOWN_RESOURCE_TYPE);
140: }
141:
142: /**
143: * Returns a String representation of the XML content
144: * usage exampel : <BR/>
145: * String content = (String)xmlResource.getContent(); <BR/>
146: * @return a String representation of the XML content
147: */
148: public Object getContent() throws XMLDBException {
149: try {
150: return toString("xml", "UTF-8", true);
151: } catch (Exception e) {
152: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
153: .getMessage());
154: }
155: }
156:
157: /**
158: * Returns the resource type for this Resource.
159: *
160: * @return the resource type for the Resource.
161: */
162: public String getResourceType() throws XMLDBException {
163: return XMLResource.RESOURCE_TYPE;
164: }
165:
166: /**
167: * Returns the content of the <code>Resource</code> as a DOM Node.
168: *
169: * @return The XML content as a DOM <code>Node</code>
170: */
171: public Node getContentAsDOM() throws XMLDBException {
172: ExternalTransaction tx = database.newTransaction();
173: try {
174: tx.begin();
175: DocumentBuilderFactory builderFactory = new org.apache.xerces.jaxp.DocumentBuilderFactoryImpl();
176: DocumentBuilder documentBuilder = builderFactory
177: .newDocumentBuilder();
178: Document doc = container.extractDOM(documentBuilder
179: .newDocument());
180: tx.commit();
181: return doc;
182: } catch (Exception e) {
183: try {
184: if (tx.getStatus() == tx.STATUS_ACTIVE)
185: tx.rollback();
186: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
187: .getMessage());
188: } catch (Exception rollbackException) {
189: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
190: rollbackException.toString());
191: }
192: }
193: }
194:
195: /**
196: * Sets the content of the <code>Resource</code> using a DOM Node as the
197: * source.
198: *
199: * @param content The new content value
200: */
201: public void setContentAsDOM(Node content) throws XMLDBException {
202: ExternalTransaction tx = database.newTransaction();
203: try {
204: if (content == null) {
205: System.out
206: .println("XMLResourceImpl.setContentAsDOM() - Content is null");
207: throw new XMLDBException(ErrorCodes.INVALID_RESOURCE);
208: }
209: if (content instanceof Document) {
210: Document doc = (Document) content;
211: tx.begin();
212: container.storeDOM(doc);
213: tx.commit();
214: } else {
215: System.out
216: .println("Cannot store Nodes right now, must be a Document");
217: }
218: } catch (Exception e) {
219: e.printStackTrace();
220: try {
221: System.out
222: .println("XMLResourceImpl.setContentAsDOM() - Transaction status is "
223: + tx.getStatus());
224: if (tx.getStatus() == tx.STATUS_ACTIVE)
225: tx.rollback();
226: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
227: .getMessage());
228: } catch (Exception rollbackException) {
229: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
230: rollbackException.getMessage());
231: }
232: }
233: }
234:
235: /**
236: * Allows you to use a <code>ContentHandler</code> to parse the XML data from
237: * the database for use in an application.
238: *
239: * @param handler the SAX <code>ContentHandler</code> to use to handle the
240: * <code>Resource</code> content.
241: */
242: public void getContentAsSAX(ContentHandler handler)
243: throws XMLDBException {
244: ExternalTransaction tx = database.newTransaction();
245: try {
246: tx.begin();
247: container.extractSAX(handler);
248: tx.commit();
249: } catch (Exception e) {
250: try {
251: if (tx.getStatus() == tx.STATUS_ACTIVE)
252: tx.rollback();
253: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
254: .getMessage());
255: } catch (Exception rollbackException) {
256: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
257: rollbackException.toString());
258: }
259: }
260: }
261:
262: /**
263: * Sets the content of the <code>Resource</code> using a SAX
264: * <code>ContentHandler</code>.
265: *
266: * @return a SAX <code>ContentHandler</code> that can be used to add content
267: * into the <code>Resource</code>.
268: */
269: public ContentHandler setContentAsSAX() throws XMLDBException {
270: ExternalTransaction tx = database.newTransaction();
271: try {
272: tx.begin();
273: ContentHandler handler = container.storeSAX();
274: tx.commit();
275: return handler;
276: } catch (Exception e) {
277: try {
278: if (tx.getStatus() == tx.STATUS_ACTIVE)
279: tx.rollback();
280: throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e
281: .getMessage());
282: } catch (Exception rollbackException) {
283: throw new XMLDBException(ErrorCodes.VENDOR_ERROR,
284: rollbackException.toString());
285: }
286: }
287: }
288:
289: /** returns a String representation of the Document with the method to be used ,
290: * the encoding type specified and whether to indent or not <br/>
291: * Example: String content = toString( "xml", "UTF-8", true );
292: *
293: */
294: private String toString(String type, String encoding,
295: boolean indenting) throws Exception {
296: int depth = -1;
297: ExternalTransaction tx = database.newTransaction();
298: tx.begin();
299: try {
300: StringWriter writer = new StringWriter();
301: XMLSerializer serializer = new XMLSerializer(writer,
302: new OutputFormat(type, encoding, indenting));
303: ContentHandler handler = serializer.asContentHandler();
304: container.extractSAX(handler, null, depth);
305: writer.flush();
306: tx.commit();
307: return writer.toString();
308: } catch (Exception e) {
309: if (tx.getStatus() == tx.STATUS_ACTIVE)
310: tx.rollback();
311: throw e;
312: }
313: }
314: }
|