EMMA Coverage Report (generated Mon Mar 20 21:34:30 PST 2006)
[all classes][com.moesol.bindings.platform_sdk.component_services]

COVERAGE SUMMARY FOR SOURCE FILE [OleThread.java]

nameclass, %method, %block, %line, %
OleThread.java100% (2/2)81%  (17/21)69%  (225/326)74%  (73.6/99)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class OleThread100% (1/1)78%  (14/18)68%  (202/299)73%  (64.6/88)
attachCurrent (): void 0%   (0/1)0%   (0/15)0%   (0/5)
finalize (): void 0%   (0/1)0%   (0/3)0%   (0/2)
oleUninitialize (): void 0%   (0/1)0%   (0/2)0%   (0/2)
release (): void 0%   (0/1)0%   (0/10)0%   (0/4)
invokeAndWaitOrRuntimeException (Runnable): void 100% (1/1)26%  (5/19)43%  (3/7)
invokeLater (Runnable): void 100% (1/1)53%  (16/30)83%  (5/6)
safeInvokeAndWait (Runnable): void 100% (1/1)68%  (13/19)80%  (4/5)
invokeAndWait (Runnable): void 100% (1/1)73%  (51/70)92%  (13.8/15)
startAndInit (): void 100% (1/1)76%  (19/25)75%  (6/8)
simpleInvokeAndWait (Runnable): void 100% (1/1)77%  (10/13)80%  (4/5)
run (): void 100% (1/1)86%  (32/37)98%  (10.8/11)
<static initializer> 100% (1/1)100% (7/7)100% (2/2)
OleThread (String): void 100% (1/1)100% (15/15)100% (6/6)
conditionalThrowNotStartedExcpt (): void 100% (1/1)100% (18/18)100% (3/3)
getCurrentOleThread (): OleThread 100% (1/1)100% (4/4)100% (1/1)
getJavaThread (): Thread 100% (1/1)100% (3/3)100% (1/1)
oleInitialize (): void 100% (1/1)100% (2/2)100% (2/2)
stopAndDeinit (): void 100% (1/1)100% (7/7)100% (3/3)
     
class OleThread$1SafeRunner100% (1/1)100% (3/3)85%  (23/27)82%  (9/11)
run (): void 100% (1/1)56%  (5/9)60%  (3/5)
OleThread$1SafeRunner (OleThread, Runnable): void 100% (1/1)100% (15/15)100% (5/5)
getError (): Error 100% (1/1)100% (3/3)100% (1/1)

