« Return to Thread: XMLDBException on LocalXMLResource.getContentAsDOM()

XMLDBException on LocalXMLResource.getContentAsDOM()

by Michael-526 :: Rate this Message:

Reply to Author | View in Thread

Hello,

I am attempting to convert an application that has been using a server deployment of eXist to embedding eXist right in the application. I have been able to configure the program to start and initialize the embedded database. I can also query the embedded database, however, when parsing the results of a query I am having some difficulty.

When I perform the following actions:

    ResourceSet results = query(RESNAME, query);
    XMLResource resultBlob = (XMLResource) results.getMembersAsResource();
    Node node = resultBlob.getContentAsDOM();

I receive an XMLDBException with error INVALID_RESOURCE (301) thrown from within resultBlob.getContentAsDOM(). This did not cause any exceptions to be thrown when the database was running as a server and not embedded. It appears the LocalXMLResource implementation of getContentAsDOM() differs from the RemoteXMLResource in such a way that the local version causes this exception.

The LocalXMLResource implementation of getContentAsDOM() attempts to retrieve the DOM Document by calling
    document = parent.getCollection().getDocumentWithLock(broker, docId, lock);
Which fails to retrieve a document since the docID is blank.

The RemoteXMLResource implementation of getContentAsDOM() creates and builds the document from scratch using the string field "content". This properly returns the DOM Document without error.

I suppose a solution around this would be to simply call getContent() and then build the DOM Document from the returned string. Though, I am not really sure if I am simply performing an invalid action, or if there is something wrong with my setup, or if this really should just simply work but is not. Any suggestions/info/advise/solutions would be greatly appreciated.


Here is a simplified sample of what is occurring in my application. This is a simple example of the issue which reproduces the same issue that I am seeing in my application. I created this example to best show the problem. I have also hosted the source of this application as a complete eclipse workspace at http://mtbin.com/source/existExample.zip if anyone would like to attempt running this example on their system.


package main;

import java.util.Properties;

import org.exist.xmldb.DatabaseInstanceManager;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XPathQueryService;

public class DBExample
{
    public static final String DRIVER_NAME = "org.exist.xmldb.DatabaseImpl";
   
    private static String DBPARAM_BASEURI = "exist://";
   
    public static final String USERNAME = "admin";
   
    public static final String PASSWORD = "admin";
   
    // the resource name for system preferences
    private static final String RESNAME_SYSTEM_PREFERENCES_DATABASE =
        "systempreferences.xml";
   
    // the root element of the resource
    private static final String ELEMENTNAME_ROOT = "systempreferences";
   
    // The element name of any preference in the database
    private static final String ELEMENTNAME_SYSTEM_PREFERENCE = "preference";
   
    private Collection rootCollection;
   
    private XPathQueryService queryService;
   
    public void init(String id) throws Exception
    {
        Database database = registerDatabaseByDriver(DRIVER_NAME);
       
        Collection pluginRootCollection =
            database
                .getCollection(DBPARAM_BASEURI + "/db/", USERNAME, PASSWORD);
       
        Collection localCollection =
            pluginRootCollection.getChildCollection(id);
       
        if (localCollection == null)
        {
            CollectionManagementService collectionManagementService =
                (CollectionManagementService) pluginRootCollection.getService(
                    "CollectionManagementService",
                    "1.0");
           
            if (collectionManagementService == null)
            {
                // We need this exception in two places so it must be created
                // ahead of the throw statement.
                NullPointerException ex =
                    new NullPointerException(
                        "collectionManagementService must be supported.");
               
                // Crash time (not really, the davadoc DOES warn clients this
                // may happen)
                throw ex;
            }
           
            // Create the collection
            localCollection = collectionManagementService.createCollection(id);
           
        }
       
        this.rootCollection = localCollection;
       
        this.queryService =
            (XPathQueryService) rootCollection.getService(
                "XPathQueryService",
                "1.0");
    }
   
