
org.xmldb.api.DatabaseManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmldb-api Show documentation
Show all versions of xmldb-api Show documentation
XML:DB Initiative for XML Databases
/*
* The XML:DB Initiative Software License, Version 1.0
*
*
* Copyright (c) 2000-2003 The XML:DB Initiative. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* XML:DB Initiative (http://www.xmldb.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The name "XML:DB Initiative" must not be used to endorse or
* promote products derived from this software without prior written
* permission. For written permission, please contact [email protected].
*
* 5. Products derived from this software may not be called "XML:DB",
* nor may "XML:DB" appear in their name, without prior written
* permission of the XML:DB Initiative.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the XML:DB Initiative. For more information
* on the XML:DB Initiative, please see .
*/
package org.xmldb.api;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.locks.StampedLock;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.ErrorCodes;
import org.xmldb.api.base.XMLDBException;
/**
* DatabaseManager
is the entry point for the API and enables you to get the
* initial Collection
references necessary to do anything useful with the API.
* DatabaseManager
is intended to be
* provided as a concrete implementation in a particular programming
* language. Individual language mappings should define the exact syntax and
* semantics of its use.
*/
public class DatabaseManager
{
protected static final String URI_PREFIX = "xmldb:";
static final Properties properties = new Properties();
static final StampedLock dbLock = new StampedLock();
static final Map databases = new HashMap<>(5);
static boolean strictRegistrationBehavior = Boolean.getBoolean("org.xmldb.api.strictRegistrationBehavior");
/**
* Returns a list of all available Database
implementations
* that have been registered with this DatabaseManager
.
*
* @return An array of Database
instances.
* One for each Database
registered
* with the DatabaseManager
. If no Database
* instances exist then an empty array is returned.
*/
public static Database[] getDatabases() {
// try optimistic read first
long stamp = dbLock.tryOptimisticRead();
if (stamp > 0) {
final Database[] result = databases.values().toArray(new Database[0]);
if (dbLock.validate(stamp)) {
return result;
}
}
// fallback to locking read
stamp = dbLock.readLock();
try {
return databases.values().toArray(new Database[0]);
} finally {
dbLock.unlockRead(stamp);
}
}
/**
* Registers a new Database
implementation with the
* DatabaseManager
.
*
* @param database The database instance to register.
* @throws XMLDBException with expected error codes.
* ErrorCodes.VENDOR_ERROR
for any vendor
* specific errors that occur.
* ErrorCodes.INVALID_DATABASE
if the provided Database
*
instance is invalid.
*/
public static void registerDatabase(final Database database) throws XMLDBException {
final String[] databaseNames = database.getNames();
// we need at least one suitable name for this instance
if (databaseNames == null || databaseNames.length == 0 || databaseNames[0].isEmpty()) {
throw new XMLDBException(ErrorCodes.INVALID_DATABASE);
}
final long stamp = dbLock.writeLock();
try {
// put all names of this instance into the databases map
for (final String databaseName : databaseNames) {
updateDatabases(databaseName, database);
}
} finally {
dbLock.unlockWrite(stamp);
}
}
private static void updateDatabases(final String databaseName, final Database database) throws XMLDBException {
final Database existing = databases.putIfAbsent(databaseName, database);
if (existing != null && existing != database && strictRegistrationBehavior) {
throw new XMLDBException(ErrorCodes.INSTANCE_NAME_ALREADY_REGISTERED);
}
}
/**
* Deregisters a Database
implementation from the DatabaseManager
. Once a
* Database
has been deregistered it can no longer be used to handle
* requests.
*
* @param database The Database
instance to deregister.
* @throws XMLDBException with expected error codes.
* ErrorCodes.VENDOR_ERROR
for any vendor
* specific errors that occur.
*/
public static void deregisterDatabase(final Database database)
throws XMLDBException {
final long stamp = dbLock.writeLock();
try {
for (Iterator dbIterator = databases.values().iterator(); dbIterator.hasNext();) {
if (database.equals(dbIterator.next())) {
dbIterator.remove();
}
}
} finally {
dbLock.unlockWrite(stamp);
}
}
/**
* Retrieves a Collection
instance from the database for the
* given URI. The format of the majority of the URI is database
* implementation specific however the uri must begin with characters xmldb:
* and be followed by the name of the database instance as returned by
* Database.getName()
and a colon
* character. An example would be for the database named "vendordb" the URI
* handed to getCollection would look something like the following.
* xmldb:vendordb://host:port/path/to/collection
. The xmldb:
* prefix will be removed from the URI prior to handing the URI to the
* Database
instance for handling.
*
* This method is called when no authentication is necessary for the
* database.
*
* @param uri The database specific URI to use to locate the collection.
* @return A Collection
instance for the requested collection or
* null if the collection could not be found.
* @throws XMLDBException with expected error codes.
* ErrorCodes.VENDOR_ERROR
for any vendor
* specific errors that occur.
* ErrroCodes.INVALID_URI
If the URI is not in a valid format.
* ErrroCodes.NO_SUCH_DATABASE
If a Database
* instance could not be found to handle the provided URI.
*/
public static Collection getCollection(final String uri)
throws XMLDBException {
return getCollection(uri, null, null);
}
/**
* Retrieves a Collection
instance from the database for the
* given URI. The format of the majority of the URI is database
* implementation specific however the uri must begin with characters xmldb:
* and be followed by the name of the database instance as returned by
* Database.getName()
and a colon
* character. An example would be for the database named "vendordb" the URI
* handed to getCollection would look something like the following.
* xmldb:vendordb://host:port/path/to/collection
. The xmldb:
* prefix will be removed from the URI prior to handing the URI to the
* Database
instance for handling.
*
* @param uri The database specific URI to use to locate the collection.
* @param username The username to use for authentication to the database or
* null if the database does not support authentication.
* @param password The password to use for authentication to the database or
* null if the database does not support authentication.
* @return A Collection
instance for the requested collection or
* null if the collection could not be found.
* @throws XMLDBException with expected error codes.
* ErrorCodes.VENDOR_ERROR
for any vendor
* specific errors that occur.
* ErrroCodes.INVALID_URI
If the URI is not in a valid format.
* ErrroCodes.NO_SUCH_DATABASE
If a Database
* instance could not be found to handle the provided URI.
* ErrroCodes.PERMISSION_DENIED
If the username
* and password
were not accepted by the database.
*/
public static Collection getCollection(final String uri,
final String username, final String password) throws XMLDBException {
final Database db = getDatabase(uri);
return db.getCollection(stripURIPrefix(uri), username, password);
}
/**
* Returns the Core Level conformance value for the provided URI. The current
* API defines valid resuls of "0" or "1" as defined in the XML:DB API
* specification.
*
* @param uri The database specific URI to use to locate the collection.
* @return The XML:DB Core Level conformance for the uri.
* @throws XMLDBException with expected error codes.
* ErrorCodes.VENDOR_ERROR
for any vendor
* specific errors that occur.
* ErrroCodes.INVALID_URI
If the URI is not in a valid format.
* ErrroCodes.NO_SUCH_DATABASE
If a Database
* instance could not be found to handle the provided URI.
*/
public static String getConformanceLevel(final String uri) throws XMLDBException {
final Database database = getDatabase(uri);
return database.getConformanceLevel();
}
/**
* Retrieves a property that has been set for the DatabaseManager
.
*
* @param name The property name
* @return The property value
*/
public static String getProperty(final String name) {
return properties.getProperty(name);
}
/**
* Sets a property for the DatabaseManager
.
*
* @param name The property name
* @param value The value to set.
*/
public static void setProperty(final String name, final String value) {
properties.put(name, value);
}
/**
* Retrieves the registered Database
instance associated with the provided
* URI.
*
* @param uri The uri containing the database reference.
* @return the requested Database
instance.
* @throws XMLDBException if an error occurs whilst getting the database
*/
protected static Database getDatabase(final String uri) throws XMLDBException {
if (!uri.startsWith(URI_PREFIX)) {
throw new XMLDBException(ErrorCodes.INVALID_URI);
}
final int end = uri.indexOf(":", URI_PREFIX.length());
if (end == -1) {
throw new XMLDBException(ErrorCodes.INVALID_URI);
}
final String databaseName = uri.substring(URI_PREFIX.length(), end);
// try optimistic read first
long stamp = dbLock.tryOptimisticRead();
if (stamp > 0) {
final Database db = databases.get(databaseName);
if (dbLock.validate(stamp)) {
if (db == null) {
throw new XMLDBException(ErrorCodes.NO_SUCH_DATABASE);
}
return db;
}
}
// fallback to locking read
final Database db;
stamp = dbLock.readLock();
try {
db = databases.get(databaseName);
} finally {
dbLock.unlockRead(stamp);
}
if (db == null) {
throw new XMLDBException(ErrorCodes.NO_SUCH_DATABASE);
}
return db;
}
/**
* Removes the URI_PREFIX from the front of the URI. This is so the database
* can focus on handling its own URIs.
*
* @param uri The full URI to strip.
* @return The database specific portion of the URI.
* @throws XMLDBException if an error occurs whilst stripping the URI prefix
*/
protected static String stripURIPrefix(final String uri) throws XMLDBException {
if (!uri.startsWith(URI_PREFIX)) {
throw new XMLDBException(ErrorCodes.INVALID_URI);
}
return uri.substring(URI_PREFIX.length());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy