package com.dbxml.db.client.xmldb;
/*
* dbXML - Native XML Database
* Copyright (c) 1999-2006 The dbXML Group, L.L.C.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* $Id: DatabaseImpl.java,v 1.3 2006/02/02 18:53:47 bradford Exp $
*/
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import com.dbxml.db.client.CollectionClient;
import com.dbxml.db.client.dbXMLClient;
import com.dbxml.db.client.xmlrpc.dbXMLClientImpl;
import com.dbxml.db.server.dbXML;
import com.dbxml.util.SoftHashMap;
import com.dbxml.util.dbXMLException;
import org.xmldb.api.base.*;
/**
* DatabaseImpl implements the XML:DB Database interface for dbXML. The
* URL form is: dbxml://[server]:[port]/[collection-path]
*/
public final class DatabaseImpl implements Database, Configurable {
private static final String DEFAULT_DRIVER = dbXMLClientImpl.class.getName();
private static final String NAME = "dbxml";
private static final String DBXML_PREFIX = NAME+':';
private static final String HTTP_PREFIX = "http:";
private static final String CONFORMANCE_LEVEL = "1";
private static final String DRIVER = "driver";
private static final String CONNECTION = "connection";
private Properties props = new Properties();
private Map clientCache = Collections.synchronizedMap(new SoftHashMap());
public String getName() throws XMLDBException {
return NAME;
}
public String getProperty(String name) throws XMLDBException {
return props.getProperty(name);
}
public void setProperty(String name, String value) throws XMLDBException {
props.setProperty(name, value);
}
public Collection getCollection(String uri, String username, String password) throws XMLDBException {
// Morph into an HTTP URI so it can be parsed by the URL class
if ( uri.startsWith(DBXML_PREFIX) )
uri = HTTP_PREFIX + uri.substring(DBXML_PREFIX.length());
URL url = null;
try {
url = new URL(uri);
}
catch ( MalformedURLException e ) {
throw new XMLDBException(ErrorCodes.INVALID_URI, e.getMessage());
}
String host = url.getHost();
int port = url.getPort();
String path = url.getPath();
String conID = getConnectionID(host, port, username, password);
dbXMLClient dbClient = (dbXMLClient)clientCache.get(conID);
if ( dbClient == null ) {
String driver = props.getProperty(DRIVER, DEFAULT_DRIVER);
try {
dbClient = (dbXMLClient)Class.forName(driver).newInstance();
}
catch ( Exception e ) {
throw new XMLDBException(ErrorCodes.INVALID_DATABASE, "Driver '"+driver+"' could not be instantiated");
}
String connection = props.getProperty(CONNECTION);
if ( connection != null )
dbClient.setProperty(CONNECTION, connection);
if ( host != null && !host.equals(dbXML.DEFAULT_HOST) )
dbClient.setProperty(dbXMLClient.HOST, host);
if ( port != dbXML.DEFAULT_PORT )
dbClient.setProperty(dbXMLClient.PORT, Integer.toString(port));
if ( username != null )
dbClient.setProperty(dbXMLClient.USER, username);
if ( password != null )
dbClient.setProperty(dbXMLClient.PASS, password);
try {
dbClient.connect();
clientCache.put(conID, dbClient);
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.NO_SUCH_DATABASE, e.getMessage());
}
}
try {
CollectionClient colClient = dbClient.getCollection(path);
if ( colClient != null )
return new CollectionImpl(colClient);
else
throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, "No such Collection at '"+uri+"'");
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, e.getMessage());
}
}
public boolean acceptsURI(String uri) throws XMLDBException {
return uri.startsWith(DBXML_PREFIX);
}
public String getConformanceLevel() throws XMLDBException {
return CONFORMANCE_LEVEL;
}
private String getConnectionID(String host, int port, String user, String pass) {
StringBuffer sb = new StringBuffer(32);
sb.append(DBXML_PREFIX);
if ( user != null ) {
sb.append(user);
sb.append(':');
sb.append(pass);
sb.append('@');
}
sb.append(host);
sb.append(':');
sb.append(Integer.toString(port));
sb.append(':');
return sb.toString();
}
}