/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * 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 Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.services.cms.repository.slide;

//JDK
import java.lang.reflect.Constructor;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.util.List;
import java.util.Iterator;
import java.util.Date;

// Slide
import org.apache.slide.common.AbstractSimpleService;
import org.apache.slide.common.ServiceConnectionFailedException;
import org.apache.slide.common.ServiceDisconnectionFailedException;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.ServiceResetFailedException;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;

import org.apache.slide.store.LockStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.store.RevisionDescriptorsStore;
import org.apache.slide.store.RevisionDescriptorStore;
import org.apache.slide.store.SecurityStore;

import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.structure.ObjectAlreadyExistsException;

import org.apache.slide.security.NodePermission;

import org.apache.slide.lock.NodeLock;
import org.apache.slide.lock.LockTokenNotFoundException;

import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.RevisionContentNotFoundException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.NodeRevisionNumber;

import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;

// Turbine

import org.apache.torque.util.Criteria;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.util.Log;


// Jetspeed
import org.apache.jetspeed.services.security.JetspeedSecurityService;
import org.apache.jetspeed.services.security.GroupManagement;
import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRole;
import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRolePeer;
import org.apache.jetspeed.om.security.turbine.TurbineUserPeer;
import org.apache.jetspeed.om.security.turbine.TurbineUser;
import org.apache.jetspeed.om.security.turbine.TurbineGroup;
import org.apache.jetspeed.om.security.turbine.TurbineGroupPeer;
import org.apache.jetspeed.om.security.Group;
import org.apache.jetspeed.om.security.JetspeedUser;


/**
 * Jetspeed security compliant store implementation.
 *
 * This Slide store is using only to retrieve jetspeed user/group info.
 * It is not used to update a jetspeed user/group. You have to use the  Jetspeed application
 * for doing that
 *
 * TODO :
 *  + This class has to be review. Check if it possible to be more "Turbine independent".
 *    Use in this store the new Jetspeed security stuff.
 *  + Check if the interface NodeStore is not sufficient.
 *
 * @author <a href="mailto:christophe.lombart@skynet.be">Christophe Lombart</a>
 */
