/**
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 - JASS: Java Advanced tranSaction Support
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 - This module was originally developed by 
 -
 -    LSD (Distributed Systems Lab, http://lsd.ls.fi.upm.es/lsd/lsd.htm)
 -    at Universidad Politecnica de Madrid (UPM) as an ObjectWeb Consortium
 -    (http://www.objectweb.org) project.
 -
 -    This project has been partially funded by the European Commission under
 -    the IST programme of V FP grant IST-2001-37126 and by the Spanish
 -    Ministry of Science & Technology (MCyT) grants TIC2002-10376-E and
 -    TIC2001-1586-C03-02
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -  The original code and portions created by LSD are 
 -  Copyright (c) 2004 LSD (UPM)  
 -  All rights reserved.
 -  
 - Redistribution and use in source and binary forms, with or without 
 - modification, are permitted provided that the following conditions are met:
 -
 - -Redistributions of source code must retain the above copyright notice, this
 - list of conditions and the following disclaimer. 
 -
 - -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. 
 -
 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 - AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -
 -  Author: Francisco Perez Sorrosal (frperezs)
 -
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/

package org.objectweb.jass.as;

import java.io.Serializable;

import javax.activity.ActivityCompletedException;
import javax.activity.ActivityCoordinator;
import javax.activity.ActivityManager;
import javax.activity.ActivityToken;
import javax.activity.GlobalId;
import javax.activity.InvalidActivityException;
import javax.activity.InvalidParentContextException;
import javax.activity.ServiceNotRegisteredException;
import javax.activity.SystemException;

import org.apache.log4j.Logger;

/**
 * Implements the extended AS access interface (ActivityManager) available to 
 * HLSs and container. Currently, it only implements the suspend/resume methods. 
 * @author fran
 * Date: Feb 16, 2004
 * org.objectweb.jass.asActivityManagerImpl.java
 */
public class ActivityManagerImpl
	extends UserActivityImpl
	implements ActivityManager, Serializable {

	private static Logger log = Logger.getLogger(ActivityManagerImpl.class);

	/**
	 * Default constructor.
	 */
	public ActivityManagerImpl() {
		super();

	}

	// ActivityManager implementation ------------------------------

	/**
	 * Suspends the association of the current Activity from the
	 * calling thread of execution along with any child Activities
	 * of the same ContextGroup nested within that Activity.
	 * If the suspended Activity is nested within a parent then the
	 * parent Activity becomes associated with the thread on
	 * completion of this method.
	 * @return An ActivityToken representing the suspended Activity.
	 * This ActivityToken maintains knowledge of the nested
	 * Activities and transactions that were suspended when the
	 * target Activity was suspended as well as any parent Activity
	 * that was established as a result of the suspend operation.
	 * The ActivityToken may be used on a subsequent call to resume
	 * but not to resumeAll or resumeGroup.
	 * If the calling thread is not associated with any Activity
	 * then null is returned.
	 * @throws ServiceNotRegisteredException - Thrown if no ServiceManager
	 * has been registered.
	 * @throws SystemException
	 */
	public ActivityToken suspend()
		throws ServiceNotRegisteredException, SystemException {

		ActivityContext context = null;

		ThreadInfo ti = getThreadInfo();
		ActivityImpl currentActivity = ti.activity;

		if (currentActivity != null) {
			ActivityCoordinator parent = currentActivity.getParent();

			log.debug(
				"SUSPEND: Disassociating activity "
					+ ti.activity.getName()
					+ " from thread "
					+ Thread.currentThread().toString());
			disassociateThread(ti);

			if (parent != null) {
				log.debug(
					"SUSPEND: Associating activity "
						+ parent.getName()
						+ " to thread "
						+ Thread.currentThread().toString());
				associateThread(ti, (ActivityImpl) parent);
				context =
					new ActivityContext(currentActivity, parent.getGlobalId());
			} else
				context = new ActivityContext(currentActivity, null);
		}

		return context;
	}

	/**
	 * Resumes the association of the Activity, and any nested
	 * Activities and transactions, represented by the
	 * ActivityToken with the calling thread of execution.
	 * The ActivityToken represents a hierarchy of one of more
	 * Activities and transactions and must have been obtained by
	 * a prior call to suspend. If there is an Activity
	 * associated with the thread prior to the method invocation
	 * then the re-associated Activity is resumed as a child of
	 * the Activity that is already on the thread. Any such
	 * parent Activity must be the same parent Activity within
	 * which the child Activity was originally begun.
	 * If the specified ActivityToken is null, then no new
	 * associated is made.
	 * @param activityToken - the ActivityToken to resume. The
	 * ActivityToken represents a hierarchy of one of more
	 * Activities and transactions and must have been obtained
	 * by a prior call to suspend.
	 * @throws InvalidActivityException - May be thrown if the
	 * specified ActivityToken was not obtained by a prior call
	 * to suspend or if the ActivityToken does not represent a
	 * valid Activity or Activity hierarchy. No new association
	 * is made.
	 * @throws InvalidParentContextException - Thrown if the
	 * parent Activity is different from that in which the resumed
	 * Activity was begun. No new association is made.
	 * @throws ServiceNotRegisteredException - Thrown if no ServiceManager
	 * has been registered.
	 * @throws SystemException
	 */
	public void resume(ActivityToken activityToken)
		throws
			InvalidActivityException,
			InvalidParentContextException,
			ServiceNotRegisteredException,
			SystemException {

		if (sm == null)
			throw new ServiceNotRegisteredException();
		if (activityToken == null)
			throw new InvalidActivityException();

		ActivityContext context = (ActivityContext) activityToken;

		ThreadInfo ti = getThreadInfo();
		ActivityImpl currentActivity = ti.activity;

		if (currentActivity != null) {
			if (!currentActivity.getGlobalId().equals(context.getParent()))
				throw new InvalidParentContextException();

			log.debug(
				"RESUME: Disassociating activity "
					+ ti.activity.getName()
					+ " from thread "
					+ Thread.currentThread().toString());
			disassociateThread(ti);
		}
		log.debug(
			"RESUME: Associating activity "
				+ context.getActivity().getName()
				+ " to thread "
				+ Thread.currentThread().toString());
		associateThread(ti, context.getActivity());
	}

	/**
	 * Not yet implemented.
	 */
	public ActivityToken suspendGroup()
		throws ServiceNotRegisteredException, SystemException {
		return null;
	}

	/**
	 * Not yet implemented.
	 */
	public void resumeGroup(ActivityToken activityToken)
		throws
			InvalidActivityException,
			InvalidParentContextException,
			ServiceNotRegisteredException,
			SystemException {
	}

	/**
	 * Not yet implemented.
	 */
	public ActivityToken suspendAll()
		throws ServiceNotRegisteredException, SystemException {
		return null;
	}
	
	/**
	 * Not yet implemented.
	 */
	public void resumeAll(ActivityToken activityToken)
		throws
			InvalidActivityException,
			InvalidParentContextException,
			ServiceNotRegisteredException,
			SystemException {
	}

	/**
	 * Not yet implemented.
	 */
	public GlobalId hibernate()
		throws
			ServiceNotRegisteredException,
			InvalidActivityException,
			SystemException {
		return null;
	}

	/**
	 * Not yet implemented.
	 */
	public void reactivate(GlobalId globalId)
		throws
			ActivityCompletedException,
			InvalidParentContextException,
			ServiceNotRegisteredException,
			SystemException {
	}

	// My Public -----------------------------------------------------

	// My Private ----------------------------------------------------

	// My Protected --------------------------------------------------

}
