EMMA Coverage Report (generated Wed Apr 19 22:57:21 CEST 2006)
[all classes][com.eaio.nativecall]

COVERAGE SUMMARY FOR SOURCE FILE [NativeCall.java]

nameclass, %method, %block, %line, %
NativeCall.java100% (1/1)100% (12/12)86%  (228/266)88%  (66,3/75)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class NativeCall100% (1/1)100% (12/12)86%  (228/266)88%  (66,3/75)
NativeCall (String, String): void 100% (1/1)58%  (18/31)67%  (6/9)
finalize (): void 100% (1/1)69%  (9/13)88%  (4,4/5)
init (): void 100% (1/1)78%  (14/18)88%  (7/8)
toStringBuffer (StringBuffer): StringBuffer 100% (1/1)82%  (55/67)86%  (12/14)
equals (Object): boolean 100% (1/1)90%  (35/39)86%  (6,9/8)
check (Object []): void 100% (1/1)97%  (34/35)91%  (10/11)
<static initializer> 100% (1/1)100% (3/3)100% (2/2)
NativeCall (String): void 100% (1/1)100% (6/6)100% (2/2)
checkParam (Object): void 100% (1/1)100% (34/34)100% (11/11)
getLastErrorCode (): int 100% (1/1)100% (3/3)100% (1/1)
hashCode (): int 100% (1/1)100% (12/12)100% (3/3)
toString (): String 100% (1/1)100% (5/5)100% (1/1)