public class JetspeedDescriptorsStore
	extends AbstractSimpleService
	implements
		LockStore,
		NodeStore,
		RevisionDescriptorsStore,
		RevisionDescriptorStore,
		SecurityStore
{

	// Structure descriptors

	protected static final int OBJECTS_URI = 1;
	protected static final int OBJECTS_CLASS = 2;

	protected static final int CHILDREN_URI = 1;
	protected static final int CHILDREN_CHILDURI = 2;

	protected static final int LINKS_LINK = 1;
	protected static final int LINKS_LINKTO = 2;

	// Security descriptors

	protected static final int PERMISSIONS_OBJECT = 1;
	protected static final int PERMISSIONS_REVISION_NUMBER = 2;
	protected static final int PERMISSIONS_SUBJECT = 3;
	protected static final int PERMISSIONS_ACTION = 4;
	protected static final int PERMISSIONS_INHERITABLE = 5;
	protected static final int PERMISSIONS_NEGATIVE = 6;

	// Lock descriptors

	protected static final int LOCKS_ID = 1;
	protected static final int LOCKS_OBJECT = 2;
	protected static final int LOCKS_SUBJECT = 3;
	protected static final int LOCKS_TYPE = 4;
	protected static final int LOCKS_EXPIRATIONDATE = 5;
	protected static final int LOCKS_INHERITABLE = 6;
	protected static final int LOCKS_EXCLUSIVE = 7;

	// Content descriptors

	protected static final int REVISIONS_URI = 1;
	protected static final int REVISIONS_ISVERSIONED = 2;
	protected static final int REVISIONS_INITIALREVISION = 3;

	protected static final int WORKINGREVISION_URI = 1;
	protected static final int WORKINGREVISION_BASEREVISION = 2;
	protected static final int WORKINGREVISION_NUMBER = 3;

	protected static final int LATESTREVISIONS_URI = 1;
	protected static final int LATESTREVISIONS_BRANCHNAME = 2;
	protected static final int LATESTREVISIONS_NUMBER = 3;

	protected static final int BRANCHES_URI = 1;
	protected static final int BRANCHES_NUMBER = 2;
	protected static final int BRANCHES_CHILDNUMBER = 3;

	protected static final int REVISION_URI = 1;
	protected static final int REVISION_NUMBER = 2;
	protected static final int REVISION_BRANCHNAME = 3;

	protected static final int LABEL_URI = 1;
	protected static final int LABEL_NUMBER = 2;
	protected static final int LABEL_LABEL = 3;

	protected static final int PROPERTY_URI = 1;
	protected static final int PROPERTY_NUMBER = 2;
	protected static final int PROPERTY_NAME = 3;
	protected static final int PROPERTY_VALUE = 4;
	protected static final int PROPERTY_NAMESPACE = 5;
	protected static final int PROPERTY_TYPE = 6;
	protected static final int PROPERTY_PROTECTED = 7;


	// ----------------------------------------------- DescriptorsStore Methods

	/**
	 * Retrieve an object.
	 *
	 * @param uri Uri of the object we want to retrieve
	 * @exception ServiceAccessException Error accessing the Service
	 * @exception ObjectNotFoundException The object to retrieve was not found
	 */
	public ObjectNode retrieveObject(Uri uri)
		throws ServiceAccessException, ObjectNotFoundException
	{

		ObjectNode result = null;

		try
		{
			// Check if parent uri name = the turbine group uri root
			if (uri.getParentUri()
				   .toString()
				   .equals(Utility.getGroupParentUri()))
			{
				String groupName = uri.toString().substring(uri.toString().lastIndexOf('/') + 1);
                GroupManagement groupService = (GroupManagement)TurbineServices.getInstance()
                									.getService("GroupManagement");

				Criteria criteria = new Criteria();
				criteria.addJoin(
					TurbineGroupPeer.GROUP_ID,
					TurbineUserGroupRolePeer.GROUP_ID);
				criteria.addJoin(
					TurbineUserGroupRolePeer.USER_ID,
					TurbineUserPeer.USER_ID);
				criteria.add(TurbineGroupPeer.GROUP_NAME, groupName);
				criteria.setDistinct();
				List users = TurbineUserPeer.doSelectUsers(criteria);

				if (Log.getLogger().isDebugEnabled())
				{
					Log.debug("TurbineDescriptorStore -  Group size : " + users.size());
				}
				Vector childrenVector = new Vector();
				Vector linksVector = new Vector();

				// Get  users from the UserGroupRole info
				Iterator iterator = users.iterator();
				while (iterator.hasNext())
				{
					JetspeedUser user = (JetspeedUser)iterator.next();
                    childrenVector.addElement(
						Utility.getUserParentUri() + "/" + user.getUserName());
				}

				Class objclass =
					Class.forName("org.apache.slide.structure.GroupNode");

				Class[] argClasses =
					{
						Class.forName("java.lang.String"),
						Class.forName("java.util.Vector"),
						Class.forName("java.util.Vector")
					};
				Object[] arguments =
					{
						uri.toString(),
						childrenVector,
						linksVector
					};

				Constructor constructor = objclass.getConstructor(argClasses);

				result = (ObjectNode)constructor.newInstance(arguments);

            // Check if parent uri name = the jetspeed user uri root
			}
			else if (uri.getParentUri()
						.toString()
						.equals(Utility.getUserParentUri()))
			{

                // Retrieve Jetspeed users
				String userName =
					uri.toString().substring(
						uri.toString().lastIndexOf('/') + 1);

                JetspeedSecurityService service = (JetspeedSecurityService) TurbineServices.getInstance().
                                         getService(JetspeedSecurityService.SERVICE_NAME);
                JetspeedUser user = service.getUser(userName);

                // Create and populate a Slide ObjectNode for this user
				Vector childrenVector = new Vector();
				Vector linksVector = new Vector();

				Class objclass = Class.forName("slideroles.basic.UserRoleImpl");

				Class[] argClasses =
					{
						Class.forName("java.lang.String"),
						Class.forName("java.util.Vector"),
						Class.forName("java.util.Vector")
					};
				Object[] arguments =
					{
						uri.toString(),
						childrenVector,
						linksVector
					};
				Constructor constructor = objclass.getConstructor(argClasses);
				result = (ObjectNode)constructor.newInstance(arguments);
			}
			else
			{
				//if (uri.toString().equals(Utility.getUserParentUri())) {
				// Slide engine ask first information on uri like '/users/turbine/' or
				// 'users/turbine/users' or '/users/turbine/groups'
				Vector childrenVector = new Vector();
				Vector linksVector = new Vector();

				Class objclass = Class.forName("slideroles.basic.UserRoleImpl");

				Class[] argClasses =
					{
						Class.forName("java.lang.String"),
						Class.forName("java.util.Vector"),
						Class.forName("java.util.Vector")
					};
				Object[] arguments =
					{
						uri.toString(),
						childrenVector,
						linksVector
					};
				Constructor constructor = objclass.getConstructor(argClasses);
				result = (ObjectNode)constructor.newInstance(arguments);
			}
		}
		catch (Exception e)
		{
			//Log.debug("TurbineDescriptorStore Exception - retrieveObject : " +
			//          e.getMessage());
			e.printStackTrace();
			throw new ObjectNotFoundException(uri);
		}

		return result;
	}

/*********************************************************************************
 *
 *   OTHER METHODE ARE NOT USED IN THIS STORE
 *
 */



	// -------------------------------------------------------- Service Methods

	/**
	 * Initializes the data source with a set of parameters.
	 *
	 * @param parameters Hashtable containing the parameters' name
	 * and associated value
	 * @exception ServiceParameterErrorException Incorrect service parameter
	 * @exception ServiceParameterMissingException Service parameter missing
	 */
	/*
	   public void setParameters(Hashtable parameters)
	       throws ServiceParameterErrorException,
	       ServiceParameterMissingException {


	   }

	*/
	/**
	 * Connects to JDBC and creates the basic table structure.
	 *
	 * @exception ServiceConnectionFailedException Connection to the
	 * database failed
	 */
	public synchronized void connect() throws ServiceConnectionFailedException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - connect");
		}
	}

	/**
	 * Disconnects from data source.
	 *
	 * @exception ServiceDisconnectionFailedException Disconnection
	 * from database failed
	 */
	public void disconnect() throws ServiceDisconnectionFailedException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - disconnect");
		}
	}

	/**
	 * Initializes data source.
	 * <p/>
	 * Occurs in four steps :
	 * <li>Driver class is loaded</li>
	 * <li>Driver is intantiated</li>
	 * <li>Driver registration in the driver manager</li>
	 * <li>Creation of the basic tables, if they didn't exist before</li>
	 *
	 * @exception ServiceInitializationFailedException Throws an exception
	 * if the data source has already been initialized before
	 */
	public synchronized void initialize(NamespaceAccessToken token)
		throws ServiceInitializationFailedException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - initialize");
		}
	}

	/**
	 * Deletes data source. Should remove stored data if possible.
	 *
	 * @exception ServiceResetFailedException Reset failed
	 */
	public synchronized void reset() throws ServiceResetFailedException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - reset");
		}
	}

	/**
	 * This function tells whether or not the data source is connected.
	 *
	 * @return boolean true if we are connected
	 * @exception ServiceAccessException Error accessing DataSource
	 */
	public boolean isConnected() throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - isConnected : true");
		}

		return true;
	}

	// ----------------------------------------------------- XAResource Methods

	/**
	 * Commit the global transaction specified by xid.
	 */
	public void commit(Xid xid, boolean onePhase) throws XAException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - commit");
		}

		// No Turbine user info update by using this descriptor store
		/*
		        super.commit(xid, onePhase);
		        try {
		            // ---------------  Commit the Turbine user info

		            connection.commit();
		            connection.setAutoCommit(true);


		        } catch (SQLException e) {
		            throw new XAException(XAException.XA_RBCOMMFAIL);
		        }
		   */
	}

	/**
	 * Inform the resource manager to roll back work done on behalf of a
	 * transaction branch.
	 */
	public void rollback(Xid xid) throws XAException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - rollback");
		}
		// No Turbine user info update by using this descriptor store
		/*
		       super.rollback(xid);
		       try {
		           // ---------------  Commit the Turbine user info
		           /*
		           connection.rollback();
		           connection.setAutoCommit(true);


		       } catch (SQLException e) {

		           throw new XAException(XAException.XA_HEURCOM);
		       }
		       */
	}

	/**
	 * Start work on behalf of a transaction branch specified in xid.
	 */
	public void start(Xid xid, int flags) throws XAException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - start");
		}
		// No Turbine user info update by using this descriptor store
		/*
		        System.out.println("JDBDescriptorStore.start()");
		        super.start(xid, flags);
		        try {
		            connection.setAutoCommit(false);
		        } catch (SQLException e) {
		            System.out.println("JDBDescriptorStore.start() hummm begin");
		            throw new XAException(XAException.XAER_RMERR);

		        }
		*/
	}

	/**
	 * Update an object.
	 *
	 * @param object Object to update
	 * @exception ServiceAccessException Error accessing the Service
	 * @exception ObjectNotFoundException The object to update was not found
	 */
	public void storeObject(Uri uri, ObjectNode object)
		throws ServiceAccessException, ObjectNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - storeObject :" + uri);
		}
	}

	/**
	 * Create a new object.
	 *
	 * @param object ObjectNode
	 * @param uri Uri of the object we want to create
	 * @exception ServiceAccessException Error accessing the Service
	 * @exception ObjectAlreadyExistsException An object already exists
	 * at this Uri
	 */
	public void createObject(Uri uri, ObjectNode object)
		throws ServiceAccessException, ObjectAlreadyExistsException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - createObject :" + uri);
		}
	}

	/**
	 * Remove an object.
	 *
	 * @param object Object to remove
	 * @exception ServiceAccessException Error accessing the Service
	 * @exception ObjectNotFoundException The object to remove was not found
	 */
	public void removeObject(Uri uri, ObjectNode object)
		throws ServiceAccessException, ObjectNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - removeObject");
		}
	}

	/**
	 * Grant a new permission.
	 *
	 * @param permission Permission we want to create
	 * @exception ServiceAccessException Error accessing the Service
	 */
	public void grantPermission(Uri uri, NodePermission permission)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - grantPermission");
		}
	}

	/**
	 * Revoke a permission.
	 *
	 * @param permission Permission we want to create
	 * @exception ServiceAccessException Error accessing the Service
	 */
	public void revokePermission(Uri uri, NodePermission permission)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - revokePermission");
		}
	}

	/**
	 * Revoke all the permissions on an object.
	 *
	 * @param permission Permission we want to create
	 * @exception ServiceAccessException Error accessing the Service
	 */
	public void revokePermissions(Uri uri) throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - revokePermission");
		}
	}

	/**
	 * Enumerate permissions on an object.
	 *
	 * @param permission Permission we want to create
	 * @exception ServiceAccessException Error accessing the Service
	 */
	public Enumeration enumeratePermissions(Uri uri)
		throws ServiceAccessException
	{
		//Vector permissionVector = new Vector();
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - enumeratePermission : " + uri);
		}
		/*NodePermission permission =
			new NodePermission(
				uri.toString(),
				null,
				"/users/turbine",
				"/actions/read",
				true,
				false);
		permissionVector.addElement(permission);
		return permissionVector.elements();
		*/
        return null;
	}

	/**
	 * Create a new lock.
	 *
	 * @param lock Lock token
	 * @exception ServiceAccessException Service access error
	 */
	public void putLock(Uri uri, NodeLock lock) throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - putLock");
		}
	}

	/**
	 * Renew a lock.
	 *
	 * @param lock Token to renew
	 * @exception ServiceAccessException Service access error
	 * @exception LockTokenNotFoundException Lock token was not found
	 */
	public void renewLock(Uri uri, NodeLock lock)
		throws ServiceAccessException, LockTokenNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - renewLock");
		}
	}

	/**
	 * Unlock.
	 *
	 * @param lock Token to remove
	 * @exception ServiceAccessException Service access error
	 * @exception LockTokenNotFoundException Lock token was not found
	 */
	public void removeLock(Uri uri, NodeLock lock)
		throws ServiceAccessException, LockTokenNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - removeLock");
		}
	}

	/**
	 * Kill a lock.
	 *
	 * @param lock Token to remove
	 * @exception ServiceAccessException Service access error
	 * @exception LockTokenNotFoundException Lock token was not found
	 */
	public void killLock(Uri uri, NodeLock lock)
		throws ServiceAccessException, LockTokenNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - KillLock");
		}
	}

	/**
	 * Enumerate locks on an object.
	 *
	 * @param subject Subject
	 * @return Enumeration List of locks which have been put on the subject
	 * @exception ServiceAccessException Service access error
	 */
	public Enumeration enumerateLocks(Uri uri) throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - enumerateLocks : " + uri);
		}

		return new Vector().elements();
	}

	/**
	 * Retrieve the revisions informations of an object.
	 *
	 * @param uri Uri
	 * @exception ServiceAccessException Service access error
	 * @exception RevisionDescriptorNotFoundException Revision descriptor
	 * was not found
	 */
	public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
		throws ServiceAccessException, RevisionDescriptorNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - retrieveRevisionDescriptor");
		}

		return null;
	}

	/**
	 * Create a new revision information object.
	 *
	 * @param uri Uri
	 * @param revisionDescriptors Node revision descriptors
	 * @exception ServiceAccessException Service access error
	 */
	public void createRevisionDescriptors(
		Uri uri,
		NodeRevisionDescriptors revisionDescriptors)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - createRevisionDescriptors");
		}
	}

	/**
	 * Update revision information.
	 *
	 * @param uri Uri
	 * @param revisionDescriptors Node revision descriptors
	 * @exception ServiceAccessException Service access error
	 * @exception RevisionDescriptorNotFoundException Revision descriptor
	 * was not found
	 */
	public void storeRevisionDescriptors(
		Uri uri,
		NodeRevisionDescriptors revisionDescriptors)
		throws ServiceAccessException, RevisionDescriptorNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - storeRevisionDescriptors");
		}
	}

	/**
	 * Remove revision information.
	 *
	 * @param uri Uri
	 * @exception ServiceAccessException Service access error
	 */
	public void removeRevisionDescriptors(Uri uri)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - removeRevisionDescriptors");
		}
	}

	/**
	 * Retrieve an individual object's revision descriptor.
	 *
	 * @param Uri uri
	 * @param revisionNumber Node revision number
	 */
	public NodeRevisionDescriptor retrieveRevisionDescriptor(
		Uri uri,
		NodeRevisionNumber revisionNumber)
		throws ServiceAccessException, RevisionDescriptorNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - retrieveRevisionDescriptor");
		}

		return null;
	}

	/**
	 * Create a new revision descriptor.
	 *
	 * @param uri Uri
	 * @param revisionDescriptor Node revision descriptor
	 * @exception ServiceAccessException Service access error
	 */
	public void createRevisionDescriptor(
		Uri uri,
		NodeRevisionDescriptor revisionDescriptor)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - createRevisionDescriptor");
		}

		return;
	}

	/**
	 * Update a revision descriptor.
	 *
	 * @param uri Uri
	 * @param revisionDescriptors Node revision descriptor
	 * @exception ServiceAccessException Service access error
	 * @exception RevisionDescriptorNotFoundException Revision descriptor
	 * was not found
	 */
	public void storeRevisionDescriptor(
		Uri uri,
		NodeRevisionDescriptor revisionDescriptor)
		throws ServiceAccessException, RevisionDescriptorNotFoundException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - storeRevisionDescriptor");
		}
	}

	/**
	 * Remove a revision descriptor.
	 *
	 * @param uri Uri
	 * @param revisionNumber Revision number
	 * @exception ServiceAccessException Service access error
	 */
	public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
		throws ServiceAccessException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - removeRevisionDescriptor");
		}
	}

	/**
	 * Initializes the data source with a set of parameters.
	 *
	 * @param parameters Hashtable containing the parameters' name
	 * and associated value
	 * @exception ServiceParameterErrorException Incorrect service parameter
	 * @exception ServiceParameterMissingException Service parameter missing
	 */
	public void setParameters(Hashtable parameters)
		throws ServiceParameterErrorException, ServiceParameterMissingException
	{
		if (Log.getLogger().isDebugEnabled())
		{
			Log.debug("TurbineDescriptorStore - setParamters");
		}
	}
}
