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: CollectionImpl.java,v 1.4 2006/02/02 18:53:47 bradford Exp $
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import com.dbxml.db.client.CollectionClient;
import com.dbxml.util.dbXMLException;
import org.xmldb.api.base.*;
/**
* CollectionImpl
*/
public final class CollectionImpl implements Collection, Configurable {
private static final Service[] EmptyServices = new Service[0];
private Properties props = new Properties();
private List services = new ArrayList();
private CollectionClient client;
private boolean opened = true;
private String name;
private int type = -1;
public CollectionImpl(CollectionClient client) {
this.client = client;
addService(new XPathQueryServiceImpl(this));
addService(new XUpdateQueryServiceImpl(this));
addService(new XSLTransformServiceImpl(this));
}
private int getContentType() throws dbXMLException {
if ( type == -1 )
type = client.getCollectionType();
return type;
}
private void checkOpened() throws XMLDBException {
if ( !opened )
throw new XMLDBException(ErrorCodes.COLLECTION_CLOSED, "Collection is closed");
}
public CollectionClient getCollectionClient() {
return client;
}
public String getName() throws XMLDBException {
checkOpened();
try {
if ( name == null )
name = client.getName();
return name;
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public String getProperty(String name) throws XMLDBException {
return props.getProperty(name);
}
public void setProperty(String name, String value) throws XMLDBException {
props.setProperty(name, value);
}
private void addService(Service service) {
services.add(service);
}
public Service[] getServices() throws XMLDBException {
return (Service[])services.toArray(EmptyServices);
}
public Service getService(String name, String version) throws XMLDBException {
checkOpened();
Iterator iter = services.iterator();
while ( iter.hasNext() ) {
Service service = (Service)iter.next();
if ( service.getName().equals(name) && service.getVersion().equals(version) )
return service;
}
return null;
}
public Collection getParentCollection() throws XMLDBException {
checkOpened();
try {
CollectionClient parent = client.getParentCollection();
if ( parent != null )
return new CollectionImpl(parent);
else
throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, "No Parent Collection");
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public int getChildCollectionCount() throws XMLDBException {
checkOpened();
try {
return client.listCollections().length;
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public String[] listChildCollections() throws XMLDBException {
checkOpened();
try {
return client.listCollections();
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public Collection getChildCollection(String name) throws XMLDBException {
try {
CollectionClient child = client.getCollection(name);
if ( child != null )
return new CollectionImpl(child);
else
throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, "No Child Collection named '" + name + "'");
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, "No Child Collection named '" + name + "'");
}
}
public int getResourceCount() throws XMLDBException {
checkOpened();
try {
return (int)client.getKeyCount();
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public String[] listResources() throws XMLDBException {
checkOpened();
try {
return client.listKeys();
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public Resource createResource(String id, String type) throws XMLDBException {
try {
switch ( getContentType() ) {
case CollectionClient.TYPE_DOCUMENTS:
if ( type.equals(XMLResourceImpl.TYPE) )
return new XMLResourceImpl(this, id, id, null);
break;
case CollectionClient.TYPE_VALUES:
if ( type.equals(BinaryResourceImpl.TYPE) )
return new BinaryResourceImpl(this, id, null);
break;
}
throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "Invalid Resource type '" + type + "'");
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public void removeResource(Resource res) throws XMLDBException {
checkOpened();
try {
String id = res.getId();
if ( id != null && id.length() > 0 )
client.remove(id);
else
throw new XMLDBException(ErrorCodes.NO_SUCH_RESOURCE, "Invalid Resource ID '" + id + "'");
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public void storeResource(Resource res) throws XMLDBException {
try {
switch ( getContentType() ) {
case CollectionClient.TYPE_DOCUMENTS:
if ( res instanceof XMLResourceImpl )
client.setDocumentAsText(res.getId(), (String)res.getContent());
else
throw new dbXMLException("Collection can only store document content");
break;
case CollectionClient.TYPE_VALUES:
if ( res instanceof BinaryResourceImpl )
client.setValue(res.getId(), (byte[])res.getContent());
else
throw new dbXMLException("Collection can only store binary content");
break;
default:
throw new dbXMLException("Unknown Content Type");
}
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public Resource getResource(String id) throws XMLDBException {
try {
switch ( getContentType() ) {
case CollectionClient.TYPE_DOCUMENTS:
return new XMLResourceImpl(this, id, id, client.getDocumentAsText(id));
case CollectionClient.TYPE_VALUES:
return new BinaryResourceImpl(this, id, client.getValue(id));
default:
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "Unknown Content Type");
}
}
catch ( dbXMLException e ) {
if ( e.getMessage().endsWith("not found") )
return null;
else
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public String createId() throws XMLDBException {
try {
return client.createKey();
}
catch ( dbXMLException e ) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
public boolean isOpen() throws XMLDBException {
return opened;
}
public void close() throws XMLDBException {
opened = false;
client = null;
}
}