1/* 
2 * NativeCall.java
3 * 
4 * Created on 07.09.2004.
5 *
6 * eaio: NativeCall - calling operating system methods from Java
7 * Copyright (c) 2004-2006 Johann Burkard (<mailto:jb@eaio.com>)
8 * <http://eaio.com>
9 * 
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 * 
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 * 
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
23 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 * USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 */
29package com.eaio.nativecall;
30 
31import java.io.IOException;
32 
33import sun.misc.ServiceConfigurationError;
34 
35import com.eaio.util.lang.NativeLoader;
36 
37/**
38 * NativeCall loads the native library and prepares the matching
39 * {@link com.eaio.nativecall.Verifier}.
40 * <p>
41 * Before being able to use NativeCall, the {@link #init()} method must have
42 * been called:
43 * <pre>
44 * try {
45 *     NativeCall.init();
46 * }
47 * catch (IOException ex) { ... }
48 * catch (SecurityException ex) { ... }
49 * catch (UnsatisfiedLinkError er) { ... }
50 * catch (sun.misc.ServiceConfigurationError) { ... }
51 * catch (UnsupportedOperationException) { ... }
52 * </pre>
53 * After usage, each NativeCall object must be destroyed to release 
54 * resources. This is done by calling the {@link #destroy()} method. Failure
55 * to call this method might result in memory leaks.
56 * 
57 * @see #destroy()
58 * @see #init()
59 * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
60 * @version $Id: NativeCall.java,v 1.3 2006/04/19 20:54:58 grnull Exp $
61 */
62public abstract class NativeCall {
63 
64    /**
65     * The error code of the last call.
66     * <p>
67     * Accessed by native code. DO NOT RENAME THIS FIELD.
68     */
69    private int lastErrorCode;
70 
71    /**
72     * The internal handle to the function and the module.
73     * <p>
74     * These are set in native code, so ignore any warnings.
75     * <p>
76     * Accessed by native code. DO NOT RENAME THIS FIELD.
77     */
78    private int functionHandle, moduleHandle;
79 
80    /**
81     * The name of the function to call.
82     * <p>
83     * Accessed by native code. DO NOT RENAME THIS FIELD.
84     */
85    private String function;
86 
87    /**
88     * The name of the module to call.
89     * <p>
90     * Accessed by native code. DO NOT RENAME THIS FIELD.
91     */
92    private String module;
93 
94    /**
95     * Initialize JNI field and method IDs
96     */
97    private static native void initIDs();
98 
99    /**
100     * Whether the class has been initialized properly.
101     */
102    private static boolean initialized = false;
103 
104    /**
105     * Before NativeCall may be used, this method must be called.
106     * It loads the native library, prepares JNI field and method IDs and loads
107     * the matching {@link Verifier}.
108     * <p>
109     * Multiple calls are ignored.
110     * 
111     * @throws IOException if an IOException occured during unpacking of
112     * the native library
113     * @throws SecurityException if accessing system properties was forbidden
114     * by the {@link SecurityManager}
115     * @throws UnsatisfiedLinkError if the <code>NativeCall.dll</code> could
116     * not be found
117     * @throws sun.misc.ServiceConfigurationError
118     * @throws UnsupportedOperationException if no matching
119     * {@link Verifier} could be found
120     */
121    public static synchronized void init()
122        throws
123            IOException,
124            SecurityException,
125            UnsatisfiedLinkError,
126            ServiceConfigurationError,
127            UnsupportedOperationException {
128        if (!initialized) {
129            Verifiers.init();
130            if (Verifiers.getInstance() == null) {
131                throw new UnsupportedOperationException();
132            }
133            new NativeLoader("NativeCall").load();
134            initIDs();
135            initialized = true;
136        }
137    }
138 
139    /**
140     * Constructor for NativeCall.
141     * 
142     * @param function the name of the function to use, may not be
143     * <code>null</code>
144     * @throws IllegalArgumentException if the function could not be found
145     * @throws NullPointerException if function is <code>null</code>
146     * @see Verifier#getDefaultModule()
147     * @see NativeCall#NativeCall(String, String)
148     */
149    public NativeCall(String function)
150        throws IllegalArgumentException, NullPointerException {
151        this(Verifiers.getInstance().getDefaultModule(), function);
152    }
153 
154    /**
155     * Constructor for NativeCall.
156     * 
157     * @param module the name of the module the function is stored in, may be
158     * <code>null</code>
159     * @param function the name of the function to use, may not be
160     * <code>null</code>
161     * @throws IllegalArgumentException if the function could not be found
162     * @throws NullPointerException if function is <code>null</code>
163     */
164    public NativeCall(String module, String function)
165        throws IllegalArgumentException, NullPointerException {
166        Verifier v = Verifiers.getInstance();
167        this.function = v.verifyFunctionName(function);
168        this.module = v.verifyModuleName(module);
169        if (!initHandles()) {
170            if (lastErrorCode != 0) {
171                throw new IllegalArgumentException(getLastError());
172            }
173            throw new IllegalArgumentException();
174        }
175    }
176 
177    /**
178     * Attempts to acquire handles to the functions. Returns if these could be
179     * acquired.
180     * 
181     * @return if the handles could be acquired
182     */
183    private native boolean initHandles();
184 
185    /**
186     * Returns the error code that was returned during the last method call or
187     * 0 if the last method call did not produce an error.
188     * 
189     * @see #getLastError()
190     * @return the last error code or 0
191     */
192    public final int getLastErrorCode() {
193        return lastErrorCode;
194    }
195 
196    /**
197     * Returns a formatted String containing the last error code or
198     * <code>null</code> if the last call did not produce an error.
199     * 
200     * @see #getLastErrorCode()
201     * @return a String or <code>null</code> if the last error code is 0
202     */
203    public final native String getLastError();
204 
205    /**
206     * Releases acquired module handles. This method must be called if the
207     * instance is not used anymore. After this method is called, methods of this
208     * NativeCall Object cannot be called anymore.
209     * <p>
210     * <strong>Failure to call this method might result in memory leaks.</strong>
211     * <p>
212     * <em>Updates the error code field. See {@link #getLastError()}.</em>
213     */
214    public native synchronized void destroy();
215 
216    /**
217     * Checks the supplied Object array for illegal/unsupported types.
218     * <p>
219     * <strong>During the verification, the contents of the array might be
220     * changed.</strong>
221     * 
222     * @param params the Object array, may be <code>null</code>
223     * @throws ClassCastException if the type of one argument is not supported
224     */
225    protected void check(Object[] params) throws ClassCastException {
226        if (params == null) {
227            return;
228        }
229        for (int i = 0; i < params.length; ++i) {
230            checkParam(params[i]);
231            if (params[i] instanceof String) {
232                params[i] =
233                    Verifiers.getInstance().handleString(
234                        (String) params[i],
235                        module,
236                        function);
237            }
238        }
239    }
240 
241    /**
242     * Checks one Object for illegal/unsupported types.
243     * 
244     * @param o the Object, may be <code>null</code>
245     * @throws ClassCastException if the type of one argument is not supported
246     */
247    protected void checkParam(Object o) throws ClassCastException {
248        if (o == null
249            || o instanceof Boolean
250            || o instanceof Integer
251            || o instanceof byte[]
252            || o instanceof char[]
253            || o instanceof String) {
254            return;
255        }
256        if (o instanceof Holder) {
257            checkParam(((Holder) o).get());
258            return;
259        }
260        throw new ClassCastException(o.getClass().getName());
261    }
262 
263    /**
264     * Returns if this Object is equal to another Object. The other Object must
265     * be an instance of the same type as this Object. Also, both the module
266     * and the function field must be equal.
267     * 
268     * @param obj the other Object
269     * @return if this and the other Object are equal
270     * @see java.lang.Object#equals(java.lang.Object)
271     */
272    public boolean equals(Object obj) {
273        if (this == obj) {
274            return true;
275        }
276        if (!(obj instanceof NativeCall)) {
277            return false;
278        }
279        if (!getClass().getName().equals(obj.getClass().getName())) {
280            return false;
281        }
282        NativeCall c = (NativeCall) obj;
283        return module.equals(c.module) && function.equals(c.function);
284    }
285 
286    /**
287     * Returns the hashCode of this Object. The hashCode is computed by XOR'ing
288     * the hash codes of the function and the module names.
289     * 
290     * @return the hashCode
291     * @see java.lang.Object#hashCode()
292     */
293    public int hashCode() {
294        int out = function.hashCode();
295        out ^= module.hashCode();
296        return out;
297    }
298 
299    /**
300     * Calls {@link #destroy()}.
301     * 
302     * @see java.lang.Object#finalize()
303     */
304    protected void finalize() throws Throwable {
305        try {
306            destroy();
307        }
308        finally {
309            super.finalize();
310            // in case NativeCall is a subclass of a class other than Object
311        }
312    }
313 
314    /**
315     * Returns a String representation of this Object.
316     * 
317     * @return a String, never <code>null</code>
318     * @see java.lang.Object#toString()
319     * @see #toStringBuffer(StringBuffer)
320     */
321    public final String toString() {
322        return toStringBuffer(null).toString();
323    }
324 
325    /**
326     * Appends a String representation of this Object to the given
327     * {@link StringBuffer} or creates a new one if none is given.
328     * 
329     * @param in the StringBuffer to append to, may be <code>null</code>
330     * @return a StringBuffer, never <code>null</code>
331     */
332    public StringBuffer toStringBuffer(StringBuffer in) {
333        if (in == null) {
334            in = new StringBuffer(64);
335        }
336        else {
337            in.ensureCapacity(in.length() + 64);
338        }
339        in.append("{ ");
340        int idx = getClass().getName().lastIndexOf(".");
341        if (idx > -1) {
342            in.append(getClass().getName().substring(++idx));
343        }
344        else {
345            in.append(getClass().getName());
346        }
347        in.append(": module = ");
348        in.append(module);
349        in.append(", function = ");
350        in.append(function);
351        in.append(" }");
352        return in;
353    }
354 
355}

[all classes][com.eaio.nativecall]
EMMA 2.0.4217 (C) Vladimir Roubtsov