    public Database registerDatabaseByDriver(String driver)
        throws ClassNotFoundException,
            InstantiationException,
            IllegalAccessException,
            XMLDBException
    {
        Database database = (Database) Class.forName(driver).newInstance();
        database.setProperty("create-database", "true");
        System.setProperty("exist.home", System.getProperty("user.dir"));
       
        DatabaseManager.registerDatabase(database);
       
        return database;
    }
   
    public void deregisterDatabase() throws XMLDBException
    {
        DatabaseInstanceManager manager =
            (DatabaseInstanceManager) rootCollection.getService(
                "DatabaseInstanceManager",
                "1.0");
        manager.shutdown();
    }
   
    public ResourceSet query(String context, String query)
        throws XMLDBException
    {
        // Check if this query is against the collection or a specific resource
        if (context == null || context.equals(""))
        {
            return queryService.query(query);
        }
       
        // Must be a specific resource
        return queryService.queryResource(context, query);
    }
   
    public Properties getPreferences(String group) throws XMLDBException
    {
        // For making the query
        String query;
        ResourceSet results;
       
        // For parsing the results
        XMLResource resultBlob;
        Node node;
        Document document;
        NodeList nodeList;
        Element element;
       
        // To store the results
        Properties preferences = new Properties();
       
        /*
         * /systempreferences/preference[@group='NameHere']
         */
        // Build the query
        query =
            String.format(
                "/%s/%s[@%s='%s']",
                ELEMENTNAME_ROOT,
                ELEMENTNAME_SYSTEM_PREFERENCE,
                "group",
                group);
       
        // Make the query
        results = query(RESNAME_SYSTEM_PREFERENCES_DATABASE, query);
       
        if (results.getSize() == 0)
        {
            // No results
            return null;
        }
       
        // Parse out the results
        resultBlob = (XMLResource) results.getMembersAsResource();
       
        // Display the results to console
        System.out.println(resultBlob.getContent());
       
        // get content as DOM for parsing
        // !!!!!!!!!! an XMLDBException is being thrown here !!!!!!!!!!
        node = resultBlob.getContentAsDOM();
        if (node.getOwnerDocument() == null)
        {
            document = (Document) node;
        }
        else
        {
            document = node.getOwnerDocument();
        }
       
        // create a list of all the preference nodes
        nodeList = document.getElementsByTagName(ELEMENTNAME_SYSTEM_PREFERENCE);
       
        // parse the list into a properties map
        for (int index = 0; index < nodeList.getLength(); index++)
        {
            // grab an element in the list
            element = (Element) nodeList.item(index);
           
            // add "value" to the properties map with the key "name"
            preferences.put(element.getAttribute("name"), element
                .getAttribute("value"));
           
        }
       
        return preferences;
    }
   
    public static void main(String args[]) throws Exception
    {
        DBExample dbExample = null;
        try
        {
            dbExample = new DBExample();
            dbExample.init("preferences");
            dbExample.getPreferences("group1");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (dbExample != null)
                dbExample.deregisterDatabase();
        }
    }
}

The output of this program is:

log4j:WARN No appenders could be found for logger (org.exist.util.ConfigurationHelper).
log4j:WARN Please initialize the log4j system properly.
<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist" hitCount="4">
    <preference group="group1" name="preference1" value="50"/>
    <preference group="group1" name="preference2" value="foo"/>
    <preference group="group1" name="preference3" value="200"/>
    <preference group="group1" name="preference4" value="true"/>
</exist:result>
org.xmldb.api.base.XMLDBException:
        at org.exist.xmldb.LocalXMLResource.getDocument(LocalXMLResource.java:496)
        at org.exist.xmldb.LocalXMLResource.getContentAsDOM(LocalXMLResource.java:210)
        at main.DBExample.getPreferences(DBExample.java:170)
        at main.DBExample.main(DBExample.java:205)



Thank you,
Michael


------------------------------------------------------------------------------
_______________________________________________
Exist-open mailing list
Exist-open@...
https://lists.sourceforge.net/lists/listinfo/exist-open

 « Return to Thread: XMLDBException on LocalXMLResource.getContentAsDOM()