package org.exist.fluent; import java.io.File; import java.lang.annotation.*; import java.util.Iterator; import org.exist.collections.Collection; import org.exist.dom.*; import org.exist.security.SecurityManager; import org.exist.storage.DBBroker; import org.exist.xmldb.XmldbURI; import org.junit.*; /** * A superclass for database unit tests. It takes care of starting up and clearing the database in * its <code>setUp</code> method, and supports mocking with jMock. By default, the database * will be configured from the file "conf.xml" in the current directory, but you can annotate your * test class with {@link DatabaseTestCase.ConfigFile} to specify a different one. * * @author <a href="mailto:piotr@ideanest.com">Piotr Kaminski</a> */ @DatabaseTestCase.ConfigFile("conf.xml") public abstract class DatabaseTestCase { /** * An annotation that specifies the path of the config file to use when setting up the database * for a test. * * @author <a href="mailto:piotr@ideanest.com">Piotr Kaminski</a> */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ConfigFile { String value(); } protected static Database db; @Before public void startupDatabase() throws Exception { ConfigFile configFileAnnotation = getClass().getAnnotation(ConfigFile.class); if (configFileAnnotation == null) throw new DatabaseException("Missing ConfigFile annotation on DatabaseTestCase subclass"); File configFile = new File(configFileAnnotation.value()); if (!Database.isStarted()) { Database.startup(configFile); db = null; } if (db == null) db = new Database(SecurityManager.SYSTEM_USER); wipeDatabase(); Database.configureRootCollection(configFile); // config file gets erased by wipeDatabase() } @AfterClass public static void shutdownDatabase() throws Exception { if (Database.isStarted()) { wipeDatabase(); Database.shutdown(); db = null; } } @SuppressWarnings("unchecked") private static void wipeDatabase() throws Exception { Transaction tx = db.requireTransactionWithBroker(); try { Collection root = tx.broker.getCollection(XmldbURI.ROOT_COLLECTION_URI); for (Iterator<XmldbURI> it = root.collectionIterator(); it.hasNext(); ) { XmldbURI childName = it.next(); if (!childName.getCollectionPath().equals(DBBroker.SYSTEM_COLLECTION_NAME)) { tx.broker.removeCollection(tx.tx, tx.broker.getCollection(root.getURI().append(childName))); } } for (Iterator<DocumentImpl> it = root.iterator(tx.broker); it.hasNext(); ) { DocumentImpl doc = it.next(); if (doc instanceof BinaryDocument) { root.removeBinaryResource(tx.tx, tx.broker, doc); } else { root.removeXMLResource(tx.tx, tx.broker, doc.getFileURI()); } } tx.commit(); } finally { tx.abortIfIncomplete(); } } }