001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.flow.java;
018:
019: import java.util.HashMap;
020:
021: /**
022: * Continations object to store the current execution. The contiunation
023: * object can only used once.
024: *
025: * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
026: * @author <a href="mailto:tcurdt@apache.org">Torsten Curdt</a>
027: * @version CVS $Id: Continuation.java 433543 2006-08-22 06:22:54Z crossley $
028: */
029: public class Continuation {
030: private ContinuationStack stack;
031: private Object context;
032:
033: private static HashMap continuationsmap = new HashMap();
034:
035: public boolean restoring = false;
036: public boolean capturing = false;
037:
038: /**
039: * Create new continuation.
040: */
041: public Continuation(Object context) {
042: stack = new ContinuationStack();
043: this .context = context;
044: }
045:
046: /**
047: * Create a new continuation, which continue a previous continuation.
048: */
049: public Continuation(Continuation parent, Object context) {
050: if (parent == null)
051: throw new NullPointerException(
052: "Parent continuation is null");
053:
054: stack = new ContinuationStack(parent.stack);
055: this .context = context;
056: restoring = true;
057: }
058:
059: /**
060: * Return the stack, which is used to store the frame information.
061: */
062: public ContinuationStack getStack() {
063: return stack;
064: }
065:
066: /**
067: * Return context object, which is associated to this continuation.
068: */
069: public Object getContext() {
070: return context;
071: }
072:
073: /**
074: * Stop the running continuation.
075: */
076: public static void suspend() {
077:
078: Continuation continuation = Continuation.currentContinuation();
079:
080: if (continuation == null)
081: throw new IllegalStateException(
082: "No continuation is running");
083:
084: if (continuation.restoring) {
085: continuation.capturing = false;
086: } else {
087: continuation.capturing = true;
088: }
089: continuation.restoring = false;
090: }
091:
092: /**
093: * True, if the continuation restores the previous stack trace to the
094: * last invocation of suspend().
095: */
096: public boolean isRestoring() {
097: return restoring;
098: }
099:
100: /**
101: * True, is the continuation freeze the strack trace, and stops the continuation.
102: */
103: public boolean isCapturing() {
104: return capturing;
105: }
106:
107: /**
108: * Bind the continuation to running thread.
109: */
110: public void registerThread() {
111: synchronized (continuationsmap) {
112: continuationsmap.put(Thread.currentThread(), this );
113: }
114: }
115:
116: /**
117: * Unbind the continuation to running thread.
118: */
119: public void deregisterThread() {
120: synchronized (continuationsmap) {
121: continuationsmap.remove(Thread.currentThread());
122: }
123: }
124:
125: /**
126: * Return the continuation, which is associated to the
127: * current thread.
128: */
129: public static Continuation currentContinuation() {
130: synchronized (continuationsmap) {
131: Thread t = Thread.currentThread();
132: return (Continuation) continuationsmap.get(t);
133: }
134: }
135: }
|