Running Xindice with Cocoon 2

by Perry Molendijk

Note:
The problems seem to be fixed in the current CVS version of Cocoon. So, if you're using a version newer than 2.0.1, it should be working out of the box. (note by Andreas Hartmann)

Getting Started

Getting Xindice to run with Cocoon 2 was a bit of a confusing experience, so I thougth that my notes may be usefull to other users.

Part of the confusion was the two different ways you could accomplish the task, one of which is to become deprecated shortly.

The setup described below uses the source-handler and gets rid of the parts that are used by the generator.

The environment: Win2K, Tomcat 4.0.1, Cocoon 2.0.1 and Xindice 1.0rc1.

Fixme (Perry Molendijk):
Please, correct me if I'm wrong about getting rid of the generator bits and the source-handler comments RE C2.0.
Fixme (Perry Molendijk):
Details about the reasons I don't know. Someone can add them maybe.

Cocoon 2.0.1

See "Installing" section for details

Note:
The XMLDB source-handler is new to C2.0.1 so you'll need to get this or a later distribution.

Xindice

Download and install the latest version of Xindice from http://www.dbxml.org. Version at time of writing xml-xindice-1.0rc1.zip

Create the addressbook example database.

Installation instructions are included with the distribution and available on http://www.dbxml.org.

Assumptions

In the remainder it's assumed that:

  • Xindice is running on http://localhost:4080 and
  • The /db/addressbook is created.

Sitemap Modifcations

We need to make some changes to the sitemap.xmap mainly to avoid confusion.

Getting Rid Of The Old Stuff

Because the generator will be deprecated shortly we'll comment out those parts (or delete it if you're keen). Look for the following code snippet in sitemap.xmap:

<map:generator name="xmldb"
   src="org.apache.cocoon.generation.XMLDBGenerator"
   logger="sitemap.generator.xmldb">
  <driver>org.dbxml.client.xmldb.DatabaseImpl</driver>
  <base>xmldb:dbxml:///db/</base>
</map:generator>
<map:generator name="xmldbcollection"
   src="org.apache.cocoon.generation.XMLDBCollectionGenerator"
   logger="sitemap.generator.xmldbcollection">
  <driver>org.dbxml.client.xmldb.DatabaseImpl</driver>
  <base>xmldb:dbxml:///db/</base>
</map:generator>

and

  <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>

Changes To Match Tag

We're now left with one match tag to do with XMLDB and it needs some modification. Look for the following code snippet in sitemap.xmap:

  <map:match pattern="xmldb/**">
    <map:match type="request-parameter" 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>

Change the part that reads xmldb:dbxml://localhost:4080/... to xmldb:xindice://localhost:4080/db/... so that you end up with:

  <map:match pattern="xmldb/**">
    <map:match type="request-parameter" pattern="xpath">
      <map:generate
        src="xmldb:xindice://localhost:4080/db/{../1}#{1}"/>
      <map:serialize type="xml"/>
    </map:match>
    <map:generate src="xmldb:xindice://localhost:4080/db/{1}"/>
    <map:serialize type="xml"/>
  </map:match>

The /db after xmldb:xindice://localhost:4080/ was the only way I got rid of an error.

When requesting: http://localhost:8080/cocoon/xmldb/addressbook/?xpath=//person Xindice looked for a file %XINDICE_HOME/docs/addressbook_bootstrap.ior which doesn't exist. By adding /db to the URI the problem was solved.

Config Modifications

Changes to cocoon.conf are minor. Look for:

  <source-handler logger="core.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>

and <driver type="dbxml" class="org.dbxml.client.xmldb.DatabaseImpl"/> to read <driver type="xindice" class="org.apache.xindice.client.xmldb.DatabaseImpl"/> so you end up with:

  <source-handler logger="core.source-handler">
    <!-- xmldb pseudo protocol -->
    <protocol name="xmldb"
      class="org.apache.cocoon.components.source.XMLDBSourceFactory">
      <!-- Xindice driver -->
      <driver type="xindice"
        class="org.apache.xindice.client.xmldb.DatabaseImpl"/>
      <!-- Add here other XML:DB compliant databases drivers -->
    </protocol>
  </source-handler>

Finish Up

  • Copy xindice.jar from %XINDICE_HOME/java/lib to cocoon\WEB-INF\lib
  • Start Xindice, if it isn't running.
  • Start Tomcat

Try: http://localhost:8080/cocoon/xmldb/addressbook/ and you end up with:

  <?xml version="1.0" encoding="UTF-8"?>
  <collection:collections resources="3" collections="0"
       xmlns:collection="http://apache.org/cocoon/xmldb/1.0">
    <collection:resource name="0100007f1f9fdabb000000ec2b2a4110"/>
    <collection:resource name="0100007f1f9fdabb000000ec2b30c130"/>
    <collection:resource name="0100007f1f9fdabb000000ec2b8cabd3"/>
  </collection:collections>

Try: http://localhost:8080/cocoon/xmldb/addressbook/?xpath=//person[contains(fname,'Donald')] (replace 'Donald' with something that matches an entry in your DB) and you end up with:

<?xml version="1.0" encoding="UTF-8"?>
<collection:results query="//person[contains(fname,'Donald')]"
  resources="1" xmlns:collection="http://apache.org/cocoon/xmldb/1.0">
  <collection:result docid="0100007f1f9fdabb000000ec2b8cabd3">
    <person xmlns:src="http://xml.apache.org/xindice/Query"
      src:col="/db/addressbook"
      src:key="0100007f1f9fdabb000000ec2b8cabd3">
      <fname>Donald</fname>
      <lname>Duck</lname>
      <phone type="work">9876543</phone>
      <phone type="home">1234567</phone>
      <phone type="cell">040404040</phone>
      <email type="home">donald@duck.com</email>
      <email type="work">donald@disney.com</email>
      <address type="home">big pond</address>
      <address type="work">large pond</address>
    </person>
  </collection:result>
</collection:results>