pax_global_header00006660000000000000000000000064114266500650014517gustar00rootroot0000000000000052 comment=34a06955314d02daa96c8c7ad5e3aa31b5ec637c hawtjni-1.0~+git0c502e20c4/000077500000000000000000000000001142665006500152105ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/.gitignore000066400000000000000000000001261142665006500171770ustar00rootroot00000000000000.classpath .project .settings *.iml *.ipr *.iws webgen/out webgen/webgen.cache target hawtjni-1.0~+git0c502e20c4/hawtjni-example/000077500000000000000000000000001142665006500203055ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/pom.xml000066400000000000000000000073531142665006500216320ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-pom 1.1-SNAPSHOT org.fusesource.hawtjni hawtjni-example 1.1-SNAPSHOT HawtJNI Example org.fusesource.hawtjni hawtjni-runtime 1.1-SNAPSHOT junit junit 4.7 test log4j log4j 1.2.14 test org.apache.maven.plugins maven-clean-plugin 2.3 org.fusesource.hawtjni maven-hawtjni-plugin 1.1-SNAPSHOT generate build package-jar package-source org.apache.maven.plugins maven-shade-plugin 1.3 package shade junit:junit hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/000077500000000000000000000000001142665006500210745ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/000077500000000000000000000000001142665006500220205ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/java/000077500000000000000000000000001142665006500227415ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/java/test/000077500000000000000000000000001142665006500237205ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/java/test/Example.java000077500000000000000000000246241142665006500261710ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package test; import java.util.Arrays; import org.fusesource.hawtjni.runtime.ClassFlag; import org.fusesource.hawtjni.runtime.JniArg; import org.fusesource.hawtjni.runtime.JniClass; import org.fusesource.hawtjni.runtime.JniField; import org.fusesource.hawtjni.runtime.JniMethod; import org.fusesource.hawtjni.runtime.Library; import static org.fusesource.hawtjni.runtime.ArgFlag.*; import static org.fusesource.hawtjni.runtime.FieldFlag.*; import static org.fusesource.hawtjni.runtime.MethodFlag.*; /** * * @author Hiram Chirino */ @JniClass public class Example { private static final Library LIBRARY = new Library("hawtjni-example", Example.class); static { LIBRARY.load(); init(); } public static final void main(String args[]) { System.out.println("Checking Operating System Constants:"); System.out.println(" O_RDONLY: "+O_RDONLY); System.out.println(" O_WRONLY: "+O_WRONLY); System.out.println(" O_RDWR: "+O_RDWR); System.out.println(""); System.out.println("Allocating c structures on the heap..."); int COUNT = 10; // We track memory pointers with longs. long []ptrArray = new long[COUNT]; long last=0; for( int i=0; i < COUNT; i++ ) { // Allocate heap space of the structure.. ptrArray[i] = malloc(foo.SIZEOF); // Configure some data for a structure... foo f = new foo(); f.a = i; f.b = 1; byte[] src = "hello world".getBytes(); System.arraycopy(src, 0, f.c, 0, src.length); f.c5 = 0; f.prev = last; // Copy the data values into the allocated space. memmove(ptrArray[i], f, foo.SIZEOF); last = ptrArray[i]; } // Display a couple of structures... System.out.println("Dump of the first 2 structures:"); print_foo(ptrArray[0]); print_foo(ptrArray[1]); System.out.println("Passing a pointer array to a c function..."); long rc = foowork(ptrArray, COUNT); System.out.println("Function result (expecting 55): "+rc); System.out.println("freein up allocated memory."); for( int i=0; i < COUNT; i++ ) { free(ptrArray[i]); } } // Example of how to load constants. @JniMethod(flags={CONSTANT_INITIALIZER}) private static final native void init(); @JniField(flags={CONSTANT}) public static int O_RDONLY; @JniField(flags={CONSTANT}) public static int O_WRONLY; @JniField(flags={CONSTANT}) public static int O_RDWR; @JniMethod(cast="void *") public static final native long malloc( @JniArg(cast="size_t") long size); public static final native void free( @JniArg(cast="void *") long ptr); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) short[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) int[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) long[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) float[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) double[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) char[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) short[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) long[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) float[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) double[] dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, @JniArg(cast="size_t") long size); @JniMethod(cast="void *") public static final native long memset ( @JniArg(cast="void *") long buffer, int c, @JniArg(cast="size_t") long num); public static final native int strlen( @JniArg(cast="char *")long s); @JniClass(flags={ClassFlag.STRUCT}) static public class foo { static { LIBRARY.load(); init(); } @JniMethod(flags={CONSTANT_INITIALIZER}) private static final native void init(); // public static final native int foo_sizeof (); @JniField(flags={CONSTANT}, accessor="sizeof(struct foo)") public static int SIZEOF; public int a; @JniField(cast="size_t") public long b; public byte c[] = new byte[20]; @JniField(accessor="c[5]") public byte c5; @JniField(cast="void *") public long prev; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + a; result = prime * result + (int) (b ^ (b >>> 32)); result = prime * result + Arrays.hashCode(c); result = prime * result + c5; result = prime * result + (int) (prev ^ (prev >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; foo other = (foo) obj; if (a != other.a) return false; if (b != other.b) return false; if (!Arrays.equals(c, other.c)) return false; if (c5 != other.c5) return false; if (prev != other.prev) return false; return true; } @Override public String toString() { return "foo [a=" + a + ", b=" + b + ", c=" + Arrays.toString(c) + ", c5=" + c5 + ", prev=" + prev + "]"; } } public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) foo src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) foo dest, @JniArg(cast="const void *") long src, @JniArg(cast="size_t") long size); public static final native void print_foo(@JniArg(cast="struct foo *")long ptr); public static final native long foowork (@JniArg(cast="struct foo **") long[] foos, int count); @JniClass(flags={ClassFlag.STRUCT, ClassFlag.TYPEDEF}) static public class point { static { LIBRARY.load(); init(); } @JniMethod(flags={CONSTANT_INITIALIZER}) private static final native void init(); @JniField(flags={CONSTANT}, accessor="sizeof(point)") public static int SIZEOF; public int x; public int y; } public static final native void callmeback(@JniArg(cast="void *")long ptr); } hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/java/test/ObjectiveCExample.java000066400000000000000000000054231142665006500301200ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package test; import org.fusesource.hawtjni.runtime.JniArg; import org.fusesource.hawtjni.runtime.JniClass; import org.fusesource.hawtjni.runtime.JniMethod; import org.fusesource.hawtjni.runtime.Library; import static org.fusesource.hawtjni.runtime.ArgFlag.*; import static org.fusesource.hawtjni.runtime.MethodFlag.*; /** * * @author Hiram Chirino */ @JniClass(conditional="defined(__APPLE__)") public class ObjectiveCExample { private static final Library LIBRARY = new Library("hawtjni-example", Example.class); static { LIBRARY.load(); } public static final void main(String args[]) { // Memory pool... long NSAutoreleasePool = objc_getClass("NSAutoreleasePool"); long pool = $($(NSAutoreleasePool, alloc), init); // Allocate and use a simple Objective C object long NSString = objc_getClass("NSString"); long id = $(NSString, stringWithUTF8String, "Hello"); long value = $(id, length); System.out.println("The length was: "+value); // Release the pool to release the allocations.. $(pool, release); } public static final long stringWithUTF8String = sel_registerName("stringWithUTF8String:"); public static final long release = sel_registerName("release"); public static final long alloc = sel_registerName("alloc"); public static final long init = sel_registerName("init"); public static final long length = sel_registerName("length"); @JniMethod(cast="SEL", flags={POINTER_RETURN}) public static final native long sel_registerName(String selectorName); @JniMethod(cast="id", flags={POINTER_RETURN}) public static final native long objc_getClass(String className); @JniMethod(cast="id", flags={POINTER_RETURN}, accessor="objc_msgSend") public static final native long $( @JniArg(cast="id", flags={POINTER_ARG})long id, @JniArg(cast="SEL", flags={POINTER_ARG})long sel ); @JniMethod(cast="id", flags={POINTER_RETURN}, accessor="objc_msgSend") public static final native long $( @JniArg(cast="id", flags={POINTER_ARG})long id, @JniArg(cast="SEL", flags={POINTER_ARG})long sel, String arg0); } hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/native-package/000077500000000000000000000000001142665006500246775ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/native-package/src/000077500000000000000000000000001142665006500254665ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/native-package/src/foo.c000066400000000000000000000015711142665006500264210ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ #include "foo.h" #include void print_foo(struct foo *arg) { printf("foo@%p: { a: %d, b: %d, c: \"%s\", prev: @%p}\n", arg, arg->a, (int)arg->b, arg->c, arg->prev); } long foowork(struct foo **arg, int count) { long rc=0; int i=0; for( i=0; i < count; i++ ) { rc = rc + (*arg)->a; rc = rc + (*arg)->b; arg++; } return rc; } long callmeback(void (*thecallback)(int number)) { thecallback(69); } hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/native-package/src/foo.h000066400000000000000000000015241142665006500264240ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ #ifndef INCLUDED_FOO_H #define INCLUDED_FOO_H #include struct foo { int a; size_t b; char c[20]; struct foo *prev; }; typedef struct _point { int x; int y; } point; void print_foo(struct foo *arg); long foowork(struct foo **arg, int count); long callmeback(void (*thecallback)(int number)); #endif /* INCLUDED_FOO_H */ hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/main/native-package/src/hawtjni-example.h000066400000000000000000000020251142665006500307330ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ #ifndef INCLUDED_PLATFORM_H #define INCLUDED_PLATFORM_H #ifdef HAVE_CONFIG_H /* configure based build.. we will use what it discovered about the platform */ #include "config.h" #else #ifdef WIN32 /* Windows based build */ #define HAVE_STDLIB_H 1 #define HAVE_STRINGS_H 1 #endif #endif #ifdef __APPLE__ #import #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include "foo.h" #endif /* INCLUDED_PLATFORM_H */ hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/test/000077500000000000000000000000001142665006500220535ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/test/java/000077500000000000000000000000001142665006500227745ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/test/java/test/000077500000000000000000000000001142665006500237535ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-example/src/test/java/test/ExampleTest.java000066400000000000000000000033641142665006500270570ustar00rootroot00000000000000package test; import static org.junit.Assert.*; import static test.Example.*; import org.fusesource.hawtjni.runtime.Callback; import org.junit.Test; import test.Example.foo; public class ExampleTest { static private int staticCallbackResult; private int instanceCallbackResult; @Test public void test() { // Allocate and initialize some memory on the heap. long ptr = malloc(foo.SIZEOF); memset(ptr, 0, foo.SIZEOF); // Configure an object that can be mapped to a C structure. foo expected = new foo(); expected.a = 35; expected.b = Integer.MAX_VALUE; System.arraycopy("Hello World!".getBytes(), 0, expected.c, 0, 5); // Marshal the object to the allocated heap memory memmove(ptr, expected, foo.SIZEOF); // Unmarshal the object from the allocated heap memory. foo acutal = new foo(); memmove(acutal, ptr, foo.SIZEOF); assertEquals(expected, acutal); Callback callback = new Callback(this, "instanceCallback", 1); callmeback(callback.getAddress()); assertEquals(69, instanceCallbackResult); callback.dispose(); callback = new Callback(ExampleTest.class, "staticCallback", 1); callmeback(callback.getAddress()); assertEquals(69, staticCallbackResult); callback.dispose(); // Heap memory is not GCed, we must manually free it. free(ptr); } public long instanceCallback(long value) { this.instanceCallbackResult = (int) value; return 0; } static public long staticCallback(long value) { staticCallbackResult = (int) value; return 0; } } hawtjni-1.0~+git0c502e20c4/hawtjni-generator/000077500000000000000000000000001142665006500206405ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/pom.xml000066400000000000000000000056651142665006500221710ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-pom 1.1-SNAPSHOT org.fusesource.hawtjni hawtjni-generator 1.1-SNAPSHOT HawtJNI Generator This module contains the JNI code generation tools. org.fusesource.hawtjni hawtjni-runtime 1.1-SNAPSHOT xbean-finder org.apache.xbean 3.6 asm asm 3.1 asm asm-commons 3.1 commons-cli commons-cli 1.0 org.apache.maven.plugins maven-shade-plugin 1.3 package shade junit:junit hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/000077500000000000000000000000001142665006500214275ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/000077500000000000000000000000001142665006500223535ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/000077500000000000000000000000001142665006500232745ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/000077500000000000000000000000001142665006500240635ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/000077500000000000000000000000001142665006500262465ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001142665006500277125ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/000077500000000000000000000000001142665006500317005ustar00rootroot00000000000000CleanupClass.java000077500000000000000000000105331142665006500350460ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.*; import java.util.*; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIMethod; /** * * @author Hiram Chirino */ public abstract class CleanupClass extends JNIGenerator { String classSourcePath; String[] sourcePath; String classSource; HashMap files; int usedCount, unusedCount; String[] getArgNames(JNIMethod method) { int n_args = method.getParameters().size(); if (n_args == 0) return new String[0]; String name = method.getName(); String params = ""; int index = 0; while (true) { index = classSource.indexOf(name, index + 1); if (!Character.isWhitespace(classSource.charAt(index - 1))) continue; if (index == -1) return null; int parantesesStart = classSource.indexOf("(", index); if (classSource.substring(index + name.length(), parantesesStart).trim().length() == 0) { int parantesesEnd = classSource.indexOf(")", parantesesStart); params = classSource.substring(parantesesStart + 1, parantesesEnd); break; } } String[] names = new String[n_args]; StringTokenizer tk = new StringTokenizer(params, ","); for (int i = 0; i < names.length; i++) { String s = tk.nextToken().trim(); StringTokenizer tk1 = new StringTokenizer(s, " "); String s1 = null; while (tk1.hasMoreTokens()) { s1 = tk1.nextToken(); } names[i] = s1.trim(); } return names; } void loadClassSource() { if (classSourcePath == null) return; File f = new File(classSourcePath); classSource = loadFile(f); } void loadFiles() { // BAD - holds on to a lot of memory if (sourcePath == null) return; files = new HashMap(); for (int i = 0; i < sourcePath.length; i++) { File file = new File(sourcePath[i]); if (file.exists()) { if (!file.isDirectory()) { if (file.getAbsolutePath().endsWith(".java")) { files.put(file, loadFile(file)); } } else { loadDirectory(file); } } } } String loadFile(File file) { try { FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); StringBuffer str = new StringBuffer(); char[] buffer = new char[1024]; int read; while ((read = br.read(buffer)) != -1) { str.append(buffer, 0, read); } fr.close(); return str.toString(); } catch (IOException e) { e.printStackTrace(System.out); } return ""; } void loadDirectory(File file) { String[] entries = file.list(); for (int i = 0; i < entries.length; i++) { String entry = entries[i]; File f = new File(file, entry); if (!f.isDirectory()) { if (f.getAbsolutePath().endsWith(".java")) { files.put(f, loadFile(f)); } } else { loadDirectory(f); } } } public void generate(JNIClass clazz) { loadFiles(); loadClassSource(); } public void setSourcePath(String[] sourcePath) { this.sourcePath = sourcePath; files = null; } public void setClassSourcePath(String classSourcePath) { this.classSourcePath = classSourcePath; } } CleanupConstants.java000077500000000000000000000074001142665006500357540ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.ReflectClass; /** * * @author Hiram Chirino */ public class CleanupConstants extends CleanupClass { String getFieldValue(JNIField field) { String name = field.getName(); int index = 0; while (true) { index = classSource.indexOf(name, index + 1); if (index == -1) return null; int equalsIndex = classSource.indexOf("=", index); if (classSource.substring(index + name.length(), equalsIndex).trim().length() == 0) { int semiIndex = classSource.indexOf(";", equalsIndex); return classSource.substring(equalsIndex + 1, semiIndex).trim(); } } } public void generate(JNIClass clazz) { unusedCount = usedCount = 0; super.generate(clazz); List fields = clazz.getDeclaredFields(); generate(fields); output("used=" + usedCount + " unused=" + unusedCount + " total=" + (unusedCount + usedCount)); } public void generate(List fields) { sortFields(fields); for (JNIField field : fields) { if ((field.getModifiers() & Modifier.FINAL) == 0) continue; generate(field); } } public void generate(JNIField field) { String name = field.getName(); Collection values = files.values(); for (String str : values) { if (str.indexOf(name) != -1) { int modifiers = field.getModifiers(); String modifiersStr = Modifier.toString(modifiers); output("\t"); output(modifiersStr); if (modifiersStr.length() > 0) output(" "); output(field.getType().getTypeSignature3(false)); output(" "); output(field.getName()); output(" = "); output(getFieldValue(field)); outputln(";"); usedCount++; return; } } unusedCount++; // output("NOT USED=" + field.toString() + " \n"); } public static void main(String[] args) { if (args.length < 3) { System.out.println("Usage: java CleanupConstants "); return; } try { CleanupConstants gen = new CleanupConstants(); String clazzName = args[0]; String classSource = args[1]; String[] sourcePath = new String[args.length - 2]; System.arraycopy(args, 2, sourcePath, 0, sourcePath.length); Class clazz = Class.forName(clazzName); gen.setSourcePath(sourcePath); gen.setClassSourcePath(classSource); gen.generate(new ReflectClass(clazz)); } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } } CleanupNatives.java000077500000000000000000000075141142665006500354170ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.util.*; import java.io.File; import java.lang.reflect.*; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIMethod; import org.fusesource.hawtjni.generator.model.ReflectClass; /** * * @author Hiram Chirino */ public class CleanupNatives extends CleanupClass { public CleanupNatives() { } public void generate(JNIClass clazz) { unusedCount = usedCount = 0; super.generate(clazz); List methods = clazz.getDeclaredMethods(); generate(methods); output("used=" + usedCount + " unused=" + unusedCount + " total=" + (unusedCount + usedCount)); } public void generate(List methods) { sortMethods(methods); for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; generate(method); } } public void generate(JNIMethod method) { String name = method.getName(); Set keys = files.keySet(); for (File key : keys) { String str = (String) files.get(key); if (str.indexOf(name) != -1) { // int modifiers = method.getModifiers(); // Class clazz = method.getDeclaringClass(); // String modifiersStr = Modifier.toString(modifiers); // output(modifiersStr); // if (modifiersStr.length() > 0) output(" "); // output(getTypeSignature3(method.getReturnType())); // output(" " ); // output(method.getName()); // output("("); // Class[] paramTypes = method.getParameterTypes(); // String[] paramNames = getArgNames(method); // for (int i = 0; i < paramTypes.length; i++) { // Class paramType = paramTypes[i]; // if (i != 0) output(", "); // String sig = getTypeSignature3(paramType); // if (clazz.getPackage().equals(paramType.getPackage())) sig = // getClassName(paramType); // output(sig); // output(" "); // output(paramNames[i]); // } // outputln(");"); usedCount++; return; } } unusedCount++; output("NOT USED=" + method.toString() + "\n"); } public static void main(String[] args) { if (args.length < 2) { System.out.println("Usage: java CleanupNatives "); return; } try { CleanupNatives gen = new CleanupNatives(); String clazzName = args[0]; String classSource = args[1]; String[] sourcePath = new String[args.length - 2]; System.arraycopy(args, 2, sourcePath, 0, sourcePath.length); Class clazz = Class.forName(clazzName); gen.setSourcePath(sourcePath); gen.setClassSourcePath(classSource); gen.generate(new ReflectClass(clazz)); } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } } ConstantsGenerator.java000077500000000000000000000047021142665006500363150ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.JNIType; import org.fusesource.hawtjni.generator.model.ReflectClass; /** * * @author Hiram Chirino */ public class ConstantsGenerator extends JNIGenerator { public void generate(JNIClass clazz) { List fields = clazz.getDeclaredFields(); generate(fields); } public void generate(List fields) { sortFields(fields); outputln("int main() {"); for (JNIField field : fields) { if ((field.getModifiers() & Modifier.FINAL) == 0) continue; generate(field); } outputln("}"); } public void generate(JNIField field) { JNIType type = field.getType(); output("\tprintf(\"public static final "); output(field.getType().getTypeSignature3(false)); output(" "); output(field.getName()); output(" = "); if (type.isType("java.lang.String") || type.isType("[B")) output("\"%s\""); else output("0x%x"); output(";\\n\", "); output(field.getName()); outputln(");"); } public static void main(String[] args) { if (args.length < 1) { System.out.println("Usage: java ConstantsGenerator "); return; } try { ConstantsGenerator gen = new ConstantsGenerator(); for (String clazzName : args) { Class clazz = Class.forName(clazzName); gen.generate(new ReflectClass(clazz)); } } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } } DOMWriter.java000077500000000000000000000076431142665006500343150ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.PrintStream; import java.util.Arrays; import java.util.Comparator; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * * @author Hiram Chirino */ public class DOMWriter { static String ENCONDING = "UTF8"; PrintStream out; String[] attributeFilter; String nodeFilter; public DOMWriter(PrintStream out) { this.out = new PrintStream(out); } String nodeName(Node node) { // TODO use getLocalName()? return node.getNodeName(); } boolean filter(Attr attr) { if (attributeFilter == null) return false; String name = attr.getNodeName(); for (int i = 0; i < attributeFilter.length; i++) { if (name.matches(attributeFilter[i])) return false; } return true; } void print(String str) { out.print(str); } void println() { out.println(); } public void print(Node node) { print(node, 0); } public void print(Node node, int level) { if (node == null) return; int type = node.getNodeType(); switch (type) { case Node.DOCUMENT_NODE: { print(""); println(); print(((Document) node).getDocumentElement()); break; } case Node.ELEMENT_NODE: { Attr attrs[] = sort(node.getAttributes()); String name = nodeName(node); boolean gen = name.equals("arg") || name.equals("retval"); for (int i = 0; i < attrs.length && !gen; i++) { Attr attr = attrs[i]; if (nodeName(attr).startsWith(nodeFilter)) gen = true; } if (!gen) break; for (int i = 0; i < level; i++) print("\t"); print("<"); print(name); for (int i = 0; i < attrs.length; i++) { Attr attr = attrs[i]; if (filter(attr)) continue; print(" "); print(nodeName(attr)); print("=\""); print(normalize(attr.getNodeValue())); print("\""); } print(">"); NodeList children = node.getChildNodes(); int count = 0; if (children != null) { int len = children.getLength(); for (int i = 0; i < len; i++) { if (children.item(i).getNodeType() == Node.ELEMENT_NODE) count++; } if (count > 0) println(); for (int i = 0; i < len; i++) { print(children.item(i), level + 1); } if (count > 0) { for (int i = 0; i < level; i++) print("\t"); } } print(""); println(); break; } } out.flush(); } Attr[] sort(NamedNodeMap attrs) { if (attrs == null) return new Attr[0]; Attr result[] = new Attr[attrs.getLength()]; for (int i = 0; i < result.length; i++) { result[i] = (Attr) attrs.item(i); } Arrays.sort(result, new Comparator() { public int compare(Node arg0, Node arg1) { return nodeName(arg0).compareTo(nodeName(arg1)); } }); return result; } String normalize(String s) { if (s == null) return ""; StringBuffer str = new StringBuffer(); for (int i = 0, length = s.length(); i < length; i++) { char ch = s.charAt(i); switch (ch) { case '"': str.append("\""); break; case '\r': case '\n': // FALL THROUGH default: str.append(ch); } } return str.toString(); } public void setNodeFilter(String filter) { nodeFilter = filter; } public void setAttributeFilter(String[] filter) { attributeFilter = filter; } }HawtJNI.java000077500000000000000000000407751142665006500337500ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.lang.reflect.Array; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.xbean.finder.ClassFinder; import org.apache.xbean.finder.UrlSet; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.ReflectClass; import org.fusesource.hawtjni.generator.util.FileSupport; import org.fusesource.hawtjni.runtime.ClassFlag; import org.fusesource.hawtjni.runtime.JniClass; import static org.fusesource.hawtjni.generator.util.OptionBuilder.*; /** * * @author Hiram Chirino */ public class HawtJNI { public static final String END_YEAR_TAG = "%END_YEAR%"; private ProgressMonitor progress; private File nativeOutput = new File("."); // private File javaOutputDir = new File("."); private List classpaths = new ArrayList(); private List packages = new ArrayList(); private String name = "hawtjni_native"; private String copyright = ""; private boolean callbacks = true; /////////////////////////////////////////////////////////////////// // Command line entry point /////////////////////////////////////////////////////////////////// public static void main(String[] args) { String jv = System.getProperty("java.version").substring(0, 3); if (jv.compareTo("1.5") < 0) { System.err.println("This application requires jdk 1.5 or higher to run, the current java version is " + System.getProperty("java.version")); System.exit(-1); return; } HawtJNI app = new HawtJNI(); System.exit(app.execute(args)); } /////////////////////////////////////////////////////////////////// // Entry point for an embedded users who want to call us with // via command line arguments. /////////////////////////////////////////////////////////////////// public int execute(String[] args) { CommandLine cli = null; try { cli = new PosixParser().parse(createOptions(), args, true); } catch (ParseException e) { System.err.println( "Unable to parse command line options: " + e.getMessage() ); displayHelp(); return 1; } if( cli.hasOption("h") ) { displayHelp(); return 0; } if( cli.hasOption("v") ) { progress = new ProgressMonitor() { public void step() { } public void setTotal(int total) { } public void setMessage(String message) { System.out.println(message); } }; } name = cli.getOptionValue("n", "hawtjni_native"); nativeOutput = new File(cli.getOptionValue("o", ".")); // javaOutputDir = new File(cli.getOptionValue("j", ".")); String[] values = cli.getOptionValues("p"); if( values!=null ) { packages = Arrays.asList(values); } values = cli.getArgs(); if( values!=null ) { classpaths = Arrays.asList(values); } try { if( classpaths.isEmpty() ) { throw new UsageException("No classpath supplied."); } generate(); } catch (UsageException e) { System.err.println("Invalid usage: "+e.getMessage()); displayHelp(); return 1; } catch (Throwable e) { System.out.flush(); System.err.println("Unexpected failure:"); e.printStackTrace(); Set exceptions = new HashSet(); exceptions.add(e); for (int i = 0; i < 10; i++) { e = e.getCause(); if (e != null && exceptions.add(e)) { System.err.println("Reason: " + e); e.printStackTrace(); } else { break; } } return 2; } return 0; } /////////////////////////////////////////////////////////////////// // Entry point for an embedded users who want use us like a pojo /////////////////////////////////////////////////////////////////// public ProgressMonitor getProgress() { return progress; } public void setProgress(ProgressMonitor progress) { this.progress = progress; } public File getNativeOutput() { return nativeOutput; } public void setNativeOutput(File nativeOutput) { this.nativeOutput = nativeOutput; } public List getClasspaths() { return classpaths; } public void setClasspaths(List classpaths) { this.classpaths = classpaths; } public List getPackages() { return packages; } public void setPackages(List packages) { this.packages = packages; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setCopyright(String copyright) { this.copyright = copyright; } public boolean isCallbacks() { return callbacks; } public void setCallbacks(boolean enableCallbacks) { this.callbacks = enableCallbacks; } public void generate() throws UsageException, IOException { progress("Analyzing classes..."); ArrayList natives = new ArrayList(); ArrayList structs = new ArrayList(); findClasses(natives, structs); if( natives.isEmpty() && structs.isEmpty() ) { throw new RuntimeException("No @JniClass or @JniStruct annotated classes found."); } if (progress != null) { int nativeCount = 0; for (JNIClass clazz : natives) { nativeCount += clazz.getNativeMethods().size(); } int total = nativeCount * 4; total += natives.size() * (3); total += structs.size() * 2; progress.setTotal(total); } File file; nativeOutput.mkdirs(); progress("Generating..."); file = nativeFile(".c"); generate(new NativesGenerator(), natives, file); file = nativeFile("_stats.h"); generate(new StatsGenerator(true), natives, file); file = nativeFile("_stats.c"); generate(new StatsGenerator(false), natives, file); file = nativeFile("_structs.h"); generate(new StructsGenerator(true), structs, file); file = nativeFile("_structs.c"); generate(new StructsGenerator(false), structs, file); file = new File(nativeOutput, "hawtjni.h"); generateFromResource("hawtjni.h", file); file = new File(nativeOutput, "hawtjni.c"); generateFromResource("hawtjni.c", file); file = new File(nativeOutput, "hawtjni-callback.c"); if( callbacks ) { generateFromResource("hawtjni-callback.c", file); } else { file.delete(); } file = new File(nativeOutput, "windows"); file.mkdirs(); file = new File(file, "stdint.h"); generateFromResource("windows/stdint.h", file); progress("Done."); } /////////////////////////////////////////////////////////////////// // Helper methods /////////////////////////////////////////////////////////////////// private void findClasses(ArrayList jni, ArrayList structs) throws UsageException { ArrayList urls = new ArrayList(); for (String classpath : classpaths) { String[] fileNames = classpath.replace(';', ':').split(":"); for (String fileName : fileNames) { try { File file = new File(fileName); if( file.isDirectory() ) { urls.add(new URL(url(file)+"/")); } else { urls.add(new URL(url(file))); } } catch (Exception e) { throw new UsageException("Invalid class path. Not a valid file: "+fileName); } } } LinkedHashSet> jniClasses = new LinkedHashSet>(); try { URLClassLoader classLoader = new URLClassLoader(array(URL.class, urls), JniClass.class.getClassLoader()); UrlSet urlSet = new UrlSet(classLoader); urlSet = urlSet.excludeJavaHome(); ClassFinder finder = new ClassFinder(classLoader, urlSet.getUrls()); collectMatchingClasses(finder, JniClass.class, jniClasses); } catch (Exception e) { throw new RuntimeException(e); } for (Class clazz : jniClasses) { ReflectClass rc = new ReflectClass(clazz); if( rc.getFlag(ClassFlag.STRUCT) ) { structs.add(rc); } if( !rc.getNativeMethods().isEmpty() ) { jni.add(rc); } } } static private Options createOptions() { Options options = new Options(); options.addOption("h", "help", false, "Display help information"); options.addOption("v", "verbose", false, "Verbose generation"); options.addOption("o", "offline", false, "Work offline"); options.addOption(ob() .id("n") .name("name") .arg("value") .description("The base name of the library, used to determine generated file names. Defaults to 'hawtjni_native'.").op()); options.addOption(ob() .id("o") .name("native-output") .arg("dir") .description("Directory where generated native source code will be stored. Defaults to the current directory.").op()); // options.addOption(ob() // .id("j") // .name("java-output") // .arg("dir") // .description("Directory where generated native source code will be stored. Defaults to the current directory.").op()); options.addOption(ob() .id("p") .name("package") .arg("package") .description("Restrict looking for JNI classes to the specified package.").op()); return options; } private void displayHelp() { System.err.flush(); String app = System.getProperty("hawtjni.application"); if( app == null ) { try { URL location = getClass().getProtectionDomain().getCodeSource().getLocation(); String[] split = location.toString().split("/"); if( split[split.length-1].endsWith(".jar") ) { app = split[split.length-1]; } } catch (Throwable e) { } if( app == null ) { app = getClass().getSimpleName(); } } // The commented out line is 80 chars long. We have it here as a visual reference // p(" "); p(); p("Usage: "+ app +" [options] "); p(); p("Description:"); p(); pw(" "+app+" is a code generator that produces the JNI code needed to implement java native methods.", 2); p(); p("Options:"); p(); PrintWriter out = new PrintWriter(System.out); HelpFormatter formatter = new HelpFormatter(); formatter.printOptions(out, 78, createOptions(), 2, 2); out.flush(); p(); p("Examples:"); p(); pw(" "+app+" -o build foo.jar bar.jar ", 2); pw(" "+app+" -o build foo.jar:bar.jar ", 2); pw(" "+app+" -o build -p org.mypackage foo.jar;bar.jar ", 2); p(); } private void p() { System.out.println(); } private void p(String s) { System.out.println(s); } private void pw(String message, int indent) { PrintWriter out = new PrintWriter(System.out); HelpFormatter formatter = new HelpFormatter(); formatter.printWrapped(out, 78, indent, message); out.flush(); } @SuppressWarnings("unchecked") private void collectMatchingClasses(ClassFinder finder, Class annotation, LinkedHashSet> collector) { List annotated = finder.findAnnotatedClasses(annotation); for (Class clazz : annotated) { if( packages.isEmpty() ) { collector.add(clazz); } else { if( packages.contains(clazz.getPackage().getName()) ) { collector.add(clazz); } } } } private void progress(String message) { if (progress != null) { progress.setMessage(message); } } private void generate(JNIGenerator gen, ArrayList classes, File target) throws IOException { gen.setOutputName(name); gen.setClasses(classes); gen.setCopyright(getCopyright()); gen.setProgressMonitor(progress); ByteArrayOutputStream out = new ByteArrayOutputStream(); gen.setOutput(new PrintStream(out)); gen.generate(); if (out.size() > 0) { if( FileSupport.write(out.toByteArray(), target) ) { progress("Wrote: "+target); } } } private void generateFromResource(String resource, File target) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream is = getClass().getClassLoader().getResourceAsStream(resource); FileSupport.copy(is, out); String content = new String(out.toByteArray(), "UTF-8"); String[] parts = content.split(Pattern.quote("/* == HEADER-SNIP-LOCATION == */")); if( parts.length==2 ) { content = parts[1]; } out.reset(); PrintStream ps = new PrintStream(out); ps.print(JNIGenerator.fixDelimiter(getCopyright())); ps.print(JNIGenerator.fixDelimiter(content)); ps.close(); if( FileSupport.write(out.toByteArray(), target) ) { progress("Wrote: "+target); } } @SuppressWarnings("unchecked") private T[] array(Class type, ArrayList urls) { return urls.toArray((T[])Array.newInstance(type, urls.size())); } private String url(File file) throws IOException { return "file:"+(file.getCanonicalPath().replace(" ", "%20")); } @SuppressWarnings("serial") public static class UsageException extends Exception { public UsageException(String message) { super(message); } } private File nativeFile(String suffix) { return new File(nativeOutput, name+suffix); } public String getCopyright() { if (copyright == null) return ""; int index = copyright.indexOf(END_YEAR_TAG); if (index != -1) { String temp = copyright.substring(0, index); temp += Calendar.getInstance().get(Calendar.YEAR); temp += copyright.substring(index + END_YEAR_TAG.length()); copyright = temp; } return copyright; } } JNIGenerator.java000077500000000000000000000154171142665006500347660ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2006 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.JNIMethod; import org.fusesource.hawtjni.generator.model.JNIType; import org.fusesource.hawtjni.runtime.ClassFlag; /** * * @author Hiram Chirino */ public abstract class JNIGenerator { static final String delimiter = System.getProperty("line.separator"); static final String JNI64 = "JNI64"; ArrayList classes; String copyright = ""; boolean isCPP; PrintStream output = System.out; ProgressMonitor progress; private String outputName; static String fixDelimiter(String str) { if (delimiter.equals("\n")) { return str; } return str.replaceAll("\n", delimiter); } static String getFunctionName(JNIMethod method) { return getFunctionName(method, method.getParameterTypes()); } static String getFunctionName(JNIMethod method, List paramTypes) { if ((method.getModifiers() & Modifier.NATIVE) == 0) return method.getName(); String function = toC(method.getName()); if (!method.isNativeUnique()) { StringBuffer buffer = new StringBuffer(); buffer.append(function); buffer.append("__"); for (JNIType paramType : paramTypes) { buffer.append(toC(paramType.getTypeSignature(false))); } return buffer.toString(); } return function; } static String loadFile(String file) { try { FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); StringBuffer str = new StringBuffer(); char[] buffer = new char[1024]; int read; while ((read = br.read(buffer)) != -1) { str.append(buffer, 0, read); } fr.close(); return str.toString(); } catch (IOException e) { throw new RuntimeException("File not found:" + file, e); } } public static void sortMethods(List methods) { Collections.sort(methods, new Comparator() { public int compare(JNIMethod mth1, JNIMethod mth2) { int result = mth1.getName().compareTo(mth2.getName()); return result != 0 ? result : getFunctionName(mth1).compareTo(getFunctionName(mth2)); } }); } static void sortFields(List fields) { Collections.sort(fields, new Comparator() { public int compare(JNIField a, JNIField b) { return a.getName().compareTo(b.getName()); } }); } static void sortClasses(ArrayList classes) { Collections.sort(classes, new Comparator() { public int compare(JNIClass a, JNIClass b) { return a.getName().compareTo(b.getName()); } }); } static String toC(String str) { int length = str.length(); StringBuffer buffer = new StringBuffer(length * 2); for (int i = 0; i < length; i++) { char c = str.charAt(i); switch (c) { case '_': buffer.append("_1"); break; case ';': buffer.append("_2"); break; case '[': buffer.append("_3"); break; case '.': buffer.append("_"); break; case '/': buffer.append("_"); break; default: if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') ) { buffer.append(c); } else { buffer.append(String.format("_0%04x",(int)c)); } } } return buffer.toString(); } public abstract void generate(JNIClass clazz); public void generateCopyright() { } public void generateIncludes() { } public void generate() { if (classes == null) return; generateCopyright(); generateIncludes(); sortClasses(classes); for (JNIClass clazz : classes) { if (clazz.getFlag(ClassFlag.CPP)) { isCPP = true; break; } } generate(classes); output.flush(); } protected void generate(ArrayList classes) { for (JNIClass clazz : classes) { if (clazz.getGenerate()) generate(clazz); if (progress != null) progress.step(); } } public boolean getCPP() { return isCPP; } public String getDelimiter() { return delimiter; } public PrintStream getOutput() { return output; } public String getOutputName() { return outputName; } public void setOutputName(String outputName) { this.outputName = outputName; } public ProgressMonitor getProgressMonitor() { return progress; } public void output(String str) { output.print(str); } public void outputln() { output(getDelimiter()); } public void outputln(String str) { output(str); output(getDelimiter()); } public void setClasses(ArrayList classes) { this.classes = classes; } public void setOutput(PrintStream output) { this.output = output; } public void setProgressMonitor(ProgressMonitor progress) { this.progress = progress; } public String getCopyright() { return copyright; } public void setCopyright(String copyright) { this.copyright = copyright; } } LockGenerator.java000077500000000000000000000130761142665006500352350ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIMethod; import org.fusesource.hawtjni.generator.model.JNIType; import org.fusesource.hawtjni.generator.model.ReflectClass; import org.fusesource.hawtjni.generator.model.ReflectType; /** * * @author Hiram Chirino */ public class LockGenerator extends CleanupClass { public LockGenerator() { } String getParams(JNIMethod method) { int n_args = method.getParameters().size(); if (n_args == 0) return ""; String name = method.getName(); String params = ""; int index = 0; while (true) { index = classSource.indexOf(name, index + 1); if (!Character.isWhitespace(classSource.charAt(index - 1))) continue; if (index == -1) return null; int parantesesStart = classSource.indexOf("(", index); if (classSource.substring(index + name.length(), parantesesStart).trim().length() == 0) { int parantesesEnd = classSource.indexOf(")", parantesesStart); params = classSource.substring(parantesesStart + 1, parantesesEnd); break; } } return params; } String getReturn(JNIMethod method) { JNIType returnType = method.getReturnType32(); if (!returnType.isType("int")) return returnType.getTypeSignature3(false); String modifierStr = Modifier.toString(method.getModifiers()); String name = method.getName(); Pattern p = Pattern.compile(modifierStr + ".*" + name + ".*(.*)"); Matcher m = p.matcher(classSource); if (m.find()) { String methodStr = classSource.substring(m.start(), m.end()); int index = methodStr.indexOf("/*long*/"); if (index != -1 && index < methodStr.indexOf(name)) { return new ReflectType(Integer.TYPE).getTypeSignature3(false) + " /*long*/"; } } return new ReflectType(Integer.TYPE).getTypeSignature3(false); } public void generate(JNIClass clazz) { super.generate(clazz); generate(clazz.getDeclaredMethods()); } public void generate(List methods) { sortMethods(methods); for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; generate(method); } } public void generate(JNIMethod method) { int modifiers = method.getModifiers(); boolean lock = (modifiers & Modifier.SYNCHRONIZED) != 0; String returnStr = getReturn(method); String paramsStr = getParams(method); if (lock) { String modifiersStr = Modifier.toString(modifiers & ~Modifier.SYNCHRONIZED); output(modifiersStr); if (modifiersStr.length() > 0) output(" "); output(returnStr); output(" _"); output(method.getName()); output("("); output(paramsStr); outputln(");"); } String modifiersStr = Modifier.toString(modifiers & ~(Modifier.SYNCHRONIZED | (lock ? Modifier.NATIVE : 0))); output(modifiersStr); if (modifiersStr.length() > 0) output(" "); output(returnStr); output(" "); output(method.getName()); output("("); output(paramsStr); output(")"); if (lock) { outputln(" {"); outputln("\tlock.lock();"); outputln("\ttry {"); output("\t\t"); if (!method.getReturnType32().isType("void")) { output("return "); } output("_"); output(method.getName()); output("("); String[] paramNames = getArgNames(method); for (int i = 0; i < paramNames.length; i++) { if (i != 0) output(", "); output(paramNames[i]); } outputln(");"); outputln("\t} finally {"); outputln("\t\tlock.unlock();"); outputln("\t}"); outputln("}"); } else { outputln(";"); } } public static void main(String[] args) { if (args.length < 2) { System.out.println("Usage: java LockGenerator "); return; } try { LockGenerator gen = new LockGenerator(); String clazzName = args[0]; String classSource = args[1]; Class clazz = Class.forName(clazzName); gen.setClassSourcePath(classSource); gen.generate(new ReflectClass(clazz)); } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } } MacGenerator.java000077500000000000000000002076271142665006500350540ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.TreeSet; import javax.xml.parsers.DocumentBuilderFactory; import org.fusesource.hawtjni.generator.HawtJNI.UsageException; import org.fusesource.hawtjni.generator.util.FileSupport; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * * @author Hiram Chirino */ public class MacGenerator { String[] xmls; Document[] documents; String outputDir, mainClassName; String delimiter = System.getProperty("line.separator"); PrintStream out; public MacGenerator() { } static void list(File path, ArrayList list) { if (path == null) return; File[] frameworks = path.listFiles(); if (frameworks == null) return; for (int i = 0; i < frameworks.length; i++) { File file = frameworks[i]; String name = file.getName(); int index = name.lastIndexOf("."); if (index != -1) { String xml = file.getAbsolutePath() + "/Resources/BridgeSupport/" + name.substring(0, index) + "Full.bridgesupport"; if (new File(xml).exists()) { list.add(xml); } } } } int getLevel(Node node) { int level = 0; while (node != null) { level++; node = node.getParentNode(); } return level; } void merge(Document document, Document extraDocument) { if (extraDocument == null) return; /* Build a lookup table for extraDocument */ HashMap extras = new HashMap(); buildLookup(extraDocument, extras); /* * Merge attributes on existing elements building a lookup table for * document */ HashMap lookup = new HashMap(); merge(document, extras, lookup); /* * Merge new elements. Extras at this point contains only elements that * were not found in the document. */ ArrayList sortedNodes = Collections.list(Collections.enumeration(extras.values())); Collections.sort(sortedNodes, new Comparator() { public int compare(Node arg0, Node arg1) { int compare = getLevel(arg0) - getLevel(arg1); if (compare == 0) { return (arg0).getNodeName().compareTo((arg1).getNodeName()); } return compare; } }); String delimiter = System.getProperty("line.separator"); for (Iterator iterator = sortedNodes.iterator(); iterator.hasNext();) { Node node = iterator.next(); String name = node.getNodeName(); if ("arg".equals(name) || "retval".equals(name)) { if (!sortedNodes.contains(node.getParentNode())) continue; } Node parent = lookup.get(getKey(node.getParentNode())); Element element = document.createElement(node.getNodeName()); String text = parent.getChildNodes().getLength() == 0 ? delimiter : ""; for (int i = 0, level = getLevel(parent) - 1; i < level; i++) { text += " "; } parent.appendChild(document.createTextNode(text)); parent.appendChild(element); parent.appendChild(document.createTextNode(delimiter)); NamedNodeMap attributes = node.getAttributes(); for (int j = 0, length = attributes.getLength(); j < length; j++) { Node attr = (Node) attributes.item(j); element.setAttribute(attr.getNodeName(), attr.getNodeValue()); } lookup.put(getKey(element), element); } } public void generate(ProgressMonitor progress) throws UsageException { if (progress != null) { progress.setTotal(3); progress.setMessage("extra attributes..."); } generateExtraAttributes(); if (progress != null) { progress.step(); progress.setMessage(mainClassName); } generateMainClass(); if (progress != null) { progress.step(); progress.setMessage("classes..."); } generateClasses(); if (progress != null) { progress.step(); progress.setMessage("Done."); } } String fixDelimiter(String str) { if (delimiter.equals("\n")) return str; int index = 0, length = str.length(); StringBuffer buffer = new StringBuffer(); while (index != -1) { int start = index; index = str.indexOf('\n', start); if (index == -1) { buffer.append(str.substring(start, length)); } else { buffer.append(str.substring(start, index)); buffer.append(delimiter); index++; } } return buffer.toString(); } void generateMethods(String className, ArrayList methods) { for (Node method : methods) { NamedNodeMap mthAttributes = method.getAttributes(); String sel = mthAttributes.getNamedItem("selector").getNodeValue(); out("public "); boolean isStatic = isStatic(method); if (isStatic) out("static "); Node returnNode = getReturnNode(method.getChildNodes()); if (getType(returnNode).equals("void")) returnNode = null; String returnType = "", returnType64 = ""; if (returnNode != null) { String type = returnType = getJavaType(returnNode), type64 = returnType64 = getJavaType64(returnNode); out(type); if (!type.equals(type64)) { out(" /*"); out(type64); out("*/"); } out(" "); } else { out("void "); } String methodName = sel; if (isUnique(method, methods)) { int index = methodName.indexOf(":"); if (index != -1) methodName = methodName.substring(0, index); } else { // TODO improve this selector methodName = methodName.replaceAll(":", "_"); if (isStatic) methodName = "static_" + methodName; } out(methodName); out("("); NodeList params = method.getChildNodes(); boolean first = true; for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { NamedNodeMap paramAttributes = param.getAttributes(); if (!first) out(", "); String type = getJavaType(param), type64 = getJavaType64(param); out(type); if (!type.equals(type64)) { out(" /*"); out(type64); out("*/"); } first = false; out(" "); String paramName = paramAttributes.getNamedItem("name").getNodeValue(); if (paramName.length() == 0) paramName = "arg" + paramAttributes.getNamedItem("index").getNodeValue(); if (paramName.equals("boolean")) paramName = "b"; out(paramName); } } out(") {"); outln(); if (returnNode != null && isStruct(returnNode)) { out("\t"); out(returnType); out(" result = new "); out(returnType); out("();"); outln(); out("\tOS.objc_msgSend_stret(result, "); } else if (returnNode != null && isBoolean(returnNode)) { out("\treturn "); out("OS.objc_msgSend_bool("); } else if (returnNode != null && isFloatingPoint(returnNode)) { out("\treturn "); if (returnType.equals("float")) out("(float)"); out("OS.objc_msgSend_fpret("); } else if (returnNode != null && isObject(returnNode)) { out("\tint /*long*/ result = OS.objc_msgSend("); } else { if (returnNode != null) { out("\treturn "); if ((returnType.equals("int") && returnType64.equals("int")) || !returnType.equals("int")) { out("("); out(returnType); out(")"); } if (returnType.equals("int") && returnType64.equals("int")) { out("/*64*/"); } } else { out("\t"); } out("OS.objc_msgSend("); } if (isStatic) { out("OS.class_"); out(className); } else { out("this.id"); } out(", OS."); out(getSelConst(sel)); first = false; for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { NamedNodeMap paramAttributes = param.getAttributes(); if (!first) out(", "); first = false; String paramName = paramAttributes.getNamedItem("name").getNodeValue(); if (paramName.length() == 0) paramName = "arg" + paramAttributes.getNamedItem("index").getNodeValue(); if (paramName.equals("boolean")) paramName = "b"; if (isObject(param)) { out(paramName); out(" != null ? "); out(paramName); out(".id : 0"); } else { out(paramName); } } } out(")"); out(";"); outln(); if (returnNode != null && isObject(returnNode)) { if (!isStatic && returnType.equals(className)) { out("\treturn result == this.id ? this : (result != 0 ? new "); out(returnType); out("(result) : null);"); } else { out("\treturn result != 0 ? new "); NamedNodeMap attributes = returnNode.getAttributes(); Node hawtjni_alloc = attributes.getNamedItem("hawtjni_alloc"); if (hawtjni_alloc != null && hawtjni_alloc.getNodeValue().equals("true")) { out(className); } else { out(returnType); } out("(result) : null;"); } outln(); } else if (returnNode != null && isStruct(returnNode)) { out("\treturn result;"); outln(); } out("}"); outln(); outln(); } } void generateExtraMethods(String className) { /* Empty constructor */ out("public "); out(className); out("() {"); outln(); out("\tsuper();"); outln(); out("}"); outln(); outln(); /* pointer constructor */ out("public "); out(className); out("(int /*long*/ id) {"); outln(); out("\tsuper(id);"); outln(); out("}"); outln(); outln(); /* object constructor */ out("public "); out(className); out("(id id) {"); outln(); out("\tsuper(id);"); outln(); out("}"); outln(); outln(); /* NSObject helpers */ if (className.equals("NSObject")) { out("public NSObject alloc() {"); outln(); out("\tthis.id = OS.objc_msgSend(objc_getClass(), OS.sel_alloc);"); outln(); out("\treturn this;"); outln(); out("}"); outln(); outln(); } /* NSString helpers */ if (className.equals("NSString")) { /* Get java string */ out("public String getString() {"); outln(); out("\tchar[] buffer = new char[(int)/*64*/length()];"); outln(); out("\tgetCharacters(buffer);"); outln(); out("\treturn new String(buffer);"); outln(); out("}"); outln(); outln(); /* create NSString */ out("public NSString initWithString(String str) {"); outln(); out("\tchar[] buffer = new char[str.length()];"); outln(); out("\tstr.getChars(0, buffer.length, buffer, 0);"); outln(); out("\treturn initWithCharacters(buffer, buffer.length);"); outln(); out("}"); outln(); outln(); out("public static NSString stringWith(String str) {"); outln(); out("\tchar[] buffer = new char[str.length()];"); outln(); out("\tstr.getChars(0, buffer.length, buffer, 0);"); outln(); out("\treturn stringWithCharacters(buffer, buffer.length);"); outln(); out("}"); outln(); outln(); } } static class NodeEntry { private final Node parent; private final ArrayList children; public NodeEntry(Node parent, ArrayList children) { this.parent = parent; this.children = children; } } TreeMap getGeneratedClasses() { TreeMap classes = new TreeMap(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("class".equals(node.getNodeName()) && getGen(node)) { ArrayList methods; String name = node.getAttributes().getNamedItem("name").getNodeValue(); NodeEntry clazz = classes.get(name); if (clazz == null) { methods = new ArrayList(); classes.put(name, new NodeEntry(node, methods)); } else { methods = clazz.children; } NodeList methodList = node.getChildNodes(); for (int j = 0; j < methodList.getLength(); j++) { Node method = methodList.item(j); if ("method".equals(method.getNodeName()) && getGen(method)) { methods.add(method); } } } } } return classes; } void copyClassMethodsDown(final Map classes) { ArrayList sortedClasses = Collections.list(Collections.enumeration(classes.values())); Collections.sort(sortedClasses, new Comparator() { int getHierarchyLevel(Node node) { String superclass = getSuperclassName(node); int level = 0; while (!superclass.equals("id")) { level++; superclass = getSuperclassName(classes.get(superclass).parent); } return level; } public int compare(NodeEntry arg0, NodeEntry arg1) { return getHierarchyLevel(arg0.parent) - getHierarchyLevel(arg1.parent); } }); for (NodeEntry clazz : sortedClasses) { Node node = (Node) clazz.parent; ArrayList methods = (ArrayList) clazz.children; NodeEntry superclass = classes.get(getSuperclassName(node)); if (superclass != null) { for (Node method : superclass.children) { if (isStatic(method)) { methods.add(method); } } } } } String getSuperclassName(Node node) { NamedNodeMap attributes = node.getAttributes(); Node superclass = attributes.getNamedItem("hawtjni_superclass"); if (superclass != null) { return superclass.getNodeValue(); } else { Node name = attributes.getNamedItem("name"); if (name.getNodeValue().equals("NSObject")) { return "id"; } else { return "NSObject"; } } } void generateClasses() { TreeMap classes = getGeneratedClasses(); copyClassMethodsDown(classes); Set classNames = classes.keySet(); for (Iterator iterator = classNames.iterator(); iterator.hasNext();) { ByteArrayOutputStream out = new ByteArrayOutputStream(); this.out = new PrintStream(out); // out(fixDelimiter(metaData.getCopyright())); String className = iterator.next(); NodeEntry clazz = classes.get(className); Node node = clazz.parent; ArrayList methods = clazz.children; out("package "); String packageName = getPackageName(mainClassName); out(packageName); out(";"); outln(); outln(); out("public class "); out(className); out(" extends "); out(getSuperclassName(node)); out(" {"); outln(); outln(); generateExtraMethods(className); generateMethods(className, methods); out("}"); outln(); String fileName = outputDir + packageName.replace('.', '/') + "/" + className + ".java"; try { out.flush(); if (out.size() > 0) { FileSupport.write(out.toByteArray(), new File(fileName)); } } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } out = null; } } void generateExtraAttributes() { Document[] documents = getDocuments(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null || !getGen(document.getDocumentElement())) continue; saveExtraAttributes(xmls[x], document); } } void generateMainClass() { ByteArrayOutputStream out = new ByteArrayOutputStream(); this.out = new PrintStream(out); String header = "", footer = ""; String fileName = outputDir + mainClassName.replace('.', '/') + ".java"; FileInputStream is = null; try { InputStreamReader input = new InputStreamReader(new BufferedInputStream(is = new FileInputStream(fileName))); StringBuffer str = new StringBuffer(); char[] buffer = new char[4096]; int read; while ((read = input.read(buffer)) != -1) { str.append(buffer, 0, read); } String section = "/** This section is auto generated */"; int start = str.indexOf(section) + section.length(); int end = str.indexOf(section, start); header = str.substring(0, start); footer = str.substring(end); } catch (IOException e) { } finally { try { if (is != null) is.close(); } catch (IOException e) { } } out(header); outln(); outln(); out("/** Custom callbacks */"); outln(); generateCustomCallbacks(); outln(); out("/** Classes */"); outln(); generateClassesConst(); outln(); out("/** Protocols */"); outln(); generateProtocolsConst(); outln(); out("/** Selectors */"); outln(); generateSelectorsConst(); outln(); out("/** Constants */"); outln(); generateEnums(); outln(); out("/** Globals */"); outln(); generateConstants(); outln(); out("/** Functions */"); outln(); outln(); generateFunctions(); outln(); out("/** Super Sends */"); outln(); generateSends(true); outln(); out("/** Sends */"); outln(); generateSends(false); outln(); generateStructNatives(); outln(); out(footer); try { out.flush(); if (out.size() > 0) { FileSupport.write(out.toByteArray(), new File(fileName)); } } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } public Document[] getDocuments() { if (documents == null) { String[] xmls = getXmls(); documents = new Document[xmls.length]; for (int i = 0; i < xmls.length; i++) { String xmlPath = xmls[i]; Document document = documents[i] = getDocument(xmlPath); if (document == null) continue; if (mainClassName != null && outputDir != null) { String packageName = getPackageName(mainClassName); String extrasPath = outputDir + packageName.replace('.', '/') + "/" + getFileName(xmlPath) + ".extras"; merge(document, getDocument(extrasPath)); } } } return documents; } public String[] getXmls() { if (xmls == null || xmls.length == 0) { ArrayList array = new ArrayList(); list(new File("/System/Library/Frameworks"), array); list(new File("/System/Library/Frameworks/CoreServices.framework/Frameworks"), array); list(new File("/System/Library/Frameworks/ApplicationServices.framework/Frameworks"), array); Collections.sort(array, new Comparator() { public int compare(String o1, String o2) { return new File(o1).getName().compareTo(new File(o2).getName()); } }); xmls = array.toArray(new String[array.size()]); } return xmls; } void saveExtraAttributes(String xmlPath, Document document) { try { String packageName = getPackageName(mainClassName); String fileName = outputDir + packageName.replace('.', '/') + "/" + getFileName(xmlPath) + ".extras"; ByteArrayOutputStream out = new ByteArrayOutputStream(); DOMWriter writer = new DOMWriter(new PrintStream(out)); String[] names = getIDAttributeNames(); String[] filter = new String[names.length + 2]; filter[0] = "class_method"; filter[1] = "hawtjni_.*"; System.arraycopy(names, 0, filter, 2, names.length); writer.setAttributeFilter(filter); writer.setNodeFilter("hawtjni_"); writer.print(document); if (out.size() > 0) { FileSupport.write(out.toByteArray(), new File(fileName)); } } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } public void setOutputDir(String dir) { if (dir != null) { if (!dir.endsWith("\\") && !dir.endsWith("/")) { dir += "/"; } } this.outputDir = dir; } public void setXmls(String[] xmls) { this.xmls = xmls; this.documents = null; } public void setMainClass(String mainClassName) { this.mainClassName = mainClassName; } Document getDocument(String xmlPath) { try { InputStream is = null; if (xmlPath.indexOf(File.separatorChar) == -1) is = getClass().getResourceAsStream(xmlPath); if (is == null) is = new BufferedInputStream(new FileInputStream(xmlPath)); if (is != null) return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(is)); } catch (Exception e) { // e.printStackTrace(); } return null; } public String[] getExtraAttributeNames(Node node) { String name = node.getNodeName(); if (name.equals("method")) { return new String[] { "hawtjni_gen_super_msgSend", "hawtjni_gen_custom_callback" }; } else if (name.equals("function")) { NamedNodeMap attribs = node.getAttributes(); if (attribs != null && attribs.getNamedItem("variadic") != null) { return new String[] { "hawtjni_variadic_count", "hawtjni_variadic_java_types" }; } } else if (name.equals("class")) { return new String[] { "hawtjni_superclass" }; } else if (name.equals("retval")) { return new String[] { "hawtjni_java_type", "hawtjni_java_type64", "hawtjni_alloc" }; } else if (name.equals("arg")) { return new String[] { "hawtjni_java_type", "hawtjni_java_type64" }; } return new String[0]; } public String getFileName(String xmlPath) { File file = new File(xmlPath); return file.getName(); } String getKey(Node node) { StringBuffer buffer = new StringBuffer(); while (node != null) { if (buffer.length() > 0) buffer.append("_"); String name = node.getNodeName(); StringBuffer key = new StringBuffer(name); Node nameAttrib = getIDAttribute(node); if (nameAttrib != null) { key.append("-"); key.append(nameAttrib.getNodeValue()); } NamedNodeMap attributes = node.getAttributes(); if (attributes != null) { boolean isStatic = attributes.getNamedItem("class_method") != null; if (isStatic) key.append("-static"); } buffer.append(key.reverse()); node = node.getParentNode(); } buffer.reverse(); return buffer.toString(); } public Node getIDAttribute(Node node) { NamedNodeMap attributes = node.getAttributes(); if (attributes == null) return null; String[] names = getIDAttributeNames(); for (int i = 0; i < names.length; i++) { Node nameAttrib = attributes.getNamedItem(names[i]); if (nameAttrib != null) return nameAttrib; } return null; } public String[] getIDAttributeNames() { return new String[] { "name", "selector", "path", }; } void merge(Node node, HashMap extras, HashMap docLookup) { NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node childNode = list.item(i); if (childNode.getNodeType() == Node.ELEMENT_NODE) { String key = getKey(childNode); if (docLookup != null && docLookup.get(key) == null) { docLookup.put(key, childNode); } Node extra = extras.remove(key); if (extra != null) { NamedNodeMap attributes = extra.getAttributes(); for (int j = 0, length = attributes.getLength(); j < length; j++) { Node attr = (Node) attributes.item(j); String name = attr.getNodeName(); if (name.startsWith("hawtjni_")) { ((Element) childNode).setAttribute(name, attr.getNodeValue()); } } } } merge(childNode, extras, docLookup); } } void out(String str) { PrintStream out = this.out; if (out == null) out = System.out; out.print(str); } void outln() { PrintStream out = this.out; if (out == null) out = System.out; out.println(); } void generateConstants() { for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("constant".equals(node.getNodeName())) { if (getGen(node)) { NamedNodeMap attributes = node.getAttributes(); String constName = attributes.getNamedItem("name").getNodeValue(); out("/** @method flags=const */"); outln(); out("public static final native "); String type = getType(node), type64 = getType64(node); out(type); if (!type.equals(type64)) { out(" /*"); out(type64); out("*/"); } out(" "); out(constName); out("();"); outln(); if (attributes.getNamedItem("declared_type").getNodeValue().equals("NSString*")) { out("public static final NSString "); out(constName); out(" = new NSString("); out(constName); out("());"); outln(); } } } } } } void generateEnums() { for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("enum".equals(node.getNodeName())) { if (getGen(node)) { NamedNodeMap attributes = node.getAttributes(); Node valueNode = attributes.getNamedItem("value"); if (valueNode != null) { String value = valueNode.getNodeValue(); out("public static final "); boolean isLong = false; if (value.indexOf('.') != -1) { out("double "); } else { try { Integer.parseInt(value); out("int "); } catch (NumberFormatException e) { isLong = true; out("long "); } } out(attributes.getNamedItem("name").getNodeValue()); out(" = "); out(value); if (isLong && !value.endsWith("L")) out("L"); out(";"); outln(); } } } } } } boolean getGen(Node node) { NamedNodeMap attributes = node.getAttributes(); if (attributes == null) return false; Node gen = attributes.getNamedItem("hawtjni_gen"); return gen != null && !gen.getNodeValue().equals("false"); } boolean getGenSuper(Node node) { NamedNodeMap attributes = node.getAttributes(); if (attributes == null) return false; Node gen = attributes.getNamedItem("hawtjni_gen_super_msgSend"); return gen != null && !gen.getNodeValue().equals("false"); } boolean getGenCallback(Node node) { NamedNodeMap attributes = node.getAttributes(); if (attributes == null) return false; Node gen = attributes.getNamedItem("hawtjni_gen_custom_callback"); return gen != null && !gen.getNodeValue().equals("false"); } boolean isStatic(Node node) { NamedNodeMap attributes = node.getAttributes(); Node isStatic = attributes.getNamedItem("class_method"); return isStatic != null && isStatic.getNodeValue().equals("true"); } boolean isStruct(Node node) { NamedNodeMap attributes = node.getAttributes(); String code = attributes.getNamedItem("type").getNodeValue(); return code.startsWith("{"); } boolean isFloatingPoint(Node node) { NamedNodeMap attributes = node.getAttributes(); String code = attributes.getNamedItem("type").getNodeValue(); return code.equals("f") || code.equals("d"); } boolean isObject(Node node) { NamedNodeMap attributes = node.getAttributes(); String code = attributes.getNamedItem("type").getNodeValue(); return code.equals("@"); } boolean isBoolean(Node node) { NamedNodeMap attributes = node.getAttributes(); String code = attributes.getNamedItem("type").getNodeValue(); return code.equals("B"); } void buildLookup(Node node, HashMap table) { NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node childNode = list.item(i); if (childNode.getNodeType() == Node.ELEMENT_NODE) { String key = getKey(childNode); if (table.get(key) == null) table.put(key, childNode); buildLookup(childNode, table); } } } boolean isUnique(Node method, ArrayList methods) { String methodName = method.getAttributes().getNamedItem("selector").getNodeValue(); String signature = ""; NodeList params = method.getChildNodes(); for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { signature += getJavaType(param); } } int index = methodName.indexOf(":"); if (index != -1) methodName = methodName.substring(0, index); for (Node node : methods) { NamedNodeMap attributes = node.getAttributes(); Node otherSel = null; if (attributes != null) otherSel = attributes.getNamedItem("selector"); if (node != method && otherSel != null) { String otherName = otherSel.getNodeValue(); index = otherName.indexOf(":"); if (index != -1) otherName = otherName.substring(0, index); if (methodName.equals(otherName)) { NodeList otherParams = node.getChildNodes(); String otherSignature = ""; for (int k = 0; k < otherParams.getLength(); k++) { Node param = otherParams.item(k); if ("arg".equals(param.getNodeName())) { otherSignature += getJavaType(param); } } if (signature.equals(otherSignature)) { return false; } } } } return true; } void generateSelectorsConst() { TreeSet set = new TreeSet(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("class".equals(node.getNodeName()) || "informal_protocol".equals(node.getNodeName())) { if (getGen(node)) { NodeList methods = node.getChildNodes(); for (int j = 0; j < methods.getLength(); j++) { Node method = methods.item(j); if (getGen(method)) { NamedNodeMap mthAttributes = method.getAttributes(); String sel = mthAttributes.getNamedItem("selector").getNodeValue(); set.add(sel); } } } } } } set.add("alloc"); for (Iterator iterator = set.iterator(); iterator.hasNext();) { String sel = iterator.next(); String selConst = getSelConst(sel); out("public static final int /*long*/ "); out(selConst); out(" = "); out("sel_registerName(\""); out(sel); out("\");"); outln(); } } void generateStructNatives() { TreeSet set = new TreeSet(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("struct".equals(node.getNodeName()) && getGen(node)) { set.add(getIDAttribute(node).getNodeValue()); } } } out("/** Sizeof natives */"); outln(); for (Iterator iterator = set.iterator(); iterator.hasNext();) { String struct = iterator.next(); out("public static final native int "); out(struct); out("_sizeof();"); outln(); } outln(); out("/** Memmove natives */"); outln(); outln(); for (Iterator iterator = set.iterator(); iterator.hasNext();) { String struct = iterator.next(); out("/**"); outln(); out(" * @param dest cast=(void *),flags=no_in critical"); outln(); out(" * @param src cast=(void *),flags=critical"); // out(" * @param src cast=(void *),flags=no_out critical"); outln(); out(" */"); outln(); out("public static final native void memmove("); out("int /*long*/ dest, "); out(struct); out(" src, int /*long*/ size);"); outln(); out("/**"); outln(); out(" * @param dest cast=(void *),flags=no_in critical"); outln(); out(" * @param src cast=(void *),flags=critical"); // out(" * @param src cast=(void *),flags=no_out critical"); outln(); out(" */"); outln(); out("public static final native void memmove("); out(struct); out(" dest, int /*long*/ src, int /*long*/ size);"); outln(); } } String buildSend(Node method, boolean tags, boolean only64, boolean superCall) { Node returnNode = getReturnNode(method.getChildNodes()); StringBuffer buffer = new StringBuffer(); buffer.append("public static final native "); if (returnNode != null && isStruct(returnNode)) { buffer.append("void "); buffer.append(superCall ? "objc_msgSendSuper_stret" : "objc_msgSend_stret"); buffer.append("("); buffer.append(getJavaType(returnNode)); buffer.append(" result, "); } else if (returnNode != null && isFloatingPoint(returnNode)) { buffer.append("double "); buffer.append(superCall ? "objc_msgSendSuper_fpret" : "objc_msgSend_fpret"); buffer.append("("); } else if (returnNode != null && isBoolean(returnNode)) { buffer.append("boolean "); buffer.append(superCall ? "objc_msgSendSuper_bool" : "objc_msgSend_bool"); buffer.append("("); } else { if (only64) { buffer.append("long"); } else { if (tags) { buffer.append("int /*long*/"); } else { buffer.append("int"); } } buffer.append(" "); buffer.append(superCall ? "objc_msgSendSuper" : "objc_msgSend"); buffer.append("("); } if (superCall) { if (only64) { buffer.append("objc_super superId, long sel"); } else { if (tags) { buffer.append("objc_super superId, int /*long*/ sel"); } else { buffer.append("objc_super superId, int sel"); } } } else { if (only64) { buffer.append("long id, long sel"); } else { if (tags) { buffer.append("int /*long*/ id, int /*long*/ sel"); } else { buffer.append("int id, int sel"); } } } NodeList params = method.getChildNodes(); boolean first = false; int count = 0; for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { if (!first) buffer.append(", "); if (isStruct(param)) { buffer.append(getJavaType(param)); } else { String type = getType(param), type64 = getType64(param); buffer.append(only64 ? type64 : type); if (!only64 && tags && !type.equals(type64)) { buffer.append(" /*"); buffer.append(type64); buffer.append("*/"); } } first = false; buffer.append(" arg"); buffer.append(String.valueOf(count++)); } } buffer.append(");"); return buffer.toString(); } String getCType(Node node) { NamedNodeMap attributes = node.getAttributes(); return attributes.getNamedItem("declared_type").getNodeValue(); } Node findNSObjectMethod(Node method) { NamedNodeMap methodAttributes = method.getAttributes(); String selector = methodAttributes.getNamedItem("selector").getNodeValue(); NodeList list = method.getParentNode().getParentNode().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node cls = list.item(i); if ("class".equals(cls.getNodeName())) { NamedNodeMap classAttributes = cls.getAttributes(); if ("NSObject".equals(classAttributes.getNamedItem("name").getNodeValue())) { NodeList methods = cls.getChildNodes(); for (int j = 0; j < methods.getLength(); j++) { Node mth = methods.item(j); if ("method".equals(mth.getNodeName())) { NamedNodeMap mthAttributes = mth.getAttributes(); if (selector.equals(mthAttributes.getNamedItem("selector").getNodeValue())) { return mth; } } } } } } return null; } void generateCustomCallbacks() { TreeMap set = new TreeMap(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if (("class".equals(node.getNodeName()) || "informal_protocol".equals(node.getNodeName())) && getGen(node)) { NodeList methods = node.getChildNodes(); for (int j = 0; j < methods.getLength(); j++) { Node method = methods.item(j); if ("method".equals(method.getNodeName()) && getGen(method) && getGenCallback(method)) { NamedNodeMap mthAttributes = method.getAttributes(); String sel = mthAttributes.getNamedItem("selector").getNodeValue(); set.put(sel, method); } } } } } for (Iterator iterator = set.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); Node method = set.get(key); if ("informal_protocol".equals(method.getParentNode().getNodeName())) { method = findNSObjectMethod(method); if (method == null) continue; } String nativeMth = key.replaceAll(":", "_"); out("/** @method callback_types="); Node returnNode = getReturnNode(method.getChildNodes()); out(returnNode == null ? "void" : getCType(returnNode)); out(";id;SEL;"); NodeList params = method.getChildNodes(); for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { out(getCType(param)); out(";"); } } out(",callback_flags="); out(returnNode != null && isStruct(returnNode) ? "struct" : "none"); out(";none;none;"); for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { out(isStruct(param) ? "struct" : "none"); out(";"); } } out(" */"); outln(); out("public static final native int /*long*/ CALLBACK_"); out(nativeMth); out("(int /*long*/ func);"); outln(); } } void generateSends(boolean superCall) { TreeMap set = new TreeMap(); TreeMap set64 = new TreeMap(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("class".equals(node.getNodeName()) && getGen(node)) { NodeList methods = node.getChildNodes(); for (int j = 0; j < methods.getLength(); j++) { Node method = methods.item(j); if ("method".equals(method.getNodeName()) && getGen(method) && (!superCall || getGenSuper(method))) { String code = buildSend(method, false, false, superCall); String code64 = buildSend(method, false, true, superCall); if (set.get(code) == null) { set.put(code, method); } if (set64.get(code64) == null) { set64.put(code64, method); } } } } } } outln(); TreeMap tagsSet = new TreeMap(); for (Iterator iterator = set.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); Node method = set.get(key); String tagCode = buildSend(method, false, true, superCall); if (set64.get(tagCode) != null) { tagsSet.put(key, method); iterator.remove(); set64.remove(tagCode); } } TreeMap all = new TreeMap(); for (Iterator iterator = tagsSet.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); Node method = tagsSet.get(key); all.put(buildSend(method, true, false, superCall), method); } for (Iterator iterator = set.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); all.put(key, set.get(key)); } for (Iterator iterator = set64.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); all.put(key, set64.get(key)); } for (Iterator iterator = all.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); Node method = all.get(key); NodeList params = method.getChildNodes(); ArrayList tags = new ArrayList(); int count = 0; for (int k = 0; k < params.getLength(); k++) { Node param = params.item(k); if ("arg".equals(param.getNodeName())) { if (isStruct(param)) { tags.add(" * @param arg" + count + " flags=struct"); } count++; } } out("/**"); if (tags.size() > 0) { outln(); out(" *"); } out(" @method flags=cast"); if (tags.size() > 0) outln(); for (String tag : tags) { out(tag); outln(); } out(" */"); outln(); out(key.toString()); outln(); } } String getSelConst(String sel) { return "sel_" + sel.replaceAll(":", "_"); } void generateClassesConst() { TreeSet set = new TreeSet(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("class".equals(node.getNodeName())) { if (getGen(node)) { NamedNodeMap attributes = node.getAttributes(); String name = attributes.getNamedItem("name").getNodeValue(); set.add(name); } } } } for (Iterator iterator = set.iterator(); iterator.hasNext();) { String cls = iterator.next(); String clsConst = "class_" + cls; out("public static final int /*long*/ "); out(clsConst); out(" = "); out("objc_getClass(\""); out(cls); out("\");"); outln(); } } void generateProtocolsConst() { TreeSet set = new TreeSet(); for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("informal_protocol".equals(node.getNodeName())) { if (getGen(node)) { NamedNodeMap attributes = node.getAttributes(); String name = attributes.getNamedItem("name").getNodeValue(); set.add(name); } } } } for (Iterator iterator = set.iterator(); iterator.hasNext();) { String cls = iterator.next(); String clsConst = "protocol_" + cls; out("public static final int /*long*/ "); out(clsConst); out(" = "); out("objc_getProtocol(\""); out(cls); out("\");"); outln(); } } String getPackageName(String className) { int dot = mainClassName.lastIndexOf('.'); if (dot == -1) return ""; return mainClassName.substring(0, dot); } String getClassName(String className) { int dot = mainClassName.lastIndexOf('.'); if (dot == -1) return mainClassName; return mainClassName.substring(dot + 1); } Node getReturnNode(NodeList list) { for (int j = 0; j < list.getLength(); j++) { Node node = list.item(j); if ("retval".equals(node.getNodeName())) { return node; } } return null; } String getType(Node node) { NamedNodeMap attributes = node.getAttributes(); Node javaType = attributes.getNamedItem("hawtjni_java_type"); if (javaType != null) return javaType.getNodeValue(); String code = attributes.getNamedItem("type").getNodeValue(); return getType(code, attributes, false); } String getType64(Node node) { NamedNodeMap attributes = node.getAttributes(); Node javaType = attributes.getNamedItem("hawtjni_java_type"); if (javaType != null) { Node javaType64 = attributes.getNamedItem("hawtjni_java_type64"); return javaType64 != null ? javaType64.getNodeValue() : javaType.getNodeValue(); } Node attrib = attributes.getNamedItem("type"); String code = attrib.getNodeValue(); Node attrib64 = attributes.getNamedItem("type64"); if (attrib64 != null) code = attrib64.getNodeValue(); return getType(code, attributes, true); } String getType(String code, NamedNodeMap attributes, boolean is64) { if (code.equals("c")) return "byte"; if (code.equals("i")) return "int"; if (code.equals("s")) return "short"; if (code.equals("l")) return "int"; if (code.equals("q")) return "long"; if (code.equals("C")) return "byte"; if (code.equals("I")) return "int"; if (code.equals("S")) return "short"; if (code.equals("L")) return "int"; if (code.equals("Q")) return "long"; if (code.equals("f")) return "float"; if (code.equals("d")) return "double"; if (code.equals("B")) return "boolean"; if (code.equals("v")) return "void"; if (code.equals("*")) return is64 ? "long" : "int"; if (code.equals("@")) return is64 ? "long" : "int"; if (code.equals("#")) return is64 ? "long" : "int"; if (code.equals(":")) return is64 ? "long" : "int"; if (code.startsWith("^")) return is64 ? "long" : "int"; if (code.startsWith("{")) { return attributes.getNamedItem("declared_type").getNodeValue(); } return "BAD " + code; } String getJNIType(Node node) { NamedNodeMap attributes = node.getAttributes(); String code = attributes.getNamedItem("type").getNodeValue(); if (code.equals("c")) return "B"; if (code.equals("i")) return "I"; if (code.equals("s")) return "S"; if (code.equals("l")) return "I"; if (code.equals("q")) return "J"; if (code.equals("C")) return "B"; if (code.equals("I")) return "I"; if (code.equals("S")) return "S"; if (code.equals("L")) return "I"; if (code.equals("Q")) return "J"; if (code.equals("f")) return "F"; if (code.equals("d")) return "D"; if (code.equals("B")) return "Z"; if (code.equals("v")) return "V"; if (code.equals("*")) return "I"; if (code.equals("@")) return "I"; if (code.equals("#")) return "I"; if (code.equals(":")) return "I"; if (code.startsWith("^")) return "I"; if (code.startsWith("[")) return "BAD " + code; if (code.startsWith("{")) { return "BAD " + code; } if (code.startsWith("(")) return "BAD " + code; return "BAD " + code; } String getJavaType(Node node) { NamedNodeMap attributes = node.getAttributes(); Node javaType = attributes.getNamedItem("hawtjni_java_type"); if (javaType != null) return javaType.getNodeValue().trim(); String code = attributes.getNamedItem("type").getNodeValue(); return getJavaType(code, attributes, false); } String getJavaType64(Node node) { NamedNodeMap attributes = node.getAttributes(); Node javaType = attributes.getNamedItem("hawtjni_java_type"); if (javaType != null) { Node javaType64 = attributes.getNamedItem("hawtjni_java_type64"); return javaType64 != null ? javaType64.getNodeValue() : javaType.getNodeValue(); } Node attrib = attributes.getNamedItem("type"); String code = attrib.getNodeValue(); Node attrib64 = attributes.getNamedItem("type64"); if (attrib64 != null) code = attrib64.getNodeValue(); return getJavaType(code, attributes, true); } String getJavaType(String code, NamedNodeMap attributes, boolean is64) { if (code.equals("c")) return "byte"; if (code.equals("i")) return "int"; if (code.equals("s")) return "short"; if (code.equals("l")) return "int"; if (code.equals("q")) return "long"; if (code.equals("C")) return "byte"; if (code.equals("I")) return "int"; if (code.equals("S")) return "short"; if (code.equals("L")) return "int"; if (code.equals("Q")) return "long"; if (code.equals("f")) return "float"; if (code.equals("d")) return "double"; if (code.equals("B")) return "boolean"; if (code.equals("v")) return "void"; if (code.equals("*")) return is64 ? "long" : "int"; if (code.equals("#")) return is64 ? "long" : "int"; if (code.equals(":")) return is64 ? "long" : "int"; if (code.startsWith("^")) return is64 ? "long" : "int"; if (code.equals("@")) { String type = attributes.getNamedItem("declared_type").getNodeValue(); int index = type.indexOf('*'); if (index != -1) type = type.substring(0, index); index = type.indexOf('<'); if (index != -1) type = type.substring(0, index); return type.trim(); } if (code.startsWith("{")) { return attributes.getNamedItem("declared_type").getNodeValue().trim(); } return "BAD " + code; } static String[] split(String str, String separator) { StringTokenizer tk = new StringTokenizer(str, separator); ArrayList result = new ArrayList(); while (tk.hasMoreElements()) { result.add(tk.nextElement()); } return result.toArray(new String[result.size()]); } void generateFunctions() { for (int x = 0; x < xmls.length; x++) { Document document = documents[x]; if (document == null) continue; NodeList list = document.getDocumentElement().getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if ("function".equals(node.getNodeName())) { if (getGen(node)) { NamedNodeMap attributes = node.getAttributes(); String name = attributes.getNamedItem("name").getNodeValue(); NodeList params = node.getChildNodes(); int count = 0; for (int j = 0; j < params.getLength(); j++) { Node param = params.item(j); if ("arg".equals(param.getNodeName())) { count++; } } if (count > 0) { out("/**"); outln(); } for (int j = 0; j < params.getLength(); j++) { Node param = params.item(j); if ("arg".equals(param.getNodeName())) { NamedNodeMap paramAttributes = param.getAttributes(); out(" * @param "); out(paramAttributes.getNamedItem("name").getNodeValue()); if (isStruct(param)) { out(" flags=struct"); } else { out(" cast="); Node declaredType = paramAttributes.getNamedItem("declared_type"); String cast = declaredType.getNodeValue(); if (!cast.startsWith("(")) out("("); out(cast); if (!cast.endsWith(")")) out(")"); } outln(); } } if (count > 0) { out(" */"); outln(); } out("public static final native "); Node returnNode = getReturnNode(node.getChildNodes()); if (returnNode != null) { String type = getType(returnNode), type64 = getType64(returnNode); out(type); if (!type.equals(type64)) { out(" /*"); out(type64); out("*/"); } out(" "); } else { out("void "); } out(name); out("("); params = node.getChildNodes(); boolean first = true; for (int j = 0; j < params.getLength(); j++) { Node param = params.item(j); if ("arg".equals(param.getNodeName())) { NamedNodeMap paramAttributes = param.getAttributes(); if (!first) out(", "); first = false; String type = getType(param), type64 = getType64(param); out(type); if (!type.equals(type64)) { out(" /*"); out(type64); out("*/"); } out(" "); out(paramAttributes.getNamedItem("name").getNodeValue()); } } generateVariadics(node); out(");"); outln(); } } } } } void generateVariadics(Node node) { NamedNodeMap attributes = node.getAttributes(); Node variadicCount = attributes.getNamedItem("hawtjni_variadic_count"); if (variadicCount != null) { Node variadicTypes = attributes.getNamedItem("hawtjni_variadic_java_types"); String[] types = null; if (variadicTypes != null) { types = split(variadicTypes.getNodeValue(), ","); } int varCount = 0; try { varCount = Integer.parseInt(variadicCount.getNodeValue()); } catch (NumberFormatException e) { } for (int j = 0; j < varCount; j++) { out(", "); if (types != null && types.length > j && !types[j].equals("*")) { out(types[j]); } else if (types != null && types[types.length - 1].equals("*")) { out(types[types.length - 2]); } else { out("int /*long*/"); } out(" varArg"); out("" + j); } } } public static void main(String[] args) { try { MacGenerator gen = new MacGenerator(); gen.setXmls(args); gen.setOutputDir("../org.eclipse.hawtjni/Eclipse SWT PI/cocoa/"); gen.setMainClass("org.eclipse.hawtjni.internal.cocoa.OS"); gen.generate(null); } catch (Throwable e) { e.printStackTrace(); } } } MozillaGenerator.java000077500000000000000000000577471142665006500357710ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2003, 2006 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.io.*; import java.util.*; /** * Produces the java classes mapping to XPCOM Mozilla objects. * * @author Hiram Chirino */ public class MozillaGenerator { static boolean DEBUG = false; FileReader r = null; FileWriter w = null; int maxLines = 1000; int cntLines = 0; int n = 0; String[] b = null; String body = null; int nMethods = 0; String uuidName; String uuidValue; String className; String parentName; String[] constantNames; String[] constantValues; String[] methodNames; String[][] argTypes; String[][] argNames; String bodyOrder; TreeMap> vtbls = new TreeMap>(); // Contains the characters found before a method name // Useful to extract the method name. e.g. // NS_IMETHOD QueryInterface(const nsIID & uuid, void * *result) = 0; // NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; // method name follows: QueryInterface, AddRef etc. static String[] BEFORE_METHOD_NAME = { " NS_IMETHOD ", " NS_IMETHOD_(nsrefcnt) ", " NS_IMETHOD_(void *) ", " NS_IMETHOD_(void) ", " NS_IMETHOD_(nsresult) ", " NS_SCRIPTABLE NS_IMETHOD ", " NS_SCRIPTABLE NS_IMETHOD_(nsrefcnt) ", " NS_SCRIPTABLE NS_IMETHOD_(void *) ", " NS_SCRIPTABLE NS_IMETHOD_(void) ", " NS_SCRIPTABLE NS_IMETHOD_(nsresult) ", }; static String NO_SUPER_CLASS = "SWT_NO_SUPER_CLASS"; static String[][] TYPES_C2JAVA = { { "PRBool *", "int[]" }, { "nsIID &", "nsID" }, { "nsCID &", "nsID" }, { "nsCID * *", "int /*long*/" }, // nsID[] not supported by jnigen { "* *", "int /*long*/[]" }, { "**", "int /*long*/[]" }, { "* &", "int /*long*/[]" }, { "PRUint32 *", "int[]" }, { "PRInt32 *", "int[]" }, { "PRInt64 *", "long[]" }, { "PRUnichar *", "char[]" }, { "char *", "byte[]" }, { "float *", "float[]" }, { "PRUint16 *", "short[]" }, { "nativeWindow *", "int /*long*/[]" }, { "nsWriteSegmentFun", "int /*long*/" }, { "nativeWindow", "int /*long*/" }, { "*", "int /*long*/" }, // c type containing one or more * (and any // other character, and did not match // previous patterns) is a simple pointer { "&", "int /*long*/" }, { "PRUint32", "int" }, { "PRInt32", "int" }, { "PRInt64", "long" }, { "nsresult", "int" }, { "PRBool", "int" }, { "float", "float" }, { "PRUint16", "short" }, { "size_t", "int" }, }; static String GECKO = "/bluebird/teamhawtjni/hawtjni-builddir/mozilla/1.4/linux_gtk2/mozilla/dist/include/"; static String TARGET_FOLDER = "/bluebird/teamhawtjni/chrisx/amd64/workspace/org.eclipse.hawtjni/Eclipse SWT Mozilla/common/org/eclipse/hawtjni/internal/mozilla/"; static String[] XPCOM_HEADERS = { "profile/nsIProfile.h", "widget/nsIAppShell.h", "widget/nsIBaseWindow.h", "xpcom/nsIComponentManager.h", "xpcom/nsIComponentRegistrar.h", "webbrwsr/nsIContextMenuListener.h", "docshell/nsIDocShell.h", "dom/nsIDOMEvent.h", "dom/nsIDOMMouseEvent.h", "dom/nsIDOMUIEvent.h", "dom/nsIDOMWindow.h", "uriloader/nsIDownload.h", "webbrwsr/nsIEmbeddingSiteWindow.h", "xpcom/nsIFactory.h", "xpcom/nsIFile.h", "helperAppDlg/nsIHelperAppLauncherDialog.h", "exthandler/nsIExternalHelperAppService.h", // contains // nsIHelperAppLauncher "xpcom/nsIInputStream.h", "xpcom/nsIInterfaceRequestor.h", "necko/nsIIOService.h", "xpcom/nsILocalFile.h", "xpcom/nsIMemory.h", "progressDlg/nsIProgressDialog.h", "windowwatcher/nsIPromptService.h", "xpcom/nsIServiceManager.h", "xpcom/nsISupports.h", "webbrwsr/nsITooltipListener.h", "necko/nsIURI.h", "uriloader/nsIURIContentListener.h", "xpcom/nsIWeakReference.h", "webbrwsr/nsIWebBrowser.h", "webbrwsr/nsIWebBrowserChrome.h", "webbrwsr/nsIWebBrowserChromeFocus.h", "webbrwsr/nsIWebBrowserFocus.h", "docshell/nsIWebNavigation.h", "uriloader/nsIWebProgress.h", "uriloader/nsIWebProgressListener.h", "embed_base/nsIWindowCreator.h", "windowwatcher/nsIWindowWatcher.h" }; public static void main(String[] args) { MozillaGenerator x = new MozillaGenerator(); for (int i = 0; i < XPCOM_HEADERS.length; i++) x.parse(GECKO + XPCOM_HEADERS[i], TARGET_FOLDER); x.outputVtblCall(); System.out.println("done"); } /** Write callbacks */ public void write(String data) { if (DEBUG) { System.out.print(data); return; } try { w.write(data); } catch (IOException e) { e.printStackTrace(); } } public void writeLine() { if (DEBUG) { System.out.println(); return; } write("\r\n"); } public void writeLine(String data) { if (DEBUG) { System.out.println(data); return; } write(data + "\r\n"); } public void writeCopyrights() { writeLine(COPYRIGHTS); } public void writePackageDeclaration() { writeLine(PACKAGE_DECLARATION); } public void writeClassDeclaration(String className, String parentName) { String line = "public class " + className; if (!parentName.equals(NO_SUPER_CLASS)) line += " extends " + parentName; line += " {"; writeLine(line); } public void writeLastMethodId(String parentName, int nMethods) { String line = "\tstatic final int LAST_METHOD_ID = "; if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + nMethods + ";"; else line += "" + (nMethods - 1) + ";"; // zero indexed writeLine(line); } public void writeIID(String uuidName, String uuidValue) { writeLine("\tpublic static final String " + uuidName + " ="); writeLine("\t\t\"" + uuidValue + "\";"); writeLine(); String iid = uuidName.substring(0, uuidName.indexOf("_STR")); writeLine("\tpublic static final nsID " + iid + " ="); writeLine("\t\tnew nsID(" + uuidName + ");"); } public void writeAddressField() { writeLine("\tint /*long*/ address;"); } public void writeConstructor(String className, String parentName) { writeLine("\tpublic " + className + "(int /*long*/ address) {"); if (!parentName.equals(NO_SUPER_CLASS)) { writeLine("\t\tsuper(address);"); } else { writeLine("\t\tthis.address = address;"); } writeLine("\t}"); } public void writeAddressGetter() { writeLine("\tpublic int /*long*/ getAddress() {"); writeLine("\t\treturn this.address;"); writeLine("\t}"); } public void writeConstant(String name, String value) { writeLine("\tpublic static final int " + name + " = " + value + ";"); } public void writeMethod(String name, String parentName, int methodIndex, String[] argTypes, String[] argNames) { write("\tpublic int " + name + "("); for (int i = 0; i < argTypes.length; i++) { write(argTypes[i] + " " + argNames[i]); if (i < argTypes.length - 1) write(", "); } write(") {"); writeLine(); String line = "\t\treturn XPCOM.VtblCall("; if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + (methodIndex + 1) + ", getAddress()"; else line += methodIndex + ", getAddress()"; // zero indexed write(line); if (argTypes.length > 0) write(", "); for (int i = 0; i < argTypes.length; i++) { write(argNames[i]); if (i < argTypes.length - 1) write(", "); } writeLine(");"); writeLine("\t}"); } public void writeClassEnd() { write("}"); } public void logVtblCall(String[] argTypes) { String vtbl = "static final native int VtblCall(int fnNumber, int /*long*/ ppVtbl"; if (argTypes.length > 0) vtbl += ", "; for (int i = 0; i < argTypes.length; i++) { vtbl += argTypes[i] + " arg" + i; if (i < argTypes.length - 1) vtbl += ", "; } vtbl += ");"; Integer key = new Integer(argTypes.length); TreeSet list = vtbls.get(key); if (list == null) { list = new TreeSet(); vtbls.put(key, list); } boolean duplicate = false; for (String s : list) { if (vtbl.equals(s)) { duplicate = true; break; } } if (!duplicate) list.add(vtbl); } public void outputVtblCall() { Collection> values = vtbls.values(); for (TreeSet elts : values) { for (String elt : elts) { System.out.println(elt); } } } /** Parsing invoking write callbacks */ /* * Convert a C header file into a Java source file matching SWT Mozilla * binding. */ public void parse(String src, String destPath) { if (DEBUG) writeLine("*** PARSING <" + src + "> to folder " + destPath); b = new String[maxLines]; cntLines = 0; try { r = new FileReader(src); BufferedReader br = new BufferedReader(r); while ((b[cntLines] = br.readLine()) != null) { cntLines++; } br.close(); } catch (IOException e) { e.printStackTrace(); return; } n = 0; boolean lookForClasses = true; while (lookForClasses) { /* parsing */ lookForClasses = parse(); String destFile = destPath + className + ".java"; try { w = new FileWriter(destFile); if (DEBUG) writeLine("** CREATED JAVA FILE <" + destFile + ">"); } catch (IOException e) { e.printStackTrace(); return; } /* writing */ writeCopyrights(); writePackageDeclaration(); writeLine(); writeClassDeclaration(className, parentName); writeLine(); writeLastMethodId(parentName, nMethods); writeLine(); writeIID(uuidName, uuidValue); writeLine(); if (parentName.equals(NO_SUPER_CLASS)) { writeAddressField(); writeLine(); } writeConstructor(className, parentName); writeLine(); if (parentName.equals(NO_SUPER_CLASS)) { writeAddressGetter(); writeLine(); } int constantIndex = 0, methodIndex = 0; for (int i = 0; i < bodyOrder.length(); i++) { if (bodyOrder.charAt(i) == 'C') { writeConstant(constantNames[constantIndex], constantValues[constantIndex]); if (i < bodyOrder.length() - 1) writeLine(); constantIndex++; } else if (bodyOrder.charAt(i) == 'M') { writeMethod(methodNames[methodIndex], parentName, methodIndex, argTypes[methodIndex], argNames[methodIndex]); if (i < bodyOrder.length() - 1) writeLine(); methodIndex++; } } writeClassEnd(); try { w.close(); } catch (IOException e) { e.printStackTrace(); } } } public String getPackages() { return "package org.eclipse.hawtjni.internal.mozilla;"; } public boolean parse() { if (!jumpToUuidDeclaration()) return false; uuidName = getUuidName(b[n]); if (DEBUG) System.out.println("UUID name: <" + uuidName + ">"); uuidValue = getUuidValue(b[n]); if (DEBUG) System.out.println("UUID value: <" + uuidValue + ">"); jumpToInterfaceDeclaration(); className = getClassName(b[n]); if (DEBUG) System.out.println("Interface name: <" + className + ">"); parentName = getParentName(b[n]); if (DEBUG) System.out.println("parentName: <" + parentName + ">"); parseBody(); return true; } boolean jumpToUuidDeclaration() { // jump to line matching: // "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c"" while (!(b[n].startsWith("#define ") && b[n].indexOf("_IID_STR \"") != -1)) { n++; if (n >= cntLines) return false; } return true; } // assume a declaration matching: // "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c"" // returns NS_IWEBBROWSERCHROME_IID_STR String getUuidName(String declaration) { return declaration.substring(declaration.indexOf("#define ") + "#define ".length(), declaration.indexOf(" \"")); } // assume a declaration matching: // "#define NS_IWEBBROWSERCHROME_IID_STR "ba434c60-9d52-11d3-afb0-00a024ffc08c"" // returns ba434c60-9d52-11d3-afb0-00a024ffc08c String getUuidValue(String declaration) { return declaration.substring(declaration.indexOf("_IID_STR \"") + "_IID_STR \"".length(), declaration.lastIndexOf('"')); } void jumpToInterfaceDeclaration() { // jump to line matching: // "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {" while (!(b[n].startsWith("class NS_NO_VTABLE "))) { n++; } } // Assume a declaration matching: // "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {" // or // "class NS_NO_VTABLE NS_SCRIPTABLE nsIWebBrowserChrome : public nsISupports {" // returns nsIWebBrowserChrome. // Special case for nsISupports that has no super class: class NS_NO_VTABLE // nsISupports { String getClassName(String declaration) { int endIndex = declaration.indexOf(" :"); // nsISupports special case (no super class) if (endIndex == -1) endIndex = declaration.indexOf(" {"); String searchString = "class NS_NO_VTABLE NS_SCRIPTABLE"; int startIndex = declaration.indexOf(searchString); if (startIndex == -1) { searchString = "class NS_NO_VTABLE "; startIndex = declaration.indexOf(searchString); } return declaration.substring(startIndex + searchString.length(), endIndex); } // assume a declaration matching: // "class NS_NO_VTABLE nsIWebBrowserChrome : public nsISupports {" // returns nsISupports // special case for nsISupports that has no super class: class NS_NO_VTABLE // nsISupports { String getParentName(String declaration) { if (declaration.indexOf(" :") == -1) return NO_SUPER_CLASS; return declaration.substring(declaration.indexOf(": public ") + ": public ".length(), declaration.indexOf(" {")); } // parse methods and constants declarations starting at the current index // out: // .String body - contains the corresponding java content // .n - set to the end of the interface body declaration ( line with the // enclosing "};" ) // .nMethods - set to the number of methods parsed void parseBody() { body = ""; bodyOrder = ""; int nConstants = 0; nMethods = 0; int tmp_n = n; while (true) { int type = jumpToNextConstantOrMethod(); if (type == CONSTANT) nConstants++; if (type == METHOD) nMethods++; if (type == END_BODY) break; n++; } n = tmp_n; constantNames = new String[nConstants]; constantValues = new String[nConstants]; methodNames = new String[nMethods]; argTypes = new String[nMethods][]; argNames = new String[nMethods][]; int constantIndex = 0, methodIndex = 0; while (true) { int type = jumpToNextConstantOrMethod(); if (type == CONSTANT) { parseConstant(b[n], constantIndex); bodyOrder += "C"; constantIndex++; } if (type == METHOD) { parseMethod(b[n], methodIndex); logVtblCall(argTypes[methodIndex]); bodyOrder += "M"; methodIndex++; } if (type == END_BODY) return; n++; } } static int CONSTANT = 0; static int METHOD = 1; static int END_BODY = 2; boolean isEndOfInterfaceBody() { return b[n].startsWith("};"); } int jumpToNextConstantOrMethod() { while (!isEndOfInterfaceBody()) { if (b[n].startsWith(" enum { ")) { return CONSTANT; } if (methodNameStartIndexOf(b[n]) != -1) { return METHOD; } n++; } return END_BODY; } void parseConstant(String constant, int constantIndex) { String constantName = constant.substring(constant.indexOf(" enum { ") + " enum { ".length(), constant.indexOf(" =")); if (DEBUG) writeLine("constantName <" + constantName + ">"); constantNames[constantIndex] = constantName; // most constants values have a trailing U // enum { APP_TYPE_UNKNOWN = 0U }; int endIndex = constant.indexOf("U };"); // a few others don't // enum { ENUMERATE_FORWARDS = 0 }; if (endIndex == -1) endIndex = constant.indexOf(" };"); String constantValue = constant.substring(constant.indexOf(" = ") + " = ".length(), endIndex); if (DEBUG) writeLine("constantValue <" + constantValue + ">"); constantValues[constantIndex] = constantValue; } // NS_IMETHOD SetStatus(PRUint32 statusType, const PRUnichar *status) = 0; // identify: // method name: // Nbr of arguments: 2 // Type of argument 0: PRUint32 // Name of argument 0: statusType // Type of argument 1: const PRUnichar * // Name of argument 1: status void parseMethod(String line, int methodIndex) { int start = methodNameStartIndexOf(line); int end = methodNameEndIndexOf(line); String methodName = line.substring(start, end); if (DEBUG) writeLine("method name: <" + methodName + ">"); methodNames[methodIndex] = methodName; int argStart = end + "(".length(); int argEnd = line.indexOf(")", argStart); parseArgs(line.substring(argStart, argEnd), methodIndex); } // Given a line, returns the start of the method name or -1 // if the line does not contain a method declaration. int methodNameStartIndexOf(String line) { for (int i = 0; i < BEFORE_METHOD_NAME.length; i++) { int index = line.indexOf(BEFORE_METHOD_NAME[i]); if (index != -1) return index + BEFORE_METHOD_NAME[i].length(); } return -1; } int methodNameEndIndexOf(String line) { int startIndex = methodNameStartIndexOf(line); return line.indexOf("(", startIndex); } void parseArgs(String args, int methodIndex) { int nArgs = -1; // methods with no args look like: () or (void) String[] noArgs = new String[] { "", "void" }; for (int i = 0; i < noArgs.length; i++) { if (args.equals(noArgs[i])) { nArgs = 0; break; } } if (nArgs == -1) nArgs = count(args, ", ") + 1; String[] argTypes = new String[nArgs]; this.argTypes[methodIndex] = argTypes; String[] argNames = new String[nArgs]; this.argNames[methodIndex] = argNames; int typeStart = 0; // name is separated from its type by either of the following (sorted by // decreasing size to find the most complete pattern */ String[] typeNameSep = new String[] { " * *", " **", " * & ", " * ", " *", " & ", " " }; for (int i = 0; i < nArgs; i++) { /* get the type */ int nextTypeStart = i < nArgs - 1 ? args.indexOf(", ", typeStart) + ", ".length() : args.length(); int typeNameSepIndex = 0; int separatorIndex = 0; for (; typeNameSepIndex < typeNameSep.length; typeNameSepIndex++) { separatorIndex = args.indexOf(typeNameSep[typeNameSepIndex], typeStart); if (separatorIndex != -1 && separatorIndex < nextTypeStart) break; } String separator = typeNameSep[typeNameSepIndex]; argTypes[i] = getC2JavaType(args.substring(typeStart, separatorIndex + separator.length())); if (DEBUG) writeLine("arg type" + i + ": <" + argTypes[i] + ">"); /* get the name */ int nameStart = separatorIndex + separator.length(); int nameEnd = i < nArgs - 1 ? args.indexOf(", ", nameStart) : args.length(); argNames[i] = args.substring(nameStart, nameEnd); if (DEBUG) writeLine("arg name" + i + ": <" + argNames[i] + ">"); typeStart = nextTypeStart; } } String getC2JavaType(String cType) { for (int i = 0; i < TYPES_C2JAVA.length; i++) { if (cType.indexOf(TYPES_C2JAVA[i][0]) != -1) return TYPES_C2JAVA[i][1]; } return "!ERROR UNKNOWN C TYPE <" + cType + ">!"; } // how many times part can be found in s static int count(String s, String part) { int index = -1, cnt = 0; while ((index = s.indexOf(part, index + 1)) != -1) cnt++; return cnt; } static String COPYRIGHTS = "/* ***** BEGIN LICENSE BLOCK *****\r\n" + " * Version: MPL 1.1\r\n" + " *\r\n" + " * The contents of this file are subject to the Mozilla Public License Version\r\n" + " * 1.1 (the \"License\"); you may not use this file except in compliance with\r\n" + " * the License. You may obtain a copy of the License at\r\n" + " * http://www.mozilla.org/MPL/\r\n" + " *\r\n" + " * Software distributed under the License is distributed on an \"AS IS\" basis,\r\n" + " * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r\n" + " * for the specific language governing rights and limitations under the\r\n" + " * License.\r\n" + " *\r\n" + " * The Original Code is Mozilla Communicator client code, released March 31, 1998.\r\n" + " *\r\n" + " * The Initial Developer of the Original Code is\r\n" + " * Netscape Communications Corporation.\r\n" + " * Portions created by Netscape are Copyright (C) 1998-1999\r\n" + " * Netscape Communications Corporation. All Rights Reserved.\r\n" + " *\r\n" + " * Contributor(s):\r\n" + " *\r\n" + " * IBM\r\n" + " * - Binding to permit interfacing between Mozilla and SWT\r\n" + " * - Copyright (C) 2003, 2009 IBM Corp. All Rights Reserved.\r\n" + " *\r\n" + " * ***** END LICENSE BLOCK ***** */"; static String PACKAGE_DECLARATION = "package org.eclipse.hawtjni.internal.mozilla;"; } NativesGenerator.java000077500000000000000000001253451142665006500357610ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.JNIMethod; import org.fusesource.hawtjni.generator.model.JNIParameter; import org.fusesource.hawtjni.generator.model.JNIType; import org.fusesource.hawtjni.runtime.ArgFlag; import org.fusesource.hawtjni.runtime.ClassFlag; import org.fusesource.hawtjni.runtime.FieldFlag; import org.fusesource.hawtjni.runtime.MethodFlag; import static org.fusesource.hawtjni.runtime.MethodFlag.*; /** * * @author Hiram Chirino */ public class NativesGenerator extends JNIGenerator { boolean enterExitMacro; public NativesGenerator() { enterExitMacro = true; } public void generateCopyright() { outputln(fixDelimiter(getCopyright())); } public void generateIncludes() { String outputName = getOutputName(); outputln("#include \"" + outputName + ".h\""); outputln("#include \"hawtjni.h\""); outputln("#include \"" + outputName + "_structs.h\""); outputln("#include \"" + outputName + "_stats.h\""); outputln(); } public void generate(JNIClass clazz) { List methods = clazz.getNativeMethods(); if( methods.isEmpty() ) { return; } sortMethods(methods); generateNativeMacro(clazz); generate(methods); } public void generate(List methods) { sortMethods(methods); for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; generate(method); if (progress != null) progress.step(); } } boolean isStruct(ArgFlag flags[]) { for (ArgFlag flag : flags) { if (flag.equals(ArgFlag.BY_VALUE)) return true; } return false; } void generateCallback(JNIMethod method, String function, List params, JNIType returnType) { output("static jintLong "); output(function); outputln(";"); output("static "); String[] types = method.getCallbackTypes(); ArgFlag[][] flags = method.getCallbackFlags(); output(types[0]); output(" "); output("proc_"); output(function); output("("); boolean first = true; for (int i = 1; i < types.length; i++) { if (!first) output(", "); output(types[i]); output(" "); output("arg"); output(String.valueOf(i - 1)); first = false; } outputln(") {"); output("\t"); if (isStruct(flags[0])) { output(types[0]); output("* lprc = "); } else if (!types[0].equals("void")) { output("return "); } output("(("); output(types[0]); if (isStruct(flags[0])) output("*"); output(" (*)("); first = true; for (int i = 1; i < types.length; i++) { if (!first) output(", "); first = false; output(types[i]); if (isStruct(flags[i])) output("*"); } output("))"); output(function); output(")("); first = true; for (int i = 1; i < types.length; i++) { if (!first) output(", "); first = false; if (isStruct(flags[i])) output("&"); output("arg"); output(String.valueOf(i - 1)); } outputln(");"); if (isStruct(flags[0])) { output("\t"); output(types[0]); outputln(" rc;"); outputln("\tif (lprc) {"); outputln("\t\trc = *lprc;"); outputln("\t\tfree(lprc);"); outputln("\t} else {"); output("\t\tmemset(&rc, 0, sizeof("); output(types[0]); outputln("));"); outputln("\t}"); outputln("\treturn rc;"); } outputln("}"); output("static jintLong "); output(method.getName()); outputln("(jintLong func) {"); output("\t"); output(function); outputln(" = func;"); output("\treturn (jintLong)proc_"); output(function); outputln(";"); outputln("}"); } private void generateConstantsInitializer(JNIMethod method) { JNIClass clazz = method.getDeclaringClass(); ArrayList constants = getConstantFields(clazz); if( constants.isEmpty() ) { return; } outputln("JNIEXPORT void JNICALL "+clazz.getSimpleName()+"_NATIVE("+toC(method.getName())+")(JNIEnv *env, jclass that)"); outputln("{"); for (JNIField field : constants) { String conditional = field.getConditional(); if (conditional!=null) { outputln("#if "+conditional); } JNIType type = field.getType(), type64 = field.getType64(); boolean allowConversion = !type.equals(type64); String typeName = type.getSimpleName(); String accessor = field.getAccessor(); if (accessor == null || accessor.length() == 0) accessor = field.getName(); String fieldId = "(*env)->GetStaticFieldID(env, that, \""+field.getName()+"\", \""+type.getTypeSignature(allowConversion)+"\")"; if (type.isPrimitive()) { output("\t(*env)->SetStatic"+type.getTypeSignature1(allowConversion)+"Field(env, that, "+fieldId +", "); output("("+type.getTypeSignature2(allowConversion)+")"); if( field.isPointer() ) { output("(intptr_t)"); } output(accessor); output(");"); } else if (type.isArray()) { JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType(); if (componentType.isPrimitive()) { outputln("\t{"); output("\t"); output(type.getTypeSignature2(allowConversion)); output(" lpObject1 = ("); output(type.getTypeSignature2(allowConversion)); if (isCPP) { output(")env->GetStaticObjectField(that, "); } else { output(")(*env)->GetStaticObjectField(env, that, "); } output(field.getDeclaringClass().getSimpleName()); output(fieldId); outputln(");"); if (isCPP) { output("\tenv->Set"); } else { output("\t(*env)->Set"); } output(componentType.getTypeSignature1(!componentType.equals(componentType64))); if (isCPP) { output("ArrayRegion(lpObject1, 0, sizeof("); } else { output("ArrayRegion(env, lpObject1, 0, sizeof("); } output(accessor); output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(allowConversion, false)); output(")"); output(accessor); outputln(");"); output("\t}"); } else { throw new Error("not done"); } } else { outputln("\t{"); output("\tjobject lpObject1 = (*env)->GetStaticObjectField(env, that, "); output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); output("\tif (lpObject1 != NULL) set"); output(typeName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor); outputln(");"); output("\t}"); } outputln(); if (conditional!=null) { outputln("#endif"); } } outputln(" return;"); outputln("}"); } private ArrayList getConstantFields(JNIClass clazz) { ArrayList rc = new ArrayList(); List fields = clazz.getDeclaredFields(); for (JNIField field : fields) { int mods = field.getModifiers(); if ( (mods & Modifier.STATIC) != 0 && field.getFlag(FieldFlag.CONSTANT)) { rc.add(field); } } return rc; } public void generate(JNIMethod method) { if (method.getFlag(MethodFlag.METHOD_SKIP)) return; JNIType returnType = method.getReturnType32(), returnType64 = method.getReturnType64(); if( method.getFlag(CONSTANT_INITIALIZER)) { if( returnType.isType("void") && method.getParameters().isEmpty() ) { generateConstantsInitializer(method); } else { output("#error Warning: invalid CONSTANT_INITIALIZER tagged method. It must be void and take no arguments: "); outputln(method.toString()); } return; } if (!(returnType.isType("void") || returnType.isPrimitive() || isSystemClass(returnType) || returnType.isType("java.lang.String"))) { output("#error Warning: bad return type. :"); outputln(method.toString()); return; } String conditional = method.getConditional(); if (conditional!=null) { outputln("#if "+conditional); } List params = method.getParameters(); String function = getFunctionName(method), function64 = getFunctionName(method, method.getParameterTypes64()); boolean sameFunction = function.equals(function64); if (!sameFunction) { output("#ifndef "); output(JNI64); outputln(); } if (isCPP) { output("extern \"C\" "); generateFunctionPrototype(method, function, params, returnType, returnType64, true); outputln(";"); } if (function.startsWith("CALLBACK_")) { generateCallback(method, function, params, returnType); } generateFunctionPrototype(method, function, params, returnType, returnType64, !sameFunction); if (!function.equals(function64)) { outputln(); outputln("#else"); if (isCPP) { output("extern \"C\" "); generateFunctionPrototype(method, function64, params, returnType, returnType64, true); outputln(";"); } generateFunctionPrototype(method, function64, params, returnType, returnType64, !sameFunction); outputln(); outputln("#endif"); } generateFunctionBody(method, function, function64, params, returnType, returnType64); if (conditional!=null) { outputln("#endif"); } outputln(); } public void setEnterExitMacro(boolean enterExitMacro) { this.enterExitMacro = enterExitMacro; } void generateNativeMacro(JNIClass clazz) { output("#define "); output(clazz.getSimpleName()); output("_NATIVE(func) Java_"); output(toC(clazz.getName())); outputln("_##func"); outputln(); } boolean generateGetParameter(JNIMethod method, JNIParameter param, boolean critical, int indent) { JNIType paramType = param.getType32(), paramType64 = param.getType64(); if (paramType.isPrimitive() || isSystemClass(paramType)) return false; String iStr = String.valueOf(param.getParameter()); for (int j = 0; j < indent; j++) output("\t"); output("if (arg"); output(iStr); output(") if ((lparg"); output(iStr); output(" = "); if (paramType.isArray()) { JNIType componentType = paramType.getComponentType(); if (componentType.isPrimitive()) { if( "long".equals( componentType.getName() ) && param.isPointer() ) { // This case is special as we may need to do pointer conversions.. // if your on a 32 bit system but are keeping track of the pointers in a 64 bit long output("hawtjni_malloc_pointer_array(env, arg"); output(iStr); output(")"); } else if (critical) { if (isCPP) { output("("); output(componentType.getTypeSignature2(!paramType.equals(paramType64))); output("*)"); output("env->GetPrimitiveArrayCritical(arg"); } else { output("(*env)->GetPrimitiveArrayCritical(env, arg"); } output(iStr); output(", NULL)"); } else { if (isCPP) { output("env->Get"); } else { output("(*env)->Get"); } output(componentType.getTypeSignature1(!paramType.equals(paramType64))); if (isCPP) { output("ArrayElements(arg"); } else { output("ArrayElements(env, arg"); } output(iStr); output(", NULL)"); } } else { throw new Error("not done"); } } else if (paramType.isType("java.lang.String")) { if (param.getFlag(ArgFlag.UNICODE)) { if (isCPP) { output("env->GetStringChars(arg"); } else { output("(*env)->GetStringChars(env, arg"); } output(iStr); output(", NULL)"); } else { if (isCPP) { output("env->GetStringUTFChars(arg"); } else { output("(*env)->GetStringUTFChars(env, arg"); } output(iStr); output(", NULL)"); } } else { if (param.getFlag(ArgFlag.NO_IN)) { output("&_arg"); output(iStr); } else { output("get"); output(paramType.getSimpleName()); output("Fields(env, arg"); output(iStr); output(", &_arg"); output(iStr); output(")"); } } outputln(") == NULL) goto fail;"); return true; } void generateSetParameter(JNIParameter param, boolean critical) { JNIType paramType = param.getType32(), paramType64 = param.getType64(); if (paramType.isPrimitive() || isSystemClass(paramType)) return; String iStr = String.valueOf(param.getParameter()); if (paramType.isArray()) { output("\tif (arg"); output(iStr); output(" && lparg"); output(iStr); output(") "); JNIType componentType = paramType.getComponentType(); if (componentType.isPrimitive()) { if( "long".equals( componentType.getName() ) && param.isPointer() ) { // This case is special as we may need to do pointer conversions.. // if your on a 32 bit system but are keeping track of the pointers in a 64 bit long output("hawtjni_free_pointer_array(env, arg"); output(iStr); } else if (critical) { if (isCPP) { output("env->ReleasePrimitiveArrayCritical(arg"); } else { output("(*env)->ReleasePrimitiveArrayCritical(env, arg"); } output(iStr); } else { if (isCPP) { output("env->Release"); } else { output("(*env)->Release"); } output(componentType.getTypeSignature1(!paramType.equals(paramType64))); if (isCPP) { output("ArrayElements(arg"); } else { output("ArrayElements(env, arg"); } output(iStr); } output(", lparg"); output(iStr); output(", "); if (param.getFlag(ArgFlag.NO_OUT)) { output("JNI_ABORT"); } else { output("0"); } output(");"); } else { throw new Error("not done"); } outputln(); } else if (paramType.isType("java.lang.String")) { output("\tif (arg"); output(iStr); output(" && lparg"); output(iStr); output(") "); if (param.getFlag(ArgFlag.UNICODE)) { if (isCPP) { output("env->ReleaseStringChars(arg"); } else { output("(*env)->ReleaseStringChars(env, arg"); } } else { if (isCPP) { output("env->ReleaseStringUTFChars(arg"); } else { output("(*env)->ReleaseStringUTFChars(env, arg"); } } output(iStr); output(", lparg"); output(iStr); outputln(");"); } else { if (!param.getFlag(ArgFlag.NO_OUT)) { output("\tif (arg"); output(iStr); output(" && lparg"); output(iStr); output(") "); output("set"); output(paramType.getSimpleName()); output("Fields(env, arg"); output(iStr); output(", lparg"); output(iStr); outputln(");"); } } } void generateEnterExitMacro(JNIMethod method, String function, String function64, boolean enter) { if (!enterExitMacro) return; if (!function.equals(function64)) { output("#ifndef "); output(JNI64); outputln(); } output("\t"); output(method.getDeclaringClass().getSimpleName()); output("_NATIVE_"); output(enter ? "ENTER" : "EXIT"); output("(env, that, "); output(method.getDeclaringClass().getSimpleName()+"_"+function); outputln("_FUNC);"); if (!function.equals(function64)) { outputln("#else"); output("\t"); output(method.getDeclaringClass().getSimpleName()); output("_NATIVE_"); output(enter ? "ENTER" : "EXIT"); output("(env, that, "); output(method.getDeclaringClass().getSimpleName()+"_"+function64); outputln("_FUNC);"); outputln("#endif"); } } boolean generateLocalVars(JNIMethod method, List params, JNIType returnType, JNIType returnType64) { boolean needsReturn = enterExitMacro; for (int i = 0; i < params.size(); i++) { JNIParameter param = params.get(i); JNIType paramType = param.getType32(), paramType64 = param.getType64(); if (paramType.isPrimitive() || isSystemClass(paramType)) continue; output("\t"); if (paramType.isArray()) { JNIType componentType = paramType.getComponentType(); if( "long".equals( componentType.getName() ) && param.isPointer() ) { output("void **lparg" + i+"=NULL;"); } else if (componentType.isPrimitive()) { output(componentType.getTypeSignature2(!paramType.equals(paramType64))); output(" *lparg" + i); output("=NULL;"); } else { throw new Error("not done"); } } else if (paramType.isType("java.lang.String")) { if (param.getFlag(ArgFlag.UNICODE)) { output("const jchar *lparg" + i); } else { output("const char *lparg" + i); } output("= NULL;"); } else { if (param.getTypeClass().getFlag(ClassFlag.STRUCT) && !param.getTypeClass().getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(paramType.getSimpleName()); output(" _arg" + i); if (param.getFlag(ArgFlag.INIT)) output("={0}"); output(", *lparg" + i); output("=NULL;"); } outputln(); needsReturn = true; } if (needsReturn) { if (!returnType.isType("void")) { output("\t"); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); outputln(" rc = 0;"); } } return needsReturn; } boolean generateGetters(JNIMethod method, List params) { boolean genFailTag = false; int criticalCount = 0; for (JNIParameter param : params) { if (!isCritical(param)) { genFailTag |= generateGetParameter(method, param, false, 1); } else { criticalCount++; } } if (criticalCount != 0) { outputln("#ifdef JNI_VERSION_1_2"); outputln("\tif (IS_JNI_1_2) {"); for (JNIParameter param : params) { if (isCritical(param)) { genFailTag |= generateGetParameter(method, param, true, 2); } } outputln("\t} else"); outputln("#endif"); outputln("\t{"); for (JNIParameter param : params) { if (isCritical(param)) { genFailTag |= generateGetParameter(method, param, false, 2); } } outputln("\t}"); } return genFailTag; } void generateSetters(JNIMethod method, List params) { int criticalCount = 0; for (int i = params.size() - 1; i >= 0; i--) { JNIParameter param = params.get(i); if (isCritical(param)) { criticalCount++; } } if (criticalCount != 0) { outputln("#ifdef JNI_VERSION_1_2"); outputln("\tif (IS_JNI_1_2) {"); for (int i = params.size() - 1; i >= 0; i--) { JNIParameter param = params.get(i); if (isCritical(param)) { output("\t"); generateSetParameter(param, true); } } outputln("\t} else"); outputln("#endif"); outputln("\t{"); for (int i = params.size() - 1; i >= 0; i--) { JNIParameter param = params.get(i); if (isCritical(param)) { output("\t"); generateSetParameter(param, false); } } outputln("\t}"); } for (int i = params.size() - 1; i >= 0; i--) { JNIParameter param = params.get(i); if (!isCritical(param)) { generateSetParameter(param, false); } } } void generateDynamicFunctionCall(JNIMethod method, List params, JNIType returnType, JNIType returnType64, boolean needsReturn) { outputln("/*"); generateFunctionCall(method, params, returnType, returnType64, needsReturn); outputln("*/"); outputln("\t{"); String name = method.getName(); if (name.startsWith("_")) name = name.substring(1); output("\t\tLOAD_FUNCTION(fp, "); output(name); outputln(")"); outputln("\t\tif (fp) {"); output("\t\t"); generateFunctionCallLeftSide(method, returnType, returnType64, needsReturn); output("(("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(" (CALLING_CONVENTION*)("); for (int i = 0; i < params.size(); i++) { if (i != 0) output(", "); JNIParameter param = params.get(i); String cast = param.getCast(); if( param.isPointer() ) { output("(intptr_t)"); } boolean isStruct = param.getFlag(ArgFlag.BY_VALUE); if (cast.length() > 2) { cast = cast.substring(1, cast.length() - 1); if (isStruct) { int index = cast.lastIndexOf('*'); if (index != -1) cast = cast.substring(0, index).trim(); } output(cast); } else { JNIType paramType = param.getType32(), paramType64 = param.getType64(); output(paramType.getTypeSignature4(!paramType.equals(paramType64), isStruct)); } } output("))"); output("fp"); output(")"); generateFunctionCallRightSide(method, params, 0); output(";"); outputln(); outputln("\t\t}"); outputln("\t}"); } void generateFunctionCallLeftSide(JNIMethod method, JNIType returnType, JNIType returnType64, boolean needsReturn) { output("\t"); if (!returnType.isType("void")) { if (needsReturn) { output("rc = "); } else { output("return "); } String cast = method.getCast(); if (cast != null) { if( method.isPointer() ) { output("(intptr_t)"); } output(cast); } else { output("("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(")"); } } if (method.getFlag(MethodFlag.ADDRESS)) { output("&"); } if (method.getFlag(MethodFlag.JNI)) { output(isCPP ? "env->" : "(*env)->"); } } void generateFunctionCallRightSide(JNIMethod method, List params, int paramStart) { if (!method.getFlag(MethodFlag.CONSTANT_GETTER)) { output("("); if (method.getFlag(MethodFlag.JNI)) { if (!isCPP) output("env, "); } for (int i = paramStart; i < params.size(); i++) { JNIParameter param = params.get(i); if (i != paramStart) output(", "); if (param.getFlag(ArgFlag.BY_VALUE)) output("*"); output(param.getCast()); if( param.isPointer() ) { output("(intptr_t)"); } if (param.getFlag(ArgFlag.CS_OBJECT)) output("TO_OBJECT("); if (i == params.size() - 1 && param.getFlag(ArgFlag.SENTINEL)) { output("NULL"); } else { JNIType paramType = param.getType32(); if (!paramType.isPrimitive() && !isSystemClass(paramType)) output("lp"); output("arg" + i); } if (param.getFlag(ArgFlag.CS_OBJECT)) output(")"); } output(")"); } } void generateFunctionCall(JNIMethod method, List params, JNIType returnType, JNIType returnType64, boolean needsReturn) { String name = method.getName(); String copy = method.getCopy(); boolean makeCopy = copy.length() != 0 && isCPP && !returnType.isType("void"); if (makeCopy) { output("\t"); output(copy); output(" temp = "); } else { generateFunctionCallLeftSide(method, returnType, returnType64, needsReturn); } int paramStart = 0; if (name.startsWith("_")) name = name.substring(1); boolean objc_struct = false; if (name.equals("objc_msgSend_stret") || name.equals("objc_msgSendSuper_stret")) objc_struct = true; if (objc_struct) { outputln("if (sizeof(_arg0) > STRUCT_SIZE_LIMIT) {"); generate_objc_msgSend_stret(method, params, name); paramStart = 1; } else if (name.equalsIgnoreCase("call")) { output("("); JNIParameter param = params.get(0); String cast = param.getCast(); if (cast.length() != 0 && !cast.equals("()")) { output(cast); if( param.isPointer() ) { output("(intptr_t)"); } } else { output("("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(" (*)())"); } output("arg0)"); paramStart = 1; } else if (name.startsWith("VtblCall") || name.startsWith("_VtblCall")) { output("(("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(" (STDMETHODCALLTYPE *)("); for (int i = 1; i < params.size(); i++) { if (i != 1) output(", "); JNIParameter param = params.get(i); JNIType paramType = param.getType32(), paramType64 = param.getType64(); output(paramType.getTypeSignature4(!paramType.equals(paramType64), false)); } output("))(*("); JNIType paramType = params.get(1).getType32(), paramType64 = params.get(1).getType64(); output(paramType.getTypeSignature4(!paramType.equals(paramType64), false)); output(" **)arg1)[arg0])"); paramStart = 1; } else if (method.getFlag(MethodFlag.CPP) || method.getFlag(MethodFlag.SETTER) || method.getFlag(MethodFlag.GETTER) || method.getFlag(MethodFlag.ADDER)) { if (method.getFlag(MethodFlag.CS_OBJECT)) { output("TO_HANDLE("); } output("("); JNIParameter param = params.get(0); if (param.getFlag(ArgFlag.BY_VALUE)) output("*"); String cast = param.getCast(); if (cast.length() != 0 && !cast.equals("()")) { output(cast); if( param.isPointer() ) { output("(intptr_t)"); } } if (param.getFlag(ArgFlag.CS_OBJECT)) { output("TO_OBJECT("); } output("arg0"); if (param.getFlag(ArgFlag.CS_OBJECT)) { output(")"); } output(")->"); String accessor = method.getAccessor(); if (accessor.length() != 0) { output(accessor); } else { int index = -1; if ((index = name.indexOf('_')) != -1) { output(name.substring(index + 1, name.length())); } else { output(name); } } paramStart = 1; } else if (method.getFlag(MethodFlag.CS_NEW)) { output("TO_HANDLE(gcnew "); String accessor = method.getAccessor(); if (accessor.length() != 0) { output(accessor); } else { int index = -1; if ((index = name.indexOf('_')) != -1) { output(name.substring(index + 1)); } else { output(name); } } } else if (method.getFlag(MethodFlag.CPP_NEW)) { if (method.getFlag(MethodFlag.CS_OBJECT)) { output("TO_HANDLE("); } output("new "); String accessor = method.getAccessor(); if (accessor.length() != 0) { output(accessor); } else { int index = -1; if ((index = name.indexOf('_')) != -1) { output(name.substring(0, index)); } else { output(name); } } } else if (method.getFlag(MethodFlag.CPP_DELETE)) { output("delete "); JNIParameter param = params.get(0); String cast = param.getCast(); if (cast.length() != 0 && !cast.equals("()")) { output(cast); if( param.isPointer() ) { output("(intptr_t)"); } } else { output("("); output(name.substring(0, name.indexOf("_"))); output(" *)"); } outputln("arg0;"); return; } else { if (method.getFlag(MethodFlag.CS_OBJECT)) { output("TO_HANDLE("); } if (method.getFlag(MethodFlag.CAST)) { output("(("); String returnCast = returnType.getTypeSignature2(!returnType.equals(returnType64)); if (name.equals("objc_msgSend_bool") && returnCast.equals("jboolean")) { returnCast = "BOOL"; } output(returnCast); output(" (*)("); for (int i = 0; i < params.size(); i++) { if (i != 0) output(", "); JNIParameter param = params.get(i); String cast = param.getCast(); if (cast != null && cast.length() != 0) { if (cast.startsWith("(")) cast = cast.substring(1); if (cast.endsWith(")")) cast = cast.substring(0, cast.length() - 1); output(cast); } else { JNIType paramType = param.getType32(), paramType64 = param.getType64(); if (!(paramType.isPrimitive() || paramType.isArray())) { if (param.getTypeClass().getFlag(ClassFlag.STRUCT) && !param.getTypeClass().getFlag(ClassFlag.TYPEDEF)) { output("struct "); } } output(paramType.getTypeSignature4(!paramType.equals(paramType64), param.getFlag(ArgFlag.BY_VALUE))); } } output("))"); } String accessor = method.getAccessor(); if (accessor.length() != 0) { output(accessor); } else { output(name); } if (method.getFlag(MethodFlag.CAST)) { output(")"); } } if ((method.getFlag(MethodFlag.SETTER) && params.size() == 3) || (method.getFlag(MethodFlag.GETTER) && params.size() == 2)) { output("[arg1]"); paramStart++; } if (method.getFlag(MethodFlag.SETTER)) output(" = "); if (method.getFlag(MethodFlag.ADDER)) output(" += "); if (!method.getFlag(MethodFlag.GETTER)) { generateFunctionCallRightSide(method, params, paramStart); } if (method.getFlag(MethodFlag.CS_NEW) || method.getFlag(MethodFlag.CS_OBJECT)) { output(")"); } output(";"); outputln(); if (makeCopy) { outputln("\t{"); output("\t\t"); output(copy); output("* copy = new "); output(copy); outputln("();"); outputln("\t\t*copy = temp;"); output("\t\trc = "); output("("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(")"); outputln("copy;"); outputln("\t}"); } if (objc_struct) { outputln("\t} else {"); generate_objc_msgSend_stret(method, params, name.substring(0, name.length() - "_stret".length())); generateFunctionCallRightSide(method, params, 1); outputln(";"); outputln("\t}"); } } void generate_objc_msgSend_stret(JNIMethod method, List params, String func) { output("\t\t*lparg0 = (*("); JNIType paramType = params.get(0).getType32(), paramType64 = params.get(0).getType64(); output(paramType.getTypeSignature4(!paramType.equals(paramType64), true)); output(" (*)("); for (int i = 1; i < params.size(); i++) { if (i != 1) output(", "); JNIParameter param = params.get(i); String cast = param.getCast(); if( param.isPointer() ) { output("(intptr_t)"); } if (cast != null && cast.length() != 0) { if (cast.startsWith("(")) cast = cast.substring(1); if (cast.endsWith(")")) cast = cast.substring(0, cast.length() - 1); output(cast); } else { paramType = param.getType32(); paramType64 = param.getType64(); if (!(paramType.isPrimitive() || paramType.isArray())) { if (param.getTypeClass().getFlag(ClassFlag.STRUCT) && !param.getTypeClass().getFlag(ClassFlag.TYPEDEF)) { output("struct "); } } output(paramType.getTypeSignature4(!paramType.equals(paramType64), param.getFlag(ArgFlag.BY_VALUE))); } } output("))"); output(func); output(")"); } void generateReturn(JNIMethod method, JNIType returnType, boolean needsReturn) { if (needsReturn && !returnType.isType("void")) { outputln("\treturn rc;"); } } void generateMemmove(JNIMethod method, String function, String function64, List params) { generateEnterExitMacro(method, function, function64, true); output("\t"); boolean get = params.get(0).getType32().isPrimitive(); String className = params.get(get ? 1 : 0).getType32().getSimpleName(); output(get ? "if (arg1) get" : "if (arg0) set"); output(className); output(get ? "Fields(env, arg1, (" : "Fields(env, arg0, ("); output(className); output(get ? " *)arg0)" : " *)arg1)"); outputln(";"); generateEnterExitMacro(method, function, function64, false); } void generateFunctionBody(JNIMethod method, String function, String function64, List params, JNIType returnType, JNIType returnType64) { outputln("{"); /* Custom GTK memmoves. */ String name = method.getName(); if (name.startsWith("_")) name = name.substring(1); boolean isMemove = (name.equals("memmove") || name.equals("MoveMemory")) && params.size() == 2 && returnType.isType("void"); if (isMemove) { generateMemmove(method, function, function64, params); } else { boolean needsReturn = generateLocalVars(method, params, returnType, returnType64); generateEnterExitMacro(method, function, function64, true); boolean genFailTag = generateGetters(method, params); if (method.getFlag(MethodFlag.DYNAMIC)) { generateDynamicFunctionCall(method, params, returnType, returnType64, needsReturn); } else { generateFunctionCall(method, params, returnType, returnType64, needsReturn); } if (genFailTag) outputln("fail:"); generateSetters(method, params); generateEnterExitMacro(method, function, function64, false); generateReturn(method, returnType, needsReturn); } outputln("}"); } void generateFunctionPrototype(JNIMethod method, String function, List params, JNIType returnType, JNIType returnType64, boolean singleLine) { output("JNIEXPORT "); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(" JNICALL "); output(method.getDeclaringClass().getSimpleName()); output("_NATIVE("); output(function); if (singleLine) { output(")"); output("(JNIEnv *env, "); } else { outputln(")"); output("\t(JNIEnv *env, "); } if ((method.getModifiers() & Modifier.STATIC) != 0) { output("jclass"); } else { output("jobject"); } output(" that"); for (int i = 0; i < params.size(); i++) { output(", "); JNIType paramType = params.get(i).getType32(), paramType64 = params.get(i).getType64(); output(paramType.getTypeSignature2(!paramType.equals(paramType64))); output(" arg" + i); } output(")"); if (!singleLine) outputln(); } boolean isCritical(JNIParameter param) { JNIType paramType = param.getType32(); return paramType.isArray() && paramType.getComponentType().isPrimitive() && param.getFlag(ArgFlag.CRITICAL); } boolean isSystemClass(JNIType type) { return type.isType("java.lang.Object") || type.isType("java.lang.Class"); } } ProgressMonitor.java000077500000000000000000000013301142665006500356400ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2005 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; /** * * @author Hiram Chirino */ public interface ProgressMonitor { public void setTotal(int total); public void setMessage(String message); public void step(); } SizeofGenerator.java000077500000000000000000000045001142665006500355740ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.ReflectClass; /** * * @author Hiram Chirino */ public class SizeofGenerator extends JNIGenerator { public void generate(JNIClass clazz) { String className = clazz.getSimpleName(); output("\tprintf(\""); output(className); output("=%d\\n\", sizeof("); output(className); outputln("));"); } public void generate() { outputln("int main() {"); super.generate(); outputln("}"); } public void generate(List fields) { sortFields(fields); for (JNIField field : fields) { if ((field.getModifiers() & Modifier.FINAL) == 0) continue; generate(field); } } public void generate(JNIField field) { output("\tprintf(\""); output(field.getName()); output("=%d\\n\", sizeof("); output(field.getName()); outputln("));"); } public static void main(String[] args) { if (args.length < 1) { System.out.println("Usage: java SizeofGenerator "); return; } try { SizeofGenerator gen = new SizeofGenerator(); for (int i = 0; i < args.length; i++) { String clazzName = args[i]; Class clazz = Class.forName(clazzName); gen.generate(new ReflectClass(clazz)); } } catch (Exception e) { System.out.println("Problem"); e.printStackTrace(System.out); } } } StatsGenerator.java000077500000000000000000000163261142665006500354440ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIMethod; /** * * @author Hiram Chirino */ public class StatsGenerator extends JNIGenerator { boolean header; public StatsGenerator(boolean header) { this.header = header; } public void generateCopyright() { outputln(fixDelimiter(getCopyright())); } public void generateIncludes() { if (!header) { outputln("#include \"hawtjni.h\""); outputln("#include \""+getOutputName()+"_stats.h\""); outputln(); } } public void generate(JNIClass clazz) { if (header) { generateHeaderFile(clazz); } else { generateSourceFile(clazz); } } void generateHeaderFile(JNIClass clazz) { generateNATIVEMacros(clazz); List methods = clazz.getDeclaredMethods(); sortMethods(methods); generateFunctionEnum(methods); } void generateNATIVEMacros(JNIClass clazz) { String className = clazz.getSimpleName(); outputln("#ifdef NATIVE_STATS"); output("extern int "); output(className); outputln("_nativeFunctionCount;"); output("extern int "); output(className); outputln("_nativeFunctionCallCount[];"); output("extern char* "); output(className); outputln("_nativeFunctionNames[];"); output("#define "); output(className); output("_NATIVE_ENTER(env, that, func) "); output(className); outputln("_nativeFunctionCallCount[func]++;"); output("#define "); output(className); outputln("_NATIVE_EXIT(env, that, func) "); outputln("#else"); output("#ifndef "); output(className); outputln("_NATIVE_ENTER"); output("#define "); output(className); outputln("_NATIVE_ENTER(env, that, func) "); outputln("#endif"); output("#ifndef "); output(className); outputln("_NATIVE_EXIT"); output("#define "); output(className); outputln("_NATIVE_EXIT(env, that, func) "); outputln("#endif"); outputln("#endif"); outputln(); } void generateSourceFile(JNIClass clazz) { outputln("#ifdef NATIVE_STATS"); outputln(); List methods = clazz.getDeclaredMethods(); int methodCount = 0; for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; methodCount++; } String className = clazz.getSimpleName(); output("int "); output(className); output("_nativeFunctionCount = "); output(String.valueOf(methodCount)); outputln(";"); output("int "); output(className); output("_nativeFunctionCallCount["); output(String.valueOf(methodCount)); outputln("];"); output("char * "); output(className); outputln("_nativeFunctionNames[] = {"); sortMethods(methods); for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; String function = getFunctionName(method), function64 = getFunctionName(method, method.getParameterTypes64()); if (!function.equals(function64)) { output("#ifndef "); output(JNI64); outputln(); } output("\t\""); output(function); outputln("\","); if (!function.equals(function64)) { outputln("#else"); output("\t\""); output(function64); outputln("\","); outputln("#endif"); } if (progress != null) progress.step(); } outputln("};"); outputln(); generateStatsNatives(className); outputln(); outputln("#endif"); } void generateStatsNatives(String className) { outputln("#define STATS_NATIVE(func) Java_org_fusesource_hawtjni_runtime_NativeStats_##func"); outputln(); output("JNIEXPORT jint JNICALL STATS_NATIVE("); output(toC(className + "_GetFunctionCount")); outputln(")"); outputln("\t(JNIEnv *env, jclass that)"); outputln("{"); output("\treturn "); output(className); outputln("_nativeFunctionCount;"); outputln("}"); outputln(); output("JNIEXPORT jstring JNICALL STATS_NATIVE("); output(toC(className + "_GetFunctionName")); outputln(")"); outputln("\t(JNIEnv *env, jclass that, jint index)"); outputln("{"); output("\treturn "); if (isCPP) { output("env->NewStringUTF("); } else { output("(*env)->NewStringUTF(env, "); } output(className); outputln("_nativeFunctionNames[index]);"); outputln("}"); outputln(); output("JNIEXPORT jint JNICALL STATS_NATIVE("); output(toC(className + "_GetFunctionCallCount")); outputln(")"); outputln("\t(JNIEnv *env, jclass that, jint index)"); outputln("{"); output("\treturn "); output(className); outputln("_nativeFunctionCallCount[index];"); outputln("}"); } void generateFunctionEnum(List methods) { if (methods.isEmpty()) return; outputln("typedef enum {"); for (JNIMethod method : methods) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; String function = getFunctionName(method), function64 = getFunctionName(method, method.getParameterTypes64()); if (!function.equals(function64)) { output("#ifndef "); output(JNI64); outputln(); } output("\t"); output(method.getDeclaringClass().getSimpleName()+"_"+function); outputln("_FUNC,"); if (!function.equals(function64)) { outputln("#else"); output("\t"); output(method.getDeclaringClass().getSimpleName()+"_"+function64); outputln("_FUNC,"); outputln("#endif"); } if (progress != null) progress.step(); } JNIClass clazz = methods.get(0).getDeclaringClass(); output("} "); output(clazz.getSimpleName()); outputln("_FUNCS;"); } } StructsGenerator.java000077500000000000000000000472131142665006500360140ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2007 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.JNIType; import org.fusesource.hawtjni.runtime.ClassFlag; /** * * @author Hiram Chirino */ public class StructsGenerator extends JNIGenerator { boolean header; static final boolean GLOBAL_REF = false; public StructsGenerator(boolean header) { this.header = header; } public void generateCopyright() { outputln(fixDelimiter(getCopyright())); } public void generateIncludes() { if (header) { outputln("#include \""+getOutputName()+".h\""); } else { outputln("#include \""+getOutputName()+".h\""); outputln("#include \"hawtjni.h\""); outputln("#include \""+getOutputName()+"_structs.h\""); } outputln(); } public void generate(JNIClass clazz) { ArrayList fields = getStructFields(clazz); if (fields.isEmpty()) return; if (header) { generateHeaderFile(clazz); } else { generateSourceFile(clazz); } } private ArrayList getStructFields(JNIClass clazz) { ArrayList rc = new ArrayList(); List fields = clazz.getDeclaredFields(); for (JNIField field : fields) { int mods = field.getModifiers(); if ( (mods & Modifier.STATIC) == 0 && (mods & Modifier.TRANSIENT) == 0) { rc.add(field); } } return rc; } void generateHeaderFile(JNIClass clazz) { generateSourceStart(clazz); generatePrototypes(clazz); generateBlankMacros(clazz); generateSourceEnd(clazz); outputln(); } void generateSourceFile(JNIClass clazz) { generateSourceStart(clazz); generateFIDsStructure(clazz); outputln(); generateGlobalVar(clazz); outputln(); generateFunctions(clazz); generateSourceEnd(clazz); outputln(); } void generateSourceStart(JNIClass clazz) { String conditional = clazz.getConditional(); if (conditional!=null) { outputln("#if "+conditional); } } void generateSourceEnd(JNIClass clazz) { if (clazz.getConditional()!=null) { outputln("#endif"); } } void generateGlobalVar(JNIClass clazz) { String clazzName = clazz.getSimpleName(); output(clazzName); output("_FID_CACHE "); output(clazzName); outputln("Fc;"); } void generateBlankMacros(JNIClass clazz) { if (clazz.getConditional()==null) { return; } String clazzName = clazz.getSimpleName(); outputln("#else"); output("#define cache"); output(clazzName); outputln("Fields(a,b)"); output("#define get"); output(clazzName); outputln("Fields(a,b,c) NULL"); output("#define set"); output(clazzName); outputln("Fields(a,b,c)"); } void generatePrototypes(JNIClass clazz) { String clazzName = clazz.getSimpleName(); output("void cache"); output(clazzName); outputln("Fields(JNIEnv *env, jobject lpObject);"); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); output(" *get"); output(clazzName); output("Fields(JNIEnv *env, jobject lpObject, "); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); outputln(" *lpStruct);"); output("void set"); output(clazzName); output("Fields(JNIEnv *env, jobject lpObject, "); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); outputln(" *lpStruct);"); } void generateFIDsStructure(JNIClass clazz) { String clazzName = clazz.getSimpleName(); output("typedef struct "); output(clazzName); outputln("_FID_CACHE {"); outputln("\tint cached;"); outputln("\tjclass clazz;"); output("\tjfieldID "); List fields = clazz.getDeclaredFields(); boolean first = true; for (JNIField field : fields) { if (ignoreField(field)) continue; if (!first) output(", "); output(field.getName()); first = false; } outputln(";"); output("} "); output(clazzName); outputln("_FID_CACHE;"); } void generateCacheFunction(JNIClass clazz) { String clazzName = clazz.getSimpleName(); output("void cache"); output(clazzName); outputln("Fields(JNIEnv *env, jobject lpObject)"); outputln("{"); output("\tif ("); output(clazzName); outputln("Fc.cached) return;"); JNIClass superclazz = clazz.getSuperclass(); if (!superclazz.getName().equals("java.lang.Object")) { String superName = superclazz.getSimpleName(); output("\tcache"); output(superName); outputln("Fields(env, lpObject);"); } output("\t"); output(clazzName); if (isCPP) { if (GLOBAL_REF) { output("Fc.clazz = (jclass)env->NewGlobalRef(env->GetObjectClass(lpObject));"); } else { output("Fc.clazz = env->GetObjectClass(lpObject);"); } } else { if (GLOBAL_REF) { output("Fc.clazz = (*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, lpObject));"); } else { output("Fc.clazz = (*env)->GetObjectClass(env, lpObject);"); } } outputln(); List fields = clazz.getDeclaredFields(); for (JNIField field : fields) { if (ignoreField(field)) continue; output("\t"); output(clazzName); output("Fc."); output(field.getName()); if (isCPP) { output(" = env->GetFieldID("); } else { output(" = (*env)->GetFieldID(env, "); } output(clazzName); output("Fc.clazz, \""); output(field.getName()); JNIType type = field.getType(), type64 = field.getType64(); output("\", "); if (type.equals(type64)) output("\""); output(type.getTypeSignature(!type.equals(type64))); if (type.equals(type64)) output("\""); outputln(");"); } output("\t"); output(clazzName); outputln("Fc.cached = 1;"); outputln("}"); } void generateGetFields(JNIClass clazz) { JNIClass superclazz = clazz.getSuperclass(); String clazzName = clazz.getSimpleName(); String superName = superclazz.getSimpleName(); if (!superclazz.getName().equals("java.lang.Object")) { /* * Windows exception - cannot call get/set function of super class * in this case */ if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) { output("\tget"); output(superName); output("Fields(env, lpObject, ("); output(superName); outputln(" *)lpStruct);"); } else { generateGetFields(superclazz); } } List fields = clazz.getDeclaredFields(); for (JNIField field : fields) { if (ignoreField(field)) continue; String conditional = field.getConditional(); if (conditional!=null) { outputln("#if "+conditional); } JNIType type = field.getType(), type64 = field.getType64(); String typeName = type.getSimpleName(); String accessor = field.getAccessor(); if (accessor == null || accessor.length() == 0) accessor = field.getName(); if (type.isPrimitive()) { output("\tlpStruct->"); output(accessor); output(" = "); output(field.getCast()); if( field.isPointer() ) { output("(intptr_t)"); } if (isCPP) { output("env->Get"); } else { output("(*env)->Get"); } output(type.getTypeSignature1(!type.equals(type64))); if (isCPP) { output("Field(lpObject, "); } else { output("Field(env, lpObject, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); output(");"); } else if (type.isArray()) { JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType(); if (componentType.isPrimitive()) { outputln("\t{"); output("\t"); output(type.getTypeSignature2(!type.equals(type64))); output(" lpObject1 = ("); output(type.getTypeSignature2(!type.equals(type64))); if (isCPP) { output(")env->GetObjectField(lpObject, "); } else { output(")(*env)->GetObjectField(env, lpObject, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); if (isCPP) { output("\tenv->Get"); } else { output("\t(*env)->Get"); } output(componentType.getTypeSignature1(!componentType.equals(componentType64))); if (isCPP) { output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->"); } else { output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->"); } output(accessor); output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(!type.equals(type64), false)); output(")lpStruct->"); output(accessor); outputln(");"); output("\t}"); } else { throw new Error("not done"); } } else { outputln("\t{"); if (isCPP) { output("\tjobject lpObject1 = env->GetObjectField(lpObject, "); } else { output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); output("\tif (lpObject1 != NULL) get"); output(typeName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor); outputln(");"); output("\t}"); } outputln(); if (conditional!=null) { outputln("#endif"); } } } void generateGetFunction(JNIClass clazz) { String clazzName = clazz.getSimpleName(); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); output(" *get"); output(clazzName); output("Fields(JNIEnv *env, jobject lpObject, "); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); outputln(" *lpStruct)"); outputln("{"); output("\tif (!"); output(clazzName); output("Fc.cached) cache"); output(clazzName); outputln("Fields(env, lpObject);"); if( clazz.getFlag(ClassFlag.ZERO_OUT) ) { outputln("memset(lpStruct, 0, sizeof(struct "+clazzName+"));"); } generateGetFields(clazz); outputln("\treturn lpStruct;"); outputln("}"); } void generateSetFields(JNIClass clazz) { JNIClass superclazz = clazz.getSuperclass(); String clazzName = clazz.getSimpleName(); String superName = superclazz.getSimpleName(); if (!superclazz.getName().equals("java.lang.Object")) { /* * Windows exception - cannot call get/set function of super class * in this case */ if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) { output("\tset"); output(superName); output("Fields(env, lpObject, ("); output(superName); outputln(" *)lpStruct);"); } else { generateSetFields(superclazz); } } List fields = clazz.getDeclaredFields(); for (JNIField field : fields) { if (ignoreField(field)) continue; String conditional = field.getConditional(); if (conditional!=null) { outputln("#if "+conditional); } JNIType type = field.getType(), type64 = field.getType64(); boolean allowConversion = !type.equals(type64); String typeName = type.getSimpleName(); String accessor = field.getAccessor(); if (accessor == null || accessor.length() == 0) accessor = field.getName(); if (type.isPrimitive()) { if (isCPP) { output("\tenv->Set"); } else { output("\t(*env)->Set"); } output(type.getTypeSignature1(allowConversion)); if (isCPP) { output("Field(lpObject, "); } else { output("Field(env, lpObject, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); output(", "); output("("+type.getTypeSignature2(allowConversion)+")"); if( field.isPointer() ) { output("(intptr_t)"); } output("lpStruct->"+accessor); output(");"); } else if (type.isArray()) { JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType(); if (componentType.isPrimitive()) { outputln("\t{"); output("\t"); output(type.getTypeSignature2(allowConversion)); output(" lpObject1 = ("); output(type.getTypeSignature2(allowConversion)); if (isCPP) { output(")env->GetObjectField(lpObject, "); } else { output(")(*env)->GetObjectField(env, lpObject, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); if (isCPP) { output("\tenv->Set"); } else { output("\t(*env)->Set"); } output(componentType.getTypeSignature1(!componentType.equals(componentType64))); if (isCPP) { output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->"); } else { output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->"); } output(accessor); output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(allowConversion, false)); output(")lpStruct->"); output(accessor); outputln(");"); output("\t}"); } else { throw new Error("not done"); } } else { outputln("\t{"); output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, "); output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); output("\tif (lpObject1 != NULL) set"); output(typeName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor); outputln(");"); output("\t}"); } outputln(); if (conditional!=null) { outputln("#endif"); } } } void generateSetFunction(JNIClass clazz) { String clazzName = clazz.getSimpleName(); output("void set"); output(clazzName); output("Fields(JNIEnv *env, jobject lpObject, "); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); outputln(" *lpStruct)"); outputln("{"); output("\tif (!"); output(clazzName); output("Fc.cached) cache"); output(clazzName); outputln("Fields(env, lpObject);"); generateSetFields(clazz); outputln("}"); } void generateFunctions(JNIClass clazz) { generateCacheFunction(clazz); outputln(); generateGetFunction(clazz); outputln(); generateSetFunction(clazz); } boolean ignoreField(JNIField field) { int mods = field.getModifiers(); return ((mods & Modifier.PUBLIC) == 0) || ((mods & Modifier.FINAL) != 0) || ((mods & Modifier.STATIC) != 0); } } hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/000077500000000000000000000000001142665006500330005ustar00rootroot00000000000000JNIClass.java000077500000000000000000000021301142665006500351710ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.util.List; import org.fusesource.hawtjni.runtime.ClassFlag; /** * * @author Hiram Chirino */ public interface JNIClass { public boolean getFlag(ClassFlag flag); public String getName(); public String getSimpleName(); public JNIClass getSuperclass(); public List getDeclaredFields(); public List getDeclaredMethods(); public List getNativeMethods(); public boolean getGenerate(); public String getConditional(); } JNIField.java000077500000000000000000000020471142665006500351560ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import org.fusesource.hawtjni.runtime.FieldFlag; /** * * @author Hiram Chirino */ public interface JNIField { public boolean getFlag(FieldFlag flag); public String getName(); public int getModifiers(); public JNIType getType(); public JNIType getType64(); public JNIClass getDeclaringClass(); public String getAccessor(); public String getCast(); public String getConditional(); public boolean isPointer(); } JNIMethod.java000077500000000000000000000026601142665006500353540ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.util.List; import org.fusesource.hawtjni.runtime.ArgFlag; import org.fusesource.hawtjni.runtime.MethodFlag; /** * * @author Hiram Chirino */ public interface JNIMethod { public boolean getFlag(MethodFlag flag); public String getName(); public int getModifiers(); public boolean isNativeUnique(); public JNIType getReturnType32(); public JNIType getReturnType64(); public List getParameters(); public List getParameterTypes(); public List getParameterTypes64(); public JNIClass getDeclaringClass(); public String getAccessor(); public String getConditional(); public String getCopy(); public String[] getCallbackTypes(); public ArgFlag[][] getCallbackFlags(); public String getCast(); public boolean isPointer(); } JNIParameter.java000077500000000000000000000017421142665006500360540ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import org.fusesource.hawtjni.runtime.ArgFlag; /** * * @author Hiram Chirino */ public interface JNIParameter { public boolean getFlag(ArgFlag flag); public String getCast(); public boolean isPointer(); public JNIMethod getMethod(); public int getParameter(); public JNIClass getTypeClass(); public JNIType getType32(); public JNIType getType64(); } JNIType.java000077500000000000000000000022071142665006500350520ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; /** * * @author Hiram Chirino */ public interface JNIType { public boolean isPrimitive(); public boolean isArray(); public JNIType getComponentType(); public boolean isType(String type); public String getName(); public String getSimpleName(); public String getTypeSignature(boolean define); public String getTypeSignature1(boolean define); public String getTypeSignature2(boolean define); public String getTypeSignature3(boolean define); public String getTypeSignature4(boolean define, boolean struct); } ReflectClass.java000077500000000000000000000100551142665006500361420ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.fusesource.hawtjni.runtime.ClassFlag; import org.fusesource.hawtjni.runtime.JniClass; /** * * @author Hiram Chirino */ public class ReflectClass implements JNIClass { private Class clazz; private ArrayList fields; private ArrayList methods; private JniClass annotation; private HashSet flags; public ReflectClass(Class clazz) { this.clazz = clazz; } public String toString() { return clazz.toString(); } public int hashCode() { return clazz.hashCode(); } public boolean equals(Object obj) { if (!(obj instanceof ReflectClass)) return false; return ((ReflectClass) obj).clazz.equals(clazz); } public Class getWrapedClass() { return clazz; } /////////////////////////////////////////////////////////////////// // JNIClass interface methods /////////////////////////////////////////////////////////////////// public String getName() { return clazz.getName(); } public JNIClass getSuperclass() { return new ReflectClass(clazz.getSuperclass()); } public String getSimpleName() { return clazz.getSimpleName(); } public List getDeclaredFields() { lazyLoad(); return new ArrayList(fields); } public List getDeclaredMethods() { lazyLoad(); return new ArrayList(methods); } public List getNativeMethods() { ArrayList rc = new ArrayList(); for (JNIMethod method : getDeclaredMethods()) { if ((method.getModifiers() & Modifier.NATIVE) == 0) continue; rc.add(method); } return rc; } public String getConditional() { lazyLoad(); return annotation == null ? null : emptyFilter(annotation.conditional()); } public boolean getGenerate() { return !getFlag(ClassFlag.CLASS_SKIP); } public boolean getFlag(ClassFlag flag) { lazyLoad(); return flags.contains(flag); } /////////////////////////////////////////////////////////////////// // Helper methods /////////////////////////////////////////////////////////////////// static public String emptyFilter(String value) { if( value==null || value.length()==0 ) return null; return value; } private void lazyLoad() { if (fields != null) return; this.annotation = this.clazz.getAnnotation(JniClass.class); this.flags = new HashSet(); if( this.annotation!=null ) { this.flags.addAll(Arrays.asList(this.annotation.flags())); } Field[] fields = clazz.getDeclaredFields(); this.fields = new ArrayList(fields.length); for (Field field : fields) { this.fields.add(new ReflectField(this, field)); } Method[] methods = clazz.getDeclaredMethods(); this.methods = new ArrayList(methods.length); for (int i = 0; i < methods.length; i++) { this.methods.add(new ReflectMethod(this, methods[i])); } } } ReflectField.java000077500000000000000000000076711142665006500361320ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashSet; import org.fusesource.hawtjni.runtime.FieldFlag; import org.fusesource.hawtjni.runtime.JniField; import org.fusesource.hawtjni.runtime.T32; import static org.fusesource.hawtjni.generator.util.TextSupport.*; import static org.fusesource.hawtjni.runtime.FieldFlag.*; /** * * @author Hiram Chirino */ public class ReflectField implements JNIField { private ReflectClass parent; private Field field; private ReflectType type; private JniField annotation; private HashSet flags; private boolean allowConversion; public ReflectField(ReflectClass parent, Field field) { this.parent = parent; this.field = field; lazyLoad(); } public int hashCode() { return field.hashCode(); } public boolean equals(Object obj) { if (!(obj instanceof ReflectField)) return false; return ((ReflectField) obj).field.equals(field); } public String toString() { return field.toString(); } /////////////////////////////////////////////////////////////////// // JNIField interface methods /////////////////////////////////////////////////////////////////// public JNIClass getDeclaringClass() { return parent; } public int getModifiers() { return field.getModifiers(); } public String getName() { return field.getName(); } public JNIType getType() { return type.asType32(allowConversion); } public JNIType getType64() { return type.asType64(allowConversion); } public String getAccessor() { return annotation == null ? "" : annotation.accessor(); } public String getCast() { String rc = annotation == null ? "" : annotation.cast().trim(); return cast(rc); } public boolean isPointer() { if( annotation == null ) { return false; } return getFlag(POINTER_FIELD) || ( type.getWrappedClass() == Long.TYPE && getCast().endsWith("*)") ); } public String getConditional() { String parentConditional = getDeclaringClass().getConditional(); String myConditional = annotation == null ? null : emptyFilter(annotation.conditional()); if( parentConditional!=null ) { if( myConditional!=null ) { return parentConditional+" && "+myConditional; } else { return parentConditional; } } return myConditional; } public boolean getFlag(FieldFlag flag) { return flags.contains(flag); } /////////////////////////////////////////////////////////////////// // Helper methods /////////////////////////////////////////////////////////////////// static public String emptyFilter(String value) { if( value==null || value.length()==0 ) return null; return value; } private void lazyLoad() { this.type = new ReflectType(field.getType()); this.annotation = this.field.getAnnotation(JniField.class); this.flags = new HashSet(); if( this.annotation!=null ) { this.flags.addAll(Arrays.asList(this.annotation.flags())); } allowConversion = this.field.getAnnotation(T32.class)!=null; } } ReflectMethod.java000077500000000000000000000161571142665006500363260ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.fusesource.hawtjni.runtime.ArgFlag; import org.fusesource.hawtjni.runtime.JniArg; import org.fusesource.hawtjni.runtime.JniMethod; import org.fusesource.hawtjni.runtime.MethodFlag; import org.fusesource.hawtjni.runtime.T32; import static org.fusesource.hawtjni.generator.util.TextSupport.*; import static org.fusesource.hawtjni.runtime.MethodFlag.*; /** * * @author Hiram Chirino */ public class ReflectMethod implements JNIMethod { private ReflectClass declaringClass; private Method method; private List paramTypes32; private List paramTypes64; private List parameters; private boolean unique; private JniMethod annotation; private boolean allowConversion; private ReflectType returnType; private HashSet flags; public ReflectMethod(ReflectClass declaringClass, Method method) { this.declaringClass = declaringClass; this.method = method; lazyLoad(); } public int hashCode() { return method.hashCode(); } public boolean equals(Object obj) { if (!(obj instanceof ReflectMethod)) return false; return ((ReflectMethod) obj).method.equals(method); } public String toString() { return method.toString(); } public Method getWrapedMethod() { return method; } /////////////////////////////////////////////////////////////////// // JNIMethod interface methods /////////////////////////////////////////////////////////////////// public JNIClass getDeclaringClass() { return declaringClass; } public int getModifiers() { return method.getModifiers(); } public String getName() { return method.getName(); } public List getParameters() { lazyLoad(); return parameters; } public List getParameterTypes() { lazyLoad(); return paramTypes32; } public List getParameterTypes64() { lazyLoad(); return paramTypes64; } public JNIType getReturnType32() { lazyLoad(); return returnType.asType32(allowConversion); } public JNIType getReturnType64() { lazyLoad(); return returnType.asType64(allowConversion); } public boolean getFlag(MethodFlag flag) { lazyLoad(); return flags.contains(flag); } public String getCast() { lazyLoad(); String rc = annotation == null ? "" : annotation.cast(); return cast(rc); } public boolean isPointer() { lazyLoad(); if( annotation == null ) { return false; } return getFlag(POINTER_RETURN) || ( returnType.getWrappedClass() == Long.TYPE && getCast().endsWith("*)") ); } public String getCopy() { lazyLoad(); return annotation == null ? "" : annotation.copy(); } public String getAccessor() { lazyLoad(); return annotation == null ? "" : annotation.accessor(); } public String getConditional() { lazyLoad(); String parentConditional = getDeclaringClass().getConditional(); String myConditional = annotation == null ? null : emptyFilter(annotation.conditional()); if( parentConditional!=null ) { if( myConditional!=null ) { return parentConditional+" && "+myConditional; } else { return parentConditional; } } return myConditional; } public boolean isNativeUnique() { lazyLoad(); return unique; } public String[] getCallbackTypes() { lazyLoad(); if( annotation==null ) { return new String[0]; } JniArg[] callbackArgs = annotation.callbackArgs(); String[] rc = new String[callbackArgs.length]; for (int i = 0; i < rc.length; i++) { rc[i] = callbackArgs[i].cast(); } return rc; } public ArgFlag[][] getCallbackFlags() { lazyLoad(); if( annotation==null ) { return new ArgFlag[0][]; } JniArg[] callbackArgs = annotation.callbackArgs(); ArgFlag[][] rc = new ArgFlag[callbackArgs.length][]; for (int i = 0; i < rc.length; i++) { rc[i] = callbackArgs[i].flags(); } return rc; } /////////////////////////////////////////////////////////////////// // Helper methods /////////////////////////////////////////////////////////////////// static public String emptyFilter(String value) { if( value==null || value.length()==0 ) return null; return value; } private void lazyLoad() { if( flags!=null ) { return; } this.annotation = this.method.getAnnotation(JniMethod.class); this.allowConversion = method.getAnnotation(T32.class)!=null; this.flags = new HashSet(); if( this.annotation!=null ) { this.flags.addAll(Arrays.asList(this.annotation.flags())); } Class returnType = method.getReturnType(); Class[] paramTypes = method.getParameterTypes(); this.paramTypes32 = new ArrayList(paramTypes.length); this.paramTypes64 = new ArrayList(paramTypes.length); this.parameters = new ArrayList(paramTypes.length); this.returnType = new ReflectType(returnType); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (int i = 0; i < paramTypes.length; i++) { ReflectParameter parameter = new ReflectParameter(this, i, parameterAnnotations[i]); this.parameters.add(parameter); this.paramTypes32.add( parameter.getType32() ); this.paramTypes64.add( parameter.getType64() ); } unique = true; Class parent = ((ReflectClass)declaringClass).getWrapedClass(); String name = method.getName(); for (Method mth : parent.getDeclaredMethods() ) { if ( (mth.getModifiers()&Modifier.NATIVE) != 0 && method!=mth && !method.equals(mth) && name.equals(mth.getName())) { unique = false; break; } } } } ReflectParameter.java000077500000000000000000000055041142665006500370200ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import org.fusesource.hawtjni.runtime.ArgFlag; import org.fusesource.hawtjni.runtime.JniArg; import org.fusesource.hawtjni.runtime.T32; import static org.fusesource.hawtjni.generator.util.TextSupport.*; import static org.fusesource.hawtjni.runtime.ArgFlag.*; /** * * @author Hiram Chirino */ public class ReflectParameter implements JNIParameter { private ReflectMethod method; private ReflectType type; private int parameter; private JniArg annotation; private boolean allowConversion; private HashSet flags; public ReflectParameter(ReflectMethod method, int parameter, Annotation[] annotations) { this.method = method; this.parameter = parameter; this.type = new ReflectType(method.getWrapedMethod().getParameterTypes()[parameter]); this.flags = new HashSet(); if( annotations!=null ) { for (Annotation annotation : annotations) { if( annotation instanceof JniArg ) { this.annotation = (JniArg) annotation; this.flags.addAll(Arrays.asList(this.annotation.flags())); } else if( annotation instanceof T32 ) { this.allowConversion = true; } } } } public String getCast() { String rc = annotation == null ? "" : annotation.cast(); return cast(rc); } public boolean isPointer() { if( annotation == null ) { return false; } return getFlag(POINTER_ARG) || ( type.getWrappedClass() == Long.TYPE && getCast().endsWith("*)") ); } public JNIMethod getMethod() { return method; } public boolean getFlag(ArgFlag flag) { return flags.contains(flag); } public JNIType getType32() { return type.asType32(allowConversion); } public JNIType getType64() { return type.asType64(allowConversion); } public JNIClass getTypeClass() { ReflectType type = (ReflectType) getType32(); return new ReflectClass(type.getWrappedClass()); } public int getParameter() { return parameter; } } ReflectType.java000077500000000000000000000162301142665006500360170ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.model; /** * * @author Hiram Chirino */ public class ReflectType implements JNIType { private Class clazz; public ReflectType(Class clazz) { this.clazz = clazz; } public int hashCode() { return clazz.hashCode(); } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof ReflectType)) return false; return ((ReflectType) obj).clazz == clazz; } public Class getWrappedClass() { return clazz; } public ReflectType asType32(boolean allowConversion) { if (allowConversion) { if (clazz == long.class) return new ReflectType(int.class); else if (clazz == long[].class) return new ReflectType(int[].class); else if (clazz == double.class) return new ReflectType(float.class); else if (clazz == double[].class) return new ReflectType(float[].class); } return this; } public ReflectType asType64(boolean allowConversion) { if (allowConversion) { if (clazz == int.class) return new ReflectType(long.class); else if (clazz == int[].class) return new ReflectType(long[].class); else if (clazz == float.class) return new ReflectType(double.class); else if (clazz == float[].class) return new ReflectType(double[].class); } return this; } public JNIType getComponentType() { return new ReflectType(clazz.getComponentType()); } public String getName() { return clazz.getName(); } public String getSimpleName() { return clazz.getSimpleName(); } public String getTypeSignature(boolean define) { if (clazz == Void.TYPE) return "V"; if (clazz == Integer.TYPE) return define ? "I_J" : "I"; if (clazz == Boolean.TYPE) return "Z"; if (clazz == Long.TYPE) return define ? "J_J" : "J"; if (clazz == Short.TYPE) return "S"; if (clazz == Character.TYPE) return "C"; if (clazz == Byte.TYPE) return "B"; if (clazz == Float.TYPE) return define ? "F_D" : "F"; if (clazz == Double.TYPE) return define ? "F_D" : "D"; if (clazz == String.class) return "Ljava/lang/String;"; if (clazz.isArray()) { if (define) return getComponentType().getTypeSignature(define) + "Array"; return "[" + getComponentType().getTypeSignature(define); } return "L" + clazz.getName().replace('.', '/') + ";"; } public String getTypeSignature1(boolean define) { if (clazz == Void.TYPE) return "Void"; if (clazz == Integer.TYPE) return define ? "IntLong" : "Int"; if (clazz == Boolean.TYPE) return "Boolean"; if (clazz == Long.TYPE) return define ? "IntLong" : "Long"; if (clazz == Short.TYPE) return "Short"; if (clazz == Character.TYPE) return "Char"; if (clazz == Byte.TYPE) return "Byte"; if (clazz == Float.TYPE) return define ? "FloatDouble" : "Float"; if (clazz == Double.TYPE) return define ? "FloatDouble" : "Double"; if (clazz == String.class) return "String"; return "Object"; } public String getTypeSignature2(boolean define) { if (clazz == Void.TYPE) return "void"; if (clazz == Integer.TYPE) return define ? "jintLong" : "jint"; if (clazz == Boolean.TYPE) return "jboolean"; if (clazz == Long.TYPE) return define ? "jintLong" : "jlong"; if (clazz == Short.TYPE) return "jshort"; if (clazz == Character.TYPE) return "jchar"; if (clazz == Byte.TYPE) return "jbyte"; if (clazz == Float.TYPE) return define ? "jfloatDouble" : "jfloat"; if (clazz == Double.TYPE) return define ? "jfloatDouble" : "jdouble"; if (clazz == String.class) return "jstring"; if (clazz == Class.class) return "jclass"; if (clazz.isArray()) { return getComponentType().getTypeSignature2(define) + "Array"; } return "jobject"; } public String getTypeSignature3(boolean define) { if (clazz == Void.TYPE) return "void"; if (clazz == Integer.TYPE) return "int"; if (clazz == Boolean.TYPE) return "boolean"; if (clazz == Long.TYPE) return "long"; if (clazz == Short.TYPE) return "short"; if (clazz == Character.TYPE) return "char"; if (clazz == Byte.TYPE) return "byte"; if (clazz == Float.TYPE) return "float"; if (clazz == Double.TYPE) return "double"; if (clazz == String.class) return "String"; if (clazz.isArray()) { return getComponentType().getTypeSignature3(define) + "[]"; } return clazz.getName(); } public String getTypeSignature4(boolean define, boolean struct) { if (clazz == Void.TYPE) return "void"; if (clazz == Integer.TYPE) return define ? "jintLong" : "jint"; if (clazz == Boolean.TYPE) return "jboolean"; if (clazz == Long.TYPE) return define ? "jintLong" : "jlong"; if (clazz == Short.TYPE) return "jshort"; if (clazz == Character.TYPE) return "jchar"; if (clazz == Byte.TYPE) return "jbyte"; if (clazz == Float.TYPE) return define ? "jfloatDouble" : "jfloat"; if (clazz == Double.TYPE) return define ? "jfloatDouble" : "jdouble"; if (clazz == String.class) return "jstring"; if (clazz.isArray()) { String sig = getComponentType().getTypeSignature4(define, struct); return struct ? sig : sig + " *"; } String sig = getSimpleName(); return struct ? sig : sig + " *"; } public boolean isArray() { return clazz.isArray(); } public boolean isPrimitive() { return clazz.isPrimitive(); } public boolean isType(String type) { return clazz.getName().equals(type); } } hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/000077500000000000000000000000001142665006500326555ustar00rootroot00000000000000FileSupport.java000066400000000000000000000052701142665006500357210ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.util; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * * @author Hiram Chirino */ public class FileSupport { public static boolean write(byte[] bytes, File file) throws IOException { if( !equals(bytes, file) ) { FileOutputStream out = new FileOutputStream(file); try { out.write(bytes); } finally { out.close(); } return true; } return false; } public static void copy(InputStream is, OutputStream os) throws IOException { try { byte data[] = new byte[1024*4]; int count; while( (count=is.read(data, 0, data.length))>=0 ) { os.write(data, 0, count); } } finally { close(is); close(os); } } public static boolean equals(byte[] bytes, File file) throws IOException { FileInputStream is = null; try { is = new FileInputStream(file); return equals(new ByteArrayInputStream(bytes), new BufferedInputStream(is)); } catch (FileNotFoundException e) { return false; } finally { close(is); } } public static void close(InputStream is) { try { if (is != null) is.close(); } catch (Throwable e) { } } public static void close(OutputStream ioss) { try { if (ioss != null) ioss.close(); } catch (Throwable e) { } } public static boolean equals(InputStream is1, InputStream is2) throws IOException { while (true) { int c1 = is1.read(); int c2 = is2.read(); if (c1 != c2) return false; if (c1 == -1) break; } return true; } } OptionBuilder.java000066400000000000000000000047241142665006500362270ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.util; import org.apache.commons.cli.Option; /** * a better version of org.apache.commons.cli.OptionBuilder * IDE provides nicer auto complete and less compiler warnings. * * @author Hiram Chirino */ public class OptionBuilder { private String id; private String name; private String description; private boolean required; private boolean optional; private int args =-1; private String arg; private Object type; private char sperator; public static OptionBuilder ob() { return new OptionBuilder(); } public Option op() { Option option = new Option( id!=null ? id : " ", description ); option.setLongOpt(name); option.setRequired( required ); option.setOptionalArg(optional); option.setType( type ); option.setValueSeparator(sperator); if( arg !=null && args==-1 ) { args=1; } option.setArgs(args); option.setArgName(arg); return option; } public OptionBuilder arg(String argName) { this.arg = argName; return this; } public OptionBuilder args(int args) { this.args = args; return this; } public OptionBuilder description(String description) { this.description = description; return this; } public OptionBuilder name(String lname) { this.name = lname; return this; } public OptionBuilder id(String name) { this.id = name; return this; } public OptionBuilder optional(boolean optional) { this.optional = optional; return this; } public OptionBuilder required(boolean required) { this.required = required; return this; } public OptionBuilder sperator(char sperator) { this.sperator = sperator; return this; } public OptionBuilder type(Object type) { this.type = type; return this; } }TextSupport.java000066400000000000000000000016201142665006500357610ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.fusesource.hawtjni.generator.util; /** * * @author Hiram Chirino */ public class TextSupport { static public String cast(String cast) { cast = cast.trim(); if (cast.length() > 0) { if (!cast.startsWith("(")) cast = "(" + cast; if (!cast.endsWith(")")) cast = cast + ")"; } return cast; } } hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/000077500000000000000000000000001142665006500243655ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/hawtjni-callback.c000077500000000000000000000537251142665006500277460ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ /* == HEADER-SNIP-LOCATION == */ #include "hawtjni.h" #include #include /* define this to print out debug statements */ /* #define DEBUG_CALL_PRINTS */ /* --------------- callback globals ----------------- */ #if defined (_WIN32) || defined (_WIN32_WCE) #include "windows.h" #define RETURN_TYPE LRESULT CALLBACK #define RETURN_CAST (LRESULT) #endif #ifndef RETURN_TYPE #define RETURN_TYPE jintLong #endif #ifndef RETURN_CAST #define RETURN_CAST #endif /* * Note that only x86 assembler is supported */ #if !(defined(__i386__) || defined(_M_IX86) || defined(_X86_)) #undef USE_ASSEMBLER #endif #ifdef REDUCED_CALLBACKS #define MAX_CALLBACKS 16 #else #ifdef USE_ASSEMBLER #define MAX_CALLBACKS 256 #else #define MAX_CALLBACKS 128 #endif #endif /* REDUCED_CALLBACKS */ #define MAX_ARGS 12 typedef struct CALLBACK_DATA { jobject callback; jmethodID methodID; jobject object; jboolean isStatic; jboolean isArrayBased; jint argCount; jintLong errorResult; } CALLBACK_DATA; static JavaVM *jvm = NULL; static CALLBACK_DATA callbackData[MAX_CALLBACKS]; static int callbackEnabled = 1; static int callbackEntryCount = 0; static int initialized = 0; static jint JNI_VERSION = 0; #ifdef DEBUG_CALL_PRINTS static int counter = 0; #endif #ifdef ATOMIC #include #define ATOMIC_INC(value) OSAtomicIncrement32(&value); #define ATOMIC_DEC(value) OSAtomicDecrement32(&value); #else #define ATOMIC_INC(value) value++; #define ATOMIC_DEC(value) value--; #endif jintLong callback(int index, ...); #ifdef USE_ASSEMBLER #if !(defined (_WIN32) || defined (_WIN32_WCE)) #include #endif static unsigned char *callbackCode = NULL; #define CALLBACK_THUNK_SIZE 64 #else /* ------------- Start: class Callback impl --------------- */ /* Function name from index and number of arguments */ #define FN(index, args) fn##index##_##args /** * Functions templates * * NOTE: If the maximum number of arguments changes (MAX_ARGS), the number * of function templates has to change accordingly. */ /* Function template with no arguments */ #define FN_0(index) RETURN_TYPE FN(index, 0)() { return RETURN_CAST callback(index); } /* Function template with 1 argument */ #define FN_1(index) RETURN_TYPE FN(index, 1)(jintLong p1) { return RETURN_CAST callback(index, p1); } /* Function template with 2 arguments */ #define FN_2(index) RETURN_TYPE FN(index, 2)(jintLong p1, jintLong p2) { return RETURN_CAST callback(index, p1, p2); } /* Function template with 3 arguments */ #define FN_3(index) RETURN_TYPE FN(index, 3)(jintLong p1, jintLong p2, jintLong p3) { return RETURN_CAST callback(index, p1, p2, p3); } /* Function template with 4 arguments */ #define FN_4(index) RETURN_TYPE FN(index, 4)(jintLong p1, jintLong p2, jintLong p3, jintLong p4) { return RETURN_CAST callback(index, p1, p2, p3, p4); } /* Function template with 5 arguments */ #define FN_5(index) RETURN_TYPE FN(index, 5)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5); } /* Function template with 6 arguments */ #define FN_6(index) RETURN_TYPE FN(index, 6)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6); } /* Function template with 7 arguments */ #define FN_7(index) RETURN_TYPE FN(index, 7)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7); } /* Function template with 8 arguments */ #define FN_8(index) RETURN_TYPE FN(index, 8)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8); } /* Function template with 9 arguments */ #define FN_9(index) RETURN_TYPE FN(index, 9)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9); } /* Function template with 10 arguments */ #define FN_10(index) RETURN_TYPE FN(index, 10) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } /* Function template with 11 arguments */ #define FN_11(index) RETURN_TYPE FN(index, 11) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10, jintLong p11) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } /* Function template with 12 arguments */ #define FN_12(index) RETURN_TYPE FN(index, 12) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10, jintLong p11, jintLong p12) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } /** * Define all functions with the specified number of arguments. * * NOTE: If the maximum number of callbacks changes (MAX_CALLBACKS), * this macro has to be updated. */ #if MAX_CALLBACKS == 16 #define FN_BLOCK(args) \ FN_##args(0) \ FN_##args(1) \ FN_##args(2) \ FN_##args(3) \ FN_##args(4) \ FN_##args(5) \ FN_##args(6) \ FN_##args(7) \ FN_##args(8) \ FN_##args(9) \ FN_##args(10) \ FN_##args(11) \ FN_##args(12) \ FN_##args(13) \ FN_##args(14) \ FN_##args(15) #elif MAX_CALLBACKS == 128 #define FN_BLOCK(args) \ FN_##args(0) \ FN_##args(1) \ FN_##args(2) \ FN_##args(3) \ FN_##args(4) \ FN_##args(5) \ FN_##args(6) \ FN_##args(7) \ FN_##args(8) \ FN_##args(9) \ FN_##args(10) \ FN_##args(11) \ FN_##args(12) \ FN_##args(13) \ FN_##args(14) \ FN_##args(15) \ FN_##args(16) \ FN_##args(17) \ FN_##args(18) \ FN_##args(19) \ FN_##args(20) \ FN_##args(21) \ FN_##args(22) \ FN_##args(23) \ FN_##args(24) \ FN_##args(25) \ FN_##args(26) \ FN_##args(27) \ FN_##args(28) \ FN_##args(29) \ FN_##args(30) \ FN_##args(31) \ FN_##args(32) \ FN_##args(33) \ FN_##args(34) \ FN_##args(35) \ FN_##args(36) \ FN_##args(37) \ FN_##args(38) \ FN_##args(39) \ FN_##args(40) \ FN_##args(41) \ FN_##args(42) \ FN_##args(43) \ FN_##args(44) \ FN_##args(45) \ FN_##args(46) \ FN_##args(47) \ FN_##args(48) \ FN_##args(49) \ FN_##args(50) \ FN_##args(51) \ FN_##args(52) \ FN_##args(53) \ FN_##args(54) \ FN_##args(55) \ FN_##args(56) \ FN_##args(57) \ FN_##args(58) \ FN_##args(59) \ FN_##args(60) \ FN_##args(61) \ FN_##args(62) \ FN_##args(63) \ FN_##args(64) \ FN_##args(65) \ FN_##args(66) \ FN_##args(67) \ FN_##args(68) \ FN_##args(69) \ FN_##args(70) \ FN_##args(71) \ FN_##args(72) \ FN_##args(73) \ FN_##args(74) \ FN_##args(75) \ FN_##args(76) \ FN_##args(77) \ FN_##args(78) \ FN_##args(79) \ FN_##args(80) \ FN_##args(81) \ FN_##args(82) \ FN_##args(83) \ FN_##args(84) \ FN_##args(85) \ FN_##args(86) \ FN_##args(87) \ FN_##args(88) \ FN_##args(89) \ FN_##args(90) \ FN_##args(91) \ FN_##args(92) \ FN_##args(93) \ FN_##args(94) \ FN_##args(95) \ FN_##args(96) \ FN_##args(97) \ FN_##args(98) \ FN_##args(99) \ FN_##args(100) \ FN_##args(101) \ FN_##args(102) \ FN_##args(103) \ FN_##args(104) \ FN_##args(105) \ FN_##args(106) \ FN_##args(107) \ FN_##args(108) \ FN_##args(109) \ FN_##args(110) \ FN_##args(111) \ FN_##args(112) \ FN_##args(113) \ FN_##args(114) \ FN_##args(115) \ FN_##args(116) \ FN_##args(117) \ FN_##args(118) \ FN_##args(119) \ FN_##args(120) \ FN_##args(121) \ FN_##args(122) \ FN_##args(123) \ FN_##args(124) \ FN_##args(125) \ FN_##args(126) \ FN_##args(127) #else #error Invalid MAX_CALLBACKS #endif /* MAX_CALLBACKS == 16 */ /** * Define all callback functions. * * NOTE: If the maximum number of arguments changes (MAX_ARGS), the following * has to change accordinglly. */ FN_BLOCK(0) FN_BLOCK(1) FN_BLOCK(2) FN_BLOCK(3) FN_BLOCK(4) FN_BLOCK(5) FN_BLOCK(6) FN_BLOCK(7) FN_BLOCK(8) FN_BLOCK(9) FN_BLOCK(10) FN_BLOCK(11) FN_BLOCK(12) /** * Initialize the function pointers for the callback routines. * * NOTE: If MAX_ARGS or MAX_CALLBACKS changes, the following has to be updated. */ #if MAX_CALLBACKS == 16 #define FN_A_BLOCK(args) { \ (jintLong)FN(0, args), \ (jintLong)FN(1, args), \ (jintLong)FN(2, args), \ (jintLong)FN(3, args), \ (jintLong)FN(4, args), \ (jintLong)FN(5, args), \ (jintLong)FN(6, args), \ (jintLong)FN(7, args), \ (jintLong)FN(8, args), \ (jintLong)FN(9, args), \ (jintLong)FN(10, args), \ (jintLong)FN(11, args), \ (jintLong)FN(12, args), \ (jintLong)FN(13, args), \ (jintLong)FN(14, args), \ (jintLong)FN(15, args), \ }, #elif MAX_CALLBACKS == 128 #define FN_A_BLOCK(args) { \ (jintLong)FN(0, args), \ (jintLong)FN(1, args), \ (jintLong)FN(2, args), \ (jintLong)FN(3, args), \ (jintLong)FN(4, args), \ (jintLong)FN(5, args), \ (jintLong)FN(6, args), \ (jintLong)FN(7, args), \ (jintLong)FN(8, args), \ (jintLong)FN(9, args), \ (jintLong)FN(10, args), \ (jintLong)FN(11, args), \ (jintLong)FN(12, args), \ (jintLong)FN(13, args), \ (jintLong)FN(14, args), \ (jintLong)FN(15, args), \ (jintLong)FN(16, args), \ (jintLong)FN(17, args), \ (jintLong)FN(18, args), \ (jintLong)FN(19, args), \ (jintLong)FN(20, args), \ (jintLong)FN(21, args), \ (jintLong)FN(22, args), \ (jintLong)FN(23, args), \ (jintLong)FN(24, args), \ (jintLong)FN(25, args), \ (jintLong)FN(26, args), \ (jintLong)FN(27, args), \ (jintLong)FN(28, args), \ (jintLong)FN(29, args), \ (jintLong)FN(30, args), \ (jintLong)FN(31, args), \ (jintLong)FN(32, args), \ (jintLong)FN(33, args), \ (jintLong)FN(34, args), \ (jintLong)FN(35, args), \ (jintLong)FN(36, args), \ (jintLong)FN(37, args), \ (jintLong)FN(38, args), \ (jintLong)FN(39, args), \ (jintLong)FN(40, args), \ (jintLong)FN(41, args), \ (jintLong)FN(42, args), \ (jintLong)FN(43, args), \ (jintLong)FN(44, args), \ (jintLong)FN(45, args), \ (jintLong)FN(46, args), \ (jintLong)FN(47, args), \ (jintLong)FN(48, args), \ (jintLong)FN(49, args), \ (jintLong)FN(50, args), \ (jintLong)FN(51, args), \ (jintLong)FN(52, args), \ (jintLong)FN(53, args), \ (jintLong)FN(54, args), \ (jintLong)FN(55, args), \ (jintLong)FN(56, args), \ (jintLong)FN(57, args), \ (jintLong)FN(58, args), \ (jintLong)FN(59, args), \ (jintLong)FN(60, args), \ (jintLong)FN(61, args), \ (jintLong)FN(62, args), \ (jintLong)FN(63, args), \ (jintLong)FN(64, args), \ (jintLong)FN(65, args), \ (jintLong)FN(66, args), \ (jintLong)FN(67, args), \ (jintLong)FN(68, args), \ (jintLong)FN(69, args), \ (jintLong)FN(70, args), \ (jintLong)FN(71, args), \ (jintLong)FN(72, args), \ (jintLong)FN(73, args), \ (jintLong)FN(74, args), \ (jintLong)FN(75, args), \ (jintLong)FN(76, args), \ (jintLong)FN(77, args), \ (jintLong)FN(78, args), \ (jintLong)FN(79, args), \ (jintLong)FN(80, args), \ (jintLong)FN(81, args), \ (jintLong)FN(82, args), \ (jintLong)FN(83, args), \ (jintLong)FN(84, args), \ (jintLong)FN(85, args), \ (jintLong)FN(86, args), \ (jintLong)FN(87, args), \ (jintLong)FN(88, args), \ (jintLong)FN(89, args), \ (jintLong)FN(90, args), \ (jintLong)FN(91, args), \ (jintLong)FN(92, args), \ (jintLong)FN(93, args), \ (jintLong)FN(94, args), \ (jintLong)FN(95, args), \ (jintLong)FN(96, args), \ (jintLong)FN(97, args), \ (jintLong)FN(98, args), \ (jintLong)FN(99, args), \ (jintLong)FN(100, args), \ (jintLong)FN(101, args), \ (jintLong)FN(102, args), \ (jintLong)FN(103, args), \ (jintLong)FN(104, args), \ (jintLong)FN(105, args), \ (jintLong)FN(106, args), \ (jintLong)FN(107, args), \ (jintLong)FN(108, args), \ (jintLong)FN(109, args), \ (jintLong)FN(110, args), \ (jintLong)FN(111, args), \ (jintLong)FN(112, args), \ (jintLong)FN(113, args), \ (jintLong)FN(114, args), \ (jintLong)FN(115, args), \ (jintLong)FN(116, args), \ (jintLong)FN(117, args), \ (jintLong)FN(118, args), \ (jintLong)FN(119, args), \ (jintLong)FN(120, args), \ (jintLong)FN(121, args), \ (jintLong)FN(122, args), \ (jintLong)FN(123, args), \ (jintLong)FN(124, args), \ (jintLong)FN(125, args), \ (jintLong)FN(126, args), \ (jintLong)FN(127, args), \ }, #else #error Invalid MAX_CALLBACKS #endif /* MAX_CALLBACKS == 16 */ jintLong fnx_array[MAX_ARGS+1][MAX_CALLBACKS] = { FN_A_BLOCK(0) FN_A_BLOCK(1) FN_A_BLOCK(2) FN_A_BLOCK(3) FN_A_BLOCK(4) FN_A_BLOCK(5) FN_A_BLOCK(6) FN_A_BLOCK(7) FN_A_BLOCK(8) FN_A_BLOCK(9) FN_A_BLOCK(10) FN_A_BLOCK(11) FN_A_BLOCK(12) }; #endif /* USE_ASSEMBLER */ /* --------------- class Callback Native Methods --------------- */ JNIEXPORT jintLong JNICALL Java_org_fusesource_hawtjni_runtime_Callback_bind (JNIEnv *env, jclass that, jobject callbackObject, jobject object, jstring method, jstring signature, jint argCount, jboolean isStatic, jboolean isArrayBased, jintLong errorResult) { int i; jmethodID mid = NULL; jclass javaClass = that; const char *methodString = NULL, *sigString = NULL; if (jvm == NULL) (*env)->GetJavaVM(env, &jvm); if (JNI_VERSION == 0) JNI_VERSION = (*env)->GetVersion(env); if (!initialized) { memset(&callbackData, 0, sizeof(callbackData)); initialized = 1; } if (method) methodString = (const char *) (*env)->GetStringUTFChars(env, method, NULL); if (signature) sigString = (const char *) (*env)->GetStringUTFChars(env, signature, NULL); if (object && methodString && sigString) { if (isStatic) { mid = (*env)->GetStaticMethodID(env, object, methodString, sigString); } else { javaClass = (*env)->GetObjectClass(env, object); mid = (*env)->GetMethodID(env, javaClass, methodString, sigString); } } if (method && methodString) (*env)->ReleaseStringUTFChars(env, method, methodString); if (signature && sigString) (*env)->ReleaseStringUTFChars(env, signature, sigString); if (mid == 0) goto fail; for (i=0; iNewGlobalRef(env, callbackObject)) == NULL) goto fail; if ((callbackData[i].object = (*env)->NewGlobalRef(env, object)) == NULL) goto fail; callbackData[i].isStatic = isStatic; callbackData[i].isArrayBased = isArrayBased; callbackData[i].argCount = argCount; callbackData[i].errorResult = errorResult; callbackData[i].methodID = mid; #ifndef USE_ASSEMBLER return (jintLong) fnx_array[argCount][i]; #else { int j = 0, k; unsigned char* code; #ifdef __APPLE__ int pad = 0; #endif if (callbackCode == NULL) { #if defined (_WIN32) || defined (_WIN32_WCE) callbackCode = VirtualAlloc(NULL, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (callbackCode == NULL) return 0; #else callbackCode = mmap(NULL, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (callbackCode == MAP_FAILED) return 0; #endif } code = (unsigned char *)(callbackCode + (i * CALLBACK_THUNK_SIZE)); //PUSH EBP - 1 byte code[j++] = 0x55; //MOV EBP,ESP - 2 bytes code[j++] = 0x8b; code[j++] = 0xec; #ifdef __APPLE__ /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */ k = (argCount+3)*sizeof(jintLong); pad = ((k + 15) & ~15) - k; if (pad > 0) { //SUB ESP,pad - 3 bytes code[j++] = 0x83; code[j++] = 0xec; code[j++] = pad; } #endif // 3*argCount bytes for (k=(argCount + 1) * sizeof(jintLong); k >= sizeof(jintLong)*2; k -= sizeof(jintLong)) { //PUSH SS:[EBP+k] code[j++] = 0xff; code[j++] = 0x75; code[j++] = k; } if (i > 127) { //PUSH i - 5 bytes code[j++] = 0x68; code[j++] = ((i >> 0) & 0xFF); code[j++] = ((i >> 8) & 0xFF); code[j++] = ((i >> 16) & 0xFF); code[j++] = ((i >> 24) & 0xFF); } else { //PUSH i - 2 bytes code[j++] = 0x6a; code[j++] = i; } //MOV EAX callback - 1 + sizeof(jintLong) bytes code[j++] = 0xb8; ((jintLong *)&code[j])[0] = (jintLong)&callback; j += sizeof(jintLong); //CALL EAX - 2 bytes code[j++] = 0xff; code[j++] = 0xd0; //ADD ESP,(argCount + 1) * sizeof(jintLong) - 3 bytes code[j++] = 0x83; code[j++] = 0xc4; #ifdef __APPLE__ code[j++] = (unsigned char)(pad + ((argCount + 1) * sizeof(jintLong))); #else code[j++] = (unsigned char)((argCount + 1) * sizeof(jintLong)); #endif //POP EBP - 1 byte code[j++] = 0x5d; #if defined (_WIN32) || defined (_WIN32_WCE) //RETN argCount * sizeof(jintLong) - 3 bytes code[j++] = 0xc2; code[j++] = (unsigned char)(argCount * sizeof(jintLong)); code[j++] = 0x00; #else //RETN - 1 byte code[j++] = 0xc3; #endif if (j > CALLBACK_THUNK_SIZE) { jclass errorClass = (*env)->FindClass(env, "java/lang/Error"); (*env)->ThrowNew(env, errorClass, "Callback thunk overflow"); } return (jintLong)code; } #endif /* USE_ASSEMBLER */ } } fail: return 0; } JNIEXPORT void JNICALL Java_org_fusesource_hawtjni_runtime_Callback_unbind (JNIEnv *env, jclass that, jobject callback) { int i; for (i=0; iIsSameObject(env, callback, callbackData[i].callback)) { if (callbackData[i].callback != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].callback); if (callbackData[i].object != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].object); memset(&callbackData[i], 0, sizeof(CALLBACK_DATA)); } } } JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_Callback_getEnabled (JNIEnv *env, jclass that) { return (jboolean)callbackEnabled; } JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_Callback_getEntryCount (JNIEnv *env, jclass that) { return (jint)callbackEntryCount; } JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_Callback_setEnabled (JNIEnv *env, jclass that, jboolean enable) { callbackEnabled = enable; } JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_Callback_reset (JNIEnv *env, jclass that) { memset((void *)&callbackData, 0, sizeof(callbackData)); } jintLong callback(int index, ...) { if (!callbackEnabled) return 0; { JNIEnv *env = NULL; jmethodID mid = callbackData[index].methodID; jobject object = callbackData[index].object; jboolean isStatic = callbackData[index].isStatic; jboolean isArrayBased = callbackData[index].isArrayBased; jint argCount = callbackData[index].argCount; jintLong result = callbackData[index].errorResult; int detach = 0; va_list vl; #ifdef DEBUG_CALL_PRINTS fprintf(stderr, "* callback starting %d\n", counter++); #endif #ifdef JNI_VERSION_1_2 if (IS_JNI_1_2) { (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2); } #endif #ifdef JNI_VERSION_1_4 if (env == NULL) { if (JNI_VERSION >= JNI_VERSION_1_4) { (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, NULL); } } #endif if (env == NULL) { (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); if (IS_JNI_1_2) detach = 1; } /* If the current thread is not attached to the VM, it is not possible to call into the VM */ if (env == NULL) { #ifdef DEBUG_CALL_PRINTS fprintf(stderr, "* could not get env\n"); #endif goto noEnv; } /* If an exception has occurred in previous callbacks do not call into the VM. */ if ((*env)->ExceptionOccurred(env)) { goto done; } /* Call into the VM. */ ATOMIC_INC(callbackEntryCount); va_start(vl, index); if (isArrayBased) { int i; jintLongArray argsArray = (*env)->NewIntLongArray(env, argCount); if (argsArray != NULL) { jintLong *elements = (*env)->GetIntLongArrayElements(env, argsArray, NULL); if (elements != NULL) { for (i=0; iReleaseIntLongArrayElements(env, argsArray, elements, 0); if (isStatic) { result = (*env)->CallStaticIntLongMethod(env, object, mid, argsArray); } else { result = (*env)->CallIntLongMethod(env, object, mid, argsArray); } } /* * This function may be called many times before returning to Java, * explicitly delete local references to avoid GP's in certain VMs. */ (*env)->DeleteLocalRef(env, argsArray); } } else { if (isStatic) { result = (*env)->CallStaticIntLongMethodV(env, object, mid, vl); } else { result = (*env)->CallIntLongMethodV(env, object, mid, vl); } } va_end(vl); ATOMIC_DEC(callbackEntryCount); done: /* If an exception has occurred in Java, return the error result. */ if ((*env)->ExceptionOccurred(env)) { #ifdef DEBUG_CALL_PRINTS fprintf(stderr, "* java exception occurred\n"); (*env)->ExceptionDescribe(env); #endif result = callbackData[index].errorResult; } if (detach) { (*jvm)->DetachCurrentThread(jvm); env = NULL; } noEnv: #ifdef DEBUG_CALL_PRINTS fprintf(stderr, "* callback exiting %d\n", --counter); #endif return result; } } /* ------------- END: class Callback impl --------------- */ hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/hawtjni.c000077500000000000000000000050531142665006500262030ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ /* == HEADER-SNIP-LOCATION == */ #include "hawtjni.h" #include #include int IS_JNI_1_2 = 0; #ifdef JNI_VERSION_1_2 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { IS_JNI_1_2 = 1; return JNI_VERSION_1_2; } #endif void throwOutOfMemory(JNIEnv *env) { jclass clazz = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); if (clazz != NULL) { (*env)->ThrowNew(env, clazz, ""); } } #ifndef JNI64 void **hawtjni_malloc_pointer_array(JNIEnv *env, jlongArray array) { int i, size; jlong *elems; void **rc; if( array==NULL ) { return NULL; } #ifdef JNI_VERSION_1_2 if (IS_JNI_1_2) { elems = (*env)->GetPrimitiveArrayCritical(env, array, NULL); } else #endif { elems = (*env)->GetLongArrayElements(env, array, NULL); } if( elems == NULL) { return NULL; } size = (*env)->GetArrayLength(env, array); rc=malloc(sizeof(void *)*(size+1)); if( rc!= NULL ) { for( i=0; i < size; i++ ) { rc[i]=(void *)(intptr_t)(elems[i]); } rc[size]=NULL; } #ifdef JNI_VERSION_1_2 if (IS_JNI_1_2) { (*env)->ReleasePrimitiveArrayCritical(env, array, elems, JNI_ABORT); } else #endif { (*env)->ReleaseLongArrayElements(env, array, elems, JNI_ABORT); } return rc; } void hawtjni_free_pointer_array(JNIEnv *env, jlongArray array, void **elems, jint mode) { // do we need to copy back the data?? if( mode != JNI_ABORT) { int i, size; jlong *tmp; size = (*env)->GetArrayLength(env, array); #ifdef JNI_VERSION_1_2 if (IS_JNI_1_2) { tmp = (*env)->GetPrimitiveArrayCritical(env, array, NULL); } else #endif { tmp = (*env)->GetLongArrayElements(env, array, NULL); } if( tmp != NULL) { for( i=0; i < size; i++ ) { tmp[i]=(intptr_t)elems[i]; } #ifdef JNI_VERSION_1_2 if (IS_JNI_1_2) { (*env)->ReleasePrimitiveArrayCritical(env, array, tmp, 0); } else #endif { (*env)->ReleaseLongArrayElements(env, array, tmp, 0); } } } /* mode != JNI_ABORTmode */ free(elems); } #endif /* JNI64 */ hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/hawtjni.h000077500000000000000000000115471142665006500262150ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ /* == HEADER-SNIP-LOCATION == */ /** * hawtjni.h * * This file contains the global macro declarations for a hawtjni based * library. * */ #ifndef INC_HAWTJNI_H #define INC_HAWTJNI_H #include "jni.h" #include #ifdef __cplusplus extern "C" { #endif extern int IS_JNI_1_2; #ifndef JNI64 #if __x86_64__ #define JNI64 #endif #endif /* 64 bit support */ #ifndef JNI64 /* int/long defines */ #define GetIntLongField GetIntField #define SetIntLongField SetIntField #define GetIntLongArrayElements GetIntArrayElements #define ReleaseIntLongArrayElements ReleaseIntArrayElements #define GetIntLongArrayRegion GetIntArrayRegion #define SetIntLongArrayRegion SetIntArrayRegion #define NewIntLongArray NewIntArray #define CallStaticIntLongMethod CallStaticIntMethod #define CallIntLongMethod CallIntMethod #define CallStaticIntLongMethodV CallStaticIntMethodV #define CallIntLongMethodV CallIntMethodV #define jintLongArray jintArray #define jintLong jint #define I_J "I" #define I_JArray "[I" /* float/double defines */ #define GetFloatDoubleField GetFloatField #define SetFloatDoubleField SetFloatField #define GetFloatDoubleArrayElements GetFloatArrayElements #define ReleaseFloatDoubleArrayElements ReleaseFloatArrayElements #define GetFloatDoubleArrayRegion GetFloatArrayRegion #define jfloatDoubleArray jfloatArray #define jfloatDouble jfloat #define F_D "F" #define F_DArray "[F" #else /* int/long defines */ #define GetIntLongField GetLongField #define SetIntLongField SetLongField #define GetIntLongArrayElements GetLongArrayElements #define ReleaseIntLongArrayElements ReleaseLongArrayElements #define GetIntLongArrayRegion GetLongArrayRegion #define SetIntLongArrayRegion SetLongArrayRegion #define NewIntLongArray NewLongArray #define CallStaticIntLongMethod CallStaticLongMethod #define CallIntLongMethod CallLongMethod #define CallStaticIntLongMethodV CallStaticLongMethodV #define CallIntLongMethodV CallLongMethodV #define jintLongArray jlongArray #define jintLong jlong #define I_J "J" #define I_JArray "[J" /* float/double defines */ #define GetFloatDoubleField GetDoubleField #define SetFloatDoubleField SetDoubleField #define GetFloatDoubleArrayElements GetDoubleArrayElements #define ReleaseFloatDoubleArrayElements ReleaseDoubleArrayElements #define GetFloatDoubleArrayRegion GetDoubleArrayRegion #define jfloatDoubleArray jdoubleArray #define jfloatDouble jdouble #define F_D "D" #define F_DArray "[D" #endif #ifdef __APPLE__ #define CALLING_CONVENTION #define LOAD_FUNCTION(var, name) \ static int initialized = 0; \ static void *var = NULL; \ if (!initialized) { \ CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR(name##_LIB)); \ if (bundle) var = CFBundleGetFunctionPointerForName(bundle, CFSTR(#name)); \ initialized = 1; \ } #elif defined (_WIN32) || defined (_WIN32_WCE) #define CALLING_CONVENTION CALLBACK #define LOAD_FUNCTION(var, name) \ static int initialized = 0; \ static FARPROC var = NULL; \ if (!initialized) { \ HMODULE hm = LoadLibrary(name##_LIB); \ if (hm) var = GetProcAddress(hm, #name); \ initialized = 1; \ } #else #define CALLING_CONVENTION #define LOAD_FUNCTION(var, name) \ static int initialized = 0; \ static void *var = NULL; \ if (!initialized) { \ void* handle = dlopen(name##_LIB, RTLD_LAZY); \ if (handle) var = dlsym(handle, #name); \ initialized = 1; \ } #endif void throwOutOfMemory(JNIEnv *env); #define CHECK_NULL_VOID(ptr) \ if ((ptr) == NULL) { \ throwOutOfMemory(env); \ return; \ } #define CHECK_NULL(ptr) \ if ((ptr) == NULL) { \ throwOutOfMemory(env); \ return 0; \ } #ifndef JNI64 void ** hawtjni_malloc_pointer_array(JNIEnv *env, jlongArray array); void hawtjni_free_pointer_array(JNIEnv *env, jlongArray array, void **elems, jint mode); #else #ifdef __cplusplus #define hawtjni_malloc_pointer_array(env, array) ( (void **)(intptr_t)env->GetLongArrayElements(array, NULL) ) #define hawtjni_free_pointer_array(env, array, elems, mode) ( env->ReleaseLongArrayElements(array, (jlong*)elems, mode) ) #else #define hawtjni_malloc_pointer_array(env, source) ( (void **)(intptr_t)(*env)->GetLongArrayElements(env, source, NULL) ) #define hawtjni_free_pointer_array(env, array, elems, mode) ( (*env)->ReleaseLongArrayElements(env, array, (jlong*)elems, mode) ) #endif #endif /* JNI64 */ #ifdef __cplusplus } #endif #endif /* ifndef INC_HAWTJNI_H */ hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/windows/000077500000000000000000000000001142665006500260575ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-generator/src/main/resources/windows/stdint.h000066400000000000000000000170601142665006500275410ustar00rootroot00000000000000// ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2008 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ #if _MSC_VER > 1000 #pragma once #endif #include // For Visual Studio 6 in C++ mode and for many Visual Studio versions when // compiling for ARM we should wrap include with 'extern "C++" {}' // or compiler give many errors like this: // error C2733: second C linkage of overloaded function 'wmemchr' not allowed #ifdef __cplusplus extern "C" { #endif # include #ifdef __cplusplus } #endif // Define _W64 macros to mark types changing their size, like intptr_t. #ifndef _W64 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # define _W64 __w64 # else # define _W64 # endif #endif // 7.18.1 Integer types // 7.18.1.1 Exact-width integer types // Visual Studio 6 and Embedded Visual C++ 4 doesn't // realize that, e.g. char has the same size as __int8 // so we give up on __intX for them. #if (_MSC_VER < 1300) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #else typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; #endif typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; // 7.18.1.2 Minimum-width integer types typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef int64_t int_least64_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; typedef int64_t int_fast64_t; typedef uint8_t uint_fast8_t; typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef signed __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else // _WIN64 ][ typedef _W64 signed int intptr_t; typedef _W64 unsigned int uintptr_t; #endif // _WIN64 ] // 7.18.1.5 Greatest-width integer types typedef int64_t intmax_t; typedef uint64_t uintmax_t; // 7.18.2 Limits of specified-width integer types #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 // 7.18.2.1 Limits of exact-width integer types #define INT8_MIN ((int8_t)_I8_MIN) #define INT8_MAX _I8_MAX #define INT16_MIN ((int16_t)_I16_MIN) #define INT16_MAX _I16_MAX #define INT32_MIN ((int32_t)_I32_MIN) #define INT32_MAX _I32_MAX #define INT64_MIN ((int64_t)_I64_MIN) #define INT64_MAX _I64_MAX #define UINT8_MAX _UI8_MAX #define UINT16_MAX _UI16_MAX #define UINT32_MAX _UI32_MAX #define UINT64_MAX _UI64_MAX // 7.18.2.2 Limits of minimum-width integer types #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX // 7.18.2.3 Limits of fastest minimum-width integer types #define INT_FAST8_MIN INT8_MIN #define INT_FAST8_MAX INT8_MAX #define INT_FAST16_MIN INT16_MIN #define INT_FAST16_MAX INT16_MAX #define INT_FAST32_MIN INT32_MIN #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MIN INT64_MIN #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT8_MAX #define UINT_FAST16_MAX UINT16_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX // 7.18.2.4 Limits of integer types capable of holding object pointers #ifdef _WIN64 // [ # define INTPTR_MIN INT64_MIN # define INTPTR_MAX INT64_MAX # define UINTPTR_MAX UINT64_MAX #else // _WIN64 ][ # define INTPTR_MIN INT32_MIN # define INTPTR_MAX INT32_MAX # define UINTPTR_MAX UINT32_MAX #endif // _WIN64 ] // 7.18.2.5 Limits of greatest-width integer types #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX // 7.18.3 Limits of other integer types #ifdef _WIN64 // [ # define PTRDIFF_MIN _I64_MIN # define PTRDIFF_MAX _I64_MAX #else // _WIN64 ][ # define PTRDIFF_MIN _I32_MIN # define PTRDIFF_MAX _I32_MAX #endif // _WIN64 ] #define SIG_ATOMIC_MIN INT_MIN #define SIG_ATOMIC_MAX INT_MAX #ifndef SIZE_MAX // [ # ifdef _WIN64 // [ # define SIZE_MAX _UI64_MAX # else // _WIN64 ][ # define SIZE_MAX _UI32_MAX # endif // _WIN64 ] #endif // SIZE_MAX ] // WCHAR_MIN and WCHAR_MAX are also defined in #ifndef WCHAR_MIN // [ # define WCHAR_MIN 0 #endif // WCHAR_MIN ] #ifndef WCHAR_MAX // [ # define WCHAR_MAX _UI16_MAX #endif // WCHAR_MAX ] #define WINT_MIN 0 #define WINT_MAX _UI16_MAX #endif // __STDC_LIMIT_MACROS ] // 7.18.4 Limits of other integer types #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 // 7.18.4.1 Macros for minimum-width integer constants #define INT8_C(val) val##i8 #define INT16_C(val) val##i16 #define INT32_C(val) val##i32 #define INT64_C(val) val##i64 #define UINT8_C(val) val##ui8 #define UINT16_C(val) val##ui16 #define UINT32_C(val) val##ui32 #define UINT64_C(val) val##ui64 // 7.18.4.2 Macros for greatest-width integer constants #define INTMAX_C INT64_C #define UINTMAX_C UINT64_C #endif // __STDC_CONSTANT_MACROS ] #endif // _MSC_STDINT_H_ ] hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/000077500000000000000000000000001142665006500203355ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/pom.xml000066400000000000000000000024331142665006500216540ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-pom 1.1-SNAPSHOT org.fusesource.hawtjni hawtjni-runtime 1.1-SNAPSHOT HawtJNI Runtime The API that projects using HawtJNI should build against. hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/000077500000000000000000000000001142665006500211245ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/000077500000000000000000000000001142665006500220505ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/000077500000000000000000000000001142665006500227715ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/000077500000000000000000000000001142665006500235605ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/000077500000000000000000000000001142665006500257435ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001142665006500274075ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/000077500000000000000000000000001142665006500310725ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/ArgFlag.java000066400000000000000000000052301142665006500332400ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * * @author Hiram Chirino */ public enum ArgFlag { /** * Indicate that a native method parameter is an out only variable. * This only makes sense if the parameter is a structure or an array * of primitives. It is an optimization to avoid copying the java * memory to C memory on the way in. */ NO_IN, /** * Indicate that a native method parameter is an in only variable. * This only makes sense if the parameter is a structure or an array * of primitives. It is an optimization to avoid copying the C memory * from java memory on the way out. */ NO_OUT, /** * Indicate that GetPrimitiveArrayCritical() should be used instead * of GetArrayElements() when transferring array of * primitives from/to C. This is an optimization to avoid copying * memory and must be used carefully. It is ok to be used in * MoveMemory() and memmove() natives. */ CRITICAL, /** * Indicate that the associated C local variable for a native method * parameter should be initialized with zeros. */ INIT, /** * Indicate that the parameter is a pointer. */ POINTER_ARG, /** * Indicate that a structure parameter should be passed by value * instead of by reference. This dereferences the parameter by * prepending *. The parameter must not be NULL. */ BY_VALUE, /** * Indicate that GetStringChars()should be used instead of * GetStringUTFChars() to get the characters of a java.lang.String * passed as a parameter to native methods. */ UNICODE, /** * Indicate that the parameter of a native method is the sentinel * (last parameter of a variable argument C function). The generated * code is always the literal NULL. Some compilers expect the sentinel * to be the literal NULL and output a warning if otherwise. */ SENTINEL, /** * Indicate that the native parameter is a C# managed object. */ CS_OBJECT, }Callback.java000066400000000000000000000224011142665006500333510ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * Instances of this class represent entry points into Java which can be invoked * from operating system level callback routines. *

* IMPORTANT: A callback is only valid when invoked on the thread which created * it. The results are undefined (and typically bad) when a callback is passed * out to the operating system (or other code) in such a way that the callback * is called from a different thread. */ public class Callback { Object object; String method, signature; int argCount; long /* int */ address, errorResult; boolean isStatic, isArrayBased; static final String PTR_SIGNATURE = "J"; /* C.PTR_SIZEOF == 4 ? "I" : "J"; */ static final String SIGNATURE_0 = getSignature(0); static final String SIGNATURE_1 = getSignature(1); static final String SIGNATURE_2 = getSignature(2); static final String SIGNATURE_3 = getSignature(3); static final String SIGNATURE_4 = getSignature(4); static final String SIGNATURE_N = "([" + PTR_SIGNATURE + ")" + PTR_SIGNATURE; /** * Constructs a new instance of this class given an object to send the * message to, a string naming the method to invoke and an argument count. * Note that, if the object is an instance of Class it is * assumed that the method is a static method on that class. * * @param object * the object to send the message to * @param method * the name of the method to invoke * @param argCount * the number of arguments that the method takes */ public Callback(Object object, String method, int argCount) { this(object, method, argCount, false); } /** * Constructs a new instance of this class given an object to send the * message to, a string naming the method to invoke, an argument count and a * flag indicating whether or not the arguments will be passed in an array. * Note that, if the object is an instance of Class it is * assumed that the method is a static method on that class. * * @param object * the object to send the message to * @param method * the name of the method to invoke * @param argCount * the number of arguments that the method takes * @param isArrayBased * true if the arguments should be passed in an * array and false otherwise */ public Callback(Object object, String method, int argCount, boolean isArrayBased) { this(object, method, argCount, isArrayBased, 0); } /** * Constructs a new instance of this class given an object to send the * message to, a string naming the method to invoke, an argument count, a * flag indicating whether or not the arguments will be passed in an array * and a value to return when an exception happens. Note that, if the object * is an instance of Class it is assumed that the method is a * static method on that class. * * @param object * the object to send the message to * @param method * the name of the method to invoke * @param argCount * the number of arguments that the method takes * @param isArrayBased * true if the arguments should be passed in an * array and false otherwise * @param errorResult * the return value if the java code throws an exception */ public Callback(Object object, String method, int argCount, boolean isArrayBased, int /* long */errorResult) { /* Set the callback fields */ this.object = object; this.method = method; this.argCount = argCount; this.isStatic = object instanceof Class; this.isArrayBased = isArrayBased; this.errorResult = errorResult; /* Inline the common cases */ if (isArrayBased) { signature = SIGNATURE_N; } else { switch (argCount) { case 0: signature = SIGNATURE_0; break; //$NON-NLS-1$ case 1: signature = SIGNATURE_1; break; //$NON-NLS-1$ case 2: signature = SIGNATURE_2; break; //$NON-NLS-1$ case 3: signature = SIGNATURE_3; break; //$NON-NLS-1$ case 4: signature = SIGNATURE_4; break; //$NON-NLS-1$ default: signature = getSignature(argCount); } } /* Bind the address */ address = bind(this, object, method, signature, argCount, isStatic, isArrayBased, errorResult); } /** * Allocates the native level resources associated with the callback. This * method is only invoked from within the constructor for the argument. * * @param callback * the callback to bind * @param object * the callback's object * @param method * the callback's method * @param signature * the callback's method signature * @param argCount * the callback's method argument count * @param isStatic * whether the callback's method is static * @param isArrayBased * whether the callback's method is array based * @param errorResult * the callback's error result */ static native synchronized long /* int */ bind(Callback callback, Object object, String method, String signature, int argCount, boolean isStatic, boolean isArrayBased, long /* int */errorResult); /** * Releases the native level resources associated with the callback, and * removes all references between the callback and other objects. This helps * to prevent (bad) application code from accidentally holding onto * extraneous garbage. */ public void dispose() { if (object == null) return; unbind(this); object = method = signature = null; address = 0; } /** * Returns the address of a block of machine code which will invoke the * callback represented by the receiver. * * @return the callback address */ public long /* int */getAddress() { return address; } /** * Returns the SWT platform name. * * @return the platform name of the currently running SWT */ public static native String getPlatform(); /** * Returns the number of times the system has been recursively entered * through a callback. *

* Note: This should not be called by application code. *

* * @return the entry count * * @since 2.1 */ public static native int getEntryCount(); static String getSignature(int argCount) { String signature = "("; //$NON-NLS-1$ for (int i = 0; i < argCount; i++) signature += PTR_SIGNATURE; signature += ")" + PTR_SIGNATURE; //$NON-NLS-1$ return signature; } /** * Indicates whether or not callbacks which are triggered at the native * level should cause the messages described by the matching * Callback objects to be invoked. This method is used to * safely shut down SWT when it is run within environments which can * generate spurious events. *

* Note: This should not be called by application code. *

* * @param enable * true if callbacks should be invoked */ public static final native synchronized void setEnabled(boolean enable); /** * Returns whether or not callbacks which are triggered at the native level * should cause the messages described by the matching Callback * objects to be invoked. This method is used to safely shut down SWT when * it is run within environments which can generate spurious events. *

* Note: This should not be called by application code. *

* * @return true if callbacks should not be invoked */ public static final native synchronized boolean getEnabled(); /** * Immediately wipes out all native level state associated with all * callbacks. *

* WARNING: This operation is extremely dangerous, and * should never be performed by application code. *

*/ public static final native synchronized void reset(); /** * Releases the native level resources associated with the callback. * * @see #dispose */ static final native synchronized void unbind(Callback callback); } ClassFlag.java000066400000000000000000000025621142665006500335220ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * * @author Hiram Chirino */ public enum ClassFlag { /** * Indicate that the item should not be generated. For example, * custom natives are coded by hand. */ CLASS_SKIP, /** * Indicate that the platform source is in C++ */ CPP, /** * Indicate that this class will define a structure */ STRUCT, /** * Indicate that structure name is a typedef (It should * not be prefixed with 'struct' to reference it.) */ TYPEDEF, /** * Indicate that the struct should get zeroed out before * setting any of it's fields. Comes in handy when * you don't map all the struct fields to java fields but * still want the fields that are not mapped initialized. */ ZERO_OUT, }FieldFlag.java000066400000000000000000000020621142665006500334730ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * * @author Hiram Chirino */ public enum FieldFlag { /** * Indicate that the item should not be generated. For example, * custom natives are coded by hand. */ FIELD_SKIP, /** * Indicate that the field represents a constant or global * variable. It is expected that the java field will be declared * static. */ CONSTANT, /** * Indicate that the field is a pointer. */ POINTER_FIELD, }hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/JniArg.java000066400000000000000000000015101142665006500331040ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * */ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; @Target({PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface JniArg { ArgFlag[] flags() default {}; String cast() default ""; } JniClass.java000066400000000000000000000015161142665006500333670ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * */ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; @Target({TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface JniClass { ClassFlag[] flags() default {}; String conditional() default ""; } JniField.java000066400000000000000000000017161142665006500333470ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; /** * * @author Hiram Chirino */ @Target({FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface JniField { String cast() default ""; String accessor() default ""; String conditional() default ""; FieldFlag[] flags() default {}; } JniMethod.java000066400000000000000000000021301142665006500335330ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; /** * * @author Hiram Chirino */ @Target({METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface JniMethod { String cast() default ""; // Pointer pointer() default Pointer.DETERMINE_FROM_CAST; String accessor() default ""; MethodFlag[] flags() default {}; String copy() default ""; String conditional() default ""; JniArg[] callbackArgs() default {}; } hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/Library.java000077500000000000000000000271171142665006500333540ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2000, 2009 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.regex.Pattern; /** * Used to optionally extract and load a JNI library. * * It will search for the library in order at the following locations: *
    *
  1. in the custom library path: If the "library.${name}.path" System property is set to a directory *
      *
    1. "${name}-${version}" if the version can be determined. *
    2. "${name}" *
    *
  2. system library path: This is where the JVM looks for JNI libraries by default. *
      *
    1. "${name}-${version}" if the version can be determined. *
    2. "${name}" *
    *
  3. classpath path: If the JNI library can be found on the classpath, it will get extracted * and and then loaded. This way you can embed your JNI libraries into your packaged JAR files. * They are looked up as resources in this order: *
      *
    1. "META-INF/native/${platform}/${library}" : Store your library here if you want to embed more * than one platform JNI library in the jar. *
    2. "META-INF/native/${library}": Store your library here if your JAR is only going to embedding one * platform library. *
    * The file extraction is attempted until it succeeds in the following directories. *
      *
    1. The directory pointed to by the "library.${name}.path" System property (if set) *
    2. a temporary directory (uses the "java.io.tmpdir" System property) *
    *
* * where: *
    *
  • "${name}" is the name of library *
  • "${version}" is the value of "library.${name}.version" System property if set. * Otherwise it is set to the ImplementationVersion property of the JAR's Manifest
  • *
  • "${os}" is your operating system, for example "osx", "linux", or "windows"
  • *
  • "${bit-model}" is "64" if the JVM process is a 64 bit process, otherwise it's "32" if the * JVM is a 32 bit process
  • *
  • "${platform}" is "${os}${bit-model}", for example "linux32" or "osx64"
  • *
  • "${library}": is the normal jni library name for the platform. For example "${name}.dll" on * windows, "lib${name}.jnilib" on OS X, and "lib${name}.so" on linux
  • *
* * @author Hiram Chirino */ public class Library { static final String SLASH = System.getProperty("file.separator"); final private String name; final private String version; final private ClassLoader classLoader; private boolean loaded; public Library(String name) { this(name, null, null); } public Library(String name, Class clazz) { this(name, version(clazz), clazz.getClassLoader()); } public Library(String name, String version) { this(name, version, null); } public Library(String name, String version, ClassLoader classLoader) { if( name == null ) { throw new IllegalArgumentException("name cannot be null"); } this.name = name; this.version = version; this.classLoader= classLoader; } private static String version(Class clazz) { try { return clazz.getPackage().getImplementationVersion(); } catch (Throwable e) { } return null; } public String getOperatingSystem() { String name = System.getProperty("os.name").toLowerCase().trim(); if( name.startsWith("linux") ) { return "linux"; } if( name.startsWith("mac os x") ) { return "osx"; } if( name.startsWith("win") ) { return "windows"; } return name.replaceAll("\\W+", "_"); } public String getPlatform() { return getOperatingSystem()+getBitModel(); } protected static int getBitModel() { String prop = System.getProperty("sun.arch.data.model"); if (prop == null) { prop = System.getProperty("com.ibm.vm.bitmode"); } if( prop!=null ) { return Integer.parseInt(prop); } return -1; // we don't know.. } /** * */ synchronized public void load() { if( loaded ) { return; } doLoad(); loaded = true; } private void doLoad() { /* Perhaps a custom version is specified */ String version = System.getProperty("library."+name+".version"); if (version == null) { version = this.version; } ArrayList errors = new ArrayList(); /* Try loading library from a custom library path */ String customPath = System.getProperty("library."+name+".path"); if (customPath != null) { if( version!=null && load(errors, file(customPath, map(name + "-" + version))) ) return; if( load(errors, file(customPath, map(name))) ) return; } /* Try loading library from java library path */ if( version!=null && load(errors, name + "-" + version) ) return; if( load(errors, name ) ) return; /* Try extracting the library from the jar */ if( classLoader!=null ) { if( exractAndLoad(errors, version, customPath, getPlatformSpecifcResourcePath()) ) return; if( exractAndLoad(errors, version, customPath, getOperatingSystemSpecifcResourcePath()) ) return; // For the simpler case where only 1 platform lib is getting packed into the jar if( exractAndLoad(errors, version, customPath, getResorucePath()) ) return; } /* Failed to find the library */ throw new UnsatisfiedLinkError("Could not load library. Reasons: " + errors.toString()); } final public String getOperatingSystemSpecifcResourcePath() { return getPlatformSpecifcResourcePath(getOperatingSystem()); } final public String getPlatformSpecifcResourcePath() { return getPlatformSpecifcResourcePath(getPlatform()); } final public String getPlatformSpecifcResourcePath(String platform) { return "META-INF/native/"+platform+"/"+map(name); } final public String getResorucePath() { return "META-INF/native/"+map(name); } final public String getLibraryFileName() { return map(name); } private boolean exractAndLoad(ArrayList errors, String version, String customPath, String resourcePath) { URL resource = classLoader.getResource(resourcePath); if( resource !=null ) { String libName = name; if( version !=null) { libName += "-" + version; } if( customPath!=null ) { // Try to extract it to the custom path... File target = file(customPath, map(libName)); if( extract(errors, resource, target) ) { if( load(errors, target) ) { return true; } } } // Fall back to extracting to the tmp dir customPath = System.getProperty("java.io.tmpdir"); File target = file(customPath, map(libName)); if( extract(errors, resource, target) ) { if( load(errors, target) ) { return true; } } } return false; } private File file(String ...paths) { File rc = null ; for (String path : paths) { if( rc == null ) { rc = new File(path); } else { rc = new File(rc, path); } } return rc; } private String map(String libName) { /* * libraries in the Macintosh use the extension .jnilib but the some * VMs map to .dylib. */ libName = System.mapLibraryName(libName); String ext = ".dylib"; if (libName.endsWith(ext)) { libName = libName.substring(0, libName.length() - ext.length()) + ".jnilib"; } return libName; } private boolean extract(ArrayList errors, URL source, File target) { FileOutputStream os = null; InputStream is = null; boolean extracting = false; try { if (!target.exists() || isStale(source, target) ) { is = source.openStream(); if (is != null) { byte[] buffer = new byte[4096]; os = new FileOutputStream(target); extracting = true; int read; while ((read = is.read(buffer)) != -1) { os.write(buffer, 0, read); } os.close(); is.close(); chmod("755", target); } } } catch (Throwable e) { try { if (os != null) os.close(); } catch (IOException e1) { } try { if (is != null) is.close(); } catch (IOException e1) { } if (extracting && target.exists()) target.delete(); errors.add(e.getMessage()); return false; } return true; } private boolean isStale(URL source, File target) { if( source.getProtocol().equals("jar") ) { // unwrap the jar protocol... try { String parts[] = source.getFile().split(Pattern.quote("!")); source = new URL(parts[0]); } catch (MalformedURLException e) { return false; } } File sourceFile=null; if( source.getProtocol().equals("file") ) { sourceFile = new File(source.getFile()); } if( sourceFile!=null && sourceFile.exists() ) { if( sourceFile.lastModified() > target.lastModified() ) { return true; } } return false; } private void chmod(String permision, File path) { if (getPlatform().startsWith("windows")) return; try { Runtime.getRuntime().exec(new String[] { "chmod", permision, path.getCanonicalPath() }).waitFor(); } catch (Throwable e) { } } private boolean load(ArrayList errors, File lib) { try { System.load(lib.getPath()); return true; } catch (UnsatisfiedLinkError e) { errors.add(e.getMessage()); } return false; } private boolean load(ArrayList errors, String lib) { try { System.loadLibrary(lib); return true; } catch (UnsatisfiedLinkError e) { errors.add(e.getMessage()); } return false; } } MethodFlag.java000066400000000000000000000062721142665006500336770ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2000, 2008 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; /** * * @author Hiram Chirino */ public enum MethodFlag { /** * Indicate that the item should not be generated. For example, * custom natives are coded by hand. */ METHOD_SKIP, /** * Indicate that a native method should be looked up dynamically. It * is useful when having a dependence on a given library is not * desirable. The library name is specified in the *_custom.h file. */ DYNAMIC, /** * Indicate that the native method represents a constant or global * variable instead of a function. This omits () from the generated * code. */ CONSTANT_GETTER, /** * Indicate that the C function should be casted to a prototype * generated from the parameters of the native method. Useful for * variable argument C functions. */ CAST, /** * Indicate that the native is part of the Java Native Interface. For * example: NewGlobalRef(). */ JNI, /** * Indicate that the native method represents a structure global * variable and the address of it should be returned to Java. This is * done by prepending &. */ ADDRESS, /** * Indicate that the platform source is in C++ */ CPP, /** * Indicate that the native method is a C++ constructor that allocates * an object on the heap. */ CPP_NEW, /** * Indicate that the native method is a C++ destructor that * deallocates an object from the heap. */ CPP_DELETE, /** * Indicate that the native method is a C# constructor that allocates * an object on the managed (i.e. garbage collected) heap. */ CS_NEW, /** * Indicate that the native method's return value is a * C# managed object. */ CS_OBJECT, /** * Indicate that the native method represents a setter for a field in * an object or structure */ SETTER, /** * Indicate that the native method represents a getter for a field in * an object or structure. */ GETTER, /** * Indicate that the native method takes 2 arguments, a collection and * an item, and the += operator is used to add the item to the * collection. */ ADDER, /** * Indicate that the return value is a pointer. */ POINTER_RETURN, /** * Indicate that this method will be the constant initializer for * the class. When called, it will set all the static constant fields * to the values defined in your platform. */ CONSTANT_INITIALIZER, }NativeStats.java000077500000000000000000000166271142665006500341420ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * Copyright (c) 2004, 2006 IBM Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map.Entry; /** * Instructions on how to use the NativeStats tool with a standalone SWT * example: *
    *
  1. Compile the native libraries defining the NATIVE_STATS flag.
  2. *
  3. Add the following code around the sections of * interest to dump the native calls done in that section. *
     *      StatsInterface si = MyFooStatsInterface.INSTANCE;
     *      NativeStats stats = new NativeStats(si); 
     *      ... // your code
     *      stats.diff().dump(System.out);
     *      
    *
  4. *
  5. Or add the following code at a given point to dump a snapshot of * the native calls done until that point. *
     *      stats.snapshot().dump(System.out);
     *      
    *
  6. *
* * @author Hiram Chirino */ public class NativeStats { public interface StatsInterface { String getNativeClass(); int functionCount(); String functionName(int ordinal); int functionCounter(int ordinal); } public static class NativeFunction implements Comparable { private final int ordinal; private final String name; private int counter; public NativeFunction(int ordinal, String name, int callCount) { this.ordinal = ordinal; this.name = name; this.counter = callCount; } void subtract(NativeFunction func) { this.counter -= func.counter; } public int getCounter() { return counter; } public void setCounter(int counter) { this.counter = counter; } public String getName() { return name; } public int getOrdinal() { return ordinal; } public int compareTo(NativeFunction func) { return func.counter - counter; } public void reset() { counter=0; } public NativeFunction copy() { return new NativeFunction(ordinal, name, counter); } } private final HashMap> snapshot; public NativeStats(StatsInterface... classes) { this(Arrays.asList(classes)); } public NativeStats(Collection classes) { this(snapshot(classes)); } private NativeStats(HashMap> snapshot) { this.snapshot = snapshot; } public void reset() { for (ArrayList functions : snapshot.values()) { for (NativeFunction function : functions) { function.reset(); } } } public void update() { for (Entry> entry : snapshot.entrySet()) { StatsInterface si = entry.getKey(); for (NativeFunction function : entry.getValue()) { function.setCounter( si.functionCounter(function.getOrdinal()) ); } } } public NativeStats snapshot() { NativeStats copy = copy(); copy.update(); return copy; } public NativeStats copy() { HashMap> rc = new HashMap>(snapshot.size()*2); for (Entry> entry : snapshot.entrySet()) { ArrayList list = new ArrayList(entry.getValue().size()); for (NativeFunction function : entry.getValue()) { list.add(function.copy()); } rc.put(entry.getKey(), list); } return new NativeStats(rc); } public NativeStats diff() { HashMap> rc = new HashMap>(snapshot.size()*2); for (Entry> entry : snapshot.entrySet()) { StatsInterface si = entry.getKey(); ArrayList list = new ArrayList(entry.getValue().size()); for (NativeFunction original : entry.getValue()) { NativeFunction copy = original.copy(); copy.setCounter( si.functionCounter(copy.getOrdinal()) ); copy.subtract(original); list.add(copy); } rc.put(si, list); } return new NativeStats(rc); } /** * Dumps the stats to the print stream in a JSON format. * @param ps */ public void dump(PrintStream ps) { boolean firstSI=true; for (Entry> entry : snapshot.entrySet()) { StatsInterface si = entry.getKey(); ArrayList funcs = entry.getValue(); int total = 0; for (NativeFunction func : funcs) { total += func.getCounter(); } if( !firstSI ) { ps.print(", "); } firstSI=false; ps.print("["); if( total>0 ) { ps.println("{ "); ps.println(" \"class\": \""+si.getNativeClass()+"\","); ps.println(" \"total\": "+total+", "); ps.print(" \"functions\": {"); boolean firstFunc=true; for (NativeFunction func : funcs) { if (func.getCounter() > 0) { if( !firstFunc ) { ps.print(","); } firstFunc=false; ps.println(); ps.print(" \""+func.getName()+"\": "+func.getCounter()); } } ps.println(); ps.println(" }"); ps.print("}"); } ps.print("]"); } } static private HashMap> snapshot(Collection classes) { HashMap> rc = new HashMap>(); for (StatsInterface sc : classes) { int count = sc.functionCount(); ArrayList functions = new ArrayList(count); for (int i = 0; i < count; i++) { String name = (String) sc.functionName(i); functions.add(new NativeFunction(i, name, 0)); } Collections.sort(functions); rc.put(sc, functions); } return rc; } } hawtjni-1.0~+git0c502e20c4/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/T32.java000066400000000000000000000014211142665006500323030ustar00rootroot00000000000000/******************************************************************************* * Copyright (c) 2009 Progress Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.fusesource.hawtjni.runtime; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE}) @Retention(RetentionPolicy.RUNTIME) public @interface T32 { } hawtjni-1.0~+git0c502e20c4/license.txt000066400000000000000000000570251142665006500174040ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------------------------------- Eclipse Public License - Version 1.0

Eclipse Public License - v 1.0

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.

1. DEFINITIONS

"Contribution" means:

a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and

b) in the case of each subsequent Contributor:

i) changes to the Program, and

ii) additions to the Program;

where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.

"Contributor" means any person or entity that distributes the Program.

"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.

"Program" means the Contributions distributed in accordance with this Agreement.

"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.

2. GRANT OF RIGHTS

a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.

b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.

c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.

d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.

3. REQUIREMENTS

A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:

a) it complies with the terms and conditions of this Agreement; and

b) its license agreement:

i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;

ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;

iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and

iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.

When the Program is made available in source code form:

a) it must be made available under this Agreement; and

b) a copy of this Agreement must be included with each copy of the Program.

Contributors may not remove or alter any copyright notices contained within the Program.

Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.

4. COMMERCIAL DISTRIBUTION

Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.

For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.

5. NO WARRANTY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.

6. DISCLAIMER OF LIABILITY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. GENERAL

If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.

If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.

All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.

Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.

This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.

hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/000077500000000000000000000000001142665006500212545ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/pom.xml000066400000000000000000000116711142665006500225770ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-pom 1.1-SNAPSHOT org.fusesource.hawtjni maven-hawtjni-plugin 1.1-SNAPSHOT maven-plugin HawtJNI Maven Plugin Use HawtJNI from a maven plugin ${mavenVersion} 2.0.6 ${project.version} org.fusesource.hawtjni hawtjni-generator 1.1-SNAPSHOT org.apache.maven maven-plugin-api ${mavenVersion} org.apache.maven maven-project ${mavenVersion} org.codehaus.plexus plexus-utils 1.5.15 org.codehaus.plexus plexus-interpolation 1.12 org.apache.maven maven-artifact-manager 2.0 org.apache.maven maven-artifact 2.0 org.apache.maven maven-archiver 2.4 org.codehaus.plexus plexus-archiver 1.0-alpha-9 org.codehaus.plexus plexus-container-default org.codehaus.plexus plexus-component-api org.codehaus.plexus plexus-io 1.0-alpha-1 org.codehaus.plexus plexus-container-default org.codehaus.plexus plexus-component-api maven-compiler-plugin 1.5 1.5 org.codehaus.plexus plexus-maven-plugin 1.3.8 descriptor org.apache.maven.plugins maven-javadoc-plugin 2.6 ${project.build.sourceEncoding} org.apache.maven.plugin-tools maven-plugin-tools-javadoc 2.5.1 hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/000077500000000000000000000000001142665006500220435ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/000077500000000000000000000000001142665006500227675ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/000077500000000000000000000000001142665006500237105ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/000077500000000000000000000000001142665006500244775ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/000077500000000000000000000000001142665006500266625ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001142665006500303265ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/000077500000000000000000000000001142665006500314345ustar00rootroot00000000000000BuildMojo.java000066400000000000000000000307031142665006500341070ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009 Progress Software, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtjni.maven; import java.io.File; import java.io.IOException; import java.util.List; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.archiver.UnArchiver; import org.codehaus.plexus.archiver.manager.ArchiverManager; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.fusesource.hawtjni.runtime.Library; /** * This goal builds the JNI module which was previously * generated with the generate goal. It adds the JNI module * to the test resource path so that unit tests can load * the freshly built JNI library. * * @goal build * @phase generate-test-resources * @author Hiram Chirino */ public class BuildMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * Remote repositories * * @parameter expression="${project.remoteArtifactRepositories}" * @required * @readonly */ protected List remoteArtifactRepositories; /** * Local maven repository. * * @parameter expression="${localRepository}" * @required * @readonly */ protected ArtifactRepository localRepository; /** * Artifact factory, needed to download the package source file * * @component role="org.apache.maven.artifact.factory.ArtifactFactory" * @required * @readonly */ protected ArtifactFactory artifactFactory; /** * Artifact resolver, needed to download the package source file * * @component role="org.apache.maven.artifact.resolver.ArtifactResolver" * @required * @readonly */ protected ArtifactResolver artifactResolver; /** * @component * @required * @readonly */ private ArchiverManager archiverManager; /** * The base name of the library, used to determine generated file names. * * @parameter default-value="${project.artifactId}" */ private String name; /** * Where the unpacked build package is located. * * @parameter default-value="${project.build.directory}/generated-sources/hawtjni/native-package" */ private File packageDirectory; /** * The output directory where the built JNI library will placed. This directory will be added * to as a test resource path so that unit tests can verify the built JNI library. * * The library will placed under the META-INF/native/${platform} directory that the HawtJNI * Library uses to find JNI libraries as classpath resources. * * @parameter default-value="${project.build.directory}/generated-sources/hawtjni/lib" */ private File libDirectory; /** * The directory where the build will be produced. It creates a native-build and native-dist directory * under the specified directory. * * @parameter default-value="${project.build.directory}" */ private File buildDirectory; /** * Should we skip executing the autogen.sh file. * * @parameter default-value="${skip-autogen}" */ private boolean skipAutogen; /** * Should we force executing the autogen.sh file. * * @parameter default-value="${force-autogen}" */ private boolean forceAutogen; /** * Extra arguments you want to pass to the autogen.sh command. * * @parameter */ private List autogenArgs; /** * Should we skip executing the configure command. * * @parameter default-value="${skip-configure}" */ private boolean skipConfigure; /** * Should we force executing the configure command. * * @parameter default-value="${force-configure}" */ private boolean forceConfigure; /** * Should we display all the native build output? * * @parameter default-value="${hawtjni-verbose}" */ private boolean verbose; /** * Extra arguments you want to pass to the configure command. * * @parameter */ private List configureArgs; /** * The platform identifier of this build. If not specified, * it will be automatically detected. * * @parameter */ private String platform; /** * The classifier of the package archive that will be created. * * @parameter default-value="native-src" */ private String sourceClassifier; /** * If the source build could not be fully generated, perhaps the autotools * were not available on this platform, should we attempt to download * a previously deployed source package and build that? * * @parameter default-value="true" */ private boolean downloadSourcePackage = true; private final CLI cli = new CLI(); public void execute() throws MojoExecutionException { cli.verbose = verbose; cli.log = getLog(); try { File buildDir = new File(buildDirectory, "native-build"); buildDir.mkdirs(); if ( CLI.IS_WINDOWS ) { vsBasedBuild(buildDir); } else { configureBasedBuild(buildDir); } getLog().info("Adding test resource root: "+libDirectory.getAbsolutePath()); Resource testResource = new Resource(); testResource.setDirectory(libDirectory.getAbsolutePath()); this.project.addTestResource(testResource); //(); } catch (Exception e) { throw new MojoExecutionException("build failed: "+e, e); } } private void vsBasedBuild(File buildDir) throws CommandLineException, MojoExecutionException, IOException { FileUtils.copyDirectoryStructureIfModified(packageDirectory, buildDir); Library library = new Library(name); String platform; String configuration="release"; if( "windows32".equals(library.getPlatform()) ) { platform = "Win32"; } else if( "windows64".equals(library.getPlatform()) ) { platform = "x64"; } else { throw new MojoExecutionException("Usupported platform: "+library.getPlatform()); } //TODO: look into supporting cross compilation int rc = cli.system(buildDir, new String[]{"vcbuild", "/platform:"+platform, "vs2008.vcproj", configuration}); if( rc != 0 ) { throw new MojoExecutionException("vcbuild failed with exit code: "+rc); } File libFile=FileUtils.resolveFile(buildDir, "target/"+platform+"-"+configuration+"/lib/"+library.getLibraryFileName()); if( !libFile.exists() ) { throw new MojoExecutionException("vcbuild did not generate: "+libFile); } File target=FileUtils.resolveFile(libDirectory, library.getPlatformSpecifcResourcePath()); FileUtils.copyFile(libFile, target); } private void configureBasedBuild(File buildDir) throws IOException, MojoExecutionException, CommandLineException { File configure = new File(packageDirectory, "configure"); if( configure.exists() ) { FileUtils.copyDirectoryStructureIfModified(packageDirectory, buildDir); } else if (downloadSourcePackage) { downloadNativeSourcePackage(buildDir); } else { throw new MojoExecutionException("The configure script is missing from the generated native source package and downloadSourcePackage is disabled: "+configure); } configure = new File(buildDir, "configure"); File autogen = new File(buildDir, "autogen.sh"); File makefile = new File(buildDir, "Makefile"); File distDirectory = new File(buildDir, "target"); File distLibDirectory = new File(distDirectory, "lib"); distLibDirectory.mkdirs(); if( autogen.exists() && !skipAutogen ) { if( (!configure.exists() && !CLI.IS_WINDOWS) || forceAutogen ) { cli.setExecutable(autogen); int rc = cli.system(buildDir, new String[] {"./autogen.sh"}, autogenArgs); if( rc != 0 ) { throw new MojoExecutionException("./autogen.sh failed with exit code: "+rc); } } } if( configure.exists() && !skipConfigure ) { if( !makefile.exists() || forceConfigure ) { File autotools = new File(buildDir, "autotools"); File[] listFiles = autotools.listFiles(); if( listFiles!=null ) { for (File file : listFiles) { cli.setExecutable(file); } } cli.setExecutable(configure); int rc = cli.system(buildDir, new String[]{"./configure", "--disable-ccache", "--prefix="+distDirectory.getCanonicalPath()}, configureArgs); if( rc != 0 ) { throw new MojoExecutionException("./configure failed with exit code: "+rc); } } } int rc = cli.system(buildDir, new String[]{"make", "install"}); if( rc != 0 ) { throw new MojoExecutionException("make based build failed with exit code: "+rc); } Library library = new Library(name); File libFile = new File(distLibDirectory, library.getLibraryFileName()); if( !libFile.exists() ) { throw new MojoExecutionException("Make based build did not generate: "+libFile); } if( platform == null ) { platform = library.getPlatform(); } File target=FileUtils.resolveFile(libDirectory, library.getPlatformSpecifcResourcePath(platform)); FileUtils.copyFile(libFile, target); } public void downloadNativeSourcePackage(File buildDir) throws MojoExecutionException { Artifact artifact = artifactFactory.createArtifactWithClassifier(project.getGroupId(), project.getArtifactId(), project.getVersion(), "zip", sourceClassifier); try { artifactResolver.resolve(artifact, remoteArtifactRepositories, localRepository); } catch (ArtifactResolutionException e) { throw new MojoExecutionException("Error downloading.", e); } catch (ArtifactNotFoundException e) { throw new MojoExecutionException("Requested download does not exist.", e); } File packageZipFile = artifact.getFile(); try { File dest = new File(buildDirectory, "native-build-extracted"); getLog().info("Extracting "+packageZipFile+" to "+dest); UnArchiver unArchiver = archiverManager.getUnArchiver("zip"); unArchiver.setSourceFile(packageZipFile); unArchiver.extract("", dest); String packageName = project.getArtifactId()+"-"+project.getVersion()+"-"+sourceClassifier; File source = new File(dest, packageName); FileUtils.copyDirectoryStructureIfModified(source, buildDir); } catch (Throwable e) { throw new MojoExecutionException("Could not extract the native source package.", e); } } } hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/CLI.java000077500000000000000000000064431142665006500327200ustar00rootroot00000000000000package org.fusesource.hawtjni.maven; import java.io.File; import java.util.List; import java.util.regex.Pattern; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.StreamConsumer; import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer; public class CLI { public static final boolean IS_WINDOWS = isWindows(); static private boolean isWindows() { String name = System.getProperty("os.name").toLowerCase().trim(); return name.startsWith("win"); } public boolean verbose; public Log log; public void setExecutable(File path) { if( IS_WINDOWS ) { return; } try { // These are Java 1.6 Methods.. if( !path.canExecute() ) { path.setExecutable(true); } } catch (NoSuchMethodError e1) { // Do it the old fasioned way... try { system(path.getParentFile(), new String[] { "chmod", "a+x", path.getCanonicalPath() }); } catch (Throwable e2) { } } } public int system(File wd, String[] command) throws CommandLineException { return system(wd, command, null); } public int system(File wd, String[] command, List args) throws CommandLineException { Commandline cli = new Commandline(); cli.setWorkingDirectory(wd); for (String c : command) { cli.createArg().setValue(c); } if( args!=null ) { for (String arg : args) { cli.createArg().setValue(arg); } } log.info("executing: "+cli); StreamConsumer consumer = new StreamConsumer() { public void consumeLine(String line) { log.info(line); } }; if( !verbose ) { consumer = new StringStreamConsumer(); } int rc = CommandLineUtils.executeCommandLine(cli, null, consumer, consumer); if( rc!=0 ) { if( !verbose ) { // We only display output if the command fails.. String output = ((StringStreamConsumer)consumer).getOutput(); if( output.length()>0 ) { String nl = System.getProperty( "line.separator"); String[] lines = output.split(Pattern.quote(nl)); for (String line : lines) { log.info(line); } } } log.info("rc: "+rc); } else { if( !verbose ) { String output = ((StringStreamConsumer)consumer).getOutput(); if( output.length()>0 ) { String nl = System.getProperty( "line.separator"); String[] lines = output.split(Pattern.quote(nl)); for (String line : lines) { log.debug(line); } } } log.debug("rc: "+rc); } return rc; } } GenerateMojo.java000066400000000000000000000263401142665006500346040ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009 Progress Software, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtjni.maven; import java.io.File; import java.io.IOException; import java.io.Reader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.interpolation.InterpolatorFilterReader; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.FileUtils.FilterWrapper; import org.fusesource.hawtjni.generator.HawtJNI; import org.fusesource.hawtjni.generator.ProgressMonitor; /** * This goal generates the native source code and a * autoconf/msbuild based build system needed to * build a JNI library for any HawtJNI annotated * classes in your maven project. * * @goal generate * @phase process-classes * @author Hiram Chirino */ public class GenerateMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * The directory where the generated native source files are located. * * @parameter default-value="${project.build.directory}/generated-sources/hawtjni/native-src" */ private File generatedNativeSourceDirectory; /** * The base name of the library, used to determine generated file names. * * @parameter default-value="${project.artifactId}" */ private String name; /** * The copyright header template that will be added to the generated source files. * Use the '%END_YEAR%' token to have it replaced with the current year. * * @parameter default-value="" */ private String copyright; /** * Restrict looking for JNI classes to the specified package. * * @parameter */ private List packages = new ArrayList(); /** * The directory where the java classes files are located. * * @parameter default-value="${project.build.outputDirectory}" */ private File classesDirectory; /** * The directory where the generated build package is located.. * * @parameter default-value="${project.build.directory}/generated-sources/hawtjni/native-package" */ private File packageDirectory; /** * The list of additional files to be included in the package will be * placed. * * @parameter default-value="${basedir}/src/main/native-package" */ private File customPackageDirectory; /** * The text encoding of the files. * * @parameter default-value="UTF-8" */ private String encoding; /** * Should we skip executing the autogen.sh file. * * @parameter default-value="${skip-autogen}" */ private boolean skipAutogen; /** * Should we force executing the autogen.sh file. * * @parameter default-value="${force-autogen}" */ private boolean forceAutogen; /** * Should we display all the native build output? * * @parameter default-value="${hawtjni-verbose}" */ private boolean verbose; /** * Extra arguments you want to pass to the autogen.sh command. * * @parameter */ private List autogenArgs; /** * Set this value to false to disable the callback support in HawtJNI. * Disabling callback support can substantially reduce the size * of the generated native library. * * @parameter default-value="true" */ private boolean callbacks; private File targetSrcDir; private CLI cli = new CLI(); public void execute() throws MojoExecutionException { cli.verbose = verbose; cli.log = getLog(); generateNativeSourceFiles(); generateBuildSystem(); } private void generateNativeSourceFiles() throws MojoExecutionException { HawtJNI generator = new HawtJNI(); generator.setClasspaths(getClasspath()); generator.setName(name); generator.setCopyright(copyright); generator.setNativeOutput(generatedNativeSourceDirectory); generator.setPackages(packages); generator.setCallbacks(callbacks); generator.setProgress(new ProgressMonitor() { public void step() { } public void setTotal(int total) { } public void setMessage(String message) { getLog().info(message); } }); try { generator.generate(); } catch (Exception e) { throw new MojoExecutionException("Native source code generation failed: "+e, e); } } private void generateBuildSystem() throws MojoExecutionException { try { packageDirectory.mkdirs(); new File(packageDirectory, "m4").mkdirs(); targetSrcDir = new File(packageDirectory, "src"); targetSrcDir.mkdirs(); if( customPackageDirectory!=null && customPackageDirectory.isDirectory() ) { FileUtils.copyDirectoryStructureIfModified(customPackageDirectory, packageDirectory); } if( generatedNativeSourceDirectory!=null && generatedNativeSourceDirectory.isDirectory() ) { FileUtils.copyDirectoryStructureIfModified(generatedNativeSourceDirectory, targetSrcDir); } copyTemplateResource("readme.md", false); copyTemplateResource("configure.ac", true); copyTemplateResource("Makefile.am", true); copyTemplateResource("m4/custom.m4", false); copyTemplateResource("m4/jni.m4", false); copyTemplateResource("m4/osx-universal.m4", false); // To support windows based builds.. copyTemplateResource("vs2008.vcproj", true); File autogen = new File(packageDirectory, "autogen.sh"); File configure = new File(packageDirectory, "configure"); if( !autogen.exists() ) { copyTemplateResource("autogen.sh", false); cli.setExecutable(autogen); } if( !skipAutogen ) { if( (!configure.exists() && !CLI.IS_WINDOWS) || forceAutogen ) { try { cli.system(packageDirectory, new String[] {"./autogen.sh"}, autogenArgs); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { throw new MojoExecutionException("Native build system generation failed: "+e, e); } } @SuppressWarnings("unchecked") private ArrayList getClasspath() throws MojoExecutionException { ArrayList artifacts = new ArrayList(); try { artifacts.add(classesDirectory.getCanonicalPath()); for (Artifact artifact : (Set) project.getArtifacts()) { File file = artifact.getFile(); getLog().debug("Including: " + file); artifacts.add(file.getCanonicalPath()); } } catch (IOException e) { throw new MojoExecutionException("Could not determine project classath.", e); } return artifacts; } private void copyTemplateResource(String file, boolean filter) throws MojoExecutionException { try { File target = FileUtils.resolveFile(packageDirectory, file); if( target.isFile() && target.canRead() ) { return; } URL source = getClass().getClassLoader().getResource("project-template/" + file); File tmp = FileUtils.createTempFile("tmp", "txt", new File(project.getBuild().getDirectory())); try { FileUtils.copyURLToFile(source, tmp); FileUtils.copyFile(tmp, target, encoding, filters(filter), true); } finally { tmp.delete(); } } catch (IOException e) { throw new MojoExecutionException("Could not extract template resource: "+file, e); } } @SuppressWarnings("unchecked") private FilterWrapper[] filters(boolean filter) throws IOException { if( !filter ) { return new FilterWrapper[0]; } final String startExp = "@"; final String endExp = "@"; final String escapeString = "\\"; final Map values = new HashMap(); values.put("PROJECT_NAME", name); values.put("PROJECT_NAME_UNDER_SCORE", name.replaceAll("\\W", "_")); values.put("VERSION", project.getVersion()); List files = new ArrayList(); files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.c", null, false)); files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.cpp", null, false)); files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.cxx", null, false)); String sources = ""; String xml_sources = ""; boolean first = true; for (String f : files) { if( !first ) { sources += "\\\n"; } else { values.put("FIRST_SOURCE_FILE", "src/"+f.replace('\\', '/')); first=false; } sources += " src/"+f; xml_sources+=" \n"; } values.put("PROJECT_SOURCES", sources); values.put("PROJECT_XML_SOURCES", xml_sources); FileUtils.FilterWrapper wrapper = new FileUtils.FilterWrapper() { public Reader getReader(Reader reader) { StringSearchInterpolator propertiesInterpolator = new StringSearchInterpolator(startExp, endExp); propertiesInterpolator.addValueSource(new MapBasedValueSource(values)); propertiesInterpolator.setEscapeString(escapeString); InterpolatorFilterReader interpolatorFilterReader = new InterpolatorFilterReader(reader, propertiesInterpolator, startExp, endExp); interpolatorFilterReader.setInterpolateWithPrefixPattern(false); return interpolatorFilterReader; } }; return new FilterWrapper[] { wrapper }; } } PackageJarMojo.java000066400000000000000000000201331142665006500350340ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009 Progress Software, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtjni.maven; import java.io.File; import java.util.List; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.archiver.jar.JarArchiver; import org.codehaus.plexus.archiver.jar.Manifest; import org.codehaus.plexus.archiver.jar.Manifest.Attribute; import org.codehaus.plexus.archiver.manager.ArchiverManager; import org.fusesource.hawtjni.runtime.Library; /** * This goal allows allows you to package the JNI library created by build goal * in a JAR which the HawtJNI runtime can unpack when the library needs to be * loaded. * * This platform specific jar is attached with a classifier which matches the * current platform. * * @goal package-jar * @phase package * @author Hiram Chirino */ public class PackageJarMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * The base name of the library, used to determine generated file names. * * @parameter default-value="${project.artifactId}" */ private String name; /** * @component * @required * @readonly */ private ArchiverManager archiverManager; /** * @component * @required * @readonly */ private MavenProjectHelper projectHelper; /** * The output directory where the built JNI library will placed. This * directory will be added to as a test resource path so that unit tests can * verify the built JNI library. * * The library will placed under the META-INF/native/${platform} directory * that the HawtJNI Library uses to find JNI libraries as classpath * resources. * * @parameter * default-value="${project.build.directory}/generated-sources/hawtjni/lib" */ private File libDirectory; /** * The platform identifier of this build. If not specified, * it will be automatically detected. This will be used as the * artifact classifier for the platform specific jar. * * @parameter default-value="${hawtjni-platform}" */ private String platform; /** * The osgi platforms that the library match for. Example value: * osname=MacOS;processor=x86-64 * * @parameter */ private List osgiPlatforms; public void execute() throws MojoExecutionException { try { Library library = new Library(name); if (platform == null || platform.trim().length()==0 ) { platform = library.getPlatform(); } String packageName = project.getArtifactId() + "-" + project.getVersion() + "-" + platform; JarArchiver archiver = (JarArchiver) archiverManager.getArchiver("jar"); File packageFile = new File(new File(project.getBuild().getDirectory()), packageName + ".jar"); archiver.setDestFile(packageFile); archiver.setIncludeEmptyDirs(true); archiver.addDirectory(libDirectory); Manifest manifest = new Manifest(); manifest.addConfiguredAttribute(new Attribute("Bundle-SymbolicName", project.getArtifactId() + "-" + platform)); manifest.addConfiguredAttribute(new Attribute("Bundle-Name", name + " for " + platform)); manifest.addConfiguredAttribute(new Attribute("Bundle-NativeCode", getNativeCodeValue(library))); manifest.addConfiguredAttribute(new Attribute("Bundle-Version", project.getVersion())); manifest.addConfiguredAttribute(new Attribute("Bundle-ManifestVersion", "2")); manifest.addConfiguredAttribute(new Attribute("Bundle-Description", project.getDescription())); archiver.addConfiguredManifest(manifest); archiver.createArchive(); projectHelper.attachArtifact(project, "jar", platform, packageFile); } catch (Exception e) { throw new MojoExecutionException("packageing failed: " + e, e); } } public String getNativeCodeValue(Library library) { if (osgiPlatforms == null || osgiPlatforms.isEmpty() ) { return library.getPlatformSpecifcResourcePath(platform) + ";" +"osname=" + getOsgiOSName() + ";processor=" + getOsgiProcessor()+ ",*"; } boolean first=true; String rc = ""; for (String s : osgiPlatforms) { if( !first ) { rc += ","; } first = false; if( "*".equals(s) ) { rc += s; } else { rc += library.getPlatformSpecifcResourcePath(platform) + ";"+s; } } return rc; } public String getOsgiOSName() { String name = System.getProperty("os.name"); String trimmed = name.toLowerCase().trim(); if (trimmed.startsWith("win")) { return "Win32"; } else if (trimmed.startsWith("linux")) { return "Linux"; } else if (trimmed.startsWith("macos") || trimmed.startsWith("mac os")) { return "MacOS"; } else if (trimmed.startsWith("aix")) { return "AIX"; } else if (trimmed.startsWith("hpux")) { return "HPUX"; } else if (trimmed.startsWith("irix")) { return "IRIX"; } else if (trimmed.startsWith("netware")) { return "Netware"; } else if (trimmed.startsWith("openbsd")) { return "OpenBSD"; } else if (trimmed.startsWith("netbsd")) { return "NetBSD"; } else if (trimmed.startsWith("os2") || trimmed.startsWith("os/2")) { return "OS2"; } else if (trimmed.startsWith("qnx") || trimmed.startsWith("procnto")) { return "QNX"; } else if (trimmed.startsWith("solaris")) { return "Solaris"; } else if (trimmed.startsWith("sunos")) { return "SunOS"; } else if (trimmed.startsWith("vxworks")) { return "VxWorks"; } return name; } public String getOsgiProcessor() { String name = System.getProperty("os.arch"); String trimmed = name.toLowerCase().trim(); if (trimmed.startsWith("x86-64") || trimmed.startsWith("amd64") || trimmed.startsWith("em64") || trimmed.startsWith("x86_64")) { return "x86-64"; } else if (trimmed.startsWith("x86") || trimmed.startsWith("pentium") || trimmed.startsWith("i386") || trimmed.startsWith("i486") || trimmed.startsWith("i586") || trimmed.startsWith("i686")) { return "x86"; } else if (trimmed.startsWith("68k")) { return "68k"; } else if (trimmed.startsWith("arm")) { return "ARM"; } else if (trimmed.startsWith("alpha")) { return "Alpha"; } else if (trimmed.startsWith("ignite") || trimmed.startsWith("psc1k")) { return "Ignite"; } else if (trimmed.startsWith("mips")) { return "Mips"; } else if (trimmed.startsWith("parisc")) { return "PArisc"; } else if (trimmed.startsWith("powerpc") || trimmed.startsWith("power") || trimmed.startsWith("ppc")) { return "PowerPC"; } else if (trimmed.startsWith("sparc")) { return "Sparc"; } return name; } } PackageSourceMojo.java000066400000000000000000000075401142665006500355670ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009 Progress Software, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtjni.maven; import java.io.File; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.archiver.Archiver; import org.codehaus.plexus.archiver.manager.ArchiverManager; /** * This goal creates a source zip file of the native build * module and attaches it to the build so that it can get * deployed. * * @goal package-source * @phase package * @author Hiram Chirino */ public class PackageSourceMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * @component * @required * @readonly */ private ArchiverManager archiverManager; /** * @component * @required * @readonly */ private MavenProjectHelper projectHelper; /** * The directory where the generated native files are located.. * * @parameter default-value="${project.build.directory}/generated-sources/hawtjni/native-package" */ private File packageDirectory; /** * The classifier of the package archive that will be created. * * @parameter default-value="native-src" */ private String sourceClassifier; /** * Should we skip executing the autogen.sh file. * * @parameter default-value="${skip-autogen}" */ private boolean skipAutogen; public void execute() throws MojoExecutionException { try { String packageName = project.getArtifactId()+"-"+project.getVersion()+"-"+sourceClassifier; File packageFile = new File(new File(project.getBuild().getDirectory()), packageName+".zip"); // Verify the the configure script got generated before packaging. File configure = new File(packageDirectory, "configure"); if( !skipAutogen && !configure.exists() ) { // Looks like this platform could not generate the // configure script. So don't install deploy // partially created source package. getLog().info(""); getLog().warn("Will NOT package the native sources to: "+packageFile); getLog().info(" Native source build directory did not contain a 'configure' script."); getLog().info(" To ignore this warnning and package it up anyways configure the plugin with: true"); getLog().info(""); return; } Archiver archiver = archiverManager.getArchiver( "zip" ); archiver.setDestFile( packageFile); archiver.setIncludeEmptyDirs(true); archiver.addDirectory(packageDirectory, packageName+"/"); archiver.createArchive(); projectHelper.attachArtifact( project, "zip", sourceClassifier, packageFile ); } catch (Exception e) { throw new MojoExecutionException("packageing failed: "+e, e); } } } hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/000077500000000000000000000000001142665006500250015ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/000077500000000000000000000000001142665006500302605ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/Makefile.am000066400000000000000000000021771142665006500323230ustar00rootroot00000000000000# --------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --------------------------------------------------------------------------- ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = lib@PROJECT_NAME@.la # lib@PROJECT_NAME_UNDER_SCORE@_la_CFLAGS = #lib@PROJECT_NAME_UNDER_SCORE@_la_LDFLAGS = lib@PROJECT_NAME_UNDER_SCORE@_la_SOURCES =@PROJECT_SOURCES@ hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/autogen.sh000077500000000000000000000030061142665006500322600ustar00rootroot00000000000000#!/bin/sh # --------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --------------------------------------------------------------------------- auto_clean() { AUTO_FILES=" configure config.log config.status autom4te.cache autotools aclocal.m4 libtool m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 Makefile.in Makefile src/Makefile src/Makefile.in src/config.in src/config.h src/config.h.in* src/stamp-h1 " for f in "$AUTO_FILES" ; do rm -Rf $f done } auto_reconf() { autoreconf --force --install -I m4 } case "$1" in clean) echo "auto clean..." auto_clean ;; *) echo "auto reconf..." auto_clean auto_reconf ;; esac hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/configure.ac000066400000000000000000000041121142665006500325440ustar00rootroot00000000000000# --------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --------------------------------------------------------------------------- ## -------------------------------- ## Initialization macros. ## -------------------------------- AC_PREREQ([2.61]) AC_INIT([@PROJECT_NAME@], [@VERSION@]) AC_CONFIG_AUX_DIR([autotools]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([@FIRST_SOURCE_FILE@]) AC_CONFIG_HEADERS([src/config.h]) AC_CANONICAL_HOST AC_CANONICAL_SYSTEM ## ----------------------------------------------- ## Application Checks ## ----------------------------------------------- AC_PROG_CC AC_PROG_INSTALL AC_PROG_LIBTOOL([disable-static]) ## ----------------------------------------------- ## API Checks ## ----------------------------------------------- WITH_JNI_JDK CUSTOM_M4_SETUP WITH_OSX_UNIVERSAL CFLAGS="$CFLAGS $JNI_EXTRA_CFLAGS" AC_SUBST(CFLAGS) LDFLAGS="$LDFLAGS $JNI_EXTRA_LDFLAGS -release @VERSION@" AC_SUBST(LDFLAGS) ## ----------------------------------------------------- ## Generate the files ## ----------------------------------------------------- AM_INIT_AUTOMAKE([no-dependencies -Wall -Werror foreign]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT echo " ($PACKAGE_NAME) version $PACKAGE_VERSION Prefix.........: $prefix C Compiler.....: $CC $CFLAGS Linker.........: $LD $LDFLAGS $LIBS "hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/m4/000077500000000000000000000000001142665006500306005ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/m4/custom.m4000066400000000000000000000020331142665006500323520ustar00rootroot00000000000000dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009 Progress Software, Inc. dnl http://fusesource.com dnl dnl Licensed under the Apache License, Version 2.0 (the "License"); dnl you may not use this file except in compliance with the License. dnl You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl --------------------------------------------------------------------------- AC_DEFUN([CUSTOM_M4_SETUP], [ # # This is just a stub. If you wish to customize your configure.ac # just copy this file to src/main/native-package/m4/custom.m4 # then replace add your configure.ac statements here. # ])hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/m4/jni.m4000066400000000000000000000126571142665006500316350ustar00rootroot00000000000000dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009 Progress Software, Inc. dnl http://fusesource.com dnl dnl Licensed under the Apache License, Version 2.0 (the "License"); dnl you may not use this file except in compliance with the License. dnl You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl --------------------------------------------------------------------------- dnl --------------------------------------------------------------------------- dnl SYNOPSIS: dnl dnl WITH_JNI_JDK() dnl dnl Adds the --with-jni-jdk=PATH option. If not provided, it searches dnl for the JDK in the default OS locations. dnl dnl This macro calls: dnl AC_SUBST(JNI_JDK) dnl AC_SUBST(JNI_EXTRA_CFLAGS) dnl AC_SUBST(JNI_EXTRA_LDFLAGS) dnl dnl AUTHOR: Hiram Chrino dnl --------------------------------------------------------------------------- AC_DEFUN([WITH_JNI_JDK], [ AC_PREREQ([2.61]) AC_ARG_WITH(jni-jdk, [AS_HELP_STRING([--with-jni-jdk=PATH], [Location of the Java Development Kit. Defaults to your JAVA_HOME setting and falls back to where it is typically installed on your OS])], [ if test "$withval" = "no" || test "$withval" = "yes"; then AC_MSG_ERROR([--with-jni-jdk: PATH to JDK not supplied]) fi CHECK_JNI_JDK([$withval], [], [AC_MSG_ERROR([JDK not found. Invalid --with-jni-jdk PATH])]) ],[ if test -n "$JAVA_HOME" ; then AC_MSG_NOTICE([JAVA_HOME was set, checking to see if it's a JDK we can use...]) CHECK_JNI_JDK([$JAVA_HOME], [], []) fi __JNI_GUESS=`which javac` AS_IF(test -z "$JNI_JDK" && test -n "$__JNI_GUESS", [ AC_MSG_NOTICE([javac was on your path, checking to see if it's part of a JDK we can use...]) # transitively resolve the symbolic links to javac while file -h "$__JNI_GUESS" 2>/dev/null | grep " symbolic link to " >/dev/null; do __JNI_LINK=$( file -h $__JNI_GUESS | sed 's/.*symbolic link to //' | sed "s/'$//" | sed 's/^`//' ) __JNI_GUESS=$(cd $(dirname $__JNI_GUESS); cd $(dirname $__JNI_LINK); echo "$(pwd)/$(basename $__JNI_LINK)") done # move 2 dirs up to the home dir... __JNI_GUESS=$(dirname $(dirname $__JNI_GUESS)) CHECK_JNI_JDK([$__JNI_GUESS], [], [],[]) ],[]) AS_IF(test -z "$JNI_JDK", [ case "$host_os" in darwin*) __JNI_GUESS="/System/Library/Frameworks/JavaVM.framework";; *) __JNI_GUESS="/usr";; esac AC_MSG_NOTICE([Taking a guess as to where your OS installs the JDK by default...]) CHECK_JNI_JDK([$__JNI_GUESS], [], [AC_MSG_ERROR([JDK not found. Please use the --with-jni-jdk option])]) ],[]) ]) ]) dnl --------------------------------------------------------------------------- dnl dnl JNI_CHECK_JDK_HOME(PATH, [ACTION-SUCCESS], [ACTION-FAILURE]) dnl dnl Tests to see if the given path is a valid JDK home location with dnl with a JNI headers and library that can be compiled against. dnl dnl This macro calls: dnl dnl AC_SUBST(JNI_JDK) dnl AC_SUBST(JNI_EXTRA_CFLAGS) dnl AC_SUBST(JNI_EXTRA_LDFLAGS) dnl dnl AUTHOR: Hiram Chrino dnl --------------------------------------------------------------------------- AC_DEFUN([CHECK_JNI_JDK],[ AC_PREREQ([2.61]) __JNI_JDK_HOME="$1" AC_MSG_CHECKING(if '$__JNI_JDK_HOME' is a JDK) # OSX had to be a little different. case "$host_os" in darwin*) __JNI_INCLUDE="$__JNI_JDK_HOME/Headers";; *) __JNI_INCLUDE="$__JNI_JDK_HOME/include";; esac AS_IF(test -r "$__JNI_INCLUDE/jni.h",[ # Also include the os specific include dirs in the JNI_CFLAGS __JNI_CFLAGS="-I$__JNI_INCLUDE" case "$host_os" in bsdi*) __JNI_INCLUDE_EXTRAS="bsdos";; linux*) __JNI_INCLUDE_EXTRAS="linux genunix";; osf*) __JNI_INCLUDE_EXTRAS="alpha";; solaris*) __JNI_INCLUDE_EXTRAS="solaris";; mingw*) __JNI_INCLUDE_EXTRAS="win32";; cygwin*) __JNI_INCLUDE_EXTRAS="win32";; *) __JNI_INCLUDE_EXTRAS="genunix";; esac for f in $__JNI_INCLUDE_EXTRAS ; do if test -d "$__JNI_INCLUDE/$f"; then __JNI_CFLAGS="$__JNI_CFLAGS -I$__JNI_INCLUDE/$f" fi done saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $__JNI_CFLAGS" JNI_VERSION="1_2" AC_LANG_PUSH(C) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[@%:@include ]],[[ #ifndef JNI_VERSION_$JNI_VERSION # error JNI version $JNI_VERSION is not supported. #endif ]]) ],[ JNI_JDK=$"$__JNI_JDK_HOME" JNI_EXTRA_CFLAGS="$__JNI_CFLAGS" AC_SUBST(JNI_JDK) AC_SUBST(JNI_EXTRA_CFLAGS) case $host_os in darwin*) JNI_EXTRA_LDFLAGS="-shrext .jnilib -dynamiclib" ;; esac AC_SUBST(JNI_EXTRA_LDFLAGS) AC_MSG_RESULT([yes]) $2 ],[ AC_MSG_RESULT([no]) $3 ]) AC_LANG_POP() CPPFLAGS="$saved_CPPFLAGS" ],[ AC_MSG_RESULT([no]) $3 ]) ]) osx-universal.m4000066400000000000000000000054371142665006500336130ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/m4dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009 Progress Software, Inc. dnl http://fusesource.com dnl dnl Licensed under the Apache License, Version 2.0 (the "License"); dnl you may not use this file except in compliance with the License. dnl You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl --------------------------------------------------------------------------- dnl --------------------------------------------------------------------------- dnl SYNOPSIS: dnl dnl WITH_OSX_UNIVERSAL() dnl dnl Allows creating universal binaries on the dnl dnl Adds the --with-universal=ARCH option. This will will dnl set sysroot option to /Developer/SDKs/MacOSX${OSX_VERSION}.sdk. dnl if OSX_VERSION is not defined, it will set it to 10.5 (the first dnl release where intel universal binaries were supported) dnl dnl You must use the no-dependencies option when automake is initialized. dnl for example: AM_INIT_AUTOMAKE([no-dependencies]) dnl dnl This macro calls: dnl AC_SUBST(CFLAGS) dnl AC_SUBST(LDFLAGS) dnl AC_SUBST(MAC_OSX_VERSION) dnl dnl AUTHOR: Hiram Chrino dnl --------------------------------------------------------------------------- AC_DEFUN([WITH_OSX_UNIVERSAL], [ AC_PREREQ([2.61]) case "$host_os" in darwin*) AS_IF(test -z "$OSX_VERSION", [ OSX_VERSION="10.5" AC_SUBST(OSX_VERSION) ]) AC_MSG_CHECKING(whether to build universal binaries) AC_ARG_WITH([universal], [AS_HELP_STRING([--with-universal@<:@=ARCH@:>@], [Build a universal binary. Set to a space separated architecture list. Pick from: i386, x86_64, ppc, and/or ppc64. @<:@default="i386 x86_64 ppc"@:>@])], [ AS_IF(test "$withval" = "no", [ OSX_UNIVERSAL="" AC_MSG_RESULT([no]) ], test "$withval" = "yes", [ OSX_UNIVERSAL="i386 x86_64 ppc" AC_MSG_RESULT([yes, archs: $OSX_UNIVERSAL]) ],[ OSX_UNIVERSAL="$withval" AC_MSG_RESULT([yes, archs: $OSX_UNIVERSAL]) ]) ],[ OSX_UNIVERSAL="" AC_MSG_RESULT([no]) ]) AS_IF(test -n "$OSX_UNIVERSAL", [ for i in $OSX_UNIVERSAL ; do CFLAGS="-arch $i $CFLAGS" LDFLAGS="-arch $i $LDFLAGS" done CFLAGS="-isysroot /Developer/SDKs/MacOSX${OSX_VERSION}.sdk $CFLAGS" LDFLAGS="-syslibroot,/Developer/SDKs/MacOSX${OSX_VERSION}.sdk $LDFLAGS" AC_SUBST(CFLAGS) AC_SUBST(LDFLAGS) ]) ;; esac ]) hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/readme.md000066400000000000000000000024311142665006500320370ustar00rootroot00000000000000Building on Unix/Linux/OS X --------------------------- The configure script will customize the way the software is built and installed into your system along with detecting the available libraries that have been installed. To use the default configuration just run: ./configure For more help on how to customize the build configuration, run: ./configure --help Once the configure script has run successfully, you are ready to build. Run: make This will build all of the core ActiveMQ CPP source code. To build and install the code into the system directories, run: make install You will have to become the superuser in order to be able to install the JNI libraries. Building on Windows ------------------- Download and install the free [Microsoft Windows SDK][1]. The SDK includes all the headers, libraries, and build tools needed to compile the JNI library. Set the `JAVA_HOME` environment variable to the location where your JDK is installed. Use the "Start>All Programs>Microsoft Windows SDK vX.X>CMD" command window and change to the directory that this file is located in and then run: vcbuild The dll files will be located under the target directory. [1]: http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505hawtjni-1.0~+git0c502e20c4/maven-hawtjni-plugin/src/main/resources/project-template/vs2008.vcproj000077500000000000000000000165061142665006500324620ustar00rootroot00000000000000 @PROJECT_XML_SOURCES@ hawtjni-1.0~+git0c502e20c4/pom.xml000066400000000000000000000247141142665006500165350ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-pom 1.1-SNAPSHOT pom HawtJNI A JNI code generator based on the JNI generator used by the eclipse SWT project hawtjni HAWTJNI UTF-8 scm:git:ssh://git@forge.fusesource.com/${forge-project-id}.git http://${forge-project-id}.fusesource.org 2009 Progress Software Inc. http://fusesource.com/ jira http://fusesource.com/issues/browse/${forge-project-id-uc} ${forge-project-id} dev ${forge-project-id}-dev@fusesource.org ${forge-project-id}-dev-subscribe@fusesource.org ${forge-project-id} commits ${forge-project-id}-commits@fusesource.org ${forge-project-id}-commits-subscribe@fusesource.org Eclipse Public License - v 1.0 http://www.eclipse.org/legal/epl-v10.html repo The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:git:git://forge.fusesource.com/${forge-project-id}.git ${release-altGitURL} http://fusesource.com/forge/gitweb?p=${forge-project-id}.git fusesource-nexus-staging Fusesource Release Repository http://repo.fusesource.com/nexus/service/local/staging/deploy/maven2 fusesource-nexus-snapshots Fusesource Nexus Snapshots http://repo.fusesource.com/nexus/content/repositories/snapshots website.fusesource.org website dav:http://fusesource.com/forge/dav/${forge-project-id}/maven/${project.version} chirino Hiram Chirino hiram@hiramchirino.com http://hiramchirino.com GMT-5 install org.apache.maven.wagon wagon-webdav-jackrabbit 1.0-beta-6 maven-compiler-plugin 2.1 1.5 1.5 org.apache.maven.plugins maven-idea-plugin 2.2 true true org.apache.maven.plugins maven-eclipse-plugin 2.5.1 true true org.apache.maven.plugins maven-surefire-plugin 2.4.3 false org.apache.maven.plugins maven-release-plugin 2.0 true false clean install deploy -Prelease org.apache.maven.plugins maven-scm-plugin 1.3 org.apache.maven.scm maven-scm-provider-gitexe 1.3 org.codehaus.mojo jxr-maven-plugin 2.0-beta-1 true org.apache.maven.plugins maven-javadoc-plugin 2.6.1 *.internal true http://java.sun.com/j2se/1.5.0/docs/api org.apache.maven.plugins maven-project-info-reports-plugin 2.1.1 index sumary plugins dependencies mailing-list issue-tracking license scm org.codehaus.mojo surefire-report-maven-plugin 2.0-beta-1 org.apache.maven.plugins maven-plugin-plugin 2.5 graph mvnplugins.fusesource.org http://mvnplugins.fusesource.org/repo/release true org.fusesource.mvnplugins maven-graph-plugin 1.2 release org.apache.maven.plugins maven-gpg-plugin 1.0 ${gpg.passphrase} sign org.apache.maven.plugins maven-source-plugin 2.1.1 attach-sources jar-no-fork org.apache.maven.plugins maven-javadoc-plugin 2.6 ${project.build.sourceEncoding} attach-javadocs jar hawtjni-runtime hawtjni-generator maven-hawtjni-plugin hawtjni-example hawtjni-1.0~+git0c502e20c4/readme.md000066400000000000000000000053361142665006500167760ustar00rootroot00000000000000HawtJNI ========== Description ----------- [HawtJNI][1] is a code generator that produces the JNI code needed to implement java native methods. It is based on the [jnigen][2] code generator that is part of the SWT Tools project which is used to generate all the JNI code which powers the eclipse platform. Features -------- * jni code generated from annotations on your java code * maven integration Synopsis -------- There are many open source JNI code generators available, but if your performance sensitive, the code generator used by the eclipse SWT project is by far the best option. The biggest problem is that it was not developed to be reused by other projects. It was tightly coupled to producing the SWT jni libraries and it could only be run within the eclipse platform. HawtJNI takes that code generator and makes it more generally accessible to any project. Example Usage ------------- Your JNI methods must be defined as static native methods in a class annotated with `@JniClass`. The following example will expose the C `open` function as a java method: @JniClass public class Platform { public static native long open (String file, int flags, int mode); } You will also need to tell the JVM to load the native library when your class is loaded. You can do this using the standard `System.loadLibrary` method: @JniClass public class Platform { static { System.loadLibrary("hawtjni-example"); } public static native long open (String file, int flags, int mode); } If you want to bundle the native library in as a resource of your jar, so that it can be automatically unpacked if it cannot be be found in your java library path. Then a better option is to use the `Library` helper class that HawtJNI provides: @JniClass public class Platform { private static Library library = new Library("hawtjni-example", 1, 0, 0); static { library.load(); } public static native long open (String file, int flags, int mode); } To generate the JNI code, first compile your annotated class, then use the `hawtjni-generate.jar` runnable jar as follows: java -jar hawtjni-generate.jar -o target/native target/classes The above example expects your compiled java classes to be in the `target/classes` directory. The generated JNI classes will be placed in the `target/native` directory. Readme TODO ----------- * Need to explain/show examples of struct handling * Need to explain/show examples of 32/64 bit variable types * Show the maven plugin * Show the OSX cocoa native code generation tool [1]: http://github.com/chirino/mvnplugins/tree/master/hawtjni "HawtJNI" [2]: http://www.eclipse.org/swt/jnigen.php hawtjni-1.0~+git0c502e20c4/webgen/000077500000000000000000000000001142665006500164575ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/.gitignore000066400000000000000000000001141142665006500204430ustar00rootroot00000000000000out webgen.cache .sitecopyrc.tmp .sitecopy.tmp .DS_Store *.iml *.ipr *.iws hawtjni-1.0~+git0c502e20c4/webgen/README000077500000000000000000000032741142665006500173500ustar00rootroot00000000000000description: This skeleton of a webgen website provides a set of default files for every created webgen website. When using the standard settings, the sources are in the directory `src` and the generated output goes into `out`. Extensions can be placed under `ext`. For configuration purposes, use the config.rb or config.yaml files. --- note: This file can be deleted! Prerequisites: Webgen is known to work with: Ruby 1.8.6 and RubyGems 1.3.4 If you have an older version of RubyGems (check by running 'gem --version'), you can upgrade it by running: sudo gem install rubygems-update sudo update_rubygems You may also need to clear out your previously installed gems. On OSX, you would run: sudo rm -Rf ~/.gem /Library/Ruby/Gems/1.8/* Installing: sudo gem install webgen coderay feedtools haml RedCloth sudo easy_install Pygments Configuring: * edit the src/metainfo file to change the variables to your project specific values (such as the project name, source code locations & JIRA etc) * edit Rakefile to specify the project id (lower case) which is used for deploying the site Generating the site: webgen open out/index.html Auto mode: rake auto will run webgen in auto mode where it will auto-detect changes in the source files and regenerate the site automatically for you. Cleaning up: rake clobber Deploying: * to be able to deploy the site you will need to install sitecopy sudo port install sitecopy * to deploy the site run rake upload To see how to use Continuous Integration with this build see: http://fusesource.com/wiki/display/FUSEFORGE/Deploy+Webgen+Sites+using+Continuous+Integration hawtjni-1.0~+git0c502e20c4/webgen/Rakefile000066400000000000000000000101161142665006500201230ustar00rootroot00000000000000# NOTE - YOU MUST EDIT THE CHANGEME LINE BELOW!!! # # ## -*- ruby -*- # # This is a sample Rakefile to which you can add tasks to manage your website. For example, users # may use this file for specifying an upload task for their website (copying the output to a server # via rsync, ftp, scp, ...). # # It also provides some tasks out of the box, for example, rendering the website, clobbering the # generated files, an auto render task,... # require 'webgen/webgentask' require 'webgen/website' # couldn't figure out how to use the autoload stuff! :) require 'ext/fuse/sitecopy_rake.rb' # TODO must change this to the actual project! # one day it would be nice to find this from the src/metainfo file # # NOTE this file is the lower case name used to find the WebDAV location!! project_id = "hawtjni" task :default => :webgen task :rebuild => [:clobber, :webgen] task :upload => ["sitecopy:upload"] task :reupload => ["sitecopy:clobber", "sitecopy:upload"] task :deploy => ["sitecopy:clobber", :webgen, "sitecopy:upload", :linkcheck] task :auto => :auto_webgen Webgen::WebgenTask.new do |website| website.clobber_outdir = true website.config_block = lambda do |config| # you can set configuration options here end end desc "Render the website automatically on changes" task :auto_webgen do puts 'Starting auto-render mode' time = Time.now abort = false old_paths = [] Signal.trap('INT') {abort = true} while !abort # you may need to adjust the glob so that all your sources are included paths = Dir['src/**/*'].sort if old_paths != paths || paths.any? {|p| File.mtime(p) > time} Rake::Task['webgen'].execute({}) end time = Time.now old_paths = paths sleep 2 end end # lets parse a file from ~/.fuseforge.rc # username anonymous # password foo@bar.example def get_username_pwd userpwd = "" userpwd_file_name = File.expand_path("~/.fuseforge.rc") #puts "Looking for file #{userpwd_file_name}" #userpwd_file_name = "/Users/jstrachan/.fuseforge.rc" if File.file?(userpwd_file_name) userpwd = IO.readlines(userpwd_file_name).join("") #puts "User file is #{userpwd}" end userpwd.strip end # lets not use safe mode due to timestamp wierdness #safe Fuse::SitecopyTask.new("forgesite", <<-SITECOPYRC) server fusesource.com protocol http #{get_username_pwd} local out remote /forge/dav/#{project_id} state checksum exclude /maven exclude /repo exclude /ignore exclude /ignore ignore /maven ignore /repo ignore /.htaccess exclude /.htaccess SITECOPYRC desc "checks the links on the deployed site" task :linkcheck do puts 'Generating linkerrors.html file using the linkchecker executable from (http://linkchecker.sourceforge.net)' params = "--ignore-url=\"(http://localhost|^git|^ssh|^mailto)\" http://#{project_id}.fusesource.org/" htmlcmd = "linkchecker -o html #{params} > linkerrors.html" puts htmlcmd system htmlcmd puts "##teamcity[publishArtifacts 'webgen/linkerrors.html']" puts '' puts 'Starting link checking' system "linkchecker #{params} > linkerrors.log" pat = /.* (\d+) warnings? found.* (\d+) errors? found.*/ text = File.read("linkerrors.log") match = pat.match(text) if match == nil puts "##teamcity[buildStatus status='FAILURE' text='LinkChecker failed to find the number of warnings and errors in linkerrors.log. See build artifact: linkerrors.html']" exit end warnings = match[1] errors = match[2] if has_value(warnings) puts "##teamcity[errorDetails='LinkChecker found some bad HTML links! #{warnings} warnings. See build artifact: linkerrors.html' status='WARNING']" end if has_value(errors) puts "##teamcity[errorDetails='LinkChecker found some bad HTML links! #{errors} errors. See build artifact: linkerrors.html' status='FAILURE']" end if has_value(warnings) or has_value(errors) puts "##teamcity[buildStatus status='FAILURE' text='LinkChecker found some bad HTML links! #{warnings} warnings and #{errors} errors. See build artifact: linkerrors.html']" exit 1 end end def has_value(text) text != nil and text != "" and text != "0" endhawtjni-1.0~+git0c502e20c4/webgen/config.yaml000066400000000000000000000013361142665006500206130ustar00rootroot00000000000000# This is the YAML configuration file for webgen used to set configuration options. # # The general syntax is: # # configuration.option.name: value # # For example, to set a different default language, you would do: # # website.lang: de # # Have a look at the documentation of the individual configuration options to see # the allowed format of the values. Since this is a YAML file, you can easily set # configuration options to strings, integers, dates, arrays, hashes and more. # # The available configuration options can be listed using the `webgen config` # command, for example: `webgen config sourcehandler` will list all options starting # with sourcehandler. # lets turn off line numbers tag.coderay.line_numbers: false hawtjni-1.0~+git0c502e20c4/webgen/ext/000077500000000000000000000000001142665006500172575ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/ext/fuse/000077500000000000000000000000001142665006500202215ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/ext/fuse/asciidoc.rb000066400000000000000000000024071142665006500223270ustar00rootroot00000000000000# # Depends on hte mizuho gem. To install it: # gem install --source http://gems.github.com FooBarWidget-mizuho module Fuse # Processes content in AsciiDoc markup using the +asciidoc+ command class AsciiDoc # Convert the content in +AsciiDoc+ markup to HTML. def call(context) require 'mizuho/generator' require 'tempfile' # # This shells out to the asciidoc python tool so we have to pass the content via # temp files. # ascii_doc_in = Dir::tmpdir + "/ascii_doc."+ $$.to_s() +".in" ascii_doc_out = Dir::tmpdir + "/ascii_doc."+ $$.to_s() +".out" File.open(ascii_doc_in, 'w') do |f| f.write(context.content) end # Generate the HTML Mizuho::Generator.run_asciidoc(ascii_doc_in, ascii_doc_out) File.unlink(ascii_doc_in); # Strip off the asciidoc layout and just get the contents. parser = Mizuho::Parser.new(ascii_doc_out); File.unlink(ascii_doc_out); context.content = "
"+parser.contents+"
"; context rescue Exception => e raise RuntimeError, "Error converting AsciiDoc markup to HTML in <#{context.ref_node.absolute_lcn}>: #{e.message}\n#{e.backtrace.join("\n")}" end end end hawtjni-1.0~+git0c502e20c4/webgen/ext/fuse/pygmentize.rb000066400000000000000000000037241142665006500227470ustar00rootroot00000000000000# # Depends on Pygments. To install it: # sudo easy_install Pygments # module Fuse # Provides syntax highlighting via the pygmentize tool. class Pygmentize include Webgen::Tag::Base include Webgen::WebsiteAccess # Highlight the body of the block. def call(tag, body, context) # figure out the indent level of the tag last_line = body.split(/\r?\n/).last tag_indent = "" if( last_line.match(/^[ \t]+$/) ) tag_indent = last_line end # Strip off the tag_indent... if( tag_indent.size > 0 ) buffer = "" for i in body.split(/\r?\n/) buffer += i.sub(/^[ \t]{#{tag_indent.size}}/, "")+"\n" end body = buffer.chomp end # Execute the pygmentize tool lang = param('fuse.pygmentize.lang') lines = param('fuse.pygmentize.lines') ? ",linenos=1" : "" result="" IO.popen("pygmentize -O 'style=colorful#{lines}' -f html -l #{lang}", 'r+') do |pipe| pipe.print body pipe.close_write result = pipe.read end if $? != 0 raise Exception, "'pygmentize' execution failed: #{$?}. Did you install it from http://pygments.org/download/ ?" end # Apply white space preservation.. result = result.gsub(/\r?\n/, " ") # Format the result result = "#{tag_indent}
#{result}
\n" rescue Exception => e raise RuntimeError, "Error processing the pygmentize tag <#{context.ref_node.absolute_lcn}>: #{e.message}\n#{e.backtrace.join("\n")}" end end Webgen::WebsiteAccess.website.config.fuse.pygmentize.lang('text', :doc => 'The highlighting language', :mandatory => 'default') Webgen::WebsiteAccess.website.config.fuse.pygmentize.lines(false, :doc => 'Should line numbers be shown') Webgen::WebsiteAccess.website.config['contentprocessor.tags.map']['pygmentize'] = 'Fuse::Pygmentize' end hawtjni-1.0~+git0c502e20c4/webgen/ext/fuse/sitecopy_rake.rb000066400000000000000000000054641142665006500234200ustar00rootroot00000000000000#!/usr/bin/env ruby # # (c) 2006-2008, Levin Alexander # # This library is released under the same license as ruby itself. # module Fuse #:nodoc: # This is an interface to the sitecopy program # # it uses sitecopy to keep a local directory syncronized with # a FTP or webDAV server # # Example usage # ------------- # # rcfile = <<-EOF # server ftp.example.com # username example # password 12345 # ... # EOF # t = Rake::SitecopyTask.new("site", rcfile) # # it generates rake tasks to download, upload or check the # contents on the remote server # # see `rake --tasks` for information the generated rules # class SitecopyTask def initialize(name, rcfile) @site = name # Sitecopy configuration @rc = "site #{@site}\n" << rcfile @rcfile = ".sitecopyrc.tmp" @state_dir = ".sitecopy.tmp" # sitecopy-command @sitecopy = "sitecopy -r #{@rcfile} -p #{@state_dir} " define end def fetch sh "#{@sitecopy} --fetch #{@site}" end # list all differences between the local files and the # remote copy # def list sh "#{@sitecopy} --list #{@site}" end # update the remote copy of this site # def upload sh "#{@sitecopy} --update #{@site}" end # update the local site from the remote copy # WARNING: this will overwrite local files # def download sh "#{@sitecopy} --synchronize #{@site}" end def define namespace :sitecopy do # Create sitecopy .rcfile task @rcfile do File.open(@rcfile,"w+", 0600) { |f| f.write(@rc) } end # Create sitecopy storage directory file @state_dir do Dir.mkdir(@state_dir, 0700) fetch # check state on server end # Remove sitecopy configfile and state cache desc "Clean temporary files" task :clobber do rm_r @state_dir rescue nil rm @rcfile rescue nil end task :prepare => [@rcfile, @state_dir] desc "Resyncronize sitecopy state with remote server" task :check_server => [:clobber, :prepare] do list end desc "List changes between local directory and remote server" task :list => [:prepare] do list end desc "Fetches the remote site" task :fetch => [:prepare] do fetch end task "upload_#{@site}" => [:prepare] do upload end desc "Upload all sites to remote server" task :upload => ["upload_#{@site}"] task "download_#{@site}" => [:prepare] do download end desc "Download all sites from remote server" task :download => ["download_#{@site}"] end end end end hawtjni-1.0~+git0c502e20c4/webgen/ext/init.rb000066400000000000000000000017051142665006500205520ustar00rootroot00000000000000# = webgen extensions directory # # All init.rb files anywhere under this directory get automatically loaded on a webgen run. This # allows you to add your own extensions to webgen or to modify webgen's core! # # If you don't need this feature you can savely delete this file and the directory in which it is! # # The +config+ variable below can be used to access the Webgen::Configuration object for the current # website. $LOAD_PATH << File.dirname(__FILE__) load 'fuse/asciidoc.rb' load 'fuse/pygmentize.rb' #load 'fuse/sitecopy_rake.rb' config = Webgen::WebsiteAccess.website.config config['contentprocessor.map']['asciidoc'] = 'Fuse::AsciiDoc' module Fuse autoload :AsciiDoc, 'fuse/asciidoc' end # # Custom HAML filter which is like the plain filter, # but which also does not indent the block. # require 'haml' module Haml::Filters::Raw include Haml::Filters::Base def render_with_options(text, options) options[:ugly]=true text end end hawtjni-1.0~+git0c502e20c4/webgen/src/000077500000000000000000000000001142665006500172465ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/blog/000077500000000000000000000000001142665006500201715ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/blog/index.feed000066400000000000000000000001511142665006500221220ustar00rootroot00000000000000--- entries: [*/**/*.html] site_url: http://exmaple.org/blog author: MyProject title: The MyProject Blog hawtjni-1.0~+git0c502e20c4/webgen/src/blog/index.page000077500000000000000000000022311142665006500221370ustar00rootroot00000000000000--- title: Blog in_menu: false sort_info: 7 --- name:head pipeline:tags --- name:overview

{project_name:} Blog

Updates you can't afford to miss! --- name:blog pipeline:erb,tags,blocks <% max_posts_per_page = 10; pattern = /#{File.join(context.node.parent.alcn, '/')}.*\.html$/ nodes = context.content_node.tree.node_access[:path].select {|path, n| path =~ pattern}; nodes.sort.reverse.slice(0,max_posts_per_page).each do |path, n| next if n.is_fragment? next if !n['blog_post'] %>

<%= context.dest_node.link_to(n) %>

Posted by <%= n['author']%> on <%= n['created_at']%>

<% if n.node_info[:page].blocks.has_key?('full_story') %>
<%= context.dest_node.link_to(n, {:link_text=>"Read more..."}) %>
<% end %>
<% end %> hawtjni-1.0~+git0c502e20c4/webgen/src/blog/releases/000077500000000000000000000000001142665006500217745ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/blog/releases/release-1_0_0.page.sample000066400000000000000000000005701142665006500263300ustar00rootroot00000000000000--- blog_post: true title: MyProject 1.0.0 Released author: Hiram Chirino author_url: http://hiramchirino.com created_at: 2008-08-02 14:06:40.000000 -06:00 --- The MyProject team is pleased to announce the availability of MyProject 1.0.0 This release includes a number of bug fixes and improvements. For more informations, please see the [release notes](http://example.com) hawtjni-1.0~+git0c502e20c4/webgen/src/blog/releases/release-1_0_1.page.sample000066400000000000000000000006641142665006500263350ustar00rootroot00000000000000--- blog_post: true title: MyProject 1.0.1 Released author: Hiram Chirino author_url: http://hiramchirino.com created_at: 2008-08-02 14:06:40.000000 -06:00 modified_at: 2008-08-02 14:06:40.000000 -06:00 draft: false --- The MyProject team is pleased to announce the availability of MyProject 1.0.1 This release includes a number of bug fixes and improvements. For more informations, please see the [release notes](http://example.com) hawtjni-1.0~+git0c502e20c4/webgen/src/building.page000066400000000000000000000033251142665006500217040ustar00rootroot00000000000000--- title: Building --- name:overview # How to Build {project_name:} The way most developers get started contributing to a project. --- name:content ## Building {project_name:} uses [Maven](http://maven.apache.org/) as its build tool. If you don't fancy using Maven you can use your IDE directly or [Download](download.html) a distribution or JAR. Alternatively you can try using [sbt](sbt.html) which is particularly good for rapid edit-compile-test cycles ### Prequisites *Required:* * Download and [install Maven](http://maven.apache.org/download.html) * Get the latest [Source](source.html) * Java 1.5 ### Maven options To build {project_name:} maven has to be configured to use more memory set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m ### A normal build mvn install ### Doing a Quick Build The following avoids running all the unit test cases, we just skip the test running phase and not the building part mvn -Dtest=false clean install ### Using an IDE If you prefer to use an IDE then you can auto-generate the IDE's project files using maven plugins. e.g. mvn eclipse:eclipse or mvn idea:idea ### Importing into Eclipse If you have not already done so, you will need to make Eclipse aware of the Maven repository so that it can build everything. In the preferences, go to `Java -> Build Path -> Classpath` and define a new Classpath Variable named `M2_REPO` that points to your local Maven repository. i.e. `~/.m2/repository` on Unix and `c:\Documents and Settings\$username\.m2\repository` on Windows). You can also get Maven to do this for you: mvn eclipse:add-maven-repo -Declipse.workspace=/path/to/the/workspace/ ### See Also * [Source](source.html) * [Maven Reports](maven.html) hawtjni-1.0~+git0c502e20c4/webgen/src/community.page000066400000000000000000000037001142665006500221300ustar00rootroot00000000000000--- title: Community in_menu: true sort_info: 50 --- name:overview # Lets Talk The {project_name:} community is here to help you --- name:content We really want you to get involved in the {project_name:} and we love [contributions](contributing.html). One of the easiest ways to get involved is to join the community discussions. # Nabble Forum The mailing lists are all mirrored with an online forum at Nabble * [hawtjni-dev](http://n3.nabble.com/HawtJNI-Dev-f212345.html) * [hawtjni-commits](http://n3.nabble.com/HawtJNI-Commits-f212350.html) # Developer Mailing List The developer list is used for general discussions and ideas about the code and how to use it.
To post an email: {project_id:}-dev@fusesource.org
To subscribe: {project_id:}-dev-subscribe@fusesource.org
To unsubscribe: {project_id:}-dev-unsubscribe@fusesource.org
# Commit Mailing List The commit list is notified of all changes to the source code or changes to [issues](support.html) so you can use this list to watch development and support occur.
To post an email: {project_id:}-commits@fusesource.org
To subscribe: {project_id:}-commits-subscribe@fusesource.org
To unsubscribe: {project_id:}-commits-unsubscribe@fusesource.org
hawtjni-1.0~+git0c502e20c4/webgen/src/contributing.page000066400000000000000000000042571142665006500226230ustar00rootroot00000000000000--- title: Contributing in_menu: false --- name:overview # How to contribute to {project_name:} We love contributions! --- name:content We really want you to get involved in the {project_name:} project, to [join the community](community.html) and help make it a better price of software - please do dive in and help! Try surf the [documentation](documentation/index.html) and website in general - if somethings confusing or not clear, [let us know](community.html) or raise a [support request](support.html). [Download](download.html) the code and try it out and see what you think. Browse the [source code](source.html). Got an itch to scratch, want to tune some operation or add some feature? Want to do some hacking on the {project_name:} code? Try surfing the our Issue Tracker for open issues or features that need to be implemented, take ownership of an issue and try fix it. ## Improving the documentation Documentation is massively important to help users make the most of {project_name:} and its probably the area that needs the most help! So if you are interested in helping the documentation effort; whether its just to fix a page here or there, correct a link or even write a tutorial or improve what documentation is already there please do dive in and help\! All of the documentation is stored in a GIT repo, see [How the Site works](site.html) ## If you find a bug or problem Please raise a new issue in our Issue Tracker. If you can create a JUnit test case then your issue is more likely to be resolved quicker. Then we can add your issue to our [source control system](source.html) and then we'll know when its really fixed and we can ensure that the problem stays fixed in future releases. ## Working on the code and creating patches We gladly accept patches if you can find ways to improve, tune or fix {project_name:} in some way. {include_file: {filename: src/creating_patches.include, process_output: true}} ## Becoming a committer Once you have made some good contributions you may be invited to become a committer by the project team. We'll chat to you offline about it; we'll just need to know your github ID.hawtjni-1.0~+git0c502e20c4/webgen/src/creating_patches.include000066400000000000000000000014741142665006500241240ustar00rootroot00000000000000 * go to the [{project_name:} github page]({project_git_browser:}) and click on the fork button to clone your own copy of the {project_name:} repository * hack your copy as much as you like, pushing your local changes back to your git repo on github * click on the pull request button the [{project_name:} github page]({project_git_browser:}) to let us know you've a patch you'd like to contribute * you may want to [create a new Issue in the Issue Tracker]({project_issue_url:}) (you will need to register but its quick and painless) * fire off an email to the [Community](community.html) linking to the issue When a ticket is created in JIRA it automatically sends an email to the [commit mailing list](community.html) but an email always helps alert folks (as lots of emails are generated from every change to every JIRA). hawtjni-1.0~+git0c502e20c4/webgen/src/documentation/000077500000000000000000000000001142665006500221175ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/documentation/hawtjni-developer-guide.md000066400000000000000000000662421142665006500271750ustar00rootroot00000000000000# HawtJNI Developer Guide * Table of contents {:toc} ## Features {#features} * Automatic mapping from Java to native functions, with simple mappings for all primitive data types * Automatic conversion between C and Java strings * Structure and Union arguments/return values * Function Pointers, (callbacks from native code to Java) as arguments and/or members of a struct * Nested structures * Native long support (32 or 64 bit as appropriate) * Customizable mapping from Java method to native function name * Maven integration: * Generates an autoconf and msbuild projects for the the native library so it can be built on other platforms using the native toolchain. * Native library is built before the test phase, so you can unit tests your JNI classes. * Built native library is packaged as a jar resource and deployed to the maven repo for easy distribution of native code. ## Getting Started with HawtJNI {#getting-started} Implementing JNI libraries is a piece of cake when you use HawtJNI. It will code generate the JNI code needed to access the native methods defined in your Java classes. Lets say you wanted to access to the c library's classic `printf` function: {pygmentize:: c} int printf(const char *format, ...); {pygmentize} To do that, you would only need to define a simple Java class like: {pygmentize:: java} import org.fusesource.hawtjni.runtime.* @JniClass public class Simple { private static final Library LIBRARY = new Library("simple", Simple.class); static { LIBRARY.load(); } public static native int printf(String message); } {pygmentize} That's it. No JNI coding required. It's composed of a static class initializer and a native method interface definition for the `printf` function. For folks who have done JNI before this looks familiar except for the way the library is loaded. You could have also loaded the library the traditional textbook way: {pygmentize:: java} static { System.loadLibrary("simple"); } {pygmentize} The benefit of using the Library class to load the native library is that it can automatically unpack the native library from a jar resource and use that so that you don't have to worry installing it to the java library path. The HawtJNI build process will take care of implementing your `simple` jni library by using some maven tooling which we will cover in the next example. ## Building with Maven If you are not familiar with Maven, please checkout [Maven by Example](http://www.sonatype.com/books/mvnex-book/reference/public-book.html). The easiest way to get started with HawtJNI is copy and use [the example maven project](http://github.com/chirino/hawtjni/tree/master/hawtjni-example/) as a template for your module. At the root of the maven project run: {pygmentize:: text} mvn install {pygmentize} The maven build will produce the following artifacts: * `target/${artifactId}-${version}.jar`: is the standard jar which maven produces that contains all your java classes. * `target/${artifactId}-${version}-native-src.zip`: is a source archive of a autoconf and msbuild based build project for the native library. You can easily build this on other platforms using the platforms native toolchain. * `target/${artifactId}-${version}-${platform}.jar` is the platform specific jar which contains the your build JNI library as a resource. These artifacts will be deployed to the maven repository so that other users can easily use them as dependencies in their builds. You may also be interesting in [How to Add HawtJNI to an Existing Maven Build](#adding-to-maven-build). ## Native Method Mapping {#method-mapping} HawtJNI looks for all classes annotated with `@JniClass`. For every static native method found, it will generate the corresponding JNI function which calls a the platform function of the same name as the java method. The JNI method mapping can be customized by applying the `@JniMethod` annotation to the method and the `@JniArg` to each method argument. ### Default Type Mappings {#default-type-mappings} Without additional configuration native methods automatically convert the method arguments and return types to the corresponding type of the same size on the platform. | Java Type | Native Type | Description | Windows Types | |-------------|---------------|------------------------|-----------------| | `byte` | `char` | 8-bit integer | `BYTE`, `TCHAR` | | `short` | `short` | 16-bit integer | `WORD` | | `char` | `wchar_t` | 16 or 32-bit character | `TCHAR` | | `int` | `int` | 32-bit integer | `DWORD` | | `long` | `long long` | 64-bit integer | `LONG` | | `boolean` | `int` | boolean value | `BOOL` | | `float` | `float` | 32-bit FP | | | `double` | `double` | 64-bit FP | | If a primitive array type or String is used, it gets converted to the corresponding native array/pointer type. | Java Type | Native Type | Description | Windows Types | |-------------|---------------|------------------------|-----------------| | `byte[]` | `char*` | 8-bit array | `BYTE`, `TCHAR` | | `short[]` | `short*` | 16-bit array | `WORD` | | `char[]` | `wchar_t*` | 16 or 32-bit array | `TCHAR` | | `int[]` | `int*` | 32-bit array | `DWORD` | | `long[]` | `long long*` | 64-bit array | `LONG` | | `float[]` | `float*` | 32-bit FP array | | | `double[]` | `double*` | 64-bit FP array | | | `String` | `char*` | 8-bit array | `LPTCSTR` | It's important to note that when dealing with arrays and structures, HawtJNI must copy the contents of the java object to the native type since the JVM can any time move java objects in memory. It will then call the native function and then copy back the native array back over the original java array so that the original java array picks up any changes. When a Java string is converted to a `char *` it applies a UTF-8 conversion. If your native code can handle wide character (i.e. double byte unicode characters), then you annotate the argument with `UNICODE` flag. For example: {pygmentize:: java} public static native int printf( @JniArg(flags={UNICODE}) String message); {pygmentize} ### Passing Primitives by Reference It is common to run into native methods similar to the following: {pygmentize:: c} void adder(int *result, int left, int right) { *result = left + right; } {pygmentize} They use a pointer to a simple type to store the result of function call. It may not be obvious at first, but this can be mapped in java using a primitive array. For example: {pygmentize:: java} public static native void adder(int []result, int left, int right); {pygmentize} Just make sure you use the method with 1 element array: {pygmentize:: java} byte[] result = new byte[1]; adder(result, 3, 4); System.out.println("The result was: "+result[0]); {pygmentize} ## Mapping Native Structures {#mapping-native-structures} You define a Java class for each native structure that you want map and replicate all the fields that you will need to access as regular java fields. For example, say you had a C structure and function that was defined as follows: {pygmentize:: c} struct COORD { int x; int y; }; void display_coord(struct COORD* position); {pygmentize} Then the the corresponding Java class for the structure would look like: {pygmentize:: java} @JniClass(flags={STRUCT}) public static class COORD { public short x; public short y; } {pygmentize} The native method definition can then just take COORD java object as an argument. {pygmentize:: java} public static native void display_coord(COORD position); {pygmentize} ### Nested Structs and Unions Nested native structures are also easy. For example: {pygmentize:: c} struct RECT { struct COORD top_left; struct COORD bottom_right; }; {pygmentize} Would be mapped as: {pygmentize:: java} @JniClass(flags={STRUCT}) public static class RECT { public COORD top_left = new COORD(); public COORD bottom_right = new COORD(); } {pygmentize} ### Passing Structs By Value You probably noticed that structures are passed by reference by default. If your native method accepts the structure by value instead, then you need to annotate the method argument with the `BY_VALUE` flag. For example, if your native method was defined as: {pygmentize:: c} int validate_coord(struct COORD position); {pygmentize} Then your Java method mapping would look like {pygmentize:: java} public static native int validate_coord( @JniArg(flags={BY_VALUE}) COORD position); {pygmentize} The passed object MUST not be `null`. ### Typedef Structures If the structure name your mapping is actually a typedef, in other words, the type is referred to in native code by just the plain `name` and not the `struct name`, then you need to add the `TYPEDEF` flag to struct definition. For example, if the native definition was: {pygmentize:: c} typedef struct _COORD { int x; int y; } COORD; {pygmentize} Then the the corresponding Java class for the structure would look like: {pygmentize:: java} @JniClass(flags={STRUCT,TYPEDEF}) public static class COORD { public short x; public short y; } {pygmentize} ### Zeroing Out Structures You do NOT have to map all the native fields in a structure it's corresponding Java structure class. You will actually get better performance if you only map the fields that will be accessed by your Java application. If not all the fields of the structure are mapped, then when the native structure is created from a Java structure, the unmapped fields will have whatever random data was in the allocated memory location the native structure was allocated on. If you prefer or NEED to zero out unmapped fields, then add the `ZERO_OUT` flag. For example: {pygmentize:: java} @JniClass(flags={STRUCT,ZERO_OUT}) public static class COORD { public short x; } {pygmentize} ### Skipping Fields If you need to have a Java field which is not mapped to a native structure field, annotate it with `@JniField(flags={FIELD_SKIP})`. This can be useful, to holding java side computations of the structure. For example, if you want to cache the hash computation of the structure you could do the following: {pygmentize:: java} @JniClass(flags={STRUCT,ZERO_OUT}) public static class COORD { public short x; public short y; @JniField(flags={FIELD_SKIP}) public int hash; public int hashCode() { if( hash==0 ) { hash = (x << 16) & y; } return hash; } } {pygmentize} ## Loading Platform Constants {#platform-constants} Many times you need to access the value of platform constants. To load platform constants you will need to: 1. Define a constant initializer method which when called will sets all the static fields annotated as constant fields with the constant value. Example: {pygmentize:: java} @JniMethod(flags={CONSTANT_INITIALIZER}) private static final native void init(); {pygmentize} 2. For each constant you want to load define a static field for it with the `@JniField(flags={CONSTANT})` annotation. Example: {pygmentize:: java} @JniField(flags={CONSTANT}) public static short FOREGROUND_BLUE; {pygmentize} 3. Call the constant initializer method in the class initializer, after the library is loaded. For example: {pygmentize:: java} private static final Library LIBRARY = new Library("simple", Simple.class); static { LIBRARY.load(); init(); } {pygmentize} ## Accessors: Changing the Function or Field Accessed {#accessors} If you want to call your java method something different from the native method name, you can set the `accessor` attribute on a `@JniMethod` or `@JniField` annotation. For example, to call the native `printf` function from a Java `print` method, you would set it up as follows: {pygmentize:: java} @JniMethod(accessor="printf") public static native int print(String message); {pygmentize} In the case of field on a structure this can be used to do simple renames or to map field to the field of a nested structure or union: {pygmentize:: java} // Just a simple rename.. @JniField(accessor="dwSize") public int size; // Mapping to a nested field. @JniField(accessor="u.pos") public int deep; {pygmentize} The accessor also comes in handy when you want to load constants which are not a simple symbol, for example the size of a structure: {pygmentize:: java} @JniField(accessor="sizeof(struct COORD)", flags={CONSTANT}) public static int SIZEOF_COORD; {pygmentize} ## Working with Pointers {#pointers} If you want the same java class to be able to work with 32 bit and 64 bit pointers, you should map pointers to Java `long`. If your only targeting 32 bit platforms you can map pointers to `int`. When HawtJNI is on a 32 bit platform but is mapping pointers to Java's 64 bit longs, it needs to know that the value it's working with is a pointer so that it properly up and down casts the pointer value. This is typically done by setting the `cast` attribute on the the `@JniMethod`, `@JniArg` and `@JniField` annotations to the pointer type. In general it's good practice to set the cast attribute to the defined type of value. For example, to let HawtJNI know that the `malloc` function returns a void pointer you would define it as follows: {pygmentize:: java} @JniMethod(cast="void *") public static final native long malloc( @JniArg(cast="size_t") long size); {pygmentize} If the cast end with `*` and it's being mapped to a Java `long` then HawtJNI knows that it's dealing with a pointer type. But if your using a typedef to pointer, then you need to flag the condition with one of the following: * `@JniMethod(flag={POINTER_RETURN})` * `@JniArg(flags={POINTER_ARG})` * `@JniField(flags={POINTER_FIELD})` This is very common on the Windows platform where tend to typedef pointer types like `LPTCSTR`. You may be tempted to do pointer arithmetic on the java side long value, but DON'T. The native pointer is a combination of signed/unsigned, and 32/64 bit value which may more may not match java's memory model. Adding offsets to the pointer on the java side will likely result in a invalid pointer location. ## Allocating Arrays and Structures on the Native Heap {#heap-structures} The memory associated with a passed structure or array is reclaimed at the end of every native method call. Therefore, a method expects a passed array or structure reference to remain valid after the method call then that array or structure needs to be allocated on the native heap instead. This is accomplished using the standard native `malloc` function call. For example to create a char array 80 bytes big: {pygmentize:: java} long buffer = malloc(80); {pygmentize} To create a structure on the the heap, your going to need a couple of helper methods. 1. You need to know the size of the structure. 2. You need define a versions of memmove which copy to and from the your Java structure object and memory buffer (`void *`). I recommend keeping those defined in the structure class itself. For example: {pygmentize:: java} @JniClass(flags={STRUCT}) public static class COORD { public short x; public short y; // To hand loading the SIZE_OF constant @JniMethod(flags={CONSTANT_INITIALIZER}) private static final native void init(); @JniField(flags={CONSTANT}, accessor="sizeof(struct COORD)") public static short SIZE_OF; static { init(); } public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL})) COORD dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) long src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL})) long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) COORD src, @JniArg(cast="size_t") long size); } {pygmentize} Now you can allocate and initialize a structure on the heap: {pygmentize:: java} long buffer = malloc(COORD.SIZE_OF); COORD tmp = new COORD() tmp.x = 3; tmp.y = 4; COORD.memmove(buffer, tmp, COORD.SIZE_OF); {pygmentize} ## Callbacks: Calling Java methods from native functions. Some native functions require a callback function pointer as an argument. You can create one using a `Callback` object. For example, lets say needed to call the following native function: {pygmentize:: java} long foo(void (*fp)(char *buffer, int n)); {pygmentize} It you could map it in Java as: {pygmentize:: java} public static final native void foo ( @JniArg(cast="void *") long fp); {pygmentize} Next you need to create a java method that can accept the callback. The method MUST return long and can have any number of arguments, but they must also all be longs. The method can be a static or instance method. For example: {pygmentize:: java} class MyObject { public long mymethod(long buffer, long n) { System.out.println("Was given a buffer "+n+" byte big at "+buffer); } } {pygmentize} Then to create a function pointer which points back to a Java method, you create a Callback object with a reference to the Java object, method name, and number of arguments on the method takes. For example: {pygmentize:: java} MyObject object = new MyObject(); Callback callback = new Callback(object, "mymethod", 2); long fp = callback.getAddress(); foo(fp); {pygmentize} Warning: you can only create up to 128 Callbacks concurrently. If you exceed this number `callback.getAddress()` returns zero. You should use the `callback.dispose()` method to release a callback once it's not being used anymore. ## Optimizations {#optimizations} If you have performance sensitive method that works on an Array or Structure, setting on of the following flags may help your performance. * __`@JniArg(flags={NO_IN})`__:Indicate that a native method parameter is an out only variable. This only makes sense if the parameter is a structure or an array of primitives. It is an optimization to avoid copying the java memory to C memory on the way in. * __`@JniArg(flags={NO_OUT})`__: Indicate that a native method parameter is an in only variable. This only makes sense if the parameter is a structure or an array of primitives. It is an optimization to avoid copying the C memory from java memory on the way out. * __`@JniArg(flags={CRITICAL})`__: Uses a special JVM call which locks the java array in memory and disable garbage collection for the duration of the native call. This is an optimization to avoid copying memory and must only be used with low latency functions. This only makes sense if the parameter is an array These optimization flags are typically used for the `memmove` C library function. for example, to copy the the contents of a `byte[]` into a java `int[]`, you would define the `memmove` method as follows: {pygmentize:: java} public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL})) int[] dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, @JniArg(cast="size_t") long size); {pygmentize} ## Conditionals {#conditionals} You can use the `conditional` attribute on the `@JniClass`, `@JniMethod` and `@JniField` annotations to control if JNI code associated with the class, method, or field gets conditionally compiled out. This is very useful if your mapping to a native function, structure, or field that may not be available on all the platforms which your Java class is going to be made available to. Example: {pygmentize:: java} @JniMethod(conditional="defined(_WIN32)") public static native int printf(String message); {pygmentize} Would produce a JNI `printf` method implementation which is surrounded by the following pre-processor directives: {pygmentize:: c} #if defined(_WIN32) // ... the JNI method implementation would be here #endif {pygmentize} The `conditional` on a `@JniMethod` or `@JniField` defaults to value configured on the enclosing `@JniClass`. So if most of the fields or methods in a class need to have have the same conditional applied, just set it on the `@JniClass` annotation. ## How to Add HawtJNI to an Existing Maven Build {#adding-to-maven-build} The HawtJNI provides a maven plugin which makes it easy code generate and build the native library for your current platform. Once you have a working maven build for a java module, you can then update it to use HawtJNI to generate your JNI libraries. With the following steps: 1. Add the hawtjni repositories to the `pom.xml` configuration. {pygmentize:: xml} ... hawtjni.snapshot.fusesource.org HawtJNI Snapshot Repo http://hawtjni.fusesource.org/repo/snapshot false true ... ... hawtjni.snapshot.fusesource.org HawtJNI Snapshot Repo http://hawtjni.fusesource.org/repo/snapshot false true ... {pygmentize} 2. Add the `hawtjni-runtime` dependency to pom. This small 19k jar file contains the HawtJNI annotations and a few Helper classes that you will be developing against. {pygmentize:: xml} ... org.fusesource.hawtjni hawtjni-runtime {project_version:} ... {pygmentize} 3. Add the HawtJNI maven plugin to the pom. {pygmentize:: xml} ... org.fusesource.hawtjni maven-hawtjni-plugin {project_version:} generate build package-jar package-source ... {pygmentize} 4. If you run into problems with `mvn clean` no deleting native files, make sure you are using at least version 2.3 of the maven clean plugin. Previous versions would run into problems with symlinks. {pygmentize:: xml} ... org.apache.maven.plugins maven-clean-plugin 2.3 ... {pygmentize} ### Generation Details You may have noticed that HawtJNI is generating a slew of code in different directories. Here is a breakdown of what gets generated where and during which maven build phase: 1. __process-classes__: Processes the annotated java classes: 1. generates JNI .c and .h files to `target/generated-sources/hawtjni/native-src` 2. generates an autoconf and msbuild build project in the `target/generated-sources/hawtjni/native-package` directory 2. __generate-test-resources__: Compiles the native library: 1. The project is built in `target/native-build` 2. The project installed the libraries to `target/native-dist` 3. The libraries are copied to `target/generated-sources/hawtjni/lib` which gets added as a test resource path. 3. __package-jar__: The contents of `target/generated-sources/hawtjni/lib` get jarred and attached to the maven build with a platform specific classifier. 4. __package-source__: The contents of `target/generated-sources/hawtjni/native-package` get zipped up into a platform agnostic source package for building the native library. hawtjni-1.0~+git0c502e20c4/webgen/src/documentation/hawtjni-developer-guide.page000066400000000000000000000005121142665006500274750ustar00rootroot00000000000000--- title: HawtJNI Developers Guide in_menu: false sort_info: 10 --- name:overview # HawtJNI Developers Guide All the information you need to be become an expert with HawtJNI --- name:content pipeline:tags,markdown {include_file: {filename: src/documentation/hawtjni-developer-guide.md, process_output: true, escape_html: false}}hawtjni-1.0~+git0c502e20c4/webgen/src/documentation/index.page000066400000000000000000000004751142665006500240720ustar00rootroot00000000000000--- title: Documentation in_menu: true sort_info: 2 --- name:overview # HawtJNI Developers Guide All the information you need to be become an expert with HawtJNI --- name:content pipeline:tags,markdown {include_file: {filename: src/documentation/hawtjni-developer-guide.md, process_output: true, escape_html: false}}hawtjni-1.0~+git0c502e20c4/webgen/src/downloads/000077500000000000000000000000001142665006500212405ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/downloads/index.page000066400000000000000000000037701142665006500232140ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. title: Downloads in_menu: true sort_info: 1 --- name:overview # {project_name:} Download it Today! --- name:content pipeline:haml,tags .left %h1 Just need a jar? .right Try out the nightly build: %ul %li %a{:href => "http://{project_id:}.fusesource.org/repo/snapshot/org/fusesource/{project_id:}/{project_id:}/{project_version:}/{project_id:}-{project_version:}.jar"} {project_id:}-{project_version:}.jar .left %h1 Are you a Maven User? .right %p Just the following to your %code pom.xml :plain {coderay:: xml} org.fusesource.{project_id:} {project_id:} {project_version:} {coderay} %p You you should ensure you have the {project_id:} maven repository defined in your %code pom.xml :plain {coderay:: xml} {project_id:}.release.m2 {project_name:} Snapshot Repository http://{project_id:}.fusesource.org/repo/snapshot true true {coderay} hawtjni-1.0~+git0c502e20c4/webgen/src/faq.page000066400000000000000000000022501142665006500206520ustar00rootroot00000000000000--- title: FAQ in_menu: true sort_info: 41 # FYI: # The fragments processor allows the TOC to generated by the menu tag. --- name:overview pipeline:tags

Burning Questions?

This page contains all the frequently asked questions about the {project_name:} project.
{menu: {used_nodes: fragments, min_levels: 4, max_levels: 6}}
--- name:content pipeline:tags,markdown,fragments ## General Questions General questions on the *{project_name:}* project. ### What is the license? The license is [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0) ### How do I build {project_name:} See the [building guide](building.html) ### How do I get support? See the [support guide](support.html) for more details. ### How do I contribute or become a committer? We love [contributions](contributing.html)! More details on how to contribute and how to become a committer are in the [contributing guide](contributing.html). ### How does the website work? For details on how to edit the website and how it works see [How the Site works](site.html) ### Using {project_name:} ### How do I get started? ## Errors hawtjni-1.0~+git0c502e20c4/webgen/src/images/000077500000000000000000000000001142665006500205135ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/images/lightbulb.jpg000066400000000000000000000432151142665006500231760ustar00rootroot00000000000000JFIFHH2http://ns.adobe.com/xap/1.0/ Adobe Fireworks CS4 2009-04-04T09:23:02Z 2009-04-04T09:23:02Z image/jpeg CCxJ  <!"1A 2B#Qa3b$Rq 4F3!1AQaq"2R#Bbr ?8G\\3dV]f<=R vӀJL -0 I[^g>"n=X£AT(?-3b^}+שA'\M};t8|^ي80GM0} @}~aTlWՊdP%?2ABs&ԦByw4[ZZMWIZj.M8; ة9nDPC}"?0@s h'*h)nAdAk ]îmSrÁ`#6&jө?+?,P_IɯԐ|s=A0M؈$BY@GHTc>Pإ@wH ;pɷm4q6 P2h \FzE웼d1 !}1ۤTY&wfp$Z-⢢j)5XZ1DEd\ꤻuMdEBȪ@:j;ܦC@][hT벳'M¶L2 j*bGz_U˥Ǫg3Uzˠ &h4ðhB`%!C}[2D@J].@~<o`6}hk9fN߷EG,w dAt]#1Q@D@.x=WeQʎ+,bgT2cWʟԯ=fS1cCo)@3.Hɧ21+Vi$*Rb6bCaӷm "`@~ޚ@f̆ D·SU1GR 5}u=HuftÒ:^]EgANOؤ`[7`C}r`QbkV*A<=-M[k=o~ȠF$ɑIEJR5OChG8%Hd`kHl$T( ɀxc bmR Σ4d|Y.h"e53`zەSl(=AK=$es=G@98oi&K~fG N Ɍ>*K97bacGfQrZ&aZ-arE0o=Sa Ca.GRs)'1=I_nA%$p]SP󋼮En#Pd̽q5ګ j_o5=mMzʿV1 6 4PSj)[aG55ږSBtO-fUu/uA=4͒S"%\E_ng]L/]N_ " n M0Eueh $`%B%U^oyI! =Bp<~ܯߧL3N7c27%TK!c_HW(}.#pSh1U"h@|O.(~ߞ=zmr-^Y5%a5o]z)t2D_pتJ^YIegpfyӆLz~ɋh]fd9h ̷"M +wMVSX00ݹMUTԾ8m~]%¦}I5ŞtIbraK9x:J)f@RnREs@" )M0t)MY,0ðo߷qD v+]ĕg5nzd:2ng}@1uMRЌa`#DF3 * V#)w1s"#3zOiY01rߙP@6L6@_pJM̠ 'COƆ :e,w!!#&` #J #71--CЭfa`0"rE;gf@ 颫*Z>zE3-qLwt~ P|F(c@"#![[6J_-Y:;7V6mbOQso+.USvm vdD4FLQ*1n2ŦZ_r-~geo5_N$,qQ*U8iLokuZTɲd(q/<;Ց"2%%feR &kEڅL pf v '4z+NZU'JzSRiKCf j@I&4lz&dHP֒ h@@Q<.$$[dis/M&[q BSx\[aiM>hTGőԊxAm+8LULPS6Vz]r*S\.t7=Ъe?ΑG~2Y4bRRI62}EH-SjTUݹFLx{f31y[pYXRI#ǨD8BaYwlSu :㟪0GUz{k alY]b1 ߃\[A3dv&6UbU+ư1VSMAwEh "n9\EʁLdiQUI)T7p3?Qռ}@nnx~ɯײ\Ȳ]+kq OޫB)UM5SE;|nt qPƾ.y>o;C90d:s>3*'jS~d[TN^N,ik,ݘmx5K=zL*BioDꁀwT,ˈ5?5=\ĵun#1d]#KrC12X 7UMG}e_9鴔2KC8V7s:aRw@JQc[43Rs l j*AD02t4^:K7%,nLscN h@j9{-6^Ҧe"m XH>fv&I`PWbL_!D9gfw=v[)tYJ]fVߒ>h ?bIC'G";~F!E^ʦ]xMOYƞgVyc,dعIw~^R|J*hvԌ"W <1U/v*(-zb+\/G3|RC `+\Nr,8-:¶QFh? \?HD"a)7+-[W%Vy E붒umV#g5|=>AX_%dJe(X^R瞧|完ʼn T: l`͔~gB*->ˤglt^~ 4 h@TGwyǾ2xg(:fٸ9!1ǹZ)Jk>ceJ풧M%Y:熙|_ⳮ[L@EWPTMa/:R0nl{ ܆.)6ҿ>~.رM27 ӑQSH3M((ř:# IyYN${DѓLvhdn$AE!RER/"I"6 ;ht]h@hawtjni-1.0~+git0c502e20c4/webgen/src/images/project-icon-160x160.png000066400000000000000000002360721142665006500245520ustar00rootroot00000000000000PNG  IHDRg-sBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time2/17/107\+prVWx[o~HŌ b8H=,t+ye.{e_5%|QYQ,#^n%߿ֲ5m[⿛m궩Fuu[WmڪnTVi:VM>iTS7M]7uԪꦪ 84jUU]rjUJʩU;NTQs]jksoZ;1ցO"i)Q, Up-Nn.R8}{ɱbsIEj,}oa`s0<ոP:NdB'& ftlQf3Z&1_-""}}-h udxgs̢aHZI0шx&r~W.SJgA#J#" RHgO>x/ P>wA,Q1Q.{%dʼnHrr}<֟Z @K+BPxOngH#|;motv6(KK1ؿ4GòC:;jsSef(ziߡ*pC%oh)ӑoiIܴJ { H<?Ҁ E|Y?i^:C?P֠ rafF=huN@W__ii!~vu' M:Vz7a^a!~ψ8~  zd*[/lt9 oˬĿ/?c)M8 XVRΖ {OY_GuҴ̷c5KD/uͅjg[z|o;i?t넕DTa)| HCR&l>fTv387\KDK#]هWHC![ $M,Q7?3YB!% ̤IjKEP~ a7LļY50Pj?LBP$3Lht^)|L~q%;Bqpq8_9-%q|N#qBrZH9DIg(Q{;W& %;H~!/᳠H8!v-^.39J %%/|*+:yMC?9?4x:5Ç8 Ҡ3c9`?ӏ|V@DGÿ;\ܒk 0I۰gb Hz ه O x l><_p,t2=Kg@_$sW#Qc@[E;Sh 3q`BeyvO p>H "V@Qw<弃6i\8J01/P 4 lh)R?p( 3|[@4J?=Vr Ok`KR%#}g98gOi;Zq [ܤ$ty@uQjϩmL .U'FSC!%'`O!XhtB7xt}H Z[_~НʯO?DPrtv@#/A{z72u9v .-GߠsR|bɃ+{hL 9 t5_X?rJN¶Ttx<rsz5,\_8"f9Tr<)tO= ,#NIxw E-y!g )DJ1g&"t#&pp`gdt38n6tf 4٦Nu4hD&6k$y jWծv]jW=?,[HmkBF)3mkTSxۗF'i-=a_t9+2UU*I%Xe i׶/=x""/ "iv EdFFF⒉=xsZ~y-[|rqYSKS-..գ%s˳ɳ X''o.N{//Gz`T^.FѓOCh6;:?˳S${ Qs<8ztq)s8Po&1v`_pLv|F')\[/sG|sGOU)=H詠1Aa97l56Gs(Hza ^ih e}yt8qn}yUMvأrhs;q!8$rrS׍) ?<<op>'g fF2Yɧc%~mv3?<>]Gxi ϣ72Y` ?m Vjf0/᎗Ͷ ]L87"@Ql2|Ge7e2?a^UIĦl-< ǣzDE)P"HQ' NiQ̘Z9Zz=rϣNX:62~8?9XQE~}O%tHvU/Խu/_ۋԎe癘sI rDS='OIn'r\ˉxb #n$Lr|DMA`I9pIlku.a/ٌ;A5`gW>;Fc3vJws<;6Euw"ЂBt߬뚑ccDƣrJrK>ni-Tv .6||?jL8.ZEh-.oEDr| >`='i/yZcL 9t߶ŃrzKhW+ӝȧ&=fkMBXS85cM15l/>]]_|e2RCqH~H뛌f0Y6SEFrڵ8DZW(HWK6 >#OkHYqNVu}Ct7~1$D1&V"=tt$N;.r82 P~b*Xr IPl?*]͊vBr뙫v c#!S ٗc ӿwExviG>ؙ 898v.\1trUf^o]A5V9?8bx~}!PG0Z]-nB3F+r[Bjs(Vm "O<3qa, A,<@}=pUY>#+H=lWuf'_$`I_=,)-1bLod̙76U?ΞvI"y<,iMr8D )E_Έfq=.qQ `wm@"8midЗga<1їh~-( uj ^95. RU܋!~gZ8$쮈II[b8&}ʫ'ͣ$Q{|Nwt z i 50Öս!Q}T$aJ}6k΁ F_Ey}t~ s"hǶi ۋՓ U/7$Z^ ,& V ~Eӫjx6P+A6b.+W&V?*a&QL;:X*gvI&W{`_"Yf n6K08&Nj:9~S.E*!X(! BeOA:Ꮠ~9`-tfsg? _Rƫח|@ 1⻍^TCWt;ASj[%[!PcD‡HO۾3iZ2͔!_ ~'VY}F!Vآ`b<&gU[JQәUguLvdM*Oo 5Tvj/c./kNYSˆ0:Ť<&$5|==l"c>f}R6 UzR7'Z ๐ ȯ%{!OzjT wā^ai<ڒMFr!j^{T E$nm ETැr J-r?YoޡK[ my&S3 n&Ku3ybdoLSg"z[bi VO6 RϣE!LjAUYszkVh@ͿmeBs3hMs>zkGu8*5+8ʋ);Z7u= Fpov-\Lk]O]C"{V^sNL~DEohG?+ UO'o.?!?ZRntte~C/{Grޏ:>=gt9*1#> ]/6` V™>,_g۲;MG_0P/s凭+KE?i]J^8)G*>Ph-)₩M7Q'['eCt`| x|NՍ>+Fʫ"hX\YTo|A:Œܢ7*^r=VëE#Fɤoh}R <0k -RQ/l<}/1Ag}_ ?`$f=h-"ߗ+F͟ Iޫf_bĦwމw:N L0'Sx nCA&~kkgp\?壖Ĥ{}V^;_vNu^;^;iv7u^G_{{=@G: 9{ }Z5^C513Z^;kg{[Vc5k轆k-4tc5tkzGwk^g+:{Cg76:UyvW^;οʻ~tn:zU5w{ 8~w{.h}^;6SyW5^Co;w{ .h}^C5t*x n,sj ÌmYS ;w׺-"оv̕z#p@݈yۑme/D׼UɚN"W'kfkYC4I^ް?}͚H$f=M^H4m#}گdnzqOAC pA)k轆k}j5'>6:xC'f0ѹs;Yy;O.g|kWM77\-xƂZ÷!PC+ޣ;TU>zy:fRqgmŔ hKH>Ȗ$]] I!Z)])>iE>P nV8ɔY9G2 r7d,e뱔_n1̒ ԟ-8C{p2`Qj,f0b~AmG\hov{zMo+"z^GΕq.#w4S{֙x~T 2GCEcvc'wsDgOQ׬NuB}]%+w ZZɃC 8zf+.zxI#o7={R4#z5I;py#g{?__umߍ8׾O{{g:X}Nt^ߺM nl~ڧ?'gwB;1zH/wyMZj,o!tv;?c6F968$>^ͣwNە.G^.C|~r/o\)+\ȫqׯGAK^)ےkzmc·F,_Ρu}#=#=~/pin8=#")B]S亢ZİTz-SeF{?}om>/>ƖeiN+ߎ8x֕ΘTqoyk M/&@]P~rdqzzM ʊ_,l{E;7 ޷oW%?̈ױУ1a}Kz-D\~!Ԡ#P H һ*;oF =~i&ֻi5Mw}]N~9j/Hp4vm-ۜjvjҭkG Hn__<5"ϩzx O 퉞W`hN̂z0aV`X89Y =aݺ3 77'EA-Nx@yo\Dٟ=svtz t.p_\]rv=txX??xs>΀˯NS,88ttqY.frA|8~|5<~|]8͹oUO6㧹rֺrf74Ebf?+ῦV>TY8PםQ&>Ae-}n?}^۲ϕy=d]Y]:o:O|J91U *dRfUe".ovQsJ'>Oٙyh}U<73i 3K5`dqO6򳚛ZF^?J^.3YV7 ײiYD| je6܅rf`0m3*\)7FiԵ6|3x\xS4Z _3`oBLͪKcBMmp^,t IF`QzL)HȂW2JcJ44kUw}hB4e74Y%=@dPsbdl#s^T Uh$DllZM伈"LyQʦuQ4c[L.hdWh}}eO/] O|<`ֶbe͈V\F*᧑6#Y40eLk>,~"kM]1Kǔ 9O;ux 0'ó3:&M 'WſXOLJD BH|r#rysgYloa}#Ql_$}3ax0<}qP6|gelaM8ki[/@K8#4*dTe,wv^(G<5.# 9S)y$OϑgO@0~vk —(n٘qY]W8+츰,~}׎5㶐c8[1+{ i W1+ dqKiK 4E0q *eI@|hR,;IU2]k Ѹ&;F!&I9&1JI$ZFwT͸kR+rL*\XX)Xl)ao@2GB#`RM5u< ⢷EЦCD^\HN8KVPN&816fgUy`h8.4&p evm"=ll@ۀ]qbot2:0$dddBE $<)0 < UTqZ  =jT"R+JVls=LS`/9p:OF&|jcp`Ӵ &f SdSՊ܈BEQ.foʄLPA٣3Ԣha&.tT=,YLW]c8(ϡi8da48Zj<2BE'SY=8M&i *j, 8ܝWVˣ{?=F@c' {nkZý.PλSSAUs;0e ;JY;2QIޝ-/ t~wg>7Fpcci7`wWrLu5ph 脊J\(wL5.1X!IAA+l[te)B9F pV!6vF@h)@9bWvV'A`K r" a yF'%*Le2SV¬SHm5iiteIN]p )&|J2Hhǖݕ*q_Ff PX/4AS͛;Y҄h8a@N;[F( 6$>6KAf@^!4O;EֺjLPe 8Nipqgz>vQ|PN@O1.KfR4͇*Mg QyQwViڨB(C#b*݇<0374U2WuwrL1Qaŀ2^f Ԡo4:LZ@yj:eZFj(Lvfx "(KL 3# +S~H2Bg,A\)ۉYф [R,`ϵT4y2Li16GD7 Od`С׽⺕bdVt8fa'@Od /g+K7ie>b0_ fiIA$ A[! NҜIQК0 2}@Wwa U"%ʐ`U/`0\!PӋ<]$2(@c1CRT,b&X7“E".c0`!>L*0<1Ƶ`"+|_}X3ceof nRc+Ϡ+4ƅjܘ ](7f  ̍ wGVPOI4cj=\0pU}D"zu`AX8E+-!'3ӎ1C(bEX$ǰd (NjҰ"5y]KT˨ШQx&9wd59BKZy^0J\ELځΤ1U**0\v4*FwShHR%&[뾬 ,2 1(o#OXs²XgnܻbHŽP*_Xws$%z0-!DdB(e3X 'tsj,JUS(R)uLZY&Av Ii$F -d:-dIMmS2If< rA`y|@+0RKb خ<7lݗ`AciVJ^EB cB57'#W]`2ړ +hJ`KJց֣z@g*D.^qJLj(RƔ P,*14e7pRkhYn_b *D,aoI!TN CejٖMTh" Ԍc4I"P"*.<@0&9,݊'_ p[+Pі RVU$Wrץ&S‚,,C.LT Y!4q6E]եЫuEB+0uΑ"HMq)&$#1 Rp,G 028 #R1"1Uh h),X!R4̗֘UlۏCVS]űWrwyߤI p1At H#-Kue2]ZJ6ւ)²Ԡ+8_Zb~ ű$3m-򘲇1z @GYDPHXs _)kALR2 LOׯKΦk%a4I, 0eK_6 l!VKKc|L;'@_ בi'Tb(lHf";R>=a?*fj5B!3턈p ddJnfq5kڰ v}oy[ٸ`unf  J CRY)+ʹ@H.E 3 !hX9`r@L;8h哦} uPAX_R1c@{D%l5ϯQݩdx -uwbICKbRsL@;08lŭa@:vqqC2%!2a`; S۝WVs•z@;$zƴC]\ؘv'}!),oUĝ la X҆ J9#HXeJ02E2U.i3>#(R[@ėh3+\/@j ]B˰]T]ePNK@s9dP ̧Ҙ23b%aIUsŀabҍMMumbʵa: y2]J}Ӿ| sh4?!o?M@bH\WN &Ta`&N1&$ԜvG.ɕpd0Oy2.@3*!Y)ӕ2*֔0Cڳ[aZER0Ldt˷IگٯV6 (-Ga%D7Ň4F ,İYh"(z D,U %-)tn! ޔ@s,eXװӻ+րA5%0?\pLlJ%(R4K_{oBwV SULs,4,~ 0%ʇ66aqg3@ =3vԫ{UT"@Rѵ+Kԕ_[2D:ZҮE'џm<`0y6x" `"Y2`pyE I.<;5/BB$HvFdy+L(G΍ ?X;u1<:>ஞaTapPkUÙLdf EOOA"ViytO-̼V܋/*bq%E[yÛwL-YaeUHZF6=tUb{1z_eVzgټ CV UI,n_aUJ4AU5%ihfS9y&pO'.rNF+FV!p'tӀ+lk:km.0P>|Vi0jr|ݩqJu.>V u~p wݙ%ܨQeNv':ŝGP063EeZeY,N3׿q|YT~]EpÒISQrZ/Vfw'f@4e9hʐH` (KΞXUuhVMՃ~m 'a EjM7^IB`UŗۍF ݨ,ԐׁtIk\ꋳ{=I&:yțTҁ‰hl^uU)R),n-0jR$xµݍP&YuT|zPLpWKfw*{U@FILcE\7`UWowI88=|I)$Wi%{w}IJȘo*-ql5`۱$u` 6V$e8Ǽ#+pMR:bi’^jJ銪 cBU_JOenLjU mZրv$I`n8f64fn[̟ni%Bnok|󫚪`$-p]7|_"'.zSa]p1.zYw9xc6NRoɫIY4<++,Zw.M/PyPwl \W'f$S&6q6X0fJAiYwJh{" 7dd:S",_&<u*,g *MNW U8%$}M v2%nӼA Kq֝HE\g9d+#|*-دCAz&H[ȝ函%wOÝGH-cϣ{\O}bWx^5<lw=X܈YOrq!8$\NNq:~x1<G ] L>AHf=+ނq߯c槞 p?bUK}Xϣ72Y/i̽Ӷ0mU8I9\@eCy) wl56OrXgjǹb;*a,ەA 0_= bDEQiXebOMO$TUيu zg4A(fX|rvFzG_-x˝2tlexk?39=pr?0} K&_{/^% )*31m߉Y9Fٞ_7؊ 9r.D<1QyF&z>"&rs$u$q5:۰lF֝ qޚsLfdW3+Rg~XWxNJ;9VQú;uhA~![ouE11d"sQ 9%%xvn*;LTFsp >J5[&Fb"At\t"FU9> |TX^<-1b&f:oAR9 =%Mf4+d`hF-=y<=nuf"*cj=>7OwOtܓ_+ĕNn.Û$i7'͛±p)k ǚb k>!^|&ez+7]0x.&6)&T96UMU/?Fw-kzy&( t`j>$P:[O~q2\f=>=i.5R= ͢dߴd{'#ЈxuΪ0#O" Zf$FתG!tmrM$ *E| ~߁?]m}`"+170M#mf3) <>9b+ Ukqz396ĵ P@8l@8%ō}ӹG xpb_x3홄[~#N<*l#b$kCjSgj͓Ljx 81Mgw!tz}Rܪʅ8'ẾAa bߘw]+I{H{: :{9MFL~({?}E1,Fy9v(`|hfE};br;ƱEy^S?1rG;LޢJj<;崣~e L~E. u:9GFEJ)mTW+^˳n|&o Tk`33 h u I+Y0Fn궯sgmY 1 [&fh[-<4 aVf r# Pг]mahx~EfS$IBcX&ۋ~ƈy2UZ1g$(V8{2ۅ&7}r@W3!陼3ߧ}9#vl)_xE5Cͷ (^PLA_yv%F ,BsCڂW{AKjv&bHGAG7{Ù%I6+o&e֥I߮j*I$IsT/p8|m_xхTv }x5<}eneG=IcaRzMs`óWzs^B뾈6Zm?CG)*=D~-\HWϽܧ=JS*Qr Q4vMmɦ Ocsj Su5 =YYڢAN7"`*g[jQ欷_]Cn%Ԅ<ޙlX7%ϺzkGu8*5+8ʋ);Z7u= Fpov-\Lk]O]C"{V^sNL~DEohG9}-FDW}=:wscfFO1⣿5o3o%)ep-;Oqt>C2*:W~غ+Zjwآ՟K/n#s~T_ӦOh7(ޢ2!:w|L- NG~*DF#UsWlaz !3YTo|A`9ŒL7^r+E#Fxoh}R <k -GQ/l<}r/͹\W%bBY}ZF8Q{EgBjd|V+_;t^WAi^x dm}#4_om |Ҹw[:T^C5kh{ 4z:z]G˽轎"qF+!z_;vkv"q\k轆n zz6rS9Ƚq:u6-PuKg5^C_Nu^C5oYCHo;w{Ϯ|۫kwAC+zhb^G :z_y{MQyvW^;oT5w{ C4n Uv*]ʻkFCU( : Ym窛7;=s%z2X%ݹ:nKFD7]'s冞HP7"{Avde[ oU~sɚZ_}ꥭmwR473ĬǢOEi?nH%s{D} g ?N^C5^CcW?ihQGŻ/ްZ~ۇUjjNo1o9FSDM5؛ 3t|>˭uN4K^ߥC5:I97 r~ܡt{*Q?>] W=W">iE>͠?+H/9NIH!HFPܸըPfp8{zXP W}8'_|{o{*A߻Rh60݌Hvc 􄻭^z4p$j;j q0. Tx#EEZ ވ\sWa}-ѷt-GݻVOu܁ȇߔ>ZkS~~S޷w{7 ]q }p!z91iuct^ߺM nl~ڧ?'g[i?S_Oq6]F;%^2>nKю4t={;Ntgo:JOoZeuB}]%+^ws4f$VM^nEQGx(cU'2IQqoDE]"K}ЖST[K;Q;Ҭٶ; 7$WQ wN |ytAs)0'ƯaƕrJ7J~ؕR-!Øk|j嫑YvIw%{?y+u;?'z{k1]DN߷%}h/d Pm6=~q܎_;m|ލLP\d>*J7x4[G}ƻ>z(;hgEDUv()ΊPêXG;{;!'-w53DT)Tx, 4F}۵= >f!3&~pI~Lm^ۖv_o@^gwAɻeWŋ;7 ޷odWp]EYױУ1}+)[+1CZG4Y%ŇU(.VD~F7 kRVg{WQUI8r񘫘U8 ̉!Il"I Y 4M=~Ic$wPf$7#\HkPcdq}۔j M)8Ee߄Kp{ECG}_'jkn?5Ys&n]ªoQުOz6w}+˨oA4 j?o{}{#'Z܍uԻj7"ao$ׅ"״[W7Ӹ*ѸpMkb+{d6gv9I~)V cs؈nfu>VtշpհS1lF—1m] O,۪uVlw{z#hGxcO"Y9x/ZP/h yhS,&_vF}J޶:Aތ=G^oK?X~H{z#nx˜fC3m4)"(dcSoBo3Fwp663fԫ}$wN}'& R(ڌM6ǧQ))YR<d+Ĉ|DS2"PV4-w w;=ZE%[UrØad+±%ͳqz-ͬR؆P_V$ݕa'J@o#KCv$aI0u]IB~W$7*kvaȇijz-pzϻSkf=y:ZxyzbQӨ?\۷͎ 5/VPgΎN/a÷K<>;Kܹo.݃߃8w_\~u טb'=#r1 Ο_ o.cOѧ'ԓ{pg(lV.XVuD6Osng|>fUi\ zQxe=+زOJiu=UOe>uymOuYxO׶l(st^O9Y&>}VׅRFNL~· YUHe*]T-,RSv&l|^mk#Zt͌zp"8u#YSm榖צOL9õlZV*g$~3Z w?&#LیEh/^9W3%T,#ͪV9G*.Xe09S*>2PS[7 eBҧk!X6S6Rǘ ZpAq0 wY! MVɩitPmz$~8ܪؿb&Y3~0HUCE|! Ql!9Ej#9/}e3Sk^{]V5 >--*,Zts_Y0-KhW%nOk4XhY3b9W⅑ gi͈p 'L6Z1!~SpTiV|fa +2{gd=OỀ`;Lp09+Ј>@#Z,?/.'Sw8EcTp゙#89%;<|#q8yNx?zѷ珑s>" ?H Ϗ珩gD{D9-E 4Y%PXv5 GL3J"p@ xy5 ɽ>ٙM282rȝ_|HrwFq}$wW<}4o@;JP*Eg=LAl `s $4[-~ϣ} etH~ ?pxpH6FK5[v"pg煜_⪨>BẠS,=E?'8~z={I %_<=MHLNg| JbX/ߛDK^Jg_} mfr&G|8-Zo b}p"kX.Y!@zԝUs_W:E ĝe̘WaJ)MC f9M2ب $X[j5ر5 5I1W5 c_`&%2ۤj]XZqcR1 (JbL) +}2^p<F˔%6h >t-6&BrQ^rz6}1^=#҈'DM C͌&Fyj]2('ArhoAn4^4x9w],!cTjROƎ(mcpI(ؘk@]ePx*D5KEw1HO]S&dxi- hy2&!ӯT2dPU 6J&H (MOYd„I ֲȲ&#Ɗ[*AVYq1`.(nacӕ xyɄy%9$C%S&,%AtMIH@Ħ׊dȠmQ,ZQBdUuaxɁy2237VUWx01 4VF*r5xS&dzl Ĥe0E e4p (u1efuAyMa/$ ӁRɔ*/Z?i2IKh g6PQcY44\t1{;i{w[{w% &c .xwt)rޝ 3݁)ch!xP2ݑ*-O$hya;y1kK+5kb,ps`Zc#5{.=8υ) jLYs.ƻ|Y`o3T9#` 0e?*&1m8 ʱ45 nsL誃Z"ݙTfjH@GbTy@ZJ9`pcys]+g{)R0 %;xVx{g^>Íg, /&&:S5fpWXu*-H@Ƣ#y x<)&H&\8G0٤79 $,}8t5 Yh@STZzXXۤ\_iT8a>:Ű72x Wb}g c`Lck,dNΛ7"`=L!EaHy J`e '<]@Pli -iXh :`T>⎲ZI=~;C_e0ik0C ƽy:r>j/C6IzB0rA?@sPl@D'TVچB10%d6h`AtyhB MB| j XaKޢ .K@7j)s0@ӄLʁk*: ,X2jXH(RNc 3:u`,TP1d",Rf.2FhIcOK,KPL tꂃeeN0cUA@S8L^V @042GzQ "mUiB&D bv:TYޚ5:EaH!YB<2 yB߿)uPCg(cq·MS=;0t]cruzqY2'21l>UwV @oY0X,Bǖ* `$q+ v23dw\@}SaS) 2jTcEa5K ,_AYblUx4qVXDzPذuL: MgnFҤeLamN݌&TJ2Ufn{h,̓%dJ8P?%y]x"C,׭#Be} 80+ U<@z"[x޵qY~,=M,KUUw` >dUfHZ"ʌ8qD\aޡ|p֧0\A"YbƬ&fQ; Y]nE'fQh%5j:22[^n`dC*Q㥭soX:J? /6A;m؄+Fjx 3&5eJ6l_{R:WWLel;*caeL+B s`_4U /'6b*hx+M[G jVH>4`vFR$DwdCQ-)IlD!3<YSǶ8Fɐ~,{x9d0X1JGLV?,҄ȼ/mpTpRb](}k[Iv)է"GTvM@ޟ ḣKhmkeHƵ>1oUMȺrP3A!뉵TZʿ.붞Ep+es$Dq]%мl'>֜%Z23 c>%NB6 4f]L{u2VM(Tv"zhN[͘Ƭ?:gޞ(2ֹ&( 2 Fӥ%P绍 ;'kN^*|(e&[:kk] j>&j[V.BTE O!F tdffkZ B ٙKq_\pr^fFrJ4F RX)K֔XE(do9 ^d&o3:̰r5o&{܄2w~uWS &dxHmHVhFo&ZZD$~~ 66Ҕy0VLBTZ`{`@$laqC(` S_"/LK*/Y'b;W,oX]9VkڨՑ6j oMUZ@@:>K-оG4Hb䔍3POMgs1>uOlWQR&OT+}WdTֲ+7=ѣ%Бh)YZ(5au"Lfd%`*%)Ç=dr9xUԾ#HC ƾ4e;dǔSQ1,qCM$v{!DvAQx|wKRju;;R}+fǑ_uJvqP @cU:n9]z&}F0_̬&f-bfU9 e U zu7hm%&||3 qMʕGq&cSl}2SX}].4SI B RL #Ӓ)utO\ SSxj0'6pyt4V96zְHL1Ta6F=6ۜN*k'Ti+Ho\H5iOFnΆ長Yy0Y˾llH6Uc؁>bkEY?IL$i;-wfBjf^)D3+[56, "= `Me0cVUD~]3@81@#vJ>i78 3G3SJ,'!™k"&㸇ǐq,ۘd+V'3B8Πk,{ԗRl;]pUG0DP 9wBbe,砰RP3`DlG_0W\i&hN5a2?=^=sE\َMyb'ԕ.%6N['$CK s[~e3 `NRO{3b̧AyLF;I9_ >{gZƛ5& 7ԥ튲[ĐȻw ˎ.8tf<~ Ht#I6*)؄t2CR?|64CmyqIY)k| p'4܃GJo I<%C߰ L7Q3TvT۝vGI lCT¿R8ɯw T#<7QMXH.L4`^M lVkqO;6hTVN=wdJor2n"R 4TA}pV^'g+JO1I.Fȹu8e;+"Heu+2Fr} I"zb8u8fϫ}{b@5d ^d۸|f4N:!ԀūZup@U)`(s/"6Tdo(K*aY'L?? yS?euXk>EA%`.5\y|,6 OITP7c9ƑT.,V2080ye^֚Mnl$i]gXN3T{IFg*d< >)".ig0H\O˝!vQJKXǛfHsD񳘨ZS+md-C?M@֙mwy Le.C? :Z,Wd߸Uǁ1M4A-Yc9sfMe(2Ͽf3' 5.&eL}7-}CMxWMӓDŽ0 'Fe``+#_;d4/#GLϚkLZW6&(#Wfܟ$((DrИ'&(|A9EV|k AO3$[b: ._T=LKQrU ulvXEpY=gU)M\؟1^?hPS2Ge \zBhӞƱL4v-=ȰάӉ*R+y'͞NcΖ(6BV:҃9PT9W۳Ӎbhu =4ِ{=I';SKXDKJiEeN7nzKm8ޓҌ7ҵ)M$ޑ2e@80%ٹޗލŒw,Ic(/6|,[zwUr;rjjBq rvfazʤ"jNDwV;ʫ+(Weej)041j7}v㣭"? L E!2zuK`w{՟[jbX,:zܰy3$:;txʛboJ:lIJJ#ecC:0$"ACh:tbjKQ8Otw!%QˣO ?Nяc8Wkގ!:yM7 w3gvC/uo_i[p.!|Onq7y-'tYj2'(v냓gi[rH2>8&ov$m}paTxea13u쩘*)/GOOY 9CŊMA#MS&Y/3UD-Lw$tF#STHJeOTb8kb Dgf"Ŝ7h1jK&h&?R;K&h#yl:?ox n▟L$ҙJqn".1`W0K(L#_zF3ٜ2 ˆz3AgW$Te6 )J7h;Ѷ6)`3Zs.4˾2.9tދ.h9Ḿm-a󸲞14c#yP%)(b ݅ǯ}T^?~Gk~ؿǏ?W8???%?x|>{sQÇ?xO??׿_ ]߭~wc{?nyᵽE鑼>ϟ'㻏EYF\hmmkBSx]N0QʫajohlU&fnÃsfd,>Op3]E1T яjV2ڃ-p uyGpodl`d/e>v 9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)PCo-=ȅ,> ҏБ0P /m~O"x(m~8p_X@-e?:"XF0F\_JDM<Czjn \PPd9ZEXw̟VJ4 | G77 \c'ZOg_?{cZRO*p\ZrMC `mo =sph3k7 6NM87C>̙~J*Yx 2܁?ׯ9Z%P~[F1܂;' Aj 1@eHzMS +v+[Z=gEBU E(Mj>avdM{7v%#] Ow8TsqH=ڊg;A%2Jy _vusWb8.$\a7!c̈́u6p͛ [g"[ss]Nu(,xU!0UNMKR?Hp&ܩ1yz 3E\Nu=nYr+pWf`.p {l)ڶp!t ryy9i߲ȻnjaٮT.~9ZՎa]xD;6?x8]>eȵӁ'¥Uw:p$(*]N:s{ Յ@Jі[uOц;NUMU۬|@J[xA}b뗹-"ܵ9*|yu uqݐ1VՆ]xxWF8]Պk3UD8ߣ3' BKRNFV)/j="2y B6{^wMSuݙ Z- #B$|]luLWm69յygGDj*գ =\"0o*{2cj;/*do  #(J0sinqϾLrΩ20Ti ( z{Us/~`n#qJᐅ|7{ wmymH);JP_Ń:j{Y᯶nqa1Tʾt-9KيPd!9ɿ#Ա~ !b ;ۗ"0SJ NojVRQյ-3Tj/ ѾvٛݷȝX;g;[j;\!5Yܵ3btmkLGf{Zfo?"oށr?; 8 wng;^Me;|)㮉]'¾!8upnC:?hr8@6{B_~5aȮvZ_ߓXuug5cu ~~y?#^b cr\~K*w}p"u8>y%Gך:1ۺ{zBPުHm}MFH{hހGt W{cp[7Cy6rB_r6 Bխ]Oo8߽aAG $Kn7)͵ m!9I< w*d[G 2@?P3L\ݵNj|ykOg s?-TnS[pg ./-pee.i0ڶV WFIvfo_t ~>zw(D&LanèW٩c^X= y exdz&?hr8ޟd6{Dp^{̜[tpgq, uz@!E FwKzco%kœ|v}? x\mfEpNjp?>T[GveÝDԺPK[)vr%v,WX~m&c];~@=sFye~ԚPG{o ZK^;3♪6{2 L{v֔9ǝ=zP 1/|^ …Fo>A\.r@6{2 s1\xP']-A'n4{y͍,4OS`ݝeb"{ (Om&cm˝S>IJg \MNiqfZy!pqpqhr6⇭8v JILM{μ;L;;scܗhcŋ2`s5 V JQC։ CMd6_@;mSg]XmŜ>7 p3 .\^s\n \*a?z Ai'Q-:vz]_]Z: K69{R ‘^o.G+B(~X\I?hƜސ;S-ޔ{eRM |P9&oM =6K1ik~)fȝW(U"> zuq$*Bb[}6ᘅoZIkcۓj\whpa;S}MЌ;˯ٔ;ɯIMW+j΅8weV=CU+{Q?W'oDn/[qsܩ0ǎKZlC(j^y =* \{'Q!2v'G{r"ok]ӏyAU*WyՊpxxꇣKG gŝt+:NkwۺZq"K3_I[[}K\??O﨓+4M$cȳ,q6s',֌*̽@@SYC3Ÿ5(^6W@/x4]~+,[޹%wq1X%9|` :%l1M+zÝOBtNv+7MxT4Ȍ;rK}}|,]O+xlVY.s_?͒;sPcф;Qa/kY2Z寓+x vn>M$s64[=w:Jݶ[:qs1ǥyJhza&|z{7m}-_BQ9U ukg]qxX>MㅅȝVnW`F嫧 NE᷏vEFܩ'UVTMxu/O 9,s6jN;+t^bƝdsL.Mjgu㧚x/QaŝNlɝ칟ox\6NjJ#|)gJ(^χܣV\~o`%+U'a=ssyU:^>OD4f? 4zu%+KI<.V{\˝8,M;^z^^a_O;<ȼZ;k˝9\>2ǝRk6gUg= g? Wpt _'&y.s:}Nh/9gsG(wo_8#/;F `v"-w XyHbl'6zO‡"m|Ƿ94;}KGqWn7E>}ng$dd^-]۷nъ{u=s=T@k7xI$$^"]۷q:[E10ΒM'fd..ʝoWNQi #ne$$^!]Ɨ=/e6Ѣqݵ=^/4Ϗ$uRdx Emo7B탆;_jߓp}OƒWr׶a~p"/6X˭7$fDk/.bPS5f`۠";Y(dfU:wp_CewA"nפ gC/ʟs}a/Οܧ]]癫Ryp_ƒ+rg{dm~M? x3%{&{|b()]ͯgAp*o1pm~9jx{|. <6:Amm~9A(rMëX/vۂP_&r Ҟ6m~(~mkBTxx흍) q ĉ8D^>׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ףmkBTpxAqPQ$0$DB$ !A%A%Tu@Ao&&% Ns?slGHjsʹ~PuZU}//rی_/z3@3v5W];<X5qY5q g w@<gӭ vn3)WO lOT<F?lPtCCV [t?cO-}/vA]*mkBTx}+(H,"H$"#X$,QԈZs>U{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw)2iTXtXML:com.adobe.xmp Adobe Fireworks CS4 2010-02-17T17:58:27Z 2010-02-17T17:58:56Z image/png _DIDATxypWǿO%jcELlOp لdI'3;r;S@d+U`;`&ÙnL6v #9 >CRR[R.KV_ڭvk0 E$U;hhKPQT(RTUE]5G6eж-8,hwG +je q?}qctX}.)DoLιY3}heDW"[@V){Wh߲#=R4—\b c[vՌƇ FTF#RvÓ3Ed\0xAh*|MϾ$H:]$ PkuGlI;wD Op$t~XB0n 㽶Uoekr}p4zG+$~ Es'5@2v"]D'd Hen%B )66 /I;i=T+Oywڳ/g\`p0b~* Ss4/&ٛhK:-OX8bAoGq~Ȭ- z5܀knBQ~:*!Wgrr-U4Hk߿y4"d `\Ԁu7mHT;j01hψxGr, zΒx6m3bml464 `D1y 7'l>m 7$z5*?UP<:4~=k7e@7t5\k`=4e  xv#rMa^V6:¹qpMY5ٮ\AL08x!4” Snsqћn͏lt_e5 _B)YNCOZ,8a|j:8z`>v˖ g+޲X2KXY@kUMAdNm؈6cp|%h_7HnG {<`Ģá)߷pUnGw Op ܷze?3PvVR[@kek nWUk#Gm8˝$S{'t >gisa z,]]45H?$ >_=}k~t1#:wKg%.L +/}WY-l=\T`ut86nvqզ/]CSR.]D8˽ ; 0xz^ n[6g8ejFnJj7J|(h6[JOĝ3O[,B$,vxMx{WTO-f3lD<0P^=pcTBo  zYiV}!Dllqu]GĿWLv8ݻQMc$ *͋ϧU <H7̼"{Qz_=%y;]7<oR` -*#558 XY>ƀw/%-^+:Q Y7xh(,X@>ڀdŭ~:p1<ѯ',4=FΠ|'N+GL0BcltVռCąB+GJN^+:u#Pũ7BNF~SSƠ;9Wb$x9L6lrspA9bk4ԛTq#tR$dGEaف^pތ/X|ȿ~Ě%a[}] ch=~y8ggawq*s7Ӵ`O0z0q}:5,JW~#yҫA ^(Qrsrԭz 2 Ǜ.$ c0HvTV]-zS}jq*z gdXpy&4|,K!`l =_@)dN"t*cp~'i|BiHW^D;/`_ $:0h5T!Ly-E![W,)D8:Ef0dFYhixV`/ 2A6wЛ2#Hx 0v#p~vH$6¶j|=l܋2SAn^fr0e Q!X *z蒵AǶXP^"zEWOa :Ue+>cK}GA3ȫ"ix/x8x-yRbqFAF,8U6IsqBбI9Y.3Ja0\@R[ <π':Z4Wx:A41 >S^x|?#"j$ _ @_!@=q;{M&#Ʋrp`X”G;e8t}ڰa*' >@&З; B\9 >V*"liWE2۲I&IShU :뭰,,U'S!c2+/ X= <6*NvP"|,N# LpZnpsўE2(1`/msmjӓ^]2:uyjO:s5^ovxE, KEm0,ߩnK{ B+2F;xoEW6h&i@NDBn߮2bj D0ypb6x*3tg^> D3kUh#:^tt]/+oR)7eMi턚9O]U%XB?d(-rcFgHHǙi-Tdà6E_(8i [:vM7˙cⲂЩ5]>"Xd}*hoȀqݞiدO: ^FI`-o8%Y쬀]2cH ]a^ @p>D ~dRB中Sؙy^np}~7H1 /h0\&EH'x,,-DE0uaLl}Vp|Y+']c@ Bر&x¢`iֶ>QV*{ MpT,4.C0x!Vy Y9S:˵o[|(;0t\@DxRV&WÂ6}`. M>OV`t0`s+pĎKnX_icQpa >#*­!,#zy·8;(.Y̳h|u+Δƀj@#>krx_ &ЛI\YFI aP=2 Ȭdu J6޵3:zpFWL=wi+]>|N/*PYF@A?_'x2;Kńpf\ 1 CUJΨAiak!?;?{ΰ4K\!C(R4āECo]<>1 3u߀ov‘?-W<=Ǣb@\!fod;Sho'> Ce!SL&+$1 p;qn{$ 0g8L|*M$xli</N1ܞb2ŬY.hp"s(a` CGNLr|ޣlFIAIZTx ULC@Ȝgkv|އ;}n9~(YӲ^._?b@jv 4K ,'evk=.OiY|o#JNǚ0bStkZ,\s IF +ovш+ 3")/@?RV(F[}=L**-WO5^5KtJR @ ݶxlBn.F A^Qe!'^і1?!$^V4 xF#<8"`@0du[,Pm[AedRARy9]뮺P+kw\M87͎.@hfYyRPQ$[TºRĔ[Te~|m (R20IPJ²{ô͸䦗R%8&hXP Lb +@EEnDǒV_(&|R^x'JRZPFbzù֜HE 2Sf^7X^ \ 2ԜU+b2LPQd(YFLceܢ" 7d_Xa0RQKPQT`EQ%\EUTU)*EU,uG<&IENDB`hawtjni-1.0~+git0c502e20c4/webgen/src/images/project-logo.gif000066400000000000000000000162461142665006500236170ustar00rootroot00000000000000GIF89a}u*Ph)G\ICs~ S|SLlR Y2jpHk@cQt Y,d}QvZAbMmcJy!SsJ{ȖBsCl(U{;c|Jk:lJseZY{knS)cS}!\SPu⦺9] Ae"Q{HkFuQ2Wo3fS||l+d/UyRƑ]S{LrAjK{Q{ƫCjZKsS|u;r9jKsZg3f![}'Tq\X*Z 9[{X}Dr\cW}BkItݵy;t;bތD_1c0Zt/eLkSVly;jZKc\vt$`H{Zنê͊4Y;bbY*Z|r愤 Lv~J{r0\|Jk+Wu3fslŝ=E={N[ܰZ'[00C,S(J$-rRZ&lI \(2!&%`r pt y%,;ZƤv;0\2Hr4^w? u`AP@/?vg M!gy%8ƘʴIr -Up`uI/B` SU h!Mp9 B ; 0oAjtrU pQ pKKk@+Lg=`/u)/ Ƀ:]9}ʍCy  QJ^ױX t|@f4РĻ_ũ"mHe0 `;uۧkŐ 9OF `P G pj>)L[m K gp8H0թbпctpL14ە 2йàr A P tPtqE @>y.|p{+=og:p s_S%ܾ}A]?0@ߋp}Pq0 +S4@wL@b f =] : Nwc]jحxP#'-O :QP}@ 1 s*;9LG d] 8N0. 26 jBךPFP 0P go hp/e*@EO -m-Y| @@L"[n 6FsCd KPlP^. ! $@JKP" u䌰0|yyx^?$'华ҝX PH  J:r*0l*nJ˘)P36@W^?@` o ӐlMaNy E3j`B` ,w\f` ԞC^p˚m;}  Ф1[@ $oR0 tytf@7{;/`RuK3ʀ ]: $ػgx#9@` HHo9L@ %|@Hl. Q (Kc} pvHIA[`C??; Z"Z-✻s]!YT_\*܄hљĉ:n7-WI)Tv!N;-b;CB ȧ Ȣ@*@Ƃ5iN1|RH@:mˬ)1rs0i (9 pT2A h6Ck2;5~P %wP#si'RBv; mI ;ccB|r!~{|X~@ ԘaPp`" 8k L sJ K03"P $ X0`L,b0Tj2FFQnM ȩЅ8AMנM#H,:>(m0`H!H[餱:YEՑ2FTؾ@M 6lL!VpH sF Wn a bm6qP!u€Xf&UL㌺5 6x%Q:&N0 /6gx wR(t3N(]4,♀i(qQHXްp1y( T3 (rr>ޘĚF;TrkAVodȧ֓^!JC!v' 4XNӐX@ N MB} js1GY2Geo045Mkzً×9@_OعdNwt^U׶]:;:;Kڴƴi25ZmoQ(e3&cMZZJ^YT˘I)fJ3bu|Sw<3*G_oև~3҇"+A8W<҇ ©Q"[o yS/0"_@/(QkΓ^VJ ^2 O]LCr 8E'8Gk /ubI^m_l='vRv`<8-YeU7?kO\pp-'XN,nJXJ,t9bUYLJ>2Yt*GayO5g[XmwT?/|qxgιI[oW =p!KcdɄ>K&E,G; w0lz{CL賸.Wp%`GF=łm&vbv }ϿѦ~aNozwkv}w?'           PӤpHmkBF)3{hmkTSxٓF'۷n{yQd^d>*]dɖAҮi/}%Y}=߿sN. js] ;ɓ'_r<,_\\qeQ >R,_-.K{Rbl9>,. O_[^A5fp8(jCG|j0<=xJm@\/_\4 ]49ANѧ3{GO]'y|Nמҧ1/'#Zۓ}۞=<>^>^eg sc3NKn|xgn6f#g,oޅ{B?a?5:?1Fp-cyHߟVtXnB݀':G>Y QƸE[EHZr2Ru27xf1Fc3f8Jrŷ+nÎ{x|т^-/dKwڡ;>2K'Zw[rVnE*@|3]D6fh J9{"G-ƢH.Z]QEb0720.`ry\&819H:Hq/=w% 3?20$qXۓfcHU33pUltz>D{Sp7]ʼnN ZqWӽO&=f*cLBf,4&d=lϾlRF",BT#^&׻:PM0) 0Tvnt9fz׃n>xu`jg! nBo'F6cL߹DwءHiKYˑqӊ#)ċ}3b*/gߪ.ĬZU;$Ϛ~}IBO2IzvνDVdo@LXc?8ᔁ~ѷt[ʻ*w-Nh&BK T1J`z3[X\؇" ؈F>NLbYCaDŽyemDٙ`)f6LT;P+f.Gd w"ֵjV[9`+fߴܞ o|i4v1xSt])|F^G)y5>i#!mQD8L>7Sb}?-X9oGEYQNTn=\[ Ӛ9dWO;^fʥeT#Ӗ] 898.ljljvhT>?»Uve@Kjϓ}mU8XEt!lx߾ϟ;t12LNr\-fW7]!fۼ+eYnXobzEroնg&Roƒ 4S>\wӷ6OJ di+s=f-@~<$&4eoWK|riZ0g^OQ¿?kZIco҈.> +D ?S9#u =.bp]@,ʻQy3 mqחca4!җh~,( uLIaư¼;;W㹰0cC: :Z͝3$.$K߻&}T'CM%aXZϝoFÉ^GڤG?L}])0]Ne+ܷMt^]TtaZŸqE&" Ka9(;:/$r3{]}-,- >dO}jP..,zHAp;aIxn.m ݫnp_qs24;˺ĺ vcE׬yPHgr[Q w(o+҈X#/muG.t s3b#K\i`ؼK|GEҘvǰ9!VELE}huNAYӪmgߝ1PvzӞdbcK|ޣɂU?P+*XOF婑;}Eyk/(Wx`uy3u.agП*G7iLr5hAًӇ_OlrjX߲qSn<e۱  6 nMvt;VYyf7 K76tm T0Z̛|Q@kf7垢P~D @_, v{"oyd=y'؞ېJ.\|KYr=vֈȪe7| KbO]uJ*|Skj}u鷦sOϓWFKcii܆;Zd0ź;: R*KjOmt/w(+vtg‼>ff=vj_Q|Ū?_nԚ[j%\ǿFܢձ1;mw$s^<ǼI>֧slu|H ] W:*5U4ydX4elTf 8>i;c~]}VC,򞺠_;= ARU#zc Dt+>ټswdM*Ӆ"'8<ۯ҄u?~hlț',7OʺüOI?b_8"~[Lc*У{6{H%pWx&Hla ˅Tk@yBo=wާY-xTEvs[rIzm[ɟЖo#S0$Yr|䩚)['o$Agꩈto >nSMoh8D4˄Mv(tS͒o0neqz1ĝm+Π.kR^mU@O;7vTsI~UEԬZ`/1 V:V^;TNjkCK]C"{rz19'SQ3FE-(cA@^O۞d4y{y|t  ,m||%\{QnA' . ^ـ>|dRteOS#~D{ ֕W~E+wG?j\K^Y)*Zh-iM>=nmѺCڃ5뮏Px6u*nD"=XPq*|Q Ţ좨* 9}L+ l{px"-,cѝZ8Qty݉/)"ώǾ%k=+ᐨgBf|~׬+_{X+?@SœܴW ~$|lv{ =Iqow:Ԯ`kvv늽vkvvdkxƷu^G_{{CGs:z Pz[C{ { EcL׾kvvyy k轆v -zz ݨk轆v ڽk߲}}^guu;Eg*.h}^;s[軠w{}tonW5^ComT]ʻvkmN^C k轆FCv*.h}^C5t*=ÆVC{Ӻfu $fОmc, Suk햌vnh^ #YՑP7{xe[5gU~sG557㶦݉?:~úb5k"h\Dqܶ'X5z,'^?XS AC 迶}ͽk轆 VCTlE4.a߷rk1׊N)Db5?w%Ɋ׻Z:^4 _7{?ajoYHC>'|~V'Gc[7(#;{[q0g7))gdђp-]]4y BSRjSZ"e޻j͟YSx dx ujחGJ{dq~__f-K)o ́󠁌?4׭` g# \c(@51j~[5Y OsN7"Ӂ8=lտ:;H?~ NhG|HLZj,o~wi]ԮO)g!=] tgn78"tĝ㶮񶹋l'a|ˇ#勳#ΗJorMG^ezJk+m83e4}w~Y~~׍y=|Zm gHPW.D9ljV=-SeF{7Z羷v>+>4=%j-½|;6h{T>%o],jR2VwA,WFq{7!q~C8L;P 8INIeGI3MHLODz7A߇YMK.R܂l ?Z60*BF;dwAŒxSGD) }ȯVDǫ,ڻ xe_u\n+w]xoC?<~L  )lFYŝBz>yͫ%P'ѐ|.g\ߝ (k$ һ*;oƸO G~z3Үuwj:iX{*pWp\`6{rʜ/o Mq .X?OmgwﻊWTScXv{W1J3u _q>Mhn?lN>Vq_:-CRXX[_w[Q珴ĞywՂmTa45ׅ&WʄWOmjKHeo6]=Oig{Pٙ9N)VO Im,67#Fݶ%] <_ՏZgw\]!w&zJ("wtn맯~gjCݑZmv+^+~oqMݺ0iQ=^ ֽMf[(O^ [lkZWmNmsv*ҭ8W׏h0+mut_\ _ã"Qizo+YkόM/ 9!QGg4\֧b§_sz&9s|>rVO9_ƕ 6ռnZT<\Y͊2lq%{]+J3u߼J'dUͧ+Sԭ(|st^M9Y:<}VUY7+e@ku>хg1WM# ,+xƧU>-y5.rrKUͲR>G䫥 $DQ+LԬ +d<-T5bZ͔25,x)1Df%` 5t&D.nrk# _7*/IVOkfj.[Q_C[ȚϦYVZKγ!5%Y!WYVӶl<]iV >jɬ)+2U i3=)Ys^Z _5e0gV#9fᓂxRY,W|L+<cB)G8z᳀``tf:1&`6p1чhD_GTx؏aNx)xb?cs#q6")z<'g9yG'hˉ=G?F[gtIGZ^|qJ׾xB?Ssp'^P/\\K:,Cx׃tw=v9=pl?-G˳e6Tg#f}s̽Y O<=6O)6K([>~B=>ӬbF4'IJ K[Lc#xaHWgx/g/u!~|LFg&pPWïp_D6͇Rnü`ٳ96×/#ÜsQ,_LIn%~1#>< VBR0l? L!`X!!1)R^Xeݣrm(TP#Z`U =b#6#@,TF0=Bd&"uu :u܂q +xr אq<~NJgOfk@ 3lk=Zk7Ç95a6}fMp۴*I7#Z_k>, cGodq@l3rDTfT >e'[ɣV PJ9 @"nS$A)·V O#udeIDdW 9LnFFܓ3czu.v`>T!A$ɣf@ڱ(DPh t.|Mlt.:wTЋ&d/#B&AII"TFdd"08W'\!{1I4&!h lMPP@i8]S4AI4rEVtӈ%˽B3Wf}vp<>?{=ŃO,a1ZGg%aC@ ʆ ERbl P+ʅ h Q`(l|sؠΫa'Cs`tbI8 muX>TVC #ʡu!f hz`՚(4OHeA)4xQΆS;4)&(b0qbQa`{(yP2 .H)^ (1ubHb8-"p+. ӜbH଒>FWc[!x!& i$#b)2jZ[cȌ@^!B4I(zؠHLw=g$1EA⽅PDtLuX4,:S`eֲ]iF|3G,f@r VG$fLV{2 6@0ܫIafѧCGo 9TڻEv Syp@ 4z{p>36+،]yM-a ` u# @#uڗ:r O BgEAQ3d]كa̳du \L #76&02 ,1QVQ3Nnj)r>(B&9V!RS&G+#(40scl*s`A6>I2s1=6}Ao`6}r &Q,끍ԲQg>IQY;*b"QhfC=d3Ө>dC3FRTjEK Jfycໜ͢frZ J.d6l7D,Y'ZCLstmk ($L6%JҭjK$CkdH jՖ0Elxvfyd: X% $܀iMFՖ0CSOkc*V &U2HօAf0MČJiQ YAbz;g+DK3sM7X MΘsPޱxS2N@w9_òVt*j!ĸIdipujB;.#'>TI1_IfLAܖd--x9Τ+g]ހt6_1@ p =.+e4&6Hf`_IM:_1"h|HCڝH4YNӇ%^a0 VtjE0@FD`]䛬GLD 7Y 'EH (a<'5)yʚIr_˴e3)QIsR"φ9Je8)OJ Ljq[*Pb4:I\ S%kr fj:۳eRC<Ơ_8+icv:hbb&<7~bEt(`jDUOK@dpm Bbq%9v;>O ý2gTf09rHQx2Es.a1%A. p]Cx P!Ӯ l}]\W J]_.Uvvd>r83||KrVnyU骝PdYADV`B(]ɨ8:!kڧ NWN@'w]3i~Y XLlrTdžHW:j R]]xP)֔Vi}2Zr _:w1a5Tt JR#&75s .U(m&D1gX陉6 דPyA@3| zJCk@0K3RGisZsU] oT Ft9ƙYq| Wap?LuN+Go 2g1UaZJt]1{4 ׀_T 1]I A!"Ud8KMN@wf-'+948cl-&Y]$΅JWL8mTM}-`JU73RKxA3׫p/t3Ӹc\I*nFhs$v%{-Tm[9ߪzG]o)pS„`0dYL ǯv֤Y A ,-_f͘H  H,R9:_ P'fW4$2Y`byprM)c=f"#oΛ`@ {9y[$ EA.#TQ3<ڇ@8SH`3.0ǸH#7Cc19d{l$Xy$R˪@)19I3w*r 8=3ہ%:S4v3sne#Qx(h&M"+HޙB׏V3?O=O^kW.|'5?8En ӚLMX1D%REX9pW)UrsL4 ӉYͩՄWlEW,߀~NIО^Y*p9 B)Cĥtq-YMp78ON!N@a?z4y5penލ5Y`kb3i{VsKnw ܪvMr &_]AqJFUa Xhswi]1߲h/$^kh0z0 ydn,}AeEn"46nҗ6@\M[ L0B)>ǤҴbۄ|\%6=mEn:g^$Qt9.s P\+:+Jp,2d,xVzҫeUMkn k*pߩdɦ̓ VKòm&8=[H4m&ĝ&t!p9&-Ẍ́ ui3'm'3 NNKCXy͜hFG(Q)o&ҥ&bB8WNlʸ%d0XNF4&gU=vMq`el=Bx"D*-Ve$LjrsBI$n@9`hz&ԩS^Qf.QʹsK=v͞8giV`nm*뤏VY#ȦcGTMǝ0[,V6p'{3C,i^oUJj_wPW(ˍ9V`>ܒy26nG~qW5;7 U:ora\-f҅.>Lr |0`c|?ĥ^nn Qqt*D{81.BZSxkS XUe@ndXTK dz4gr{Cʥ:E t!~'.u#)@:=Wv 5C?˕³z![%V&YY'ͷcs&>zJ[m/Oc"cBW+:^O x=rcesMLũeWI+~~ۥ2e.GѸ'VlQ 8VG-mkZbHV2Nf*]侈MshFF-22ETĄ4oe( ӓ>)rܹOW,RyMR-ԃL,X{_"i .BVb~V(ΒFhp2yr5ùztlV _: -R=VQFA|3H)g<4"ϳz >P5eE)$ j(iOlʮFC܄3Ec~[u1ZQʠ {TmՅ`}_= .5`V]L^x'O{:5n7>k㋬WP'7K7cQ~g;uFKXwDnj7!AtN:5pϹZQJ?Zq[wᯑI%Ca;CMc+S-$m݅恇|!Xǂ&a8mW^R8@SHM.z_uރq:vOaVAX41˹ 7.r-==-iglJ xngwP^}⯦IeJ*=\v\IZAHh!Oor.(t=}bt/7ߌD+z\34uB,JLەEDN=G, ͮ,ef,W/7_b{=%?&I[XҶS|y[%z0Mf+mRe ܘϵzNfe1B9WO{q"} fmV?|  1Q3> 0IKYŽ„:fmVfDVd@7!t+U ؇鱐lqr/dZg#:4JwYK}h-{U8df`; &ܗT iR$m];qhc:Vr`,?dZ:˵(eIꢌwP,E(efgΤ`iMHZ. ͕~BFWWٶW2X/gg# 4487~|,/hF ]G3:|#t#*θ̢⑧Tà|4V< 9|{i|2W#FgGx>ڃQ?Q?b\Paӫigp[Z9Vg|]u8pҬж:svw~>u_>]\Vx`!,88?Ή̧Ϟ0 ~^P̓<:E~:Gg3ڄJrY gg3lS"#G^~1~6g</ώ/Eɡ=8>NcGЯ 'Cu֋gxK{pUْͥ2Nt ^)XA>cb^kc`/Oy8>~{0[>Dsw x,|zOyx%>لل8q9:>ǎ'Vߞ8JgZ8c,|7ƁZ'\'ϱC {1:*jj:vjG􈖤!ϻ:6Ri1Ǹ ~.RՃGgB;.8<%OI>_N@]jyhUm|bĶgIY?=&}qawql)Cs|AaOV` swD܃obrga^yG1چnF.}=XM``C@'k1n ;qI\NF_[NаUSd] 3OF $3J>J;0&o[p1nKk&0Z,qN6,E[r%.$,mf.f:]YWPd%QlWrzWĦo-DŨ$i" )DLu @V]t g$?nd3L \%]Q>+o:)"M~‡:>ѡA;+L&_z{U'b/YJa&f](\H45#9"~+$\xˉDO ns@Or8"|rnZĿo bxf$ b;oFqx b͘ w+E6:^ƃ{:a?ؼj -ЂBtجQc s Jz%xZE+hV7E$hcƏ୔'r$ڢh,5PEiQ, *-|*si!/wu`o`ӹSK~s7[0^#C27-=i<&a_;]8[;w ]vLWGN)7|XU tNsU${' &71݋݂4g2 Mf,4& ǝ,fcgn~e2R!eR爐Q6XlIY0?p[Qt0+p wzÎM6S> Ygu;Ν*m;װ>1G`%#mFJ[bDZVNa$^/Py< g8VuI$fת:F!tm|LzI-|xs='"xbB` DCxRUkqF3)DZPȧڈWK#ߒ>PF̗6xtb䊿&䧖+l#[H1aj*-܁Z(6s9"k&U;\[8^7c%TxLIDѦ8'.R$ݍ/fRtkr%}baOGAGBڢ؉4q}l/o((?~R[r>4F[Pzps895şsȮ-vԿ̔K-ʨF)-+ԯ3qrpl],:;>#lѩ}3ve@Kjϓ}mU8XEt!lx@^cdZ̮oB̼wO:ʮp–.f}ba )Uۂ'c?H~ .`_OpMߪ,>+-R8lVm+hnjx0藽B\/S[rcyeziN$Üy=F fa3kM"&qI#&a?g$pwL)Hv0n/h{}wMu(BF((L^_% ,Bs݅!Bm - ;өSx5 ;6܉o!h8mU:Rf\wY Nk |Hn?7#i`-=4Uͻ!Q> wT$iJ} [? bo_TȻΏV]t=v{Y e7홯O&6ĝ=q,Xu` 3 %ROBUlI _W$Gv;qf\Lht{ki5ߪ[vqr^L3mX(k9}<{uq\"y|u\kjBMICJ n5(ӡ+0Bt*/?2r$N6x0E8*|I3^UɇO=.؝ڤؑ7EU]*\H:I84$j5t{ ;пf}~0L_5;?{z.eemUDijT\PngLCogvt{mCƀLżɷ>4ykvhi)Z) EIĹeq͢1O=pn7IK9.h)WHywҮI Ikߪz¥|%SkjȉH-\v|Q*څZvcʀJ5F-mچZ9j=eA|uXZ=-4:L.ŽFҩi: ʊ] 8 FlO]WT9_j|Z=v G ~';ǴbvdM/]Яۂ枃ϠE]1Y "v:ӕjl^9;2_̦lmGvʎ eߦyTf)*YmiBZ:ϟ?4 b6͓h'ea^'$[گu A~e}-&1 =U=e+< alj 60 B5Xd7;f SYk<"w9-9$u=-VOMh?)Fu,9ITMŔdS>ݒ<᫧"ݿ-6VO6 ȣ,:65` e7Y ~bí,Q/ݿmeBSkMicƎp.үP Ł_|dRteOSc~{ ֕W~Ek s{ԺվxMb{No8Tew>lLѺCm5x뮏Pxo*BD"=B'I'Tm|AβEwO-s)E#2ޛ[X4^q P ;;'qF躳^% %\j1!^'Pb:VݽAo}joH~&yorg~uZ:$?%*!{ =ɟH_wMj|и:T_} v5k轆kkr:zqi%ރkjyq5|^C5uk|z{h?9 =&^z*g؟pξn:{:{ z]CǺv;87Yyh}^;k;E;*.h}^C5t [軠w{8~w{|nyonW5^Cʻξ:{_y{W۩k軠w{ е>  Z ]YM몛%73A{Jf.ySuk햌vnh^ #YՑP7{xe[3"Ϊx-?Wkzk^CocmM{t9u"hz=x(d{4twcx!c_szt0ۨ?iQn~k՟?w/hqVʂM}A1:54KZ}5:N>7| ~jUy %p\mJu}jC]xIZ Z4M(Y_uJ<av yhAF77djO! CIV ʈ~cos9foK>N3=ACB Ν z@ "FڅMJ4_P͍ź15k8o%>;|]cV+vyFvM'}ԸSyz~64_uxۣtߣ]sC wz'Hy-4VG݈L{X}_W>@c>"-$g[iS_;tZ=wo7ï'$[E%eMi $eyhs~#ԍVZYw߇Bس_Y kdfmͶ7gW_- o[wCd}8:{=,R[|\i3RW懵v?vJ[-?!Ü%Wq{9;GBu>w~JC{6Dto\S\2;Sm6;b-=һf|3{[yg_ʿ^QMac^5hkamla%ŭx7aQ;yiYhCRX]_?ۣ'i= QшHjׯ L7{M³~UˆlZuL-{y? >3͉s-lEY|Ud#ݮO@[;'>QcIW}W֟; ۛ3ul~YP$ez,Ө̵v+#~?oX5V#e] ʞV(X\^C># sLSMyOōծKG N?q<\ш]{$)2' ޸LiEPϒxcӸoBoC{F}w3y5|ilۣO~3͎^HnppzI5X]3} JAyȂ7'[; &(a? el}ͳ_i0H iZ|z%[UccNwxʖ$g5p37Ja=BU#~Yӿ?{WzKR/1ޏw/WّEwv$vkWׅw%V]I~Ī߯["f?;ckº=yZZx9:8{yxtvqXdoy4 z4M#H+^gϦNN0yrq%[؞{d/<q>= \>|\#w<| ((_\\P4pjZ<}rC8:Nh$OłOLOsz,| r|O9+g+l&yfxe,WJWW*'g΅1TUyOUQpOW[Q 鼚s*txE#rωN# LE^@^,.p?{ m4ʌ1pgj W sxaSl (iCT G6A%l3M4G/>Fgr&pPïp_.C-Oa^0t:_˗aι(/&$7z?˜ p gzdR+!T)nqJ}Đ 0,CUhp\`Gp/@2Q9GPLEGb(ś-DzL1c@j! g*g#LLM!DTRU:BnAE丅؄pLhV3&OS ؤf/ϵ 1ѣ7 8x 9d"d3 92NQ+H%g6:V; LrE@HfIpVݠ$*#`YPCrZۘ$Aс&(b(B)C$t9ˊVX:Ii ^!y)d3m;\=yv'}ذugbϳtVﰡwkw l`R ea")16lzmo N4 (\0]6|hp9l U0eѡ90:QC1T€$bs:,*Q! :3gsc4`sg@jMMsVz\ l(gC~\szgp1P8 1C00=B̼s(ec/xhp 1$P1[g~iRJ 1 [~$pVIIp#ȫҭ<IV sVb t4WpQ -rd1YQdFs !ˤq q=d{ClPVx&Na3pC"H| pkK xD"V&\wºQ,qJ)@r~T`k̮4#L#q3NoaY# Q3&=kn B bդ0ӊ!gXR݃^yu*";<8iD^qdȽ@8LllƍLGxئ0 0M؂m:P oT:Kq\aЧxǠt0Y2@:h@ }JHt\gf&j\uYA Ky({Өna`b9CD!GŐL))c#蕑`I 169 Z]$Y>TX\IRH0>9^(rFGj(3(ЬOB1 ~(J3sfftf!Ǎoi Сr)z j5r%3̼t]fQ3%P2Or6twJuZ95dZ& `Pe~P%V%L!p52]$jKP6<;jR]!O$CZB0+ :5 "R `B.@M֣O&VF›,"$bw]0cÀ kneͤve2ܤD9)gt%2'%r&sL8-NJ(1TkDgL9r mIJ t35zY2!HQTc /41]Bps@411Cbhx?1Q"su:bV{Z% G6w`! 1BJڸ|@N˝ŧ^3*3Y(S]V1YuEPE:Q'bJn!t6FW2jc.ιNȚi&eSVb&C܏<ћI ![ JGpsd\k+S;՚* Of@kYK#&,p#pVTjĄY\[zn!bBpT٥tz̈́( +~\3"=3fA9#z:88o hOAWthm&ysF(X4m\kRY+ *PSN98ҙ6 ΀Ϣ* Ni C ћy CbgyTovJ+_oQ %z cM>@@lA0!߽V{,N0r!UܗZUVΕ? q"OI]˭fS'Ȯ| 0׺']:uQ\̹{иc]=XZ;;w^je%PH2oJ\cD-1bDnހ=aĈ̸hM%3fXݨ>(o-}&VH "dզ]#'Cm IdZNx_K+8|$ɏxr<$l]Y>YBՀ T@ ZPu`D@v߾"<I<9rEI1dq`+LvSC$+GwLECD;ni즬xB"&]M42a 6 I[b2|*β[k!kzLLUimZ޷j@RaG-5Vc'\Rf|`8|M^R-b?QS:ZNK%5whu5_2ב)0AB5֝m'@:`/"8$r#G%%gEIzO0y`I"TT^U*0Zt5ox_^&r I=]Jhy ˌ0fV&^!Z:+7,D@V"gbP`# ^ˎW V=K<ݓR-1~%Ze++O:%<9jWY ˀ+.pfˑ~h%sխE2lyShT2>K$QU͝x5ɛuwnՐVge3n br==)# V*˪.>a'rwK2r*=)](aӾ6^re nw`Pa}LSHU(1ѓcSYˏP qT$ OW30Tj@*,w4>I1sN R] MCg<۳ F1  yו,e.&6ƕrA|׺W,I5퇁{k+&EĘ\x:X\\~{TA:ٵFtfld u0f%/|-{39j8Hl"flJڽv=%1 O;#"6F?7}iwYv³QE,ɝG_fȀ4^N]H#ʿ. &Ѿ ㆌ.#A^bRzD<: .1Am~7T>2dؘA~\kmSh:3+@owJXC9-Ó)qI'IH(RϪ+?.i. z%󐯸Z3b#0` Vu A\X]Cpj@^ޮȍć'+AJ9*1j -<0Mz3qmn1c!UN2 ر[̆Ʊ4@حebgcmM':Aq;vkaix柋L|ۦ תq pQE>LRnA^U?_YR$U3@BWӵIFĶ9/]M#l^A\N, XS{JhSlZ8FJ}-%d]sj"0Fl!R)0hǕ+xj&.}75Y;[lSLHۮlƛQ^2~߉*R90qQ0_ū^,,CxNk v9WP^c[~47%Y*V_FA7.΋<ӹ \)Xѥ!OI~ IZ{i47ϳI*zSTP9^TLfǓslU&.k5@ma{v\, Z(evRi"E LʲcvŒNNExtsҮActfR9~>cJg2&}y٭;Dm+ܱGoS'wndFPVՄ.&7-nJӘ:hb%sLϥTRd>=8+p"1lu u['y50<2w{:<~MNă +ݞN% Œ͋4RQ!3}_D7.VAAv+CW&@[\(R}dA4df'"$*8W5U 8 MOg![Ll\̓i?G[CQLú{`ùtpI֩iVnr> Y2:= t錗z66D NH,X˙;3dka4-)#ix~E>5zGUg&Cs+Gj3T\"Y%_lhl.ls%6!ע3MTme"ae{,Ԇ.!?NX26tL5zsѹ\Bl7n|TY.XIգbql&ǗZ-Jm"Z"*r2> ^0~E \X= lI[ƶ|5{Q]v|M(k)F_>֜/H\9H lxۀ,r!͵ge>}To]4~wD[3m*K[Q"UzrYsCм!Yk9u,ќi[cWӶDylICg@ѝ6Uf1rit6ϖ%tnGFJ\'ЯC<1fmc C$dF9 Bγ&݉/lC.RvelCiU bͲuOrrz-f\8>Y T̴ {M"R*3p.qhƍ`3^a0?\^?҉B/ ӣ|uj;/O? >oHxy=m/G] nSa=wW|ū҅ .rv _,mP?G?W7wKp\Z|]~ݫDzN~|E%~[\^¯BUHRʀ{υdλu>_VCKSкy3|7|(fq?\.f_?!+0_L}wXz{e{xoٛ?7nޕ%W*60mkBSx]N0QʫajohlU&fnÃsfd,>Op3]E1T яjV2ڃ-p uyGpodl`d/e>v 9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEmkBT5Lxama`PP a A('U[mzY}^XX@Ϸ,#oQHc{=X=e4Vw#]Hc{=X=e4Vw#]Hc{=X=e4Vw#]Hc{=X=e4VtKѬXo͚EfgΚp쬼 gw8=8Κ]RY;R8kfGp̬n?8kVG33k|wHX;q8G=`-5k]?~}ﻟﯹDV^58_ gZ8(s_ gYGbeYGbe?9=YO)u$VF|f-uVN/_I|㞕lh̬7$7Gq*`J!B!ck`ymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)P.J+E]ZU_[MkѩTLto&:7}?"۟!k),߆gcnlgg;?Sޓ󧷎ՓxsA'g7cmbKllz2oI`}m FȸDc,,mUqV? }O5' 'c->~l6@A|2O@,> k\~bU sfcyOo[XwhM}O' {>mar|-Gwd;RG%#ښO=go[sr羧d#׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ףmkBTxktEڀ vȅ E6 +(w4*,\W2 e3 \ "  (LkoUWwz:=3{s$y߹<ȯZJK=}DhsG@ i s_ ?!\4TQhuvkAmDw{; Mt倗 yЉAw k5JNhkA-F΁p _Xs@`T"iD>/SH}sd6G;D8 v&7psh!H\PQ́hrw{;$~8uThP\vxE\/N#IxSB'3P=!8S㿑ֹivIk;Z׊Nd&`P;? Ht_\a_93^]~[~; Syḿ;a !zkXz9ۊ޷1(\]6Rv߷w4,D{UwyFn=oB?zrn@؂C-;ȆwJD5ɥC76+{]i\b:͝v+A~>|&V1*-SֺݿQkCEp56# ?CYso>}&G@R =N}8пܻywy͎9d?BFɒgvͫp|?#eݿZlj:;ֹE}~ K e~a)߲@JUzp@B,_XpON+YΉYS)43I9r@kdߪhP1vΕo$@ԍׇvCaK žwNga>8Snj :g="~U-w'=)k7=`TDHlt?;sI:-)DPAe{L‡(9d#.l3o/_c܂=X6]&30YuHԬ̚"dyo;b{Zf"}tx'5{Yq?`2{ߝ+2~N6ƫwBFq/;g:݋d;ݿ4x }k8IO՟/PirVVy/k-aߧ_x+ZٙA+)NB,v{uc*b#m=ƞcUg:yҵ]aܿEZ K\(${y{cy?ް}޿NmE[)ɰ_D2!+Igr.h؉QMm;pzXܫGH 8vټ d-q.F:OtoSyߢbݹMߏ[]߱U/*4yPRᠢ.Q]$16B.)w}':ʍs!ダygZrȃpib_4/i}Fow(`Q>3Rޡ=TtO>B@8'yo2ʡ_åɿC❲ϼ+oc}yw3#@YVcmrPPO탳vS ӊw:O7IxF7y?Gya{A'hr!y hKЬC1>}&ſ/egC֫^7WC\ϐ*J13}p/ 2!pyzz&w_Jx |޵螜ag@kEv ο ˧( \(1YZsQ3YOB޿aWVɉ rC>TuɅ7p{CPlMppd{휧O [!tt"|(H. '=k ˅+sP>x7tk?s⁰33k_H|gy q~w磤&%cTX?y߬xNwOfuzjtGɃ#H]N3>D} V>8`G++ O~R;Wy3—@9(gDE{ x퓴jyO}pxtO3zxV3);&"y%qs}p_h2}I!%)#yjEҹ/ۆwk+kˑV2NL,f}M>8h^ե<=vf~ 9:;}WN_ ~ A,}pO/9;g>x_]9ǏIM'><ͅ#Ff8ӣYaV+3EZ~s iúyB6sbՙЊo7nnE6=˵BR* p~~w^r(Ԗ +c3Ka<(Ʌ/~3 nptSjr߾OZONaP~=؝6و /Jx_E@S+ ]'1Qv<ݥwZ}=;FN3gu7sr.T. *_[ph^64m% p~ȺPy}eyb=YYybȃW/Uczų\'kuuz屽mwZ;6-~;\ʦ)yp _۱W[ _o+6~sHe$."}t?!grpkAO׿j8GBs"V#Xρ{\;{ZAO?B9R]=ntWUz;]Nk5 0IuWɅål7)ۇ(3amNpw:/=/8|N72?[;:hkk}

4;]?8NxWJo[b:9H>d&];;=5Gcϼ?,q|Mbk>9@QITSiwl*{X"n:w&o̿~t^7xPhB}dp>z/6>IӰ5k`}4cr{Ȼ>;ޕgfϻǘ2I]Ts>$v 뼼ipz/>e4~tzvw5!O+]MNÁEeJnoxS7w{; LȁvM$xvM(2 9` w{;&onoD×d<0xh!_'Ar t noLB/tׅyhF́E'6xhQb6no C=/h0noLãZHλF3tH$ڵ 4yw(xhQno҂w{;nNvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq p-dK!*mkBTx}+(H,"H$"#X$,QԈZs>U{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw)mkBTx 0 7M zOxmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm$I$Iw//%2mkBT9xaQP#I$$D“ HX H!'7Z}34{Ж2mx4?3s$sԇ,\\|BQ2>g|p|]ໄ &C{I!e=_|B).x_{=肧 >!6 ~&C۴ ~&C 9F\2'?O B|L fq =FB' MAqeޓ;OK}׭rc ̣m{,䱤Å!mCrcPx{K$()|+|B)a?zu[_.޺5Bx{1>|J1qGe ^𹥝3ljHi{-߄|#!xu'9?4_}~\sg*=!xׄnc{Vykj!x5!25R]=/i+!e<L~{{s O =_kK[Qr{[&5g7%ꄽ}[4>? ;BQ웺4ׄL kZck秄6.dy]J9y`d>Ӛs_;>+@!B!?s%2iTXtXML:com.adobe.xmp Adobe Fireworks CS4 2010-02-08T15:01:33Z 2010-02-17T17:56:18Z image/png #&.IDATx{[}?KA`L VLZvvm5rQĊ@A# 4[rд~! E^# +CǃCAh/~52%)A_꾍+)Dla=ƖM _EAc}hAN̓kQS!AЪ﷗z29T{ŪhEqH\qO[/'fpVаzkWg۲+1"I۸̗8pq~DCUo؉7y8:w (1|> ˈ~1sigcz8D*|\S*lfkFJ3__DSNE>GJ9P{ 1PmnG!j*W߄B1yc~ IN%UЈߏL0U*/#sBá_ʭS I$U Ѷf ӔQMg=ՌqMG (P>/̆  7be72`E"UGJ%mKY_ ZbU0FAhxI"VO]Neװo H OG7<,ᢙm&\iA@e"V,YXuDXJF\ -d|y>7<-^V$Uڴ|[F蝂/ub5L| r6umu붞}Q}EkB({*V%4Ob9<غX: XMFE.>{l^˗W۱I.O$1D{=Qamjo.^'{;$kz847Cc{O0'ͻ<,A8{no3K݀sJ|B59PZʱYՋ0#SGxƧ4AUwڂP?UQɩPm,A=x nNjtZV:]U[Xj9vO킐=[54ǩ/@'*dܲ 뗓^ށP'ijԟas)ܟӨnFlKwP)~p1;޴XmUvg_>>%V կ9V2%NEΎL% XќLV[(7W5(` U#Ak3̢Ʋ דzb.v۲-t IM6hJΎLE ײ 5LT9i8(::PtA{rʖ^æNREC~UMCoCa .uDp/ڳ888$<EVs焀> Bv¶ߌNEvt*YGDh!e6ͨf*Z@fNOAGV1;=΋XC۴x{Ԕh0j:4 -AA;խD?ybt*Zvwsov;kЏW>[XW%3auBb]8]ygWhJ ԵkJRWs35W]pؚ+Dfmr˛p$ 8kDu7Cu%eakF$q/VNWenxnnEeq=.|R4`n)#Ğwla*Y)TV5Fum7^6>U 0qh^@w9sЫJX~ƋX8{8&L.n)~n@ avjFT٢YǞH#QD<06ʛQJPkď]żz'm5 ncleЀ&<ֿp4*pK#y(^j/ ]`yl7`UcM!՗90JLTy kJCGu`_hw&~ZoR(&c+IwQ't:Fbv2p%18R޺rO6x}'\QgC:Īܦ9fjp|c%k}jgFiיBgtz7IB!Al\WQ'D"ݖBHz86S;{NY>qU1;q{u<.kk:fǬoR@O>z0ж^6Ӯ"ĭIEZ`nh!>ziLdTZSEI$ 8UsaxJm7n|oq]GcVZs `V$RVw{軣N%=Z~)}(7?{>-\7Edl7ϕ9>vEvR,m2^,(T'(΄. 7b%kۏ@fP=y.kZt#U~se"eaҸ1>s;RŘMBHܳ͝cWMk,Te"44sq~ewLl6\8dq`֊sƖbwvU,@IнBOQ:KZF٧ 4L Sxˢ)/J![K \)KFy7f [YGԡ3tC/`yWy\IvOZDgd;[Í,)Y N'9.Pnn%:47+{'Q_זa?22 7{EZqH\J(Jb5pe GcOc~S#tWi=sNpZv) NqΊچ/bJL +(|{k_R%R[黙:y\pҖjF/s<iU*ݒsxˡ֮9܎[Eq~mF>a|7']vzv /-g lؼח]%R*o`OcNa:*Ʃ/D%-dS_|K7%W^o:NuWqw;*XћvZژtVobz=K/yP%RVf~Ļ/7[hyXaf8fkǞ`yM(n t isQwQ@e ^/:%$_ cuΟP%R#w/.yZUwSIG_OfEdɦOw!^yI]řX*ө(9!Uyxc>('ZtZDo& X|c)X5_?{o+5OFg誢#^XA#k֗Ӥ1\׫g$qn%x]-fSlqwo[p:34!# D~-|hKT)\~2O/\%RZh+-lqɸJ&YPsW2K7``xqu&EYVcu;VS;Ju&PE1!'iUsJx(&VƯ Hq.Ͽ2/Gͽ:di[6w`&nN#h em'"-& Vw>[=Fm{AEf'j{XŸef-upXrf(/2[UL Ļ㟛g^-dT|!2uޮPNWQW'PW);~\;݇z(e"ڢzxj+斳as Z~Y^DʞOm?4Ρ{OBEj?5lw#ZPݧ}JZ{iU ;lpK codg@ޤaƩW> oݬJz^;˺0NDAS*h饕Lέn@h _oJњyznW݀V28]>VxHa{|U}ժ|}~^HaUɱvcWiߣPF޼l&gY4(`Ns4<{Ej]M 7'pĨta|ZYL'_F~+[??އ"U2@,aWvn\?L=ANZU*1In"V]NzXV;<A|!َı@lP')#xH#E{Ns$,biTx̶.[I,Ni⿎M(.RJ?z?/?y|rS]>Y/ODjBjbu[!,M|Xr^..# DĀv,s16q€ㆭkк54}13 g +A5b񱉨eͻ)kQ%cV ]DGXםW3GG tUU0*x`A5J,>IUSBe\ ' DWu?O̙690I7St |n%J}XT &#zXZɜFSqt t] Xyl0!DP5Ldegi%NT=avz0 JOFVv'a{J"+AГs,aTaACyXZnz+Pb`ve}vqB B1bJV2Ǩ-X] t(;J,[ t(;R`Y Bc j Bd- Bt A /O"A/VR!Ġ] t"V&@-A**',O4. +"] t=u=H$ BkȪ (YX t6t WbHD/ 4@AGJAxDAu}s%IENDB`hawtjni-1.0~+git0c502e20c4/webgen/src/images/rss.gif000066400000000000000000000022161142665006500220120ustar00rootroot00000000000000GIF89a9ܵx]sX{8XQofb+Mó[Ii᮳㲹,H_~6T&D9tse~AŎRxAav=cQmEh4Tk/Lꖴraz-P떫Lq@[g|kPq\Fe)I=Jj[굺Xo䑬pZt}x[tCcik!:k茵2W0Pk:Zn0MX|Bb!BJkAb+P[z{JiSs骶Jc3Qd|Sq1RbjZ^u!,!t"t@Ə#Hq ?(!e AnA2g&YeŊQ8d +Kx` '#j‰;!K:M:B]6dSy0M><' =AʒL!𤧍< AxD4wxQA>9@えAX@ix 8I͙cE3x#HF5 A6+ &IށH@͗N A^\kP0`@A>hqC[AÎ"-@/d/4ET@!P1v衇#P0(āF 4`@;hawtjni-1.0~+git0c502e20c4/webgen/src/images/spot-download-releases.jpg000066400000000000000000000117541142665006500256200ustar00rootroot00000000000000JFIFHHC       C  K  1!A"Qa2BRU#&bqr$%5Tst6CSc7!1"2AQRa4q#Bb3 ?.\QN2hΌ_ZKfuI=L*ƒs/*ZK*~wr0UW?;* PtJ܇wj:%OC }{w!]{>ڽjSm^DxW}^϶pZT<`gW-A*~wr0UW?;* PtJ܌}bUnm C5j3-Js慈h>γAʪ߹!>oii#) ..\mJ1? TA.\p .Hl<|Pّ Wn| ˌ@p%eB'Eqqp .\p ?'g򄪤~̍ish]I>n po?̷(lQ:f~'G .\p g1)?8%#>7?%U$V4]D. p )q\p.M[6(?W#~l501F6PQ%﷋`җ v+YI:;6;uFĶ7TC>ktz܌'"NڤɅR,4I64ۘƪ,w)bhbWFYQaLJ̱m6,5xhCKOnpuUMWVܽKxU`jFz #жnaw"Ql„Y %JҜYQ>=SSٖ-_% v|6ir6璷Jh#gb},ޅGQWe٦+U3n%t? }pQ% о{V-xI[ UfC]h->dG&0lͧ*έڗbQ(aWMٝR|NqqA ) W CϾ O YIvK$\p e{Өpd#ZRۼ$Ɍ]kw5~Ni [?ݻX'4Q,_}kA؇/}!/FG DԔ1m6Z{YY^{K};qiכ>1D /ڂv$= T[E.bNy،;%cEE66q Ðj#T^ r(iVe`՛>sw˱:aOzpy+֧sA\>4b|OJNyNwZSxt]twz{6JB߉!sbnW^"FW鬦CMRW_"{Tr*ZjJSqdD0~~PiFFA\S4cU60K>:UkIxq䔩(tcy t.gvWbl%R?b6MQjR;}py+֧sA\>4b|OJNyNwMWI׊toXN]L;j8* -~2(@r]1M7,p|JUo"F!C*]rݙ؄+5҇}t'3B . aaĪHA"ȃu.<2.ѱM5]UEm)e'**yݬU)tsi.I<%lp3&5zMh[3~g4H'Ie<欉q;0 [C![ѥ$h㇪z{Ȍ bb6N!ZU}qi*str{y^i2R;ǩ5"2},ۉgt5a' H H H ϰ4!9eA#+\=ԝOMJsqgSw$VG]wyJ=LƋqƙQ VH,-Nv4q6Rtˑ) W}'ۢ1jfgI7].e7q ߽ |I H H I<MfIgxҕUhZq.f4E i|Q , k~"CyqYRO?S|.۹NaڢK+q\Givs.ClxWemH H H&قpk*KjTN%WTڬ)1,X`ՆD ,XDN :j$"e.|˸.I5)zHH;s{?EI>de;Z5Q7e,@ $@ 3W ?ZufDD+Fz4j504qln$lS%R҂LxZGgygk|MZ띪R`,X` ,XK9viS &F"GU|aM础-Fz>e:kЦ6mIaY\A$|j/; uQ)g IxvMjn7n#V9RlfHIEڵy\ \^1Y+q$+4E,mrٖ=V]G!EG]z띹PTV ,X  ǠceVI&粓/_4C}1祗֊I%زS2Q֖VRTZT)$Шr33D$ȐmvD\LF#MĎ+V_ڥBBqVu:IXQ$QH%$Ң]JjmNMAȝO/5_a82 mwg#ˍӊmԚAZV22ԌAi#="eZr!"}em-g +]rH,h(e K땔{:w%Ȼ{GugJuDJJZ*.4PhYfJ8ֶDR"a؝%TY\R1ǫ8}WKݙٖ#:O<|Cv2m>j~㤽jbkYuCH$ <*$ˍr$#m *IIr ?hawtjni-1.0~+git0c502e20c4/webgen/src/images/spot-get-involved.gif000066400000000000000000000076701142665006500246020ustar00rootroot00000000000000GIF89afffÌu鼓fޡҕ٬{{zϪf笽|bŝڝz뮵ļzt^șⵄ|z´~{է~tʎߜزɥ|{tƽ敔rqimݵǻȅsǎӚz̙xvm~Ϝ祣rzإcͿ֭浉zХۦfff֜ϔruxܮǢȕi{tĔ|xd·i{~j{zkνtƻq֖ͥ栺|yllp¸k̜}u˕tssέf÷yt`ffm!,YH*\ȰÇ#JHŋ3j(PGG,ɓ( y#Ǘ0cr$l\iŊ$@\!C"NXrAH2JuEd@Mf@ւYfh XsDViv*^ Cj1y;z*y5`G#*`* 9倦g̎@"Fvl8,#oJmJ"$pr`D#EJ^Qu!9'&9!0`WB ;QW&Zȋ݀C?"@"0$'oߊ837h)ϋ5@H#_LgK[J]%dϐ glu8 2t<6|zs1A6ߌ#hK8A@Q7`uڋoWh@10pr%`(n;C|4u#PPq3Nx"aܡGo}@Cw)\}=h{O< q40>4 0OJH>hA`p n"'m@ ; } Xa ǶAy d@_ 'G@%$̴ojH^ 떀<!khv0 9+V)-~8X<A Fϒh&:vc5ҭVĢ 0sv"~>"` aֿ5ѐq"H!#! EUk c!9لe}ri!!? fă"c$ 2^V hd 0TWL,v0 'I24!`xc؇n¬ aJsV,Ew,H@`3@-)~aj/U,}(&JF0v_8?5-P5BFI,Vv_JYګॶg"hʭ(TC;y+|vm%@@f5b Ŧ*U#6!<дbpLPL&f"han-SZ0"L g/F"&qLdNh\-)1 !""`\4T sE܄]:m,pvuC8(xHv5q9=lAPr.`Dl"<" Q",<E6Uo1Y H9 "n3 Z{*mf Tlly 6ЂŪX36wL0d=hMM_/ ۡBQ4K൲S\ )|E8"D3ޙ FDv@8ķ9@lPTHOwpo h>hl/X9U$(˕<HPdhW@ s-@(xǺڟ4`WcLpD yO%0AYtd q@@G3p) Ƭ2P̛(h a˟:/2p; 'Az@e H LPY(̀5a]@`Mؾ> q8&fA%Lp3^ȷs~By5y@!W}~%{'l&@@0F޷SnZP{wzefWBv p(& 'W{ljq1"*`4>B`A8"a `-@|p+peP|'s`X4+p`& nP&c`j thgP!W8HG8X(%W'~93`8 `l@t HMXP=Pf 0S:x8XsX\hpjv0BPZ-5`5А-p@؉4 =fp& b/1>4G,ْ.i1 Wp+`v@i@pp`fwfgI0 "l 4^(1yX4OxjOHvX%t=+&0&RPh`Yib1И18tzI0gJ)yy)w) "G1Pٛz1Ѕ;Z88f= y!:r'4PYYhcap9c& y,I17=' H Ja 2 ZH9ky9Y2p`i&zX>).*ns6zY8ਛ7@B:-;hawtjni-1.0~+git0c502e20c4/webgen/src/images/spot-learn-more.jpg000066400000000000000000000146661142665006500242560ustar00rootroot00000000000000JFIFHHC       C   O !1"AQ2aq#7BRS3bu6Cr$4s%5Vcӓ.!1A2Qq"a3R#B ?ӝ#t H7ZZK1kO6 L6 )HG=*Q²Z);$Ֆa5)ɇd.&}OI$A?f rvn o9)EB)jV n̬˳R (kn,tgD̲^p/qgv,:.Vn|s^F'emIc/M`:FՕ[wenfpM^Z0NԞ:é t|<7ֽ8 F#&v:mY%S/fZm(m$s3MX6 )9zȶ ~J7pI)J=br{n\E$ $%X^J=m}&Irm7$7C3j-Pji);vK[X[ yS+SvIIo904 ;"(R3{ \&Iy*OEEQpC>'PpfB(ӟ=߁ Ƙ6ٔAW. %}5g;8~dGtx"?#t/▥n*(@פY*'0fG%HR&^RШ+B1UKoYY zg 1d'\eX4_lRD&eRX@jTVR%er ΐ什 bO"Fj2Ь+>eX,M JHӘ˄b+/6gc_IMprM:o[a\K--vG X#\ƜM1]њBr̛Bh 9#P;>XˌiZ eNNy}2SK%, ;!87[hAq#-ܾ0H"K;O@ +L1sB@rW,1KVi lj\@%%YӁFfJR E2NzQ1X L:mapPgJgN<Ǘ JUR᧺>oq=5$<3EbNGP^-JTPrTѿbuEiK;w6ieJֹE=oҟٓn81-z~薌;m$>B攌QҖ;{IU'1RC9v^>Eu\_!o\La:w+$C%VJEضi4UդZ"ARš]=L\ u`ӜtQ ouE24}*-*zP 1SD1!kxScnx%IŨ^qs0ee-bبlX CJ3RYrm*Tvy#TӜYfKBѾVڗ('pj#p&Ϭy'IIq_r>D|#Z^l+YdUR9:b˜d8KTᠭ"Mz[XJuJ +:R9&Zks]Bi228S8qzwz, n$vU,4sw`*?bMsZJݒlT[dqPO ()ŧQmBQ`J-ya8' z\JpfT(;*fSDŽK?o&K3NvrH~U!T)8-=وۋc<)[Z٦rW6qk|%j٪7((07OTM+a(~ aMQ, %6w_CrF1䐙%K; @QDR]-rhY!;czMIyg✏м#Z8sjeRA-5"RsUjObՠYjOIJ]{3w[ܱ16U\-EtU8l.YMrNvGR3Vrkҵ\5/u8GrԹVRIJKLS@ˌMcEjRE}O֦ a,as2MNa9c%MO)t)rc`^X()>/-Q֞5}s]ɇ6!4[ ZhSN\9 Ό!8LWx~'q%t䂜qh6P)}a^DNG%<0yƗRt3'9!TNI\f>lʳ2RND~먬5Qm31"Hn_^Y"mt.62iSsh#qIFU.0}smͨ]q> Z]-j3UӶe)l?"V~d)HX|]W-FUJXp9H8H2vYjCFٝ~WjМF%uhV+/v=jvJVP<u{tRHʐ"噕3΄Zh{!yhu\Îu6U14P0 %͉~|K;%O;N{>ٴ?{Z@&bba 8s$>r ?*ِJpPb8M!+)\\b \7HYk(gٗ@B^#pUdz47e*eoRv$} 1r!5:6A:,q6c @aOĿ{\y|f靂'yɽlr=] -JP O+` 5O %GKqMLЄ#M!v5eif] ""N%Fc- <9U*!@bMr8ajO )Fd6< lВh=b[KlU_ 'AQRwȎLPg |;mVؗwˏ3Խ3T"'ʽlr=]+-J9@YJ152 )3V9]-!4&VbG0}@ kE9f4ɭxm[ :!owQ,شU2Uxiz/:0 #0k,~lǝjV`iE:O{>ٴ?{WV  2LTZTmGXz^c+AR4H`rMp8eld#V8xjp:ө _T`p4*lń@=R2ڂv=# *Lim~J?2`iʲwv)) U]f!Wwو9,*sXXB)jV n̬˳R (kn,tgD̲^p/qgv,:.Vn|s^F'emIc/M`:FՕ[wenfpM^Z0NԞ:é t|<7ֽ8 F#&v:mY%S/fZm(m$s3MX6 )9zȶ ~J7pI)J=br{n\E$ $%X^J=m}&Irm7$7C3j-Pji);vK[X[ yS+SvIIo904 ;"(R3{ \&Iy*OEEQpC>'PpfB(ӟ=߁ Ƙ6ٔAW. %}5g;8~dGtx"?#t/▥n*(@פY*'0fG%HR&^RШ+B1UKoYY zg 1d'\eX4_lRD&eRX@jTVR%er ΐ什 bO"Fj2Ь+>eX,M JHӘ˄b+/6gc_IMprM:o[a\K--vG X#\ƜM1]њBr̛Bh 9#P;>XˌiZ eNNy}2SK%, ;!87[hAq#-ܾ0H"K;O@ +L1sB@rW,1KVi lj\@%%YӁFfJR E2NzQ1X L:mapPgJgN<Ǘ JUR᧺>oq=5$<3EbNGP^-JTPrTѿbuEiK;w6ieJֹE=oҟٓn81-z~薌;m$>B攌QҖ;{IU'1RC9v^>Eu\_!o\La:w+$C%VJEضi4UդZ"ARš]=L\ u`ӜtQ ouE24}*-*zP 1SD1!kxScnx%IŨ^qs0ee-bبlX CJ3RYrm*Tvy#TӜYfKBѾVڗ('pj#p&Ϭy'IIq_r>D|#Z^l+YdUR9:b˜d8KTᠭ"Mz[XJuJ +:R9&Zks]Bi228S8qzwz, n$vU,4sw`*?bMsZJݒlT[dqPO ()ŧQmBQ`J-ya8' z\JpfT(;*fSDŽK?o&K3NvrH~U!T)8-=وۋc<)[Z٦rW6qk|%j٪7((07OTM+a(~ aMQ, %6w_CrF1䐙%K; @QDR]-rhY!;czMIyg✏м#Z8sjeRA-5"RsUjObՠYjOIJ]{3w[ܱ16U\-EtU8l.YMrNvGR3Vrkҵ\5/u8GrԹVRIJKLS@ˌMcEjRE}O֦ a,as2MNa9c%MO)t)rc`^X()>/-Q֞5}s]ɇ6!4[ ZhSN\9 Ό!8LWx~'q%t䂜qh6P)}a^DNG%<0yƗRt3'9!TNI\f>lʳ2RND~먬5Qm31"Hn_^Y"mt.62iSsh#qIFU.0}smͨ]q> Z]-j3UӶe)l?"V~d)HX|]W-FUJXp9H8H2vYjCFٝ~WjМF%uhV+/v=jvJVP<u{tRHʐ"噕3΄Zh{!yhu\Îu6U14P0 %͉~|K;%O;N{>ٴ?{Z@&bba 8s$>r ?*ِJpPb8M!+)\\b \7HYk(gٗ@B^#pUdz47e*eoRv$} 1r!5:6A:,q6c @aOĿ{\y|f靂'yɽlr=] -JP O+` 5O %GKqMLЄ#M!v5eif] ""N%Fc- <9U*!@bMr8ajO )Fd6< lВh=b[KlU_ 'AQRwȎLPg |;mVؗwˏ3Խ3T"'ʽlr=]+-J9@YJ152 )3V9]-!4&VbG0}@ kE9f4ɭxm[ :!owQ,شU2Uxiz/:0 #0k,~lǝjV`iE:O{>ٴ?{WV  2LTZTmGXz^c+AR4H`rMp8eld#V8xjp:ө _T`p4*lń@=R2ڂv=# *Lim~J?2`iʲwv)) U]f!Wwو9,*sXX Adobe Fireworks CS4 2009-04-04T10:07:40Z 2009-04-04T10:07:52Z image/jpeg C  22@0'0@;0000;OCCCCCOVSSSSSSWWWWWWWWWWWWWWWWWWWWWWWWWWWWWC )$)00E0)0EWE77EWWWBCTWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWxk= !1AQa"2q#B3RCbcSr.!1A"Q2a#qBRr ?P&ښ(^[ _iwr+B==;vbɿC7ͧHk NMrb {-KAAI+at%( @JPOeOI@%z2^HvWgq>><k0܁T[/+[bٷÂ:^Ƈ>9;V$58I%Pvc\_q*GDw'.[e|U6<m.rP̥%( @JV-5Jw?^gI3r6ңb鸊췠}ųy2 QRR.jWh\c1O RΔzi)G՛+M42VU;)v}l<95vJ $ TicXԁvZuHPH m3 : leUAUɛhJ/Ke/9DzyUXQ5kT ֺTb6JHTuhX}+Ԣ'i_=e 3x jK񱬃BMnⷞI|ʤ'?PtsITpd1;D4OZNvqEP/#l:[ Z  " _/'R6up$|җx%5 3U(S Nگ*{[QRlޔqWJ+Tr)SJ£K9Gk(CQRmTru/"ԕkQM?)1Jljt)¢j[n; ^̭\o*1Z C+ C T5lrʷn<9 ry1|I!_@q&9a,aqV+EWjtU/'pi2Sz7Vŧ9A\HPwpH33bX4:obO7JrR*49ҮHMU>Hj ~sSSj85L)JԖbMI[דob ?#P Sm%Ԏ[PbDMF[Zʍ/\VnwȖ(UU; R%y˙/&Ude ޭN 7.#5T뭸!!&׶\l)RXK JT" yv0-)6$n޺‡i`@Ua'qYx"m@JDt6Hh |g#Zfָe9honA&J\2P,&(m ,:対8ҍ/4!,XJW5U:")pCֽMM?e42Jr&ǀjE>Mb2Q]$ۢ)QZq*O*?[QZ)hn^._Zaٛa'&c3[Qvh6Uxր&I _NgTQe7)rַ@9 !Yl΀$} [R W}kC]MǰV#SUZMGrꞃ3Wn?!eV9i伜7Y4fG"ܫ%^n'9݄ܤORuEL_HtpP1J7ݎ"@DHۧ*yl;- M{kC9f{.͕i*=-/ G֡$h)D-vqt^gѝ-uW to?{ʶqw7 ;IFch V/=ǥ_'b[*9~t&%RwZMn"!=^y $ʪswæ<ȓq֗8WA@O`x5lnKiAec D3g7r'vϒQpw&)..Ve FDc?<\MѲ)ޤ ,I.0*Y\AdW)j>N ; Y^ -(1y VQ}F!I@rsiB+=8*Z _) 1WS^Qz(J)W42q\_brTr]HZ,ʵ*t ٹF]W{"2M^r`x8zR4qԌͭbIY^{QZO %(U9k=Lx%*_(\+Lâ!-PW,K\,V^HoC/VQ:Tw%cF}|ﰷYX* ^ʏ[JrQжf,p5*O!] [@JP8Y4F h+>Fƀ@O3{E;V۾߶ heB,:PT G,N"hawtjni-1.0~+git0c502e20c4/webgen/src/index.page000066400000000000000000000031021142665006500212070ustar00rootroot00000000000000--- title: HawtJNI in_menu: true sort_info: 1 --- name:overview pipeline:haml,tags %h1 {project_name:} {project_slogan:} --- name:content pipeline:tags,markdown {project_name:} =============== {project_name:} is a code generator that produces the JNI code needed to implement java native methods. It is based on the [jnigen](http://www.eclipse.org/swt/jnigen.php) code generator that is part of the SWT Tools project which is used to generate all the JNI code which powers the eclipse platform. Features -------- * JNI code generated declaratively from annotations on your java code * Maven integration: * Generates JNI source code * Generates an autoconf and msbuild source project to build the native library. This gets attached to the maven project as as the native source zip file. * Builds the native source tar for the current platform * Built native library is stored in a platform specific jar. This gets attached to the maven project as a platform specific jar file. Introduction ------------ There are many open source JNI code generators available, but if your performance sensitive, the code generator used by the eclipse SWT project is by far the best option. The biggest problem is that it was not developed to be reused by other projects. It was tightly coupled to producing the SWT jni libraries and it could only be run within the eclipse platform. HawtJNI has taken that code generator and made it easier to use and accessible to more projects. Getting started --------------- For more information, checkout the [developer guide](documentation/index.html) hawtjni-1.0~+git0c502e20c4/webgen/src/maven.page000066400000000000000000000004561142665006500212170ustar00rootroot00000000000000--- title: Maven Reports --- name:overview # Maven Reports Various documentation generated by maven. --- name:contentpipeline:tags,markdown ## Snapshots * [1.0-SNAPSHOT](http://{project_id:}.fusesource.org/maven/1.0-SNAPSHOT/) ## Releases * [1.0](http://{project_id:}.fusesource.org/maven/1.0/) hawtjni-1.0~+git0c502e20c4/webgen/src/metainfo000066400000000000000000000035531142665006500210010ustar00rootroot00000000000000--- name:paths # # You cand define metainfo for mutliple pages in this file. # **/*.page: # <-- That means the following attributes get applied to all pages # in the site. # ------------------------------------------------------------------- # You can easily switch the site from one look to another here: # ------------------------------------------------------------------- #template: /styles/default/default.template template: /styles/impact/main.template # ------------------------------------------------------------------- # Define the project properties here, these can be accessed in the # pages using the {var:} syntax. # ------------------------------------------------------------------- project_name: "HawtJNI" project_slogan: 'Making JNI easy and fast.' project_id: 'hawtjni' project_jira_key: 'HAWTJNI' project_issue_url: 'http://fusesource.com/issues/browse/HAWTJNI' project_forums_url: 'http://fusesource.com/forums' project_wiki_url: 'http://fusesource.com/wiki/display/HAWTJNI' project_logo: "/images/project-logo.png" project_version: "1.0-SNAPSHOT" # ------------------------------------------------------------------- # TODO it would be nice to define these in terms of the project_id variable! # ------------------------------------------------------------------- project_svn_url: 'http://fusesource.com/forge/svn/hawtjni/trunk' project_svn_branches_url: 'http://fusesource.com/forge/svn/hawtjni/branches' project_svn_tags_url: 'http://fusesource.com/forge/svn/hawtjni/tags' project_maven_groupId: 'org.fusesource.hawtjni' project_maven_artifactId: hawtjni-core project_git_browser: 'http://github.com/chirino/hawtjni' project_git_url: 'git://github.com/chirino/hawtjni.git' blog/*/**/*: template: /styles/impact/blog.template output_path_style: [:parent, :year, /, :month, /, :cnbase, [., :lang], :ext] hawtjni-1.0~+git0c502e20c4/webgen/src/sbt.page000066400000000000000000000017731142665006500207040ustar00rootroot00000000000000--- title: build with SBT --- name:overview # How to build {project_name:} using SBT Using SBT (Simple Build Tool) to build fast --- name:content ## Building with SBT You can use [sbt](http://code.google.com/p/simple-build-tool/) as a build tool - its particularly well suited to rapid edit-compile-test cycles. ### Setting up SBT The first time you run *sbt* you need to tell it to update its dependencies from the maven pom.xml files. So type ./sbt update You should now have the project loaded and the dependencies updated from the maven poms. ### A normal build If you have not done so already, start a sbt shell ./sbt To build things type compile To run the test cases test ### Incremental builds To sit in incremental mode, re-running all the test cases as you edit code ~ test Or to just re-run failed test cases interactively ~ test-quick ### See Also * [Source](source.html) * [Building](building.html) * [Maven Reports](maven.html) hawtjni-1.0~+git0c502e20c4/webgen/src/site.page000066400000000000000000000042371142665006500210560ustar00rootroot00000000000000--- title: Building --- name:overview # {project_name:} Site How the website works --- name:content

# How it works
The *{project_name:}* documentation and site is created using [WebGen](http://webgen.rubyforge.org/) and is stored in git in the same [source control system as the code](source.html)
# Editing the source code
If you [grab the source code](source.html) you can get the site source in the *webgen* directory. If you have webgen installed (see below for instructions) then you can build the website from [the code](source.html) as follows cd {project_id:}/webgen webgen If you want to edit the files in your text editor and be able to immediately see the site re-rendered in a browser then use webgen You can now surf the site and see changes immediately. If you are on OS X then we highly recommend [TextMate](http://macromates.com/) as a great editor which supports Textile and Markdown
# Editing the site in your browser
The generated HTML has a link at the bottom of the page to Edit This Page! as well as supporting the [Universal Edit Button](http://universaleditbutton.org/) if your browser supports it. There is also a link to the page source if you are wondering where it is kept in subversion. If you use FireFox you might want to install the [Edit Page Plugin](https://addons.wikihow.com/univedit.xpi) This feature depends on having a restful resource which will accept posted changes to the page.
# Installing WebGen
Before running the webgen command above you need to install it by [following these instructions]() sudo gem install webgen You also need to install the following gems sudo gem install --source http://gems.github.com FooBarWidget-mizuho sudo gem install coderay sudo gem install feedtools sudo gem install haml To be able to deploy the site you will need sudo port install sitecopy
hawtjni-1.0~+git0c502e20c4/webgen/src/source.page000066400000000000000000000026231142665006500214070ustar00rootroot00000000000000--- title: Source in_menu: true sort_info: 40 --- name:overview # {project_name:} Get the latest source code --- name:content # Source Repository The *{project_name:}* project stores its source code in a [Git](http://git-scm.com/) repository hosted on [github](http://github.com) at this location: * [{project_git_browser:}]({project_git_browser:}) If you are new to Git you might like to try the [Git guide for subversion users](http://git.or.cz/course/svn.html) or have a look at the [Git community book](http://book.git-scm.com/). You can [browse the repository online]({project_git_browser:}) if you prefer. ## How to Checkout Read only access to the repository is available at the following URL: * **{project_git_url:}** You must first install a [Git client](http://git-scm.com/download). Then you clone the repository using the following: git clone {project_git_url:} cd {project_id:} ## Contributing patches If you are not yet a committer but want to contribute some patch (we love [contributions!]({relocatable: contributing.html})) here's how you can submit patches {include_file: {filename: src/creating_patches.include, process_output: true}} # Next steps Once you have checked out the code try following * [instructions to build {project_name:}]({relocatable: building.html}) * read the [documentation]({relocatable: documentation/index.html}) * browse the [maven reports](maven.html) hawtjni-1.0~+git0c502e20c4/webgen/src/styles/000077500000000000000000000000001142665006500205715ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/000077500000000000000000000000001142665006500222155ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/browserfix.css000066400000000000000000000001731142665006500251220ustar00rootroot00000000000000/**************** IE fixes ****************/ html {overflow:hidden;} body {height:100%; width:100%; overflow:auto;}hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/default.css000066400000000000000000000055141142665006500243600ustar00rootroot00000000000000/* andreas07 - an open source xhtml/css website layout by Andreas Viklund - http://andreasviklund.com . Free to use for any purpose as long as the proper credits are given for the original design work. Version: 1.1, November 28, 2005 */ /**************** Page and tag styles ****************/ body {margin:0; padding:0; color:#303030; background:#fafafa url(images/bodybg.gif) top left repeat-y; font:76% Verdana,Tahoma,sans-serif;} ul {list-style:circle; margin:15px 0 20px 0; font-size:0.9em;} li {margin:0 0 8px 25px;} a {color:#d85d5d; font-weight:bold; text-decoration:none;} a:hover {color:#505050; text-decoration:underline;} img {float:left; margin:0 15px 15px 0; padding:1px; background:#ffffff; border:1px solid #d0d0d0;} a img {border-color:#d85d5d;} a img:hover {background:#d85d5d; border-color:#d85d5d;} /**************** Sidebar area styles ****************/ #sidebar {position:absolute; top:0; left:0; width:220px; height:100%; overflow:auto; background:#e0e0e0 url(images/sidebarbg.gif) top right repeat-y; text-align:right;} body > #sidebar {position:fixed;} #sidebar h1 {margin:20px 18px 0 5px; color:#d85d5d; font-size:1.6em; letter-spacing:-2px; text-align:right;} #sidebar h2, #sidebar h3 {margin:0 20px 18px 5px; color:#808080; font-size:1.1em; font-weight:bold; letter-spacing:-1px; text-align:right;} #sidebar h3 {margin:20px 18px 4px 5px; color:#606060;} #sidebar p {margin:0 20px 18px 5px; color:#606060; font-size:0.8em;} #sidebar a {color:#808080} #sidebar ul {margin-right: 20px; margin-left: 5px; list-style-type: none;} #sidebar li {margin: 0px; padding-left: 5px;} /**************** Navigation menu styles ****************/ #menu ul {list-style-type: none; margin: 0px; padding: 0px; font-size: 1.0em;} #menu li {margin: 0px; padding: 0px} #menu a, #menu span {display:block; width:202px; padding:5px 18px 5px 0; color:#606060; background:#e0e0e0 url(images/sidebarbg.gif) top right repeat-y; font-size:1.8em; font-weight:normal; text-decoration:none; letter-spacing:-2px;} #menu a:hover, #menu span:hover {color:#303030; background:#f0f0f0 url(images/sidebarbg.gif) top right repeat-y;} #menu li.webgen-menu-item-selected a, #menu li.webgen-menu-item-selected span {padding:5px 18px 5px 0; background:#fafafa; border-top:2px solid #c0c0c0; border-bottom:2px solid #c0c0c0;} #menu li.webgen-menu-item-selected a:hover, #menu li.webgen-menu-item-selected span:hover {color:#505050; background:#fafafa;} /**************** Content area styles ****************/ #content {width:520px; margin:0 0 0 240px; padding:20px 0; background:#fafafa;} #content p {margin:0 0 20px 0; line-height:1.5em;} #content h1 {margin:0; color:#808080; font-weight:normal; font-size:2.5em; letter-spacing:-2px; text-align:center;} #content h2 {clear:both; margin:30px 0 10px 0; color:#d85d5d; font-weight:normal; font-size: 2em; letter-spacing:-2px;} hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/default.template000066400000000000000000000031201142665006500253720ustar00rootroot00000000000000--- template: ~ --- {title:}

site info

© 2005-2006 Your Name | Generated by webgen | Design by Andreas Viklund.

hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/images/000077500000000000000000000000001142665006500234625ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/images/bodybg.gif000066400000000000000000000001531142665006500254160ustar00rootroot00000000000000GIF89a,DڋH扦ʶ Lo ĢL*̦ JԪjn;hawtjni-1.0~+git0c502e20c4/webgen/src/styles/default/images/sidebarbg.gif000066400000000000000000000000431142665006500260700ustar00rootroot00000000000000GIF89a,Q;hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/000077500000000000000000000000001142665006500220465ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/blog.template000077500000000000000000000004551142665006500245350ustar00rootroot00000000000000--- template: main.template ---

{title:}

Posted by {author:} on {created_at:}
<% if context.node.node_info[:page].blocks.has_key?('full_story') %> <% end %>
hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/css/000077500000000000000000000000001142665006500226365ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/css/pygmentize.css000066400000000000000000000106131142665006500255440ustar00rootroot00000000000000.syntax .hll { background-color: #ffffcc } .syntax { background: #f0f0f0; } .syntax .c { color: #60a0b0; font-style: italic } /* Comment */ .syntax .err { border: 1px solid #FF0000 } /* Error */ .syntax .k { color: #007020; font-weight: bold } /* Keyword */ .syntax .o { color: #666666 } /* Operator */ .syntax .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ .syntax .cp { color: #007020 } /* Comment.Preproc */ .syntax .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ .syntax .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ .syntax .gd { color: #A00000 } /* Generic.Deleted */ .syntax .ge { font-style: italic } /* Generic.Emph */ .syntax .gr { color: #FF0000 } /* Generic.Error */ .syntax .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .syntax .gi { color: #00A000 } /* Generic.Inserted */ .syntax .go { color: #808080 } /* Generic.Output */ .syntax .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .syntax .gs { font-weight: bold } /* Generic.Strong */ .syntax .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .syntax .gt { color: #0040D0 } /* Generic.Traceback */ .syntax .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .syntax .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .syntax .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .syntax .kp { color: #007020 } /* Keyword.Pseudo */ .syntax .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .syntax .kt { color: #902000 } /* Keyword.Type */ .syntax .m { color: #40a070 } /* Literal.Number */ .syntax .s { color: #4070a0 } /* Literal.String */ .syntax .na { color: #4070a0 } /* Name.Attribute */ .syntax .nb { color: #007020 } /* Name.Builtin */ .syntax .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .syntax .no { color: #60add5 } /* Name.Constant */ .syntax .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .syntax .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .syntax .ne { color: #007020 } /* Name.Exception */ .syntax .nf { color: #06287e } /* Name.Function */ .syntax .nl { color: #002070; font-weight: bold } /* Name.Label */ .syntax .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .syntax .nt { color: #062873; font-weight: bold } /* Name.Tag */ .syntax .nv { color: #bb60d5 } /* Name.Variable */ .syntax .ow { color: #007020; font-weight: bold } /* Operator.Word */ .syntax .w { color: #bbbbbb } /* Text.Whitespace */ .syntax .mf { color: #40a070 } /* Literal.Number.Float */ .syntax .mh { color: #40a070 } /* Literal.Number.Hex */ .syntax .mi { color: #40a070 } /* Literal.Number.Integer */ .syntax .mo { color: #40a070 } /* Literal.Number.Oct */ .syntax .sb { color: #4070a0 } /* Literal.String.Backtick */ .syntax .sc { color: #4070a0 } /* Literal.String.Char */ .syntax .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .syntax .s2 { color: #4070a0 } /* Literal.String.Double */ .syntax .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .syntax .sh { color: #4070a0 } /* Literal.String.Heredoc */ .syntax .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .syntax .sx { color: #c65d09 } /* Literal.String.Other */ .syntax .sr { color: #235388 } /* Literal.String.Regex */ .syntax .s1 { color: #4070a0 } /* Literal.String.Single */ .syntax .ss { color: #517918 } /* Literal.String.Symbol */ .syntax .bp { color: #007020 } /* Name.Builtin.Pseudo */ .syntax .vc { color: #bb60d5 } /* Name.Variable.Class */ .syntax .vg { color: #bb60d5 } /* Name.Variable.Global */ .syntax .vi { color: #bb60d5 } /* Name.Variable.Instance */ .syntax .il { color: #40a070 } /* Literal.Number.Integer.Long */ .syntax { font-size: 10pt; font-family:Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace; background-color: #F8F8FF; overflow:auto; -moz-background-clip:border; -moz-background-inline-policy:continuous; -moz-background-origin:padding; margin: 1em 0 1em 0; border:1px solid #DDDDDD; } .syntax .linenodiv { background-color:#ECECEC; border-right:1px solid #DDDDDD; color:#AAAAAA; padding: .5em; text-align:right; } .syntax .highlight { padding: .5em; } .syntax pre { margin:0; } pre.syntax { padding: .5em; background-color: #F8F8FF; overflow:auto; } .syntax code { font-family:Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace; font-size: 10pt; } hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/css/site.css000066400000000000000000000071711142665006500243220ustar00rootroot00000000000000body, html { font-family:Arial,Verdana,Helvetica,sans-serif; color: #666666; } body, html, table, tr, td, tbody { padding:0; margin:0; vertical-align: top; } body { padding-top: 20px; } h1, h2, h3, h4, h5, h6 { overflow: visible; color: #993333; } thead { color: #eee; background: #222; padding:0px; margin:0px; } table { width: 100%; background: #eee; font-size: 90%; } th { padding:3px; } td { padding:2px; } /* h1 { margin-top: 0em; margin-bottom: 2em; } */ p { margin-bottom:0px; } a { color: #990000; font-weight:bold; text-decoration: none; } a:hover { color: #ff3333; text-decoration: underline; } img { border: none; /* padding-right:2em */ } .wrapper { min-width: 762px; width: 762px; margin: 0 auto; } #navigation { width: 100%; float: left; font-family: Helvetica,Verdana,Arial,sans-serif; background: black; text-align:center; padding: 8px; color: #b55; font-size: 10pt; font-weight: bold; position: absolute; top: 0px; } #navigation a { color: white; } #navigation ul { display: block; margin:0; padding:0; } #navigation li { list-style-type: none; display: inline; margin:0 5px 0 5px;} #overview { width: 100%; padding-top:20px} #overview div.message { font-size: 11pt; margin-top: -20px; padding-left: 95px; width: 350px; } #overview div.message h1{ margin-bottom: 5px; display:none; } #overview div.message p{ margin-top: 0px; padding-bottom:14px; } #spot { width: 100%; float: left; margin-top: 15px; background:transparent url(../images/spot-banner.gif) repeat-x scroll 0 0; height: 277px; } #spot div.title { text-align:center; height:25px; text-align:center; padding-top: 2px; color: white; font-size: 10pt; font-weight: bold; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; } #spot div.content table { width: 100%; text-align:center; color: black; font-size: 10pt; } #spot a:hover {text-decoration: none; } #spot div.spot-balloon { background:transparent url( ../../../images/spot-get-involved.gif ) no-repeat; background-position:center; height: 121px; text-align:left; padding-top: 25px; padding-left: 35px; } #spot div.spot-balloon li { /* list-style: none; */ list-style: disc; } /* #spot div.spot-balloon { height: 120px; text-align:left; padding-top: 20px; padding-left: 15px; } */ #content { width: 100%; float: left; padding-bottom: 20px; } #content .wrapper { min-width: 700px; width: 700px; margin: 0 auto; padding-top: 1em} #content div.left { float:left; width:200px; text-align:right; font-size: 18pt; clear:both; } #content h1 { font-size: 18pt; } #content div.right { float:right; width:450px; text-align:left; } #blog { width: 100%; float: left; } #blog .wrapper { min-width: 600px; width: 600px; margin: 0 auto; } #blog h1 { font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; font-size: 18pt; color: #993333; } #blog h2 { border-bottom: thin dashed #DDD; font-size: 16pt; margin-bottom: 5px; } #blog div.post p { padding-left: 10px; } #blog div.post .details { padding-top: 5px; color: #ccc; font-size: 10pt; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; } #content .post h2 { margin-bottom:5px; } #content .post .details { color: #ccc; font-size: 10pt; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; margin-top:0px; }hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/images/000077500000000000000000000000001142665006500233135ustar00rootroot00000000000000hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/images/rss.gif000066400000000000000000000022161142665006500246120ustar00rootroot00000000000000GIF89a9ܵx]sX{8XQofb+Mó[Ii᮳㲹,H_~6T&D9tse~AŎRxAav=cQmEh4Tk/Lꖴraz-P떫Lq@[g|kPq\Fe)I=Jj[굺Xo䑬pZt}x[tCcik!:k茵2W0Pk:Zn0MX|Bb!BJkAb+P[z{JiSs骶Jc3Qd|Sq1RbjZ^u!,!t"t@Ə#Hq ?(!e AnA2g&YeŊQ8d +Kx` '#j‰;!K:M:B]6dSy0M><' =AʒL!𤧍< AxD4wxQA>9@えAX@ix 8I͙cE3x#HF5 A6+ &IށH@͗N A^\kP0`@A>hqC[AÎ"-@/d/4ET@!P1v衇#P0(āF 4`@;hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/images/spot-banner.gif000066400000000000000000000002141142665006500262270ustar00rootroot00000000000000GIF89a M襆!,9PIͻ d).hp,AmxϬD,rl:tJ*;hawtjni-1.0~+git0c502e20c4/webgen/src/styles/impact/main.template000077500000000000000000000034721142665006500245400ustar00rootroot00000000000000--- template: ~ --- {title:} <% if context.node.node_info[:page].blocks.has_key?('head') %> <% end %> <% if context.node.node_info[:page].blocks.has_key?('overview') %>
<% if context.node.node_info[:page].meta_info.has_key?('project_logo') %> <% end %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('spot') %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('content') %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('blog') %>
<% end %> hawtjni-1.0~+git0c502e20c4/webgen/src/support.page000066400000000000000000000014451142665006500216240ustar00rootroot00000000000000--- title: Support in_menu: true sort_info: 55 --- name:overview # You Are Not Alone We can help! --- name:content pipeline:textile,tags You can get "Enterprise Support, Mentoring and Training":http://fusesource.com/enterprise-support/ from "fusesource.com":http://fusesource.com/ - please do get in touch we'd love to help! You may also find the "Frequently Asked Questions (FAQ)":documentation/faq.html useful. We love feedback of all kinds; whether it's thoughts, suggestions, or bug reports. To submit feedback please use the {project_name:} Issue Tracker. h3. See Also * "FAQ":documentation/faq.html * Issue Tracker * Contact Ushawtjni-1.0~+git0c502e20c4/webgen/src/virtual000066400000000000000000000015431142665006500206620ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. in_menu: false --- name:content pipeline:tags \--- !omap - /development.html: title: Reports in_menu: true sort_info: 100 url: http://hawtjni.fusesource.org/maven/1.0-SNAPSHOT/