vgritsenko    01/12/20 19:29:56

  Modified:    src/org/apache/cocoon/components/source XMLDBSource.java
               src/org/apache/cocoon/generation xmldb.sitemap
               webapp   cocoon.xconf sitemap.xmap
               .        changes.xml
  Added:       lib      xmldb.jar
  Log:
  - Enable XML:DB support by default: add xmldb.jar from dbXML1.0b4.
  - Add XPath query capability to XML:DB pseudo protocol.
  - Override getLastModified: XML:DB is not (yet?) cacheable
  - Fix NPE in resourceToSAX
  - Add default configuration to XML:DB generators. Will work out-of-the-box with
  dbXML on localhost.
  - Add XML:DB protocol and generators test pipelines (TODO: examples)
  
  Revision  Changes    Path
  1.1                  xml-cocoon2/lib/xmldb.jar
  
        <<Binary file>>
  
  
  1.2       +224 -157  
xml-cocoon2/src/org/apache/cocoon/components/source/XMLDBSource.java
  
  Index: XMLDBSource.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/org/apache/cocoon/components/source/XMLDBSource.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLDBSource.java  2001/12/09 17:05:22     1.1
  +++ XMLDBSource.java  2001/12/21 03:29:56     1.2
  @@ -1,4 +1,3 @@
  -
   /*****************************************************************************
    * Copyright (C) The Apache Software Foundation. All rights reserved.        *
    * ------------------------------------------------------------------------- *
  @@ -13,6 +12,7 @@
   import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.ResourceNotFoundException;
  +import org.apache.cocoon.xml.IncludeXMLConsumer;
   import org.apache.cocoon.environment.Environment;
   import org.apache.cocoon.environment.Source;
   import org.apache.cocoon.environment.ModifiableSource;
  @@ -20,14 +20,17 @@
   import org.apache.cocoon.sitemap.SitemapComponentSelector;
   import org.apache.log.Logger;
   
  -import org.xmldb.api.DatabaseManager;   
  +import org.xmldb.api.DatabaseManager;
   import org.xmldb.api.base.Collection;   
   import org.xmldb.api.base.Database;   
   import org.xmldb.api.base.ErrorCodes;   
   import org.xmldb.api.base.Resource;   
   import org.xmldb.api.base.Service;   
  -import org.xmldb.api.base.XMLDBException;   
  -import org.xmldb.api.modules.XMLResource; 
  +import org.xmldb.api.base.XMLDBException;
  +import org.xmldb.api.base.ResourceSet;
  +import org.xmldb.api.base.ResourceIterator;
  +import org.xmldb.api.modules.XMLResource;
  +import org.xmldb.api.modules.XPathQueryService;
   
   import org.xml.sax.InputSource;
   import org.xml.sax.ContentHandler;
  @@ -46,10 +49,9 @@
    * content from an XML:DB enabled XML database.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Gianugo Rabellino</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Vadim Gritsenko</a>
    */
  -
  -public class XMLDBSource
  -  extends AbstractSAXSource {
  +public class XMLDBSource extends AbstractSAXSource {
   
       /** The Database instance */
       protected Database database;
  @@ -70,19 +72,41 @@
       protected String systemId;
   
       /** Static Strings used for XML Collection representation */
  -    
  +
       protected static final String URI = "http://apache.org/cocoon/xmldb/1.0";;
  +    // FIXME (VG): Should not be this more generic? Say, "xmldb"?
       protected static final String PREFIX = "collection";
  +
  +    /** Root element &lt;collections&gt; */
  +    protected static final String COLLECTIONS  = "collections";
  +    protected static final String QCOLLECTIONS  = PREFIX + ":" + COLLECTIONS;
       protected static final String RESOURCE_COUNT_ATTR = "resources";
       protected static final String COLLECTION_COUNT_ATTR  = "collections";
  +//    protected static final String COLLECTION_BASE_ATTR  = "base";
  +
  +    /** Element &lt;collection&gt; */
       protected static final String COLLECTION  = "collection";
  -    protected static final String QCOLLECTION  = PREFIX + ":collection";
  +    protected static final String QCOLLECTION  = PREFIX + ":" + COLLECTION;
  +
  +    /** Element &lt;resource&gt; */
       protected static final String RESOURCE  = "resource";
  -    protected static final String QRESOURCE  = PREFIX + ":resource";
  +    protected static final String QRESOURCE  = PREFIX + ":" + RESOURCE;
       protected static final String NAME_ATTR  = "name";
  -    protected static final String CDATA  = "CDATA";
   
  +    /** Root element &lt;results&gt; */
  +    protected static final String RESULTSET = "results";
  +    protected static final String QRESULTSET = PREFIX + ":" + RESULTSET;
  +    protected static final String QUERY_ATTR = "query";
  +    protected static final String RESULTS_COUNT_ATTR = "resources";
  +
  +    /** Element &lt;result&gt; */
  +    protected static final String RESULT = "result";
  +    protected static final String QRESULT = PREFIX + ":" + RESULT;
  +    protected static final String RESULT_DOCID_ATTR = "docid";
  +    protected static final String RESULT_ID_ATTR = "id";
   
  +    protected static final String CDATA  = "CDATA";
  +
       /**
        * The constructor.
        * 
  @@ -90,61 +114,61 @@
        * @param url the URL being queried.
        * @param driver the XML:DB driver class name.
        */
  -    
  -    public XMLDBSource(Environment environment, 
  +
  +    public XMLDBSource(Environment environment,
                          ComponentManager manager,
                          Logger logger,
                          String driver,
                          String url) {
   
  -      super(environment, manager, logger);                 
  -      int start;
  +        super(environment, manager, logger);
  +        int start;
   
  -      this.driver = driver;
  +        this.driver = driver;
   
  -      if ((start = url.indexOf('?')) != -1) {
  -        this.url = url.substring(0, start);
  -        this.urlParameters = url.substring(start+1);
  -      } else {
  -        this.url = url;
  -      }
  +        if ((start = url.indexOf('?')) != -1) {
  +            this.url = url.substring(0, start);
  +            this.urlParameters = url.substring(start + 1);
  +        } else {
  +            this.url = url;
  +        }
       }
   
  -    /** 
  +    /**
        * Initialize the XML:DB connection.
        *
        */
   
       public void connect() throws Exception {
  -
  -      if (log.isDebugEnabled()) {
  -        this.log.debug("Initializing XML:DB connection");
  -      }
   
  -      try {
  -
  -        Class c = Class.forName(driver);
  -        database = (Database)c.newInstance();
  -        DatabaseManager.registerDatabase(database);
  +        if (log.isDebugEnabled()) {
  +            this.log.debug("Initializing XML:DB connection");
  +        }
   
  -      } catch (XMLDBException xde) {
  +        try {
   
  -        this.log.error("Unable to connect to the XML:DB database");
  -        throw new ProcessingException("Unable to connect to the XMLDB database" 
  -          + xde.getMessage());
  +            Class c = Class.forName(driver);
  +            database = (Database)c.newInstance();
  +            DatabaseManager.registerDatabase(database);
  +
  +        } catch (XMLDBException xde) {
  +
  +            this.log.error("Unable to connect to the XML:DB database");
  +            throw new ProcessingException("Unable to connect to the XMLDB database"
  +                    + xde.getMessage());
   
  -      } catch (Exception e) {
  +        } catch (Exception e) {
   
  -        this.log.error("There was a problem setting up the connection");
  -        this.log.error("Make sure that your driver is available");
  -        throw new ProcessingException("Problem setting up the connection: " 
  -          + e.getMessage(), e);
  +            this.log.error("There was a problem setting up the connection");
  +            this.log.error("Make sure that your driver is available");
  +            throw new ProcessingException("Problem setting up the connection: "
  +                    + e.getMessage(), e);
   
  -      } 
  +        }
   
  -      this.connected = true;
  +        this.connected = true;
       }
  - 
  +
   
       /**
        * Stream SAX events to a given ContentHandler. If the requested
  @@ -152,143 +176,186 @@
        *
        */
   
  -    public void toSAX(ContentHandler handler) 
  -      throws SAXException, ProcessingException {
  +    public void toSAX(ContentHandler handler) throws SAXException, 
ProcessingException {
   
  -      if (!connected) {
  -        try {
  -        this.connect();
  -        } catch (Exception e) {
  -          this.log.error("Unable to connect to the database", e);  
  -          throw new ProcessingException("Unable to connect to the database: " +
  -            e.getMessage());
  +        if (!connected) {
  +            try {
  +                this.connect();
  +            } catch (Exception e) {
  +                this.log.error("Unable to connect to the database", e);
  +                throw new ProcessingException("Unable to connect to the database: " 
+
  +                        e.getMessage());
  +            }
           }
  -      }
  -      if (url.endsWith("/")) 
  -        this.collectionToSAX(handler);
  -      else
  -        this.resourceToSAX(handler);
  -
  -    }  
  -
  -    private void resourceToSAX(ContentHandler handler) 
  -      throws SAXException, ProcessingException {
  -
  -      Collection collection;
  -      XMLResource xmlResource;
  -      
  -      String col = url.substring(0, url.lastIndexOf('/'));        
  -      String res = url.substring(url.lastIndexOf('/') + 1);
  +        if (url.endsWith("/"))
  +            this.collectionToSAX(handler);
  +        else
  +            this.resourceToSAX(handler);
   
  -      try {
  -        collection = DatabaseManager.getCollection(col);
  -        xmlResource = (XMLResource) collection.getResource(res);
  -
  -        if (xmlResource == null)
  -          throw new ResourceNotFoundException("Document " + col + "/" + res + 
  -            " not found");
  -
  -        xmlResource.getContentAsSAX(handler);
  +    }
   
  -        collection.close();
  +    private void resourceToSAX(ContentHandler handler) throws SAXException, 
ProcessingException {
   
  -      } catch (XMLDBException xde) {
  +        Collection collection;
  +        XMLResource xmlResource;
   
  -        throw new ProcessingException("Unable to fetch content: " +
  -          xde.getMessage(), xde);
  +        String col = url.substring(0, url.lastIndexOf('/'));
  +        String res = url.substring(url.lastIndexOf('/') + 1);
   
  -      } catch (NullPointerException npe) {
  +        try {
  +            collection = DatabaseManager.getCollection(col);
  +            if (collection == null) {
  +                throw new ResourceNotFoundException("Document " + url + " not 
found");
  +            }
  +
  +            xmlResource = (XMLResource) collection.getResource(res);
  +            if (xmlResource == null) {
  +                throw new ResourceNotFoundException("Document " + url + " not 
found");
  +            }
  +
  +            xmlResource.getContentAsSAX(handler);
  +            collection.close();
  +        } catch (XMLDBException xde) {
  +
  +            throw new ProcessingException("Unable to fetch content: " +
  +                    xde.getMessage(), xde);
   
  -          this.log.error("The XML:DB driver raised an exception");
  -          this.log.error("probably the document was not found");
  +        } catch (NullPointerException npe) {
   
  -          throw new ProcessingException("Null pointer exception while " + 
  -            "retrieving document : " + npe.getMessage());
  -      } 
  +            this.log.error("The XML:DB driver raised an exception");
  +            this.log.error("probably the document was not found");
   
  +            throw new ProcessingException("Null pointer exception while " +
  +                    "retrieving document : " + npe.getMessage());
  +        }
       }
   
  -    private void collectionToSAX(ContentHandler handler) 
  -      throws SAXException, ProcessingException {
  +    private void collectionToSAX(ContentHandler handler) throws SAXException, 
ProcessingException {
   
  -      Collection collection;
  -      AttributesImpl attributes = new AttributesImpl();
  -      int queryStart;
  -
  -      try {
  -        collection = DatabaseManager.getCollection(url);
  -
  -        if (collection == null) {
  -          throw new ResourceNotFoundException("Collection " + url + 
  -            " not found");
  -        }
  +        AttributesImpl attributes = new AttributesImpl();
   
  -        String ncollections;
  -        String nresources;
  -        String[] resources;
  -        String[] collections;
  -
  -        ncollections = Integer.toString(collection.getChildCollectionCount());
  -        nresources = Integer.toString(collection.getResourceCount());
  -
  -        attributes.clear();
  -        attributes.addAttribute("", RESOURCE_COUNT_ATTR,
  -          RESOURCE_COUNT_ATTR, "CDATA", nresources);
  -        attributes.addAttribute("", COLLECTION_COUNT_ATTR,
  -          COLLECTION_COUNT_ATTR, "CDATA", ncollections);
  -
  -        collections = collection.listChildCollections();
  -        resources = collection.listResources();
  -
  -        handler.startDocument();
  -        handler.startPrefixMapping(PREFIX, URI);
  -
  -        handler.startElement(URI, "collections", 
  -          "collection:collections", attributes);
  -
  -        // Print child collections
  -
  -        for (int i = 0; i < collections.length; i++) {
  -          attributes.clear();
  -          attributes.addAttribute("", NAME_ATTR, NAME_ATTR, CDATA, collections[i]);
  -          handler.startElement(URI, COLLECTION, 
  -            QCOLLECTION, attributes);
  -          handler.endElement(URI, COLLECTION, COLLECTION);
  +        try {
  +            Collection collection = DatabaseManager.getCollection(url);
  +            if (collection == null) {
  +                throw new ResourceNotFoundException("Collection " + url +
  +                        " not found");
  +            }
  +
  +            if (urlParameters != null) {
  +                queryToSAX(handler, collection);
  +                return;
  +            }
  +
  +            final String ncollections = 
Integer.toString(collection.getChildCollectionCount());
  +            final String nresources = 
Integer.toString(collection.getResourceCount());
  +            attributes.addAttribute("", RESOURCE_COUNT_ATTR,
  +                    RESOURCE_COUNT_ATTR, "CDATA", nresources);
  +            attributes.addAttribute("", COLLECTION_COUNT_ATTR,
  +                    COLLECTION_COUNT_ATTR, "CDATA", ncollections);
  +//            attributes.addAttribute("", COLLECTION_BASE_ATTR,
  +//                    COLLECTION_BASE_ATTR, "CDATA", url);
  +
  +            handler.startDocument();
  +            handler.startPrefixMapping(PREFIX, URI);
  +            handler.startElement(URI, COLLECTIONS, QCOLLECTIONS, attributes);
  +
  +            // Print child collections
  +            String[] collections = collection.listChildCollections();
  +            for (int i = 0; i < collections.length; i++) {
  +                attributes.clear();
  +                attributes.addAttribute("", NAME_ATTR, NAME_ATTR, CDATA, 
collections[i]);
  +                handler.startElement(URI, COLLECTION,
  +                        QCOLLECTION, attributes);
  +                handler.endElement(URI, COLLECTION, COLLECTION);
  +            }
  +
  +            // Print child resources
  +            String[] resources = collection.listResources();
  +            for (int i = 0; i < resources.length; i++) {
  +                attributes.clear();
  +                attributes.addAttribute("", NAME_ATTR, NAME_ATTR, CDATA, 
resources[i]);
  +                handler.startElement(URI, RESOURCE,
  +                        QRESOURCE, attributes);
  +                handler.endElement(URI, RESOURCE, RESOURCE);
  +            }
  +
  +            handler.endElement(URI, COLLECTIONS, QCOLLECTIONS);
  +            handler.endPrefixMapping(PREFIX);
  +            handler.endDocument();
  +        } catch (XMLDBException xde) {
  +            this.log.error("Collection listing failed. " + xde.getMessage());
  +            throw new SAXException("Collection listing failed. " + 
xde.getMessage());
           }
  +    }
   
  -        // Print child resources
  +    public void queryToSAX(ContentHandler handler, Collection collection) throws 
SAXException {
   
  -        for (int i = 0; i < resources.length; i++) {
  -          attributes.clear();
  -          attributes.addAttribute("", NAME_ATTR, NAME_ATTR, CDATA, resources[i]);
  -          handler.startElement(URI, RESOURCE, 
  -            QRESOURCE, attributes);
  -          handler.endElement(URI, RESOURCE, RESOURCE);
  -        }
  +        AttributesImpl attributes = new AttributesImpl();
   
  -        handler.endElement(URI, "collections", 
  -          "collection:collections");
  -          
  -        handler.endPrefixMapping(PREFIX);
  -        handler.endDocument();
  -          
  -      } catch (XMLDBException xde) {
  -        this.log.error("Collection listing failed" + xde.getMessage());
  -        throw new SAXException("Collection listing failed" + xde.getMessage());
  -      }
  -      
  +        try {
  +            XPathQueryService service =
  +                (XPathQueryService) collection.getService("XPathQueryService", 
"1.0");
  +            ResourceSet resultSet = service.query(urlParameters);
  +
  +            attributes.addAttribute("", QUERY_ATTR, QUERY_ATTR, "CDATA", 
urlParameters);
  +            attributes.addAttribute("", RESULTS_COUNT_ATTR,
  +                    RESULTS_COUNT_ATTR, "CDATA", 
Long.toString(resultSet.getSize()));
  +
  +            handler.startDocument();
  +            handler.startPrefixMapping(PREFIX, URI);
  +            handler.startElement(URI, RESULTSET, QRESULTSET, attributes);
  +
  +            IncludeXMLConsumer includeHandler = new IncludeXMLConsumer(handler);
  +
  +            // Print search results
  +            ResourceIterator results = resultSet.getIterator();
  +            while (results.hasMoreResources()) {
  +                XMLResource resource = (XMLResource)results.nextResource();
  +
  +                final String id = resource.getId();
  +                final String documentId = resource.getDocumentId();
  +
  +                attributes.clear();
  +                if (id != null) {
  +                    attributes.addAttribute("", RESULT_ID_ATTR, RESULT_ID_ATTR,
  +                        CDATA, id);
  +                }
  +                if (documentId != null) {
  +                    attributes.addAttribute("", RESULT_DOCID_ATTR, 
RESULT_DOCID_ATTR,
  +                        CDATA, documentId);
  +                }
  +                handler.startElement(URI, RESULT, QRESULT, attributes);
  +
  +                resource.getContentAsSAX(includeHandler);
  +
  +                handler.endElement(URI, RESULT, RESULT);
  +            }
  +
  +            handler.endElement(URI, RESULTSET, QRESULTSET);
  +            handler.endPrefixMapping(PREFIX);
  +            handler.endDocument();
  +        } catch (XMLDBException xde) {
  +            this.log.error("Collection query failed. " + xde.getMessage());
  +            throw new SAXException("Collection query failed. " + xde.getMessage());
  +        }
       }
   
       public void recycle() {
  -      this.driver = null;
  -      this.log = null;
  -      this.manager = null;
  -      this.url = null;
  -      this.urlParameters = null;
  +        this.driver = null;
  +        this.log = null;
  +        this.manager = null;
  +        this.url = null;
  +        this.urlParameters = null;
       }
   
       public String getSystemId() {
  -      return url;
  +        return url;
       }
   
  +    /**
  +     * Modification date is not known.
  +     */
  +    public long getLastModified() {
  +        return 0;
  +    }
   }
  
  
  
  1.2       +2 -2      xml-cocoon2/src/org/apache/cocoon/generation/xmldb.sitemap
  
  Index: xmldb.sitemap
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/generation/xmldb.sitemap,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- xmldb.sitemap     2001/11/23 09:11:51     1.1
  +++ xmldb.sitemap     2001/12/21 03:29:56     1.2
  @@ -1,2 +1,2 @@
  
-category:generators|componentName:xmldb|componentClass:org.apache.cocoon.generation.XMLDBGenerator
  
-category:generators|componentName:xmldbcollection|componentClass:org.apache.cocoon.generation.XMLDBCollectionGenerator
  
+category:generators|componentName:xmldb|componentClass:org.apache.cocoon.generation.XMLDBGenerator|configuration:<driver>org.dbxml.client.xmldb.DatabaseImpl</driver><base>xmldb:dbxml:///db/</base>
  
+category:generators|componentName:xmldbcollection|componentClass:org.apache.cocoon.generation.XMLDBCollectionGenerator|configuration:<driver>org.dbxml.client.xmldb.DatabaseImpl</driver><base>xmldb:dbxml:///db/</base>
  
  
  
  1.46      +6 -0      xml-cocoon2/webapp/cocoon.xconf
  
  Index: cocoon.xconf
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/webapp/cocoon.xconf,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- cocoon.xconf      2001/12/20 15:15:08     1.45
  +++ cocoon.xconf      2001/12/21 03:29:56     1.46
  @@ -150,6 +150,12 @@
       sitemap components.
     -->
     <source-handler>
  +    <!-- xmldb pseudo protocol -->
  +    <protocol name="xmldb" 
class="org.apache.cocoon.components.source.XMLDBSourceFactory">
  +      <!-- dbXML driver -->
  +      <driver type="dbxml" class="org.dbxml.client.xmldb.DatabaseImpl"/>
  +      <!-- Add here other XML:DB compliant databases drivers -->
  +    </protocol>
     </source-handler>
   
     <!-- Program Generator:
  
  
  
  1.71      +21 -0     xml-cocoon2/webapp/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/webapp/sitemap.xmap,v
  retrieving revision 1.70
  retrieving revision 1.71
  diff -u -r1.70 -r1.71
  --- sitemap.xmap      2001/12/20 09:37:31     1.70
  +++ sitemap.xmap      2001/12/21 03:29:56     1.71
  @@ -1027,6 +1027,27 @@
       <map:serialize/>
      </map:match>
   
  +   <!-- ========================= XML:DB ================================ -->
  +   <map:match pattern="xmldb/**">
  +    <map:match type="request" pattern="xpath">
  +     <map:generate src="xmldb:dbxml://localhost:4080/{../1}?{1}"/>
  +     <map:serialize type="xml"/>
  +    </map:match>
  +
  +    <map:generate src="xmldb:dbxml://localhost:4080/{1}"/>
  +    <map:serialize type="xml"/>
  +   </map:match>
  +
  +   <map:match pattern="xmldb-generator/db/**/">
  +    <map:generate type="xmldbcollection" src="/{1}"/>
  +    <map:serialize type="xml"/>
  +   </map:match>
  +
  +   <map:match pattern="xmldb-generator/db/**">
  +    <map:generate type="xmldb" src="/{1}"/>
  +    <map:serialize type="xml"/>
  +   </map:match>
  +
      <!-- ========================= Server ================================ -->
      <map:match pattern="request">
       <map:generate type="request"/>
  
  
  
  1.62      +9 -1      xml-cocoon2/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/changes.xml,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- changes.xml       2001/12/19 21:24:45     1.61
  +++ changes.xml       2001/12/21 03:29:56     1.62
  @@ -4,7 +4,7 @@
   
   <!--
     History of Cocoon changes
  -  $Id: changes.xml,v 1.61 2001/12/19 21:24:45 vgritsenko Exp $
  +  $Id: changes.xml,v 1.62 2001/12/21 03:29:56 vgritsenko Exp $
   -->
   
   <changes title="History of Changes">
  @@ -29,6 +29,14 @@
    </devs>
   
    <release version="@version@" date="@date@">
  +  <action dev="VG" type="add">
  +    Added ability to use XPath expressions to query XML:DB collections using
  +    XML:DB pseudo protocol. URL should be in form:
  +    xmldb:dbxml://host:port/db/collection/?/xpath
  +  </action>
  +  <action dev="VG" type="add">
  +    Enabled XML:DB support (generators and pseudo protocol) by default.
  +  </action>
     <action dev="VG" type="fix" fixes-bug="4239">
       JSPEngine returns result in UTF-8 charset.
     </action>
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to