package org.exist.xquery; import org.exist.storage.DBBroker; import org.exist.xmldb.XQueryService; import org.w3c.dom.Node; import org.xmldb.api.DatabaseManager; import org.xmldb.api.base.Collection; import org.xmldb.api.base.CompiledExpression; import org.xmldb.api.base.Database; import org.xmldb.api.base.ResourceSet; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.XMLResource; import junit.framework.TestCase; /** * RemoveAndReloadTest.java * * O2 IT Engineering * Zurich, Switzerland (CH) */ /** * This test provokes a parameter type error (how?). * * @author Tobias Wunden * @version 1.0 */ public class NodeTypeTest extends TestCase { /** eXist database url */ static final String eXistUrl ="xmldb:exist://"; /** eXist home directory */ static final String existHome = "C:\\Documents and Settings\\Tobias Wunden\\My Documents\\Projects\\Varia\\Test"; public static void main(String[] args) { junit.textui.TestRunner.run(NodeTypeTest.class); } /** * This test passes nodes containing xml entities to eXist and tries * to read it back in: * <ul> * <li>Register a database instance</li> * <li>Write a "live" document to the database using the XQueryService</li> * <li>Create a "work" version of it</li> * </ul> */ public final void testRemoveAndReload() { XQueryService service = setupDatabase(); // write "live" document to the database try { store(createDocument(), service, "live.xml"); } catch (Exception e) { fail("Failed to write document to database: " + e.getMessage()); } // copy content from work.xml to live.xml using XUpdate try { prepareWorkVersion(service); } catch (Exception e) { e.printStackTrace(); fail("Failed to update document in database: " + e.getMessage()); } } /** * Stores the given xml fragment into the database. * * @param xml the xml document * @param service the xquery service * @param document the document name */ private final void store(String xml, XQueryService service, String document) { StringBuffer query = new StringBuffer(); query.append("xquery version \"1.0\";"); query.append("declare namespace xdb=\"http://exist-db.org/xquery/xmldb\";"); query.append("let $isLoggedIn := xdb:login('" + eXistUrl + DBBroker.ROOT_COLLECTION + "', \"admin\", \"admin\"),"); query.append("$doc := xdb:store(\"" + eXistUrl + DBBroker.ROOT_COLLECTION + "\", $document, $data)"); query.append("return <result/>"); try { service.declareVariable("document", document); service.declareVariable("data", xml); CompiledExpression cQuery = service.compile(query.toString()); service.execute(cQuery); } catch (XMLDBException e) { fail(e.getMessage()); } } /** * Updates the given xml fragment in the database using XUpdate. * * @param service the xquery service */ private final void prepareWorkVersion(XQueryService service) { StringBuffer query = new StringBuffer(); query.append("xquery version \"1.0\";\n"); query.append("declare namespace xdb=\"http://exist-db.org/xquery/xmldb\";\n"); query.append("declare namespace f=\"urn:weblounge\";\n"); // Returns a new with a given body and a new header query.append("declare function f:create($live as node(), $target as xs:string) as node() { \n"); query.append(" <page partition=\"{$live/@partition}\" path=\"{$live/@path}\" version=\"{$target}\"> \n"); query.append(" {$live/*} \n"); query.append(" </page> \n"); query.append("}; \n"); // Function "prepare". Checks if the work version already exists. If this is not the // case, it calls the "create" function to have a new page created with the live body // but with a "work" or "$target" header. query.append("declare function f:prepare($data as node(), $target as xs:string) as xs:string? { \n"); query.append(" if (empty(xmldb:xcollection($collection)/page[@version=$target])) then \n"); query.append(" let $isLoggedIn := xdb:login(concat(\"xmldb:exist://\", $collection), 'admin', 'admin') \n"); query.append(" return xdb:store(concat(\"xmldb:exist://\", $collection), concat($target, \".xml\"), f:create($data, $target)) \n"); query.append(" else \n"); query.append(" () \n"); query.append("}; \n"); // Main clause, tries to create a work from an existing live version query.append("let $live := xmldb:xcollection($collection)/page[@version=\"live\"],\n"); query.append(" $log := util:log('DEBUG', $live),\n"); query.append(" $w := f:prepare($live, \"work\")\n"); query.append(" return\n"); query.append(" ()\n"); try { service.declareVariable("collection", DBBroker.ROOT_COLLECTION); CompiledExpression cQuery = service.compile(query.toString()); service.execute(cQuery); } catch (XMLDBException e) { fail(e.getMessage()); } } /** * Updates the given xml fragment in the database using XUpdate. * * @param service the xquery service */ private final void xupdateRemove(String doc, XQueryService service) { StringBuffer query = new StringBuffer(); query.append("xquery version \"1.0\";"); query.append("declare namespace xdb=\"http://exist-db.org/xquery/xmldb\";"); query.append("let $isLoggedIn := xdb:login('" + eXistUrl + DBBroker.ROOT_COLLECTION + "', \"admin\", \"admin\"),"); query.append("$mods := xdb:remove(\"" + eXistUrl + DBBroker.ROOT_COLLECTION + "\", \"" + doc + "\")"); query.append("return <modifications>{$mods}</modifications>"); try { CompiledExpression cQuery = service.compile(query.toString()); service.execute(cQuery); } catch (XMLDBException e) { fail(e.getMessage()); } } /** * Loads the xml document identified by <code>document</code> from the database. * * @param service the xquery service * @param document the document to load */ private final Node load(XQueryService service, String document) { StringBuffer query = new StringBuffer(); query.append("xquery version \"1.0\";"); query.append("let $result := xmldb:document(concat('" + DBBroker.ROOT_COLLECTION + "', $document))"); query.append("return ($result)"); try { service.declareVariable("document", document); CompiledExpression cQuery = service.compile(query.toString()); ResourceSet set = service.execute(cQuery); if (set != null && set.getSize() > 0) { return ((XMLResource)set.getIterator().nextResource()).getContentAsDOM(); } } catch (XMLDBException e) { fail(e.getMessage()); } return null; } /** * Registers a new database instance and returns it. */ private final Database registerDatabase() { Class driver = null; String driverName = "org.exist.xmldb.DatabaseImpl"; try { driver = Class.forName(driverName); Database database = (Database)driver.newInstance(); database.setProperty("create-database", "true"); DatabaseManager.registerDatabase(database); return database; } catch (Exception e) { fail(e.getMessage()); } return null; } /** * Retrieves the base collection and thereof returns a reference to the collection's * xquery service. * * @param db the database * @return the xquery service */ private final XQueryService getXQueryService(Database db) { try { Collection collection = DatabaseManager.getCollection(eXistUrl + DBBroker.ROOT_COLLECTION, "admin", "admin"); if (collection != null) { XQueryService service = (XQueryService)collection.getService("XQueryService", "1.0"); collection.close(); return service; } } catch (XMLDBException e) { fail(e.getMessage()); } return null; } private final String createDocument() { StringBuffer xmlDocument = new StringBuffer(); xmlDocument.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); xmlDocument.append("<page partition=\"home\" path=\"/\" version=\"live\">"); xmlDocument.append(" <header>"); xmlDocument.append(" <renderer>home_dreispaltig</renderer>"); xmlDocument.append(" <layout>default</layout>"); xmlDocument.append(" <type>default</type>"); xmlDocument.append(" <publish>"); xmlDocument.append(" <from>2005/06/06 10:53:40 GMT</from>"); xmlDocument.append(" <to>292278994/08/17 07:12:55 GMT</to>"); xmlDocument.append(" </publish>"); xmlDocument.append(" <security>"); xmlDocument.append(" <owner>www</owner>"); xmlDocument.append(" <permission id=\"system:manage\" type=\"role\">system:editor</permission>"); xmlDocument.append(" <permission id=\"system:read\" type=\"role\">system:guest</permission>"); xmlDocument.append(" <permission id=\"system:translate\" type=\"role\">system:translator</permission>"); xmlDocument.append(" <permission id=\"system:publish\" type=\"role\">system:publisher</permission>"); xmlDocument.append(" <permission id=\"system:write\" type=\"role\">system:editor</permission>"); xmlDocument.append(" </security>"); xmlDocument.append(" <keywords/>"); xmlDocument.append(" <title language=\"de\">Home</title>"); xmlDocument.append(" <title language=\"fr\">Home</title>"); xmlDocument.append(" <title language=\"it\">Home</title>"); xmlDocument.append(" <modified>"); xmlDocument.append(" <date>2005/06/06 10:53:40 GMT</date>"); xmlDocument.append(" <user>markus.jauss</user>"); xmlDocument.append(" </modified>"); xmlDocument.append(" </header>"); xmlDocument.append(" <body/>"); xmlDocument.append("</page>"); return xmlDocument.toString(); } /** * Creates the database connection. * * @return the xquery service */ private XQueryService setupDatabase() { try { Database eXist = registerDatabase(); // Obtain XQuery service XQueryService service = null; service = getXQueryService(eXist); return service; } catch (Exception e) { fail("Unable to register database: " + e.getMessage()); } return null; } }