Source Code Cross Referenced for BasicContinuableRunner.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » continuations » basic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » rife 1.6.1 » com.uwyn.rife.continuations.basic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         * $Id: BasicContinuableRunner.java 3850 2007-07-12 18:46:42Z gbevin $
007:         */
008:        package com.uwyn.rife.continuations.basic;
009:
010:        import java.lang.reflect.InvocationTargetException;
011:        import java.lang.reflect.Method;
012:
013:        import com.uwyn.rife.continuations.*;
014:        import com.uwyn.rife.continuations.exceptions.AnswerException;
015:        import com.uwyn.rife.continuations.exceptions.CallException;
016:        import com.uwyn.rife.continuations.exceptions.PauseException;
017:        import com.uwyn.rife.continuations.exceptions.StepBackException;
018:
019:        /**
020:         * Basic implementation of a 'continuable runner' that will execute the
021:         * continuable objects and correctly handle the continuations-related
022:         * exceptions that are triggered.
023:         * <p>This runner is probably only applicable to the most simple of use-cases,
024:         * but by reading its source it should be relatively easy to adapt of extend
025:         * it for purposes that don't fall inside its scope.
026:         *
027:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
028:         * @version $Revision: 3850 $
029:         * @since 1.6
030:         */
031:        public class BasicContinuableRunner {
032:            private ClassLoader mClassLoader;
033:            private ContinuationConfigInstrument mConfigInstrument;
034:            private CallTargetRetriever mCallTargetRetriever = new ClassCallTargetRetriever();
035:            private boolean mCloneContinuations = true;
036:
037:            private ContinuationManager mManager;
038:
039:            private ThreadLocal<ContinuableObject> mCurrentContinuable = new ThreadLocal<ContinuableObject>();
040:
041:            /**
042:             * Create a new runner instance.
043:             *
044:             * @param configInstrument the instance of the instrumentation
045:             * configuration that will be used for the transformation
046:             * @since 1.6
047:             */
048:            public BasicContinuableRunner(
049:                    ContinuationConfigInstrument configInstrument) {
050:                this (configInstrument, null);
051:            }
052:
053:            /**
054:             * Create a new runner instance with a custom classloader.
055:             *
056:             * @param configInstrument the instance of the instrumentation
057:             * configuration that will be used for the transformation
058:             * @param classloader the classloader that will be used to load the
059:             * continuable classes, this is for example an instance of
060:             * {@link BasicContinuableClassLoader}
061:             * @since 1.6
062:             */
063:            public BasicContinuableRunner(
064:                    ContinuationConfigInstrument configInstrument,
065:                    ClassLoader classloader) {
066:                mManager = new ContinuationManager(new BasicConfigRuntime());
067:                mConfigInstrument = configInstrument;
068:                if (null == classloader) {
069:                    classloader = getClass().getClassLoader();
070:                }
071:                mClassLoader = classloader;
072:            }
073:
074:            /**
075:             * Starts the execution of a new instance of the provided class.
076:             *
077:             * @param className the name of the class that will be executed
078:             * @return the ID of the resulting paused continuation; or
079:             * <p>{@code null} if no continuation was paused
080:             * @throws Throwable when an error occurs
081:             * @since 1.6
082:             */
083:            public String start(String className) throws Throwable {
084:                return run(className, null, null, null);
085:            }
086:
087:            /**
088:             * Resumes the execution of a paused continuation.
089:             *
090:             * @param continuationId the ID of the continuation that will be resumed
091:             * @return the ID of the resulting paused continuation; or
092:             * <p>{@code null} if no continuation was paused or if the provided ID
093:             * couldn't be found
094:             * @throws Throwable when an error occurs
095:             * @since 1.6
096:             */
097:            public String resume(String continuationId) throws Throwable {
098:                return run(null, continuationId, null, null);
099:            }
100:
101:            /**
102:             * Resumes the execution of a call continuation.
103:             *
104:             * @param continuationId the ID of the continuation that will be resumed
105:             * @param callAnswer the call answer object
106:             * @return the ID of the resulting paused continuation; or
107:             * <p>{@code null} if no continuation was paused or if the provided ID
108:             * couldn't be found
109:             * @throws Throwable when an error occurs
110:             * @since 1.6.1
111:             */
112:            public String answer(String continuationId, Object callAnswer)
113:                    throws Throwable {
114:                return run(null, continuationId, null, callAnswer);
115:            }
116:
117:            /**
118:             * Executes a continuation whether it's paused or not. This is supposed to
119:             * only be used for answer continuations.
120:             *
121:             * @param continuationId the ID of the existing continuation context that
122:             * will be executed
123:             * @return the ID of the resulting paused continuation; or
124:             * <p>{@code null} if no continuation was paused or if the provided ID
125:             * couldn't be found
126:             * @throws Throwable when an error occurs
127:             * @since 1.6
128:             */
129:            public String run(String continuationId) throws Throwable {
130:                return run(null, null, continuationId, null);
131:            }
132:
133:            private String run(String className, String resumeId, String runId,
134:                    Object callAnswer) throws Throwable {
135:                // retrieve the current context classloader
136:                ClassLoader previous_context_classloader = Thread
137:                        .currentThread().getContextClassLoader();
138:
139:                String result = null;
140:                try {
141:                    // set the continuations classloader as the context classloader
142:                    Thread.currentThread().setContextClassLoader(mClassLoader);
143:
144:                    ContinuableObject object = null;
145:                    boolean stepback = false;
146:                    boolean call = false;
147:                    boolean answer = false;
148:                    do {
149:                        try {
150:                            try {
151:                                try {
152:                                    // create or retrieve a continuable object
153:                                    if (null == object) {
154:                                        // no active continuation, start a new one
155:                                        if (null == resumeId && null == runId) {
156:                                            // load the continuable class through the provided classloader
157:                                            Class continuableClass = mClassLoader
158:                                                    .loadClass(className);
159:                                            object = (ContinuableObject) continuableClass
160:                                                    .newInstance();
161:                                            ContinuationContext
162:                                                    .clearActiveContext();
163:                                        } else {
164:                                            ContinuationContext context = null;
165:
166:                                            // resume an existing continuation
167:                                            if (resumeId != null) {
168:                                                context = mManager
169:                                                        .resumeContext(resumeId);
170:                                            }
171:                                            // run an existing continuation
172:                                            else if (runId != null) {
173:                                                context = mManager
174:                                                        .getContext(runId);
175:                                            }
176:
177:                                            // setup the context
178:                                            if (context != null) {
179:                                                if (callAnswer != null) {
180:                                                    context
181:                                                            .setCallAnswer(callAnswer);
182:                                                }
183:                                                ContinuationContext
184:                                                        .setActiveContext(context);
185:                                                object = context
186:                                                        .getContinuable();
187:                                            }
188:                                        }
189:                                    }
190:
191:                                    // reset state variables
192:                                    resumeId = null;
193:                                    runId = null;
194:                                    callAnswer = null;
195:                                    stepback = false;
196:                                    call = false;
197:                                    answer = false;
198:
199:                                    // execute the continuable object
200:                                    result = null;
201:
202:                                    // setup the required threadlocal vars
203:                                    mCurrentContinuable.set(object);
204:                                    ContinuationConfigRuntime
205:                                            .setActiveConfigRuntime(mManager
206:                                                    .getConfigRuntime());
207:
208:                                    executeContinuable(object);
209:
210:                                    // clear out the continuable object
211:                                    object = null;
212:                                } finally {
213:                                    ContinuationContext.clearActiveContext();
214:                                }
215:                            } catch (InvocationTargetException invocation_target_exception) {
216:                                throw invocation_target_exception
217:                                        .getTargetException();
218:                            }
219:                        } catch (PauseException e) {
220:                            // register context
221:                            ContinuationContext context = e.getContext();
222:                            mManager.addContext(context);
223:
224:                            // obtain continuation ID
225:                            result = context.getId();
226:                        } catch (StepBackException e) {
227:                            stepback = true;
228:
229:                            // register context
230:                            ContinuationContext context = e.getContext();
231:                            mManager.addContext(context);
232:
233:                            resumeId = e.lookupStepBackId();
234:                            if (resumeId != null) {
235:                                // clear the continuable object so that it's looked up from the
236:                                // grand parent continuation
237:                                object = null;
238:                            }
239:                        } catch (CallException e) {
240:                            call = true;
241:
242:                            // register context
243:                            ContinuationContext context = e.getContext();
244:                            mManager.addContext(context);
245:
246:                            // create a new call state
247:                            CallState call_state = new CallState(context
248:                                    .getId(), null);
249:                            context.setCreatedCallState(call_state);
250:
251:                            // create the new target object
252:                            object = mCallTargetRetriever.getCallTarget(e
253:                                    .getTarget(), call_state);
254:                        } catch (AnswerException e) {
255:                            // obtain the context and the answer of the answering element
256:                            ContinuationContext context = e.getContext();
257:
258:                            // handle the call state of the last processed element context
259:                            if (context != null
260:                                    && context.getActiveCallState() != null) {
261:                                answer = true;
262:
263:                                CallState call_state = context
264:                                        .getActiveCallState();
265:                                callAnswer = e.getAnswer();
266:                                runId = call_state.getContinuationId();
267:                            }
268:
269:                            object = null;
270:                        }
271:                    } while (stepback || (call && object != null) || answer);
272:                } finally {
273:                    // restore the previous context classloader
274:                    Thread.currentThread().setContextClassLoader(
275:                            previous_context_classloader);
276:                }
277:
278:                return result;
279:            }
280:
281:            /**
282:             * Executes the continuable object by looking up the entrance method and
283:             * invoking it.
284:             * <p>This method can be overridden in case the default behavior isn't
285:             * approriate.
286:             *
287:             * @param object the continuatioble that will be executed
288:             * @throws Throwable when an unexpected error occurs
289:             * @since 1.6.1
290:             */
291:            public void executeContinuable(ContinuableObject object)
292:                    throws Throwable {
293:                // lookup the method that will be used to execute the entrance of the continuable object
294:                beforeExecuteEntryMethodHook(object);
295:                Method method = object.getClass().getMethod(
296:                        mConfigInstrument.getEntryMethodName(),
297:                        mConfigInstrument.getEntryMethodArgumentTypes());
298:                method.invoke(object, (Object[]) null);
299:            }
300:
301:            /**
302:             * Hook method that will be executed right before executing the entry
303:             * method of a continuable object, when the default implementation of
304:             * {@link #executeContinuable} is used.
305:             * <p>This can for example be used to inject a continuable support object
306:             * in case the main continuable class only implements the marker interface
307:             * without having any of the support methods (see {@link ContinuationConfigInstrument#getContinuableSupportClassName()}).
308:             *
309:             * @param object the continuable object that will be executed
310:             * @see #executeContinuable
311:             * @since 1.6
312:             */
313:            public void beforeExecuteEntryMethodHook(ContinuableObject object) {
314:            }
315:
316:            /**
317:             * Retrieves the instrumentation configuration that is used by this runner.
318:             *
319:             * @return this runner's instrumentation configuration
320:             * @since 1.6
321:             */
322:            public ContinuationConfigInstrument getConfigInstrumentation() {
323:                return mConfigInstrument;
324:            }
325:
326:            /**
327:             * Retrieves the classloader that is used by this runner.
328:             *
329:             * @return this runner's classloader
330:             * @since 1.6
331:             */
332:            public ClassLoader getClassLoader() {
333:                return mClassLoader;
334:            }
335:
336:            /**
337:             * Configures the runner to clone continuations or not.
338:             *
339:             * @param cloneContinuations {@code true} if continuations should be
340:             * cloned when they are resumed; or
341:             * <p>{@code false} if they should not be cloned
342:             * @return this runner instance
343:             * @see #setCloneContinuations
344:             * @see #getCloneContinuations
345:             * @since 1.6
346:             */
347:            public BasicContinuableRunner cloneContinuations(
348:                    boolean cloneContinuations) {
349:                setCloneContinuations(cloneContinuations);
350:                return this ;
351:            }
352:
353:            /**
354:             * Configures the runner to clone continuations or not.
355:             *
356:             * @param cloneContinuations {@code true} if continuations should be
357:             * cloned when they are resumed; or
358:             * <p>{@code false} if they should not be cloned
359:             * @see #cloneContinuations
360:             * @see #getCloneContinuations
361:             * @since 1.6
362:             */
363:            public void setCloneContinuations(boolean cloneContinuations) {
364:                mCloneContinuations = cloneContinuations;
365:            }
366:
367:            /**
368:             * Indicates whether continuations should be cloned when they are resumed.
369:             *
370:             * @return {@code true} if continuations should be cloned when they are
371:             * resumed; or
372:             * <p>{@code false} if they should not be cloned
373:             * @see #cloneContinuations
374:             * @see #setCloneContinuations
375:             * @since 1.6
376:             */
377:            public boolean getCloneContinuations() {
378:                return mCloneContinuations;
379:            }
380:
381:            /**
382:             * Sets the call target retriever that will be used when a call
383:             * continuation is triggered.
384:             *
385:             * @param callTargetRetriever the call target retriever that will be used
386:             * @return this runner instance
387:             * @see #setCallTargetRetriever
388:             * @see #getCallTargetRetriever
389:             * @since 1.6
390:             */
391:            public BasicContinuableRunner callTargetRetriever(
392:                    CallTargetRetriever callTargetRetriever) {
393:                setCallTargetRetriever(callTargetRetriever);
394:                return this ;
395:            }
396:
397:            /**
398:             * Sets the call target retriever that will be used when a call
399:             * continuation is triggered.
400:             *
401:             * @param callTargetRetriever the call target retriever that will be used
402:             * @see #callTargetRetriever
403:             * @see #getCallTargetRetriever
404:             * @since 1.6
405:             */
406:            public void setCallTargetRetriever(
407:                    CallTargetRetriever callTargetRetriever) {
408:                mCallTargetRetriever = callTargetRetriever;
409:            }
410:
411:            /**
412:             * Retrieves the call target retriever that will be used when a call
413:             * continuation is triggered.
414:             *
415:             * @return this runner's call target retriever
416:             * @see #callTargetRetriever
417:             * @see #setCallTargetRetriever
418:             * @since 1.6
419:             */
420:            public CallTargetRetriever getCallTargetRetriever() {
421:                return mCallTargetRetriever;
422:            }
423:
424:            /**
425:             * Retrieves the continuable that is active for the executing thread.
426:             *
427:             * @return this thread's continuable; or
428:             * <p>{@code null} if there's no current continuable
429:             * @since 1.6
430:             */
431:            public ContinuableObject getCurrentContinuable() {
432:                return mCurrentContinuable.get();
433:            }
434:
435:            /**
436:             * Retrieves the manager that is used by the continuation runner.
437:             *
438:             * @return this runner's continuation manager
439:             * @since 1.6
440:             */
441:            public ContinuationManager getManager() {
442:                return mManager;
443:            }
444:
445:            private class BasicConfigRuntime extends ContinuationConfigRuntime {
446:                public ContinuableObject getAssociatedContinuableObject(
447:                        Object executingInstance) {
448:                    return mCurrentContinuable.get();
449:                }
450:
451:                public ContinuationManager getContinuationManager(
452:                        ContinuableObject executingContinuable) {
453:                    return mManager;
454:                }
455:
456:                public boolean cloneContinuations(
457:                        ContinuableObject executingContinuable) {
458:                    return mCloneContinuations;
459:                }
460:            }
461:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.