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

Re: XMLDBException on LocalXMLResource.getContentAsDOM()

by Michael-526 :: Rate this Message:

Reply to Author | View in Thread

Thank you for spending the time to look into this. I am sorry that the
sample was too complicated and messy. Next time I have an issue I will
spend more time breaking it down to as little code as possible.

The solution you have suggested offers a good work-around for the
problem. I have also created a work-around solution myself which
involved building the DOM Node by parsing the result content string. In
this solution I basically replicated what
RemoteXMLResource.getContentAsDOM() does.

I suppose at this point, it appears to me that my issue is due to how
eXist implements the XML:DB API. I understand that it was probably not
expected that a developer like myself parse the results of a query in
this manner. But I am still not clear if what I am attempting to do is
an illegal action according to the API spec. I guess in the end, the
fact that there are several ways to parse the results differently to
achieve the same result is really all the solution I require. But I did
still feel it was necessary to point out the unexpected behaviour I was
seeing while using eXist.

Again, thank you for your time on this one Adam.


Michael


Adam Retter wrote:

> I have spent some time and looked over this code and to be honest it
> was a mess and a pain! This code is far much more than what you need
> to reproduce the problem. For a reproducible test case for this, I
> would have liked to have seen a single method with the absolute
> minimum required to cause the issue.
>
> Anyways, I have run this code against eXist trunk and can confirm that
> there is no problem with eXist. I think the issue is in how you are
> retrieving and parsing the output from eXist.
>
> If you look at the code below the comment   "// Parse out the results"
>  in the method "getPreferences", as you have said this causes an
> exception. Replacing this code with something similar to the following
> should work for you - I believe that it does here.
>
> The results reading code was taken from examples freely available in
> the eXist documentation on the website.
>
>
> // Parse out the results
>        ResourceIterator i = results.getIterator();
>        while(i.hasMoreResources())
>        {
>             Resource r = i.nextResource();
>             if(r.getResourceType().equals("XMLResource"))
>             {
>                 node = ((XMLResource)r).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"));
>
>                }
>             }
>         }
>
>
>
>  
>> 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
>>
>>    
>
>
>
>  


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

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