1/*
2 * $Id: OleThread.java,v 1.5 2005/12/22 19:37:15 hastings Exp $
3 *
4 * (c) Copyright, Moebius Solutions, Inc., 2004
5 *
6 *                       All Rights Reserved
7 *
8 * This material may be reproduced by or for the U. S. Government
9 * pursuant to the copyright license under the clause at
10 * DFARS 252.227-7014 (OCT 2001).
11 */
12 
13package com.moesol.bindings.platform_sdk.component_services;
14 
15import java.lang.reflect.InvocationTargetException;
16 
17import com.moesol.bindings.NativeLibraryLoader;
18import com.moesol.bindings.platform_sdk.windows_api.MSG;
19import com.moesol.bindings.platform_sdk.windows_api.PlatformSDK;
20 
21/**
22 * Creates a COM/OLE Apartment Thread. In the COM/OLE architecture
23 * Aparment threads must pump windows messages. OleThread satisfies this
24 * requirement. Typical usage is to create a subclass that is a singleton.
25 * <pre>
26 * public class MyOleThread extends OleThread {
27 *     private MyOleThread() {
28 *         super("MyOleThread");
29 *     }
30 *     public static synchronized MyOleThread instance() {
31 *         if (s_instance == null) {
32 *             s_instance = new MyOleThread();
33 *             s_instance.startAndInit();
34 *         }
35 *         return s_instance;
36 *     }
37 *
38 *     private static MyOleThread s_instance = null;
39 * }
40 * </pre>
41 * 
42 * You can use invokeLater and invokeAndWait in a similar manner as the 
43 * EventQueue.
44 * <pre>
45 * MyOleThread.instance().invokeLater(new Runnable() {
46 *     public void run() {
47 *         // code that runs on MyOleThread and in the
48 *         // MyOleThread apartment.
49 *     }
50 * });
51 * </pre>
52 * 
53 * @version $Revision: 1.5 $ $Date: 2005/12/22 19:37:15 $
54 */
55public class OleThread implements Runnable {
56        static {
57                NativeLibraryLoader.loadLibrary("com_moesol_bindings");
58        }
59 
60    public OleThread(String name) {
61        m_java_thread_name = name;
62        com_ptr = JNIOleThread();
63    }
64    public void finalize() {
65        release();
66    }
67    public Thread getJavaThread() {
68        return m_java_thread;
69    }
70    public static OleThread getCurrentOleThread() {
71            return (OleThread)s_current_ole_thread.get();
72    }
73    public static void oleInitialize() {
74        JNIoleInitialize();
75    }
76    public static void oleUninitialize() {
77        JNIoleUninitialize();
78    }
79    public synchronized void startAndInit() {
80        m_java_thread = new Thread(this, m_java_thread_name);
81        m_java_thread.setDaemon(true);
82        m_java_thread.start();
83        try {
84                        wait();
85                } catch (InterruptedException e) {
86                        throw new RuntimeException("failed to init ole thread");
87                }
88    }
89    public synchronized void attachCurrent() {
90                s_current_ole_thread.set(this);
91                
92        m_java_thread = Thread.currentThread();
93        m_java_thread_name = m_java_thread.getName();
94        JNIcreateWindow(com_ptr);
95    }
96    public synchronized void stopAndDeinit() {
97        m_stopping = true;
98        JNIpostQuit(com_ptr);
99    }
100    public void run() {
101            s_current_ole_thread.set(this);
102            
103        JNIoleInitialize();
104        JNIcreateWindow(com_ptr);
105        synchronized (this) {
106            notify();
107        }
108        MSG msg = new MSG();
109        while (PlatformSDK.GetMessage(msg, null, 0, 0)) {
110                PlatformSDK.DispatchMessage(msg);
111        }
112        
113        JNIoleUninitialize();
114    }
115    public void invokeLater(Runnable runable) {
116            conditionalThrowNotStartedExcpt();
117        if (m_stopping) {
118            throw new IllegalStateException("OleThread " + this + " stopping.");
119        }
120        java.awt.event.InvocationEvent inv_evt
121            = new java.awt.event.InvocationEvent(this, runable);
122        JNIpostEvent(com_ptr, inv_evt);
123    }
124    public void invokeAndWait(Runnable runable)
125        throws InterruptedException, java.lang.reflect.InvocationTargetException
126    {
127            conditionalThrowNotStartedExcpt();
128        if (Thread.currentThread() == getJavaThread()) {
129            throw new IllegalStateException("already on the ole thread");
130        }
131        if (m_stopping) {
132            throw new IllegalStateException("OleThread " + this + " stopping.");
133        }
134 
135        Object signal = new Object();
136        java.awt.event.InvocationEvent inv_evt
137            = new java.awt.event.InvocationEvent(this, runable, signal, true);
138 
139        // argv, you really cannot assert anything about
140        // what the GC will do. These assert's fail sometimes
141        // because the GC has not released these refs yet.
142        // AssertNoReference ref_inv_evt = null;
143        // assert(null != (ref_inv_evt = new AssertNoReference(inv_evt)));
144 
145        synchronized (signal) {
146            JNIpostEvent(com_ptr, inv_evt);
147            signal.wait();
148        }
149        
150        if (inv_evt.getException() != null) {
151            throw new java.lang.reflect.InvocationTargetException(inv_evt.getException());
152        }
153        
154        inv_evt = null;
155        // assert(!ref_inv_evt.isReferenced());
156    }
157    
158    /**
159     * Call invokeAndWait and wrap exceptions in a RuntimeException.
160     * This method makes calling invokeAndWait easy by mapping checked expections
161     * to runtime exceptions.
162     * 
163     * @param runnable
164     */
165    public void invokeAndWaitOrRuntimeException(Runnable runnable) {
166        try {
167            invokeAndWait(runnable);
168        } catch (InterruptedException e ) {
169            throw new RuntimeException("invokeAndWait interrupted", e);
170        } catch (InvocationTargetException e) {
171                // TODO consider unwrapping the target exceptions cause here...
172            throw new RuntimeException("invokeAndWait caused InvocationTargetException", e);
173        }
174    }
175    
176    /**
177     * Call invokeAndWaitOrRuntimeException unless we are already running
178     * on the thread associated with this OleThread.
179     * 
180     * @param runnable
181     * @deprecated Use safeInvokeAndWait instead.
182     */
183    public void simpleInvokeAndWait(Runnable runnable) {
184            conditionalThrowNotStartedExcpt();
185        if (Thread.currentThread() == getJavaThread()) {
186            runnable.run();
187        } else {
188            invokeAndWaitOrRuntimeException(runnable);
189        }
190    }
191    
192    /**
193     * Call simpleInvokeAndWait, but wrap any Error thrown in a RuntimeException
194     * so that the error will propagate back to the caller.
195     */
196    public void safeInvokeAndWait(Runnable runnable) {
197            class SafeRunner implements Runnable {
198                    public SafeRunner(Runnable real_runnable) {
199                            m_real_runnable = real_runnable;
200                    }
201                        public void run() {
202                                try {
203                                        m_real_runnable.run();
204                                } catch (Error e) {
205                                        m_error = e;
206                                }
207                        }
208                        public Error getError() {
209                                return m_error;
210                        }
211                        
212                    private Runnable m_real_runnable = null;
213                    private Error m_error = null;
214            }
215            final SafeRunner sr = new SafeRunner(runnable);
216            simpleInvokeAndWait(sr);
217            if (sr.getError() != null) {
218                    throw new RuntimeException(sr.getError());
219            }
220    }
221    
222    private void release() {
223        if (com_ptr != 0) {
224            JNIrelease(com_ptr);
225            com_ptr = 0;
226        }
227    }
228    
229    private void conditionalThrowNotStartedExcpt() {
230            if (m_java_thread == null) {
231                    throw new IllegalStateException("OleThread " + this + " has not been started or attached.");
232            }
233    }
234    
235    private static native void JNIoleInitialize();
236    private static native void JNIoleUninitialize();
237    private static native int JNIOleThread();
238    private static native void JNIrelease(int com_ptr);
239    private static native void JNIcreateWindow(int com_ptr);
240    private static native void JNIpostEvent(int com_ptr, java.awt.event.InvocationEvent inv_evt);
241    private static native void JNIpostQuit(int com_ptr);
242    
243    private static ThreadLocal s_current_ole_thread = new ThreadLocal();
244    /**
245     * Java thread we are attached to
246     */
247    private Thread m_java_thread;
248    private String m_java_thread_name;
249    /**
250     * COM pointer for peer COM object.
251     */
252    private int com_ptr = 0;
253    /** Set once we are stopping */
254    private boolean m_stopping = false;
255}

[all classes][com.moesol.bindings.platform_sdk.component_services]
EMMA 2.0.5312 (C) Vladimir Roubtsov