pax_global_header00006660000000000000000000000064137440177120014520gustar00rootroot0000000000000052 comment=d22bd004391c531a95e3a607b46f6089bd96b5d3 hawtjni-hawtjni-project-1.18/000077500000000000000000000000001374401771200162235ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/.gitignore000066400000000000000000000001671374401771200202170ustar00rootroot00000000000000.classpath .project .settings *.iml *.ipr *.iws .idea webgen/out webgen/webgen.cache target dependency-reduced-pom.xml hawtjni-hawtjni-project-1.18/.travis.yml000066400000000000000000000006021374401771200203320ustar00rootroot00000000000000language: java jobs: include: - arch: amd64 - arch: ppc64le before_install: - mkdir -p /opt/maven - curl https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz|tar -xz --strip 1 -C /opt/maven - export MAVEN_HOME=/opt/maven - export PATH=${MAVEN_HOME}/bin:${PATH} after_failure: print_surefire_reports.sh hawtjni-hawtjni-project-1.18/changelog.md000066400000000000000000000510421374401771200204760ustar00rootroot00000000000000# ![HawtJNI](http://fusesource.github.io/hawtjni/images/project-logo.png) ## HawtJNI 1.18, released 2020-10-21 * [`84606da`](https://github.com/fusesource/hawtjni/commit/84606dacef9bced4d21c2d47bb641b2737738ceb) Bump junit from 4.13 to 4.13.1 in /hawtjni-example * [`de46737`](https://github.com/fusesource/hawtjni/commit/de4673789a0f0892516450f837c301f5e81246d0) Merge pull request #70 from Siddhesh-Ghadi/ci-power * [`c06f662`](https://github.com/fusesource/hawtjni/commit/c06f662b9e7ef74dd98bf73f9458cae7a3f5fd86) Add ppc64le support on travis-ci * [`2976527`](https://github.com/fusesource/hawtjni/commit/2976527a43ec256c98c383110d436bba7aff8c9c) Add doc to setup the native build environment macOS * [`c00e2d2`](https://github.com/fusesource/hawtjni/commit/c00e2d22b4dfa105d31754bf044874845d7cacb5) Support for shared pointers, fixes #57 * [`5b4e5ad`](https://github.com/fusesource/hawtjni/commit/5b4e5ad74e63f1c1c180b2169eedd20c9b64e716) Merge pull request #59 from voutilad/master * [`8678713`](https://github.com/fusesource/hawtjni/commit/8678713caf00652f4f7d52e36b8b384cf611dde5) Merge pull request #61 from remkop/master * [`d145a1d`](https://github.com/fusesource/hawtjni/commit/d145a1dea37bbd8f98c9f1e6f21d756f849d7979) Do not force JDK 11 but rather support it * [`8ee5b21`](https://github.com/fusesource/hawtjni/commit/8ee5b2113069399c79610a1de6e01af7d5ae8c45) Updated to work with JDK11 * [`d1f1492`](https://github.com/fusesource/hawtjni/commit/d1f14926156d103357e7761c4182085b27e7c663) Fix example on OSX * [`b7277af`](https://github.com/fusesource/hawtjni/commit/b7277aff8f3b01c1c462ede437efb3a4a33973ff) prepare 1.17 release website * [`56b5bd0`](https://github.com/fusesource/hawtjni/commit/56b5bd0dd3e9a3091905cf262dbe232b65447e07) use hawtjni-maven-plugin for Maven Central badge * [`c14fec0`](https://github.com/fusesource/hawtjni/commit/c14fec00b9976ff6b84e62e483d678594a7d3832) Support for OSX Catalina * [`2c64ed4`](https://github.com/fusesource/hawtjni/commit/2c64ed4134de9b3cefd9423382a59f60c8f3ad25) jansi/#162 fix issue where bitModel could not be retrieved on GraalVM * [`e7806ff`](https://github.com/fusesource/hawtjni/commit/e7806ff89508fce6a61c300ea9a16992324c0ce1) support for OpenBSD ## HawtJNI 1.17, released 2019-04-03 * [`1c4a17b`](https://github.com/fusesource/hawtjni/commit/1c4a17b31bf988f99df6da7085f86829b935c342) Remove shared_ptr support until it's working * [`d3f9d0a`](https://github.com/fusesource/hawtjni/commit/d3f9d0ab71fd25d8d6f6eb9c3de6c6b47ddae92e) Keep (long*) for standard pointers * [`906aa15`](https://github.com/fusesource/hawtjni/commit/906aa158c24d3603aca6f3766b7fa0da306d23d6) Merge branch 'calin-iorgulescu-master' * [`c5130eb`](https://github.com/fusesource/hawtjni/commit/c5130eb900279531f67d4734ccf1ad2f2ad95a70) Fix typo * [`9d38df2`](https://github.com/fusesource/hawtjni/commit/9d38df2f4a25ee55fbb0dc921fb2004b33c59541) Merge branch 'master' of https://github.com/calin-iorgulescu/hawtjni into calin-iorgulescu-master * [`1c42406`](https://github.com/fusesource/hawtjni/commit/1c42406ec55ed1955d2fc573e3002e5fa557c984) Merge branch 'master' of https://github.com/batterseapower/hawtjni into batterseapower-master * [`55afd36`](https://github.com/fusesource/hawtjni/commit/55afd361a8fe44d4d6126de30b279c5b941894ba) Add 10.14 in OSX SDK version list * [`d094c95`](https://github.com/fusesource/hawtjni/commit/d094c95e7fd0fb879f896b49c796a92adee72369) Merge pull request #45 from wjsl/osx10.13 * [`d028542`](https://github.com/fusesource/hawtjni/commit/d028542040a23e090633ab0b192ca9c08f7838e2) Merge pull request #48 from castortech/master * [`c0cfb25`](https://github.com/fusesource/hawtjni/commit/c0cfb2558b8e11edd224f08fd7da6daa84876b34) Merge branch 'master' into master * [`73e0b4f`](https://github.com/fusesource/hawtjni/commit/73e0b4f68d4597295bcb6d0196a1c030ff14589a) Merge pull request #55 from tdemande/hawtjni-issue-54 * [`ec9cc6c`](https://github.com/fusesource/hawtjni/commit/ec9cc6c3ce72b7fcd99d356f1abbc0f36fbb9a29) Merge branch 'hawtjni_shared_pointer' of https://github.com/ossdev07/hawtjni into ossdev07-hawtjni_shared_pointer * [`bd514b7`](https://github.com/fusesource/hawtjni/commit/bd514b71878415e7091b914420a291310de3ec30) Implement a different strategy with sha1 checksum for extracting libraries, fixes #56 * [`40e0b2f`](https://github.com/fusesource/hawtjni/commit/40e0b2f27a2218b4d10ae3989a4ed74bcf40562d) Formatting * [`bc3f187`](https://github.com/fusesource/hawtjni/commit/bc3f187087a043caa6737a78c10f982159bd8c2c) #54 Also search in base dir when finding/extracting native lib * [`8f464d0`](https://github.com/fusesource/hawtjni/commit/8f464d07bc9a807acf33f0f2e355065471f15235) Implement new JNIField accessor model: allow support for separate getter/setter methods for individual fields. * [`5f52fee`](https://github.com/fusesource/hawtjni/commit/5f52fee5720c5cbeeaae71cfaa90611bcba56e8d) StructsGenerator: Fix bug where a JniClass extending another class that has only ignored fields would generate calls to cache the fields. * [`2b88a8f`](https://github.com/fusesource/hawtjni/commit/2b88a8f56fdbbf0e71b213f15b333a681e7dc72f) StructsGenerator: Fix bug where an empty field declaration would be created if only skipped fields are declared in a struct. * [`235f0b9`](https://github.com/fusesource/hawtjni/commit/235f0b985acba4559cfda588a0312287f9420791) Change maven settings to allow building. * [`839ddcf`](https://github.com/fusesource/hawtjni/commit/839ddcf2bff9e53020f162feeac7258ea6ac97db) added icon for hawtjni-runtime artifact in Central * [`27af76b`](https://github.com/fusesource/hawtjni/commit/27af76b5f73af61ef592cc66ed65fb12438cc166) Update StructsGenerator.java * [`f29f849`](https://github.com/fusesource/hawtjni/commit/f29f84960133e5a5740bcd6b6120b8bb7f172f0d) added Automatic-Module-Name to manifest for Java 9 auto-module name * [`1c2d511`](https://github.com/fusesource/hawtjni/commit/1c2d511d970ad07924ebdbb1e8566fb56e2edf6c) Hawtjni: Shared_pointer support added in hawtjni * [`7a6082f`](https://github.com/fusesource/hawtjni/commit/7a6082faed85ea73945065466e68ad6035cf724d) fixed typo * [`35c061c`](https://github.com/fusesource/hawtjni/commit/35c061ca7ffedb11fa52a18c8c087a41bbb5cd88) added Runtime API as a feature * [`6c1f140`](https://github.com/fusesource/hawtjni/commit/6c1f140970a59727a102b8ee2daef909eb991b78) Added customization for the Windows build. * [`98b1531`](https://github.com/fusesource/hawtjni/commit/98b1531628f236aa9a68fd49b67ac09f1b547868) Added missing case of "no directory" as per method documentation. * [`a103c50`](https://github.com/fusesource/hawtjni/commit/a103c50b1b1b357d6a5d932cac7ebc599bb0d16b) Added support to detect newer versions of Visual Studio as candidates for msbuild * [`6f891af`](https://github.com/fusesource/hawtjni/commit/6f891af96768e77f5e800fd0f723712b87e30735) Updated documentation to clearly indicate the vcbuild is deprecated and that msbuild is supported. * [`84aa381`](https://github.com/fusesource/hawtjni/commit/84aa381836dae2b784ea685b71c54c6eb6622646) update changelog.md for 1.16 release * [`3fffa67`](https://github.com/fusesource/hawtjni/commit/3fffa67c2b23f92a1c57552e3779c58382795855) fixed and improved changelog.md formatting * [`2c7134b`](https://github.com/fusesource/hawtjni/commit/2c7134b4ee612af788d8486181459580811ba1d6) Add 10.13 in OSX SDK version list ## HawtJNI 1.16, released 2018-02-02 * [`2e99592`](https://github.com/fusesource/hawtjni/commit/2e99592f7be976a935beeed7d7395d4a5787e04e) fixed site build * [`14f1d05`](https://github.com/fusesource/hawtjni/commit/14f1d0564d6e2c71c74288e537fcfa4acf7f4c18) renamed maven-hawtjni-plugin to hawtjni-maven-plugin * [`743d57b`](https://github.com/fusesource/hawtjni/commit/743d57b25337dc1e0b5dcfc7dce63b15a4433f78) switched Maven plugin from javadoc annotations to Java5 annotations * [`4a42ee6`](https://github.com/fusesource/hawtjni/commit/4a42ee611ad66c71a6d4b32d41b78ca02ca225e4) [#36](http://github.com/fusesource/hawtjni/issues/36) added info on loaded native library * [`16c5d82`](https://github.com/fusesource/hawtjni/commit/16c5d820e84864fe437ce77a33011b50b2a6f66d) Merge pull request [#37](http://github.com/fusesource/hawtjni/issues/37) from ghost/patch-1 * [`45e8a55`](https://github.com/fusesource/hawtjni/commit/45e8a557788a8dbf9fd134df6f8e99f456e3324f) [#43](http://github.com/fusesource/hawtjni/issues/43) mark HawtJNI annotations @Documented * [`f0c3b54`](https://github.com/fusesource/hawtjni/commit/f0c3b547aeecd508498871583595ab7adff54ea3) s/your/you're/ ## [HawtJNI 1.15](http://fusesource.github.io/hawtjni/blog/releases/release-1-15.html), released 2017-05-04 * [`7537b9d`](https://github.com/fusesource/hawtjni/commit/7537b9d19be9806b210674ccad4b96d90a11d50b) Update changelog * [`906cedb`](https://github.com/fusesource/hawtjni/commit/906cedb80b9661d0ea08f524fb464243610653a9) Default to extract in the users' home folder in case the temp directory is not writable * [`ed95784`](https://github.com/fusesource/hawtjni/commit/ed95784f9a4d3ed1afb0a14bd3dccc815d3e3cbe) search in library.$name.path like in META-INF/native resources * [`477c8cc`](https://github.com/fusesource/hawtjni/commit/477c8ccac78c3695ebcf6299d8b201adb3394d34) Fix some other problems with platform, especially on windows when compiling for the non native platform * [`58834e8`](https://github.com/fusesource/hawtjni/commit/58834e835c6f196f6188c6f35aa9c349db610d84) Upgrade some plugins * [`992ee3f`](https://github.com/fusesource/hawtjni/commit/992ee3fa28f30823913fe95a790fe3a08d19bdf3) Fix bad naming for the extracted file when the version contains a dot * [`6b58328`](https://github.com/fusesource/hawtjni/commit/6b58328635bd181c18048387aa7d83fda51d5be8) Do not include the extension in the windows project name, [#23](http://github.com/fusesource/hawtjni/issues/23) * [`9165154`](https://github.com/fusesource/hawtjni/commit/916515413152d2b25268d0f813c1f0f411388b3a) Merge pull request [#30](http://github.com/fusesource/hawtjni/issues/30) from felixvf/fix_lib64_bug * [`1cb6770`](https://github.com/fusesource/hawtjni/commit/1cb6770dc7348958d96b38d8d0b1f4b065f43da5) Merge pull request [#34](http://github.com/fusesource/hawtjni/issues/34) from hboutemy/master * [`4c430c6`](https://github.com/fusesource/hawtjni/commit/4c430c6d4454b37e035c1fb7ae284b8d3ac99c03) Merge pull request [#20](http://github.com/fusesource/hawtjni/issues/20) from felixvf/fix_bug_18 * [`f99972b`](https://github.com/fusesource/hawtjni/commit/f99972b7892fd621dca1442b8c8f3234edd4b02f) Better exception reporting when unable to load a library, fixes [#27](http://github.com/fusesource/hawtjni/issues/27) * [`1c5b81f`](https://github.com/fusesource/hawtjni/commit/1c5b81fb386f74e47e776f3ba2775d15003f2ae9) Allow the windows project name to be specified, fixes [#23](http://github.com/fusesource/hawtjni/issues/23) * [`ef3437c`](https://github.com/fusesource/hawtjni/commit/ef3437cde117c04793d773b25bd0627e5e260e66) Allow the -Dplatform=xxx setting to be used when doing the actual native build * [`0072848`](https://github.com/fusesource/hawtjni/commit/0072848253e100c98745725bdf5224e63103fad7) Remove explicit array creation when using var args * [`c6fb914`](https://github.com/fusesource/hawtjni/commit/c6fb9149b43292564bbc854d9942d4898a7f728d) Remove unused imports * [`145f3ee`](https://github.com/fusesource/hawtjni/commit/145f3ee50204c8b8f8ae728cc91533dd19424d7d) Fix typos in method names * [`81a35e1`](https://github.com/fusesource/hawtjni/commit/81a35e1a923bb1c7b0e6ffbdd66a08c83e119324) prepare gh-pages publication with scm-publish plugin * [`b3982d5`](https://github.com/fusesource/hawtjni/commit/b3982d573b04878918aebe5435a5f64af6a4401f) Use latest version of maven javadoc plugin * [`cb2ad85`](https://github.com/fusesource/hawtjni/commit/cb2ad85bc551e1628be25181acd6f9e97e04afab) Merge branch 'hboutemy-hawtjni-31' * [`cd20329`](https://github.com/fusesource/hawtjni/commit/cd20329a801e5d904d7a43c46d3cb150b4767b66) [#31](http://github.com/fusesource/hawtjni/issues/31) fixed API doc generation and misc other Maven-related conf * [`784a50f`](https://github.com/fusesource/hawtjni/commit/784a50f22d0abd1d4fa05f1fb720e70623092e63) Fix libdir to "/lib". Prevent any variation such as "/lib64". * [`401ce1c`](https://github.com/fusesource/hawtjni/commit/401ce1cc6f053fccae386977b695ae7a5948ef4d) Update readme.md * [`a73fc16`](https://github.com/fusesource/hawtjni/commit/a73fc165306a139e8cbb82f9dc28002c05d6d206) Merge pull request [#11](http://github.com/fusesource/hawtjni/issues/11) from OhmData/travis * [`098c501`](https://github.com/fusesource/hawtjni/commit/098c501c90feb20749105840eaca1f51fbae2559) Simplify the fallback case a bit * [`40f9f23`](https://github.com/fusesource/hawtjni/commit/40f9f23b4839941e217a8415eb9799aa539e0e36) Merge pull request [#22](http://github.com/fusesource/hawtjni/issues/22) from slaunay/use-java7-chmod-with-unix-chmod-fallback ## [HawtJNI 1.14](http://fusesource.github.io/hawtjni/blog/releases/release-1.14.html), released 2016-06-20 * [`e2522b0`](https://github.com/fusesource/hawtjni/commit/e2522b0ddd9f8975dc3a1cc99534ea458b807ddd) Merge pull request [#26](http://github.com/fusesource/hawtjni/issues/26) from michael-o/freebsd * [`6dc93fe`](https://github.com/fusesource/hawtjni/commit/6dc93fe4c3b67e68d9805b6f0cc7f2b7c36d5b06) Improve FreeBSD support * [`2d49307`](https://github.com/fusesource/hawtjni/commit/2d493076d264f6d8e2ac81ada4da4fcd78b2dabf) Deploy to sonatype. ## [HawtJNI 1.12](http://fusesource.github.io/hawtjni/blog/releases/release-1.12.html), released 2016-04-26 * [`70f24ba`](https://github.com/fusesource/hawtjni/commit/70f24ba7438a698d8e1e0de599b304774e01f5d4) Don't build the website by default. * [`ef93152`](https://github.com/fusesource/hawtjni/commit/ef931527b4ca915a53c59eb6f6ef0222f8cf3c12) Better JDK detection on OS X. * [`61ac652`](https://github.com/fusesource/hawtjni/commit/61ac6525a42117f0ea8820417d00616ef7f27452) Use Files.setPosixFilePermissions for chmod * [`57e5b32`](https://github.com/fusesource/hawtjni/commit/57e5b3262a86ac0541585f3b3a40bf3b8933561b) Define JNI64 not only in case of \_\_x86\_64\_\_ but in general for any \_LP64 platform. ## [HawtJNI 1.11](http://fusesource.github.io/hawtjni/blog/releases/release-1.11.html), released 2015-04-21 * [`e1da91a`](https://github.com/fusesource/hawtjni/commit/e1da91aec68eda9f40350b062c4fed4e75fb4cb1) Update xbean version used. * [`354e277`](https://github.com/fusesource/hawtjni/commit/354e2773cfb60008fd7500eef52ea7de8e9bb74a) Disable deployment of website since web host is not there anymore. * [`08cfdd0`](https://github.com/fusesource/hawtjni/commit/08cfdd0995bb298d88e87d559d2ce39018e6b509) Update parent pom. * [`86e97d1`](https://github.com/fusesource/hawtjni/commit/86e97d161d956009bbc92f2913dd570ece2ec3da) Merge pull request [#19](http://github.com/fusesource/hawtjni/issues/19) from jerrydlamme/master * [`1e2ee63`](https://github.com/fusesource/hawtjni/commit/1e2ee6330f6832a374e29b78a1fff2df62d4a52c) Added architecture specific native library loading path * [`d10c4b0`](https://github.com/fusesource/hawtjni/commit/d10c4b0914301810297f0f917ce3dba3e8868ff1) Merge pull request [#16](http://github.com/fusesource/hawtjni/issues/16) from NJAldwin/use-absolute-path * [`3d3aa0b`](https://github.com/fusesource/hawtjni/commit/3d3aa0be17cc8d35e251ea3594b1e684ce919d0d) Ensure absolute path is used for library * [`8c28532`](https://github.com/fusesource/hawtjni/commit/8c2853238e31b6e92f61fbdeda84314e5a529254) Merge pull request [#13](http://github.com/fusesource/hawtjni/issues/13) from batterseapower/master * [`c10adf5`](https://github.com/fusesource/hawtjni/commit/c10adf5139969f1bfa6cb6e8dd6af204d64280a9) Version bumps and markup fixes necessary for building on JDK8 * [`aed6cbd`](https://github.com/fusesource/hawtjni/commit/aed6cbd06b4579170617dae7146ec9c61b70d82c) Build a stock travis * [`efa684c`](https://github.com/fusesource/hawtjni/commit/efa684c0a87136f16b0bca67bc518ee9bf698f85) Ignore IDEA project files. * [`18cb7e5`](https://github.com/fusesource/hawtjni/commit/18cb7e5d98e0edf687ba2d02c724c36d631e9f65) prepare for next development iteration * [`f3bd38e`](https://github.com/fusesource/hawtjni/commit/f3bd38e1d83a5563c63b1bbebadf0c77c1fb54b8) Upgrade parent pom version. * [`175faf0`](https://github.com/fusesource/hawtjni/commit/175faf07fbc2ec1c42582d0b935bb05fd46fc33f) Merge pull request [#8](http://github.com/fusesource/hawtjni/issues/8) from normanmaurer/netty\_needs * [`b3f8609`](https://github.com/fusesource/hawtjni/commit/b3f8609c6682bda6d6c112c2e19c0c6cdc6dcfc6) Allow to also use generate mojo with existing native src files * [`c27b5a0`](https://github.com/fusesource/hawtjni/commit/c27b5a0c4640bce9437488275b0d8c360c45c1e6) Avoid warning. * [`c1980ef`](https://github.com/fusesource/hawtjni/commit/c1980ef32387547b0a5bba408abb00cbceaf6705) Add support for building against the Oracle JDK on OS X. ## [HawtJNI 1.10](http://fusesource.github.io/hawtjni/blog/releases/release-1.10.html), released 2014-02-12 * `efa684c` Ignore IDEA project files. * `18cb7e5` prepare for next development iteration * `f3bd38e` Upgrade parent pom version. * `175faf0` Merge pull request [#8](http://github.com/fusesource/hawtjni/issues/8) from normanmaurer/netty\_needs * `b3f8609` Allow to also use generate mojo with existing native src files * `c27b5a0` Avoid warning. * `c1980ef` Add support for building against the Oracle JDK on OS X. ## [HawtJNI 1.9](http://fusesource.github.io/hawtjni/blog/releases/release-1-9.html), released 2013-09-09 * [`1d27b2f`](https://github.com/fusesource/hawtjni/commit/1d27b2f1396920be7fce0be8b1995ac0459c69ef) Improve the generated build settings. * [`d9cd0ab`](https://github.com/fusesource/hawtjni/commit/d9cd0ab660ac5acbdc5f84c806ba14b77e197385) Should fix issue [#7](http://github.com/fusesource/hawtjni/issues/7). We now do a write barrier before setting the 'cached' field to 1 so that reader don't see this get re-ordered before all the fields are readable. ## [HawtJNI 1.8](http://fusesource.github.io/hawtjni/blog/releases/release-1-8.html), released 2013-05-13 * [`92c2661`](https://github.com/fusesource/hawtjni/commit/92c266170ce98edc200c656bd034a237098b8aa5) Simplify shared lib extraction. ## [HawtJNI 1.7](http://fusesource.github.io/hawtjni/blog/releases/release-1-7.html), released 2013-03-20 * [`3567b1d`](https://github.com/fusesource/hawtjni/commit/3567b1d89d458bddb651df252f3bb275c9076e1a) Support explicitly configuring which build tool to use on windows. * [`d566bf7`](https://github.com/fusesource/hawtjni/commit/d566bf7de5d6a67fa7c7b3e04352ca2630fb55fe) Fix for automake 1.11 ## [HawtJNI 1.6](http://fusesource.github.io/hawtjni/blog/releases/release-1-6.html), released 2012-08-09 * [`11df668`](https://github.com/fusesource/hawtjni/commit/11df668cb0d1269c0f98d9c09d80c56cf0770421) Updating hawtjni generate projects so that they work on OS X Lion. * [`f0e3ace`](https://github.com/fusesource/hawtjni/commit/f0e3ace6422e5c5413445229ac79d27f68b1485b) Fixes [#2](http://github.com/fusesource/hawtjni/issues/2) : Support passing the JNIEnv pointer to native methods. ## [HawtJNI 1.5](http://fusesource.github.io/hawtjni/blog/releases/release-1-5.html), released 2011-09-21 * [`15d5b1a`](https://github.com/fusesource/hawtjni/commit/15d5b1a4c928fb8c39eee0705316478af30704b5) Only include config.h if it's available. ## [HawtJNI 1.4](http://fusesource.github.io/hawtjni/blog/releases/release-1-4.html), released 2011-08-18 * Add more options to the maven hawtjni plugin so that you can build jars containing native libs in a different module from the one which generates the native package for the jar. ## [HawtJNI 1.3](http://fusesource.github.io/hawtjni/blog/releases/release-1-3.html), released 2011-08-08 * Add hawtjni_attach_thread and hawtjni_dettach_thread helper methods * Fully support binding against C++ source code / classes. * Support using private fields in struct bound classes. * Avoid "jump to label from here crosses initialization" compiler error message. * Provide better error messages when a user does not properly setup a C++ method binding. * Support mapping a class to a differently named structure name. * Support picking the OS X SDK version via a configure option. * Added pointer math support class to be able to do pointer math in java land without going into a JNI layer. ## [HawtJNI 1.2](http://fusesource.github.io/hawtjni/blog/releases/release-1-2.html), released 2011-06-11 * Adding bit model to the name of the extracted library to support hosts running both 32 and 64 bits JVM. * Converted website to a scalate based static website ## [HawtJNI 1.1](http://fusesource.github.io/hawtjni/blog/releases/release-1-1.html), released 2010-11-04 ---- * Generate a .vcxproj for for compatibility with the new Windows 7.1 SDK * Fixed callback failures on 32 bit platforms ## [HawtJNI 1.0](http://fusesource.github.io/hawtjni/blog/releases/2010/04/release-1-0.html), released 2010-02-24 * Initial release hawtjni-hawtjni-project-1.18/hawtjni-example/000077500000000000000000000000001374401771200213205ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/pom.xml000066400000000000000000000133741374401771200226450ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-project 1.18 hawtjni-example HawtJNI Example org.fusesource.hawtjni hawtjni-runtime ${project.version} junit junit 4.13.1 test log4j log4j 1.2.17 test org.fusesource.hawtjni hawtjni-maven-plugin ${project.version} generate build package-jar package-source org.apache.maven.plugins maven-shade-plugin 3.2.3 package shade junit:junit *:* META-INF/MANIFEST.MF mac mac org.fusesource.hawtjni hawtjni-maven-plugin osname=MacOS;processor=x86-64 osname=MacOS;processor=x86 * --with-universal osx hawtjni-hawtjni-project-1.18/hawtjni-example/src/000077500000000000000000000000001374401771200221075ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/000077500000000000000000000000001374401771200230335ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/java/000077500000000000000000000000001374401771200237545ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/java/test/000077500000000000000000000000001374401771200247335ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/java/test/Example.java000077500000000000000000000274061374401771200272050ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; 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(bar.SIZEOF); // Configure some data for a structure... bar f = new bar(); 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, bar.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(name="foo", flags={ClassFlag.STRUCT}) static public class bar { 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="struct foo *") public long prev; @JniField(getter = "get_d()", setter = "set_d()", flags = { GETTER_NONMEMBER, SETTER_NONMEMBER }) private float d; @JniField(getter = "get_sp()", setter = "set_sp()", flags={ SHARED_PTR, GETTER_NONMEMBER, SETTER_NONMEMBER }) private long CheckStr; @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)); result = prime * result + Float.valueOf(d).hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; bar other = (bar) 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; if (d != other.d) { return false; } return true; } @Override public String toString() { return "foo [a=" + a + ", b=" + b + ", c=" + Arrays.toString(c) + ", c5=" + c5 + ", prev=" + prev + ", d=" + d + "]"; } } public static final native void memmove ( @JniArg(cast="void *") long dest, @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) bar src, @JniArg(cast="size_t") long size); public static final native void memmove ( @JniArg(cast="void *", flags={NO_IN, CRITICAL}) bar 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); @JniMethod(cast = "struct foo *") public static final native long foo_add(@JniArg(cast="struct foo *")long ptr, int count); @JniMethod(cast = "char *") public static final native long char_add(@JniArg(cast="char *")long ptr, 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 (*)(int)", flags = ArgFlag.POINTER_ARG) long ptr); @JniClass(flags={ClassFlag.STRUCT, ClassFlag.CPP}) static class Range { static { LIBRARY.load(); } @JniMethod(flags={MethodFlag.CPP_NEW}) public static final native long Range(); @JniMethod(flags={MethodFlag.CPP_NEW}) public static final native long Range(int start, int end); @JniMethod(flags={MethodFlag.CPP_DELETE}) public static final native void delete(long ptr); @JniMethod(flags={MethodFlag.CPP_METHOD}) public static final native void dump(long ptr); } public static final native void passingtheenv (String msg, JNIEnv env); @JniClass(flags={ClassFlag.STRUCT}) static class ClassWithAccessors { static { LIBRARY.load(); } @JniField(getter = "get_e()", setter = "set_e()") private float e; } } hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/java/test/ObjectiveCExample.java000066400000000000000000000055461374401771200311410ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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="reinterpret_cast (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="reinterpret_cast (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-hawtjni-project-1.18/hawtjni-example/src/main/native-package/000077500000000000000000000000001374401771200257125ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/native-package/src/000077500000000000000000000000001374401771200265015ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/native-package/src/foo.cpp000066400000000000000000000026611374401771200277750ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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 float get_d(struct foo *arg) { return 0.0f; } void set_d(struct foo *arg, float d) { } std::shared_ptr get_sp(long CheckStr) { return std::make_shared (CheckStr); } void set_sp(struct foo *arg, std::shared_ptr ptr) { } void print_foo(struct foo *arg) { printf("foo@%p: { a: %d, b: %d, c: \"%s\", prev: @%p, d: %f, Checkstr: %p}\n", arg, arg->a, (int)arg->b, arg->c, arg->prev, get_d(arg), get_sp(arg->CheckStr).get()); } 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; } void callmeback(void (*thecallback)(int number)) { thecallback(69); } struct foo * foo_add(struct foo *arg, int count) { return arg+count; } char * char_add(char *arg, int count) { return arg+count; } void passingtheenv (const char *who, JNIEnv *env) { printf("%s, the JNIEnv is at: %p\n", who, env); } hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/native-package/src/foo.h000066400000000000000000000027121374401771200274370ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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 #include #include "jni.h" #ifdef __cplusplus extern "C" { #endif struct foo { int a; size_t b; char c[20]; struct foo *prev; long CheckStr; }; typedef struct _point { int x; int y; } point; struct ClassWithAccessors { float e; float (*get_e)(); void (*set_e)(float e); }; float get_d(struct foo *arg); void set_d(struct foo *arg, float d); float ClassWithAccessors_get_e(struct foo *arg); void ClassWithAccessors_set_e(struct foo *arg, float e); struct foo * foo_add(struct foo *arg, int count); char * char_add(char *arg, int count); void print_foo(struct foo *arg); long foowork(struct foo **arg, int count); void callmeback(void (*thecallback)(int number)); void passingtheenv (const char *who, JNIEnv *env); #ifdef __cplusplus } /* extern "C" */ #endif std::shared_ptr get_sp(long CheckStr); void set_sp(struct foo *arg, std::shared_ptr); #endif /* INCLUDED_FOO_H */ hawtjni-hawtjni-project-1.18/hawtjni-example/src/main/native-package/src/hawtjni-example.h000066400000000000000000000024331374401771200317510ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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 #include #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" #include "stdio.h" class Range { public: int start; int end; Range() { start = 0; end = 0; } Range(const int s, const int e) { start = s; end = e; } void dump() { printf("range: %d-%d\n", start, end); } }; #endif /* INCLUDED_PLATFORM_H */ hawtjni-hawtjni-project-1.18/hawtjni-example/src/test/000077500000000000000000000000001374401771200230665ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/test/java/000077500000000000000000000000001374401771200240075ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/test/java/test/000077500000000000000000000000001374401771200247665ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-example/src/test/java/test/ExampleTest.java000066400000000000000000000050641374401771200300710ustar00rootroot00000000000000package test; import static org.junit.Assert.*; import static test.Example.*; import org.fusesource.hawtjni.runtime.Callback; import org.fusesource.hawtjni.runtime.JNIEnv; import org.junit.Test; import static org.fusesource.hawtjni.runtime.PointerMath.*; import test.Example.bar; public class ExampleTest { static private int staticCallbackResult; private int instanceCallbackResult; @Test public void testPointerMath() { long values[] = new long[]{ 0, Long.MAX_VALUE, Long.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, 0+1, Long.MAX_VALUE+1, Long.MIN_VALUE+1, Integer.MAX_VALUE+1, Integer.MIN_VALUE+1, 0-1, Long.MAX_VALUE-1, Long.MIN_VALUE-1, Integer.MAX_VALUE-1, Integer.MIN_VALUE-1}; for( long i: values ) { assertEquals(char_add(i, 1), add(i, 1) ); assertEquals(char_add(i, -1), add(i, -1) ); } } @Test public void test() { // Allocate and initialize some memory on the heap. long ptr = malloc(bar.SIZEOF); memset(ptr, 0, bar.SIZEOF); // Configure an object that can be mapped to a C structure. bar expected = new bar(); 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, bar.SIZEOF); // Unmarshal the object from the allocated heap memory. bar acutal = new bar(); memmove(acutal, ptr, bar.SIZEOF); assertEquals(expected, acutal); Callback callback = new Callback(this, "instanceCallback", 1); callmeback(callback.getAddress()); assertEquals(69, instanceCallbackResult); callback.dispose(); long r1 = Range.Range(); Range.dump(r1); long r2 = Range.Range(10,100); Range.dump(r2); Range.delete(r1); Range.delete(r2); 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); passingtheenv("Hiram", null); } public long instanceCallback(long value) { this.instanceCallbackResult = (int) value; return 0; } static public long staticCallback(long value) { staticCallbackResult = (int) value; return 0; } } hawtjni-hawtjni-project-1.18/hawtjni-generator/000077500000000000000000000000001374401771200216535ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/pom.xml000066400000000000000000000107121374401771200231710ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-project 1.18 hawtjni-generator HawtJNI Generator This module contains the JNI code generation tools. org.fusesource.hawtjni hawtjni-runtime ${project.version} xbean-finder org.apache.xbean 4.16 org.ow2.asm asm 8.0.1 org.ow2.asm asm-commons 8.0.1 commons-cli commons-cli 1.0 org.apache.maven.plugins maven-shade-plugin 3.2.3 package shade junit:junit *:* META-INF/DEPENDENCIES META-INF/LICENSE* META-INF/NOTICE META-INF/MANIFEST.MF module-info.class org.apache.xbean:xbean-finder org/apache/xbean/asm7/original/commons/AsmConstants.class org/apache/xbean/asm7/original/commons/EmptyVisitor* hawtjni-hawtjni-project-1.18/hawtjni-generator/src/000077500000000000000000000000001374401771200224425ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/000077500000000000000000000000001374401771200233665ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/000077500000000000000000000000001374401771200243075ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/000077500000000000000000000000001374401771200250765ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/000077500000000000000000000000001374401771200272615ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001374401771200307255ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/000077500000000000000000000000001374401771200327135ustar00rootroot00000000000000CleanupClass.java000077500000000000000000000105311374401771200360570ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000073761374401771200370030ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000075121374401771200364300ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000047001374401771200373260ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000076411374401771200353260ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000412371374401771200347550ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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( target.getName().endsWith(".c") && gen.isCPP ) { target = new File(target.getParentFile(), target.getName()+"pp"); } 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.java000077500000000000000000000154151374401771200357770ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000130741374401771200362460ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000002076251374401771200360650ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000577451374401771200370020ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000001353771374401771200370020ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.JNIFieldAccessor; 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; } if (isCPP) { output("extern \"C\" "); } 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 simpleName = type.getSimpleName(); JNIFieldAccessor accessor = field.getAccessor(); String fieldId = "(*env)->GetStaticFieldID(env, that, \""+field.getName()+"\", \""+type.getTypeSignature(allowConversion)+"\")"; if (isCPP) { fieldId = "env->GetStaticFieldID(that, \""+field.getName()+"\", \""+type.getTypeSignature(allowConversion)+"\")"; } if (type.isPrimitive()) { if (isCPP) { output("\tenv->SetStatic"+type.getTypeSignature1(allowConversion)+"Field(that, "+fieldId +", "); } else { output("\t(*env)->SetStatic"+type.getTypeSignature1(allowConversion)+"Field(env, that, "+fieldId +", "); } output("("+type.getTypeSignature2(allowConversion)+")"); if( field.isPointer() ) { output("(intptr_t)"); } output(accessor.getter()); 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.getter()); output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(allowConversion, false)); output(")"); output(accessor.getter()); outputln(");"); output("\t}"); } else { throw new Error("not done"); } } else { outputln("\t{"); if (isCPP) { output("\tjobject lpObject1 = env->GetStaticObjectField(that, "); } else { output("\tjobject lpObject1 = (*env)->GetStaticObjectField(env, that, "); } output(field.getDeclaringClass().getSimpleName()); output("Fc."); output(field.getName()); outputln(");"); output("\tif (lpObject1 != NULL) set"); output(simpleName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor.getter()); 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("org.fusesource.hawtjni.runtime.JNIEnv")) { // no need to generate a local for this one.. } 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.getNativeName()); 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { if (isCritical(param)) { genFailTag |= generateGetParameter(method, param, true, 2); } } } outputln("\t} else"); outputln("#endif"); outputln("\t{"); for (JNIParameter param : params) { if( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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( !"org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { 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.length() != 0 && !cast.equals("()")) { if( method.isPointer() ) { output("(intptr_t)"); } output(cast); } else { if( method.getFlag(CPP_NEW)) { String[] parts = getNativeNameParts(method); String className = parts[0]; output("(intptr_t)("+className+" *)"); } 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 { if( "org.fusesource.hawtjni.runtime.JNIEnv".equals(param.getTypeClass().getName()) ) { output("env"); } else { JNIType paramType = param.getType32(); if (!paramType.isPrimitive() && !isSystemClass(paramType)) output("lp"); output("arg" + i); } } if (param.getFlag(ArgFlag.CS_OBJECT)) output(")"); } output(")"); } } static String[] getNativeNameParts(JNIMethod method) { String className = null; String methodName = null; JNIClass dc = method.getDeclaringClass(); if( dc.getFlag(ClassFlag.CPP) || dc.getFlag(ClassFlag.STRUCT) ) { className = method.getDeclaringClass().getNativeName(); } if( method.getAccessor().length() != 0 ) { methodName = method.getAccessor(); int pos = methodName.lastIndexOf("::"); if( pos >= 0 ) { className = methodName.substring(0, pos); methodName = methodName.substring(pos+2); } } else { methodName = method.getName(); if( className==null ) { int pos = methodName.indexOf("_"); if( pos > 0 ) { className = methodName.substring(0, pos); methodName = methodName.substring(pos+1); } } } if( className==null ) { throw new Error(String.format("Could not determine object type name of method '%s'", method.getDeclaringClass().getSimpleName()+"."+method.getName())); } return new String[]{className, methodName}; } 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("\t\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) || method.getFlag(MethodFlag.SETTER) || method.getFlag(MethodFlag.GETTER) || method.getFlag(MethodFlag.ADDER)) { String[] parts = getNativeNameParts(method); String className = parts[0]; String methodName = parts[1]; if (method.getFlag(MethodFlag.CS_OBJECT)) { output("TO_HANDLE("); } output("("); if( params.isEmpty() ) { throw new Error(String.format("C++ bound method '%s' missing the 'this' parameter", method.getDeclaringClass().getSimpleName()+"."+method.getName())); } 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)"); } } else { output("("+className+" *)(intptr_t)"); } if (param.getFlag(ArgFlag.CS_OBJECT)) { output("TO_OBJECT("); } output("arg0"); if (param.getFlag(ArgFlag.CS_OBJECT)) { output(")"); } output(")->"); output(methodName); paramStart = 1; } else if (method.getFlag(MethodFlag.CS_NEW)) { output("TO_HANDLE(gcnew "); String accessor = method.getAccessor(); if (accessor.length() != 0) { output(accessor); } else { JNIClass dc = method.getDeclaringClass(); if( dc.getFlag(ClassFlag.CPP) || dc.getFlag(ClassFlag.STRUCT) ) { output(dc.getNativeName()); } 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 { JNIClass dc = method.getDeclaringClass(); if( dc.getFlag(ClassFlag.CPP) ) { output(method.getDeclaringClass().getNativeName()); } else { int index = -1; if ((index = name.indexOf('_')) != -1) { output(name.substring(index+1)); } else { output(name); } } } } else if (method.getFlag(MethodFlag.CPP_DELETE)) { String[] parts = getNativeNameParts(method); String className = parts[0]; 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("("+className+" *)(intptr_t)"); } 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.length() != 0 && !cast.equals("()") ) { 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\t{"); output("\t\t\t"); output(copy); output("* copy = new "); output(copy); outputln("();"); outputln("\t\t\t*copy = temp;"); output("\t\t\trc = "); output("("); output(returnType.getTypeSignature2(!returnType.equals(returnType64))); output(")"); outputln("copy;"); outputln("\t\t}"); 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.length() != 0 && !cast.equals("()")) { 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.java000077500000000000000000000013301374401771200366530ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/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.java000077500000000000000000000044761374401771200366230ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000163241374401771200364550ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000561001374401771200370220ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.HashMap; import java.util.List; import org.fusesource.hawtjni.generator.model.JNIClass; import org.fusesource.hawtjni.generator.model.JNIField; import org.fusesource.hawtjni.generator.model.JNIFieldAccessor; 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; private HashMap> structFields = new HashMap>(); 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) { if (!structFields.containsKey(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); } } structFields.put(clazz, rc); } return structFields.get(clazz); } 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 simpleName = clazz.getSimpleName(); output(simpleName); output("_FID_CACHE "); output(simpleName); outputln("Fc;"); } void generateBlankMacros(JNIClass clazz) { if (clazz.getConditional() == null) { return; } String simpleName = clazz.getSimpleName(); outputln("#else"); output("#define cache"); output(simpleName); outputln("Fields(a,b)"); output("#define get"); output(simpleName); outputln("Fields(a,b,c) NULL"); output("#define set"); output(simpleName); outputln("Fields(a,b,c)"); } void generatePrototypes(JNIClass clazz) { String clazzName = clazz.getNativeName(); String simpleName = clazz.getSimpleName(); output("void cache"); output(simpleName); outputln("Fields(JNIEnv *env, jobject lpObject);"); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); output(" *get"); output(simpleName); 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(simpleName); 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 simpleName = clazz.getSimpleName(); output("typedef struct "); output(simpleName); outputln("_FID_CACHE {"); outputln("\tint cached;"); outputln("\tjclass clazz;"); List fields = clazz.getDeclaredFields(); boolean first = true; for (JNIField field : fields) { if (ignoreField(field)) continue; if (first) output("\tjfieldID "); else output(", "); output(field.getName()); first = false; } outputln(";"); output("} "); output(simpleName); outputln("_FID_CACHE;"); } void generateCacheFunction(JNIClass clazz) { String simpleName = clazz.getSimpleName(); String clazzName = clazz.getNativeName(); output("void cache"); output(simpleName); outputln("Fields(JNIEnv *env, jobject lpObject)"); outputln("{"); output("\tif ("); output(simpleName); outputln("Fc.cached) return;"); JNIClass superclazz = clazz.getSuperclass(); if (!superclazz.getName().equals("java.lang.Object") && hasNonIgnoredFields(superclazz)) { String superName = superclazz.getSimpleName(); output("\tcache"); output(superName); outputln("Fields(env, lpObject);"); } output("\t"); output(simpleName); 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(simpleName); output("Fc."); output(field.getName()); if (isCPP) { output(" = env->GetFieldID("); } else { output(" = (*env)->GetFieldID(env, "); } output(simpleName); 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(");"); } // Makes sure compiler/cpu does not reorder the following write before the previous updates are done. outputln("\thawtjni_w_barrier();"); output("\t"); output(simpleName); outputln("Fc.cached = 1;"); outputln("}"); } void generateGetFields(JNIClass clazz) { JNIClass superclazz = clazz.getSuperclass(); String clazzName = clazz.getNativeName(); String superName = superclazz.getNativeName(); String methodname; if (!superclazz.getName().equals("java.lang.Object") && hasNonIgnoredFields(superclazz)) { /* * 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(); int sharePtrIndex = 0; 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 simpleName = type.getSimpleName(); JNIFieldAccessor accessor = field.getAccessor(); boolean allowConversion = !type.equals(type64); output("\t"); if (type.isPrimitive()) { if (!accessor.isNonMemberSetter()) output("lpStruct->"); if (accessor.isMethodSetter()) { String setterStart = accessor.setter().split("\\(")[0]; output(setterStart + "("); if (accessor.isNonMemberSetter()) output("lpStruct, "); } else { output(accessor.setter()); output(" = "); } if (field.isSharedPointer()) output("std::make_shared<" + type.getTypeSignature2(allowConversion) + ">("); else 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()); if (field.isSharedPointer()) output(")"); if (accessor.isMethodSetter()) output(")"); output(");"); } else if (type.isArray()) { JNIType componentType = type.getComponentType(), componentType64 = type64.getComponentType(); if (componentType.isPrimitive()) { if (field.isSharedPointer()) { output("(&"); output("lpStruct->" + accessor); output("));"); } outputln("{"); 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("); } else { output("ArrayRegion(env, lpObject1, 0, sizeof("); } if (!accessor.isNonMemberGetter()) output("lpStruct->"); output(accessor.getter()); output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(!type.equals(type64), false)); output(")"); if (!accessor.isNonMemberGetter()) output("lpStruct->"); output(accessor.getter()); 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(simpleName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor.getter()); outputln(");"); output("\t}"); } outputln(); if (conditional != null) { outputln("#endif"); } } } void generateGetFunction(JNIClass clazz) { String clazzName = clazz.getNativeName(); String simpleName = clazz.getSimpleName(); if (clazz.getFlag(ClassFlag.STRUCT) && !clazz.getFlag(ClassFlag.TYPEDEF)) { output("struct "); } output(clazzName); output(" *get"); output(simpleName); 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(simpleName); output("Fc.cached) cache"); output(simpleName); 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.getNativeName(); String superName = superclazz.getNativeName(); if (!superclazz.getName().equals("java.lang.Object") && hasNonIgnoredFields(superclazz)) { /* * 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 simpleName = type.getSimpleName(); JNIFieldAccessor accessor = field.getAccessor(); 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)"); } if (!accessor.isNonMemberGetter()) output("lpStruct->"); if (accessor.isMethodGetter()) { String getterStart = accessor.getter().split("\\(")[0]; output(getterStart + "("); if (accessor.isNonMemberGetter()) output("lpStruct"); if (field.isSharedPointer()) output("->" + field.getName()); output(")"); } else { output(accessor.getter()); } if (field.isSharedPointer()) { output(".get()"); } 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("); } else { output("ArrayRegion(env, lpObject1, 0, sizeof("); } if (!accessor.isNonMemberGetter()) output("lpStruct->"); if (accessor.isMethodGetter()) { String getterStart = accessor.getter().split("\\(")[0]; output(getterStart + "("); if (accessor.isNonMemberGetter()) output("lpStruct"); output(")"); } else { output(accessor.getter()); } output(")"); if (!componentType.isType("byte")) { output(" / sizeof("); output(componentType.getTypeSignature2(!componentType.equals(componentType64))); output(")"); } output(", ("); output(type.getTypeSignature4(allowConversion, false)); output(")"); if (!accessor.isNonMemberGetter()) output("lpStruct->"); output(accessor.getter()); 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) set"); output(simpleName); output("Fields(env, lpObject1, &lpStruct->"); output(accessor.getter()); outputln(");"); output("\t}"); } outputln(); if (conditional != null) { outputln("#endif"); } } } void generateSetFunction(JNIClass clazz) { String clazzName = clazz.getNativeName(); String simpleName = clazz.getSimpleName(); output("void set"); output(simpleName); 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(simpleName); output("Fc.cached) cache"); output(simpleName); 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 field.ignore() || ((mods & Modifier.FINAL) != 0) || ((mods & Modifier.STATIC) != 0); } boolean hasNonIgnoredFields(JNIClass clazz) { for (JNIField field : getStructFields(clazz)) if (!ignoreField(field)) return true; return false; } } hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/000077500000000000000000000000001374401771200340135ustar00rootroot00000000000000JNIClass.java000077500000000000000000000021711374401771200362110ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 String getNativeName(); public JNIClass getSuperclass(); public List getDeclaredFields(); public List getDeclaredMethods(); public List getNativeMethods(); public boolean getGenerate(); public String getConditional(); } JNIField.java000077500000000000000000000021621374401771200361670ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 JNIFieldAccessor getAccessor(); public String getCast(); public String getConditional(); public boolean ignore(); public boolean isSharedPointer(); public boolean isPointer(); } JNIFieldAccessor.java000066400000000000000000000006031374401771200376450ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/modelpackage org.fusesource.hawtjni.generator.model; /** * @author Calin Iorgulescu */ public interface JNIFieldAccessor { public String getter(); public String setter(); public boolean isNonMemberGetter(); public boolean isNonMemberSetter(); public boolean isMethodGetter(); public boolean isMethodSetter(); } JNIMethod.java000077500000000000000000000026561374401771200363740ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000017401374401771200370650ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000022501374401771200360630ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 getNativeName(); 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.java000077500000000000000000000105751374401771200371640ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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; private String nativeName; 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 String getNativeName() { lazyLoad(); if( nativeName!=null ) return nativeName; else return 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())); if( this.annotation.name().trim().length() > 0 ) { this.nativeName = this.annotation.name().trim(); } } 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 (Method method : methods) { this.methods.add(new ReflectMethod(this, method)); } } } ReflectField.java000077500000000000000000000115661374401771200371430ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.apache.commons.lang.StringUtils; 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; private ReflectFieldAccessor accessor; 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 JNIFieldAccessor getAccessor() { return accessor; } public String getCast() { String rc = annotation == null ? "" : annotation.cast().trim(); return cast(rc); } public boolean ignore() { return getFlag(FieldFlag.FIELD_SKIP); } public boolean isPointer() { if( annotation == null ) { return false; } return getFlag(POINTER_FIELD) || ( type.getWrappedClass() == Long.TYPE && getCast().endsWith("*") ); } public boolean isSharedPointer() { if (annotation == null) { return false; } return getFlag(SHARED_PTR); } 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(); this.accessor = new ReflectFieldAccessor(this.field.getName()); if( this.annotation!=null ) { this.flags.addAll(Arrays.asList(this.annotation.flags())); if (!StringUtils.isEmpty(this.annotation.accessor())) { this.accessor = new ReflectFieldAccessor(this.annotation.accessor()); } else if (!StringUtils.isEmpty(this.annotation.getter()) && !StringUtils.isEmpty(this.annotation.setter())) { this.accessor = new ReflectFieldAccessor( this.annotation.getter(), this.flags.contains(GETTER_NONMEMBER), this.annotation.setter(), this.flags.contains(SETTER_NONMEMBER)); } } allowConversion = this.field.getAnnotation(T32.class)!=null; } } ReflectFieldAccessor.java000066400000000000000000000022641374401771200406160ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/modelpackage org.fusesource.hawtjni.generator.model; /** * @author Calin Iorgulescu */ public class ReflectFieldAccessor implements JNIFieldAccessor { private String getter; private String setter; private boolean nonMemberGetter; private boolean nonMemberSetter; public ReflectFieldAccessor(String value) { this.getter = this.setter = value; this.nonMemberGetter = this.nonMemberSetter = false; } public ReflectFieldAccessor(String getter, boolean nonMemberGetter, String setter, boolean nonMemberSetter) { this.getter = getter; this.nonMemberGetter = nonMemberGetter; this.setter = setter; this.nonMemberSetter = nonMemberSetter; } public String getter() { return getter; } public String setter() { return setter; } public boolean isNonMemberGetter() { return nonMemberGetter; } public boolean isNonMemberSetter() { return nonMemberSetter; } public boolean isMethodGetter() { return getter.contains("("); } public boolean isMethodSetter() { return setter.contains("("); } } ReflectMethod.java000077500000000000000000000161551374401771200373370ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000055021374401771200400310ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000077500000000000000000000171261374401771200370370ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/model/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.JniClass; /** * * @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 getNativeName() { JniClass annotation = clazz.getAnnotation(JniClass.class); if( annotation==null ) { return getSimpleName(); } else { String name = annotation.name().trim(); if( name.length()==0 ) { return getSimpleName(); } else { return name; } } } 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 = getNativeName(); 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-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/000077500000000000000000000000001374401771200336705ustar00rootroot00000000000000FileSupport.java000066400000000000000000000052661374401771200367410ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000066400000000000000000000047221374401771200372400ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.java000066400000000000000000000015431374401771200370000ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/util/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.endsWith(")")) cast = "(" + cast + ")"; } return cast; } } hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/resources/000077500000000000000000000000001374401771200254005ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/resources/hawtjni-callback.c000077500000000000000000000537111374401771200307540ustar00rootroot00000000000000/******************************************************************************* * 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; jlong 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 jlong 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, jlong 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; jlong 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-hawtjni-project-1.18/hawtjni-generator/src/main/resources/hawtjni.c000077500000000000000000000102201374401771200272060ustar00rootroot00000000000000/******************************************************************************* * 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 #include int IS_JNI_1_2 = 0; #ifdef HAVE_PTHREAD_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef JNI_VERSION_1_2 JavaVM *JVM; #ifdef HAVE_PTHREAD_H pthread_key_t JNI_ATTACH_THREAD_LOCAL_KEY; #endif jint hawtjni_attach_thread(JNIEnv **env, const char *thread_name) { JavaVMAttachArgs args; args.version = JNI_VERSION_1_2; args.name = (char *)thread_name; args.group = 0; #ifdef HAVE_PTHREAD_H if( JNI_ATTACH_THREAD_LOCAL_KEY ) { *env = pthread_getspecific(JNI_ATTACH_THREAD_LOCAL_KEY); if( ! *env ) { if( (*JVM)->AttachCurrentThread(JVM, (void**)env, &args)==0 ) { pthread_setspecific(JNI_ATTACH_THREAD_LOCAL_KEY, *env); } else { return -1; } } return 0; } else { return (*JVM)->AttachCurrentThread(JVM, (void**)env, &args); } #else return (*JVM)->AttachCurrentThread(JVM, (void**)env, &args); #endif } jint hawtjni_detach_thread() { #ifdef HAVE_PTHREAD_H if( JNI_ATTACH_THREAD_LOCAL_KEY ) { // Don't actually detach.. that will automatically // happen when the the thread dies. return 0; } else { return (*JVM)->DetachCurrentThread(JVM); } #else return (*JVM)->DetachCurrentThread(JVM); #endif } #ifdef HAVE_PTHREAD_H void hawtjni_thread_cleanup(void *data) { if( data ) { (*JVM)->DetachCurrentThread(JVM); pthread_setspecific(JNI_ATTACH_THREAD_LOCAL_KEY, 0); } } #endif JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { IS_JNI_1_2 = 1; JVM = vm; #ifdef HAVE_PTHREAD_H if( pthread_key_create(&JNI_ATTACH_THREAD_LOCAL_KEY, hawtjni_thread_cleanup) ) { JNI_ATTACH_THREAD_LOCAL_KEY = 0; } #endif 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-hawtjni-project-1.18/hawtjni-generator/src/main/resources/hawtjni.h000077500000000000000000000133001374401771200272150ustar00rootroot00000000000000/******************************************************************************* * 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 #define _MULTI_THREADED #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "jni.h" #include #ifdef __cplusplus extern "C" { #endif extern int IS_JNI_1_2; #ifndef JNI64 #if defined(_LP64) #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 #ifdef JNI_VERSION_1_2 extern JavaVM *JVM; jint hawtjni_attach_thread(JNIEnv **env, const char *thread_name); jint hawtjni_detach_thread(); #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 __GNUC__ #define hawtjni_w_barrier() __sync_synchronize() #elif defined(SOLARIS2) && SOLARIS2 >= 10 #include #define hawtjni_w_barrier() __machine_w_barrier() #elif defined(__APPLE__) #include #define hawtjni_w_barrier() OSMemoryBarrier() #elif defined(_WIN32) || defined(_WIN64) #include #define hawtjni_w_barrier() _mm_sfence(); _WriteBarrier() #else #pragma message ( "Don't know how to do a memory barrier on this platform" ) #define hawtjni_w_barrier() #endif void hawtjni_atomic_set(jlong *target, jlong value); jlong hawtjni_atomic_get(jlong *target); #ifdef __cplusplus } #endif #endif /* ifndef INC_HAWTJNI_H */ hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/resources/windows/000077500000000000000000000000001374401771200270725ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-generator/src/main/resources/windows/stdint.h000066400000000000000000000170601374401771200305540ustar00rootroot00000000000000// 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-hawtjni-project-1.18/hawtjni-maven-plugin/000077500000000000000000000000001374401771200222675ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/pom.xml000066400000000000000000000133461374401771200236130ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-project 1.18 hawtjni-maven-plugin maven-plugin HawtJNI Maven Plugin Use HawtJNI from a maven plugin ${mavenVersion} 3.6.3 ${project.version} org.fusesource.hawtjni hawtjni-generator ${project.version} org.apache.maven maven-plugin-api ${mavenVersion} org.apache.maven maven-project 2.0.11 org.codehaus.plexus plexus-utils 3.3.0 org.codehaus.plexus plexus-interpolation 1.26 org.apache.maven maven-artifact-manager 2.0.11 org.apache.maven maven-artifact 2.0.11 org.apache.maven maven-archiver 2.4 org.codehaus.plexus plexus-archiver 4.2.2 org.codehaus.plexus plexus-container-default org.codehaus.plexus plexus-component-api org.codehaus.plexus plexus-io 3.2.0 org.codehaus.plexus plexus-container-default org.codehaus.plexus plexus-component-api org.apache.maven.plugin-tools maven-plugin-annotations 3.6.0 provided org.apache.maven.plugins maven-plugin-plugin 3.6.0 org.apache.maven.plugins maven-plugin-plugin default-descriptor process-classes help-goal helpmojo org.apache.maven.plugins maven-plugin-plugin hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/000077500000000000000000000000001374401771200230565ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/000077500000000000000000000000001374401771200240025ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/000077500000000000000000000000001374401771200247235ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/000077500000000000000000000000001374401771200255125ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/000077500000000000000000000000001374401771200276755ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001374401771200313415ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/maven/000077500000000000000000000000001374401771200324475ustar00rootroot00000000000000BuildMojo.java000066400000000000000000000420451374401771200351240ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009-2011 FuseSource Corp. * 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.*; import java.net.URL; 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.Dependency; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; 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.IOUtil; 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. * * @author Hiram Chirino */ @Mojo(name = "build", defaultPhase = LifecyclePhase.GENERATE_TEST_RESOURCES) public class BuildMojo extends AbstractMojo { /** * The maven project. */ @Parameter(defaultValue = "${project}", readonly = true) protected MavenProject project; /** * Remote repositories */ @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true) protected List remoteArtifactRepositories; /** * Local maven repository. */ @Parameter(defaultValue = "${localRepository}", readonly = true) protected ArtifactRepository localRepository; /** * Artifact factory, needed to download the package source file */ @Component protected ArtifactFactory artifactFactory; /** * Artifact resolver, needed to download the package source file */ @Component protected ArtifactResolver artifactResolver; /** */ @Component private ArchiverManager archiverManager; /** * The base name of the library, used to determine generated file names. */ @Parameter(defaultValue = "${project.artifactId}") private String name; /** * Where the unpacked build package is located. */ @Parameter(defaultValue = "${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(defaultValue = "${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(defaultValue = "${project.build.directory}") private File buildDirectory; /** * Should we skip executing the autogen.sh file. */ @Parameter(defaultValue = "${skip-autogen}") private boolean skipAutogen; /** * Should we force executing the autogen.sh file. */ @Parameter(defaultValue = "${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(defaultValue = "${skip-configure}") private boolean skipConfigure; /** * Should we force executing the configure command. */ @Parameter(defaultValue = "${force-configure}") private boolean forceConfigure; /** * Should we display all the native build output? */ @Parameter(defaultValue = "${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(defaultValue = "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(defaultValue = "true") private boolean downloadSourcePackage = true; /** * The dependency to download to get the native sources. */ @Parameter private Dependency nativeSrcDependency; /** * URL to where we can down the source package */ @Parameter(defaultValue = "${native-src-url}") private String nativeSrcUrl; /** * The build tool to use on Windows systems. Set * to 'msbuild', 'vcbuild', or 'detect' */ @Parameter(defaultValue = "detect") private String windowsBuildTool; /** * The name of the msbuild/vcbuild project to use. * Defaults to 'vs2010' for 'msbuild' * and 'vs2008' for 'vcbuild'. */ @Parameter private String windowsProjectName; 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 libPlatform = this.platform != null ? this.platform : Library.getPlatform(); String platform; String configuration="release"; if( "windows32".equals(libPlatform) ) { platform = "Win32"; } else if( "windows64".equals(libPlatform) ) { platform = "x64"; } else { throw new MojoExecutionException("Unsupported platform: "+libPlatform); } boolean useMSBuild = false; String tool = windowsBuildTool.toLowerCase().trim(); if( "detect".equals(tool) ) { String toolset = System.getenv("PlatformToolset"); if( "Windows7.1SDK".equals(toolset) ) { useMSBuild = true; } else { String vcinstalldir = System.getenv("VCINSTALLDIR"); if( vcinstalldir!=null ) { if( vcinstalldir.contains("Microsoft Visual Studio 10") || vcinstalldir.contains("Microsoft Visual Studio 11") || vcinstalldir.contains("Microsoft Visual Studio 12") || vcinstalldir.contains("Microsoft Visual Studio 14") || vcinstalldir.contains("Microsoft Visual Studio\\2017") ) { useMSBuild = true; } } } } else if( "msbuild".equals(tool) ) { useMSBuild = true; } else if( "vcbuild".equals(tool) ) { useMSBuild = false; } else { throw new MojoExecutionException("Invalid setting for windowsBuildTool: "+windowsBuildTool); } if( useMSBuild ) { // vcbuild was removed.. use the msbuild tool instead. int rc = cli.system(buildDir, new String[]{"msbuild", (windowsProjectName != null ? windowsProjectName : "vs2010") + ".vcxproj", "/property:Platform="+platform, "/property:Configuration="+configuration}); if( rc != 0 ) { throw new MojoExecutionException("vcbuild failed with exit code: "+rc); } } else { // try to use a vcbuild.. int rc = cli.system(buildDir, new String[]{"vcbuild", "/platform:"+platform, (windowsProjectName != null ? windowsProjectName : "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.getPlatformSpecificResourcePath(libPlatform)); 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 { if( !buildDir.exists() ) { 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(), "--libdir="+distDirectory.getCanonicalPath()+"/lib"}, 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.getPlatformSpecificResourcePath(platform)); FileUtils.copyFile(libFile, target); } public void downloadNativeSourcePackage(File buildDir) throws MojoExecutionException { File packageZipFile; if( nativeSrcUrl ==null || nativeSrcUrl.trim().length()==0 ) { Artifact artifact=null; if( nativeSrcDependency==null ) { artifact = artifactFactory.createArtifactWithClassifier(project.getGroupId(), project.getArtifactId(), project.getVersion(), "zip", sourceClassifier); } else { artifact = artifactFactory.createArtifactWithClassifier(nativeSrcDependency.getGroupId(), nativeSrcDependency.getArtifactId(), nativeSrcDependency.getVersion(), nativeSrcDependency.getType(), nativeSrcDependency.getClassifier()); } try { artifactResolver.resolveAlways(artifact, remoteArtifactRepositories, localRepository); } catch (ArtifactResolutionException e) { throw new MojoExecutionException("Error downloading.", e); } catch (ArtifactNotFoundException e) { throw new MojoExecutionException("Requested download does not exist.", e); } packageZipFile = artifact.getFile(); if( packageZipFile.isDirectory() ) { // Yep. looks like we are running on mvn 3, seem like // mvn 3 does not actually download the artifact. it just points us // to our own build. throw new MojoExecutionException("Add a '-Dnative-src-url=file:...' to have maven download the native package"); } } else { try { packageZipFile = new File(buildDirectory, "native-build.zip"); URL url = new URL(nativeSrcUrl.trim()); InputStream is = url.openStream(); try { FileOutputStream os = new FileOutputStream(packageZipFile); try { IOUtil.copy(is, os); } finally { IOUtil.close(is); } } finally { IOUtil.close(is); } } catch (Exception e) { throw new MojoExecutionException("Error downloading: "+ nativeSrcUrl, e); } } 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); File source = findSourceRoot(dest); if( source==null ) { throw new MojoExecutionException("Extracted package did not look like it contained a native source build."); } FileUtils.copyDirectoryStructureIfModified(source, buildDir); } catch (MojoExecutionException e) { throw e; } catch (Throwable e) { throw new MojoExecutionException("Could not extract the native source package.", e); } } private File findSourceRoot(File dest) { if(dest.isDirectory()) { if( new File(dest, "configure").exists() ) { return dest; } else { for (File file : dest.listFiles()) { File root = findSourceRoot(file); if( root!=null ) { return root; } } return null; } } else { return null; } } } CLI.java000077500000000000000000000064431374401771200336540ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/mavenpackage 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.java000066400000000000000000000372071374401771200356230ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009-2011 FuseSource Corp. * 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.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; 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. * * @author Hiram Chirino */ @Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES) public class GenerateMojo extends AbstractMojo { /** * The maven project. */ @Parameter(defaultValue = "${project}", readonly = true) protected MavenProject project; /** * The directory where the native source files are located. */ @Parameter private File nativeSourceDirectory; /** * The directory where the generated native source files are located. */ @Parameter(defaultValue = "${project.build.directory}/generated-sources/hawtjni/native-src") private File generatedNativeSourceDirectory; /** * The base name of the library, used to determine generated file names. */ @Parameter(defaultValue = "${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(defaultValue = "") 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(defaultValue = "${project.build.outputDirectory}") private File classesDirectory; /** * The directory where the generated build package is located.. */ @Parameter(defaultValue = "${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(defaultValue = "${basedir}/src/main/native-package") private File customPackageDirectory; /** * The text encoding of the files. */ @Parameter(defaultValue = "UTF-8") private String encoding; /** * Should we skip executing the autogen.sh file. */ @Parameter(defaultValue = "${skip-autogen}") private boolean skipAutogen; /** * Should we force executing the autogen.sh file. */ @Parameter(defaultValue = "${force-autogen}") private boolean forceAutogen; /** * Should we display all the native build output? */ @Parameter(defaultValue = "${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(defaultValue = "true") private boolean callbacks; /** * The build tool to use on Windows systems. Set * to 'msbuild', 'vcbuild', or 'detect' or 'none' */ @Parameter(defaultValue = "detect") private String windowsBuildTool; /** * The name of the msbuild/vcbuild project to use. * Defaults to 'vs2010' for 'msbuild' * and 'vs2008' for 'vcbuild'. */ @Parameter private String windowsProjectName; /** * Set this value to true to include the import of a custom properties file in your vcxproj (not applicable * to vs2008). This greatly simplifies the configurability of your project. */ @Parameter(defaultValue = "false") private boolean windowsCustomProps; /** * The tools version used in the header of your vcxproj (not applicable to vs2008). */ @Parameter(defaultValue = "4.0") private String windowsToolsVersion; /** * The target platform version used in your vcxproj (not applicable to vs2008). * Not supplied by default. */ @Parameter private String windowsTargetPlatformVersion; /** * The platform toolset version used in your vcxproj (not applicable to vs2008). * Not supplied by default. */ @Parameter private String windowsPlatformToolset; private File targetSrcDir; private CLI cli = new CLI(); public void execute() throws MojoExecutionException { cli.verbose = verbose; cli.log = getLog(); if (nativeSourceDirectory == null) { generateNativeSourceFiles(); } else { copyNativeSourceFiles(); } generateBuildSystem(); } private void copyNativeSourceFiles() throws MojoExecutionException { try { FileUtils.copyDirectory(nativeSourceDirectory, generatedNativeSourceDirectory); } catch (Exception e) { throw new MojoExecutionException("Copy of Native source failed: "+e, e); } } 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.. String tool = windowsBuildTool.toLowerCase().trim(); if( "detect".equals(tool) ) { copyTemplateResource("vs2008.vcproj", (windowsProjectName != null ? windowsProjectName : "vs2008") + ".vcproj", true); copyTemplateResource("vs2010.vcxproj", (windowsProjectName != null ? windowsProjectName : "vs2010") + ".vcxproj", true); if (windowsCustomProps) { copyTemplateResource("vs2010.custom.props", (windowsProjectName != null ? windowsProjectName : "vs2010") + ".custom.props", true); } } else if( "msbuild".equals(tool) ) { copyTemplateResource("vs2010.vcxproj", (windowsProjectName != null ? windowsProjectName : "vs2010") + ".vcxproj", true); if (windowsCustomProps) { copyTemplateResource("vs2010.custom.props", (windowsProjectName != null ? windowsProjectName : "vs2010") + ".custom.props", true); } } else if( "vcbuild".equals(tool) ) { copyTemplateResource("vs2008.vcproj", (windowsProjectName != null ? windowsProjectName : "vs2008") + ".vcproj", true); } else if( "none".equals(tool) ) { } else { throw new MojoExecutionException("Invalid setting for windowsBuildTool: "+windowsBuildTool); } 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 { copyTemplateResource(file, file, filter); } private void copyTemplateResource(String file, String output, boolean filter) throws MojoExecutionException { try { File target = FileUtils.resolveFile(packageDirectory, output); 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 cpp_files = new ArrayList(); cpp_files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.cpp", null, false)); cpp_files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.cxx", null, false)); List files = new ArrayList(); files.addAll(cpp_files); files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.c", null, false)); files.addAll(FileUtils.getFileNames(targetSrcDir, "**/*.m", null, false)); String sources = ""; String xml_sources = ""; String vs10_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"; vs10_sources+=" \n"; //VS adds trailing space and eases compares } if( cpp_files.isEmpty() ) { values.put("AC_PROG_CHECKS", "AC_PROG_CC"); } else { values.put("AC_PROG_CHECKS", "AC_PROG_CXX"); } values.put("PROJECT_SOURCES", sources); values.put("PROJECT_XML_SOURCES", xml_sources); values.put("PROJECT_VS10_SOURCES", vs10_sources); values.put("CUSTOM_PROPS", windowsCustomProps ? "" : ""); values.put("TOOLS_VERSION", windowsToolsVersion); values.put("TARGET_PLATFORM_VERSION", windowsTargetPlatformVersion != null ? "" + windowsTargetPlatformVersion + "" : ""); values.put("PLATFORM_TOOLSET", windowsPlatformToolset != null ? "" + windowsPlatformToolset + "" : ""); 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.java000066400000000000000000000210171374401771200360510ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009-2011 FuseSource Corp. * 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.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; 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. * * @author Hiram Chirino */ @Mojo(name = "package-jar", defaultPhase = LifecyclePhase.PREPARE_PACKAGE) public class PackageJarMojo extends AbstractMojo { /** * The maven project. */ @Parameter(defaultValue = "${project}", readonly = true) protected MavenProject project; /** * The base name of the library, used to determine generated file names. */ @Parameter(defaultValue = "${project.artifactId}") private String name; /** */ @Component private ArchiverManager archiverManager; /** */ @Component 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(defaultValue = "${project.build.directory}/generated-sources/hawtjni/lib") private File libDirectory; /** * The platform identifier of this build. If not specified, * it will be automatically detected. * * @parameter */ @Parameter private String platform; /** * Should a classifier of the native jar be set * to match the platform? */ @Parameter(defaultValue = "true") private boolean classified; /** * 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 = Library.getPlatform(); } String classifier = null; if( classified ) { classifier = platform; 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", classifier, packageFile); } else { projectHelper.addResource(project, libDirectory.getCanonicalPath(), null, null); } } catch (Exception e) { throw new MojoExecutionException("packaging failed: " + e, e); } } public String getNativeCodeValue(Library library) { if (osgiPlatforms == null || osgiPlatforms.isEmpty() ) { return library.getPlatformSpecificResourcePath(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.getPlatformSpecificResourcePath(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.java000066400000000000000000000077321374401771200366050ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/java/org/fusesource/hawtjni/maven/** * Copyright (C) 2009-2011 FuseSource Corp. * 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.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; 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. * * @author Hiram Chirino */ @Mojo(name = "package-source", defaultPhase = LifecyclePhase.PACKAGE) public class PackageSourceMojo extends AbstractMojo { /** * The maven project. */ @Parameter(defaultValue = "${project}", readonly = true) protected MavenProject project; /** */ @Component private ArchiverManager archiverManager; /** */ @Component private MavenProjectHelper projectHelper; /** * The directory where the generated native files are located.. */ @Parameter(defaultValue = "${project.build.directory}/generated-sources/hawtjni/native-package") private File packageDirectory; /** * The classifier of the package archive that will be created. */ @Parameter(defaultValue = "native-src") private String sourceClassifier; /** * Should we skip executing the autogen.sh file. */ @Parameter(defaultValue = "${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 warning 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-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/000077500000000000000000000000001374401771200260145ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/000077500000000000000000000000001374401771200312735ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/Makefile.am000066400000000000000000000022331374401771200333270ustar00rootroot00000000000000# --------------------------------------------------------------------------- # 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 AM_CXXFLAGS = -std=gnu++11 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-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/autogen.sh000077500000000000000000000030061374401771200332730ustar00rootroot00000000000000#!/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-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/configure.ac000066400000000000000000000043531374401771200335660ustar00rootroot00000000000000# --------------------------------------------------------------------------- # 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_CHECKS@ AC_PROG_INSTALL # Make AM_PROG_AR work before automake 1.12 m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL([disable-static]) ## ----------------------------------------------- ## API Checks ## ----------------------------------------------- WITH_JNI_JDK CUSTOM_M4_SETUP WITH_OSX_UNIVERSAL CFLAGS="$CFLAGS $JNI_EXTRA_CFLAGS" AC_SUBST(CFLAGS) CXXFLAGS="$CXXFLAGS $JNI_EXTRA_CFLAGS" AC_SUBST(CXXFLAGS) LDFLAGS="$LDFLAGS $JNI_EXTRA_LDFLAGS -release @VERSION@" AC_SUBST(LDFLAGS) ## ----------------------------------------------------- ## Generate the files ## ----------------------------------------------------- AM_INIT_AUTOMAKE([subdir-objects 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-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/m4/000077500000000000000000000000001374401771200316135ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/m4/custom.m4000066400000000000000000000022221374401771200333650ustar00rootroot00000000000000dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009-2011 FuseSource Corp. 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. # AC_CHECK_HEADER([pthread.h],[AC_DEFINE([HAVE_PTHREAD_H], [1], [Define to 1 if you have the header file.])]) ])hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/m4/jni.m4000066400000000000000000000132721374401771200326420ustar00rootroot00000000000000dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009-2011 FuseSource Corp. 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";; freebsd*) __JNI_GUESS=$(env JAVAVM_DRYRUN=yes /usr/local/bin/java | grep '^JAVA_HOME' | cut -c11-);; *) __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) __JNI_INCLUDE="$__JNI_JDK_HOME/include" # OSX had to be a little different. case "$host_os" in darwin*) AS_IF(test -r "$__JNI_JDK_HOME/Headers/jni.h",[ __JNI_INCLUDE="$__JNI_JDK_HOME/Headers"; ]) 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 darwin*) __JNI_INCLUDE_EXTRAS="darwin";; freebsd*) __JNI_INCLUDE_EXTRAS="freebsd";; linux*) __JNI_INCLUDE_EXTRAS="linux genunix";; openbsd*) __JNI_INCLUDE_EXTRAS="openbsd";; 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.m4000066400000000000000000000076341374401771200346270ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/m4dnl --------------------------------------------------------------------------- dnl Copyright (C) 2009-2011 FuseSource Corp. 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 -isysroot option to the location of the MacOSX${OSX_VERSION}.sdk. dnl if OSX_VERSION is not defined, it will set it to the latest version dnl of the SDK installed on your system. 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(CXXFLAGS) dnl AC_SUBST(LDFLAGS) dnl AC_SUBST(OSX_VERSION) dnl dnl AUTHOR: Hiram Chrino dnl --------------------------------------------------------------------------- AC_DEFUN([WITH_OSX_UNIVERSAL], [ AC_PREREQ([2.61]) case "$host_os" in darwin*) AC_MSG_CHECKING(OS X SDK version) AC_ARG_WITH([osxsdk], [AS_HELP_STRING([--with-osxsdk@<:@=VERSION@:>@], [OS X SDK version to build against. Example: --with-osxsdk=10.6])], [ OSX_UNIVERSAL="$withval" ],[ OSX_SDKS_DIR="" OSX_VERSION="" for v in 10.0 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 10.10 10.11 10.12 10.13 10.14 10.15; do for location in "/Developer/SDKs" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" ; do if test -z "${OSX_VERSION}" && test -d "${location}/MacOSX${v}.sdk" ; then OSX_SDKS_DIR="${location}" OSX_VERSION="${v}" fi done done ]) AC_MSG_RESULT([$OSX_VERSION]) AC_SUBST(OSX_SDKS_DIR) 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"@:>@])], [ AS_IF(test "$withval" = "no", [ OSX_UNIVERSAL="" AC_MSG_RESULT([no]) ], test "$withval" = "yes", [ OSX_UNIVERSAL="i386 x86_64" 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" CXXFLAGS="-arch $i $CXXFLAGS" LDFLAGS="-arch $i $LDFLAGS" done for f in $__JNI_INCLUDE_EXTRAS ; do if test -d "$__JNI_INCLUDE/$f"; then __JNI_CFLAGS="$__JNI_CFLAGS -I$__JNI_INCLUDE/$f" fi done CFLAGS="-isysroot ${OSX_SDKS_DIR}/MacOSX${OSX_VERSION}.sdk $CFLAGS" CXXFLAGS="-isysroot ${OSX_SDKS_DIR}/MacOSX${OSX_VERSION}.sdk $CXXFLAGS" LDFLAGS="-syslibroot,${OSX_SDKS_DIR}/MacOSX${OSX_VERSION}.sdk $LDFLAGS" AC_SUBST(CFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(LDFLAGS) ]) ;; esac ]) hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/readme.md000066400000000000000000000030111374401771200330450ustar00rootroot00000000000000Building 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. ### OS X Lion requirements Install brew. It will depends on XCode being installed along with the command line tools. Then use brew to install autoconf, automake, and libtool. brew install autoconf automake libtool 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 installed command window and change to the directory that this file is located in and then run: For recent SDK Versions: msbuild vs2010.vcxproj (or ) For legacy SDK Versions: vcbuild vs2008.vcproj The dll files will be located under the target directory. [1]: https://developer.microsoft.com/en-us/windows/downloadshawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/vs2008.vcproj000077500000000000000000000164161374401771200334750ustar00rootroot00000000000000 @PROJECT_XML_SOURCES@ vs2010.custom.props000066400000000000000000000012531374401771200345460ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template hawtjni-hawtjni-project-1.18/hawtjni-maven-plugin/src/main/resources/project-template/vs2010.vcxproj000077500000000000000000000242171374401771200336540ustar00rootroot00000000000000 debug Win32 debug x64 release Win32 release x64 @PROJECT_NAME@ @PROJECT_NAME@ @TARGET_PLATFORM_VERSION@ DynamicLibrary Unicode @PLATFORM_TOOLSET@ DynamicLibrary Unicode @PLATFORM_TOOLSET@ true DynamicLibrary @PLATFORM_TOOLSET@ Unicode DynamicLibrary Unicode @PLATFORM_TOOLSET@ true <_ProjectFileVersion>10.0.30319.1 $(ProjectDir)/target/$(Platform)-$(Configuration)/lib\ $(ProjectDir)/target/$(Platform)-$(Configuration)/obj\ false $(ProjectDir)/target/$(Platform)-$(Configuration)/lib\ $(ProjectDir)/target/$(Platform)-$(Configuration)/obj\ false $(ProjectDir)/target/$(Platform)-$(Configuration)/lib\ $(ProjectDir)/target/$(Platform)-$(Configuration)/obj\ true $(ProjectDir)/target/$(Platform)-$(Configuration)/lib\ $(ProjectDir)/target/$(Platform)-$(Configuration)/obj\ true @CUSTOM_PROPS@ $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) MaxSpeed true Speed WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL true false Level3 ProgramDatabase StdCall true Windows true true MachineX86 $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) MaxSpeed true Speed WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL true false Level3 ProgramDatabase StdCall true Windows true true MachineX64 $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) Disabled Speed WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL false Level3 EditAndContinue StdCall true Windows MachineX86 $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) Disabled Speed WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL false Level3 EditAndContinue StdCall true Windows MachineX64 @PROJECT_VS10_SOURCES@ hawtjni-hawtjni-project-1.18/hawtjni-runtime/000077500000000000000000000000001374401771200213505ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/pom.xml000066400000000000000000000042731374401771200226730ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-project 1.18 hawtjni-runtime HawtJNI Runtime The API that projects using HawtJNI should build against. org.apache.maven.plugins maven-jar-plugin org.fusesource.hawtjni.runtime org.apache.maven.plugins maven-javadoc-plugin attach-javadocs jar hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/000077500000000000000000000000001374401771200221375ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/000077500000000000000000000000001374401771200230635ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/000077500000000000000000000000001374401771200240045ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/000077500000000000000000000000001374401771200245735ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/000077500000000000000000000000001374401771200267565ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/000077500000000000000000000000001374401771200304225ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/000077500000000000000000000000001374401771200321055ustar00rootroot00000000000000ArgFlag.java000066400000000000000000000052341374401771200342000ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 Get<PrimitiveType>ArrayElements() 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.java000077500000000000000000000224011374401771200343670ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/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, long /* int */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.java000066400000000000000000000025601374401771200345330ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.java000066400000000000000000000032011374401771200345020ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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, /** * Indicate that the field is a shared pointer. */ SHARED_PTR, /** * Indicate that the getter method used is not part of * the structure. Useful for using wrappers to access * certain structure fields. * * Only useful when the getter is declared explicitly. */ GETTER_NONMEMBER, /** * Indicate that the setter method used is not part of * the structure. Useful for using wrappers to access * certain structure fields. * * Only useful when the setter is declared explicitly. */ SETTER_NONMEMBER, } JNIEnv.java000066400000000000000000000007151374401771200337650ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/** * Copyright (C) 2010, FuseSource Corp. All rights reserved. */ package org.fusesource.hawtjni.runtime; /** *

