Source Code Cross Referenced for TJCThread.java in  » Scripting » jacl » tcl » lang » 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 » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2006 Mo DeJong
003:         *
004:         * See the file "license.amd" for information on usage and
005:         * redistribution of this file, and for a DISCLAIMER OF ALL
006:         * WARRANTIES.
007:         * 
008:         * RCS: @(#) $Id: TJCThread.java,v 1.3 2006/08/04 23:11:14 mdejong Exp $
009:         *
010:         */
011:
012:        // TJC Runtime Compiler main thread. This thread is accessed
013:        // by any active interp that wishes to compile a Tcl method
014:        // into Java class files. Generating Java code and then
015:        // compiling it to Tcl code can take some time, so it is
016:        // done in a separate thread and loaded into the requesting
017:        // Interp when ready.
018:        package tcl.lang;
019:
020:        import java.util.HashMap;
021:        import java.util.Vector;
022:        import java.util.ArrayList;
023:        import java.util.StringTokenizer;
024:
025:        public class TJCThread implements  Runnable {
026:            public static final int STATUS_OK = 0;
027:            public static final int STATUS_ERROR = 1;
028:
029:            private static boolean debug = false;
030:
031:            private static String debugSetup = "";
032:
033:            private static String driver = null;
034:
035:            // The TJCThread instance, it is possible that
036:            // the thread could be terminated and then
037:            // started again which would replace this instance.
038:
039:            private static TJCThread tinstance = null;
040:            private static Thread tmain = null;
041:
042:            // Set to true when the tmain thread should
043:            // terminate itself.
044:
045:            private boolean terminate_request = false;
046:            private boolean terminated = false;
047:
048:            // Set to true when the thread is ready to process
049:            // events. This may not be set until the thread has started
050:            // up and possibly processed any events that were initially
051:            // added to the queue.
052:
053:            private boolean ready = false;
054:
055:            // Thread safe queue of events to process.
056:
057:            private static Vector queue = new Vector();
058:
059:            // Jacl interp used to process events. The
060:            // interp is created in the other thread.
061:            // it should never be accessed from the
062:            // caller thread.
063:
064:            private Interp interp = null;
065:
066:            // Event record. This is a buffer of line
067:            // oriented data that indicates what events
068:            // are being processed and in what order.
069:
070:            private static StringBuffer eventLog = null;
071:
072:            // Invoke the compiled() method when the
073:            // results of a compileJavaSource() or
074:            // compileTclSource() invocation are ready.
075:
076:            public static interface CompiledClassReady {
077:                public void compiled(final String geninfo, // Name that identifies the source
078:                        // for generated Java code. This
079:                        // "" when compiling a Java file.
080:                        final String jfilename, // File name for Java source,
081:                        // like "Test.java".
082:                        final String jsrcode, // Java source that was compiled.
083:                        final ArrayList cnames, // List of compiled class names.
084:                        final ArrayList cdata, // List of compiled class data as byte[].
085:                        final int status, final String msg);
086:            }
087:
088:            // Invoked to indicate that a given Java
089:            // source file should be compiled.
090:
091:            public static synchronized void compileJavaSource(String filename,
092:                    String source, CompiledClassReady callback) {
093:                if (callback == null) {
094:                    throw new NullPointerException("callback");
095:                }
096:
097:                if (eventLog != null) {
098:                    eventLog.append("compileJavaSource " + filename + "\n");
099:                }
100:                if (debug) {
101:                    System.out.println("compileJavaSource " + filename);
102:                }
103:
104:                // Test 1, check that the callback works without invoking
105:                // the notify to process in the other thread.
106:
107:                if (filename.equals("__FakeTest1.java")) {
108:                    if (eventLog != null) {
109:                        eventLog.append("Fake Java Test 1 processed\n");
110:                    }
111:                    if (debug) {
112:                        System.out.println("Fake Java Test 1 processed");
113:                    }
114:
115:                    ArrayList class_names = new ArrayList();
116:                    class_names.add("__FakeTest1");
117:
118:                    byte[] bytes = { (byte) 'F', (byte) 'A', (byte) 'K',
119:                            (byte) 'E' };
120:
121:                    ArrayList class_data = new ArrayList();
122:                    class_data.add(bytes);
123:
124:                    callback.compiled("", filename, source, class_names,
125:                            class_data, 0, "");
126:                    return;
127:                }
128:
129:                // Add event to thread safe queue
130:
131:                Vector event = new Vector();
132:                event.addElement("JAVA");
133:                event.addElement(filename);
134:                event.addElement(source);
135:                event.addElement(callback);
136:
137:                queue.addElement(event);
138:
139:                synchronized (tinstance) {
140:                    if (eventLog != null) {
141:                        eventLog.append("notify in compileJavaSource\n");
142:                    }
143:                    if (debug) {
144:                        System.out.println("notify in compileJavaSource");
145:                    }
146:
147:                    tinstance.notify(); // wake up other thread
148:                }
149:            }
150:
151:            // Invoked to indicate that a given Tcl procedure
152:            // should be compiled into a class file.
153:
154:            public static synchronized void compileTclSource(String filename,
155:                    String proc_source, CompiledClassReady callback) {
156:                if (eventLog != null) {
157:                    eventLog.append("compileTclSource " + filename + "\n");
158:                }
159:                if (debug) {
160:                    System.out.println("compileTclSource " + filename);
161:                    System.out.println("Tcl proc is:\n" + proc_source);
162:                }
163:
164:                // Add event to thread safe queue
165:
166:                Vector event = new Vector();
167:                event.addElement("TCL");
168:                event.addElement(filename);
169:                event.addElement(proc_source);
170:                event.addElement(callback);
171:
172:                queue.addElement(event);
173:
174:                synchronized (tinstance) {
175:                    if (eventLog != null) {
176:                        eventLog.append("notify in compileTclSource\n");
177:                    }
178:                    if (debug) {
179:                        System.out.println("notify in compileTclSource");
180:                    }
181:
182:                    tinstance.notify(); // wake up other thread
183:                }
184:            }
185:
186:            // Invoked when the user wants the main thread to die.
187:
188:            public static synchronized void terminateThread() {
189:                if (eventLog != null) {
190:                    eventLog.append("terminateThread\n");
191:                }
192:                if (debug) {
193:                    System.out.println("terminateThread");
194:
195:                    if (queue.size() != 0) {
196:                        System.out
197:                                .println("terminateThread with unprocessed events");
198:                    } else {
199:                        System.out
200:                                .println("terminateThread with no unprocessed events");
201:                    }
202:                }
203:
204:                if (tinstance.terminated) {
205:                    if (eventLog != null) {
206:                        eventLog.append("thread already terminated\n");
207:                    }
208:                    if (debug) {
209:                        System.out.println("thread already terminated");
210:                    }
211:
212:                    return;
213:                }
214:
215:                tinstance.terminate_request = true;
216:
217:                synchronized (tinstance) {
218:                    if (eventLog != null) {
219:                        eventLog.append("notify in terminateThread\n");
220:                    }
221:                    if (debug) {
222:                        System.out.println("notify in terminateThread");
223:                    }
224:                    tinstance.notify(); // wake up other thread
225:                }
226:            }
227:
228:            // Invoked to indicate how debug options for
229:            // this module should be setup. This method
230:            // must be invoked before compilation begins
231:            // since there options are processed when the
232:            // tmain thread starts.
233:
234:            public static synchronized void debugSetup(String dbgstr) {
235:                debugSetup = dbgstr;
236:
237:                eventLog = null;
238:
239:                // Search for known debug tokens
240:
241:                StringTokenizer st = new StringTokenizer(debugSetup);
242:                while (st.hasMoreTokens()) {
243:                    String token = (String) st.nextToken();
244:                    if (token.equals("-debug")) {
245:                        debug = true;
246:                    } else if (token.equals("-event")) {
247:                        eventLog = new StringBuffer(128);
248:                    } else if (token.equals("-pizza")) {
249:                        driver = "pizza";
250:                    } else if (token.equals("-janino")) {
251:                        driver = "janino";
252:                    }
253:                }
254:            }
255:
256:            // Invoked by test code to see if the thread
257:            // started up and is ready to process events.
258:            // Events can be queued up before the thread
259:            // is ready to start processing them.
260:
261:            public static synchronized boolean isThreadReady() {
262:                return tinstance.ready;
263:            }
264:
265:            // Invoked to query the event log, if no event log
266:            // was enabled then this method will return null.
267:
268:            public static synchronized String getEventLog() {
269:                if (eventLog == null) {
270:                    return null;
271:                }
272:                return eventLog.toString();
273:            }
274:
275:            // Invoked to explicitly start up the main
276:            // thread if it is not already running.
277:            // Test code might want to do this without
278:            // having a specific file to compile.
279:
280:            public static synchronized void startThread() {
281:                if (tinstance != null && !tinstance.terminate_request) {
282:                    // Thread already started, it is currently running,
283:                    // and a terminate request is not currently pending.
284:
285:                    if (debug) {
286:                        System.out.println("thread currently running");
287:                    }
288:
289:                    return;
290:                }
291:
292:                if (debug) {
293:                    System.out.println("creating new Thread()");
294:                }
295:
296:                tinstance = new TJCThread();
297:                tmain = new Thread(tinstance);
298:                tmain.setDaemon(true);
299:
300:                // Drop Priority of compile thread below that
301:                // of the calling thread.
302:
303:                int priority = tmain.getPriority();
304:                if (priority > Thread.MIN_PRIORITY) {
305:                    priority--;
306:                    tmain.setPriority(priority);
307:                }
308:
309:                tmain.setName("TJCThread service");
310:
311:                if (eventLog != null) {
312:                    eventLog.append("thread create\n");
313:                }
314:                if (debug) {
315:                    System.out.println("thread create");
316:                }
317:                tmain.start();
318:
319:                // Don't wait around for the other thread to
320:                // be initialized and start running.
321:            }
322:
323:            public void run() {
324:                if (eventLog != null) {
325:                    eventLog.append("thread start\n");
326:                }
327:                if (debug) {
328:                    System.out.println("thread start");
329:                }
330:
331:                // Loop forever waiting for next request to be
332:                // added to the queue.
333:
334:                while (true) {
335:                    if (terminate_request) {
336:                        break;
337:                    }
338:
339:                    // Process all events in the queue, one at
340:                    // a time starting with the first one. Be
341:                    // sure to do this in a thread safe way
342:                    // in case another thread is adding elements
343:                    // to the queue.
344:
345:                    while (true) {
346:                        Vector event;
347:                        synchronized (queue) {
348:                            if (queue.size() == 0) {
349:                                break;
350:                            }
351:                            event = (Vector) queue.remove(0);
352:                            if (debug) {
353:                                System.out.println("removed event, there are "
354:                                        + queue.size() + " events left");
355:                            }
356:                        }
357:                        // Process the event after removing it
358:                        // from the queue and releasing the
359:                        // monitor.
360:                        processEvent(event);
361:
362:                        // Bail out if thread should die
363:                        if (terminate_request) {
364:                            break;
365:                        }
366:                    }
367:
368:                    // Bail out if thread should die
369:                    if (terminate_request) {
370:                        break;
371:                    }
372:
373:                    try {
374:                        synchronized (this ) {
375:                            if (eventLog != null) {
376:                                eventLog.append("thread wait\n");
377:                            }
378:                            if (debug) {
379:                                System.out.println("thread wait");
380:                            }
381:
382:                            ready = true;
383:                            this .wait(); // wait for next service request
384:                            ready = false;
385:                        }
386:                    } catch (InterruptedException e) {
387:                        e.printStackTrace();
388:                    }
389:                    if (terminate_request) {
390:                        break;
391:                    }
392:
393:                    if (eventLog != null) {
394:                        eventLog.append("thread wakeup\n");
395:                    }
396:                    if (debug) {
397:                        System.out.println("thread wakeup");
398:                    }
399:                }
400:
401:                if (terminate_request) {
402:                    if (eventLog != null) {
403:                        eventLog.append("thread terminate request\n");
404:                    }
405:                    if (debug) {
406:                        System.out.println("thread terminate request");
407:                    }
408:                }
409:
410:                // When execution reaches the end of run() the
411:                // thread will terminate itself.
412:
413:                if (eventLog != null) {
414:                    eventLog.append("thread terminated\n");
415:                }
416:                if (debug) {
417:                    System.out.println("thread terminated");
418:                }
419:                terminated = true;
420:
421:                // Dispose of Jacl interp before leaving this
422:                // thread. It is critical that the Jacl interp
423:                // be disposed of in the same thread it was
424:                // created in.
425:
426:                if (interp != null) {
427:                    if (debug) {
428:                        System.out.println("Invoking interp.dispose()");
429:                    }
430:
431:                    interp.dispose();
432:                    interp = null;
433:                }
434:            }
435:
436:            // Invoked once for each event Vector processed in the
437:            // TJC compile thread.
438:
439:            private void processEvent(Vector event) {
440:                int len = event.size();
441:
442:                if (eventLog != null) {
443:                    eventLog.append("process event\n");
444:                }
445:                if (debug) {
446:                    System.out.println("PROCESS QUEUE EVENT: " + event);
447:                }
448:
449:                if (len != 4) {
450:                    throw new RuntimeException(
451:                            "unexpected number of event args: " + len);
452:                }
453:
454:                String type = (String) event.elementAt(0);
455:                String filename = (String) event.elementAt(1);
456:                String source = (String) event.elementAt(2);
457:                CompiledClassReady callback = (CompiledClassReady) event
458:                        .elementAt(3);
459:
460:                // Test 2, check that the callback works from the
461:                // other threads.
462:
463:                if (filename.equals("__FakeTest2.java")) {
464:                    if (eventLog != null) {
465:                        eventLog.append("Fake Java Test 2 processed\n");
466:                    }
467:                    if (debug) {
468:                        System.out.println("Fake Java Test 2 processed");
469:                    }
470:
471:                    ArrayList class_names = new ArrayList();
472:                    class_names.add("__FakeTest2");
473:
474:                    byte[] bytes = { (byte) 'F', (byte) 'A', (byte) 'K',
475:                            (byte) 'E' };
476:
477:                    ArrayList class_data = new ArrayList();
478:                    class_data.add(bytes);
479:
480:                    callback.compiled("", filename, source, class_names,
481:                            class_data, 0, "");
482:                    return;
483:                }
484:
485:                try {
486:                    // Init interp if needed
487:                    if (interp == null) {
488:                        if (eventLog != null) {
489:                            eventLog.append("Interp() and init\n");
490:                        }
491:                        if (debug) {
492:                            System.out.println("Interp() and init");
493:                        }
494:                        interp = new Interp();
495:                        if (driver != null) {
496:                            interp.setVar("JAVA_DRIVER", null, driver, 0);
497:                        }
498:                        interp
499:                                .eval("source resource:/tjc/library/tjcthread.tcl");
500:                    }
501:
502:                    if (type.equals("JAVA")) {
503:                        processJavaSource(filename, source, callback);
504:                    } else if (type.equals("TCL")) {
505:                        processTclSource(filename, source, callback);
506:                    } else {
507:                        throw new TclException(interp, "unknown type " + type);
508:                    }
509:                } catch (TclException te) {
510:                    StringBuffer msg = new StringBuffer(128);
511:                    msg.append("TclException: ");
512:
513:                    TclObject ei;
514:                    try {
515:                        ei = interp.getVar("errorInfo", null, TCL.GLOBAL_ONLY);
516:                        msg.append(ei.toString());
517:                    } catch (TclException e) {
518:                        msg.append(te.getMessage());
519:                    }
520:
521:                    if (eventLog != null) {
522:                        eventLog.append(msg.toString());
523:                        eventLog.append('\n');
524:                    }
525:                    if (debug) {
526:                        System.out.println(msg.toString());
527:                    }
528:
529:                    // Invoke callback to report error
530:
531:                    callback.compiled("", filename, source, null, null, 1, msg
532:                            .toString());
533:                }
534:            }
535:
536:            // Compile a Java source file into bytecode and invoke the callback.
537:
538:            private void processJavaSource(String filename, String source,
539:                    CompiledClassReady callback) throws TclException {
540:                if (eventLog != null) {
541:                    eventLog.append("process java source: " + filename + "\n");
542:                }
543:                if (debug) {
544:                    System.out.println("processJavaSource " + filename);
545:                }
546:
547:                TclObject cmd_obj = TclString.newInstance("processJavaSource");
548:                TclObject filename_obj = TclString.newInstance(filename);
549:                TclObject source_obj = TclString.newInstance(source);
550:
551:                TclObject list = TclList.newInstance();
552:                TclList.append(interp, list, cmd_obj);
553:                TclList.append(interp, list, filename_obj);
554:                TclList.append(interp, list, source_obj);
555:
556:                interp.eval(list, TCL.EVAL_GLOBAL);
557:
558:                // Invoke processJavaSource, this method should set the interp
559:                // result to a flat list of class names and reflected byte[]
560:                // objects.
561:
562:                TclObject result = interp.getResult();
563:                if (debug) {
564:                    System.out.println("processJavaSource interp result was: "
565:                            + result.toString());
566:                }
567:
568:                ArrayList class_names = new ArrayList();
569:                ArrayList class_data = new ArrayList();
570:
571:                final int len = TclList.getLength(interp, result);
572:                for (int i = 0; i < len; i += 2) {
573:                    TclObject name = TclList.index(interp, result, i);
574:                    TclObject reflectObj = TclList.index(interp, result, i + 1);
575:
576:                    class_names.add((String) name.toString());
577:
578:                    Object obj = ReflectObject.get(interp, reflectObj);
579:                    if (!(obj instanceof  byte[])) {
580:                        throw new TclException(interp, "obj \"" + obj
581:                                + "\" is not a byte[] instance");
582:                    }
583:
584:                    class_data.add((byte[]) obj);
585:                }
586:                interp.resetResult();
587:
588:                callback.compiled("", filename, source, class_names,
589:                        class_data, 0, "");
590:            }
591:
592:            // Compile a Tcl source file into bytecode and invoke the callback.
593:
594:            private void processTclSource(String filename, String source,
595:                    CompiledClassReady callback) throws TclException {
596:                TclObject cmd_obj, filename_obj, source_obj, list;
597:
598:                if (eventLog != null) {
599:                    eventLog.append("process tcl source: " + filename + "\n");
600:                }
601:                if (debug) {
602:                    System.out.println("processTclSource " + filename);
603:                }
604:
605:                // Invoke the processTclSource Tcl command to generate Java
606:                // code from the Tcl proc declaration.
607:
608:                cmd_obj = TclString.newInstance("processTclSource");
609:                filename_obj = TclString.newInstance(filename);
610:                source_obj = TclString.newInstance(source);
611:
612:                list = TclList.newInstance();
613:                TclList.append(interp, list, cmd_obj);
614:                TclList.append(interp, list, filename_obj);
615:                TclList.append(interp, list, source_obj);
616:
617:                interp.eval(list, TCL.EVAL_GLOBAL);
618:
619:                // The result object from processTclSource is a list
620:                // containing the generated proc name and the generated
621:                // Java source code. Pass the Java source code to
622:                // the processJavaSource Tcl command.
623:
624:                TclObject processTclSourceResult = interp.getResult();
625:                String proc_name = TclList.index(interp,
626:                        processTclSourceResult, 0).toString();
627:                String java_source = TclList.index(interp,
628:                        processTclSourceResult, 1).toString();
629:
630:                if (debug) {
631:                    System.out.println("processTclSource interp result was:\n"
632:                            + java_source);
633:                }
634:
635:                cmd_obj = TclString.newInstance("processJavaSource");
636:                filename_obj = TclString.newInstance(filename);
637:                source_obj = TclString.newInstance(java_source);
638:
639:                list = TclList.newInstance();
640:                TclList.append(interp, list, cmd_obj);
641:                TclList.append(interp, list, filename_obj);
642:                TclList.append(interp, list, source_obj);
643:
644:                interp.eval(list, TCL.EVAL_GLOBAL);
645:
646:                // The processJavaSource command will set the interp
647:                // result to a flat list of class names and reflected
648:                // byte[] objects.
649:
650:                TclObject result = interp.getResult();
651:                if (debug) {
652:                    System.out.println("processTclSource interp result was: "
653:                            + result.toString());
654:                }
655:
656:                ArrayList class_names = new ArrayList();
657:                ArrayList class_data = new ArrayList();
658:
659:                final int len = TclList.getLength(interp, result);
660:                for (int i = 0; i < len; i += 2) {
661:                    TclObject name = TclList.index(interp, result, i);
662:                    TclObject reflectObj = TclList.index(interp, result, i + 1);
663:
664:                    class_names.add((String) name.toString());
665:
666:                    Object obj = ReflectObject.get(interp, reflectObj);
667:                    if (!(obj instanceof  byte[])) {
668:                        throw new TclException(interp, "obj \"" + obj
669:                                + "\" is not a byte[] instance");
670:                    }
671:
672:                    class_data.add((byte[]) obj);
673:                }
674:                interp.resetResult();
675:
676:                callback.compiled(proc_name, filename, java_source,
677:                        class_names, class_data, 0, "");
678:            }
679:
680:            // Invoked when TJCThread is garbage collected.
681:
682:            protected void finalize() throws Throwable {
683:                if (debug) {
684:                    System.out.println("TJCThread finalized");
685:                }
686:
687:                super.finalize();
688:            }
689:
690:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.