// You can redistribute this software and/or modify it under the terms of
// the Ozone Library License version 1 published by ozone-db.org.
//
// The original code and portions created by SMB are
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
//
// $Id: CollectionImpl.java,v 1.1 2001/12/18 11:03:24 per_nyfelt Exp $
package org.ozoneDB.xml.cli;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import java.io.Serializable;
import org.ozoneDB.OzoneInterface;
// don't know if using ExternalDb is the best way but the interface does not have close()
import org.ozoneDB.ExternalDatabase;
import org.ozoneDB.xml.cli.resources.XMLResourceImpl;
import org.ozoneDB.xml.core.XMLCollection;
import org.ozoneDB.xml.util.XMLContainer;
import org.xmldb.api.base.ErrorCodes;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Resource;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.Service;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.BinaryResource;
import java.util.Random;
/**
* A <code>Collection</code> represents a collection of <code>Resource</code>s
* stored within an XML database. An XML database may expose collections as a
* hierarchical set of parent and child collections.<p />
*
* A <code>Collection</code> provides access to the <code>Resource</code>s
* stored by the <code>Collection</code> and to <code>Service</code> instances
* that can operate against the <code>Collection</code> and the
* <code>Resource</code>s stored within it. The <code>Service</code> mechanism
* provides the ability to extend the functionality of a <code>Collection</code>
* in ways that allows optional functionality to be enabled for the <code>Collection</code>.
*
* @author <a href="http://www.smb-tec.com">SMB</a>, Per Nyfelt
* @version $Revision: 1.1 $
*/
public class CollectionImpl extends AbstractConfigurable
implements Collection {
//
// data
//
private Map services = null;
private ExternalDatabase database = null;
private XMLCollection collection = null;
//private Map resources = null;
/**
* gets the <code>Collection</code> using the corresponding name from the given
* database
*/
protected static Collection forName( ExternalDatabase database, String collectionName )
throws Exception {
XMLCollection collection = ( XMLCollection )database.objectForName( collectionName );
return collection != null ?
new CollectionImpl ( database, collection ) : null;
}
/**
* creates a new <code>Collection</code> and stores it in the database
*/
protected static Collection newCollection( ExternalDatabase database,
String collectionName ) throws Exception {
XMLCollection collection = ( XMLCollection ) database.createObject(
org.ozoneDB.xml.core.XMLCollectionImpl.class.getName(), OzoneInterface.Public, collectionName );
collection.setName(collectionName);
return new CollectionImpl( database, collection );
}
/**
* Constuctor
*/
protected CollectionImpl( ExternalDatabase database, XMLCollection collection ) {
this.database = database;
this.collection = collection;
services = new HashMap();
}
/**
* Returns the name of this Collection. The name is unique.
*
* @return The name of this Collection.
*/
public String getName() throws XMLDBException {
return collection.getName();
}
/**
* @return a String array of Services registered for this Collection.
*/
public synchronized Service[] getServices() throws XMLDBException {
return (Service[]) services.values().toArray( new Service[services.values().size()] );
}
/**
* Returns the Service with the provided name and version.
*
* @param name the name of the requested Service
* @param version the version of the requested Service if any
*/
public Service getService( String name, String version )
throws XMLDBException {
return (Service) services.get( name + version );
}
/**
* Registers the provided Service for this Collection.
*
* @param service The Service to be registered for this Collection.
*/
public synchronized void registerService( Service service )
throws XMLDBException {
service.setCollection( this );
services.put( service.getName() + service.getVersion(), service );
}
/**
* Returns the parent collection for this collection or null if no parent
* collection exists.
*
* @return the parent Collection instance.
* @exception XMLDBException
*/
public Collection getParentCollection() throws XMLDBException {
XMLCollection parentCollection = collection.getParentCollection();
return parentCollection == null ? null :
new CollectionImpl( database, parentCollection );
}
/**
* Returns the number of child collections under this collection or 0 if no
* child collections exist.
*
* @return the number of child collections.
* @exception XMLDBException
*/
public int getChildCollectionCount() throws XMLDBException {
return collection.getChildCollectionCount();
}
/**
* Returns a list of Collection names naming all child collections
* of the current collection. If no child collections exist an empty list is
* returned.
*
* @return an array containing Collection names for all child
* collections.
* @exception XMLDBException
*/
public String[] listChildCollections() throws XMLDBException {
return collection.listChildCollections();
}
/**
* Returns a Collection instance for the requested child collection
* if it exists.
*
* @param name the name of the child collection to retrieve.
* @return the requested child collection or null if it couldn't be found.
* @exception XMLDBException
*/
public Collection getChildCollection( String name ) throws XMLDBException {
XMLCollection cCollection = collection.getChildCollection( name );
return cCollection == null ? null :
new CollectionImpl( database, cCollection );
}
/**
*/
public int getResourceCount() throws XMLDBException {
return collection.getResourceCount();
}
/**
* Returns a list of the ids for all resources stored in the collection.
*
* @return a string array containing the names for all
* <code>Resource</code>s in the collection.
* @exception XMLDBException with expected error codes.<br />
* <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
* specific errors that occur.<br />
*/
public String[] listResources() throws XMLDBException {
Set resourceSet = collection.getResources();
String[] resourceArray = (String[])resourceSet.toArray();
return resourceArray;
}
/**
* Creates a new empty <code>Resource</code> with the provided id.
*
* @param id the unique id to associate with the created <code>Resource</code>.
* @param type the <code>Resource</code> type to create.
* @return an empty <code>Resource</code> instance.
*/
public Resource createResource( String id, String type ) throws XMLDBException {
try {
if ( ( id == null ) || ( id.length() == 0 ) ) {
id = createId();
}
if ( type.equals(XMLResource.RESOURCE_TYPE) ) {
//System.out.println("CollectionImpl.createResource() - Creating container");
XMLContainer container = XMLContainer.forName(database, id);
if (container != null ) {
System.out.println("container exists already");
throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "resource " + id + " already exists");
}
container = XMLContainer.newContainer(database, id);
//System.out.println("CollectionImpl.createResource() - created XMLContainer, adding id to the XMLCollection");
collection.addResource(id);
return new XMLResourceImpl(id, database, this, container);
} else if ( type.equals(BinaryResource.RESOURCE_TYPE) ) {
//return new BinaryResourceImpl(this, id);
throw new XMLDBException( ErrorCodes.VENDOR_ERROR, "BinaryResource: Not yet implemented");
} else {
throw new XMLDBException(ErrorCodes.UNKNOWN_RESOURCE_TYPE);
}
} catch (Exception e) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
/**
* Removes the <code>Resource</code> from the database.
*
* @param res the resource to remove.
* @exception XMLDBException with expected error codes.<br />
* <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
* specific errors that occur.<br />
* <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is
* not valid.<br />
* <code>ErrorCodes.NO_SUCH_RESOURCE</code> if the <code>Resource</code> is
* not known to this <code>Collection</code>.
*/
public void removeResource( Resource res ) throws XMLDBException {
try {
System.out.println("CollectionImpl.removeResource() - Getting XMLContainer");
XMLContainer container = null;
String id = res.getId();
if ( collection.hasResource(id) ) {
container = XMLContainer.forName(database, id);
container.delete();
} else {
throw new XMLDBException(ErrorCodes.NO_SUCH_RESOURCE, "the resource is not a part of this collection");
}
} catch (Exception e) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.toString());
}
}
/**
* Stores the provided resource into the database.
*
* @param res the resource to store in the database.
*/
public void storeResource( Resource res ) throws XMLDBException {
try {
String id = res.getId();
if ((id == null) || (id.length() == 0)) {
id = createId();
}
System.out.println("CollectionImpl.storeResource() - Dont know what to do here");
} catch (Exception e) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.toString());
}
}
/**
*/
public Resource getResource( String id ) throws XMLDBException {
try {
//System.out.println("CollectionImpl.getResource() - Getting XMLContainer");
XMLContainer container = null;
if ( collection.hasResource(id) )
container = XMLContainer.forName(database, id);
else
return null;
if (container == null) {
System.out.println("CollectionImpl.getResource() - container is null");
return null;
} else {
System.out.println("CollectionImpl.getResource() - creating new XMLResourceImpl");
Resource resource = new XMLResourceImpl( id, database, this, container );
//System.out.println("CollectionImpl.getResource() - created new XMLResourceImpl");
return resource;
}
} catch (Exception e) {
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.toString());
}
}
/**
* Creates a new unique ID within the context of the <code>Collection</code>
*
* @return the created id as a string.
*/
public String createId () throws XMLDBException {
System.out.println("CollectionImpl.createId() - fix the quick hack");
return collection.getName() + System.currentTimeMillis() + new Random().nextLong();
}
/**
* Releases all resources consumed by the <code>Collection</code>.
* The <code>close</code> method must
* always be called when use of a <code>Collection</code> is complete.
*
* @exception XMLDBException with expected error codes.<br />
* <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
* specific errors that occur.<br />
*/
public void close() throws XMLDBException {
// don't know if this is the best way but OzoneInterface does not have close()
if (database instanceof ExternalDatabase) {
try {
((ExternalDatabase)database).close();
System.out.println("CollectionImpl.close() - connection closed");
} catch (Exception e) {
throw new XMLDBException( ErrorCodes.VENDOR_ERROR, e.getMessage());
}
}
}
}