* This is a marker class. Methods that take this as an argument * will receive that actual native 'JNIEnv *' value. Since this * class cannot be instantiated, Java callers must pass null * for the value. *

* * @author Hiram Chirino */ public class JNIEnv { private JNIEnv() {} } JniArg.java000066400000000000000000000015731374401771200340510ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; import java.lang.annotation.Documented; @Documented @Target({PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface JniArg { ArgFlag[] flags() default {}; String cast() default ""; } JniClass.java000066400000000000000000000016401374401771200344000ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; import java.lang.annotation.Documented; @Documented @Target({TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface JniClass { ClassFlag[] flags() default {}; String conditional() default ""; String name() default ""; } JniField.java000066400000000000000000000020751374401771200343610ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; import java.lang.annotation.Documented; /** * * @author Hiram Chirino */ @Documented @Target({FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface JniField { String cast() default ""; String accessor() default ""; String getter() default ""; String setter() default ""; String conditional() default ""; FieldFlag[] flags() default {}; } JniMethod.java000066400000000000000000000022131374401771200345500ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; import java.lang.annotation.Documented; /** * * @author Hiram Chirino */ @Documented @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 {}; } Library.java000077500000000000000000000512501374401771200343030ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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.*; import java.lang.reflect.Method; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Set; /** * Used to find and load a JNI library, eventually after having extracted it. * * 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, * subdirectories are searched: *
      *
    1. "${platform}/${arch}" *
    2. "${platform}" *
    3. "${os}" *
    * for 2 namings of the library: *
      *
    1. as "${name}-${version}" library name if the version can be determined. *
    2. as "${name}" library name *
    *
  2. system library path: This is where the JVM looks for JNI libraries by default. *
      *
    1. as "${name}${bit-model}-${version}" library name if the version can be determined. *
    2. as "${name}-${version}" library name if the version can be determined. *
    3. as "${name}" library name *
    *
  3. classpath path: If the JNI library can be found on the classpath, it will get extracted * 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}/${arch}/${library[-version]}": Store your library here if you want to embed * more than one platform JNI library on different processor archs in the jar. *
    2. "META-INF/native/${platform}/${library[-version]}": Store your library here if you want to embed more * than one platform JNI library in the jar. *
    3. "META-INF/native/${os}/${library[-version]}": Store your library here if you want to embed more * than one platform JNI library in the jar but don't want to take bit model into account. *
    4. "META-INF/native/${library[-version]}": 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
  • *
  • "${arch}" is the architecture for the processor, for example "amd64" or "sparcv9"
  • *
  • "${platform}" is "${os}${bit-model}", for example "linux32" or "osx64"
  • *
  • "${library[-version]}": is the normal jni library name for the platform (eventually with -${version}) suffix. * For example "${name}.dll" on * windows, "lib${name}.jnilib" on OS X, and "lib${name}.so" on linux
  • *
* * @author Hiram Chirino * @see System#mapLibraryName(String) */ public class Library { public static final String STRATEGY_PROPERTY = "hawtjni.strategy"; public static final String STRATEGY_SHA1 = "sha1"; public static final String STRATEGY_TEMP = "temp"; static final String SLASH = System.getProperty("file.separator"); static final String STRATEGY = System.getProperty(STRATEGY_PROPERTY, "windows".equals(getOperatingSystem()) ? STRATEGY_SHA1 : STRATEGY_TEMP); final private String name; final private String version; final private ClassLoader classLoader; private boolean loaded; private String nativeLibraryPath; private URL nativeLibrarySourceUrl; 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; } /** * Get the path to the native library loaded. * @return the path (should not be null once the library is loaded) * @since 1.16 */ public String getNativeLibraryPath() { return nativeLibraryPath; } /** * Get the URL to the native library source that has been extracted (if it was extracted). * @return the url to the source (in classpath) * @since 1.16 */ public URL getNativeLibrarySourceUrl() { return nativeLibrarySourceUrl; } public static 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 static String getPlatform() { return getOperatingSystem()+getBitModel(); } public 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); } // GraalVM support, see https://github.com/fusesource/jansi/issues/162 String arch = System.getProperty("os.arch"); if (arch.endsWith("64") && "Substrate VM".equals(System.getProperty("java.vm.name"))) { return 64; } return -1; // we don't know.. } /** * Load the native library. */ 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(); String[] specificDirs = getSpecificSearchDirs(); String libFilename = map(name); String versionlibFilename = (version == null) ? null : map(name + "-" + version); /* Try loading library from a custom library path */ String customPath = System.getProperty("library."+name+".path"); if (customPath != null) { for ( String dir: specificDirs ) { if( version!=null && load(errors, file(customPath, dir, versionlibFilename)) ) return; if( load(errors, file(customPath, dir, libFilename)) ) return; } } /* Try loading library from java library path */ if( version!=null && loadLibrary(errors, name + getBitModel() + "-" + version) ) return; if( version!=null && loadLibrary(errors, name + "-" + version) ) return; if( loadLibrary(errors, name) ) return; /* Try extracting the library from the jar */ if( classLoader!=null ) { String targetLibName = version != null ? versionlibFilename : libFilename; for ( String dir: specificDirs ) { if( version!=null && extractAndLoad(errors, customPath, dir, versionlibFilename, targetLibName) ) return; if( extractAndLoad(errors, customPath, dir, libFilename, targetLibName) ) return; } } /* Failed to find the library */ UnsatisfiedLinkError e = new UnsatisfiedLinkError("Could not load library. Reasons: " + errors.toString()); try { Method method = Throwable.class.getMethod("addSuppressed", Throwable.class); for (Throwable t : errors) { method.invoke(e, t); } } catch (Throwable ignore) { } throw e; } @Deprecated final public String getArchSpecifcResourcePath() { return getArchSpecificResourcePath(); } final public String getArchSpecificResourcePath() { return "META-INF/native/"+ getPlatform() + "/" + System.getProperty("os.arch") + "/" +map(name); } @Deprecated final public String getOperatingSystemSpecifcResourcePath() { return getOperatingSystemSpecificResourcePath(); } final public String getOperatingSystemSpecificResourcePath() { return getPlatformSpecificResourcePath(getOperatingSystem()); } @Deprecated final public String getPlatformSpecifcResourcePath() { return getPlatformSpecificResourcePath(); } final public String getPlatformSpecificResourcePath() { return getPlatformSpecificResourcePath(getPlatform()); } @Deprecated final public String getPlatformSpecifcResourcePath(String platform) { return getPlatformSpecificResourcePath(platform); } final public String getPlatformSpecificResourcePath(String platform) { return "META-INF/native/"+platform+"/"+map(name); } @Deprecated final public String getResorucePath() { return getResourcePath(); } final public String getResourcePath() { return "META-INF/native/"+map(name); } final public String getLibraryFileName() { return map(name); } /** * Search directories for library:
    *
  • ${platform}/${arch} to enable platform JNI library for different processor archs
  • *
  • ${platform} to enable platform JNI library
  • *
  • ${os} to enable OS JNI library
  • *
  • no directory
  • *
* @return the list * @since 1.15 */ final public String[] getSpecificSearchDirs() { return new String[] { getPlatform() + "/" + System.getProperty("os.arch"), getPlatform(), getOperatingSystem(), "." }; } private boolean extractAndLoad(ArrayList errors, String customPath, String dir, String libName, String targetLibName) { String resourcePath = "META-INF/native/" + ( dir == null ? "" : (dir + '/')) + libName; URL resource = classLoader.getResource(resourcePath); if( resource !=null ) { int idx = targetLibName.lastIndexOf('.'); String prefix = targetLibName.substring(0, idx)+"-"; String suffix = targetLibName.substring(idx); // Use the user provided path, // then fallback to the java temp directory, // and last, use the user home folder for (File path : Arrays.asList( customPath != null ? file(customPath) : null, file(System.getProperty("java.io.tmpdir")), file(System.getProperty("user.home"), ".hawtjni", name))) { if( path!=null ) { // Try to extract it to the custom path... File target; if (STRATEGY_SHA1.equals(STRATEGY)) { target = extractSha1(errors, resource, prefix, suffix, path); } else { target = extractTemp(errors, resource, prefix, suffix, path); } if( target!=null ) { if( load(errors, target) ) { nativeLibrarySourceUrl = resource; return true; } } } } } return false; } private File file(String ...paths) { File rc = null ; for (String path : paths) { if( rc == null ) { rc = new File(path); } else if( path != null ) { 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 File extractSha1(ArrayList errors, URL source, String prefix, String suffix, File directory) { File target = null; directory = directory.getAbsoluteFile(); if (!directory.exists()) { if (!directory.mkdirs()) { errors.add(new IOException("Unable to create directory: " + directory)); return null; } } try { String sha1 = computeSha1(source.openStream()); String sha1f = ""; target = new File(directory, prefix + sha1 + suffix); if (target.isFile() && target.canRead()) { sha1f = computeSha1(new FileInputStream(target)); } if (sha1f.equals(sha1)) { return target; } FileOutputStream os = null; InputStream is = null; try { is = source.openStream(); if (is != null) { byte[] buffer = new byte[4096]; os = new FileOutputStream(target); int read; while ((read = is.read(buffer)) != -1) { os.write(buffer, 0, read); } chmod755(target); } return target; } finally { close(os); close(is); } } catch (Throwable e) { IOException io; if (target != null) { target.delete(); io = new IOException("Unable to extract library from " + source + " to " + target); } else { io = new IOException("Unable to create temporary file in " + directory); } io.initCause(e); errors.add(io); } return null; } private String computeSha1(InputStream is) throws NoSuchAlgorithmException, IOException { String sha1; try { MessageDigest mDigest = MessageDigest.getInstance("SHA1"); int read; byte[] buffer = new byte[4096]; while ((read = is.read(buffer)) != -1) { mDigest.update(buffer, 0, read); } byte[] result = mDigest.digest(); StringBuilder sb = new StringBuilder(); for (byte b : result) { sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); } sha1 = sb.toString(); } finally { close(is); } return sha1; } private File extractTemp(ArrayList errors, URL source, String prefix, String suffix, File directory) { File target = null; directory = directory.getAbsoluteFile(); if (!directory.exists()) { if (!directory.mkdirs()) { errors.add(new IOException("Unable to create directory: " + directory)); return null; } } try { FileOutputStream os = null; InputStream is = null; try { target = File.createTempFile(prefix, suffix, directory); is = source.openStream(); if (is != null) { byte[] buffer = new byte[4096]; os = new FileOutputStream(target); int read; while ((read = is.read(buffer)) != -1) { os.write(buffer, 0, read); } chmod755(target); } target.deleteOnExit(); return target; } finally { close(os); close(is); } } catch (Throwable e) { IOException io; if (target != null) { target.delete(); io = new IOException("Unable to extract library from " + source + " to " + target); } else { io = new IOException("Unable to create temporary file in " + directory); } io.initCause(e); errors.add(io); } return null; } static private void close(Closeable file) { if (file != null) { try { file.close(); } catch (Exception ignore) { } } } private void chmod755(File file) { if (getPlatform().startsWith("windows")) return; // Use Files.setPosixFilePermissions if we are running Java 7+ to avoid forking the JVM for executing chmod try { ClassLoader classLoader = getClass().getClassLoader(); // Check if the PosixFilePermissions exists in the JVM, if not this will throw a ClassNotFoundException Class posixFilePermissionsClass = classLoader.loadClass("java.nio.file.attribute.PosixFilePermissions"); // Set permissionSet = PosixFilePermissions.fromString("rwxr-xr-x") Method fromStringMethod = posixFilePermissionsClass.getMethod("fromString", String.class); Object permissionSet = fromStringMethod.invoke(null, "rwxr-xr-x"); // Path path = file.toPath() Object path = file.getClass().getMethod("toPath").invoke(file); // Files.setPosixFilePermissions(path, permissionSet) Class pathClass = classLoader.loadClass("java.nio.file.Path"); Class filesClass = classLoader.loadClass("java.nio.file.Files"); Method setPosixFilePermissionsMethod = filesClass.getMethod("setPosixFilePermissions", pathClass, Set.class); setPosixFilePermissionsMethod.invoke(null, path, permissionSet); } catch (Throwable ignored) { // Fallback to starting a new process try { Runtime.getRuntime().exec(new String[]{"chmod", "755", file.getCanonicalPath()}).waitFor(); } catch (Throwable e) { } } } private boolean load(ArrayList errors, File lib) { try { System.load(lib.getPath()); nativeLibraryPath = lib.getPath(); return true; } catch (UnsatisfiedLinkError e) { LinkageError le = new LinkageError("Unable to load library from " + lib); le.initCause(e); errors.add(le); } return false; } private boolean loadLibrary(ArrayList errors, String lib) { try { System.loadLibrary(lib); nativeLibraryPath = "java.library.path,sun.boot.library.pathlib:" + lib; return true; } catch (UnsatisfiedLinkError e) { LinkageError le = new LinkageError("Unable to load library " + lib); le.initCause(e); errors.add(le); } return false; } } MethodFlag.java000066400000000000000000000063311374401771200347060ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 native method is calling a C++ object's method. */ CPP_METHOD, /** * 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.java000077500000000000000000000166111374401771200351460ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * 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 Print stream. */ 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; } } PointerMath.java000066400000000000000000000015141374401771200351240ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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 class PointerMath { private static final boolean bits32 = Library.getBitModel() == 32; final public static long add(long ptr, long n) { if(bits32) { return (int)(ptr + n); } else { return ptr + n; } } } hawtjni-hawtjni-project-1.18/hawtjni-runtime/src/main/java/org/fusesource/hawtjni/runtime/T32.java000066400000000000000000000015041374401771200333200ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) 2009-2011 FuseSource Corp. * * 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.*; import java.lang.annotation.Documented; @Documented @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE}) @Retention(RetentionPolicy.RUNTIME) public @interface T32 { } hawtjni-hawtjni-project-1.18/hawtjni-website/000077500000000000000000000000001374401771200213275ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/ext/000077500000000000000000000000001374401771200221275ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/ext/ScalatePackage.scala000066400000000000000000000021631374401771200257660ustar00rootroot00000000000000/** * Copyright (C) 2009-2011 the original author or authors. * See the notice.md file distributed with this work for additional * information regarding copyright ownership. * * 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. */ import org.fusesource.scalate.support.TemplatePackage import org.fusesource.scalate.{Binding, TemplateSource} /** * Defines the template package of reusable imports, attributes and methods across templates */ class ScalatePackage extends TemplatePackage { def header(source: TemplateSource, bindings: List[Binding]) = """ // common imports go here import _root_.Website._; """ } hawtjni-hawtjni-project-1.18/hawtjni-website/ext/Website.scala000066400000000000000000000041611374401771200245400ustar00rootroot00000000000000/** * Copyright (C) 2009-2011 the original author or authors. * See the notice.md file distributed with this work for additional * information regarding copyright ownership. * * 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. */ import org.fusesource.scalate.RenderContext package /** *

*

* * @author Hiram Chirino */ object Website { val project_name= "HawtJNI" val project_slogan= "Making JNI easy and fast." val project_id= "hawtjni" val project_issue_url= "https://github.com/fusesource/hawtjni/issues" val project_forums_url= "http://groups.google.com/group/hawtjni" val project_wiki_url= "https://github.com/fusesource/hawtjni/wiki" val project_logo= "/images/project-logo.png" val project_version= "1.17" val project_snapshot_version= "1.18-SNAPSHOT" val project_versions = List( project_version, "1.16", "1.15", "1.14", "1.13", "1.12", "1.11", "1.10", "1.9", "1.8", "1.7", "1.6", "1.5", "1.4", "1.3", "1.2", "1.1", "1.0" ) val project_keywords= "jni,java,jna,c,objective-c,c++,c#" // ------------------------------------------------------------------- val github_page= "http://github.com/fusesource/hawtjni" val git_user_url= "git://github.com/fusesource/hawtjni.git" val git_commiter_url= "git@github.com:fusesources/hawtjni.git" val project_maven_groupId= "org.fusesource.hawtjni" val project_maven_artifactId= "hawtjni-runtime" val website_base_url= "http://fusesource.github.io/hawtjni/" } hawtjni-hawtjni-project-1.18/hawtjni-website/ext/scalate/000077500000000000000000000000001374401771200235435ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/ext/scalate/Boot.scala000066400000000000000000000053751374401771200254650ustar00rootroot00000000000000/** * Copyright (C) 2009-2011 the original author or authors. * See the notice.md file distributed with this work for additional * information regarding copyright ownership. * * 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 scalate import org.fusesource.scalate.util.Logging import java.util.concurrent.atomic.AtomicBoolean import _root_.Website._ import org.fusesource.scalate._ import org.fusesource.scalamd.{MacroDefinition, Markdown} import java.util.regex.Matcher import org.fusesource.scalate.wikitext.Pygmentize class Boot(engine: TemplateEngine) extends Logging { private var _initialised = new AtomicBoolean(false) def run: Unit = { if (_initialised.compareAndSet(false, true)) { def filter(m:Matcher):String = { val filter_name = m.group(1) val body = m.group(2) engine.filter(filter_name) match { case Some(filter)=> filter.filter(RenderContext(), body) case None=> "

filter not found: %s

%s
".format(filter_name, body) } } def pygmentize(m:Matcher):String = Pygmentize.pygmentize(m.group(2), m.group(1)) // add some macros to markdown. Markdown.macros :::= List( MacroDefinition("""\{filter::(.*?)\}(.*?)\{filter\}""", "s", filter, true), MacroDefinition("""\{pygmentize::(.*?)\}(.*?)\{pygmentize\}""", "s", pygmentize, true), MacroDefinition("""\{pygmentize\_and\_compare::(.*?)\}(.*?)\{pygmentize\_and\_compare\}""", "s", pygmentize, true), MacroDefinition("""\$\{project_version\}""", "", _ => project_version.toString, true), MacroDefinition("""\$\{project_name\}""", "", _ => project_name.toString, true), MacroDefinition("""\$\{project_id\}""", "", _ => project_id.toString, true), MacroDefinition("""\$\{project_issue_url\}""", "", _ => project_issue_url.toString, true), MacroDefinition("""\$\{website_base_url\}""", "", _ => website_base_url.toString, true) ) for( ssp <- engine.filter("ssp"); md <- engine.filter("markdown") ) { engine.pipelines += "ssp.md"-> List(ssp, md) engine.pipelines += "ssp.markdown"-> List(ssp, md) } info("Bootstrapped website gen for: %s".format(project_name)) } } }hawtjni-hawtjni-project-1.18/hawtjni-website/pom.xml000066400000000000000000000177041374401771200226550ustar00rootroot00000000000000 4.0.0 org.fusesource.hawtjni hawtjni-project 1.17 hawtjni-website ${project.artifactId} The HawtJNI Website pom Tomcat60 hawtjni-gh-pages scm:git:https://github.com/fusesource/hawtjni.git org.scala-lang scala-library ${scala-version} org.scala-lang scala-compiler ${scala-version} org.fusesource.scalate scalate-wikitext ${scalate-version} org.fusesource.scalate scalate-page ${scalate-version} org.fusesource.scalamd scalamd ${scalamd-version} org.slf4j slf4j-log4j12 ${slf4j-version} org.fusesource.scalate scalate-test ${scalate-version} test org.fusesource.hawtjni hawtjni-runtime ${project.version} javadoc test ext true maven-source-plugin attach-sources jar org.scala-tools maven-scala-plugin ${scala-plugin-version} compile -Xmx1024m ${scala-version} maven-surefire-plugin once false false **/*Test.* org.fusesource.scalate maven-scalate-plugin ${scalate-version} ${basedir}/src sitegen sitegen package org.apache.maven.plugins maven-scm-publish-plugin 1.1 gh-pages ${project.build.directory}/sitegen gh-pages publish-scm install org.mortbay.jetty jetty-maven-plugin ${jetty-plugin-version} ${basedir}/src scalate.editor ${env.SCALATE_EDITOR} scalate.workdir ${basedir}/target/_scalate scalate.mode development 0 org.apache.maven.plugins maven-dependency-plugin 2.2 unpack package unpack org.fusesource.hawtjni hawtjni-runtime javadoc ${basedir}/target/sitegen/documentation/api org.fusesource.mvnplugins maven-linkchecker-plugin ${mvnplugins-version} http://github.com/ http://git.or.cz/ http://localhost:8080/ http://repo.fusesource.com/ http://search.twitter.com/ http://www.chengin.com/ hawtjni-hawtjni-project-1.18/hawtjni-website/src/000077500000000000000000000000001374401771200221165ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/src/WEB-INF/000077500000000000000000000000001374401771200231455ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/src/WEB-INF/scalate/000077500000000000000000000000001374401771200245615ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/src/WEB-INF/scalate/layouts/000077500000000000000000000000001374401771200262615ustar00rootroot00000000000000hawtjni-hawtjni-project-1.18/hawtjni-website/src/WEB-INF/scalate/layouts/default.jade000066400000000000000000000057571374401771200305500ustar00rootroot00000000000000!!! Basic :plain - response.setContentType("text/html") -@ var title : String = "" -@ var body: String = null -@ var overview: String = null -@ var spot: String = null -@ var blog: String = null -@ var head: String = null - val include_console = engine.isDevelopmentMode && engine.resourceLoader.exists("/org/fusesource/scalate/console/console_head.scaml") html(lang="en") head meta(content="text/html; charset=utf-8" http-equiv="Content-Type") meta(content="#{project_slogan}" name="description") meta(content="#{project_keywords}" name="keywords") meta(content="#{project_name}" name="author") link(type="text/css" rel="stylesheet" href={uri("/styles/impact/css/pygmentize.css")}) link(type="text/css" rel="stylesheet" href={uri("/styles/impact/css/site.css")}) - if (head!=null) !~~ head -# - if (include_console) - include("/org/fusesource/scalate/console/console_head.scaml") link(href={uri("/css/scalate/console.css")} rel="stylesheet" type="text/css") title= title body div#navigation div.wrapper - include("/_navigation.ssp.md") - if (overview!=null) div#overview div.wrapper -if ( project_logo!=null ) div.logo img(src="#{uri(project_logo)}" alt="#{project_name} logo") div.message !~~ overview - if (spot!=null) div#spot div.wrapper !~~ spot - if (body!=null) div#content div.wrapper !~~ body - if (blog!=null) div#blog div.wrapper !~~ blog -# - if (include_console) = include("/org/fusesource/scalate/console/console.scaml") -# :javascript var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));