You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by ad...@apache.org on 2006/02/28 17:35:26 UTC

svn commit: r381694 [33/38] - in /incubator/ode/scratch: bpe/ ode/ ode/bpelTests/ ode/bpelTests/probeService/ ode/bpelTests/test1/ ode/bpelTests/test10/ ode/bpelTests/test12/ ode/bpelTests/test13/ ode/bpelTests/test14/ ode/bpelTests/test15/ ode/bpelTes...

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPool.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPool.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPool.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPool.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.pool;
+
+import java.util.Properties;
+
+/**
+ * The interface for a generic object pool. Implemented
+ * by subclasses that want to take advantage of 
+ * pooling mechanisms.
+ * 
+ * @author Bill Flood
+ * @version 1.1
+ * @see ObjPoolObject
+ * @since 1.1
+ */
+public interface ObjPool {
+	/**
+	 * Get an object out of the pool.
+	 * 
+	 * @param factory    The factory used to create the pooled object.
+	 *                   This is not used internally other than to pass
+	 *                   it out to methods implemented by the user.
+	 * @param auth       A user-defined object that the user-implemented
+	 *                   methods will be supplied.  Not used internally
+	 *                   by the pooling code.
+	 * @param objectSpec A user-defined object that may be checked for
+	 *                   equality at some level of the pool to see if
+	 *                   we have an object that matches the specification.
+	 * @return 
+	 * @exception Exception If there is a problem checking something out of the pool.
+	 * @since 1.1
+	 */
+	public ObjPoolObject checkout(Object factory, Object auth, Object objectSpec) throws Exception;
+
+	/**
+	 * Put an object back into the pool.
+	 * 
+	 * @param object
+	 * @exception Exception
+	 * @since 1.1
+	 */
+	public void checkin(ObjPoolObject object) throws Exception;
+
+	/**
+	 *  Initialize the pool.
+	 * 
+	 * @param prop
+	 * @param factory    The factory used to create the pooled object.
+	 *                   This is not used internally other than to pass
+	 *                   it out to methods implemented by the user.
+	 * @param auth       A user-defined object that the user-implemented
+	 *                   methods will be supplied.  Not used internally
+	 *                   by the pooling code.
+	 * @param objectSpec A user-defined object that may be checked for
+	 *                   equality at some level of the pool to see if
+	 *                   we have an object that matches the specification.
+	 *                   
+	 *                   @exception Exception If there is a problem initializing the pool.
+	 * @exception Exception
+	 * @since 1.1
+	 */
+	public void init(Properties prop, Object factory, Object auth, Object objectSpec) throws Exception;
+
+	/**
+	 * Re-initialize the object pool.
+	 * 
+	 * @param factory    The factory used to create the pooled object.
+	 *                   This is not used internally other than to pass
+	 *                   it out to methods implemented by the user.
+	 * @param auth       A user-defined object that the user-implemented
+	 *                   methods will be supplied.  Not used internally
+	 *                   by the pooling code.
+	 * @param objectSpec A user-defined object that may be checked for
+	 *                   equality at some level of the pool to see if
+	 *                   we have an object that matches the specification.
+	 *                   
+	 *                   @exception Exception If there is a problem re-initializing the pool.
+	 * @exception Exception
+	 * @since 1.1
+	 */
+	public void reInitializeObjPool(Object factory, Object auth, Object objectSpec) throws Exception;
+
+	/**
+	 * Get the current number of objects that
+	 * have been checked out.
+	 * 
+	 * Valid only if we are monitoring.
+	 * 
+	 * @return 
+	 * @since 1.1
+	 */
+	public int getObjectsInUse();
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPoolObject.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPoolObject.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPoolObject.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/ObjPoolObject.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.pool;
+
+/**
+ * An object that's to be used within the context
+ * of an ObjPool.
+ * 
+ * @author Bill Flood
+ * @version 1.1
+ * @see ObjPool
+ * @since 1.1
+ */
+public interface ObjPoolObject {
+	/**
+	 *  Called when this object has expired or
+	 *  is otherwise not going to be re-used
+	 *  by the pool.
+	 */
+	public void deleteObjPoolObject();
+
+	/**
+	 *  Determines if this object should be
+	 *  put back in the pool or not.
+	 */
+	public boolean isObjPoolObjectValid();
+
+	/**
+	 *  This method is called after the object has been removed
+	 *  from the pool, and before it has been given to whoever
+	 *  is checking it out of the pool.
+	 */
+	public void beforeObjPoolObjectCheckout();
+
+	/**
+	 *  This method is called after an object has been checked
+	 *  back in, but before the <tt>isObjPoolObjectValid()</tt>
+	 *  method is called and before it is made available for
+	 *  checkout again.
+	 */
+	public void afterObjPoolObjectCheckin();
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/PoolException.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/PoolException.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/PoolException.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/PoolException.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+/*
+ * Created on Apr 25, 2003
+ *
+ */
+package org.apache.ode.pool;
+
+import org.apache.ode.util.BPException;
+
+/**
+ * @author waterman
+ *
+ */
+public class PoolException extends BPException {
+
+	static final long serialVersionUID = -3526923457667217863L;
+
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 */
+	public PoolException(String message_id, Object[] msgParams) {
+		super(message_id, msgParams);
+	}
+
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 * @param cause
+	 */
+	public PoolException(
+		String message_id,
+		Object[] msgParams,
+		Throwable cause) {
+		super(message_id, msgParams, cause);
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/SimpleObjPool.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/SimpleObjPool.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/SimpleObjPool.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/pool/SimpleObjPool.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.pool;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *  A minimal implementation of an ObjPool.
+ *  This class provides a non-growing pool that
+ *  sleeps the threads that are trying to check
+ *  something out of the pool, and wakes them
+ *  up in-order when something is checked back in.
+ *
+ *  @see ObjPool
+ */
+public abstract class SimpleObjPool implements ObjPool {
+	private List waiters = new ArrayList();
+	private List checkedOutObjects = new ArrayList();
+	protected Object sync = new Object();
+	private boolean monitorCheckedOutObjects = true;
+	
+	private static Logger logger = 
+			Logger.getLogger(SimpleObjPool.class.getName());
+
+	/**
+	 *  This method needs to be implemented by sub-classes.
+	 *  It should return the next element in the pool, or
+	 *  null if the pool is empty.  Growable implementations
+	 *  should use this method to add more elements to the
+	 *  pool.
+	 *
+	 *  @exception Exception If there is a problem getting the
+	 *   next object for the pool -- this is implementation specific.
+	 */
+	protected abstract ObjPoolObject getNextPoolObject(Object factory, Object auth, Object objectSpec) throws PoolException;
+
+	/**
+	 *  This method needs to be implemented by sub-classes.
+	 *  It should add the given ObjPoolObject to the pool.
+	 *
+	 *  @exception Exception If there is a problem checking in the
+	 *   object -- this is implementation specific.
+	 */
+	protected abstract void checkinPoolObject(ObjPoolObject o) throws PoolException;
+
+	/**
+	 *  This method needs to be implemented by sub-classes.
+	 *  It should remove the given ObjPoolObject from the pool or
+	 *  mark it as in use.
+	 *
+	 *  @exception Exception If there is a problem checking in the
+	 *   object -- this is implementation specific.
+	 */
+	protected abstract void checkoutPoolObject(ObjPoolObject o) throws PoolException;
+
+	/**
+	 *  To be implemented by sub-classes.  This is a factory
+	 *  method for creating objects that go in this pool.
+	 *
+	 *  @exception Exception If there is a problem creating the next object for the pool -- this is implementation specific.
+	 */
+	protected abstract ObjPoolObject createObjPoolObject(Object factory, Object auth, Object objectSpec) throws PoolException;
+
+
+	/**
+	 *  Initialize the object pool.  Checked out
+	 *  objects will be monitored.
+	 */
+	public SimpleObjPool() {
+		this(true);
+	}
+
+	/**
+	 *  Initialize the object pool.  Checked out
+	 *  objects will be monitored if monitorCheckedOutObjects
+	 *  is true.
+	 */
+	public SimpleObjPool(boolean monitorCheckedOutObjects) {
+		super();
+		this.monitorCheckedOutObjects = monitorCheckedOutObjects;
+	}
+
+	/**
+	 *  Get a reference to the object being used
+	 *  as a synchronization lock.  Subclasses that
+	 *  need to lock the operation of the pool while
+	 *  they perform maintenance should synchronize
+	 *  on this object and then manipulate the pool.
+	 */
+	protected Object getSyncObject() {
+		return this.sync;
+	}
+
+	/**
+	 *  Get the number of threads waiting for an object to become available.
+	 */
+	public int getNumWaiters() {
+		return this.waiters.size();
+	}
+
+	/**
+	 *  Get the number of objects that are currently checked out.
+	 */
+	public int getObjectsInUse() {
+		return this.checkedOutObjects.size();
+	}
+
+	/**
+	 * Add a thread to the queue of threads waiting for the shared object.
+	 * If, for some reason, the thread is already in the queue, then this
+	 * call will be ignored --- the thread can only be in the queue once
+	 * via this method.
+	 */
+	private final void addToWaiters(Thread t) {
+		synchronized (waiters) {
+			if (!waiters.contains(t)) {
+				waiters.add(t);
+				//Syslog.debug(this, "Adding waiter " + t);
+			}
+		}
+	}
+
+	/**
+	 *  Get the next thread in line and remove it from the waiters.
+	 */
+	private final Thread getNextWaiter() {
+		synchronized (waiters) {
+			if (waiters.size() != 0)
+				return(Thread)waiters.remove(0);
+			return null;
+		}
+	}
+
+	/**
+	 *  Implements a first in, first out reservation scheme.  If no
+	 *  threads are waiting for the object, then the caller never blocks.
+	 *  If there are waiters, then the caller "get's in line," and waits
+	 *  for their turn with the object.
+	 *
+	 *  @exception Exception If there is a problem checking an object out of the pool.
+	 */
+	public ObjPoolObject checkout(Object factory, Object auth, Object objSpec) throws PoolException
+	{
+		Thread thread = Thread.currentThread();
+
+		ObjPoolObject obj = null;
+		while (true) { // mmmm.... infinity
+			synchronized (sync) {
+				obj = getNextPoolObject(factory, auth, objSpec); // can throw exception
+
+				if (obj != null) {
+					obj.beforeObjPoolObjectCheckout();
+					checkoutPoolObject(obj);
+					if (monitorCheckedOutObjects)
+						checkedOutObjects.add(obj);
+					return obj;
+				}
+			}
+
+			// if we got here it's because we didn't get
+			// anything from the pool.  We'll just wait
+			// till someone wakes us up and give it another
+			// try.
+			synchronized (thread) {
+				addToWaiters(thread);
+				try {
+					thread.wait();
+				}catch (InterruptedException e) {
+					PoolException pe = new PoolException("NATIVE_EXECEPTION",new Object[] {"InterruptedException"},e);
+					pe.log(logger,Level.SEVERE);
+					throw pe;
+				}
+			}
+		}
+	}
+
+	/**
+	 *  Check an object back into the pool.  If there are
+	 *  threads in the wait queue, the thread that has been waiting
+	 *  longest will get the shared object next.  The waiter may not receive
+	 *  the shared object immediately, however.
+	 *
+	 *  @exception Exception If there was a problem checking in the object.
+	 */
+	public void checkin(ObjPoolObject opo) throws PoolException
+	{
+		opo.afterObjPoolObjectCheckin();
+		synchronized(sync) {
+			try {
+				if (opo.isObjPoolObjectValid())
+					checkinPoolObject(opo);	// can throw Exception
+				else
+					opo.deleteObjPoolObject();
+			}
+			finally {
+				// make sure to remove it from the list of
+				// checked out objects.
+				if (monitorCheckedOutObjects)
+					this.checkedOutObjects.remove(opo);
+
+				// wake up the next guy in line.
+				Thread waiter = getNextWaiter();
+				if (waiter != null) {
+					synchronized (waiter) {
+						waiter.notify();
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 *  Get the list of objects that are currently checked out of the pool.
+	 */
+	protected List getCheckedOutObjects() {
+		return this.checkedOutObjects;
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/BPRuntimeException.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/BPRuntimeException.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/BPRuntimeException.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/BPRuntimeException.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.scope.service;
+
+import java.util.HashMap;
+
+import org.apache.ode.action.internal.ActionException;
+
+/**
+ *
+ * All runtime exceptions should throw this
+ * 
+ */
+public class BPRuntimeException extends ActionException {
+	
+	static final long serialVersionUID = -3191176170122334709L;
+	
+	private String faultName;
+	private String faultType;
+	private String nameSpace;
+	private HashMap errorMessage = new HashMap();
+	
+	public BPRuntimeException( String name, String detailMessage )
+	{
+	    super( detailMessage );
+	    faultName = name;
+	}
+	
+	public BPRuntimeException( String name, Throwable cause)
+	{
+	    super( cause );
+	    faultName = name;
+	}
+	
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 */
+	public BPRuntimeException(String name, String message_id, Object[] msgParams) {
+		super(message_id, msgParams);
+		faultName = name;
+	}
+
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 * @param cause
+	 */
+	public BPRuntimeException(
+		String name,
+		String message_id,
+		Object[] msgParams,
+		Throwable cause) {
+		super(message_id, msgParams, cause);
+		faultName = name;
+	}
+
+	public String getBPException() {
+		String retVal = faultName;
+		if ( nameSpace != null ) {
+			retVal = nameSpace + ":" + faultName;
+		}
+		return retVal;
+	}
+
+	public void addPartMessage(String partName, Object msg) {
+		errorMessage.put(partName,msg);
+	}
+	
+	public Object getPartMessage(String partName) {
+		return errorMessage.get(partName);
+	}
+	
+	public HashMap getMessageParts() {
+		return errorMessage;
+	}
+	
+	public void setNameSpace(String nameSpace) {
+		this.nameSpace = nameSpace;
+	}
+	
+	public String getNameSpace()
+	{
+		return this.nameSpace;
+	}
+
+	public String getName()
+	{
+		return faultName;
+	}
+	public String getType() {
+		return faultType;
+	}
+	
+	public String toString() {
+		return "BPRuntimeException(nameSpace:"+this.nameSpace+
+			" faultName:"+this.faultName+
+			" fualtType:"+this.faultType+")";
+	}
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IFCScopeInstance.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IFCScopeInstance.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IFCScopeInstance.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IFCScopeInstance.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.scope.service;
+
+import java.util.List;
+
+import org.apache.ode.action.bpel.TimerAction;
+import org.apache.ode.context.resolver.ContextResolver;
+import org.apache.ode.correlation.Registration;
+import org.apache.ode.definition.IPMDProcess;
+import org.apache.ode.engine.IEvaluationContext;
+import org.apache.ode.engine.IProcessCallBack;
+import org.apache.ode.instance.IPMIProcess;
+import org.apache.ode.timerservice.IBPETimer;
+import org.apache.ode.util.BPException;
+
+/**
+ * This is a scope instance which is stored in the scope
+ * service.
+ */
+public interface IFCScopeInstance {
+	
+	public final static String CATCH_ALL = "catchAll";
+	public final static String BPWS_NS = "http://schemas.xmlsoap.org/ws/2003/03/business-process/";
+	public final static String FORCED_TERMINATION = BPWS_NS+":forcedTermination";
+	public final static String CURRENT_FAULT = "currentFault";
+	public final static String CURRENT_EXCEPTION = "currentException";
+	public final static String FAULT_HANDLER = "faultHandler";
+	public final static String COMP_HANDLER = "compensatinHandler";
+	public final static String PROCESS = "process";
+	
+	/**
+	 * Create a new scope instance
+	 * @param scopePath the scope path in which to create this scope
+	 * @param newScopeName the new scope's name
+	 * @param newScopeId the new scope's id
+	 * @param ctxId the context id in which this scope executes
+	 * @return a scope instance
+	 * @throws BPException
+	 */
+	public IFCScopeInstance createScope(String newScopeName, String newScopeId, 
+			String ctxId) throws BPException;
+
+	
+	/**
+	 * Add a fault handler to the scope instance.
+	 * @param faultName then fault to catch
+	 * @param faultType the fault type to catch
+	 * @param defintionId the defintion that is executed for handling
+	 * @throws BPException
+	 */
+	public void addFaultHandler(String faultName, String faultType, String defintionId) throws BPException;
+	
+	/**
+	 * After a fault handler executes for this scope instance
+	 * execution will pick up at this specified point.
+	 * @param defintionId defintion where execution picks up
+	 * @throws BPException
+	 */
+	public void setFaultHandlerObserver(String defintionId) throws BPException;
+
+	/**
+	 * When the execution point for the compensation handler for this
+	 * scope is installed a snap shot of the current state will also
+	 * be taken.
+	 * @param defintionId defintion where compensation processing starts
+	 * @param locators list of locators to capture for compenstaion
+	 * @param resolver resolver used for building snap shot
+	 * @param ctx id to hang the compensation snap shot off of in context
+	 * @throws BPException
+	 */
+	public void setCompensationHandler(String defintionId, List locators, 
+			ContextResolver resolver, String ctxId) throws BPException;
+	
+	/**
+	 * Mark this process as inactive.
+	 * @param proc where compensation was called
+	 * @param ec evaluation context to run compensation in
+	 * @param pcb process call back
+	 */
+	public void setInactive(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb)  throws BPException;
+	/**
+	 * 
+	 * @return is this scope active
+	 */
+	public boolean isActive();
+	
+	/**
+	 * 
+	 * @return has this scope been faulted
+	 */
+	public boolean isFaulted();
+	
+	/**
+	 * 
+	 * @return has this scope been compensated
+	 */
+	public boolean isCompensated();
+	
+	/**
+	 * Add a process that needs to be cleaned up
+	 * after the scope completes.
+	 * @param proc
+	 */
+	public void addProcess(IPMIProcess proc);
+	
+	/**
+	 * Add a registration to this scope.  Registrations are canceled
+	 * when an active scope is terminated.
+	 * @param registration 
+	 */
+	public void addRegistration(Registration registration);
+	
+	/**
+	 * Remove a registation from this scope.
+	 * @param registration
+	 */
+	public void removeRegistration(Registration registration);
+	
+	/**
+	 * Add a timer to this scope.  Timers are canceled when an 
+	 * active scope is terminated.
+	 * @param timer
+	 */
+	public void addTimer(IBPETimer timer);
+	
+	/**
+	 * Remove a timer from this scope
+	 * @param timer
+	 */
+	public void removeTimer(IBPETimer timer);
+	
+	/**
+	 * Get the fully qualified scope path.
+	 * @return scope path
+	 */
+	public ScopePath getScopePath();
+	
+	/**
+	 * Handle a fault thrown with this scope.
+	 * @param exception the runtime exception thrown
+	 * @param proc where fault was  thrown
+	 * @param ec evaluation context to run fault handling in
+	 * @param pcb process call back
+	 * @throws BPException
+	 */
+	public void handleFault(Throwable exception, IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException;
+	
+	/**
+	 * Terminate all active scopes enclosed in this scope.
+	 * @param proc where termination was called
+	 * @param ec evaluation context to termination in
+	 * @param pcb process call back
+	 * @throws BPException
+	 */
+	public void terminate(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException;
+	
+	/**
+	 * Compensate this scope.  
+	 * @param proc where compensation was called
+	 * @param ec evaluation context to run compensation in
+	 * @param pcb process call back
+	 * @throws BPException
+	 */
+	public void compensate(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException;
+	
+	/**
+	 * This is used to capture a onAlarm at the root scope that
+	 * uses data from an incoming message to register a timer.  This
+	 * is a special case.
+	 * @param act
+	 * @param resolver
+	 * 
+	 */
+	public void setTimerAction(TimerAction act,ContextResolver resolver);
+	
+	/**
+	 * Execute the timer action.
+	 * @param ec
+	 * @param pcb
+	 * @param processInstance
+	 * @param processDefinition
+	 * @return
+	 */
+	public void executeTimerAction(IEvaluationContext ec,
+			IProcessCallBack pcb,
+			IPMIProcess processInstance,
+			IPMDProcess processDefinition) throws BPException;
+
+}
+

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IScopeService.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IScopeService.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IScopeService.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/IScopeService.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.scope.service;
+
+import org.apache.ode.context.IContextService;
+import org.apache.ode.engine.IEvaluationContext;
+import org.apache.ode.engine.IProcessCallBack;
+import org.apache.ode.instance.IPMIProcess;
+import org.apache.ode.util.BPException;
+
+/**
+ * Service which manages scope instances.
+ */
+public interface IScopeService {
+	
+	/**
+	 * Initialize the scope service.
+	 * @param cs the scope service state is stored in the context service
+	 * @param ctxId the element id to hang the scope data structure off of
+	 * in the context tree
+	 * @throws BPException
+	 */
+	public void init(IContextService cs, String ctxId) throws BPException;
+	
+	/**
+	 * Get the root scope.
+	 * @return
+	 * @throws BPException
+	 */
+	public IFCScopeInstance getRootScope() throws BPException;
+		
+	/**
+	 * Get a scope instance.
+	 * @param scopePath  the fully qualified scope path
+	 * @return the scope instance
+	 * @throws BPException
+	 */
+	public IFCScopeInstance getScope(ScopePath scopePath) throws BPException;
+
+	/**
+	 * Compensate a given scope based on a design time scope path.  This will
+	 * compensate all instances of that design time scope path.
+	 * @param scopeName this is a design time scope name, so all scopes with 
+	 * this scope name will be compensated
+	 * @param proc where fault was  thrown
+	 * @param ec evaluation context to run fault handling in
+	 * @param pcb process call back
+	 * @throws BPException
+	 */
+	public void compensate(String scopeName, IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException;
+	
+
+}
+

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopePath.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopePath.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopePath.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopePath.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.scope.service;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Scope path.
+ */
+public class ScopePath implements Serializable, Cloneable {
+	
+    static final long serialVersionUID = 4835994200408519001L;
+    
+	public static final transient String DELIMITER = "/";
+	private ArrayList scopePath;
+	
+	public ScopePath() {
+		scopePath = new ArrayList();
+	}
+	
+	private ScopePath(ArrayList scopePath) {
+		this.scopePath = scopePath;
+	}
+	
+	private ScopePath ( List list ) {
+		this.scopePath = new ArrayList(list);
+	}
+	
+	/**
+	 * Add a new scope to this path.
+	 * @param scopeName design time scope name
+	 * @param scopeId runtime scope id
+	 * @return this scope path
+	 */
+	public ScopePath addScope(String scopeName, String scopeId) {
+		scopePath.add(new ScopeNameId(scopeName,scopeId));
+		return this;
+	}
+	
+	/**
+	 * Get the current scope name.
+	 * @return the current scope name
+	 */
+	public String getCurrentScope() {
+		if ( scopePath.size() < 1 ) {
+			return "";
+		} else {
+			return ((ScopeNameId)scopePath.get(scopePath.size()-1)).getName();
+		}	
+	}
+	
+	/**
+	 * Get the enclosing scope path.
+	 * @return enclosing scope path
+	 */
+	public ScopePath getEnclosingScopePath() {
+		if ( scopePath.isEmpty() ) {
+			return this;
+		} else {
+			return new ScopePath(this.scopePath.subList(0,this.scopePath.size()-1));
+		}
+	}
+	
+	/**
+	 * Returns the scope path sans the scope ids.
+	 * @return
+	 */
+	public String getScopeNamePath() {
+		if ( scopePath.isEmpty() ) {
+			return DELIMITER;
+		}
+		String path = "";
+		Iterator it = scopePath.iterator();
+		while ( it.hasNext() ) {
+			ScopeNameId sni= (ScopeNameId)it.next();
+			path+=DELIMITER.concat(sni.getName());
+		}
+		return path;
+	}
+	
+	/**
+	 * Apply this ScopePath to a design time scope path which doesn't have
+	 * scope ids.
+	 * @param path path to apply this scope to
+	 * @return new path
+	 */
+	public String applyPathIdsToPath(String path) {
+
+		// if this is a relative path just return it
+		if ( !path.startsWith(DELIMITER)) {
+			return path;
+		}
+		
+		String newPath = "";
+		String[] pathArray = path.split(DELIMITER);
+		for ( int i = 1; i < pathArray.length ; i++ ) 
+		{
+			if ( i <= scopePath.size() && pathArray[i].equals(
+					((ScopeNameId)scopePath.get(i-1)).getName())) {
+				newPath+=DELIMITER.concat(
+						((ScopeNameId)scopePath.get(i-1)).getNameId());
+			} else {
+				for ( int j = i; j < pathArray.length; j++) {
+					newPath+=DELIMITER.concat(pathArray[j]);
+				}
+				break;
+			}
+		}
+		return newPath;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		if ( scopePath.isEmpty() ) {
+			return DELIMITER;
+		}
+		String path = "";
+		Iterator it = scopePath.iterator();
+		while ( it.hasNext() ) {
+			ScopeNameId sni= (ScopeNameId)it.next();
+			path+=DELIMITER.concat(sni.getNameId());
+		}
+		return path;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if ( obj instanceof ScopePath ) {
+			return obj.toString().equals(this.toString());
+		} else {
+			return false;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#clone()
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return new ScopePath((ArrayList)scopePath.clone());
+	}
+	
+	public static void main(String[] args) {
+		ScopePath sp = new ScopePath();
+		sp.addScope("a","1");
+		sp.addScope("b","1");
+		sp.addScope("c","1");
+		sp.addScope("d","1");
+		System.out.println(sp);
+		System.out.println(sp.getCurrentScope());
+		System.out.println(sp.getEnclosingScopePath());
+		ScopePath sp2 = new ScopePath();
+		sp2.addScope("a","1");
+		sp2.addScope("b","1");
+		sp2.addScope("c","1");
+		sp2.addScope("d","1");
+		System.out.println(sp.equals(sp2));
+		System.out.println(sp2.applyPathIdsToPath("/container/part"));
+		System.out.println(sp2.applyPathIdsToPath("/a/container/part"));
+		System.out.println(sp2.applyPathIdsToPath("/a/b/c/container/part"));
+		System.out.println(sp2.applyPathIdsToPath("/c/d/container/part"));
+		System.out.println(sp.getScopeNamePath());
+		ScopePath sp3 = new ScopePath();
+		sp3.addScope("scope_0","12345");
+		System.out.println(sp3.applyPathIdsToPath("/scope_0/request/message"));
+		System.out.println(sp3.applyPathIdsToPath("junk"));
+		ScopePath sp4 = new ScopePath();
+		sp4.addScope("a","1");
+		System.out.println(sp4.getEnclosingScopePath());
+
+	}
+	
+	
+	private class ScopeNameId implements Serializable {
+		
+	    static final long serialVersionUID = -5709053091263193526L;
+	    
+		private String name;
+		private String id;
+		
+		public ScopeNameId(String name, String id) {
+			this.name = name;
+			this.id = id;
+		}
+		
+		public String getNameId() {
+			return name.concat(id);
+		}
+		
+		/**
+		 * @return Returns the id.
+		 */
+		public String getId() {
+			return id;
+		}
+		/**
+		 * @param id The id to set.
+		 */
+		public void setId(String id) {
+			this.id = id;
+		}
+		/**
+		 * @return Returns the name.
+		 */
+		public String getName() {
+			return name;
+		}
+		/**
+		 * @param name The name to set.
+		 */
+		public void setName(String name) {
+			this.name = name;
+		}
+
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceException.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceException.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceException.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceException.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.scope.service;
+
+import org.apache.ode.util.BPException;
+
+/**
+ * @author charper
+ *
+ * 
+ * 
+ */
+public class ScopeServiceException extends BPException {
+	
+
+	static final long serialVersionUID = -7777563832523244653L;
+
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 */
+	public ScopeServiceException(String message_id, Object[] msgParams) {
+		super(message_id, msgParams);
+	}
+
+	/**
+	 * @param message_id
+	 * @param msgParams
+	 * @param cause
+	 */
+	public ScopeServiceException(
+		String message_id,
+		Object[] msgParams,
+		Throwable cause) {
+		super(message_id, msgParams, cause);
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceFactory.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceFactory.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceFactory.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/ScopeServiceFactory.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.scope.service;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.ode.context.IContextService;
+import org.apache.ode.util.BPEProperties;
+import org.apache.ode.util.BPException;
+
+/** Creates a ScopeService implementation from a set of properties.
+  * <P>
+  * A ScopeService is an abstraction over a  repository that will store 
+  * scoping information
+  */
+public class ScopeServiceFactory
+{
+	
+	private static Logger logger = 
+		Logger.getLogger(ScopeServiceFactory.class.getName());
+
+	private static Class defClass;
+	
+   /** Get a scope service.
+	 * 
+	 * @param properties */
+   public static IScopeService createScopeService(IContextService cs, 
+	String containerId, BPEProperties props) throws BPException   {
+  	  
+	  IScopeService ss = null;
+   	
+		try {
+			
+			if ( defClass == null ) {
+				// load the implementation
+				defClass = java.lang.Class.forName(props.getScopeServiceClass());
+			}
+			
+			// try to instantiate the subclass
+			ss = (IScopeService) defClass.newInstance();
+			ss.init(cs, containerId);
+			
+		} catch (ClassNotFoundException e) {
+			ScopeServiceException bpx = new ScopeServiceException("CLASS_NOT_FOUND",new Object[] {props.getScopeServiceClass()});
+			bpx.log(logger,Level.SEVERE);
+			throw bpx;
+		} catch (InstantiationException e) {
+			ScopeServiceException bpx = new ScopeServiceException("NATIVE_EXCEPTION",new Object[] {"InstantiationException"},e);
+			bpx.log(logger,Level.SEVERE);
+			throw bpx;
+		} catch (IllegalAccessException e) {
+			ScopeServiceException bpx = new ScopeServiceException("NATIVE_EXCEPTION",new Object[] {"IllegalAccessException"},e);
+			bpx.log(logger,Level.SEVERE);
+			throw bpx;
+		}	
+      
+	  return ss;
+	
+   }
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/FCScopeInstanceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/FCScopeInstanceImpl.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/FCScopeInstanceImpl.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/FCScopeInstanceImpl.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,765 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.ode.scope.service.impl;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.ode.action.bpel.TimerAction;
+import org.apache.ode.context.IContainer;
+import org.apache.ode.context.IContextService;
+import org.apache.ode.context.IPart;
+import org.apache.ode.context.resolver.ContextResolvedObject;
+import org.apache.ode.context.resolver.ContextResolver;
+import org.apache.ode.correlation.CorrelationService;
+import org.apache.ode.correlation.Registration;
+import org.apache.ode.definition.IPMDLocator;
+import org.apache.ode.definition.IPMDProcess;
+import org.apache.ode.engine.IEvaluationContext;
+import org.apache.ode.engine.IProcessCallBack;
+import org.apache.ode.engine.ProcessDefinitionKey;
+import org.apache.ode.engine.ProcessInstance;
+import org.apache.ode.engine.StateEnum;
+import org.apache.ode.event.StateEvent;
+import org.apache.ode.instance.IPMIProcess;
+import org.apache.ode.instance.service.InstanceService;
+import org.apache.ode.lang.ResourceGetter;
+import org.apache.ode.scope.service.BPRuntimeException;
+import org.apache.ode.scope.service.IFCScopeInstance;
+import org.apache.ode.scope.service.ScopePath;
+import org.apache.ode.timerservice.BPETimerServiceFactory;
+import org.apache.ode.timerservice.IBPETimer;
+import org.apache.ode.timerservice.IBPETimerService;
+import org.apache.ode.util.BPException;
+
+/**
+ *
+ */
+public class FCScopeInstanceImpl implements IFCScopeInstance, Serializable {
+	
+    static final long serialVersionUID = -810005833715560330L;
+	
+	private static Logger logger = 
+		Logger.getLogger(FCScopeInstanceImpl.class.getName());
+	
+	// scope path for this scope
+	private ScopePath scopePath;
+	// when scope is created it is active
+	private boolean active = true;
+	// when scope is created it has not been faulted
+	private boolean faulted = false;
+	// when a scope is create it has not been compensated
+	private boolean compensated = false;
+	// index fault proc defs by name
+	private HashMap faultsByName = new HashMap();
+	// ndex fault proc defs bytype
+	private HashMap faultsByType = new HashMap();
+	// ndex fault proc defs by name and type
+	private HashMap faultsByNameType = new HashMap();
+	// proc def to run after fault hanlder is run
+	private String faultObserver;
+	// proc def for compensation handler
+	private String compensationHandler;
+	// context container id for compensation snap shot
+	private String compenstationCtxId;
+	// contxt id that this scope executes in
+	private String ctxId;
+	// registrations made in this scope
+	private ArrayList receives = new ArrayList();
+	// timers registered in this scope
+	private ArrayList timers = new ArrayList();
+	// processes that need to be cleaned up after scope completes
+	// HashSet so we don't get dups
+	private HashSet procs = new HashSet();
+	// this scopes parent
+	private FCScopeInstanceImpl parentScope;
+	// this scopes children
+	private HashMap childrenScopes = new HashMap();
+	// this scopes completed children ordered by completion
+	private ArrayList completedChildrenScopes = new ArrayList();
+	// index to all scopes
+	private HashMap allScopes;
+	// timer action stuff for special case
+	private transient TimerAction act;
+	private transient ContextResolver resolver;
+	private ScopePath _sp;
+	
+	// this flag is set if this scope is 
+	// executing a faultHanlder, this flag is not
+	// set if this scope is in a fault handler
+	private boolean executingFaultHandler = false;
+	
+	// this is used to instantiate the root scope
+	protected FCScopeInstanceImpl() {
+		allScopes = new HashMap();
+		this.scopePath = new ScopePath();
+		allScopes.put(this.scopePath.toString(),this);
+	}
+	
+	private FCScopeInstanceImpl(ScopePath scopePath, String newScopeName,
+			String newScopeId, String ctxId, FCScopeInstanceImpl parentScope, HashMap allScopes) {
+		try {
+			this.scopePath = (ScopePath)scopePath.clone();
+		} catch (CloneNotSupportedException e) {
+			// this shouldn't happen
+			this.scopePath = scopePath;
+		}
+		this.ctxId = ctxId;
+		this.scopePath.addScope(newScopeName,newScopeId);
+		this.parentScope = parentScope;
+		parentScope.addChildScope(this);
+		this.allScopes = allScopes;
+		this.allScopes.put(this.scopePath.toString(),this);
+	}
+	
+	protected FCScopeInstanceImpl getParentScope() {
+		return parentScope;
+	}
+	
+	protected List getCompletedChildrenScopes() {
+		return completedChildrenScopes;
+	}
+	
+	private void addChildScope(FCScopeInstanceImpl childScope) {
+		childrenScopes.put(childScope.getScopePath().toString(),childScope);
+	}
+	
+	private void addCompletedChiledScope(FCScopeInstanceImpl scope) {
+		completedChildrenScopes.add(scope);
+	}
+	
+	protected IFCScopeInstance getScope(ScopePath scopePath) {
+		return (IFCScopeInstance)this.allScopes.get(scopePath.toString());
+	}
+	
+	protected HashMap getScopes() {
+		return allScopes;
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#createScope(java.lang.String, java.lang.String)
+	 */
+	public IFCScopeInstance createScope(String newScopeName, String newScopeId, String ctxId) throws BPException {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Creating new " + 
+					newScopeName+newScopeId + " scope in: " + this.scopePath);
+		}
+		return new FCScopeInstanceImpl(this.scopePath, newScopeName, newScopeId, ctxId, this, this.allScopes);
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#addFaultHandler(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void addFaultHandler(String faultName, String faultType,
+			String defintionId) throws BPException {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Adding fault handler for scope:" + 
+					scopePath + " name: " + faultName +
+					" faultType: " + faultType + " defid: " + defintionId);
+		}
+		if ( faultName != null ) {
+			faultsByName.put(faultName,defintionId);
+		}
+		if ( faultType != null ) {
+			faultsByType.put(faultType,defintionId);
+		}
+		if ( faultType != null && faultName != null ) {
+			faultsByNameType.put(faultName+faultType,defintionId);
+		}
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#setFaultHandlerObserver(java.lang.String, org.apache.ode.context.resolver.ContextResolver, org.apache.ode.engine.IEvaluationContext)
+	 */
+	public void setFaultHandlerObserver(String defintionId) throws BPException {
+		faultObserver = defintionId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#setCompensationHandler(java.lang.String, org.apache.ode.context.resolver.ContextResolver, org.apache.ode.engine.IEvaluationContext)
+	 */
+	public void setCompensationHandler(String defintionId, List locators,
+			ContextResolver resolver, String ctxId ) throws BPException {
+		
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Creating compensation snap shot for " + this.scopePath + 
+					" defid :" + defintionId +
+					" snap shot context: " + ctxId);
+		}
+		
+		compensationHandler = defintionId;
+		compenstationCtxId = ctxId;
+		
+		IContextService cs = resolver.getContextService();
+		IContainer rootCont = cs.getRoot();
+		IContainer snapShot = rootCont.createContainer(compenstationCtxId);
+		
+		// for each locator creat path in snap shot context
+		//Iterator it = resolver.getLocatorHolder().getLocators();
+		Iterator it = locators.iterator();
+		while ( it.hasNext() ) {		
+			
+			IPMDLocator loc  = (IPMDLocator)it.next();
+			String path[] = this.scopePath.applyPathIdsToPath(
+					loc.getPath()).split(ScopePath.DELIMITER); 
+			IContainer cont = snapShot;
+			for ( int i = 1; i < path.length - 1 ; i++ ) {
+				if ( logger.isLoggable(Level.FINE)) {
+					logger.fine("Created snap shot container("+
+							compenstationCtxId+"):"+path[i]);
+				}
+				cont = cont.createContainer(path[i]);
+			}
+			ContextResolvedObject from =
+				(ContextResolvedObject) resolver.resolveWithOutInvocation(loc);
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Copying snap shot part("+
+						compenstationCtxId+"):"+path[path.length-1]);
+			}
+			cont.copyNode(from.getContextNode(), path[path.length-1]);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#setInactive()
+	 */
+	public void setInactive(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException {
+		
+		// this process could have already been deactivated
+		if ( active ) {
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Deactivating scope:" + this.scopePath);
+			}
+			
+			active = false;
+			// inactive scopes should not have any register timers or receives
+			cleanUp(pcb);
+			if ( this.parentScope != null ) {
+				this.parentScope.addCompletedChiledScope(this);
+			}
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#isActive()
+	 */
+	public boolean isActive() {
+		return active;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#isFaulted()
+	 */
+	public boolean isFaulted() {
+		return faulted;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#isCompensated()
+	 */
+	public boolean isCompensated() {
+		return compensated;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#addRegistration(org.apache.ode.correlation.Registration)
+	 */
+	public void addRegistration(Registration registration) {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Adding registration for scope:" + this.scopePath +
+					" registration: " + registration);
+		}
+		receives.add(registration);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#addTimer(org.apache.ode.timerservice.IBPETimer)
+	 */
+	public void addTimer(IBPETimer timer) {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Adding timer for scope:" + this.scopePath + 
+					" timer: " + timer);
+		}
+		timers.add(timer);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#getScopePath()
+	 */
+	public ScopePath getScopePath() {
+		return scopePath;
+	}
+	
+	
+	private String getFaultHandler(String faultName, String faultType, 
+			Throwable t) {
+		
+		// the following implements the fault processing described in the
+		// BPEL specification
+		
+		String faultHandler = null;
+		// if no faulType, meaning no fault data, match on faultName
+		if ( faultType == null ) {
+			
+			if ( faultName != null ) {
+				faultHandler = (String)faultsByName.get(faultName);
+			}
+
+		// if faultType, meaning there is fault data, match on faultName
+		// and faultType
+		} else {
+			// is there a faultName/faultType match
+			
+			if ( faultName != null && faultType != null  ) {
+				faultHandler = (String)faultsByNameType.get(faultName+faultType);
+			}
+			
+			if ( faultHandler == null ) {
+				// look by faultName
+				if ( faultName != null ) {
+					faultHandler = (String)faultsByName.get(faultName);
+				}
+				if ( faultHandler == null ) {
+					// look by faultType
+					if ( faultType != null ) {
+						faultHandler = (String)faultsByType.get(faultType);
+					}
+				}
+			}
+			
+		} 
+		
+		// we don't want to return a catch all if this is a forced termination
+		if ( faultHandler == null && faultName != FORCED_TERMINATION) {
+			// we still have not found a handler, so look for
+			// the catchAll
+			faultHandler = (String)faultsByName.get(CATCH_ALL);
+			
+			if ( faultHandler != null && faultName == null 
+					&& faultType == null ) {
+				// we are catching all non BPEL spec defined
+				// errors with catch all so we'll dump the error
+				// to the log
+				if ( logger.isLoggable(Level.WARNING)) {
+					logger.log(Level.WARNING,ResourceGetter.getString("NON_BPEL_CATCHALL"), t);
+				}
+			}
+		}	
+		return faultHandler;
+		
+	}
+	
+	private void executeProcess(String procId, IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException {
+		
+		IPMDProcess def = ec.getProcessService().getInstanceService().getDefinitionService().getProcessDefintion(
+				new ProcessDefinitionKey(procId),proc.getDefinition().getRootKey());
+				
+		ProcessInstance pi = ec.getProcessService().createSubProcess(proc,def);
+		
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine( "Executing process:" + pi.getKey() + "(Parent:" +
+					proc.getKey() + ")");
+		}
+
+		// Send a Start event to the fault handler process instance
+		pi.processEvent(
+			new StateEvent(pi.getRootKey(),pi.getKey(), StateEnum.STARTED),
+			ec, pcb);
+	}
+	
+	private void reThrow(Throwable t) throws BPException 
+	{
+		if ( t instanceof BPException ) {
+			throw (BPException)t;
+		} else if ( t instanceof Error ) {
+			throw (Error)t;
+		} else if ( t instanceof RuntimeException ) {
+			throw (RuntimeException)t;
+		} else {
+			// checked exceptions other than
+			// BPException shouldn't ever get here
+			throw new RuntimeException(t);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#handleFault(org.apache.ode.scope.service.BPRuntimeException, org.apache.ode.engine.IEvaluationContext)
+	 */
+	public void handleFault(Throwable exception, IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb)
+			throws BPException {
+		
+		// set the execution context to fault hanlder
+		// if we are executing in a fault context, this whould
+		// be the case if a fault is thrown from a scope created
+		// inside a fault handler
+		if ( executingFaultHandler ) {
+			proc.setExecutionContext(FAULT_HANDLER);
+		}
+		
+		if (_sp != null){
+			// Special case - A fault has been thrown within a compensation handler.
+			// Need to reset the scope path so that the stack will unwind correctly.
+			proc.setScopePath(_sp);
+			ScopePath esp = _sp.getEnclosingScopePath();
+			while((this.parentScope != null)&&(!esp.equals(this.parentScope.getScopePath())))
+				this.parentScope = this.parentScope.parentScope;
+			
+			_sp = null;
+		}
+		
+		// check to see if this fault was thrown inside a fault handler,
+		// this special case exists because fault handlers are allowed 
+		// access to variables in the same scope the fault handler is define,
+		// but faults thrown from a fault handler are handled by the parent 
+		// scope of the scope that the fault handler is defined in		
+		if ( proc.getExecutionContext().equals(FAULT_HANDLER)) {
+			if ( this.parentScope != null && 
+					! this.parentScope.scopePath.getCurrentScope().equals("") ) 
+			{
+				if ( logger.isLoggable(Level.FINE)) {
+					logger.fine("Fault thrown from fault handler, passing fault to parent scope:" + this.parentScope.getScopePath());
+				}
+				// change the scope of our process
+				proc.setScopePath(this.parentScope.getScopePath());
+				// execution context is back in process, for fault handling
+				proc.setExecutionContext(PROCESS);
+				this.parentScope.handleFault(exception,proc,ec,pcb);
+			} else {
+				reThrow(exception);
+			}
+			return;
+		}
+		
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Handling fault " + exception.toString() 
+					+ " in scope:" + this.scopePath);
+		}
+		
+		// activity termination
+		// for each eclosed active scope terminate it
+		Iterator it = childrenScopes.values().iterator();
+		while (it.hasNext()) {
+			IFCScopeInstance scope = (IFCScopeInstance) it.next();
+			if (scope.isActive()) {
+				scope.terminate(proc, ec, pcb);
+			}
+		}
+		
+		// after activity termination another fault could have been thrown
+		// and this scope could have been faulted, so we don't want to fault this
+		// scope again
+		if ( ! this.faulted ) {
+			// mark this scope as faulted
+			this.faulted = true;
+			
+			String faultName = null;
+			String faultType = null;
+			
+
+			if (exception instanceof BPRuntimeException ) {
+
+				BPRuntimeException brpe = (BPRuntimeException)exception;
+				// copy fault parts into context
+				if (brpe.getMessageParts().size() > 0) {
+					IContextService cs = ec.getProcessService()
+							.getContextService(proc.getRootKey());
+					IContainer rootCont = cs.getRoot();
+					IContainer globalCont = rootCont.createContainer(proc
+							.getContextContainerId());
+					IContainer faultCont = globalCont
+							.createContainer(CURRENT_FAULT);
+					for (Iterator itrPart = brpe.getMessageParts()
+							.entrySet().iterator(); itrPart.hasNext();) {
+						Map.Entry me = (Map.Entry) itrPart.next();
+						IPart faultPart = (IPart) faultCont
+								.createPart((String) me.getKey());
+						faultPart.setObject(me.getValue());
+					}
+				}
+
+				// look for fault handler
+				faultName = brpe.getNameSpace()	+ ":" + brpe.getName();
+				faultType = brpe.getType();
+			}
+			
+			// look for fault handler
+			String faultHandler = getFaultHandler(faultName, faultType, 
+					exception);
+			
+			// found a fault handler
+			if ( faultHandler != null ) {
+				// execute fault handler
+				// make sure we are executing in the context id
+				// of this scope, the process context id may not be
+				// correct in the case where we are throwing out of a
+				// scope that was executing in a compensation handler
+				proc.setContextContaionerId(this.ctxId);
+				// we are executing in a fault handler now
+				proc.setExecutionContext(FAULT_HANDLER);
+				// this scope is executing in a fault handler
+				// this is not true when executing in scope 
+				// inside a fault handler
+				executingFaultHandler = true;
+				executeProcess(faultHandler,proc,ec,pcb);
+				// we are back in process context
+				proc.setExecutionContext(PROCESS);
+				
+				// execute fault handler observer
+				if ( faultObserver != null ) {
+					executeProcess(this.faultObserver,proc,ec,pcb);
+				} else {
+					return;
+				}
+				
+			// didn't find fault handler
+			} else {
+				// implicit compensation
+				this.compensate(proc,ec,pcb);
+				
+				// rethrow fault if the parent is not the root
+				if ( this.parentScope != null && 
+						! this.parentScope.scopePath.getCurrentScope().equals("") ) 
+				{
+					if ( logger.isLoggable(Level.FINE)) {
+						logger.fine("Re throwing fault to scope:" + this.parentScope.getScopePath());
+					}
+					// change the scope of our process
+					proc.setScopePath(this.parentScope.getScopePath());
+					this.parentScope.handleFault(exception,proc,ec,pcb);
+				} else {
+					reThrow(exception);
+				}
+			}
+			
+		}
+
+	}
+	
+	private void cleanUp(IProcessCallBack pcb) throws BPException {
+		// cancel timers
+		IBPETimerService ts = BPETimerServiceFactory.getBPETimerService();
+		Iterator it = timers.iterator();
+		while ( it.hasNext() ) {
+			IBPETimer timer = (IBPETimer)it.next();
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Canceling timer in scope:" + this.scopePath +
+						" timer: " + timer);
+			}
+			ts.removeTimer(timer);
+		}
+		
+		// cancel registrations
+		CorrelationService cs = pcb.getCorrelationService();
+		it = receives.iterator();
+		while ( it.hasNext() ) {
+			Registration reg = (Registration)it.next();
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Removing registration in scope:" + this.scopePath +
+						" registration: " + reg);
+			}
+			cs.removeRegistration(reg);
+		}
+		
+		// delete any process kept for this scope
+		InstanceService is = pcb.getCorrelationService().getProcessService().getInstanceService();
+		it = procs.iterator();
+		while ( it.hasNext() ) {
+			IPMIProcess proc = (IPMIProcess)it.next();
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Removing process in scope:" + this.scopePath +
+						" process: " + proc.getKey());
+			}
+			is.getInstance(proc.getRootKey(),proc.getKey()).remove();
+		}
+		
+		timers.clear();
+		receives.clear();
+		procs.clear();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#terminate(org.apache.ode.engine.IEvaluationContext)
+	 */
+	public void terminate(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException {
+		
+		// if this scope is active terminate it
+		if (this.active) {
+
+			if (logger.isLoggable(Level.FINE)) {
+				logger.fine("Terminating scope:" + this.scopePath);
+			}
+
+			// mark scope as inactive
+			this.active = false;
+
+			// for each eclosed active scope terminate it
+			Iterator it = childrenScopes.values().iterator();
+			while (it.hasNext()) {
+				IFCScopeInstance scope = (IFCScopeInstance) it.next();
+				if (scope.isActive()) {
+					scope.terminate(proc, ec, pcb);
+				}
+			}
+
+			// cancel all the timers and receives
+			cleanUp(pcb);
+
+			// does this scope have a bpws:forcedTermination fault handler
+			String forcedTermination = getFaultHandler(FORCED_TERMINATION, null, null);
+			if (forcedTermination != null) {
+				// execute fault handler
+				executeProcess(forcedTermination, proc, ec, pcb);
+
+				// no bpws:forcedTermination fault handler
+			} else {
+				// implicit compensation 
+				this.compensate(proc, ec, pcb);
+			}
+		}
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#compensate(org.apache.ode.engine.IEvaluationContext)
+	 */
+	public void compensate(IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException {
+		
+		// if this scope has been compensated return
+		if ( this.compensated ) {
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Scope has already been compensated:" + this.scopePath);
+			}
+			return;
+		}
+		
+		// does this scope have a compensation handler and
+		if ( this.compensationHandler != null ) {
+			
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Compensating scope:" + this.scopePath);
+			}
+			
+			// The scope path in the IPMIProcess object is used to resolve variables.
+			// However, it's scope path is set up to the level that initiated compensation
+			// (at least one level below).  Need to update the scope path here so the snapshot
+			// variables can be accessed.  CR379112.
+			_sp = proc.getScopePath();
+			proc.setScopePath(this.scopePath);
+			
+			
+			this.compensated = true;
+			// point the process at the snap shot context
+			String saveCtxId = proc.getContextContainerId();
+			proc.setContextContaionerId(this.compenstationCtxId);
+			// run compensation handler
+			executeProcess(this.compensationHandler,proc,ec,pcb);
+			proc.setContextContaionerId(saveCtxId);
+			proc.setScopePath(_sp);
+			_sp = null;
+
+			
+		// this scope doesn't have compensation handler
+		} else {
+			// look for an enclosed completed scope that has a compensation handler
+			//Iterator it = completedChildrenScopes.iterator();
+			//while ( it.hasNext() ) {
+			//	IFCScopeInstance scope = (IFCScopeInstance)it.next();
+			//	scope.compensate(proc,ec,pcb);
+			// Scopes should be compensated in the reverse order of the completion of the scopes
+			for (int i = completedChildrenScopes.size(); i > 0; i--)
+			{
+				IFCScopeInstance scope = (IFCScopeInstance)completedChildrenScopes.get(i-1);
+				scope.compensate(proc,ec,pcb);
+			}
+			
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#removeRegistration(org.apache.ode.correlation.Registration)
+	 */
+	public void removeRegistration(Registration registration) {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Removing registration from scope:" + this.scopePath +
+					" registration: " + registration );
+		}
+		receives.remove(registration);
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#removeTimer(org.apache.ode.timerservice.IBPETimer)
+	 */
+	public void removeTimer(IBPETimer timer) {
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Canceling timer in scope:" + this.scopePath + 
+					" timer: " + timer);
+		}
+		timers.remove(timer);
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#addProcess(org.apache.ode.instance.service.IPMIProcess)
+	 */
+	public void addProcess(IPMIProcess proc) {
+		procs.add(proc);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.scopePath.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#setTimerAction(org.apache.ode.action.bpel.TimerAction, org.apache.ode.context.resolver.ContextResolver, org.apache.ode.engine.IEvaluationContext, org.apache.ode.engine.IProcessCallBack, org.apache.ode.instance.service.IPMIProcess, org.apache.ode.definition.service.IPMDProcess)
+	 */
+	public void setTimerAction(TimerAction act, ContextResolver resolver ) {
+		this.act = act;
+		this.resolver = resolver;		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IFCScopeInstance#executeTimerAction()
+	 */
+	public void executeTimerAction(IEvaluationContext ec, 
+			IProcessCallBack pcb, IPMIProcess processInstance, IPMDProcess processDefinition) throws BPException {
+		if ( this.act != null ) {
+			this.act.execute(resolver, ec, pcb,processInstance, processDefinition);
+		}
+		
+	}
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/ScopeServiceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/ScopeServiceImpl.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/ScopeServiceImpl.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/scope/service/impl/ScopeServiceImpl.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.scope.service.impl;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.ode.context.IContainer;
+import org.apache.ode.context.IContextService;
+import org.apache.ode.context.IPart;
+import org.apache.ode.engine.IEvaluationContext;
+import org.apache.ode.engine.IProcessCallBack;
+import org.apache.ode.instance.IPMIProcess;
+import org.apache.ode.scope.service.IFCScopeInstance;
+import org.apache.ode.scope.service.IScopeService;
+import org.apache.ode.scope.service.ScopePath;
+import org.apache.ode.util.BPException;
+
+/**
+ * 
+ */
+public class ScopeServiceImpl implements IScopeService {
+	
+	private static Logger logger = 
+		Logger.getLogger(ScopeServiceImpl.class.getName());
+	
+//	private IContextService cs;
+	private FCScopeInstanceImpl rootScope;
+	
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IScopeService#init(org.apache.ode.context.IContextService)
+	 */
+	public void init(IContextService cs, String ctxId) throws BPException {
+//		this.cs = cs;
+		IContainer root = cs.getRoot();
+		IContainer procroot = (IContainer)root.findChild(ctxId);
+		IPart rootScopePart = (IPart)procroot.findChild("rootScope");
+		if ( rootScopePart == null ){
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Initializing context service for ctxid:" + ctxId);
+			}
+			rootScopePart = procroot.createPart("rootScope");
+			rootScope = new FCScopeInstanceImpl();
+			rootScopePart.setObject(rootScope);
+		} else {
+			rootScope = (FCScopeInstanceImpl)rootScopePart.getObjectForReadWrite();
+		}
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IScopeService#getStcope(java.lang.String)
+	 */
+	public IFCScopeInstance getScope(ScopePath scopePath) throws BPException {
+		return rootScope.getScope(scopePath);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IScopeService#compensate(java.lang.String)
+	 */
+	public void compensate(String scopeName, IPMIProcess proc, 
+			IEvaluationContext ec, IProcessCallBack pcb) throws BPException {
+		// find a matching scope and get it's parents completed scopes
+		// matching the scope name to compensate
+		FCScopeInstanceImpl parentScope = null;
+		Iterator it = rootScope.getScopes().values().iterator();
+		while( it.hasNext() ) {
+			FCScopeInstanceImpl scope = (FCScopeInstanceImpl)it.next();
+			String name = scope.getScopePath().getCurrentScope();
+			if ( name.startsWith(scopeName) ) {
+				parentScope = scope.getParentScope();
+				break;
+			}
+		}
+		
+		// bad scope name
+		if ( parentScope == null ) {
+			throw new BPException("SS_BAD_COMP_SCOPE_NAME",new Object[] { scopeName });
+		}
+		
+		// compensate the scopes the start with the scope name
+		List completedScopes = parentScope.getCompletedChildrenScopes();
+		for (int i = completedScopes.size(); i > 0; i--)
+		{
+			IFCScopeInstance scope = (IFCScopeInstance)completedScopes.get(i-1);
+			String name = scope.getScopePath().getCurrentScope();
+			if ( name.startsWith(scopeName)) {
+				scope.compensate(proc,ec,pcb);
+			}
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.scope.service.IScopeService#getRootScope()
+	 */
+	public IFCScopeInstance getRootScope() throws BPException {
+		return rootScope;
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/BPETimerServiceFactory.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/BPETimerServiceFactory.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/BPETimerServiceFactory.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/BPETimerServiceFactory.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.timerservice;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.ode.bped.EventDirectorFactory;
+import org.apache.ode.inmemory.jndi.IMContext;
+import org.apache.ode.util.BPEProperties;
+import org.apache.ode.util.BPException;
+
+public class BPETimerServiceFactory {
+	
+	private static Logger logger = Logger.getLogger(BPETimerServiceFactory.class
+			.getName());
+	public static String BPETIMER_CLASS = "BPETIMER_CLASS_KEY";
+	
+	public static IBPETimerService getBPETimerService() throws BPException {
+		BPEProperties props;
+		try {
+			String val = System.getProperty(EventDirectorFactory.JNFI);
+			if (val != null && val.compareTo(EventDirectorFactory.IMJNFI) == 0)
+			{
+				props = new BPEProperties();
+				IMContext.getProperties(props,
+						EventDirectorFactory.IM_ENGINE_PROPERTY_FILE_NAME);
+			} else {
+				props = 
+				    BPEProperties.getCachedProperties();
+			}
+		} catch (IOException e) {
+			BPException bpx = new BPException(
+					"NATIVE_EXCEPTION", new Object[]
+					{"IOException"}, e);
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		} 
+		return getBPETimerService(props);
+	}
+	
+	private static IBPETimerService getBPETimerService(BPEProperties props) throws BPException {
+		String className = props.getProperty(BPETIMER_CLASS);
+		if ( className == null ) {
+			return null;
+		}
+		IBPETimerService ts;
+		try {
+			Class instClass = java.lang.Class.forName(className);
+			ts = (IBPETimerService)instClass.newInstance();
+			ts.init(props);
+		} catch (ClassNotFoundException e) {
+			BPException bpx = new BPException(
+					"CLASS_NOT_FOUND", new Object[]
+					{props.getProperty(BPETIMER_CLASS)});
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		} catch (InstantiationException e) {
+			BPException bpx = new BPException(
+					"NATIVE_EXCEPTION", new Object[]
+					{"InstantiationException"}, e);
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		} catch (IllegalAccessException e) {
+			BPException bpx = new BPException(
+					"NATIVE_EXCEPTION", new Object[]
+					{"IllegalAccessException"}, e);
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		}
+
+		return ts;
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimer.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimer.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimer.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimer.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.timerservice;
+
+import java.io.Serializable;
+
+import org.apache.ode.event.ITimerEvent;
+
+/**
+ * BPE Timer 
+ */
+public interface IBPETimer  extends Serializable {
+	
+	static final long serialVersionUID = -1722001456714424366L;
+	
+	/**
+	 * Get the timer id.
+	 * @return
+	 */	
+	public Object getId();
+	
+	/**
+	 * Get the time event for this timer.
+	 * @return
+	 */
+	public ITimerEvent getTimerEvent();
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimerService.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimerService.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimerService.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/IBPETimerService.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.ode.timerservice;
+
+import java.util.Date;
+
+import org.apache.ode.event.ITimerEvent;
+import org.apache.ode.util.BPEProperties;
+import org.apache.ode.util.BPException;
+
+/**
+ * Service used by the timer action.
+ */
+public interface IBPETimerService {
+	
+	/**
+	 * Create a duration timer.
+	 * @param startDuration
+	 * @param timerEvent
+	 */
+	public IBPETimer createTimer(long startDuration, ITimerEvent timerEvent) throws BPException;
+	/**
+	 * Create a date timer.
+	 * @param startTime
+	 * @param timerEvent
+	 */
+	public IBPETimer createTimer(Date startTime, ITimerEvent timerEvent) throws BPException;
+	
+	/**
+	 * Remove a timer
+	 * @param timer
+	 * @throws BPException
+	 */
+	public void removeTimer(IBPETimer timer) throws BPException;
+	
+	/**
+	 * Initialize the service.
+	 *
+	 */
+	public void init(BPEProperties props) throws BPException;
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerEjbTimerImpl.java.j2ee14
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerEjbTimerImpl.java.j2ee14?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerEjbTimerImpl.java.j2ee14 (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerEjbTimerImpl.java.j2ee14 Tue Feb 28 08:31:48 2006
@@ -0,0 +1,43 @@
+
+package com.sybase.bpe.timerservice.ejbTimerImpl;
+
+import javax.ejb.TimerHandle;
+
+import com.sybase.bpe.event.ITimerEvent;
+import com.sybase.bpe.timerservice.IBPETimer;
+
+/**
+ * BPE Timer EjbTimer impl.
+ */
+public class BPETimerEjbTimerImpl implements IBPETimer {
+	
+	private TimerHandle id;
+	
+	public BPETimerEjbTimerImpl(TimerHandle id) 
+	{
+		this.id = id;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimer#getId()
+	 */
+	public Object getId() {
+		return this.id;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimer#getTimerEvent()
+	 */
+	public ITimerEvent getTimerEvent() {
+		return (ITimerEvent)id.getTimer().getInfo();
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		boolean eq = this.id.equals(((BPETimerEjbTimerImpl)obj).getId());
+		return eq;
+	}
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerServiceEjbTimerImpl.java.j2ee14
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerServiceEjbTimerImpl.java.j2ee14?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerServiceEjbTimerImpl.java.j2ee14 (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/ejbTimerImpl/BPETimerServiceEjbTimerImpl.java.j2ee14 Tue Feb 28 08:31:48 2006
@@ -0,0 +1,114 @@
+
+package com.sybase.bpe.timerservice.ejbTimerImpl;
+
+import java.util.Date;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.ejb.CreateException;
+import javax.ejb.EJBException;
+import javax.ejb.NoSuchObjectLocalException;
+import javax.ejb.Timer;
+import javax.ejb.TimerHandle;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import com.sybase.bpe.bped.ejbimpl.BPETimerLocal;
+import com.sybase.bpe.bped.ejbimpl.BPETimerLocalHome;
+import com.sybase.bpe.event.ITimerEvent;
+import com.sybase.bpe.timerservice.IBPETimer;
+import com.sybase.bpe.timerservice.IBPETimerService;
+import com.sybase.bpe.util.BPEProperties;
+import com.sybase.bpe.util.BPException;
+
+/**
+ * 
+ */
+public class BPETimerServiceEjbTimerImpl implements IBPETimerService {
+	
+	private static Logger logger = Logger.getLogger(BPETimerServiceEjbTimerImpl.class
+			.getName());
+	private static String TIMER_REF = "java:comp/env/BPETimerLocal";
+	
+	private BPETimerLocalHome timerHome;
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimerService#createTimer(long, com.sybase.bpe.event.ITimerEvent)
+	 */
+	public IBPETimer createTimer(long startDuration, ITimerEvent timerEvent) throws BPException {
+		BPETimerLocal timer;
+		try {
+			timer = timerHome.create();
+			Timer t = timer.createTimer(startDuration,timerEvent);
+			return new BPETimerEjbTimerImpl(t.getHandle());
+		} catch (CreateException e) {
+			BPException bpx = new BPException(
+					"NATIVE_EXCEPTION", new Object[]
+					{"CreateException"}, e);
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		}		
+	}
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimerService#createTimer(java.util.Date, com.sybase.bpe.event.ITimerEvent)
+	 */
+	public IBPETimer createTimer(Date startTime, ITimerEvent timerEvent) throws BPException{
+		try {
+			BPETimerLocal timer = timerHome.create();
+			Timer t = timer.createTimer(startTime, timerEvent);
+			return new BPETimerEjbTimerImpl(t.getHandle());
+		} catch (CreateException e) {
+			BPException bpx = new BPException("NATIVE_EXCEPTION",
+					new Object[] { "CreateException" }, e);
+			bpx.log(logger, Level.SEVERE);
+			throw bpx;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimerService#init(com.sybase.bpe.util.BPEProperties)
+	 */
+	public void init(BPEProperties props) throws BPException {
+			InitialContext ic;
+			try {
+				ic = new InitialContext();
+				Object o = ic.lookup(TIMER_REF);
+				timerHome = (BPETimerLocalHome) PortableRemoteObject
+						.narrow(o, BPETimerLocalHome.class);
+			} catch (NamingException e) {
+				BPException bpx = new BPException("NATIVE_EXCEPTION",
+						new Object[] { "CreateException" }, e);
+				bpx.log(logger, Level.SEVERE);
+				throw bpx;
+			}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.sybase.bpe.timerservice.IBPETimerService#removeTimer(com.sybase.bpe.timerservice.IBPETimer)
+	 */
+	public void removeTimer(IBPETimer timer) throws BPException {
+		TimerHandle handle = (TimerHandle)timer.getId();
+		Timer t = null;
+		try {
+			t = handle.getTimer();
+			t.cancel();
+		} catch (IllegalStateException e) {
+			BPException bpx = new BPException("NATIVE_EXCEPTION",
+					new Object[] { "IllegalStateException" }, e);
+		} catch ( NoSuchObjectLocalException e ) {
+			if ( logger.isLoggable(Level.FINE)) {
+				logger.fine("Timer has expired or been canceled.");
+			}
+			return;
+		} catch ( EJBException e ) {
+			BPException bpx = new BPException("NATIVE_EXCEPTION",
+					new Object[] { "EJBException" }, e);
+		}
+		if ( logger.isLoggable(Level.FINE)) {
+			logger.fine("Canceled timer:" + t);
+		}
+	}
+
+}

Added: incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/noop/NoopTimer.java
URL: http://svn.apache.org/viewcvs/incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/noop/NoopTimer.java?rev=381694&view=auto
==============================================================================
--- incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/noop/NoopTimer.java (added)
+++ incubator/ode/scratch/ode/src/main/java/org/apache/ode/timerservice/noop/NoopTimer.java Tue Feb 28 08:31:48 2006
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+/*
+ * Created on Oct 28, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.apache.ode.timerservice.noop;
+
+import org.apache.ode.event.ITimerEvent;
+import org.apache.ode.timerservice.IBPETimer;
+
+/**
+ * @author charper
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class NoopTimer implements IBPETimer {
+	
+    static final long serialVersionUID = 1650723050727088370L;
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.timerservice.IBPETimer#getId()
+	 */
+	public Object getId() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ode.timerservice.IBPETimer#getTimerEvent()
+	 */
+	public ITimerEvent getTimerEvent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}