001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.generation;
018:
019: import org.apache.avalon.framework.activity.Initializable;
020: import org.apache.avalon.framework.configuration.Configurable;
021: import org.apache.avalon.framework.configuration.Configuration;
022: import org.apache.avalon.framework.configuration.ConfigurationException;
023: import org.apache.avalon.framework.parameters.Parameters;
024:
025: import org.apache.cocoon.ProcessingException;
026: import org.apache.cocoon.ResourceNotFoundException;
027: import org.apache.cocoon.caching.CacheableProcessingComponent;
028: import org.apache.cocoon.environment.SourceResolver;
029: import org.apache.cocoon.util.Deprecation;
030:
031: import org.apache.excalibur.source.SourceValidity;
032: import org.xml.sax.SAXException;
033: import org.xml.sax.helpers.AttributesImpl;
034: import org.xmldb.api.DatabaseManager;
035: import org.xmldb.api.base.Collection;
036: import org.xmldb.api.base.Database;
037: import org.xmldb.api.base.XMLDBException;
038:
039: import java.io.IOException;
040: import java.util.Map;
041:
042: /**
043: * This class implements generation of a XML:DB collection
044: * contents as a directory listing.
045: *
046: * <pre>
047: * <driver>
048: * (a valid DB:XML compliant driver)
049: * </driver>
050: * <base>
051: * xmldb:yourdriver://host/an/optional/path/to/be/prepended
052: * </base>
053: * </pre>
054: *
055: * NOTE: the driver can be any DB:XML compliant driver (although this
056: * component has been tested only with
057: * <a href="http://www.dbxml.org">dbXML</a>, and the trailing
058: * slash in the base tag is important!
059: *
060: * @author <a href="mailto:gianugo@rabellino.it">Gianugo Rabellino</a>
061: * @version CVS $Id: XMLDBCollectionGenerator.java 433543 2006-08-22 06:22:54Z crossley $
062: * @deprecated Use the XML:DB pseudo protocol instead.
063: */
064: public class XMLDBCollectionGenerator extends ServiceableGenerator
065: implements CacheableProcessingComponent, Configurable,
066: Initializable {
067:
068: protected static final String URI = "http://apache.org/cocoon/xmldb/1.0";
069: protected static final String PREFIX = "collection";
070: protected static final String RESOURCE_COUNT_ATTR = "resources";
071: protected static final String COLLECTION_COUNT_ATTR = "collections";
072: protected static final String COLLECTION = "collection";
073: protected static final String QCOLLECTION = PREFIX + ":collection";
074: protected static final String RESOURCE = "resource";
075: protected static final String QRESOURCE = PREFIX + ":resource";
076:
077: protected String driver;
078: protected String base;
079: protected String col;
080: protected Database database;
081: protected Collection collection;
082: protected final AttributesImpl attributes = new AttributesImpl();
083:
084: /**
085: * Recycle the component, keep only the configuration variables
086: * and the database instance for reuse.
087: */
088: public void recycle() {
089: super .recycle();
090: this .col = null;
091: this .collection = null;
092: }
093:
094: /**
095: * Configure the component. This class is expecting a configuration
096: * like the following one:
097: * <pre>
098: * <driver>org.dbxml.client.xmldb.DatabaseImpl</driver>
099: * <base>xmldb:dbxml:///db/</base>
100: * </pre>
101: * NOTE: the driver can be any DB:XML compliant driver (although this
102: * component has been tested only with
103: * <a href="http://www.dbxml.org">dbXML</a>, and the trailing
104: * slash in the base tag is important!
105: *
106: * @exception ConfigurationException (configuration invalid or missing)
107: */
108: public void configure(Configuration conf)
109: throws ConfigurationException {
110: this .driver = conf.getChild("driver").getValue();
111: this .base = conf.getChild("base").getValue();
112: }
113:
114: /**
115: * Initialize the component getting a database instance.
116: *
117: * @exception Exception if an error occurs
118: */
119: public void initialize() throws Exception {
120: try {
121: Class c = Class.forName(driver);
122: database = (Database) c.newInstance();
123: DatabaseManager.registerDatabase(database);
124: } catch (XMLDBException xde) {
125: getLogger().error(
126: "Unable to connect to the XML:DB database");
127: throw new ProcessingException(
128: "Unable to connect to the XML DB"
129: + xde.getMessage());
130: } catch (Exception e) {
131: getLogger().error(
132: "There was a problem setting up the connection");
133: getLogger()
134: .error("Make sure that your driver is available");
135: throw new ProcessingException(
136: "Problem setting up the connection: "
137: + e.getMessage());
138: }
139: }
140:
141: public void setup(SourceResolver resolver, Map objectModel,
142: String src, Parameters par) throws ProcessingException,
143: SAXException, IOException {
144: Deprecation.logger
145: .warn("The XMLDBCollectionGenerator is deprecated. Use the XML:DB pseudo protocol instead");
146: super .setup(resolver, objectModel, src, par);
147: }
148:
149: /**
150: * The component isn't cached (yet)
151: */
152: public SourceValidity getValidity() {
153: return null;
154: }
155:
156: /**
157: * The component isn't cached (yet)
158: */
159: public java.io.Serializable getKey() {
160: return null;
161: }
162:
163: /**
164: * Parse the requested URI, connect to the XML:DB database
165: * and fetch the requested resource.
166: *
167: * @exception ProcessingException something unexpected happened with the DB
168: */
169: public void generate() throws IOException, SAXException,
170: ProcessingException {
171: //String col = "/";
172:
173: //if (source.indexOf('/') != -1)
174: col = source;
175:
176: try {
177: collection = DatabaseManager.getCollection(base + col);
178: if (collection == null) {
179: throw new ResourceNotFoundException("Collection " + col
180: + " not found");
181: }
182:
183: collectionToSAX(collection);
184: collection.close();
185: } catch (XMLDBException xde) {
186: throw new ProcessingException("Unable to fetch content '"
187: + source + "':" + xde.getMessage());
188: } catch (NullPointerException npe) {
189: getLogger().error("The XML:DB driver raised an exception");
190: getLogger().error("probably the document was not found");
191: throw new ProcessingException(
192: "Null pointer exception while "
193: + "retrieving document : "
194: + npe.getMessage());
195: }
196: }
197:
198: /**
199: * Output SAX events listing the collection.
200: *
201: * @exception SAXException
202: */
203: public void collectionToSAX(Collection collection)
204: throws SAXException {
205:
206: String ncollections;
207: String nresources;
208: String[] resources;
209: String[] collections;
210:
211: try {
212: ncollections = Integer.toString(collection
213: .getChildCollectionCount());
214: nresources = Integer
215: .toString(collection.getResourceCount());
216:
217: attributes.clear();
218: attributes.addAttribute("", RESOURCE_COUNT_ATTR,
219: RESOURCE_COUNT_ATTR, "CDATA", nresources);
220: attributes.addAttribute("", COLLECTION_COUNT_ATTR,
221: COLLECTION_COUNT_ATTR, "CDATA", ncollections);
222:
223: collections = collection.listChildCollections();
224: resources = collection.listResources();
225:
226: this .xmlConsumer.startDocument();
227: this .xmlConsumer.startPrefixMapping(PREFIX, URI);
228:
229: this .xmlConsumer.startElement(URI, "collections",
230: "collection:collections", attributes);
231:
232: // Print child collections
233:
234: for (int i = 0; i < collections.length; i++) {
235: attributes.clear();
236: attributes.addAttribute("", "name", "name", "CDATA",
237: collections[i]);
238: this .xmlConsumer.startElement(URI, COLLECTION,
239: QCOLLECTION, attributes);
240: this .xmlConsumer
241: .endElement(URI, COLLECTION, COLLECTION);
242: }
243:
244: // Print child resources
245:
246: for (int i = 0; i < resources.length; i++) {
247: attributes.clear();
248: attributes.addAttribute("", "name", "name", "CDATA",
249: resources[i]);
250: this .xmlConsumer.startElement(URI, RESOURCE, QRESOURCE,
251: attributes);
252: this .xmlConsumer.endElement(URI, RESOURCE, RESOURCE);
253: }
254:
255: this .xmlConsumer.endElement(URI, "collections",
256: "collection:collections");
257:
258: this .xmlConsumer.endPrefixMapping(PREFIX);
259: this .xmlConsumer.endDocument();
260: } catch (XMLDBException xde) {
261: getLogger().warn(
262: "Collection listing failed: " + xde.getMessage());
263: throw new SAXException("Collection listing failed: "
264: + xde.getMessage());
265: }
266: }
267: }
|