B-1_14-DEV merge back to main

This commit is contained in:
clay_shooter
2008-02-02 01:38:25 +00:00
parent cd58b57a99
commit df0ba33797
97 changed files with 12208 additions and 8816 deletions

View File

@@ -4,6 +4,7 @@ jacobdll.jar
*.zip
RELEASE.txt
.project
.cproject
.classpath
compilation_tools.properties
version.properties
@@ -13,3 +14,4 @@ release
foo.foo
foo.ser
JacobVersion.properties

194
build.xml
View File

@@ -16,15 +16,15 @@
The file for MS Visual C++ 8.0 building 32 and 64 bit
(releases up to 1.11 only supported 32 builds) looks something like:
JDK=d:\\j2sdk1.4.2_14
JDK=d:\\jdk1.5.0_11
MSDEV_DIR=d:\\apps\\Microsoft Visual Studio 8\\VC
MSDEV_IDE_DIR=d:\\apps\\Microsoft Visual Studio 8\\Common7\\IDE
version=1.13
version=1.14-M1
DO NOT check compilation_tools.properties into source control as the
values are specific to YOUR environment.
The version.properties file is now completely autogenerated
The JacobVersion.properties file is now completely autogenerated
====================================================================== -->
<project name="jacob" default="default" basedir=".">
@@ -47,17 +47,19 @@
Now build up all the derived properties
================================================================== -->
<property name="application.title" value="JACOB : Java COM Bridge" />
<property name="application.vendor" value="http://jacob-project.sourceforge.net" />
<property name="src.java.jacob.mainpackage" value="com.jacob" />
<property name="java.class.main" value="com.jacob.com.Jacob" />
<property name="generated.filename.dll" value="jacob.dll" />
<property name="generated.filename.jar" value="jacob.jar" />
<property name="generated.filename.zip" value="jacob_${version}" />
<property name="application.title" value="JACOB : Java COM Bridge" />
<property name="application.vendor" value="http://jacob-project.sourceforge.net" />
<property name="src.java.mainpackage" value="com.jacob" />
<property name="java.class.main" value="com.jacob.com.Jacob" />
<property name="generated.filename.dll.x86" value="jacob-${version}-x86.dll" />
<property name="generated.filename.dll.x64" value="jacob-${version}-x64.dll" />
<property name="generated.filename.jar" value="jacob.jar" />
<property name="generated.filename.zip" value="jacob-${version}" />
<property name="generated.filename.version" value="JacobVersion.properties" />
<property name="junit.jar" value="${basedir}\lib\junit3.8.1\junit.jar" />
<property name="src.java.jacob" value="${basedir}/src" />
<property name="src.java.mainroot" value="${basedir}/src" />
<property name="src.java.samples" value="${basedir}/samples" />
<property name="src.java.unittest" value="${basedir}/unittest" />
<property name="src.cpp" value="${basedir}/jni" />
@@ -66,13 +68,14 @@
<property name="release.dir.x86" value="${release.dir}\x86" />
<property name="release.dir.x86.cpp" value="${release.dir.x86}\jni" />
<property name="release.file.x86.dll" value="${release.dir.x86}\${generated.filename.dll}" />
<property name="release.file.x86.dll" value="${release.dir.x86}\${generated.filename.dll.x86}" />
<property name="release.dir.AMD64" value="${release.dir}\AMD64" />
<property name="release.dir.AMD64.cpp" value="${release.dir.AMD64}\jni" />
<property name="release.file.AMD64.dll" value="${release.dir.AMD64}\${generated.filename.dll}" />
<property name="release.dir.x64" value="${release.dir}\x64" />
<property name="release.dir.x64.cpp" value="${release.dir.x64}\jni" />
<property name="release.file.x64.dll" value="${release.dir.x64}\${generated.filename.dll.x64}" />
<property name="release.dir.java" value="${release.dir}\java" />
<property name="release.dir.java.meta.inf" value="${release.dir.java}\META-INF" />
<property name="release.file.jar" value="${release.dir.java}\${generated.filename.jar}" />
<property name="compiler.x86" value="${MSDEV_DIR}\bin\cl.exe" />
@@ -87,13 +90,13 @@
<!-- You have to love the beautiful asymetry of the MS world -->
<!-- The platform SDK comes with 64 bit tools but not 32 bit tools -->
<property name="compiler.AMD64" value="${MSDEV_DIR}\bin\x86_amd64\cl.exe" />
<property name="linker.AMD64" value="${MSDEV_DIR}\bin\x86_amd64\link.exe" />
<property name="manifesttool.AMD64" value="${MSDEV_DIR}\bin\x86_amd64\mt.exe" />
<property name="include.AMD64" value="${MSDEV_DIR}\include" />
<property name="library.AMD64" value="${MSDEV_DIR}\lib\AMD64" />
<property name="library.AMD64.platformSDK" value="${MSDEV_DIR}\PlatformSDK\lib\AMD64" />
<property name="library.AMD64.atl" value="${MSDEV_DIR}\atlmfc\lib\AMD64" />
<property name="compiler.x64" value="${MSDEV_DIR}\bin\x86_amd64\cl.exe" />
<property name="linker.x64" value="${MSDEV_DIR}\bin\x86_amd64\link.exe" />
<property name="manifesttool.x64" value="${MSDEV_DIR}\bin\x86_amd64\mt.exe" />
<property name="include.x64" value="${MSDEV_DIR}\include" />
<property name="library.x64" value="${MSDEV_DIR}\lib\amd64" />
<property name="library.x64.platformSDK" value="${MSDEV_DIR}\PlatformSDK\lib\amd64" />
<property name="library.x64.atl" value="${MSDEV_DIR}\atlmfc\lib\amd64" />
<!-- ======================================================================
@@ -101,73 +104,75 @@
already there)
================================================================== -->
<mkdir dir="${release.dir.java}"/>
<mkdir dir="${release.dir.java.meta.inf}"/>
<mkdir dir="${release.dir.x86.cpp}"/>
<mkdir dir="${release.dir.AMD64.cpp}"/>
<mkdir dir="${release.dir.x64.cpp}"/>
<mkdir dir="${release.dir}"/>
<!-- ======================================================================
Writes out a version file to be included in the jar
================================================================== -->
<property name="version" value="version not set in compilation_tools properties file"/>
<propertyfile file="version.properties">
<propertyfile file="${generated.filename.version}">
<entry key="version" type="string" value="${version}" />
<entry key="build.iteration" type="int" operation="+" value="1" pattern="00" />
<entry key="build.date" type="date" value="now" operation="=" pattern="dd-MMMM-yyyy HH:mm:ss" />
</propertyfile>
<property file="version.properties" />
<property file="${generated.filename.version}" />
<!-- ======================================================================
32 bit x86 can only be built on 32 bit because of a JDK library issue.
arch=x86 true if on 32 bit, unset in all other cases.
32 bit X86 can only be built on 32 bit because of a JDK library issue.
arch=X86 true if on 32 bit, unset in all other cases.
This module used to rely on that. Now it just checks to see if we have
the right compilers.
================================================================== -->
<available file="${compiler.x86}" property="canBuildX86"/>
<echo message="canBuildX86=${canBuildX86}" />
<available file="${compiler.AMD64}" property="canBuildAMD64"/>
<echo message="canBuildAMD64=${canBuildAMD64}" />
<available file="${compiler.x86}" property="canBuild.x86"/>
<echo message="canBuild.x86=${canBuild.x86}" />
<available file="${compiler.x64}" property="canBuild.x64"/>
<echo message="canBuild.x64=${canBuild.x64}" />
<!-- ======================================================================
Compare the date/time of the DLL against that of the cpp source.
Up to date is only true if dll exists and is later than source
================================================================== -->
<uptodate property="dllUpToDateX86" targetfile="${release.file.x86.dll}">
<uptodate property="dllUpToDate.x86" targetfile="${release.file.x86.dll}">
<srcfiles dir="${src.cpp}" includes="*.cpp" />
<srcfiles dir="${src.cpp}" includes="*.h" />
<!-- Check the build file itself as well -->
<srcfiles dir="${basedir}" includes="build.xml" />
</uptodate>
<echo message="dllUpToDateX86= ${dllUpToDateX86} (${release.file.x86.dll})" />
<uptodate property="dllUpToDateAMD64" targetfile="${release.file.AMD64.dll}">
<echo message="dllUpToDate.x86= ${dllUpToDate.x86} (${release.file.x86.dll})" />
<uptodate property="dllUpToDate.x64" targetfile="${release.file.x64.dll}">
<srcfiles dir="${src.cpp}" includes="*.cpp" />
<srcfiles dir="${src.cpp}" includes="*.h" />
<!-- Check the build file itself as well -->
<srcfiles dir="${basedir}" includes="build.xml" />
</uptodate>
<echo message="dllUpToDateAMD64= ${dllUpToDateAMD64} (${release.file.AMD64.dll})" />
<echo message="dllUpToDate.x64= ${dllUpToDate.x64} (${release.file.x64.dll})" />
<!-- ======================================================================
We should build if we can build and the dll is not up to date
================================================================== -->
<condition property="shouldBuildX86">
<condition property="shouldBuild.x86">
<and>
<isset property="canBuildX86"/>
<isset property="canBuild.x86"/>
<not>
<isset property="dllUpToDateX86"/>
<isset property="dllUpToDate.x86"/>
</not>
</and>
</condition>
<echo message="shouldBuildX86= ${shouldBuildX86}" />
<echo message="shouldBuild.x86= ${shouldBuild.x86}" />
<condition property="shouldBuildAMD64">
<condition property="shouldBuild.x64">
<and>
<isset property="canBuildAMD64"/>
<isset property="canBuild.x64"/>
<not>
<isset property="dllUpToDateAMD64"/>
<isset property="dllUpToDate.x64"/>
</not>
</and>
</condition>
<echo message="shouldBuildAMD64= ${shouldBuildAMD64}" />
<echo message="shouldBuild.x64= ${shouldBuild.x64}" />
<!--=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v=v
@@ -178,7 +183,7 @@
target: default
================================= -->
<target name="default"
depends="javaJarBin,makeDllX86,makeDllAMD64">
depends="javaJarBin,makeDll.x86,makeDll.x64">
<echo message="${application.title} ${version} build ${build.iteration} : finished on ${build.date}" />
</target>
@@ -189,7 +194,7 @@
<delete>
<fileset dir="${release.dir.java}"/>
<fileset dir="${release.dir.x86.cpp}"/>
<fileset dir="${release.dir.AMD64.cpp}"/>
<fileset dir="${release.dir.x64.cpp}"/>
<fileset dir="${release.dir}"/>
</delete>
</target>
@@ -199,38 +204,38 @@
================================================================== -->
<target name="javaJarCheck">
<uptodate property="jarUpToDate" targetfile="${release.file.jar}">
<srcfiles dir="${src.java.jacob}" includes="com/**/*.java" />
<srcfiles dir="${src.java.mainroot}" includes="com/**/*.java" />
<!-- Check the build file itself as well -->
<srcfiles dir="${basedir}" includes="build.xml" />
</uptodate>
<echo message="javaJarCheck says jarUpToDate= ${jarUpToDate}" />
</target>
<!-- ======================================================================
Compile the java files and copy version.properties to be jar'd up
Compile the java files and copy JacobVersion.properties to be jar'd up
Relies on ant recognizing when a file needs to be compiled
Unit tests compiled seperately because of junit dependency
================================================================== -->
<target name="javaCompile" >
<echo>Building Jacob classes in ${release.dir.java}</echo>
<javac srcdir="${src.java.jacob}"
<javac srcdir="${src.java.mainroot}"
destdir="${release.dir.java}"
listfiles="true" debug="on" source="1.4" />
listfiles="true" debug="on" source="1.5" />
<echo>Building sample classes in ${release.dir.java}</echo>
<javac srcdir="${src.java.samples}"
destdir="${release.dir.java}"
classpath="${release.dir.java}"
listfiles="true" debug="on" source="1.4" />
listfiles="true" debug="on" source="1.5" />
<echo>Building Jacob test classes in ${release.dir.java} using junit jar ${junit.jar}</echo>
<javac srcdir="${src.java.unittest}"
destdir="${release.dir.java}"
classpath="${release.dir.java}:${junit.jar}"
listfiles="true" debug="on" source="1.4" />
<copy file="version.properties" todir="${release.dir.java}"/>
listfiles="true" debug="on" source="1.5" />
<copy file="${generated.filename.version}" todir="${release.dir.java.meta.inf}"/>
</target>
<!-- ======================================================================
Package the classes into a JAR.
Put version.propertes into the jar file so version retrieval method can find it
Put JacobVersion.properties into the jar file so version retrieval method can find it
================================================================== -->
<target name="javaJarBin"
depends="javaCompile,javaJarCheck"
@@ -238,6 +243,7 @@
<echo>Removing old jars</echo>
<delete file="${release.file.jar}" />
<echo>Packaging java classes...</echo>
<echo>Version File is ${release.dir.java.meta.inf}/${generated.filename.version}</echo>
<jar destfile="${release.file.jar}" basedir="${release.dir.java}" update="false">
<exclude name="**/CVS" />
<!-- exclude all unit tests (ending in Test)
@@ -246,11 +252,11 @@
<exclude name="com/jacob/samples/**"/>
<exclude name="com/jacob/test/**"/>
<include name="com/**/*.class" />
<include name="version.properties" />
<include name="META-INF/${generated.filename.version}" />
<manifest>
<attribute name="Built-By" value="${user.name}" />
<attribute name="Main-Class" value="${java.class.main}"/>
<section name="${src.java.jacob.mainpackage}">
<section name="${src.java.mainpackage}">
<attribute name="Specification-Title" value="${application.title}" />
<attribute name="Specification-Vendor" value="${application.vendor}" />
<attribute name="Implementation-Title" value="${application.title} Java libraries" />
@@ -262,10 +268,10 @@
<!-- ======================================================================
Compile the c source files.
================================================================== -->
<target name="compileX86" if="shouldBuildX86">
<echo>Clean up the (x86) target folders and file, for safety</echo>
<target name="compile.x86" if="shouldBuild.x86">
<echo>Clean up the (X86) target folders and file, for safety</echo>
<delete file="${release.dir.x86.cpp}/**/*.*" />
<echo>Compiling (x86) C++ classes with JDK JNI library ${JDK}</echo>
<echo>Compiling (X86) C++ classes with JDK JNI library ${JDK}</echo>
<exec executable="${compiler.x86}" dir="${release.dir.x86.cpp}" failonerror="true">
<env key="Path" value="${MSDEV_IDE_DIR}"/>
<env key="include" value="${JDK}\include;${JDK}\include\win32;${include.x86.platformSDK};${include.x86};${include.x86.atl}"/>
@@ -294,11 +300,11 @@
</exec>
</target>
<target name="compileAMD64" if="shouldBuildAMD64">
<echo>Clean up the (AMD64) target folders and file, for safety</echo>
<delete file="${release.dir.AMD64.cpp}/**/*.*" />
<echo>Compiling C++ (AMD64) classes with JDK JNI library ${JDK}</echo>
<exec executable="${compiler.AMD64}" dir="${release.dir.AMD64.cpp}" failonerror="true">
<target name="compile.x64" if="shouldBuild.x64">
<echo>Clean up the (x64) target folders and file, for safety</echo>
<delete file="${release.dir.x64.cpp}/**/*.*" />
<echo>Compiling C++ (x64) classes with JDK JNI library ${JDK}</echo>
<exec executable="${compiler.x64}" dir="${release.dir.x64.cpp}" failonerror="true">
<env key="include" value="${JDK}\include;${JDK}\include\win32;${include.x86.platformSDK};${include.x86};${include.x86.atl}"/>
<env key="Path" value="${MSDEV_IDE_DIR}"/>
<arg value="/nologo"/>
@@ -334,7 +340,7 @@
32 bit target Yes No
64 bit target Yes Yes
================================================================== -->
<target name="makeDllX86" depends="compileX86" if="shouldBuildX86">
<target name="makeDll.x86" depends="compile.x86" if="shouldBuild.x86">
<echo>Clean up the target folders and file, for safety</echo>
<echo>Using ${library.x86}</echo>
<delete file="${release.file.x86.dll}" />
@@ -361,40 +367,40 @@
</exec>
</target>
<target name="makeDllAMD64" depends="compileAMD64" if="shouldBuildAMD64">
<target name="makeDll.x64" depends="compile.x64" if="shouldBuild.x64">
<echo>Clean up the target folders and file, for safety</echo>
<delete file="${release.file.AMD64.dll}" />
<echo>Creating {$release.file.AMD64.dll}</echo>
<exec executable="${linker.AMD64}" dir="${release.dir.AMD64.cpp}" failonerror="true">
<delete file="${release.file.x64.dll}" />
<echo>Creating {$release.file.x64.dll}</echo>
<exec executable="${linker.x64}" dir="${release.dir.x64.cpp}" failonerror="true">
<env key="Path" value="${MSDEV_IDE_DIR}"/>
<arg value="/nologo" />
<arg value="/MANIFEST" />
<arg value="/MANIFESTFILE:${release.dir.AMD64.cpp}/jacob.dll.manifest" />
<arg value="/MANIFESTFILE:${release.dir.x64.cpp}/jacob.dll.manifest" />
<arg value="/dll" />
<arg value="/version:${version}" />
<arg value="/out:${release.file.AMD64.dll}" />
<arg value="/libpath:${library.AMD64}" />
<arg value="/libpath:${library.AMD64.platformSDK}" />
<arg value="/libpath:${library.AMD64.atl}" />
<arg value="/out:${release.file.x64.dll}" />
<arg value="/libpath:${library.x64}" />
<arg value="/libpath:${library.x64.platformSDK}" />
<arg value="/libpath:${library.x64.atl}" />
<arg value="${JDK}\lib\jvm.lib" />
<arg value="${release.dir.AMD64.cpp}/*.obj" />
<arg value="${release.dir.x64.cpp}/*.obj" />
</exec>
<exec executable="${manifestool.x86}" dir="${release.dir.AMD64.cpp}" failonerror="true">
<exec executable="${manifestool.x86}" dir="${release.dir.x64.cpp}" failonerror="true">
<env key="Path" value="${MSDEV_IDE_DIR}"/>
<arg value="-outputresource:${release.file.AMD64.dll};2"/>
<arg value="-outputresource:${release.file.x64.dll};2"/>
<arg value="-manifest"/>
<arg value="${release.dir.AMD64.cpp}\jacob.dll.manifest" />
<arg value="${release.dir.x64.cpp}\jacob.dll.manifest" />
</exec>
</target>
<!-- ======================================================================
Use this target to create javadoc from ${src.java.jacob.mainpackage}/*
Use this target to create javadoc from ${src.java.mainpackage}/*
================================================================== -->
<target name="generateJavaDoc">
<defaultexcludes add="**/*Test*"/>
<javadoc
packagenames="${src.java.jacob.mainpackage}/**"
sourcepath="${src.java.jacob}"
packagenames="${src.java.mainpackage}/**"
sourcepath="${src.java.mainroot}"
destdir="${release.dir.java}/docs/api"
author="true"
version="true"
@@ -403,11 +409,11 @@
<doctitle><![CDATA[<h1>${application.title}</h1>]]></doctitle>
<bottom><![CDATA[<i>${application.vendor}</i>]]></bottom>
<group title="Core COM Communication" packages="${src.java.jacob.mainpackage}.com/**"/>
<group title="Higher Level Active X" packages="${src.java.jacob.mainpackage}.activeX/**"/>
<group title="API Stub Generator" packages="${src.java.jacob.mainpackage}.jacobgen/**"/>
<link offline="true" href="http://java.sun.com/j2se/1.4.2/docs/api/" packagelistLoc="C:\tmp"/>
<link href="http://java.sun.com/j2se/1.4.2/docs/api/"/>
<group title="Core COM Communication" packages="${src.java.mainpackage}.com/**"/>
<group title="Higher Level Active X" packages="${src.java.mainpackage}.activeX/**"/>
<group title="API Stub Generator" packages="${src.java.mainpackage}.jacobgen/**"/>
<link offline="true" href="http://java.sun.com/j2se/1.5.0/docs/api/" packagelistLoc="C:\tmp"/>
<link href="http://java.sun.com/j2se/1.5.0/docs/api/"/>
</javadoc>
<defaultexcludes default="true"/>
</target>
@@ -416,7 +422,7 @@
Use this target to package all the files for a release
================================================================== -->
<target name="PackageRelease"
depends="makeDllX86,makeDllAMD64,javaJarBin,generateJavaDoc">
depends="makeDll.x86,makeDll.x64,javaJarBin,generateJavaDoc">
<echo>Packaging release... ${release.file.jar}</echo>
<zip
@@ -424,12 +430,12 @@
<exclude name="**/CVS" />
<exclude name="**/*.obj" />
<exclude name="**/*.class" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="LICENSE.* version.properties README.txt" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="docs/**" />
<zipfileset dir="${release.dir.x86}" prefix="${generated.filename.zip}/x86" includes="${generated.filename.dll}" />
<zipfileset dir="${release.dir.AMD64}" prefix="${generated.filename.zip}/AMD64" includes="${generated.filename.dll}" />
<zipfileset dir="${release.dir.java}" prefix="${generated.filename.zip}" includes="${generated.filename.jar}" />
<zipfileset dir="${release.dir.java}" prefix="${generated.filename.zip}" includes="docs/**"/>
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="LICENSE.* ${generated.filename.version} README.txt" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="docs/**" />
<zipfileset dir="${release.dir.x86}" prefix="${generated.filename.zip}" includes="${generated.filename.dll.x86}" />
<zipfileset dir="${release.dir.x64}" prefix="${generated.filename.zip}" includes="${generated.filename.dll.x64}" />
<zipfileset dir="${release.dir.java}" prefix="${generated.filename.zip}" includes="${generated.filename.jar}" />
<zipfileset dir="${release.dir.java}" prefix="${generated.filename.zip}" includes="docs/**"/>
</zip>
<zip
destfile="${release.dir}/${generated.filename.zip}_src.zip">
@@ -447,14 +453,14 @@
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="vstudio/jacob.vcproj" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="lib/**" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="build.xml, README.txt" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="LICENSE.* version.properties" />
<zipfileset dir="${basedir}" prefix="${generated.filename.zip}" includes="LICENSE.* ${generated.filename.version}" />
</zip>
</target>
<!-- ======================================================================
JUnit testing
This should probably be dependent on dll also
This assumes we are always testing on x86
This assumes we are always testing on X86
This assumes that ant-junit is available
================================================================== -->
<target name='test' depends='javaCompile' >

View File

@@ -34,20 +34,20 @@ been removed.
<p>
<H1>Development Environment</h1>
The simplest build environment includes MS Visual C++ 8.0 (Studio 2005),
Eclipse 3.3 with the C/C++ module and JDK 1.4.
Eclipse 3.3 with the C/C++ module and JDK 1.5.
In that situation, you would just create the <i>compilation_tools.properties</i>
using the example build.xml as a template.
<UL>
<li> Microsoft Visual C++ 8.0 and it's included library. (to D:\apps in my case)
<li> Eclipse 3.3 or later from www.eclipse.org as the Java IDE.
<li> Eclipse 3.3 or later with the C/C++ plugin can be used for C coding in place of VC++ IDE.
<li> Java JDK 1.4 (1.12 was built using 1.4.2.13) Compilation using JDK 1.5 has not been tested
<li> Java JDK 1.5 (1.14 was built using 1.5.0.11)
</ul>
<p>
<p>
<table>
<TR><TD>Release</TD><TD>C Version</TD><TD>Java Version</TD><TD>ANT Version</TD><TD>Eclipse Version Used</TD><TD>generated DLLs</TD></TR>
<TR><TD>up to 1.6</TD><TD>VC 98 (6.0)</TD><TD>?</TD><td>Used MAKE</td><TD>?</TD><TD>32 bit</TD></TR>
<TR><TD>up to 1.6</TD><TD>VC 98 (6.0)</TD><TD>?</TD><td>MAKE</td><TD>?</TD><TD>32 bit</TD></TR>
<TR><TD>1.7</TD><TD>VC 98 (6.0)</TD><TD>1.4</TD><td>1.?</td><TD>?</TD><TD>32 bit</TD></TR>
<TR><TD>1.8</TD><TD>VC 98 (6.0)</TD><TD>1.4</TD><td>1.?</td><TD>?</TD><TD>32 bit</TD></TR>
<TR><TD>1.9</TD><TD>VC 98 (6.0)</TD><TD>1.4</TD><td>1.?</td><TD>?</TD><TD>32 bit</TD></TR>
@@ -55,6 +55,7 @@ using the example build.xml as a template.
<TR><TD>1.11</TD><TD>VC 98 (6.0) & 2003 64bit libs</TD><TD>1.4.?</TD><td>1.6.?</td><TD>3.2.1</TD><TD>32 and 64 bit</TD></TR>
<TR><TD>1.12</TD><TD>VC 98 (6.0) & 2003 64bit libs</TD><TD>1.4.2</TD><td>1.6.5</td><TD>3.2.2</TD><TD>32 and 64 bit</TD></TR>
<TR><TD>1.13</TD><TD>VC 2005</TD><TD>1.4.2</TD><TD>1.7.0</TD><TD>3.3</TD><TD>32 and 64 bit</TD></TR>
<TR><TD>1.14</TD><TD>VC 2005</TD><TD>1.5.0</TD><TD>1.7.0</TD><TD>3.3</TD><TD>32 and 64 bit</TD></TR>
</table>
Microsoft Visual C++ 8.0 supports 64 bit builds. so no additional tools are required.

View File

@@ -1,5 +1,113 @@
<HTML>
<BODY>
<!-- --------- -->
<h2>JACOB 1.14</h2>
<h3>What's New</h3>
<ul>
<li>
Binaries are now compiled with Java 5. JDK 1.4 support dropped.
</li>
<li>
Jacob now loads dlls based on platform (32 bit /64 bit) and version number.
</li>
</ul>
<h3>Tracked Changes</h3>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" >
<tr>
<td width="100%" colspan="2"><b>Bugs</b></td>
</tr>
<tr>
<td width="13%" valign="top">1857439</td>
<td width="87%" valign="top">(M7) version.properties renamed to META-INF/JacobVersion.properties
to remove collision with WebSphere version.properties.</td>
</tr>
<tr>
<td width="13%" valign="top">1840487</td>
<td width="87%" valign="top">(M6) toJavaObject() converting to SafeArray
did shallow copy that left two objects pointing at the same windows memory.</td>
</tr>
<tr>
<td width="13%" valign="top">1829201</td>
<td width="87%" valign="top">(M5) DECIMAL rounding behavior externalized
and old Variant decimal API restored.</td>
</tr>
<tr>
<td width="13%" valign="top">1829201</td>
<td width="87%" valign="top">(M5) DECIMAL rounding behavior externalized
and old Variant decimal API restored.</td>
</tr>
<tr>
<td width="13%" valign="top">1829201</td>
<td width="87%" valign="top">(M4) Decimal type now throws IllegalArgumentException
when more than 12 bytes worth the digits exist in BigDecimal. Rounding
support added to reduce precision of BigDecimals when converting into VT_DECIMAL</td>
</tr>
<tr>
<td width="13%" valign="top">1815163</td>
<td width="87%" valign="top">(M2) Double and Decimal conversion to Int fails for negative values</td>
</tr>
<tr>
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Patches</b></td>
</tr>
<tr>
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Feature Requests</b></td>
</tr>
<tr>
<td width="13%" valign="top">1845039 </td>
<td width="87%" valign="top">(M7) Jacob DLL name can now be customized to
support bundling of Jacob in other products.</td>
</tr>
<td width="13%" valign="top">1845039 </td>
<td width="87%" valign="top">(M6) Jacob DLL names are now qualified by platform and
release. The JacobLibraryLoader now determines the correct 32bit or 64bit
dll based on the system architecture. Jacob.jar now also knows the version
of the dll it is looking for (by name) and loads the correct one. JWS clients
will have to modify their dll loaders. See: The JWS classloader sample </td>
</tr>
<tr>
<td width="13%" valign="top">1828371 </td>
<td width="87%" valign="top">(M4) Added VT_I8 support to SafeArray.</td>
</tr>
<tr>
<td width="13%" valign="top">1813458</td>
<td width="87%" valign="top">(M3) Expand type support. Changed currency support
to use new Currency class. Added VT_I8 64 bit support. VT_I8 support
requires Windows XP or later. VT_I8 not supported by windows in
Windows 2000 and earlier. Added more primitive constructors to Variant.</td>
</tr>
<tr>
<td width="13%" valign="top">1816863</td>
<td width="87%" valign="top">(M1) Migrate Jacob to JDK 5</td>
</tr>
<tr>
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Known Issues</b></td>
</tr>
<tr>
<td width="13%" valign="top"></td>
<td width="87%" valign="top">This is now built with Java 5 compiler and
Java 5 syntax. This release is not compatible with JDK 1.4.x and earlier.</td>
</tr>
<tr>
<td width="13%" valign="top"></td>
<td width="87%" valign="top">This release requires the Visual C++ 2005
libraries. See 1.13 Known Issues for more information.</td>
</tr>
</table>
<!-- --------- -->
<h2>JACOB 1.13</h2>
<h3>What's New</h3>
@@ -82,11 +190,14 @@
<td width="100%" colspan="2"><b>Known Issues</b></td>
</tr>
<tr>
<td width="13%" valign="top">VC++ libraries</td>
<td width="13%" valign="top"></td>
<td width="87%" valign="top">Jacob 1.13 is built using VC++ 2005.
That creates a dependency on the Visual C++ 2005 libraries and msvcr80.dll.
This library is normally installed on XP systems but may have to be manually
installed on older systems. It can be obtained from the MS downloads site.</td>
installed on older systems. The pagackage, often referred to as vcredist.exe
can be obtained from the MS downloads site.
If you are getting loader errors on this release or later when loading the
dll then you may be missing this library.</td>
</tr>
</table>

View File

@@ -23,6 +23,16 @@ to provide a more object like API.
The only exception to this guideline is that the <code>ActiveXComponent</code> class is always
used to make the initial connection to the target dll/COM component.
<hr>
<H2> Considerations when doing server side automation of office </h2>
<p>
Most office and many windows client type applications are not written to be used
in high volume or multi-threaded server environment. There is a
<a href="http://support.microsoft.com/kb/257757/">
support note </a>
on the Microsoft web site that discusses some of the issues.
<p>
<hr>
<H2> Determining the API of the target application </h2>
<p>
@@ -32,14 +42,22 @@ Section not yet written.
<h2> The Jacob DLL </h2>
<p>
Jacob.jar relies on a DLL file that it loads off of the library path or classpath.
This means that you must either copy jacob.dll into your path or use VM options to
add jacob.dll directory to the path.
This means that you must either copy the appropriate jacob ddll into your path or
use VM options to add directory holding jacob dll to the path. Prior to 1.14M6,
the jacob DLL name was alwasy "jacob.dll". This made it hard to verify jacob
was loading the correct dll when multiple copies of jacob were installed on a
single system. It also was confusing on 64 bit systems where the 32 bit and 64 bit
dlls have the same tames.
Starting in 1.14M6, Jacob's library
loader selects a dll with the appropriate name based on the jacob release and platform.
The dll naming convention is: <BR>
<code>jacob&lt;platform&gt;.&lt;version.&gt;.dll</code>
<p>
<h3>Classloader issues</h3>
The code is written so that the jacob.dll is only loaded one time per classloader.
This works fine in the standard application but can cause problems if jacob.jar
is loaded from more than one class loader. This can happen in the situation where multiple
jacob dependent web applications run in the same container like a web server or JWS runtime.
<p>
In the case of a web server, Jacob is normally put in the application specific WEB-INF/lib directory.
This is the "right" way to do it and works in most situations.
But, if Jacob is put in the WEB-INF/lib directory of each application's war file for more than
@@ -71,16 +89,54 @@ oblem
Visual C redistributable installer SP1</A>
</pre>
<p>
<p></p>
<hr>
<h2>Jacob Command Line Settings</h2>
This library supports several different :
<h3>java.library.path</h3>
Used to add the location of the jacob dll to the JVM's library path.
This library supports several differentommand line options:
<table border=1>
<tr><td colspan=3>
<h3>dll path location and dll name customization</h3>
</td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>java.library.path</h4>
</td><td>
Standard Java property used to add the location of the jacob dll to the JVM's library path.
(Added 1.11)
<p>
Example: -Djava.library.path=d:/jacob/release/x86
Example: <code>-Djava.library.path=d:/jacob/release/x86</code>
</td></tr>
<h3>com.jacob.autogc </h3>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>jacob.dll.name</h4>
</td><td>
Override the standard DLL name with a custom one. This stops jacob from
using its 32bit/64bit detection and dll rendevous logic.
Sometimes used when
Jacob is bundled with another application and the application wishes
to tie the jacob dll version number to the application version numbber.
(Added 1.14M7)
<p>
Example: <code>-Djacob.dll.name=MyFunkyDllName.dll</code>
</td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>jacob.dll.name.x86 & jacob.dll.name.x64</h4>
</td><td>
Override the standard 32 bit DLL name with custome ones.
Sometimes used when
Jacob is bundled with another application and the application wishes
to tie the jacob dll version number to the application version numbber.
(Added 1.14M7)
<p>
Example to override 32 bit dll name: <code>-Djacob.dll.name.x86=MyFunkyDllName-32bit.dll</code>
</td></tr>
<tr><td colspan=3>
<h3>Memory Management</h3>
</td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>com.jacob.autogc </h4>
</td><td>
Determines if automatic garbage collection is enabled. This is the
only way to free up objects created in event callbacks. Automatic garbage collection , based on Java gc rules, garbage collection can be enabled via the
<code>com.java.autogc</code> command line option.
@@ -95,16 +151,20 @@ This library supports several different :
to long running threads or to objects created as part of event callbacks.
Code was added to let users try and let the JVM manage the object life cycles
even though the <a href="JacobComLifetime.html">JacobComLifetime.html</a> document
says this is a bad idea.
says this is a bad idea. Added 1.9.
<p>
<p>
This value is cached at startup and cannot be changed on-the-fly via <code>System.setProperty();</code>
<p>
The default value is <strong>false</strong>
The default value is <em>false</em>
<p>
Example: <code>-Dcom.jacob.autogc=false</code>
<h3>&ltclass_name&gt.PutInROT</h3>
</td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>&ltclass_name&gt.PutInROT</h4>
</td><td>
Lets a program specify that instances of certain classes are to not be inserted
into the ROT. This experimental (1.13) feature provides a mechanism for freeing
VariantViaEvent objects that are created in Event threads. There is normally no
@@ -116,7 +176,7 @@ This library supports several different :
outside of the thread it was created in but emperical evidence shows there are
situations where this great reduces the long running memory footprint of applications
that process a lot of events. <em>This function is still experimental</em>.
The functionality of this overlaps the experimental <code>com.jacob.autogc</code> introduced
The functionality was added 1.13. Some of this overlaps the experimental <code>com.jacob.autogc</code> introduced
in 1.9.
See the ROT.java test program for an example of the effects of this option.
<p>
@@ -126,8 +186,14 @@ This library supports several different :
Example: <code>System.setProperty("com.jacob.com.VariantViaVariant.PutInROT","false");</code>
<BR>
Example: <code>-Dcom.jacob.com.VariantViaVariant.PutInROT=false</code>
</td></tr>
<h3>com.jacob.debug</h3>
<tr><td colspan=3>
<h3>Debugging and Troubleshooting</h3>
</td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>com.jacob.debug</h4>
</td><td>
Determines if debug output is enabled to standard out.
<p>
This value is cached at startup and cannot be changed on-the-fly via <code>System.setProperty();</code>
@@ -136,14 +202,21 @@ This library supports several different :
<p>
Example: <code>-Dcom.jacob.debug=false</code>
</td><tr>
<h3>-XCheck:jni</h3>
<tr><td>&nbsp;&nbsp;&nbsp;</td><td valign="top">
<h4>-XCheck:jni</h4>
</td><td>
This turns on additional JVM checking for JNI issues. This is
not an actual JACOB system property but a property used by the JVM.
<p>
The default is "no additional checking"
Example: -XCheck:jni
<p>
Example: <code>-XCheck:jni</code>
</td></tr>
</table>
<p></p>
<hr>
<h2>Finding the DLL version using windows command line</h2>
The jacob.dll file includes the jacob release number in the version field.
@@ -153,8 +226,17 @@ The dll version number is stored in the "image version" field of the
This information from <a href="http://msdn2.microsoft.com/en-gb/library/h88b7dc8(VS.71).aspx">
The Microsoft msdn web site</a>
<hr>
<h2>Unit Tests</h2>
Jacob must know the location of the DLL when running the unit tests in Eclipse.
The simplest way to do this is to add the dll path to the unit as a VM argument.
The argument should be specified based on where you installed the jacob source package.
If you have jacob unpacked in d:/jacob_1_5 and built using build.xml,
then the vm arguments would be:
<br><code>-Djava.library.path=d:/jacob_1_5/release/x86</code> .
<p>
Last Modified 7/2007
Last Modified 12/2007
</BODY>
</HTML>

View File

@@ -384,25 +384,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromCharArray
len = numElements(psa);
}
// get the double array - don't make a copy
jchar *iarr = env->GetCharArrayElements(a, 0);
jchar *arrayElements = env->GetCharArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_UI2;
for(int i=0;i<len;i++) {
V_UI2(&v) = iarr[i];
V_UI2(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_UI2 || vt == VT_I2) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, iarr, len*sizeof(jchar));
memcpy(pData, arrayElements, len*sizeof(jchar));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from char", 0);
}
env->ReleaseCharArrayElements(a, iarr, 0);
env->ReleaseCharArrayElements(a, arrayElements, 0);
}
/*
@@ -427,25 +427,68 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromIntArray
len = numElements(psa);
}
// get the int array - don't make a copy
jint *iarr = env->GetIntArrayElements(a, 0);
jint *arrayElements = env->GetIntArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_I4;
for(int i=0;i<len;i++) {
V_I4(&v) = iarr[i];
V_I4(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_I4) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, iarr, len*sizeof(int));
memcpy(pData, arrayElements, len*sizeof(int));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from int", -1);
}
env->ReleaseIntArrayElements(a, iarr, 0);
env->ReleaseIntArrayElements(a, arrayElements, 0);
}
/*
* Class: SafeArray
* Method: fromLongArray
* Signature: ([L)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromLongArray
(JNIEnv *env, jobject _this, jlongArray a)
{
SAFEARRAY *psa = extractSA(env, _this);
if (!psa) {
ThrowComFail(env, "safearray object corrupted", -1);
return;
}
VARTYPE vt;
SafeArrayGetVartype(psa, &vt);
int len = env->GetArrayLength(a);
if (len > numElements(psa))
{
// max size of memcpy
len = numElements(psa);
}
// get the long array - don't make a copy
jlong *arrayElements = env->GetLongArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_I8;
for(int i=0;i<len;i++) {
V_I8(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_I8) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, arrayElements, len*sizeof(long));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from long", -1);
}
env->ReleaseLongArrayElements(a, arrayElements, 0);
}
/*
@@ -470,25 +513,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromShortArray
len = numElements(psa);
}
// get the short array - don't make a copy
jshort *iarr = env->GetShortArrayElements(a, 0);
jshort *arrayElements = env->GetShortArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_I2;
for(int i=0;i<len;i++) {
V_I2(&v) = iarr[i];
V_I2(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_I2) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, iarr, len*sizeof(short));
memcpy(pData, arrayElements, len*sizeof(short));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from short", -1);
}
env->ReleaseShortArrayElements(a, iarr, 0);
env->ReleaseShortArrayElements(a, arrayElements, 0);
}
/*
@@ -513,25 +556,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromDoubleArray
len = numElements(psa);
}
// get the double array - don't make a copy
jdouble *iarr = env->GetDoubleArrayElements(a, 0);
jdouble *arrayElements = env->GetDoubleArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_R8;
for(int i=0;i<len;i++) {
V_R8(&v) = iarr[i];
V_R8(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_R8 || vt == VT_DATE) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, iarr, len*sizeof(double));
memcpy(pData, arrayElements, len*sizeof(double));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from double", -1);
}
env->ReleaseDoubleArrayElements(a, iarr, 0);
env->ReleaseDoubleArrayElements(a, arrayElements, 0);
}
/*
@@ -613,25 +656,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromByteArray
len = numElements(psa);
}
// get the byte array - don't make a copy
jbyte *iarr = env->GetByteArrayElements(a, 0);
jbyte *arrayElements = env->GetByteArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_UI1;
for(int i=0;i<len;i++) {
V_UI1(&v) = iarr[i];
V_UI1(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_UI1 || vt == VT_I1) {
jbyte *pData;
SafeArrayAccessData(psa, (void **)&pData);
memcpy(pData, iarr, len*sizeof(jbyte));
memcpy(pData, arrayElements, len*sizeof(jbyte));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from byte", -1);
}
env->ReleaseByteArrayElements(a, iarr, 0);
env->ReleaseByteArrayElements(a, arrayElements, 0);
}
/*
@@ -656,25 +699,25 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromFloatArray
len = numElements(psa);
}
// get the float array - don't make a copy
jfloat *iarr = env->GetFloatArrayElements(a, 0);
jfloat *arrayElements = env->GetFloatArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_R4;
for(int i=0;i<len;i++) {
V_R4(&v) = iarr[i];
V_R4(&v) = arrayElements[i];
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_R4) {
void *pData;
SafeArrayAccessData(psa, &pData);
memcpy(pData, iarr, len*sizeof(float));
memcpy(pData, arrayElements, len*sizeof(float));
SafeArrayUnaccessData(psa);
} else {
ThrowComFail(env, "safearray cannot be assigned from float", -1);
}
env->ReleaseFloatArrayElements(a, iarr, 0);
env->ReleaseFloatArrayElements(a, arrayElements, 0);
}
/*
@@ -699,13 +742,13 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromBooleanArray
len = numElements(psa);
}
// get the boolean array - don't make a copy
jboolean *iarr = env->GetBooleanArrayElements(a, 0);
jboolean *arrayElements = env->GetBooleanArrayElements(a, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_BOOL;
for(int i=0;i<len;i++) {
V_BOOL(&v) = iarr[i] ? VARIANT_TRUE : VARIANT_FALSE;
V_BOOL(&v) = arrayElements[i] ? VARIANT_TRUE : VARIANT_FALSE;
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
@@ -713,14 +756,14 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromBooleanArray
// jboolean is 1 byte and VARIANT_BOOL is 2
VARIANT_BOOL v;
for(int i=0;i<len;i++) {
v = iarr[i] ? VARIANT_TRUE : VARIANT_FALSE;
v = arrayElements[i] ? VARIANT_TRUE : VARIANT_FALSE;
long x = i;
SafeArrayPutElement(psa,&x,&v);
}
} else {
ThrowComFail(env, "safearray cannot be assigned from boolean", -1);
}
env->ReleaseBooleanArrayElements(a, iarr, 0);
env->ReleaseBooleanArrayElements(a, arrayElements, 0);
}
/*
@@ -776,14 +819,14 @@ JNIEXPORT jcharArray JNICALL Java_com_jacob_com_SafeArray_toCharArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_UI2 || vt == VT_I2) {
jcharArray iarr = env->NewCharArray(num);
jcharArray arrayElements = env->NewCharArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetCharArrayRegion(iarr, 0, num, (jchar *)pData);
env->SetCharArrayRegion(arrayElements, 0, num, (jchar *)pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jcharArray iarr = env->NewCharArray(num);
jcharArray arrayElements = env->NewCharArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -793,9 +836,9 @@ JNIEXPORT jcharArray JNICALL Java_com_jacob_com_SafeArray_toCharArray
return NULL;
}
jchar val = V_UI2(&v);
env->SetCharArrayRegion(iarr, i, 1, &val);
env->SetCharArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -820,14 +863,14 @@ JNIEXPORT jintArray JNICALL Java_com_jacob_com_SafeArray_toIntArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_I4) {
jintArray iarr = env->NewIntArray(num);
jintArray arrayElements = env->NewIntArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetIntArrayRegion(iarr, 0, num, (jint *)pData);
env->SetIntArrayRegion(arrayElements, 0, num, (jint *)pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jintArray iarr = env->NewIntArray(num);
jintArray arrayElements = env->NewIntArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -837,9 +880,54 @@ JNIEXPORT jintArray JNICALL Java_com_jacob_com_SafeArray_toIntArray
return NULL;
}
jint val = V_I4(&v);
env->SetIntArrayRegion(iarr, i, 1, &val);
env->SetIntArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
/*
* Class: SafeArray
* Method: toLongArray
* Signature: ()[L
*/
JNIEXPORT jlongArray JNICALL Java_com_jacob_com_SafeArray_toLongArray
(JNIEnv *env, jobject _this)
{
SAFEARRAY *sa = extractSA(env, _this);
if (!sa) {
ThrowComFail(env, "safearray object corrupted", -1);
return NULL;
}
long lb, ub;
SafeArrayGetLBound(sa, 1, &lb);
SafeArrayGetUBound(sa, 1, &ub);
int num = ub - lb + 1;
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_I8) {
jlongArray arrayElements = env->NewLongArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetLongArrayRegion(arrayElements, 0, num, (jlong *)pData);
SafeArrayUnaccessData(sa);
return arrayElements;
} else if (vt == VT_VARIANT) {
jlongArray arrayElements = env->NewLongArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
long ix = i;
SafeArrayGetElement(sa, &ix, (void*) &v);
if (FAILED(VariantChangeType(&v, &v, 0, VT_I8))) {
return NULL;
}
jlong val = V_I8(&v);
env->SetLongArrayRegion(arrayElements, i, 1, &val);
}
return arrayElements;
}
return NULL;
}
@@ -865,14 +953,14 @@ JNIEXPORT jshortArray JNICALL Java_com_jacob_com_SafeArray_toShortArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_I2) {
jshortArray iarr = env->NewShortArray(num);
jshortArray arrayElements = env->NewShortArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetShortArrayRegion(iarr, 0, num, (jshort *)pData);
env->SetShortArrayRegion(arrayElements, 0, num, (jshort *)pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jshortArray iarr = env->NewShortArray(num);
jshortArray arrayElements = env->NewShortArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -882,9 +970,9 @@ JNIEXPORT jshortArray JNICALL Java_com_jacob_com_SafeArray_toShortArray
return NULL;
}
jshort val = V_I2(&v);
env->SetShortArrayRegion(iarr, i, 1, &val);
env->SetShortArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -909,14 +997,14 @@ JNIEXPORT jdoubleArray JNICALL Java_com_jacob_com_SafeArray_toDoubleArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_R8) {
jdoubleArray iarr = env->NewDoubleArray(num);
jdoubleArray arrayElements = env->NewDoubleArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetDoubleArrayRegion(iarr, 0, num, (jdouble *)pData);
env->SetDoubleArrayRegion(arrayElements, 0, num, (jdouble *)pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jdoubleArray iarr = env->NewDoubleArray(num);
jdoubleArray arrayElements = env->NewDoubleArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -926,9 +1014,9 @@ JNIEXPORT jdoubleArray JNICALL Java_com_jacob_com_SafeArray_toDoubleArray
return NULL;
}
jdouble val = V_R8(&v);
env->SetDoubleArrayRegion(iarr, i, 1, &val);
env->SetDoubleArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -955,7 +1043,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_jacob_com_SafeArray_toStringArray
if (vt == VT_VARIANT)
{
jclass sClass = env->FindClass("java/lang/String");
jobjectArray iarr = env->NewObjectArray(num, sClass, NULL);
jobjectArray arrayElements = env->NewObjectArray(num, sClass, NULL);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -966,20 +1054,20 @@ JNIEXPORT jobjectArray JNICALL Java_com_jacob_com_SafeArray_toStringArray
}
BSTR bs = V_BSTR(&v);
jstring js = env->NewString((jchar*)bs, SysStringLen(bs)); // SR cast SF 1689061
env->SetObjectArrayElement(iarr, i, js);
env->SetObjectArrayElement(arrayElements, i, js);
}
return iarr;
return arrayElements;
} else if (vt == VT_BSTR) {
jclass sClass = env->FindClass("java/lang/String");
jobjectArray iarr = env->NewObjectArray(num, sClass, NULL);
jobjectArray arrayElements = env->NewObjectArray(num, sClass, NULL);
for(int i=lb;i<=ub;i++) {
BSTR bs = NULL;
long ix = i;
SafeArrayGetElement(sa, &ix, (void*) &bs);
jstring js = env->NewString((jchar*)bs, SysStringLen(bs)); // SR cast SF 1689061
env->SetObjectArrayElement(iarr, i, js);
env->SetObjectArrayElement(arrayElements, i, js);
}
return iarr;
return arrayElements;
}
ThrowComFail(env, "safearray cannot be converted to string[]", 0);
return NULL;
@@ -1005,14 +1093,14 @@ JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_SafeArray_toByteArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_I1 || vt == VT_UI1) {
jbyteArray iarr = env->NewByteArray(num);
jbyteArray arrayElements = env->NewByteArray(num);
jbyte *pData;
SafeArrayAccessData(sa, (void **)&pData);
env->SetByteArrayRegion(iarr, 0, num, pData);
env->SetByteArrayRegion(arrayElements, 0, num, pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jbyteArray iarr = env->NewByteArray(num);
jbyteArray arrayElements = env->NewByteArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb,j=0;i<=ub;i++,j++) {
@@ -1022,9 +1110,9 @@ JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_SafeArray_toByteArray
return NULL;
}
jbyte val = V_UI1(&v);
env->SetByteArrayRegion(iarr, j, 1, &val);
env->SetByteArrayRegion(arrayElements, j, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -1049,14 +1137,14 @@ JNIEXPORT jfloatArray JNICALL Java_com_jacob_com_SafeArray_toFloatArray
VARTYPE vt;
SafeArrayGetVartype(sa, &vt);
if (vt == VT_R4) {
jfloatArray iarr = env->NewFloatArray(num);
jfloatArray arrayElements = env->NewFloatArray(num);
void *pData;
SafeArrayAccessData(sa, &pData);
env->SetFloatArrayRegion(iarr, 0, num, (jfloat *)pData);
env->SetFloatArrayRegion(arrayElements, 0, num, (jfloat *)pData);
SafeArrayUnaccessData(sa);
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jfloatArray iarr = env->NewFloatArray(num);
jfloatArray arrayElements = env->NewFloatArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -1066,9 +1154,9 @@ JNIEXPORT jfloatArray JNICALL Java_com_jacob_com_SafeArray_toFloatArray
return NULL;
}
jfloat val = V_R4(&v);
env->SetFloatArrayRegion(iarr, i, 1, &val);
env->SetFloatArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -1094,17 +1182,17 @@ JNIEXPORT jbooleanArray JNICALL Java_com_jacob_com_SafeArray_toBooleanArray
SafeArrayGetVartype(sa, &vt);
if (vt == VT_BOOL) {
// need to loop because jboolean=1 byte and VARIANT_BOOL=2 bytes
jbooleanArray iarr = env->NewBooleanArray(num);
jbooleanArray arrayElements = env->NewBooleanArray(num);
VARIANT_BOOL v;
for(int i=lb,j=0;i<=ub;i++,j++) {
long ix = i;
SafeArrayGetElement(sa, &ix, (void*) &v);
jboolean val = v == VARIANT_TRUE ? JNI_TRUE : JNI_FALSE;
env->SetBooleanArrayRegion(iarr, j, 1, &val);
env->SetBooleanArrayRegion(arrayElements, j, 1, &val);
}
return iarr;
return arrayElements;
} else if (vt == VT_VARIANT) {
jbooleanArray iarr = env->NewBooleanArray(num);
jbooleanArray arrayElements = env->NewBooleanArray(num);
VARIANT v;
VariantInit(&v);
for(int i=lb;i<=ub;i++) {
@@ -1114,9 +1202,9 @@ JNIEXPORT jbooleanArray JNICALL Java_com_jacob_com_SafeArray_toBooleanArray
return NULL;
}
jboolean val = V_BOOL(&v) == VARIANT_TRUE ? JNI_TRUE : JNI_FALSE;
env->SetBooleanArrayRegion(iarr, i, 1, &val);
env->SetBooleanArrayRegion(arrayElements, i, 1, &val);
}
return iarr;
return arrayElements;
}
return NULL;
}
@@ -1310,25 +1398,25 @@ JNIEXPORT jobjectArray JNICALL Java_com_jacob_com_SafeArray_toVariantArray
} \
VARTYPE vt; \
SafeArrayGetVartype(psa, &vt); \
jtyp *iarr = env->jgetArr(ja, 0); \
jtyp *arrayElements = env->jgetArr(ja, 0); \
if (vt == VT_VARIANT) { \
VARIANT v; \
VariantInit(&v); \
V_VT(&v) = varType; \
for(int i=ja_start,j=idx;i<ja_start+nelem;i++,j++) { \
varAccess(&v) = iarr[i]; \
varAccess(&v) = arrayElements[i]; \
long x = j; \
SafeArrayPutElement(psa,&x,&v); \
} \
} else if (vt == varType || vt == varType2) { \
jtyp *pData; \
SafeArrayAccessData(psa, (void **)&pData); \
memcpy(&pData[idx], &iarr[ja_start], nelem*sizeof(jtyp)); \
memcpy(&pData[idx], &arrayElements[ja_start], nelem*sizeof(jtyp)); \
SafeArrayUnaccessData(psa); \
} else { \
ThrowComFail(env, "safearray type mismatch", -1); \
} \
env->jrelArr(ja, iarr, 0);
env->jrelArr(ja, arrayElements, 0);
/*
* Class: SafeArray
@@ -1398,6 +1486,8 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setChars
GetCharArrayElements, ReleaseCharArrayElements);
}
/*----------------------- INTS ----------------------------------*/
/*
* Class: SafeArray
* Method: getInt
@@ -1465,6 +1555,79 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setInts
GetIntArrayElements, ReleaseIntArrayElements);
}
/*----------------------- END INTS ----------------------------------*/
/*----------------------- LONGS ----------------------------------*/
/*
* Class: SafeArray
* Method: getLong
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong__I
(JNIEnv *env, jobject _this, jint idx)
{
GET1DCODE(VT_I8, V_I8, jlong)
}
/*
* Class: SafeArray
* Method: getLong
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong__II
(JNIEnv *env, jobject _this, jint i, jint j)
{
GET2DCODE(VT_I8, V_I8, jlong)
}
/*
* Class: SafeArray
* Method: setLong
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong__IJ
(JNIEnv *env, jobject _this, jint idx, jlong c)
{
SET1DCODE(VT_I8, V_I8);
}
/*
* Class: SafeArray
* Method: setLong
* Signature: (IIJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong__IIJ
(JNIEnv *env, jobject _this, jint i, jint j, jlong c)
{
SET2DCODE(VT_I8, V_I8);
}
/*
* Class: SafeArray
* Method: getLongs
* Signature: (II[JI)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_getLongs
(JNIEnv *env, jobject _this, jint idx, jint nelem, jlongArray ja, jint ja_start)
{
GETARRAYCODE(VT_I8, VT_I8, V_I8, jlong, SetLongArrayRegion);
}
/*
* Class: SafeArray
* Method: setLongs
* Signature: (II[JI)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLongs
(JNIEnv *env, jobject _this, jint idx, jint nelem, jlongArray ja, jint ja_start)
{
SETARRAYCODE(VT_I8, VT_I8, V_I8, jlong,
GetLongArrayElements, ReleaseLongArrayElements);
}
/*------------------------ END LONGS -----------------------------*/
/*
* Class: SafeArray
* Method: getShort
@@ -2206,27 +2369,27 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setBooleans
{
len = numElements(psa);
}
jboolean *iarr = env->GetBooleanArrayElements(ja, 0);
jboolean *arrayElements = env->GetBooleanArrayElements(ja, 0);
if (vt == VT_VARIANT) {
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_BOOL;
for(int i=ja_start,j=idx;i<ja_start+nelem;i++,j++) {
V_BOOL(&v) = iarr[i] == JNI_TRUE ? VARIANT_TRUE : VARIANT_FALSE;
V_BOOL(&v) = arrayElements[i] == JNI_TRUE ? VARIANT_TRUE : VARIANT_FALSE;
long x = j;
SafeArrayPutElement(psa,&x,&v);
}
} else if (vt == VT_BOOL) {
VARIANT_BOOL v;
for(int i=ja_start,j=idx;i<ja_start+nelem;i++,j++) {
v = iarr[i] == JNI_TRUE ? VARIANT_TRUE : VARIANT_FALSE;
v = arrayElements[i] == JNI_TRUE ? VARIANT_TRUE : VARIANT_FALSE;
long x = j;
SafeArrayPutElement(psa,&x,&v);
}
} else {
ThrowComFail(env, "safearray type mismatch", -1);
}
env->ReleaseBooleanArrayElements(ja, iarr, 0);
env->ReleaseBooleanArrayElements(ja, arrayElements, 0);
}
/*
@@ -2660,6 +2823,8 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setChar___3IC
SETNDCODE(VT_UI2, V_UI2);
}
/*----------------------- INTS ----------------------------------*/
/*
* Class: com_jacob_com_SafeArray
* Method: getInt
@@ -2683,6 +2848,34 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setInt___3II
SETNDCODE(VT_I4, V_I4);
}
/*----------------------- END INTS ----------------------------------*/
/*----------------------- LONGS ----------------------------------*/
/*
* Class: com_jacob_com_SafeArray
* Method: getLong
* Signature: ([I)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong___3I
(JNIEnv *env, jobject _this, jintArray indices)
{
GETNDCODE(VT_I8, V_I8, jlong)
}
/*
* Class: com_jacob_com_SafeArray
* Method: setLong
* Signature: ([IJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong___3IJ
(JNIEnv *env, jobject _this, jintArray indices, jlong c)
{
SETNDCODE(VT_I8, V_I8);
}
/*----------------------- END LONGS ----------------------------------*/
/*
* Class: com_jacob_com_SafeArray
* Method: getShort

View File

@@ -149,6 +149,14 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromCharArray
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromIntArray
(JNIEnv *, jobject, jintArray);
/*
* Class: com_jacob_com_SafeArray
* Method: fromLongArray
* Signature: ([L)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_fromLongArray
(JNIEnv *, jobject, jlongArray);
/*
* Class: com_jacob_com_SafeArray
* Method: fromShortArray
@@ -221,6 +229,14 @@ JNIEXPORT jcharArray JNICALL Java_com_jacob_com_SafeArray_toCharArray
JNIEXPORT jintArray JNICALL Java_com_jacob_com_SafeArray_toIntArray
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_SafeArray
* Method: toLongArray
* Signature: ()[L
*/
JNIEXPORT jlongArray JNICALL Java_com_jacob_com_SafeArray_toLongArray
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_SafeArray
* Method: toShortArray
@@ -373,6 +389,54 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_getInts
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setInts
(JNIEnv *, jobject, jint, jint, jintArray, jint);
/*
* Class: SafeArray
* Method: getLong
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong__I
(JNIEnv *env, jobject _this, jint idx);
/*
* Class: SafeArray
* Method: getLong
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong__II
(JNIEnv *env, jobject _this, jint i, jint j);
/*
* Class: SafeArray
* Method: setLong
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong__IJ
(JNIEnv *env, jobject _this, jint idx, jlong c);
/*
* Class: SafeArray
* Method: setLong
* Signature: (IIJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong__IIJ
(JNIEnv *env, jobject _this, jint i, jint j, jlong c);
/*
* Class: SafeArray
* Method: getLongs
* Signature: (II[JI)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_getLongs
(JNIEnv *env, jobject _this, jint idx, jint nelem, jlongArray ja, jint ja_start);
/*
* Class: SafeArray
* Method: setLongs
* Signature: (II[JI)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLongs
(JNIEnv *env, jobject _this, jint idx, jint nelem, jlongArray ja, jint ja_start);
/*
* Class: com_jacob_com_SafeArray
* Method: getShort
@@ -757,6 +821,23 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_SafeArray_getInt___3I
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setInt___3II
(JNIEnv *, jobject, jintArray, jint);
/*
* Class: com_jacob_com_SafeArray
* Method: getLong
* Signature: ([I)J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_SafeArray_getLong___3I
(JNIEnv *env, jobject _this, jintArray indices);
/*
* Class: com_jacob_com_SafeArray
* Method: setLong
* Signature: ([IJ)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setLong___3IJ
(JNIEnv *env, jobject _this, jintArray indices, jlong c);
/*
* Class: com_jacob_com_SafeArray
* Method: getShort

View File

@@ -611,6 +611,17 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrency
} else ThrowComFail(env, "putVariantCurrency failed", -1);
}
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantLong
(JNIEnv *env, jobject _this, jlong longValue)
{
VARIANT *v = extractVariant(env, _this);
if (v) {
VariantClear(v); // whatever was there before
V_VT(v) = VT_I8;
V_I8(v) = (LONGLONG)longValue;
} else ThrowComFail(env, "putVariantLong failed", -1);
}
/**
* Accepts a dispatch object and sets the type to VT_DISPATCH.
* There is currently no way to pass NULL into this method
@@ -662,6 +673,18 @@ JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrency
return NULL;
}
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantLong
(JNIEnv *env, jobject _this)
{
VARIANT *v = extractVariant(env, _this);
if (v) {
if (V_VT(v) != VT_I8) {
return NULL;
}
return (jlong)V_I8(v);
}
return NULL;
}
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloatRef
(JNIEnv *env, jobject _this, jfloat val)
@@ -689,6 +712,19 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrencyRef
}
}
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantLongRef
(JNIEnv *env, jobject _this, jlong longValue)
{
VARIANT *v = extractVariant(env, _this);
if (v) {
VariantClear(v); // whatever was there before
LONGLONG *ps = (LONGLONG *)CoTaskMemAlloc(sizeof(LONGLONG));
*ps = longValue;
V_VT(v) = VT_I8|VT_BYREF;
V_I8REF(v) = ps;
}
}
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantErrorRef
(JNIEnv *env, jobject _this, jint i)
{
@@ -801,6 +837,19 @@ JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrencyRef
return NULL;
}
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantLongRef
(JNIEnv *env, jobject _this)
{
VARIANT *v = extractVariant(env, _this);
if (v) {
if (V_VT(v) != (VT_I8|VT_BYREF)) {
return NULL;
}
return (jlong)*V_I8REF(v);
}
return NULL;
}
JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantErrorRef
(JNIEnv *env, jobject _this)
{
@@ -1076,7 +1125,11 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantVariant
VariantClear(v); // whatever was there before
DECIMAL *pd = (DECIMAL *)CoTaskMemAlloc(sizeof(DECIMAL));
pd->scale = scale;
pd->sign = signum == 1?0:0x80;
if (signum == 1 || signum == 0){
pd->sign = 0;
} else {
pd->sign = 0x80;
}
pd->Hi32 = hi;
pd->Mid32 = mid;
pd->Lo32 = lo;
@@ -1099,7 +1152,11 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Variant_getVariantVariant
VariantClear(v); // whatever was there before
d = (DECIMAL*)v;
d->scale = scale;
d->sign = signum == 1?0:0x80;
if (signum == 1 || signum == 0){
d->sign = 0;
} else {
d->sign = 0x80;
}
d->Hi32 = hi;
d->Mid32 = mid;
d->Lo32 = lo;

View File

@@ -282,6 +282,14 @@ JNIEXPORT jdouble JNICALL Java_com_jacob_com_Variant_getVariantDouble
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrency
(JNIEnv *, jobject, jlong);
/*
* Class: com_jacob_com_Variant
* Method: putVariantLong
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantLong
(JNIEnv *, jobject, jlong);
/*
* Class: com_jacob_com_Variant
* Method: putVariantDispatch
@@ -306,6 +314,13 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantDouble
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrency
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_Variant
* Method: getVariantLong
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantLong
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_Variant
* Method: putVariantFloatRef
@@ -322,6 +337,14 @@ JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantFloatRef
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantCurrencyRef
(JNIEnv *, jobject, jlong);
/*
* Class: com_jacob_com_Variant
* Method: putVariantLongRef
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantLongRef
(JNIEnv *, jobject, jlong);
/*
* Class: com_jacob_com_Variant
* Method: putVariantErrorRef
@@ -386,6 +409,14 @@ JNIEXPORT jfloat JNICALL Java_com_jacob_com_Variant_getVariantFloatRef
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantCurrencyRef
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_Variant
* Method: getVariantLongRef
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_com_jacob_com_Variant_getVariantLongRef
(JNIEnv *, jobject);
/*
* Class: com_jacob_com_Variant
* Method: getVariantErrorRef

View File

@@ -4,62 +4,71 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import com.jacob.com.LibraryLoader;
/**
* It is sometimes necessary to run Jacob without being able to install the dll
* on the client machine. This is true in JavaWebStart (JWS) and possibly
* Applet (assuming security allows access to the file system).
* The obvious thing to do here is to jar up
* the Jacob.dll so that it can be downloaded the client along with the rest
* of the resources. This is simple except that the System.Load() function
* does not search jar files for DLLs. It searches the classpath.
* The work around to this problem is to write the DLL to a temporary file and then
* on the client machine. This is true in JavaWebStart (JWS) and possibly Applet
* (assuming security allows access to the file system). The obvious thing to do
* here is to jar up the Jacob.dll so that it can be downloaded the client along
* with the rest of the resources. This is simple except that the System.Load()
* function does not search jar files for DLLs. It searches the classpath. The
* work around to this problem is to write the DLL to a temporary file and then
* explicitly load the DLL calling passing the full path to the temporary file.
*
* The following code demonstrates this idea.
*
* @author joe
*
*
*/
public class DLLFromJARClassLoader {
/**
* Load the DLL from the classpath rather than from the java path.
* This code uses this class's class loader to find the dell in one
* of the jar files in this class's class path. It then
* writes the file as a temp file and calls Load() on the temp file.
* The temporary file is marked to be deleted on exit so the dll
* is deleted from the system when the application exits.
* <p>
* Derived from ample code found in Sun's java forums
* <p.
* @return true if the native library has loaded, false if there was a problem.
*/
public boolean loadLibrary()
{
try
{
//Finds a stream to the dll. Change path/class if necessary
InputStream inputStream = getClass().getResource("/jacob.dll").openStream();
//Change name if necessary
File temporaryDll = File.createTempFile("jacob", ".dll");
FileOutputStream outputStream = new FileOutputStream(temporaryDll);
byte[] array = new byte[8192];
for (int i = inputStream.read(array);
i != -1;
i = inputStream.read(array)) {
outputStream.write(array, 0, i);
}
outputStream.close();
temporaryDll.deleteOnExit();
System.load(temporaryDll.getPath());
return true;
}
catch(Throwable e)
{
e.printStackTrace();
return false;
}
}
/**
* Load the DLL from the classpath rather than from the java path. This code
* uses this class's class loader to find the dell in one of the jar files
* in this class's class path. It then writes the file as a temp file and
* calls Load() on the temp file. The temporary file is marked to be deleted
* on exit so the dll is deleted from the system when the application exits.
* <p>
* Derived from ample code found in Sun's java forums <p.
*
* @return true if the native library has loaded, false if there was a
* problem.
*/
public boolean loadLibrary() {
try {
// this assumes that the dll is in the root dir of the signed
// jws jar file for this application.
//
// Starting in 1.14M6, the dll is named by platform and architecture
// so the best thing to do is to ask the LibraryLoader what name we
// expect.
// this code might be different if you customize the name of
// the jacob dll to match some custom naming convention
InputStream inputStream = getClass().getResource(
"/" + LibraryLoader.getPreferredDLLName() + ".dll")
.openStream();
// Put the DLL somewhere we can find it with a name Jacob expects
File temporaryDll = File.createTempFile(LibraryLoader
.getPreferredDLLName(), ".dll");
FileOutputStream outputStream = new FileOutputStream(temporaryDll);
byte[] array = new byte[8192];
for (int i = inputStream.read(array); i != -1; i = inputStream
.read(array)) {
outputStream.write(array, 0, i);
}
outputStream.close();
temporaryDll.deleteOnExit();
// Ask LibraryLoader to load the dll for us based on the path we
// set
System.setProperty(LibraryLoader.JACOB_DLL_PATH, temporaryDll
.getPath());
LibraryLoader.loadJacobLibrary();
return true;
} catch (Throwable e) {
e.printStackTrace();
return false;
}
}
}

View File

@@ -1,25 +1,38 @@
package com.jacob.samples.MathProj;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.*;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
/**
* This example uses the MathTest sample VB COM DLL under
* the MathProj directory
* This example uses the MathTest sample VB COM DLL under the MathProj directory
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
class MathTest {
/**
* standard main program to run the sample
*
* @param args
* command line parameters
*/
public static void main(String[] args) {
MathTest me = new MathTest();
me.runTest();
}
public MathTest(){
/** default constructor */
public MathTest() {
}
public void runTest(){
/**
* not clear why we need a class and run method but that's the way it was
* written
*/
public void runTest() {
// deprecated
// System.runFinalizersOnExit(true);
Dispatch test = new ActiveXComponent("MathTest.Math");
@@ -42,14 +55,29 @@ class MathTest {
System.out.println("v.toDispatch=" + v.toDispatch());
}
public class TestEvents {
public void DoneAdd(Variant[] args) {
System.out.println("DoneAdd called in java");
/**
*
* sample class to catch the events
*
*/
public class TestEvents {
/**
* catches the DoneAdd event
*
* @param args
*/
public void DoneAdd(Variant[] args) {
System.out.println("DoneAdd called in java");
}
/**
* catches the DoneMult event
*
* @param args
*/
public void DoneMult(Variant[] args) {
System.out.println("DoneMult called in java");
}
}
public void DoneMult(Variant[] args) {
System.out.println("DoneMult called in java");
}
}
}

View File

@@ -19,123 +19,126 @@
*/
package com.jacob.samples.access;
import com.jacob.com.*;
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*
*/
class Access
{
/**
* the main loop for the test
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
ComThread.InitSTA();
// original test used this
// ActiveXComponent ax = new ActiveXComponent("DAO.PrivateDBEngine");
// my xp box with a later release of access needed this
ActiveXComponent ax = new ActiveXComponent("DAO.PrivateDBEngine.35");
// this only works for access files pre-access-2000
// this line doesn't work on my xp box in Eclipse
//Dispatch db = open(ax, ".\\sample2.mdb");
// this works when running in eclipse because the test cases run pwd project root
Dispatch db = open(ax, "samples/com/jacob/samples/access/sample2.mdb");
String sql = "select * from MainTable";
// make a temporary querydef
Dispatch qd = Dispatch.call(db, "CreateQueryDef","").toDispatch();
// set the SQL string on it
Dispatch.put(qd, "SQL", sql);
Variant result = getByQueryDef(qd);
class Access {
/**
* the main loop for the test
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ComThread.InitSTA();
// original test used this
// ActiveXComponent ax = new ActiveXComponent("DAO.PrivateDBEngine");
// my xp box with a later release of access needed this
ActiveXComponent ax = new ActiveXComponent("DAO.PrivateDBEngine.35");
// this only works for access files pre-access-2000
// this line doesn't work on my xp box in Eclipse
// Dispatch db = open(ax, ".\\sample2.mdb");
// this works when running in eclipse because the test cases run pwd
// project root
Dispatch db = open(ax, "samples/com/jacob/samples/access/sample2.mdb");
String sql = "select * from MainTable";
// make a temporary querydef
Dispatch qd = Dispatch.call(db, "CreateQueryDef", "").toDispatch();
// set the SQL string on it
Dispatch.put(qd, "SQL", sql);
Variant result = getByQueryDef(qd);
// the 2-d safearray is transposed from what you might expect
System.out.println("resulting array is "+result.toSafeArray());
close(db);
System.out.println("about to call ComThread.Release()");
ComThread.Release();
}
System.out.println("resulting array is " + result.toSafeArray());
close(db);
System.out.println("about to call ComThread.Release()");
ComThread.Release();
}
/**
* Open a database
* @param ax
* @param fileName
* @return dispatch object that was opened
*/
public static Dispatch open(ActiveXComponent ax, String fileName)
{
Variant f = new Variant(false);
// open the file in read-only mode
Variant[] args = new Variant[] {new Variant(fileName), f, f};
Dispatch openDB = ax.invoke("OpenDatabase", args).toDispatch();
return openDB;
}
/**
* Open a database
*
* @param ax
* @param fileName
* @return dispatch object that was opened
*/
public static Dispatch open(ActiveXComponent ax, String fileName) {
Variant f = new Variant(false);
// open the file in read-only mode
Variant[] args = new Variant[] { new Variant(fileName), f, f };
Dispatch openDB = ax.invoke("OpenDatabase", args).toDispatch();
return openDB;
}
/**
* Close a database
* @param openDB db to be closed
*/
public static void close(Dispatch openDB)
{
Dispatch.call(openDB, "Close");
}
/**
* Close a database
*
* @param openDB
* db to be closed
*/
public static void close(Dispatch openDB) {
Dispatch.call(openDB, "Close");
}
/**
* Extract the values from the recordset
* @param recset
* @return Variant that is the returned values
*/
public static Variant getValues(Dispatch recset)
{
Dispatch.callSub(recset,"moveFirst");
Variant vi = new Variant(4096);
Variant v = Dispatch.call(recset,"GetRows", vi);
return v;
}
/**
* Extract the values from the recordset
*
* @param recset
* @return Variant that is the returned values
*/
public static Variant getValues(Dispatch recset) {
Dispatch.callSub(recset, "moveFirst");
Variant vi = new Variant(4096);
Variant v = Dispatch.call(recset, "GetRows", vi);
return v;
}
/**
* should return ?? for the passed in ??
* @param qd
* @return Variant results of query?
*/
public static Variant getByQueryDef(Dispatch qd)
{
// get a reference to the recordset
Dispatch recset = Dispatch.call(qd, "OpenRecordset").toDispatch();
// get the values as a safe array
String[] cols = getColumns(recset);
for(int i=0;i<cols.length;i++)
{
System.out.print(cols[i]+" ");
}
System.out.println("");
Variant vals = getValues(recset);
return vals;
}
/**
* should return ?? for the passed in ??
*
* @param qd
* @return Variant results of query?
*/
public static Variant getByQueryDef(Dispatch qd) {
// get a reference to the recordset
Dispatch recset = Dispatch.call(qd, "OpenRecordset").toDispatch();
// get the values as a safe array
String[] cols = getColumns(recset);
for (int i = 0; i < cols.length; i++) {
System.out.print(cols[i] + " ");
}
System.out.println("");
Variant vals = getValues(recset);
return vals;
}
/**
* gets the columns form the rec set
* @param recset
* @return list of column names
*/
public static String[] getColumns(Dispatch recset)
{
Dispatch flds = Dispatch.get(recset, "Fields").toDispatch();
int n_flds = Dispatch.get(flds, "Count").getInt();
String[] s = new String[n_flds];
Variant vi = new Variant();
for (int i=0;i<n_flds;i++) {
vi.putInt(i);
// must use the invoke method because this is a method call
// that wants to have a Dispatch.Get flag...
Dispatch fld = Dispatch.invoke(recset, "Fields",
Dispatch.Get, new Object[] {vi}, new int[1]).toDispatch();
Variant name = Dispatch.get(fld, "Name");
s[i] = name.toString();
}
return s;
}
/**
* gets the columns form the rec set
*
* @param recset
* @return list of column names
*/
public static String[] getColumns(Dispatch recset) {
Dispatch flds = Dispatch.get(recset, "Fields").toDispatch();
int n_flds = Dispatch.get(flds, "Count").getInt();
String[] s = new String[n_flds];
Variant vi = new Variant();
for (int i = 0; i < n_flds; i++) {
vi.putInt(i);
// must use the invoke method because this is a method call
// that wants to have a Dispatch.Get flag...
Dispatch fld = Dispatch.invoke(recset, "Fields", Dispatch.Get,
new Object[] { vi }, new int[1]).toDispatch();
Variant name = Dispatch.get(fld, "Name");
s[i] = name.toString();
}
return s;
}
}

View File

@@ -1,120 +1,207 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Command extends Dispatch
{
public Command()
{
super("ADODB.Command");
}
/**
* Custom dispatch object to make it easy for us to provide application specific
* API.
*
*/
public class Command extends Dispatch {
/**
* standard constructor
*/
public Command() {
super("ADODB.Command");
}
/**
* This constructor is used instead of a case operation to
* turn a Dispatch object into a wider object - it must exist
* in every wrapper class whose instances may be returned from
* method calls wrapped in VT_DISPATCH Variants.
* This constructor is used instead of a case operation to turn a Dispatch
* object into a wider object - it must exist in every wrapper class whose
* instances may be returned from method calls wrapped in VT_DISPATCH
* Variants.
*
* @param dispatchTarget
*/
public Command(Dispatch dispatchTarget)
{
public Command(Dispatch dispatchTarget) {
super(dispatchTarget);
}
public Variant getProperties()
{
return Dispatch.get(this, "Properties");
}
/**
* runs the "Properties" command
*
* @return the properties
*/
public Variant getProperties() {
return Dispatch.get(this, "Properties");
}
public Connection getActiveConnection()
{
return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch());
}
/**
* runs the "ActiveConnection" command
*
* @return a Connection object
*/
public Connection getActiveConnection() {
return new Connection(Dispatch.get(this, "ActiveConnection")
.toDispatch());
}
public void setActiveConnection(Connection ppvObject)
{
Dispatch.put(this, "ActiveConnection", ppvObject);
}
/**
* Sets the "ActiveConnection" object
*
* @param ppvObject
* the new connection
*/
public void setActiveConnection(Connection ppvObject) {
Dispatch.put(this, "ActiveConnection", ppvObject);
}
public String getCommandText()
{
return Dispatch.get(this, "CommandText").toString();
}
/**
*
* @return the results from "CommandText"
*/
public String getCommandText() {
return Dispatch.get(this, "CommandText").toString();
}
public void setCommandText(String pbstr)
{
Dispatch.put(this, "CommandText", pbstr);
}
/**
*
* @param pbstr
* the new "CommandText"
*/
public void setCommandText(String pbstr) {
Dispatch.put(this, "CommandText", pbstr);
}
public int getCommandTimeout()
{
return Dispatch.get(this, "CommandTimeout").getInt();
}
/**
*
* @return the results of "CommandTimeout"
*/
public int getCommandTimeout() {
return Dispatch.get(this, "CommandTimeout").getInt();
}
public void setCommandTimeout(int plTimeout)
{
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
}
/**
*
* @param plTimeout
* the new "CommandTimeout"
*/
public void setCommandTimeout(int plTimeout) {
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
}
public boolean getPrepared()
{
return Dispatch.get(this, "Prepared").getBoolean();
}
/**
*
* @return results from "Prepared"
*/
public boolean getPrepared() {
return Dispatch.get(this, "Prepared").getBoolean();
}
public void setPrepared(boolean pfPrepared)
{
Dispatch.put(this, "Prepared", new Variant(pfPrepared));
}
/**
*
* @param pfPrepared
* the new value for "Prepared"
*/
public void setPrepared(boolean pfPrepared) {
Dispatch.put(this, "Prepared", new Variant(pfPrepared));
}
public Recordset Execute(Variant RecordsAffected, Variant Parameters, int Options)
{
return (Recordset)Dispatch.call(this, "Execute", RecordsAffected, Parameters, new Variant(Options)).toDispatch();
}
/**
* "Execute"s a command
*
* @param RecordsAffected
* @param Parameters
* @param Options
* @return
*/
public Recordset Execute(Variant RecordsAffected, Variant Parameters,
int Options) {
return (Recordset) Dispatch.call(this, "Execute", RecordsAffected,
Parameters, new Variant(Options)).toDispatch();
}
public Recordset Execute()
{
Variant dummy = new Variant();
return new Recordset(Dispatch.call(this, "Execute", dummy).toDispatch());
}
/**
* "Execute"s a command
*
* @return
*/
public Recordset Execute() {
Variant dummy = new Variant();
return new Recordset(Dispatch.call(this, "Execute", dummy).toDispatch());
}
public Variant CreateParameter(String Name, int Type, int Direction, int Size, Variant Value)
{
return Dispatch.call(this, "CreateParameter", Name, new Variant(Type), new Variant(Direction), new Variant(Size), Value);
}
/**
* creates a parameter
*
* @param Name
* @param Type
* @param Direction
* @param Size
* @param Value
* @return
*/
public Variant CreateParameter(String Name, int Type, int Direction,
int Size, Variant Value) {
return Dispatch.call(this, "CreateParameter", Name, new Variant(Type),
new Variant(Direction), new Variant(Size), Value);
}
// need to wrap Parameters
public Variant getParameters()
{
return Dispatch.get(this, "Parameters");
}
// need to wrap Parameters
/**
* @return "Parameters"
*/
public Variant getParameters() {
return Dispatch.get(this, "Parameters");
}
public void setCommandType(int plCmdType)
{
Dispatch.put(this, "CommandType", new Variant(plCmdType));
}
/**
*
* @param plCmdType
* new "CommandType"
*/
public void setCommandType(int plCmdType) {
Dispatch.put(this, "CommandType", new Variant(plCmdType));
}
public int getCommandType()
{
return Dispatch.get(this, "CommandType").getInt();
}
/**
*
* @return current "CommandType"
*/
public int getCommandType() {
return Dispatch.get(this, "CommandType").getInt();
}
public String getName()
{
return Dispatch.get(this, "Name").toString();
}
/**
*
* @return "Name"
*/
public String getName() {
return Dispatch.get(this, "Name").toString();
}
public void setName(String pbstrName)
{
Dispatch.put(this, "Name", pbstrName);
}
/**
*
* @param pbstrName
* new "Name"
*/
public void setName(String pbstrName) {
Dispatch.put(this, "Name", pbstrName);
}
public int getState()
{
return Dispatch.get(this, "State").getInt();
}
/**
*
* @return curent "State"
*/
public int getState() {
return Dispatch.get(this, "State").getInt();
}
public void Cancel()
{
Dispatch.call(this, "Cancel");
}
/**
* cancel whatever it is we're doing
*/
public void Cancel() {
Dispatch.call(this, "Cancel");
}
}

View File

@@ -2,13 +2,12 @@ package com.jacob.samples.ado;
// Enum: CommandTypeEnum
public interface CommandTypeEnum
{
public static final int adCmdUnspecified = -1;
public static final int adCmdUnknown = 8;
public static final int adCmdText = 1;
public static final int adCmdTable = 2;
public static final int adCmdStoredProc = 4;
public static final int adCmdFile = 256;
public static final int adCmdTableDirect = 512;
public interface CommandTypeEnum {
public static final int adCmdUnspecified = -1;
public static final int adCmdUnknown = 8;
public static final int adCmdText = 1;
public static final int adCmdTable = 2;
public static final int adCmdStoredProc = 4;
public static final int adCmdFile = 256;
public static final int adCmdTableDirect = 512;
}

View File

@@ -1,179 +1,151 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Connection extends Dispatch
{
public Connection()
{
super("ADODB.Connection");
}
public class Connection extends Dispatch {
public Connection() {
super("ADODB.Connection");
}
/**
* This constructor is used instead of a case operation to
* turn a Dispatch object into a wider object - it must exist
* in every wrapper class whose instances may be returned from
* method calls wrapped in VT_DISPATCH Variants.
* This constructor is used instead of a case operation to turn a Dispatch
* object into a wider object - it must exist in every wrapper class whose
* instances may be returned from method calls wrapped in VT_DISPATCH
* Variants.
*/
public Connection(Dispatch d)
{
public Connection(Dispatch d) {
super(d);
}
// need to wrap Properties
public Variant getProperties()
{
return Dispatch.get(this, "Properties");
}
// need to wrap Properties
public Variant getProperties() {
return Dispatch.get(this, "Properties");
}
public String getConnectionString()
{
return Dispatch.get(this, "ConnectionString").toString();
}
public String getConnectionString() {
return Dispatch.get(this, "ConnectionString").toString();
}
public void setConnectionString(String pbstr)
{
Dispatch.put(this, "ConnectionString", pbstr);
}
public void setConnectionString(String pbstr) {
Dispatch.put(this, "ConnectionString", pbstr);
}
public int getCommandTimeout()
{
return Dispatch.get(this, "CommandTimeout").getInt();
}
public int getCommandTimeout() {
return Dispatch.get(this, "CommandTimeout").getInt();
}
public void setCommandTimeout(int plTimeout)
{
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
}
public void setCommandTimeout(int plTimeout) {
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
}
public int getConnectionTimeout()
{
return Dispatch.get(this, "ConnectionTimeout").getInt();
}
public int getConnectionTimeout() {
return Dispatch.get(this, "ConnectionTimeout").getInt();
}
public void setConnectionTimeout(int plTimeout)
{
Dispatch.put(this, "ConnectionTimeout", new Variant(plTimeout));
}
public void setConnectionTimeout(int plTimeout) {
Dispatch.put(this, "ConnectionTimeout", new Variant(plTimeout));
}
public String getVersion()
{
return Dispatch.get(this, "Version").toString();
}
public String getVersion() {
return Dispatch.get(this, "Version").toString();
}
public void Close()
{
Dispatch.call(this, "Close");
}
public void Close() {
Dispatch.call(this, "Close");
}
// how to deal with RecordsAffected being output?
public Variant Execute(String CommandText, Variant RecordsAffected, int Options)
{
return Dispatch.call(this, CommandText, RecordsAffected, new Variant(Options));
}
// how to deal with RecordsAffected being output?
public Variant Execute(String CommandText, Variant RecordsAffected,
int Options) {
return Dispatch.call(this, CommandText, RecordsAffected, new Variant(
Options));
}
public int BeginTrans()
{
return Dispatch.call(this, "BeginTrans").getInt();
}
public int BeginTrans() {
return Dispatch.call(this, "BeginTrans").getInt();
}
public void CommitTrans()
{
Dispatch.call(this, "CommitTrans");
}
public void CommitTrans() {
Dispatch.call(this, "CommitTrans");
}
public void RollbackTrans()
{
Dispatch.call(this, "RollbackTrans");
}
public void RollbackTrans() {
Dispatch.call(this, "RollbackTrans");
}
public void Open(String ConnectionString, String UserID, String Password, int Options)
{
Dispatch.call(this, "Open", ConnectionString, UserID, Password, new Variant(Options));
}
public void Open(String ConnectionString, String UserID, String Password,
int Options) {
Dispatch.call(this, "Open", ConnectionString, UserID, Password,
new Variant(Options));
}
public void Open()
{
Dispatch.call(this, "Open");
}
public void Open() {
Dispatch.call(this, "Open");
}
public Variant getErrors()
{
return Dispatch.get(this, "Errors");
}
public Variant getErrors() {
return Dispatch.get(this, "Errors");
}
public String getDefaultDatabase()
{
return Dispatch.get(this, "DefaultDatabase").toString();
}
public String getDefaultDatabase() {
return Dispatch.get(this, "DefaultDatabase").toString();
}
public void setDefaultDatabase(String pbstr)
{
Dispatch.put(this, "DefaultDatabase", pbstr);
}
public void setDefaultDatabase(String pbstr) {
Dispatch.put(this, "DefaultDatabase", pbstr);
}
public int getIsolationLevel()
{
return Dispatch.get(this, "IsolationLevel").getInt();
}
public int getIsolationLevel() {
return Dispatch.get(this, "IsolationLevel").getInt();
}
public void setIsolationLevel(int Level)
{
Dispatch.put(this, "IsolationLevel", new Variant(Level));
}
public void setIsolationLevel(int Level) {
Dispatch.put(this, "IsolationLevel", new Variant(Level));
}
public int getAttributes()
{
return Dispatch.get(this, "Attributes").getInt();
}
public int getAttributes() {
return Dispatch.get(this, "Attributes").getInt();
}
public void setAttributes(int plAttr)
{
Dispatch.put(this, "Attributes", new Variant(plAttr));
}
public void setAttributes(int plAttr) {
Dispatch.put(this, "Attributes", new Variant(plAttr));
}
public int getCursorLocation()
{
return Dispatch.get(this, "CursorLocation").getInt();
}
public int getCursorLocation() {
return Dispatch.get(this, "CursorLocation").getInt();
}
public void setCursorLocation(int plCursorLoc)
{
Dispatch.put(this, "CursorLocation", new Variant(plCursorLoc));
}
public void setCursorLocation(int plCursorLoc) {
Dispatch.put(this, "CursorLocation", new Variant(plCursorLoc));
}
public int getMode()
{
return Dispatch.get(this, "Mode").getInt();
}
public int getMode() {
return Dispatch.get(this, "Mode").getInt();
}
public void setMode(int plMode)
{
Dispatch.put(this, "Mode", new Variant(plMode));
}
public void setMode(int plMode) {
Dispatch.put(this, "Mode", new Variant(plMode));
}
public String getProvider()
{
return Dispatch.get(this, "Provider").toString();
}
public String getProvider() {
return Dispatch.get(this, "Provider").toString();
}
public void setProvider(String pbstr)
{
Dispatch.put(this, "Provider", pbstr);
}
public void setProvider(String pbstr) {
Dispatch.put(this, "Provider", pbstr);
}
public int getState()
{
return Dispatch.get(this, "State").getInt();
}
public int getState() {
return Dispatch.get(this, "State").getInt();
}
public Variant OpenSchema(int Schema, Variant Restrictions, Variant SchemaID)
{
return Dispatch.call(this, "OpenSchema", new Variant(Schema), Restrictions, SchemaID);
}
public Variant OpenSchema(int Schema, Variant Restrictions, Variant SchemaID) {
return Dispatch.call(this, "OpenSchema", new Variant(Schema),
Restrictions, SchemaID);
}
public void Cancel()
{
Dispatch.call(this, "Cancel");
}
public void Cancel() {
Dispatch.call(this, "Cancel");
}
}

View File

@@ -1,122 +1,101 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
public class Field extends Dispatch
{
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Field extends Dispatch {
/**
* This constructor is used instead of a case operation to
* turn a Dispatch object into a wider object - it must exist
* in every wrapper class whose instances may be returned from
* method calls wrapped in VT_DISPATCH Variants.
* This constructor is used instead of a case operation to turn a Dispatch
* object into a wider object - it must exist in every wrapper class whose
* instances may be returned from method calls wrapped in VT_DISPATCH
* Variants.
*/
public Field(Dispatch d)
{
public Field(Dispatch d) {
super(d);
}
public Variant getProperties()
{
return Dispatch.get(this, "Properties");
}
public int getActualSize()
{
return Dispatch.get(this, "ActualSize").getInt();
public Variant getProperties() {
return Dispatch.get(this, "Properties");
}
public int getAttributes()
{
return Dispatch.get(this, "Attributes").getInt();
public int getActualSize() {
return Dispatch.get(this, "ActualSize").getInt();
}
public int getDefinedSize()
{
return Dispatch.get(this, "DefinedSize").getInt();
public int getAttributes() {
return Dispatch.get(this, "Attributes").getInt();
}
public String getName()
{
return Dispatch.get(this, "Name").toString();
public int getDefinedSize() {
return Dispatch.get(this, "DefinedSize").getInt();
}
public int getType()
{
return Dispatch.get(this, "Type").getInt();
public String getName() {
return Dispatch.get(this, "Name").toString();
}
public Variant getValue()
{
return Dispatch.get(this, "Value");
public int getType() {
return Dispatch.get(this, "Type").getInt();
}
public void setValue(Variant pvar)
{
Dispatch.put(this, "Value", pvar);
public Variant getValue() {
return Dispatch.get(this, "Value");
}
public byte getPrecision()
{
return Dispatch.get(this, "Precision").getByte();
public void setValue(Variant pvar) {
Dispatch.put(this, "Value", pvar);
}
public byte getNumericScale()
{
return Dispatch.get(this, "NumericScale").getByte();
public byte getPrecision() {
return Dispatch.get(this, "Precision").getByte();
}
public void AppendChunk(Variant Data)
{
Dispatch.call(this, "AppendChunk", Data);
public byte getNumericScale() {
return Dispatch.get(this, "NumericScale").getByte();
}
public Variant GetChunk(int Length)
{
return Dispatch.call(this, "GetChunk", new Variant(Length));
public void AppendChunk(Variant Data) {
Dispatch.call(this, "AppendChunk", Data);
}
public Variant getOriginalValue()
{
return Dispatch.get(this, "OriginalValue");
public Variant GetChunk(int Length) {
return Dispatch.call(this, "GetChunk", new Variant(Length));
}
public Variant getUnderlyingValue()
{
return Dispatch.get(this, "UnderlyingValue");
public Variant getOriginalValue() {
return Dispatch.get(this, "OriginalValue");
}
public Variant getDataFormat()
{
return Dispatch.get(this, "DataFormat");
public Variant getUnderlyingValue() {
return Dispatch.get(this, "UnderlyingValue");
}
public void setDataFormat(Variant ppiDF)
{
Dispatch.put(this, "DataFormat", ppiDF);
public Variant getDataFormat() {
return Dispatch.get(this, "DataFormat");
}
public void setPrecision(byte pb)
{
Dispatch.put(this, "Precision", new Variant(pb));
public void setDataFormat(Variant ppiDF) {
Dispatch.put(this, "DataFormat", ppiDF);
}
public void setNumericScale(byte pb)
{
Dispatch.put(this, "NumericScale", new Variant(pb));
public void setPrecision(byte pb) {
Dispatch.put(this, "Precision", new Variant(pb));
}
public void setType(int pDataType)
{
Dispatch.put(this, "Type", new Variant(pDataType));
public void setNumericScale(byte pb) {
Dispatch.put(this, "NumericScale", new Variant(pb));
}
public void setDefinedSize(int pl)
{
Dispatch.put(this, "DefinedSize", new Variant(pl));
public void setType(int pDataType) {
Dispatch.put(this, "Type", new Variant(pDataType));
}
public void setAttributes(int pl)
{
Dispatch.put(this, "Attributes", new Variant(pl));
public void setDefinedSize(int pl) {
Dispatch.put(this, "DefinedSize", new Variant(pl));
}
public void setAttributes(int pl) {
Dispatch.put(this, "Attributes", new Variant(pl));
}
}

View File

@@ -1,48 +1,43 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
public class Fields extends Dispatch
{
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Fields extends Dispatch {
/**
* This constructor is used instead of a case operation to
* turn a Dispatch object into a wider object - it must exist
* in every wrapper class whose instances may be returned from
* method calls wrapped in VT_DISPATCH Variants.
* This constructor is used instead of a case operation to turn a Dispatch
* object into a wider object - it must exist in every wrapper class whose
* instances may be returned from method calls wrapped in VT_DISPATCH
* Variants.
*/
public Fields(Dispatch d)
{
public Fields(Dispatch d) {
super(d);
}
public int getCount()
{
return Dispatch.get(this, "Count").getInt();
public int getCount() {
return Dispatch.get(this, "Count").getInt();
}
public Variant _NewEnum()
{
return Dispatch.call(this, "_NewEnum");
public Variant _NewEnum() {
return Dispatch.call(this, "_NewEnum");
}
public void Refresh()
{
Dispatch.call(this, "Refresh");
public void Refresh() {
Dispatch.call(this, "Refresh");
}
public Field getItem(int Index)
{
return new Field(Dispatch.call(this, "Item", new Variant(Index)).toDispatch());
public Field getItem(int Index) {
return new Field(Dispatch.call(this, "Item", new Variant(Index))
.toDispatch());
}
public void Append(String Name, int Type, int DefinedSize, int Attrib)
{
Dispatch.call(this, "Append", Name, new Variant(Type),
new Variant(DefinedSize), new Variant(Attrib));
public void Append(String Name, int Type, int DefinedSize, int Attrib) {
Dispatch.call(this, "Append", Name, new Variant(Type), new Variant(
DefinedSize), new Variant(Attrib));
}
public void Delete(Variant Index)
{
Dispatch.call(this, "Delete", Index);
public void Delete(Variant Index) {
Dispatch.call(this, "Delete", Index);
}
}

View File

@@ -1,409 +1,342 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
public class Recordset extends Dispatch
{
public Recordset()
{
super("ADODB.Recordset");
}
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Recordset extends Dispatch {
public Recordset() {
super("ADODB.Recordset");
}
/**
* This constructor is used instead of a case operation to
* turn a Dispatch object into a wider object - it must exist
* in every wrapper class whose instances may be returned from
* method calls wrapped in VT_DISPATCH Variants.
* This constructor is used instead of a case operation to turn a Dispatch
* object into a wider object - it must exist in every wrapper class whose
* instances may be returned from method calls wrapped in VT_DISPATCH
* Variants.
*/
public Recordset(Dispatch d)
{
public Recordset(Dispatch d) {
super(d);
}
public Variant getProperties()
{
return Dispatch.get(this, "Properties");
}
public int getAbsolutePosition()
{
return Dispatch.get(this, "AbsolutePosition").getInt();
public Variant getProperties() {
return Dispatch.get(this, "Properties");
}
public void setAbsolutePosition(int pl)
{
Dispatch.put(this, "AbsolutePosition", new Variant(pl));
public int getAbsolutePosition() {
return Dispatch.get(this, "AbsolutePosition").getInt();
}
public Connection getActiveConnection()
{
return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch());
}
public void setActiveConnection(Connection ppvObject)
{
Dispatch.put(this, "ActiveConnection", ppvObject);
}
public void setActiveConnection(Variant ppvObject)
{
Dispatch.put(this, "ActiveConnection", ppvObject);
}
public boolean getBOF()
{
return Dispatch.get(this, "BOF").getBoolean();
public void setAbsolutePosition(int pl) {
Dispatch.put(this, "AbsolutePosition", new Variant(pl));
}
public Variant getBookmark()
{
return Dispatch.get(this, "Bookmark");
public Connection getActiveConnection() {
return new Connection(Dispatch.get(this, "ActiveConnection")
.toDispatch());
}
public void setBookmark(Variant pvBookmark)
{
Dispatch.put(this, "Bookmark", pvBookmark);
public void setActiveConnection(Connection ppvObject) {
Dispatch.put(this, "ActiveConnection", ppvObject);
}
public int getCacheSize()
{
return Dispatch.get(this, "CacheSize").getInt();
public void setActiveConnection(Variant ppvObject) {
Dispatch.put(this, "ActiveConnection", ppvObject);
}
public void setCacheSize(int pl)
{
Dispatch.put(this, "CacheSize", new Variant(pl));
public boolean getBOF() {
return Dispatch.get(this, "BOF").getBoolean();
}
public int getCursorType()
{
return Dispatch.get(this, "CursorType").getInt();
public Variant getBookmark() {
return Dispatch.get(this, "Bookmark");
}
public void setCursorType(int pl)
{
Dispatch.put(this, "CursorType", new Variant(pl));
public void setBookmark(Variant pvBookmark) {
Dispatch.put(this, "Bookmark", pvBookmark);
}
public boolean getEOF()
{
return Dispatch.get(this, "EOF").getBoolean();
}
public Fields getFields()
{
return new Fields(Dispatch.get(this, "Fields").toDispatch());
public int getCacheSize() {
return Dispatch.get(this, "CacheSize").getInt();
}
public int getLockType()
{
return Dispatch.get(this, "LockType").getInt();
public void setCacheSize(int pl) {
Dispatch.put(this, "CacheSize", new Variant(pl));
}
public void setLockType(int plLockType)
{
Dispatch.put(this, "LockType", new Variant(plLockType));
public int getCursorType() {
return Dispatch.get(this, "CursorType").getInt();
}
public int getMaxRecords()
{
return Dispatch.get(this, "MaxRecords").getInt();
public void setCursorType(int pl) {
Dispatch.put(this, "CursorType", new Variant(pl));
}
public void setMaxRecords(int pl)
{
Dispatch.put(this, "MaxRecords", new Variant(pl));
public boolean getEOF() {
return Dispatch.get(this, "EOF").getBoolean();
}
public int getRecordCount()
{
return Dispatch.get(this, "RecordCount").getInt();
public Fields getFields() {
return new Fields(Dispatch.get(this, "Fields").toDispatch());
}
public void setSource(Object pvSource)
{
Dispatch.put(this, "Source", pvSource);
public int getLockType() {
return Dispatch.get(this, "LockType").getInt();
}
public void setSource(String pvSource)
{
Dispatch.put(this, "Source", pvSource);
public void setLockType(int plLockType) {
Dispatch.put(this, "LockType", new Variant(plLockType));
}
public Variant getSource()
{
return Dispatch.get(this, "Source");
public int getMaxRecords() {
return Dispatch.get(this, "MaxRecords").getInt();
}
public void AddNew(Variant FieldList, Variant Values)
{
Dispatch.call(this, "AddNew", FieldList, Values);
public void setMaxRecords(int pl) {
Dispatch.put(this, "MaxRecords", new Variant(pl));
}
public void CancelUpdate()
{
Dispatch.call(this, "CancelUpdate");
public int getRecordCount() {
return Dispatch.get(this, "RecordCount").getInt();
}
public void Close()
{
Dispatch.call(this, "Close");
public void setSource(Object pvSource) {
Dispatch.put(this, "Source", pvSource);
}
public void Delete(int AffectRecords)
{
Dispatch.call(this, "Delete", new Variant(AffectRecords));
public void setSource(String pvSource) {
Dispatch.put(this, "Source", pvSource);
}
public Variant GetRows(int Rows, Variant Start, Variant Fields)
{
return Dispatch.call(this, "GetRows", new Variant(Rows), Start, Fields);
public Variant getSource() {
return Dispatch.get(this, "Source");
}
public void AddNew(Variant FieldList, Variant Values) {
Dispatch.call(this, "AddNew", FieldList, Values);
}
public void CancelUpdate() {
Dispatch.call(this, "CancelUpdate");
}
public void Close() {
Dispatch.call(this, "Close");
}
public void Delete(int AffectRecords) {
Dispatch.call(this, "Delete", new Variant(AffectRecords));
}
public Variant GetRows(int Rows, Variant Start, Variant Fields) {
return Dispatch.call(this, "GetRows", new Variant(Rows), Start, Fields);
}
// get all rows
public Variant GetRows()
{
return Dispatch.call(this, "GetRows");
public Variant GetRows() {
return Dispatch.call(this, "GetRows");
}
public void Move(int NumRecords, Variant Start)
{
Dispatch.call(this, "Move", new Variant(NumRecords), Start);
public void Move(int NumRecords, Variant Start) {
Dispatch.call(this, "Move", new Variant(NumRecords), Start);
}
public void MoveNext()
{
Dispatch.call(this, "MoveNext");
public void MoveNext() {
Dispatch.call(this, "MoveNext");
}
public void MovePrevious()
{
Dispatch.call(this, "MovePrevious");
public void MovePrevious() {
Dispatch.call(this, "MovePrevious");
}
public void MoveFirst()
{
Dispatch.call(this, "MoveFirst");
public void MoveFirst() {
Dispatch.call(this, "MoveFirst");
}
public void MoveLast()
{
Dispatch.call(this, "MoveLast");
public void MoveLast() {
Dispatch.call(this, "MoveLast");
}
public void Open(Variant Source, Variant ActiveConnection, int CursorType, int LockType, int Options)
{
Dispatch.call(this, "Open", Source, ActiveConnection, new Variant(CursorType), new Variant(LockType), new Variant(Options));
public void Open(Variant Source, Variant ActiveConnection, int CursorType,
int LockType, int Options) {
Dispatch.call(this, "Open", Source, ActiveConnection, new Variant(
CursorType), new Variant(LockType), new Variant(Options));
}
public void Open(Variant Source, Variant ActiveConnection)
{
Dispatch.call(this, "Open", Source, ActiveConnection);
public void Open(Variant Source, Variant ActiveConnection) {
Dispatch.call(this, "Open", Source, ActiveConnection);
}
public void Requery(int Options)
{
Dispatch.call(this, "Requery", new Variant(Options));
public void Requery(int Options) {
Dispatch.call(this, "Requery", new Variant(Options));
}
public void Update(Variant Fields, Variant Values)
{
Dispatch.call(this, "Update", Fields, Values);
public void Update(Variant Fields, Variant Values) {
Dispatch.call(this, "Update", Fields, Values);
}
public int getAbsolutePage()
{
return Dispatch.get(this, "AbsolutePage").getInt();
public int getAbsolutePage() {
return Dispatch.get(this, "AbsolutePage").getInt();
}
public void setAbsolutePage(int pl)
{
Dispatch.put(this, "AbsolutePage", new Variant(pl));
public void setAbsolutePage(int pl) {
Dispatch.put(this, "AbsolutePage", new Variant(pl));
}
public int getEditMode()
{
return Dispatch.get(this, "EditMode").getInt();
public int getEditMode() {
return Dispatch.get(this, "EditMode").getInt();
}
public Variant getFilter()
{
return Dispatch.get(this, "Filter");
public Variant getFilter() {
return Dispatch.get(this, "Filter");
}
public void setFilter(Variant Criteria)
{
Dispatch.put(this, "Filter", Criteria);
public void setFilter(Variant Criteria) {
Dispatch.put(this, "Filter", Criteria);
}
public int getPageCount()
{
return Dispatch.get(this, "PageCount").getInt();
public int getPageCount() {
return Dispatch.get(this, "PageCount").getInt();
}
public int getPageSize()
{
return Dispatch.get(this, "PageSize").getInt();
public int getPageSize() {
return Dispatch.get(this, "PageSize").getInt();
}
public void setPageSize(int pl)
{
Dispatch.put(this, "PageSize", new Variant(pl));
public void setPageSize(int pl) {
Dispatch.put(this, "PageSize", new Variant(pl));
}
public String getSort()
{
return Dispatch.get(this, "Sort").toString();
public String getSort() {
return Dispatch.get(this, "Sort").toString();
}
public void setSort(String Criteria)
{
Dispatch.put(this, "Sort", Criteria);
public void setSort(String Criteria) {
Dispatch.put(this, "Sort", Criteria);
}
public int getStatus()
{
return Dispatch.get(this, "Status").getInt();
public int getStatus() {
return Dispatch.get(this, "Status").getInt();
}
public int getState()
{
return Dispatch.get(this, "State").getInt();
public int getState() {
return Dispatch.get(this, "State").getInt();
}
public void UpdateBatch(int AffectRecords)
{
Dispatch.call(this, "UpdateBatch", new Variant(AffectRecords));
public void UpdateBatch(int AffectRecords) {
Dispatch.call(this, "UpdateBatch", new Variant(AffectRecords));
}
public void CancelBatch(int AffectRecords)
{
Dispatch.call(this, "CancelBatch", new Variant(AffectRecords));
public void CancelBatch(int AffectRecords) {
Dispatch.call(this, "CancelBatch", new Variant(AffectRecords));
}
public int getCursorLocation()
{
return Dispatch.get(this, "CursorLocation").getInt();
public int getCursorLocation() {
return Dispatch.get(this, "CursorLocation").getInt();
}
public void setCursorLocation(int pl)
{
Dispatch.put(this, "CursorLocation", new Variant(pl));
public void setCursorLocation(int pl) {
Dispatch.put(this, "CursorLocation", new Variant(pl));
}
public Recordset NextRecordset(Variant RecordsAffected)
{
return new Recordset(Dispatch.call(this, "NextRecordset", RecordsAffected).toDispatch());
public Recordset NextRecordset(Variant RecordsAffected) {
return new Recordset(Dispatch.call(this, "NextRecordset",
RecordsAffected).toDispatch());
}
public boolean Supports(int CursorOptions)
{
return Dispatch.call(this, "Supports", new Variant(CursorOptions)).getBoolean();
public boolean Supports(int CursorOptions) {
return Dispatch.call(this, "Supports", new Variant(CursorOptions))
.getBoolean();
}
public Variant getCollect(Variant Index)
{
return Dispatch.get(this, "Collect");
public Variant getCollect(Variant Index) {
return Dispatch.get(this, "Collect");
}
public void setCollect(Variant Index, Variant pvar)
{
Dispatch.call(this, "Collect", Index, pvar);
public void setCollect(Variant Index, Variant pvar) {
Dispatch.call(this, "Collect", Index, pvar);
}
public int getMarshalOptions()
{
return Dispatch.get(this, "MarshalOptions").getInt();
public int getMarshalOptions() {
return Dispatch.get(this, "MarshalOptions").getInt();
}
public void setMarshalOptions(int pl)
{
Dispatch.put(this, "MarshalOptions", new Variant(pl));
}
public void Find(String Criteria, int SkipRecords, int SearchDirection, Variant Start)
{
Dispatch.call(this, "Find", Criteria, new Variant(SkipRecords), new Variant(SearchDirection), Start);
public void setMarshalOptions(int pl) {
Dispatch.put(this, "MarshalOptions", new Variant(pl));
}
public void Cancel()
{
Dispatch.call(this, "Cancel");
public void Find(String Criteria, int SkipRecords, int SearchDirection,
Variant Start) {
Dispatch.call(this, "Find", Criteria, new Variant(SkipRecords),
new Variant(SearchDirection), Start);
}
public Variant getDataSource()
{
return Dispatch.get(this, "DataSource");
public void Cancel() {
Dispatch.call(this, "Cancel");
}
public void setDataSource(Variant ppunkDataSource)
{
Dispatch.put(this, "DataSource", ppunkDataSource);
public Variant getDataSource() {
return Dispatch.get(this, "DataSource");
}
public void Save(String FileName, int PersistFormat)
{
Dispatch.call(this, "Save", FileName, new Variant(PersistFormat));
public void setDataSource(Variant ppunkDataSource) {
Dispatch.put(this, "DataSource", ppunkDataSource);
}
public Variant getActiveCommand()
{
return Dispatch.get(this, "ActiveCommand");
public void Save(String FileName, int PersistFormat) {
Dispatch.call(this, "Save", FileName, new Variant(PersistFormat));
}
public void setStayInSync(boolean pb)
{
Dispatch.put(this, "StayInSync", new Variant(pb));
public Variant getActiveCommand() {
return Dispatch.get(this, "ActiveCommand");
}
public boolean getStayInSync()
{
return Dispatch.get(this, "StayInSync").getBoolean();
public void setStayInSync(boolean pb) {
Dispatch.put(this, "StayInSync", new Variant(pb));
}
public String GetString(int StringFormat, int NumRows, String ColumnDelimeter, String RowDelimeter, String NullExpr)
{
return Dispatch.call(this, "GetString", new Variant(StringFormat),
new Variant(NumRows), ColumnDelimeter, RowDelimeter, NullExpr).toString();
public boolean getStayInSync() {
return Dispatch.get(this, "StayInSync").getBoolean();
}
public String getDataMember()
{
return Dispatch.get(this, "DataMember").toString();
public String GetString(int StringFormat, int NumRows,
String ColumnDelimeter, String RowDelimeter, String NullExpr) {
return Dispatch.call(this, "GetString", new Variant(StringFormat),
new Variant(NumRows), ColumnDelimeter, RowDelimeter, NullExpr)
.toString();
}
public void setDataMember(String pl)
{
Dispatch.put(this, "DataMember", new Variant(pl));
public String getDataMember() {
return Dispatch.get(this, "DataMember").toString();
}
public int CompareBookmarks(Variant Bookmark1, Variant Bookmark2)
{
return Dispatch.call(this, "CompareBookmarks", Bookmark1, Bookmark2).getInt();
public void setDataMember(String pl) {
Dispatch.put(this, "DataMember", new Variant(pl));
}
public Recordset Clone(int LockType)
{
return new Recordset(Dispatch.call(this, "Clone",
new Variant(LockType)).toDispatch());
public int CompareBookmarks(Variant Bookmark1, Variant Bookmark2) {
return Dispatch.call(this, "CompareBookmarks", Bookmark1, Bookmark2)
.getInt();
}
public void Resync(int AffectRecords, int ResyncValues)
{
Dispatch.call(this, "Resync", new Variant(AffectRecords), new Variant(ResyncValues));
public Recordset Clone(int LockType) {
return new Recordset(Dispatch
.call(this, "Clone", new Variant(LockType)).toDispatch());
}
public void Seek(Variant KeyValues, int SeekOption)
{
Dispatch.call(this, "Seek", KeyValues, new Variant(SeekOption));
public void Resync(int AffectRecords, int ResyncValues) {
Dispatch.call(this, "Resync", new Variant(AffectRecords), new Variant(
ResyncValues));
}
public void setIndex(String pl)
{
Dispatch.put(this, "Index", new Variant(pl));
public void Seek(Variant KeyValues, int SeekOption) {
Dispatch.call(this, "Seek", KeyValues, new Variant(SeekOption));
}
public String getIndex()
{
return Dispatch.get(this, "Index)").toString();
public void setIndex(String pl) {
Dispatch.put(this, "Index", new Variant(pl));
}
public String getIndex() {
return Dispatch.get(this, "Index)").toString();
}
}

View File

@@ -1,63 +1,56 @@
package com.jacob.samples.ado;
import com.jacob.com.*;
public class test
{
public static void printRS(Recordset rs)
{
Fields fs = rs.getFields();
import com.jacob.com.Variant;
for (int i=0;i<fs.getCount();i++)
{
System.out.print(fs.getItem(i).getName() + " ");
}
System.out.println("");
public class test {
public static void printRS(Recordset rs) {
Fields fs = rs.getFields();
rs.MoveFirst();
while (!rs.getEOF())
{
for(int i=0;i<fs.getCount();i++)
{
Field f = fs.getItem(i);
Variant v = f.getValue();
System.out.print(v + " ");
}
System.out.println("");
rs.MoveNext();
}
}
for (int i = 0; i < fs.getCount(); i++) {
System.out.print(fs.getItem(i).getName() + " ");
}
System.out.println("");
rs.MoveFirst();
while (!rs.getEOF()) {
for (int i = 0; i < fs.getCount(); i++) {
Field f = fs.getItem(i);
Variant v = f.getValue();
System.out.print(v + " ");
}
System.out.println("");
rs.MoveNext();
}
}
// open a recordset directly
public static void getRS(String con, String query)
{
System.out.println("Recordset Open");
public static void getRS(String con, String query) {
System.out.println("Recordset Open");
Recordset rs = new Recordset();
rs.Open(new Variant(query), new Variant(con));
printRS(rs);
printRS(rs);
}
// create connection and command objects and use them
// to get a recordset
public static void getCommand(String con, String query)
{
System.out.println("Command+Connection -> Recordset");
Connection c = new Connection();
c.setConnectionString(con);
c.Open();
Command comm = new Command();
comm.setActiveConnection(c);
comm.setCommandType(CommandTypeEnum.adCmdText);
comm.setCommandText(query);
Recordset rs = comm.Execute();
printRS(rs);
c.Close();
public static void getCommand(String con, String query) {
System.out.println("Command+Connection -> Recordset");
Connection c = new Connection();
c.setConnectionString(con);
c.Open();
Command comm = new Command();
comm.setActiveConnection(c);
comm.setCommandType(CommandTypeEnum.adCmdText);
comm.setCommandText(query);
Recordset rs = comm.Execute();
printRS(rs);
c.Close();
}
public static void main(String[] args)
{
String connectStr = "DRIVER=SQL Server;SERVER=DANADLER;UID=sa;PWD=;WSID=DANADLER;DATABASE=pubs";
String queryStr = "select * from authors";
getCommand(connectStr, queryStr);
getRS(connectStr, queryStr);
public static void main(String[] args) {
String connectStr = "DRIVER=SQL Server;SERVER=DANADLER;UID=sa;PWD=;WSID=DANADLER;DATABASE=pubs";
String queryStr = "select * from authors";
getCommand(connectStr, queryStr);
getRS(connectStr, queryStr);
}
}

View File

@@ -1,11 +1,15 @@
package com.jacob.samples.applet;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.applet.Applet;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.jacob.com.*;
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* Applet test case
@@ -38,7 +42,9 @@ public class AppTest extends Applet implements ActionListener {
/**
* action method that receives button actions
* @param ev the event
*
* @param ev
* the event
*/
public void actionPerformed(ActionEvent ev) {
if (sC == null) {

View File

@@ -1,14 +1,23 @@
package com.jacob.samples.atl;
import com.jacob.com.*;
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
class MultiFaceTest {
/**
* standard main() test program
*
* @param args
* the command line arguments
*/
public static void main(String[] args) {
// this method has been deprecated as being unreliable.
// shutdown should be done through other means
// whoever wrote this example should explain what this was intended to do
//System.runFinalizersOnExit(true);
// whoever wrote this example should explain what this was intended to
// do
// System.runFinalizersOnExit(true);
ActiveXComponent mf = new ActiveXComponent("MultiFace.Face");
try {

View File

@@ -1,46 +1,52 @@
package com.jacob.samples.office;
import com.jacob.com.*;
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* Sample test program snagged out of a question on the sun discussion area.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ExcelDispatchTest {
public static void main(String[] args)
{
ComThread.InitSTA();
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
try {
System.out.println("version="+xl.getProperty("Version"));
System.out.println("version="+Dispatch.get(xl, "Version"));
Dispatch.put(xl, "Visible", new Variant(true));
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
Dispatch workbook = Dispatch.get(workbooks,"Add").toDispatch();
Dispatch sheet = Dispatch.get(workbook,"ActiveSheet").toDispatch();
Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] {"A1"},
new int[1]).toDispatch();
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] {"A2"},
new int[1]).toDispatch();
Dispatch.put(a1, "Value", "123.456");
Dispatch.put(a2, "Formula", "=A1*2");
System.out.println("a1 from excel:"+Dispatch.get(a1, "Value"));
System.out.println("a2 from excel:"+Dispatch.get(a2, "Value"));
Variant f = new Variant(false);
Dispatch.call(workbook, "Close", f);
} catch (Exception e) {
e.printStackTrace();
} finally {
xl.invoke("Quit", new Variant[] {});
ComThread.Release();
}
}
/**
* main run loop for test program
*
* @param args
* standard command line arguments
*/
public static void main(String[] args) {
ComThread.InitSTA();
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
try {
System.out.println("version=" + xl.getProperty("Version"));
System.out.println("version=" + Dispatch.get(xl, "Version"));
Dispatch.put(xl, "Visible", new Variant(true));
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
Dispatch workbook = Dispatch.get(workbooks, "Add").toDispatch();
Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { "A1" }, new int[1]).toDispatch();
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { "A2" }, new int[1]).toDispatch();
Dispatch.put(a1, "Value", "123.456");
Dispatch.put(a2, "Formula", "=A1*2");
System.out.println("a1 from excel:" + Dispatch.get(a1, "Value"));
System.out.println("a2 from excel:" + Dispatch.get(a2, "Value"));
Variant f = new Variant(false);
Dispatch.call(workbook, "Close", f);
} catch (Exception e) {
e.printStackTrace();
} finally {
xl.invoke("Quit", new Variant[] {});
ComThread.Release();
}
}
}

View File

@@ -7,8 +7,7 @@ import com.jacob.com.Dispatch;
/**
* Snippet to show Visio print dialog
* <p>
* Sample submitted by fatbuttlarry in SourceForge 1803140
* as part of bug report
* Sample submitted by fatbuttlarry in SourceForge 1803140 as part of bug report
* <p>
* Tested with Java 6.0SE and MS Office 2003 ** Note: 1010 = VB's
* visCmdFilePrint constant
@@ -26,8 +25,7 @@ public class VisioPrintTest {
// create a blank document
Dispatch.call(oDocuments, "Add", "");
try {
Dispatch.call(oActiveX, "DoCmd", new Integer(1010))
.getInt();
Dispatch.call(oActiveX, "DoCmd", new Integer(1010)).getInt();
System.out.println("User hit the ok button.");
} catch (ComFailException e) {
System.out.println("User hit the cancel button: " + e);
@@ -37,7 +35,12 @@ public class VisioPrintTest {
return;
}
/** quick main() to test this */
/**
* quick main() to test this
*
* @param args
* standard command line arguments
*/
public static void main(String[] args) {
VisioPrintTest testObject = new VisioPrintTest();
testObject.testPrintDialog();

View File

@@ -14,150 +14,152 @@ import com.jacob.com.Variant;
* are sections that could be enhanced
*/
public class WordDocumentProperties {
//Declare word object
private ActiveXComponent objWord;
// Declare word object
private ActiveXComponent objWord;
//Declare Word Properties
private Dispatch custDocprops;
// Declare Word Properties
private Dispatch custDocprops;
private Dispatch builtInDocProps;
private Dispatch builtInDocProps;
//the doucments object is important in any real app but this demo doesn't use it
//private Dispatch documents;
// the doucments object is important in any real app but this demo doesn't
// use it
// private Dispatch documents;
private Dispatch document;
private Dispatch document;
private Dispatch wordObject;
private Dispatch wordObject;
/**
* Empty Constructor
*
*/
public WordDocumentProperties() {
}
/**
* Empty Constructor
*
*/
public WordDocumentProperties() {
}
/**
* Opens a document
*
* @param filename
*/
public void open(String filename) {
//Instantiate objWord
objWord = new ActiveXComponent("Word.Application");
/**
* Opens a document
*
* @param filename
*/
public void open(String filename) {
// Instantiate objWord
objWord = new ActiveXComponent("Word.Application");
//Assign a local word object
wordObject = objWord.getObject();
// Assign a local word object
wordObject = objWord.getObject();
//Create a Dispatch Parameter to hide the document that is opened
Dispatch.put((Dispatch) wordObject, "Visible", new Variant(false));
// Create a Dispatch Parameter to hide the document that is opened
Dispatch.put(wordObject, "Visible", new Variant(false));
//Instantiate the Documents Property
Dispatch documents = objWord.getProperty("Documents").toDispatch();
// Instantiate the Documents Property
Dispatch documents = objWord.getProperty("Documents").toDispatch();
//Open a word document, Current Active Document
document = Dispatch.call(documents, "Open", filename).toDispatch();
}
// Open a word document, Current Active Document
document = Dispatch.call(documents, "Open", filename).toDispatch();
}
/**
* Creates an instance of the VBA CustomDocumentProperties property
*
*/
public void selectCustomDocumentProperitiesMode() {
//Create CustomDocumentProperties and BuiltInDocumentProperties
// properties
custDocprops = Dispatch.get(document, "CustomDocumentProperties")
.toDispatch();
}
/**
* Creates an instance of the VBA CustomDocumentProperties property
*
*/
public void selectCustomDocumentProperitiesMode() {
// Create CustomDocumentProperties and BuiltInDocumentProperties
// properties
custDocprops = Dispatch.get(document, "CustomDocumentProperties")
.toDispatch();
}
/**
* Creates an instance of the VBA BuiltInDocumentProperties property
*
*/
public void selectBuiltinPropertiesMode() {
//Create CustomDocumentProperties and BuiltInDocumentProperties
// properties
builtInDocProps = Dispatch.get(document, "BuiltInDocumentProperties")
.toDispatch();
}
/**
* Creates an instance of the VBA BuiltInDocumentProperties property
*
*/
public void selectBuiltinPropertiesMode() {
// Create CustomDocumentProperties and BuiltInDocumentProperties
// properties
builtInDocProps = Dispatch.get(document, "BuiltInDocumentProperties")
.toDispatch();
}
/**
* Closes a document
*
*/
public void close() {
//Close object
Dispatch.call(document, "Close");
}
/**
* Closes a document
*
*/
public void close() {
// Close object
Dispatch.call(document, "Close");
}
/**
* Custom Property Name is passed in
*
* @param cusPropName
* @return String - Custom property value
*/
public String getCustomProperty(String cusPropName) {
try {
cusPropName = Dispatch.call((Dispatch) custDocprops, "Item",
cusPropName).toString();
} catch (ComException e) {
// Do nothing
cusPropName = null;
}
/**
* Custom Property Name is passed in
*
* @param cusPropName
* @return String - Custom property value
*/
public String getCustomProperty(String cusPropName) {
try {
cusPropName = Dispatch.call(custDocprops, "Item", cusPropName)
.toString();
} catch (ComException e) {
// Do nothing
cusPropName = null;
}
return cusPropName;
}
return cusPropName;
}
/**
* Built In Property Name is passed in
*
* @param builtInPropName
* @return String - Built in property value
*/
public String getBuiltInProperty(String builtInPropName) {
try {
builtInPropName = Dispatch.call((Dispatch) builtInDocProps, "Item",
builtInPropName).toString();
} catch (ComException e) {
// Do nothing
builtInPropName = null;
}
/**
* Built In Property Name is passed in
*
* @param builtInPropName
* @return String - Built in property value
*/
public String getBuiltInProperty(String builtInPropName) {
try {
builtInPropName = Dispatch.call(builtInDocProps, "Item",
builtInPropName).toString();
} catch (ComException e) {
// Do nothing
builtInPropName = null;
}
return builtInPropName;
}
return builtInPropName;
}
/**
* simple main program that gets some properties and prints them out
* @param args
*/
public static void main(String[] args) {
try {
//Instantiate the class
WordDocumentProperties jacTest = new WordDocumentProperties();
/**
* simple main program that gets some properties and prints them out
*
* @param args
*/
public static void main(String[] args) {
try {
// Instantiate the class
WordDocumentProperties jacTest = new WordDocumentProperties();
//Open the word doc
jacTest.open("\\\\Saturn\\documentstorage\\s.doc");
// Open the word doc
jacTest.open("\\\\Saturn\\documentstorage\\s.doc");
//Set Custom Properties
jacTest.selectCustomDocumentProperitiesMode();
// Set Custom Properties
jacTest.selectCustomDocumentProperitiesMode();
//Set Built In Properties
jacTest.selectBuiltinPropertiesMode();
// Set Built In Properties
jacTest.selectBuiltinPropertiesMode();
//Get custom Property Value
String custValue = jacTest.getCustomProperty("Information Source");
// Get custom Property Value
String custValue = jacTest.getCustomProperty("Information Source");
//Get built in prroperty Property Value
String builtInValue = jacTest.getBuiltInProperty("Author");
// Get built in prroperty Property Value
String builtInValue = jacTest.getBuiltInProperty("Author");
//Close Word Doc
jacTest.close();
// Close Word Doc
jacTest.close();
//Output data
System.out.println("Document Val One: " + custValue);
System.out.println("Document Author: " + builtInValue);
// Output data
System.out.println("Document Val One: " + custValue);
System.out.println("Document Author: " + builtInValue);
} catch (Exception e) {
System.out.println(e);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}

View File

@@ -5,65 +5,76 @@ package com.jacob.samples.outlook;
* Christopher Brind <christopher.brind@morse.com>
*/
import com.jacob.com.*;
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* sample class to show simple outlook manipulation
*/
public class Outlook {
private static String pad(int i) {
StringBuffer sb = new StringBuffer();
private static String pad(int i) {
StringBuffer sb = new StringBuffer();
while(sb.length() < i) {
sb.append(' ');
}
while (sb.length() < i) {
sb.append(' ');
}
return sb.toString();
}
return sb.toString();
}
private static void recurseFolders(int iIndent, Dispatch o) {
private static void recurseFolders(int iIndent, Dispatch o) {
if (o == null) {
return;
}
Dispatch oFolders = Dispatch.get(o, "Folders").toDispatch();
// System.out.println("oFolders=" + oFolders);
if (oFolders == null) {
return;
}
if (o == null) return;
Dispatch oFolders = Dispatch.get(o, "Folders").toDispatch();
// System.out.println("oFolders=" + oFolders);
if (oFolders == null) return;
Dispatch oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch();
do {
Object oFolderName = Dispatch.get(oFolder, "Name");
if (null == oFolderName) {
break;
}
Dispatch oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch();
do {
Object oFolderName = Dispatch.get(oFolder, "Name");
if (null == oFolderName) {
break;
}
System.out.println(pad(iIndent) + oFolderName);
recurseFolders(iIndent + 3, oFolder);
System.out.println(pad(iIndent) + oFolderName);
recurseFolders(iIndent + 3, oFolder);
oFolder = Dispatch.get(oFolders, "GetNext").toDispatch();
} while (true);
oFolder = Dispatch.get(oFolders, "GetNext").toDispatch();
} while(true);
}
}
/**
* standard run loop
*
* @param asArgs
* command line arguments
* @throws Exception
*/
public static void main(String asArgs[]) throws Exception {
System.out.println("Outlook: IN");
ActiveXComponent axOutlook = new ActiveXComponent("Outlook.Application");
try {
System.out.println("version=" + axOutlook.getProperty("Version"));
public static void main(String asArgs[]) throws Exception {
System.out.println("Outlook: IN");
Dispatch oOutlook = axOutlook.getObject();
System.out.println("version=" + Dispatch.get(oOutlook, "Version"));
ActiveXComponent axOutlook = new ActiveXComponent("Outlook.Application");
try {
System.out.println("version="+axOutlook.getProperty("Version"));
Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch();
System.out.println("oNameSpace=" + oNameSpace);
Dispatch oOutlook = axOutlook.getObject();
System.out.println("version="+Dispatch.get(oOutlook, "Version"));
recurseFolders(0, oNameSpace);
Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch();
System.out.println("oNameSpace=" + oNameSpace);
recurseFolders(0, oNameSpace);
} finally {
axOutlook.invoke("Quit", new Variant[] {});
}
}
} finally {
axOutlook.invoke("Quit", new Variant[] {});
}
}
}

View File

@@ -10,41 +10,49 @@ import com.jacob.com.Variant;
/**
* Example VB script that grabs hard drive properties.
* <p>
* Source Forge posting http://sourceforge.net/forum/forum.php?thread_id=1785936&forum_id=375946
* Source Forge posting
* http://sourceforge.net/forum/forum.php?thread_id=1785936&forum_id=375946
* <p>
* Enhance by clay_shooter with info from http://msdn2.microsoft.com/en-us/library/d6dw7aeh.aspx
* Enhance by clay_shooter with info from
* http://msdn2.microsoft.com/en-us/library/d6dw7aeh.aspx
*
* @author qstephenson
*
* @author qstephenson
*
*/
public class DiskUtils {
/** formatters aren't thread safe but the sample only has one thread */
private static DecimalFormat sizeFormatter = new DecimalFormat("###,###,###,###");
private static DecimalFormat sizeFormatter = new DecimalFormat(
"###,###,###,###");
/** a pointer to the scripting file system object */
private ActiveXComponent fileSystemApp = null;
/** the dispatch that points at the drive this DiskUtil operates against */
private Dispatch myDrive = null;
/**
* Standard constructor
*
* @param drive
* the drive to run the test against.
*/
public DiskUtils(String drive){
public DiskUtils(String drive) {
setUp(drive);
}
/**
* open the connection to the scripting object
*
* @param drive
* the drive to run the test against
*/
public void setUp(String drive){
if (fileSystemApp == null){
ComThread.InitSTA();
fileSystemApp = new ActiveXComponent(
"Scripting.FileSystemObject");
public void setUp(String drive) {
if (fileSystemApp == null) {
ComThread.InitSTA();
fileSystemApp = new ActiveXComponent("Scripting.FileSystemObject");
myDrive = Dispatch.call(fileSystemApp, "GetDrive", drive)
.toDispatch();
.toDispatch();
}
}
@@ -54,58 +62,61 @@ public class DiskUtils {
public void tearDown() {
ComThread.Release();
}
/**
* convenience method
*
* @return driver serial number
*/
public int getSerialNumber() {
return Dispatch.get(myDrive, "SerialNumber").getInt();
}
/**
* Convenience method.
* We go through these formatting hoops so we can make the size string pretty.
* We wouldn't have to do that if we didn't mind long strings with Exxx at the end
* or the fact that the value returned can vary in size based on the size of the disk.
* Convenience method. We go through these formatting hoops so we can make
* the size string pretty. We wouldn't have to do that if we didn't mind
* long strings with Exxx at the end or the fact that the value returned can
* vary in size based on the size of the disk.
*
* @return driver total size of the disk
*/
public String getTotalSize() {
Variant returnValue = Dispatch.get(myDrive, "TotalSize");
if (returnValue.getvt() == Variant.VariantDouble){
if (returnValue.getvt() == Variant.VariantDouble) {
return sizeFormatter.format(returnValue.getDouble());
} else if (returnValue.getvt() == Variant.VariantInt){
} else if (returnValue.getvt() == Variant.VariantInt) {
return sizeFormatter.format(returnValue.getInt());
} else {
return "Don't know type: "+returnValue.getvt();
return "Don't know type: " + returnValue.getvt();
}
}
/**
* Convenience method.
* We wouldn't have to do that if we didn't mind long strings with Exxx at the end
* or the fact that the value returned can vary in size based on the size of the disk.
* Convenience method. We wouldn't have to do that if we didn't mind long
* strings with Exxx at the end or the fact that the value returned can vary
* in size based on the size of the disk.
*
* @return driver free size of the disk
*/
public String getFreeSpace() {
Variant returnValue = Dispatch.get(myDrive, "FreeSpace");
if (returnValue.getvt() == Variant.VariantDouble){
if (returnValue.getvt() == Variant.VariantDouble) {
return sizeFormatter.format(returnValue.getDouble());
} else if (returnValue.getvt() == Variant.VariantInt){
} else if (returnValue.getvt() == Variant.VariantInt) {
return sizeFormatter.format(returnValue.getInt());
} else {
return "Don't know type: "+returnValue.getvt();
return "Don't know type: " + returnValue.getvt();
}
}
/**
*
* @return file system on the drive
*/
public String getFileSystemType() {
//figure ot the actual variant type
//Variant returnValue = Dispatch.get(myDrive, "FileSystem");
//System.out.println(returnValue.getvt());
// figure ot the actual variant type
// Variant returnValue = Dispatch.get(myDrive, "FileSystem");
// System.out.println(returnValue.getvt());
return Dispatch.get(myDrive, "FileSystem").getString();
}
@@ -116,17 +127,26 @@ public class DiskUtils {
public String getVolumeName() {
return Dispatch.get(myDrive, "VolumeName").getString();
}
/**
* Simple main program that creates a DiskUtils object and queries for the C: drive
* Simple main program that creates a DiskUtils object and queries for the
* C: drive
*
* @param args
* standard command line arguments
*/
public static void main(String[] args) {
//DiskUtils utilConnection = new DiskUtils("F");
// DiskUtils utilConnection = new DiskUtils("F");
DiskUtils utilConnection = new DiskUtils("C");
System.out.println("Disk serial number is: "+ utilConnection.getSerialNumber());
System.out.println("FileSystem is: "+ utilConnection.getFileSystemType());
System.out.println("Volume Name is: "+ utilConnection.getVolumeName());
System.out.println("Disk total size is: "+ utilConnection.getTotalSize());
System.out.println("Disk free space is: "+ utilConnection.getFreeSpace());
System.out.println("Disk serial number is: "
+ utilConnection.getSerialNumber());
System.out.println("FileSystem is: "
+ utilConnection.getFileSystemType());
System.out.println("Volume Name is: " + utilConnection.getVolumeName());
System.out.println("Disk total size is: "
+ utilConnection.getTotalSize());
System.out.println("Disk free space is: "
+ utilConnection.getFreeSpace());
utilConnection.tearDown();
}
}

View File

@@ -13,23 +13,27 @@ import com.jacob.com.Variant;
* fold, spindled and mutilated by clay_shooter
*
* @author chris_knowles
*
*
*/
public class SystemMonitor {
/**
* example run loop method called by main()
*/
public void runMonitor() {
ActiveXComponent wmi = null;
wmi = new ActiveXComponent("WbemScripting.SWbemLocator");
// no connection parameters means to connect to the local machine
Variant conRet = wmi.invoke("ConnectServer");
// the author liked the ActiveXComponent api style over the Dispatch style
// the author liked the ActiveXComponent api style over the Dispatch
// style
ActiveXComponent wmiconnect = new ActiveXComponent(conRet.toDispatch());
// the WMI supports a query language.
String query = "select CategoryString, Message, TimeGenerated, User, Type "
+ "from Win32_NtLogEvent "
+ "where Logfile = 'Application' and TimeGenerated > '20070915000000.000000-***'";
+ "from Win32_NtLogEvent "
+ "where Logfile = 'Application' and TimeGenerated > '20070915000000.000000-***'";
Variant vCollection = wmiconnect
.invoke("ExecQuery", new Variant(query));
@@ -40,7 +44,7 @@ public class SystemMonitor {
while (enumVariant.hasMoreElements()) {
resultString = "";
item = enumVariant.Next().toDispatch();
item = enumVariant.nextElement().toDispatch();
String categoryString = Dispatch.call(item, "CategoryString")
.toString();
String messageString = Dispatch.call(item, "Message").toString();
@@ -48,17 +52,21 @@ public class SystemMonitor {
.toString();
String eventUser = Dispatch.call(item, "User").toString();
String eventType = Dispatch.call(item, "Type").toString();
resultString += "TimeGenerated: "+ timeGenerated
+ " Category: " + categoryString
+ " User: " + eventUser
+ " EventType: "+ eventType
+ " Message:" + messageString;
resultString += "TimeGenerated: " + timeGenerated + " Category: "
+ categoryString + " User: " + eventUser + " EventType: "
+ eventType + " Message:" + messageString;
System.out.println(resultString);
}
}
/**
* sample's main program
*
* @param args
* command line arguments
*/
public static void main(String[] args) {
SystemMonitor utilConnection = new SystemMonitor();
utilConnection.runMonitor();

View File

@@ -1,85 +1,121 @@
package com.jacob.samples.visio;
import com.jacob.com.*;
import com.jacob.activeX.*;
import java.io.File;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
*
*
* This class represents the visio app itself
*/
public class VisioApp extends ActiveXComponent {
/**
* constructor that spins up Visio
*
* @throws VisioException
*/
public VisioApp() throws VisioException {
super("Visio.Application");
setVisible(false);
}
public VisioApp() throws VisioException {
super("Visio.Application");
setVisible(false);
}
/**
* creates a DispatchEvents object to register o as a listener
*
* @param o
*/
public void addEventListener(VisioEventListener o) {
DispatchEvents events = new DispatchEvents(this, o);
if (events == null) {
System.out
.println("You should never get null back when creating a DispatchEvents object");
}
}
/**
* creates a DispatchEvents boject to register o as a listener
* @param o
*/
public void addEventListener(VisioEventListener o) {
DispatchEvents events = new DispatchEvents(this, o);
if (events == null){
System.out.println("You should never get null back when creating a DispatchEvents object");
}
}
/**
* opens the passed in file in Visio
*
* @param f
* @throws VisioException
*/
public void open(File f) throws VisioException {
try {
ActiveXComponent documents = new ActiveXComponent(getProperty(
"Documents").toDispatch());
Variant[] args = new Variant[1];
args[0] = new Variant(f.getPath());
documents.invoke("Open", args);
} catch (Exception e) {
e.printStackTrace();
throw new VisioException(e);
}
}
/**
* tells Visio to save the drawing
*
* @throws VisioException
*/
public void save() throws VisioException {
try {
ActiveXComponent document = new ActiveXComponent(getProperty(
"ActiveDocument").toDispatch());
document.invoke("Save");
} catch (Exception e) {
e.printStackTrace();
throw new VisioException(e);
}
}
public void open(File f) throws VisioException {
try {
ActiveXComponent documents = new ActiveXComponent(getProperty("Documents").toDispatch());
Variant[] args = new Variant[1];
args[0] = new Variant(f.getPath());
documents.invoke("Open",args);
} catch (Exception e) {
e.printStackTrace();
throw new VisioException(e);
}
}
/**
* terminates Visio
*/
public void quit() {
System.out.println("Received quit()");
// there can't be any open documents for this to work
// you'll get a visio error if you don't close them
ActiveXComponent document = new ActiveXComponent(getProperty(
"ActiveDocument").toDispatch());
document.invoke("Close");
invoke("Quit");
}
public void save() throws VisioException {
try {
ActiveXComponent document = new ActiveXComponent(getProperty("ActiveDocument").toDispatch());
document.invoke("Save");
} catch (Exception e) {
e.printStackTrace();
throw new VisioException(e);
}
}
/**
* runs the Visio export command
*
* @param f
* @throws VisioException
*/
public void export(File f) throws VisioException {
try {
ActiveXComponent document = new ActiveXComponent(getProperty(
"ActivePage").toDispatch());
Variant[] args = new Variant[1];
args[0] = new Variant(f.getPath());
document.invoke("Export", args);
} catch (Exception e) {
throw new VisioException(e);
}
}
/**
* terminates visio
*/
public void quit() {
System.out.println("Received quit()");
// there can't be any open documents for this to work
// you'll get a visio error if you don't close them
ActiveXComponent document = new ActiveXComponent(getProperty("ActiveDocument").toDispatch());
document.invoke("Close");
invoke("Quit");
}
public void export(File f) throws VisioException {
try {
ActiveXComponent document = new ActiveXComponent(getProperty("ActivePage").toDispatch());
Variant[] args = new Variant[1];
args[0] = new Variant(f.getPath());
document.invoke("Export",args);
} catch (Exception e) {
throw new VisioException(e);
}
}
public void setVisible(boolean b) throws VisioException {
try {
setProperty("Visible",new Variant(b));
} catch (Exception e) {
throw new VisioException(e);
}
}
/**
* makes Visio visible so the user can watch
*
* @param b
* @throws VisioException
*/
public void setVisible(boolean b) throws VisioException {
try {
setProperty("Visible", new Variant(b));
} catch (Exception e) {
throw new VisioException(e);
}
}
}

View File

@@ -1,120 +1,180 @@
package com.jacob.samples.visio;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
*
*
* This singleton isolates the demo app from the Visio instance object so that
* you can't try and send messages to a dead Visio instance after quit() has been
* called. Direct consumption of VisioApp would mean you could quit but would
* still have a handle to the no longer connected application proxy
* you can't try and send messages to a dead Visio instance after quit() has
* been called. Direct consumption of VisioApp would mean you could quit but
* would still have a handle to the no longer connected application proxy
*
*/
public class VisioAppFacade {
private VisioApp app;
private static VisioAppFacade instance;
private VisioApp app;
private static VisioAppFacade instance;
/** extension for image files */
public static final String IMAGE_EXT = ".jpg";
/** extension for visio files */
public static final String VISIO_EXT = ".vsd";
/** the buffer size when we want to read stuff in */
public static final int BUFFER_SIZE = 2048;
public static final String IMAGE_EXT = ".jpg";
public static final String VISIO_EXT = ".vsd";
public static final int BUFFER_SIZE = 2048;
private VisioAppFacade() throws VisioException {
this.app = new VisioApp();
/**
* Wrapper around Visio
*
* @throws VisioException
*/
private VisioAppFacade() throws VisioException {
this.app = new VisioApp();
app.addEventListener(new VisioEventAdapter(app));
}
}
public static VisioAppFacade getInstance() throws VisioException {
if (instance == null) {
instance = new VisioAppFacade();
}
return instance;
}
/**
* @return the singleton instance of Visio
* @throws VisioException
*/
public static VisioAppFacade getInstance() throws VisioException {
if (instance == null) {
instance = new VisioAppFacade();
}
return instance;
}
public byte[] createPreview(byte[] visioData) throws VisioException {
byte[] preview;
File tmpFile;
try {
tmpFile = getTempVisioFile();
OutputStream out = new FileOutputStream(tmpFile);
out.write(visioData);
out.close();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
preview = createPreview(tmpFile);
tmpFile.delete();
return preview;
}
/**
* creates a preview in a temp file and returns the raw data.
*
* @param visioData
* @return raw preview data
* @throws VisioException
*/
public byte[] createPreview(byte[] visioData) throws VisioException {
byte[] preview;
File tmpFile;
try {
tmpFile = getTempVisioFile();
OutputStream out = new FileOutputStream(tmpFile);
out.write(visioData);
out.close();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
preview = createPreview(tmpFile);
tmpFile.delete();
return preview;
}
public byte[] createPreview(File visioFile) throws VisioException {
try {
File imageFile;
imageFile = getTempImageFile();
app.open(visioFile);
app.export(imageFile);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
FileInputStream fin = new FileInputStream(imageFile);
copy(fin, bout);
fin.close();
imageFile.delete();
bout.close();
return bout.toByteArray();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
}
/**
* reads a preview from a saved file
*
* @param visioFile
* @return raw preview data
* @throws VisioException
*/
public byte[] createPreview(File visioFile) throws VisioException {
try {
File imageFile;
imageFile = getTempImageFile();
app.open(visioFile);
app.export(imageFile);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
FileInputStream fin = new FileInputStream(imageFile);
copy(fin, bout);
fin.close();
imageFile.delete();
bout.close();
return bout.toByteArray();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
}
private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buff = new byte[BUFFER_SIZE];
int read;
do {
read = in.read(buff);
if (read > 0) {
out.write(buff,0,read);
}
} while (read > 0);
}
private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buff = new byte[BUFFER_SIZE];
int read;
do {
read = in.read(buff);
if (read > 0) {
out.write(buff, 0, read);
}
} while (read > 0);
}
public byte[] createPreview(InputStream in) throws VisioException {
byte[] preview;
//byte[] buff = new byte[2048];
//int read = 0;
OutputStream out;
File tmpFile;
/**
* creates a preview from an input stream
*
* @param in
* @return byte contents of the preview stream
* @throws VisioException
*/
public byte[] createPreview(InputStream in) throws VisioException {
byte[] preview;
// byte[] buff = new byte[2048];
// int read = 0;
OutputStream out;
File tmpFile;
try {
tmpFile = getTempVisioFile();
out = new FileOutputStream(tmpFile);
copy(in, out);
out.close();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
try {
tmpFile = getTempVisioFile();
out = new FileOutputStream(tmpFile);
copy(in, out);
out.close();
} catch (IOException ioe) {
throw new VisioException(ioe);
}
preview = createPreview(tmpFile);
tmpFile.delete();
return preview;
}
preview = createPreview(tmpFile);
tmpFile.delete();
return preview;
}
public void editDiagram(File f) throws VisioException {
app.open(f);
app.setVisible(true);
}
/**
* opens the file in Visio and makes the editor visible
*
* @param f
* the reference to the Visio file to be opened
* @throws VisioException
*/
public void editDiagram(File f) throws VisioException {
app.open(f);
app.setVisible(true);
}
private File getTempVisioFile() throws IOException {
return File.createTempFile("java",VISIO_EXT);
}
/**
* creates a temporary viso file
*
* @return created visio temporary file
* @throws IOException
*/
private File getTempVisioFile() throws IOException {
return File.createTempFile("java", VISIO_EXT);
}
private File getTempImageFile() throws IOException {
return File.createTempFile("java",IMAGE_EXT);
}
/**
* creates a temporary image file and returns the File object
*
* @return the created image file object
* @throws IOException
*/
private File getTempImageFile() throws IOException {
return File.createTempFile("java", IMAGE_EXT);
}
public void quit() {
app.quit();
instance = null;
}
/** exit visio */
public void quit() {
app.quit();
instance = null;
}
}

View File

@@ -1,177 +1,197 @@
package com.jacob.samples.visio;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;
import com.jacob.com.ComThread;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
* <p>
* This file contains the main() that runs the demo
* <p>
* Look in the docs area at the Jacob usage document for command line options.
* <p>
* This file contains the main() that runs the demo
* <p>
* Look in the docs area at the Jacob usage document for command line
* options.
*/
public class VisioDemo extends JFrame implements ActionListener, WindowListener {
/**
/**
* Totally dummy value to make Eclipse quit complaining
*/
private static final long serialVersionUID = 1L;
JButton chooseButton;
JButton openButton;
JPanel buttons;
JButton openButton;
JPanel buttons;
ImageIcon theImage;
JLabel theLabel; // the icon on the page is actually this button's icon
ImageIcon theImage;
JLabel theLabel; // the icon on the page is actually this button's icon
File selectedFile;
/** everyone should get this through getVisio() */
private VisioAppFacade visioProxy = null;
File selectedFile;
/** everyone should get this through getVisio() */
private VisioAppFacade visioProxy = null;
// put this up here so it remembers where we were on the last choose
JFileChooser chooser = null;
// put this up here so it remembers where we were on the last choose
JFileChooser chooser = null;
public class VisioFileFilter extends FileFilter {
public boolean accept(File f) {
if (f.isDirectory()){
return true;
} else {
return (f.getName().toUpperCase().endsWith(".VSD"));
}
}
public class VisioFileFilter extends FileFilter {
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
} else {
return (f.getName().toUpperCase().endsWith(".VSD"));
}
}
public String getDescription() {
return "Visio Drawings";
}
}
public String getDescription() {
return "Visio Drawings";
}
}
public VisioDemo() {
super("Visio in Swing POC");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttons = new JPanel();
getContentPane().setLayout(new BorderLayout());
chooseButton = new JButton("Choose file to display");
openButton = new JButton("Open file chosen file in Visio");
chooseButton.addActionListener(this);
openButton.addActionListener(this);
buttons.add(chooseButton);
buttons.add(openButton);
getContentPane().add(buttons, BorderLayout.SOUTH);
theLabel = new JLabel("");
getContentPane().add(theLabel, BorderLayout.CENTER);
addWindowListener(this);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(640,480);
this.setVisible(true);
}
public VisioDemo() {
super("Visio in Swing POC");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttons = new JPanel();
getContentPane().setLayout(new BorderLayout());
chooseButton = new JButton("Choose file to display");
openButton = new JButton("Open file chosen file in Visio");
chooseButton.addActionListener(this);
openButton.addActionListener(this);
buttons.add(chooseButton);
buttons.add(openButton);
getContentPane().add(buttons, BorderLayout.SOUTH);
theLabel = new JLabel("");
getContentPane().add(theLabel, BorderLayout.CENTER);
addWindowListener(this);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(640, 480);
this.setVisible(true);
}
public static void main(String args[]) throws Exception {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
ComThread.InitSTA();
VisioDemo poc = new VisioDemo();
ComThread.Release();
if (poc == null){
System.out.println("poc== null? That should never happen!");
}
}
});
}
public static void main(String args[]) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ComThread.InitSTA();
VisioDemo poc = new VisioDemo();
ComThread.Release();
if (poc == null) {
System.out.println("poc== null? That should never happen!");
}
}
});
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chooseButton) {
pickFile();
} else if (e.getSource() == openButton) {
try {
openFile();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
} else {
System.out.println("Awesome!");
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chooseButton) {
pickFile();
} else if (e.getSource() == openButton) {
try {
openFile();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
} else {
System.out.println("Awesome!");
}
}
private void pickFile() {
try {
chooser = new JFileChooser();
// comment this out if you want it to always go to myDocuments
chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
chooser.setFileFilter(new VisioFileFilter());
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
selectedFile = chooser.getSelectedFile();
showSelectedFilePreview();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void pickFile() {
try {
chooser = new JFileChooser();
// comment this out if you want it to always go to myDocuments
chooser
.setCurrentDirectory(new File(System
.getProperty("user.dir")));
chooser.setFileFilter(new VisioFileFilter());
int returnVal = chooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
selectedFile = chooser.getSelectedFile();
showSelectedFilePreview();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* use this private method instead of initializing on boot up so that instance
* and all listeners are created in this thread (event thread) rather than root thread
* @return
*/
private VisioAppFacade getVisio(){
if (visioProxy == null){
try {
visioProxy = VisioAppFacade.getInstance();
} catch (VisioException ve){
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
}
return visioProxy;
}
private void showSelectedFilePreview() throws VisioException {
if (selectedFile != null) {
byte[] image = getVisio().createPreview(selectedFile);
theImage = new ImageIcon(image);
theLabel.setIcon(theImage);
}
}
/**
* use this private method instead of initializing on boot up so that
* instance and all listeners are created in this thread (event thread)
* rather than root thread
*
* @return
*/
private VisioAppFacade getVisio() {
if (visioProxy == null) {
try {
visioProxy = VisioAppFacade.getInstance();
} catch (VisioException ve) {
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
}
return visioProxy;
}
private void openFile() throws VisioException {
try {
getVisio().editDiagram(selectedFile);
showSelectedFilePreview();
} catch (VisioException ve){
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
private void showSelectedFilePreview() throws VisioException {
if (selectedFile != null) {
byte[] image = getVisio().createPreview(selectedFile);
theImage = new ImageIcon(image);
theLabel.setIcon(theImage);
}
}
}
private void openFile() throws VisioException {
try {
getVisio().editDiagram(selectedFile);
showSelectedFilePreview();
} catch (VisioException ve) {
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
public void windowActivated(WindowEvent e) {
}
}
public void windowClosed(WindowEvent e) {
System.out.println("WINDOW CLOSED");
if (visioProxy != null){
visioProxy.quit();
}
}
public void windowClosing(WindowEvent e){
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e){
}
public void windowClosed(WindowEvent e) {
System.out.println("WINDOW CLOSED");
if (visioProxy != null) {
visioProxy.quit();
}
}
public void windowDeiconified(WindowEvent e){
}
public void windowClosing(WindowEvent e) {
}
public void windowIconified(WindowEvent e){
System.out.println("Fooboo");
}
public void windowOpened(WindowEvent e){
}
public void windowDeactivated(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
System.out.println("Fooboo");
}
public void windowOpened(WindowEvent e) {
}
}

View File

@@ -1,59 +1,68 @@
package com.jacob.samples.visio;
import com.jacob.com.*;
import com.jacob.com.Variant;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
*
* You can subclass this class and only implement the methods you're interested in
*
* You can subclass this class and only implement the methods you're interested
* in
*/
public class VisioEventAdapter implements VisioEventListener {
VisioApp app = null;
public VisioEventAdapter(VisioApp pApp){
public VisioEventAdapter(VisioApp pApp) {
app = pApp;
System.out.println("Event listener constructed");
}
public void BeforeQuit(Variant[] args){ }
public void DocumentChanged(Variant[] args){
System.out.println("documentChanged()");
}
public void BeforeQuit(Variant[] args) {
}
public void DocumentCloseCanceled(Variant[] args){ }
public void DocumentChanged(Variant[] args) {
System.out.println("documentChanged()");
}
public void DocumentCreated(Variant[] args){ }
public void DocumentCloseCanceled(Variant[] args) {
}
public void DocumentOpened(Variant[] args){
System.out.println("DocumentOpened()");
}
public void DocumentCreated(Variant[] args) {
}
public void DocumentSaved(Variant[] args){ }
public void DocumentOpened(Variant[] args) {
System.out.println("DocumentOpened()");
}
public void DocumentSavedAs(Variant[] args){ }
public void DocumentSaved(Variant[] args) {
}
public Variant QueryCancelDocumentClose(Variant[] args){
System.out.println("QueryCancelDocumentClose()");
return new Variant(false);
}
/**
* we don't actually let it quit. We block it so
* that we don't have to relaunch when we look at a new document
*/
public Variant QueryCancelQuit(Variant[] args) {
// these may throw VisioException
System.out.println("Saving document, hiding and telling visio not to quit");
try {
app.save();
app.setVisible(false);
} catch (VisioException ve){
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
return new Variant(true);
}
public void DocumentSavedAs(Variant[] args) {
}
public Variant QueryCancelDocumentClose(Variant[] args) {
System.out.println("QueryCancelDocumentClose()");
return new Variant(false);
}
/**
* we don't actually let it quit. We block it so that we don't have to
* relaunch when we look at a new document
*/
public Variant QueryCancelQuit(Variant[] args) {
// these may throw VisioException
System.out
.println("Saving document, hiding and telling visio not to quit");
try {
app.save();
app.setVisible(false);
} catch (VisioException ve) {
System.out.println("ailed to openFile()");
ve.printStackTrace();
}
return new Variant(true);
}
}

View File

@@ -1,33 +1,33 @@
package com.jacob.samples.visio;
import com.jacob.com.*;
import com.jacob.com.Variant;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
*
* There are many more Visio events available. See the Microsoft
* Office SDK documentation. To receive an event, add a method to this interface
* whose name matches the event name and has only one parameter, Variant[].
* The JACOB library will use reflection to call that method when an event is received.
*
* There are many more Visio events available. See the Microsoft Office SDK
* documentation. To receive an event, add a method to this interface whose name
* matches the event name and has only one parameter, Variant[]. The JACOB
* library will use reflection to call that method when an event is received.
*/
public interface VisioEventListener {
public void BeforeQuit(Variant[] args);
public void BeforeQuit(Variant[] args);
public void DocumentChanged(Variant[] args);
public void DocumentChanged(Variant[] args);
public void DocumentCloseCanceled(Variant[] args);
public void DocumentCloseCanceled(Variant[] args);
public void DocumentCreated(Variant[] args);
public void DocumentCreated(Variant[] args);
public void DocumentOpened(Variant[] args);
public void DocumentOpened(Variant[] args);
public void DocumentSaved(Variant[] args);
public void DocumentSaved(Variant[] args);
public void DocumentSavedAs(Variant[] args);
public void DocumentSavedAs(Variant[] args);
public Variant QueryCancelQuit(Variant[] args);
public Variant QueryCancelQuit(Variant[] args);
}

View File

@@ -1,22 +1,25 @@
package com.jacob.samples.visio;
/**
* Created as part of sourceforge 1386454 to demonstrate returning values in event handlers
* Created as part of sourceforge 1386454 to demonstrate returning values in
* event handlers
*
* @author miles@rowansoftware.net
*
* This extends runtime exception so that we can be sloppy and not put catch blocks everywhere
*
* This extends runtime exception so that we can be sloppy and not put catch
* blocks everywhere
*/
public class VisioException extends Exception {
/**
/**
* Totally dummy value to make Eclipse quit complaining
*/
private static final long serialVersionUID = 1L;
public VisioException(String msg) {
super(msg);
}
super(msg);
}
public VisioException(Throwable cause) {
super(cause);
}
public VisioException(Throwable cause) {
super(cause);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,67 +26,78 @@ import com.jacob.com.InvocationProxy;
/**
* RELEASE 1.12 EXPERIMENTAL.
* <p>
* Use this exactly like the DispatchEvents class. This class plugs in
* an ActiveXInvocationProxy instead of an InvocationProxy. It is the
* ActiveXInvocationProxy that implements the reflection calls and invoke
* the found java event callbacks. See ActiveXInvocationProxy for details.
* Use this exactly like the DispatchEvents class. This class plugs in an
* ActiveXInvocationProxy instead of an InvocationProxy. It is the
* ActiveXInvocationProxy that implements the reflection calls and invoke the
* found java event callbacks. See ActiveXInvocationProxy for details.
*
*
*
*/
public class ActiveXDispatchEvents extends DispatchEvents {
/**
* This is the most commonly used constructor.
* <p>
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink) {
super(sourceOfEvent, eventSink, null );
}
/**
* This is the most commonly used constructor.
* <p>
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
*
* @param sourceOfEvent
* Dispatch object who's MS app will generate callbacks
* @param eventSink
* Java object that wants to receive the events
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink) {
super(sourceOfEvent, eventSink, null);
}
/**
* None of the samples use this constructor.
* <p>
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
* @param progId ???
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink, String progId) {
super(sourceOfEvent, eventSink, progId, null );
}
/**
* None of the samples use this constructor.
* <p>
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
*
* @param sourceOfEvent
* Dispatch object who's MS app will generate callbacks
* @param eventSink
* Java object that wants to receive the events
* @param progId
* ???
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink,
String progId) {
super(sourceOfEvent, eventSink, progId, null);
}
/**
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* <pre>
* >ActiveXDispatchEvents de =
* new ActiveXDispatchEvents(someDispatch,someEventHAndler,
* "Excel.Application",
* "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
*
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
* @param progId , mandatory if the typelib is specified
* @param typeLib The location of the typelib to use
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink, String progId, String typeLib)
{
super(sourceOfEvent, eventSink, progId, typeLib);
}
/**
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
*
* <pre>
* &gt;ActiveXDispatchEvents de =
* new ActiveXDispatchEvents(someDispatch,someEventHAndler,
* &quot;Excel.Application&quot;,
* &quot;C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE&quot;);
*
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
* @param progId , mandatory if the typelib is specified
* @param typeLib The location of the typelib to use
*
*/
public ActiveXDispatchEvents(Dispatch sourceOfEvent, Object eventSink,
String progId, String typeLib) {
super(sourceOfEvent, eventSink, progId, typeLib);
}
/*
* (non-Javadoc)
* @see com.jacob.com.DispatchEvents#getInvocationProxy(java.lang.Object)
*/
protected InvocationProxy getInvocationProxy(Object pTargetObject){
/*
* (non-Javadoc)
*
* @see com.jacob.com.DispatchEvents#getInvocationProxy(java.lang.Object)
*/
protected InvocationProxy getInvocationProxy(Object pTargetObject) {
InvocationProxy newProxy = new ActiveXInvocationProxy();
newProxy.setTarget(pTargetObject);
return newProxy;

View File

@@ -29,63 +29,70 @@ import com.jacob.com.Variant;
/**
* RELEASE 1.12 EXPERIMENTAL.
* <p>
* This class that lets event handlers receive events with all java
* objects as parameters. The standard Jacob event methods all accept an array of
* Variant objects. When using this class, you can set up your event methods
* as regular java methods with the correct number of parameters of the correct
* java type. This does NOT work for any event that wishes to accept a call
* back and modify the calling parameters to tell windows what to do. An example
* is when an event lets the receiver cancel the action by setting a boolean flag
* to false. The java objects cannot be modified and their values will not be passed
* back into the originating Variants even if they could be modified.
* This class that lets event handlers receive events with all java objects as
* parameters. The standard Jacob event methods all accept an array of Variant
* objects. When using this class, you can set up your event methods as regular
* java methods with the correct number of parameters of the correct java type.
* This does NOT work for any event that wishes to accept a call back and modify
* the calling parameters to tell windows what to do. An example is when an
* event lets the receiver cancel the action by setting a boolean flag to false.
* The java objects cannot be modified and their values will not be passed back
* into the originating Variants even if they could be modified.
* <p>
* This class acts as a proxy between the windows event callback mechanism and
* the Java classes that are looking for events. It assumes that
* all of the Java classes that are looking for events implement methods with the
* same names as the windows events and that the implemented methods native
* java objects of the type and order that match the windows documentation.
* The methods can return void or a Variant that
* will be returned to the calling layer. All Event methods that will be
* recognized by InvocationProxyAllEvents have the signature
*
* <code> void eventMethodName(Object,Object...)</code>
* or
* <code> Object eventMethodName(Object,Object...)</code>
* the Java classes that are looking for events. It assumes that all of the Java
* classes that are looking for events implement methods with the same names as
* the windows events and that the implemented methods native java objects of
* the type and order that match the windows documentation. The methods can
* return void or a Variant that will be returned to the calling layer. All
* Event methods that will be recognized by InvocationProxyAllEvents have the
* signature
*
* <code> void eventMethodName(Object,Object...)</code> or
* <code> Object eventMethodName(Object,Object...)</code>
*/
public class ActiveXInvocationProxy extends InvocationProxy {
/*
* (non-Javadoc)
* @see com.jacob.com.InvocationProxy#invoke(java.lang.String, com.jacob.com.Variant[])
*
* @see com.jacob.com.InvocationProxy#invoke(java.lang.String,
* com.jacob.com.Variant[])
*/
@SuppressWarnings("unchecked")
public Variant invoke(String methodName, Variant targetParameters[]) {
Variant mVariantToBeReturned = null;
if (mTargetObject == null){
// structured programming guidlines say this return should not be up here
Variant mVariantToBeReturned = null;
if (mTargetObject == null) {
// structured programming guidlines say this return should not be up
// here
return null;
}
Class targetClass = mTargetObject.getClass();
if (methodName == null){
throw new IllegalArgumentException("InvocationProxy: missing method name");
if (methodName == null) {
throw new IllegalArgumentException(
"InvocationProxy: missing method name");
}
if (targetParameters == null){
throw new IllegalArgumentException("InvocationProxy: missing Variant parameters");
if (targetParameters == null) {
throw new IllegalArgumentException(
"InvocationProxy: missing Variant parameters");
}
try {
Method targetMethod;
Object parametersAsJavaObjects[] = getParametersAsJavaObjects(targetParameters);
Class parametersAsJavaClasses[] = getParametersAsJavaClasses(parametersAsJavaObjects);
targetMethod = targetClass.getMethod(methodName, parametersAsJavaClasses);
if (targetMethod != null){
Class parametersAsJavaClasses[] = getParametersAsJavaClasses(parametersAsJavaObjects);
targetMethod = targetClass.getMethod(methodName,
parametersAsJavaClasses);
if (targetMethod != null) {
// protected classes can't be invoked against even if they
// let you grab the method. you could do targetMethod.setAccessible(true);
// let you grab the method. you could do
// targetMethod.setAccessible(true);
// but that should be stopped by the security manager
Object mReturnedByInvocation = null;
mReturnedByInvocation =
targetMethod.invoke(mTargetObject,parametersAsJavaObjects);
if (mReturnedByInvocation == null){
mReturnedByInvocation = targetMethod.invoke(mTargetObject,
parametersAsJavaObjects);
if (mReturnedByInvocation == null) {
mVariantToBeReturned = null;
} else if (!(mReturnedByInvocation instanceof Variant)){
} else if (!(mReturnedByInvocation instanceof Variant)) {
mVariantToBeReturned = new Variant(mReturnedByInvocation);
} else {
mVariantToBeReturned = (Variant) mReturnedByInvocation;
@@ -95,11 +102,13 @@ public class ActiveXInvocationProxy extends InvocationProxy {
// what causes this exception?
e.printStackTrace();
} catch (NoSuchMethodException e) {
// this happens whenever the listener doesn't implement all the methods
// this happens whenever the listener doesn't implement all the
// methods
} catch (IllegalArgumentException e) {
// we can throw these inside the catch block so need to re-throw it
Exception oneWeShouldToss = new IllegalArgumentException("Unable to map parameters for method "+methodName
+ ": "+e.toString());
// we can throw these inside the catch block so need to re-throw it
Exception oneWeShouldToss = new IllegalArgumentException(
"Unable to map parameters for method " + methodName + ": "
+ e.toString());
oneWeShouldToss.printStackTrace();
} catch (IllegalAccessException e) {
// can't access the method on the target instance for some reason
@@ -109,23 +118,27 @@ public class ActiveXInvocationProxy extends InvocationProxy {
e.printStackTrace();
}
return mVariantToBeReturned;
}
/**
* creates a method signature compatible array of classes from an array of parameters
* creates a method signature compatible array of classes from an array of
* parameters
*
* @param parametersAsJavaObjects
* @return
*/
@SuppressWarnings("unchecked")
private Class[] getParametersAsJavaClasses(Object[] parametersAsJavaObjects) {
if (parametersAsJavaObjects == null){
throw new IllegalArgumentException("This only works with an array of parameters");
if (parametersAsJavaObjects == null) {
throw new IllegalArgumentException(
"This only works with an array of parameters");
}
int numParameters = parametersAsJavaObjects.length;
Class parametersAsJavaClasses[] = new Class[numParameters];
for ( int parameterIndex = 0 ; parameterIndex < numParameters; parameterIndex++){
for (int parameterIndex = 0; parameterIndex < numParameters; parameterIndex++) {
Object oneParameterObject = parametersAsJavaObjects[parameterIndex];
if (oneParameterObject == null){
if (oneParameterObject == null) {
parametersAsJavaClasses[parameterIndex] = null;
} else {
Class oneParameterClass = oneParameterObject.getClass();
@@ -137,31 +150,34 @@ public class ActiveXInvocationProxy extends InvocationProxy {
/**
* converts an array of Variants to their associated Java types
*
* @param targetParameters
* @return
*/
private Object[] getParametersAsJavaObjects(Variant[] targetParameters) {
if (targetParameters == null){
throw new IllegalArgumentException("This only works with an array of parameters");
if (targetParameters == null) {
throw new IllegalArgumentException(
"This only works with an array of parameters");
}
int numParameters = targetParameters.length;
Object parametersAsJavaObjects[] = new Object[numParameters];
for ( int parameterIndex = 0 ; parameterIndex < numParameters; parameterIndex++){
for (int parameterIndex = 0; parameterIndex < numParameters; parameterIndex++) {
Variant oneParameterObject = targetParameters[parameterIndex];
if (oneParameterObject == null){
if (oneParameterObject == null) {
parametersAsJavaObjects[parameterIndex] = null;
} else {
try {
parametersAsJavaObjects[parameterIndex] = oneParameterObject.toJavaObject();
} catch (NotImplementedException nie){
throw new IllegalArgumentException("Can't convert parameter "+parameterIndex+
" type "+oneParameterObject.getvt()
+" to java object: "+nie.getMessage());
parametersAsJavaObjects[parameterIndex] = oneParameterObject
.toJavaObject();
} catch (NotImplementedException nie) {
throw new IllegalArgumentException(
"Can't convert parameter " + parameterIndex
+ " type " + oneParameterObject.getvt()
+ " to java object: " + nie.getMessage());
}
}
}
return parametersAsJavaObjects;
}
}

View File

@@ -22,111 +22,120 @@ package com.jacob.com;
/**
* Standard exception thrown by com jni code when there is a problem
*/
public abstract class ComException extends JacobException
{
// Fields
/** COM code initializes this filed with an appropriate return code
* that was returned by the underlying com code
**/
protected int hr;
/** No documentation is available at this time. Someone should document this field */
protected int m_helpContext;
/** No documentation is available at this time. Someone should document this field */
protected String m_helpFile;
/** No documentation is available at this time. Someone should document this field */
protected String m_source;
public abstract class ComException extends JacobException {
/**
* constructor
*
*/
public ComException() {
super();
}
/**
* COM code initializes this filed with an appropriate return code that was
* returned by the underlying com code
*/
protected int hr;
/**
* No documentation is available at this time. Someone should document this
* field
*/
protected int m_helpContext;
/**
* No documentation is available at this time. Someone should document this
* field
*/
protected String m_helpFile;
/**
* No documentation is available at this time. Someone should document this
* field
*/
protected String m_source;
/**
* constructor with error code?
*
* @param newHr ??
*/
public ComException(int newHr) {
super();
this.hr = newHr;
}
/**
* constructor
*
*/
public ComException() {
super();
}
/**
* @param newHr
* @param description
*/
public ComException(int newHr, String description) {
super(description);
this.hr = newHr;
}
/**
* constructor with error code?
*
* @param newHr ??
*/
public ComException(int newHr) {
super();
this.hr = newHr;
}
/**
* @param newHr
* @param source
* @param helpFile
* @param helpContext
*/
public ComException(int newHr, String source, String helpFile,
int helpContext) {
super();
this.hr = newHr;
m_source = source;
m_helpFile = helpFile;
m_helpContext = helpContext;
}
/**
* @param newHr
* @param description
*/
public ComException(int newHr, String description) {
super(description);
this.hr = newHr;
}
/**
* @param newHr
* @param description
* @param source
* @param helpFile
* @param helpContext
*/
public ComException(int newHr, String description, String source,
String helpFile, int helpContext) {
super(description);
this.hr = newHr;
m_source = source;
m_helpFile = helpFile;
m_helpContext = helpContext;
}
/**
* @param newHr
* @param source
* @param helpFile
* @param helpContext
*/
public ComException(int newHr, String source, String helpFile,
int helpContext) {
super();
this.hr = newHr;
m_source = source;
m_helpFile = helpFile;
m_helpContext = helpContext;
}
/**
* @param description
*/
public ComException(String description) {
super(description);
}
/**
* @param newHr
* @param description
* @param source
* @param helpFile
* @param helpContext
*/
public ComException(int newHr, String description, String source,
String helpFile, int helpContext) {
super(description);
this.hr = newHr;
m_source = source;
m_helpFile = helpFile;
m_helpContext = helpContext;
}
/**
* @return int representation of the help context
*/
// Methods
public int getHelpContext() {
return m_helpContext;
}
/**
* @param description
*/
public ComException(String description) {
super(description);
}
/**
* @return String ??? help file
*/
public String getHelpFile() {
return m_helpFile;
}
/**
* @return int representation of the help context
*/
// Methods
public int getHelpContext() {
return m_helpContext;
}
/**
* @return int hr result ??
*/
public int getHResult() {
return hr;
}
/**
* @return String ??? help file
*/
public String getHelpFile() {
return m_helpFile;
}
/**
* @return String source ??
*/
public String getSource() {
return m_source;
}
/**
* @return int hr result ??
*/
public int getHResult() {
return hr;
}
/**
* @return String source ??
*/
public String getSource() {
return m_source;
}
}

View File

@@ -23,63 +23,66 @@ package com.jacob.com;
* COM Fail Exception class raised when there is a problem
*/
public class ComFailException extends ComException {
/**
/**
* eclipse generated to get rid of a wanring
*/
private static final long serialVersionUID = -266047261992987700L;
/**
* Constructor
* @param hrNew
*/
public ComFailException(int hrNew) {
super(hrNew);
}
*
* @param hrNew
*/
public ComFailException(int hrNew) {
super(hrNew);
}
/**
* Constructor
* @param hrNew
* @param message
*/
public ComFailException(int hrNew, String message) {
super(hrNew, message);
}
/**
* Constructor
*
* @param hrNew
* @param message
*/
public ComFailException(int hrNew, String message) {
super(hrNew, message);
}
/**
* @param hrNew
* @param source
* @param helpFile
* @param helpContext
*/
public ComFailException(int hrNew, String source, String helpFile,
int helpContext) {
super(hrNew, source, helpFile, helpContext);
}
/**
* @param hrNew
* @param source
* @param helpFile
* @param helpContext
*/
public ComFailException(int hrNew, String source, String helpFile,
int helpContext) {
super(hrNew, source, helpFile, helpContext);
}
/**
* Constructor
* @param hrNew
* @param description
* @param source
* @param helpFile
* @param helpContext
*/
public ComFailException(int hrNew, String description, String source,
String helpFile, int helpContext) {
super(hrNew, description, source, helpFile, helpContext);
}
/**
* Constructor
*
* @param hrNew
* @param description
* @param source
* @param helpFile
* @param helpContext
*/
public ComFailException(int hrNew, String description, String source,
String helpFile, int helpContext) {
super(hrNew, description, source, helpFile, helpContext);
}
/**
* No argument Constructor
*/
public ComFailException() {
super();
}
/**
* No argument Constructor
*/
public ComFailException() {
super();
}
/**
* @param message
*/
public ComFailException(String message) {
super(message);
}
/**
* @param message
*/
public ComFailException(String message) {
super(message);
}
}

View File

@@ -20,135 +20,150 @@
package com.jacob.com;
/**
* Represents a COM level thread
* This is an abstract class because all the methods are static
* and no instances are ever created.
* Represents a COM level thread This is an abstract class because all the
* methods are static and no instances are ever created.
*/
public abstract class ComThread {
private static final int MTA = 0x0;
private static final int MTA = 0x0;
private static final int STA = 0x2;
private static final int STA = 0x2;
/**
* Comment for <code>haveSTA</code>
*/
public static boolean haveSTA = false;
/**
* Comment for <code>haveSTA</code>
*/
public static boolean haveSTA = false;
/**
* Comment for <code>mainSTA</code>
*/
public static MainSTA mainSTA = null;
/**
* Comment for <code>mainSTA</code>
*/
public static MainSTA mainSTA = null;
/**
* Initialize the current java thread to be part of the Multi-threaded COM
* Apartment
*/
public static synchronized void InitMTA() {
InitMTA(false);
}
/**
* Initialize the current java thread to be part of the Multi-threaded COM
* Apartment
*/
public static synchronized void InitMTA() {
InitMTA(false);
}
/**
* Initialize the current java thread to be an STA
*/
public static synchronized void InitSTA() {
InitSTA(false);
}
/**
* Initialize the current java thread to be an STA
*/
public static synchronized void InitSTA() {
InitSTA(false);
}
/**
* Initialize the current java thread to be part of the Multi-threaded COM
* Apartment, if createMainSTA is true, create a separate MainSTA thread
* that will house all Apartment Threaded components
* @param createMainSTA
*/
public static synchronized void InitMTA(boolean createMainSTA) {
Init(createMainSTA, MTA);
}
/**
* Initialize the current java thread to be part of the Multi-threaded COM
* Apartment, if createMainSTA is true, create a separate MainSTA thread
* that will house all Apartment Threaded components
*
* @param createMainSTA
*/
public static synchronized void InitMTA(boolean createMainSTA) {
Init(createMainSTA, MTA);
}
/**
* Initialize the current java thread to be an STA COM Apartment, if
* createMainSTA is true, create a separate MainSTA thread that will house
* all Apartment Threaded components
* @param createMainSTA
*/
public static synchronized void InitSTA(boolean createMainSTA) {
Init(createMainSTA, STA);
}
/**
* Initialize the current java thread to be an STA COM Apartment, if
* createMainSTA is true, create a separate MainSTA thread that will house
* all Apartment Threaded components
*
* @param createMainSTA
*/
public static synchronized void InitSTA(boolean createMainSTA) {
Init(createMainSTA, STA);
}
/**
*
*/
public static synchronized void startMainSTA() {
mainSTA = new MainSTA();
haveSTA = true;
}
/**
*
*/
public static synchronized void startMainSTA() {
mainSTA = new MainSTA();
haveSTA = true;
}
/**
*
*/
public static synchronized void quitMainSTA() {
if (mainSTA != null)
mainSTA.quit();
}
/**
*
*/
public static synchronized void quitMainSTA() {
if (mainSTA != null)
mainSTA.quit();
}
/**
* Initialize the current java thread to be part of the MTA/STA COM
* Apartment
* @param createMainSTA
* @param mode
*/
public static synchronized void Init(boolean createMainSTA, int mode) {
if (createMainSTA && !haveSTA) {
// if the current thread is going to be in the MTA and there
// is no STA thread yet, then create a main STA thread
// to avoid COM creating its own
startMainSTA();
}
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: before Init: "+mode);}
doCoInitialize(mode);
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after Init: "+mode);}
ROT.addThread();
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after ROT.addThread: "+mode); }
}
/**
* Initialize the current java thread to be part of the MTA/STA COM
* Apartment
*
* @param createMainSTA
* @param mode
*/
public static synchronized void Init(boolean createMainSTA, int mode) {
if (createMainSTA && !haveSTA) {
// if the current thread is going to be in the MTA and there
// is no STA thread yet, then create a main STA thread
// to avoid COM creating its own
startMainSTA();
}
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: before Init: " + mode);
}
doCoInitialize(mode);
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: after Init: " + mode);
}
ROT.addThread();
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: after ROT.addThread: " + mode);
}
}
/**
* Call CoUninitialize to release this java thread from COM
*/
public static synchronized void Release() {
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: before clearObjects"); }
ROT.clearObjects();
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: before UnInit"); }
doCoUninitialize();
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after UnInit"); }
}
/**
* @deprecated the java model leave the responsibility of clearing up objects
* to the Garbage Collector. Our programming model should not require that the
* user specifically remove object from the thread.
*
* This will remove an object from the ROT
* @param o
*/
public static synchronized void RemoveObject(JacobObject o)
{
ROT.removeObject(o);
}
/**
* Call CoUninitialize to release this java thread from COM
*/
public static synchronized void Release() {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: before clearObjects");
}
ROT.clearObjects();
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: before UnInit");
}
doCoUninitialize();
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ComThread: after UnInit");
}
}
/**
* @param threadModel
*/
public static native void doCoInitialize(int threadModel);
/**
* @deprecated the java model leave the responsibility of clearing up
* objects to the Garbage Collector. Our programming model
* should not require that the user specifically remove object
* from the thread.
*
* This will remove an object from the ROT
* @param o
*/
@Deprecated
public static synchronized void RemoveObject(JacobObject o) {
ROT.removeObject(o);
}
/**
*
*/
public static native void doCoUninitialize();
/**
* @param threadModel
*/
public static native void doCoInitialize(int threadModel);
/**
* load the Jacob DLL. We do this in case COMThread is called before
* any other reference to one of the JacboObject subclasses is made.
*/
static {
LibraryLoader.loadJacobLibrary();
}
/**
*
*/
public static native void doCoUninitialize();
/**
* load the Jacob DLL. We do this in case COMThread is called before any
* other reference to one of the JacboObject subclasses is made.
*/
static {
LibraryLoader.loadJacobLibrary();
}
}

View File

@@ -0,0 +1,91 @@
package com.jacob.com;
/**
* Most COM bridges use java.lang.Long as their Java data type for COM Currency
* data. This is because COM currency is a 64 bit number where the last 4 digits
* represent the milli-cents. We wanted to support 64 bit Long values for x64
* platforms so that meant we wanted to map Java.LONG to COM.LONG even though it
* only works for 64 bit platforms. The end result was we needed a new
* representation for Money so we have this.
* <p>
* In the future, this should convert to and from BigDecimal or Double
*/
public class Currency {
Long embeddedValue = null;
/**
* constructor that takes a long already in COM representation
*
* @param newValue
*/
public Currency(long newValue) {
embeddedValue = new Long(newValue);
}
/**
* constructor that takes a String already in COM representation
*
* @param newValue
*/
public Currency(String newValue) {
embeddedValue = new Long(newValue);
}
/**
*
* @return the currency as a primitive long
*/
public long longValue() {
return embeddedValue.longValue();
}
/**
* getter to the inner storage so that cmpareTo can work
*
* @return the embedded long value
*/
protected Long getLongValue() {
return embeddedValue;
}
/**
* compares the values of two currencies
*
* @param anotherCurrency
* @return the usual compareTo results
*/
public int compareTo(Currency anotherCurrency) {
return embeddedValue.compareTo(anotherCurrency.getLongValue());
}
/**
* standard comparison
*
* @param o
* must be Currency or Long
* @return the usual compareTo results
*/
public int compareTo(Object o) {
if (o instanceof Currency) {
return compareTo((Currency) o);
} else if (o instanceof Long) {
return embeddedValue.compareTo((Long) o);
} else
throw new IllegalArgumentException(
"Can only compare to Long and Currency not "
+ o.getClass().getName());
}
/**
* {@inheritDoc}
*/
public boolean equals(Object o) {
if (o == null) {
return false;
} else if (compareTo(o) == 0) {
return true;
} else {
return false;
}
}
}

View File

@@ -24,29 +24,30 @@ import java.util.Date;
/**
* java / windows date conversion utilities
*
* @author joe
*
*
*/
public class DateUtilities {
/**
* converts a windows time to a Java Date Object
*
* @param comTime
* @return Date object representing the windows time as specified in comTime
*/
static public Date convertWindowsTimeToDate(double comTime){
return new Date(convertWindowsTimeToMilliseconds (comTime));
static public Date convertWindowsTimeToDate(double comTime) {
return new Date(convertWindowsTimeToMilliseconds(comTime));
}
/**
* Convert a COM time from functions Date(), Time(), Now() to a
* Java time (milliseconds). Visual Basic time values are based to
* 30.12.1899, Java time values are based to 1.1.1970 (= 0
* milliseconds). The difference is added to the Visual Basic value to
* get the corresponding Java value. The Visual Basic double value
* reads: <day count delta since 30.12.1899>.<1 day percentage
* fraction>, e.g. "38100.6453" means: 38100 days since 30.12.1899 plus
* (24 hours * 0.6453). Example usage:
/**
* Convert a COM time from functions Date(), Time(), Now() to a Java time
* (milliseconds). Visual Basic time values are based to 30.12.1899, Java
* time values are based to 1.1.1970 (= 0 milliseconds). The difference is
* added to the Visual Basic value to get the corresponding Java value. The
* Visual Basic double value reads: <day count delta since 30.12.1899>.<1
* day percentage fraction>, e.g. "38100.6453" means: 38100 days since
* 30.12.1899 plus (24 hours * 0.6453). Example usage:
* <code>Date javaDate = new Date(toMilliseconds (vbDate));</code>.
*
* @param comTime
@@ -68,19 +69,20 @@ public class DateUtilities {
}// convertWindowsTimeToMilliseconds()
/**
* converts a java date to a windows time object
* (is this timezone safe?)
* converts a java date to a windows time object (is this timezone safe?)
*
* @param javaDate the java date to be converted to windows time
* @param javaDate
* the java date to be converted to windows time
* @return the double representing the date in a form windows understands
*/
static public double convertDateToWindowsTime(Date javaDate){
if (javaDate == null){
throw new IllegalArgumentException("cannot convert null to windows time");
static public double convertDateToWindowsTime(Date javaDate) {
if (javaDate == null) {
throw new IllegalArgumentException(
"cannot convert null to windows time");
}
return convertMillisecondsToWindowsTime(javaDate.getTime());
}
/**
* Convert a Java time to a COM time.
*
@@ -99,5 +101,5 @@ public class DateUtilities {
result = (milliseconds / 86400000D) + 25569D;
return result;
}//convertMillisecondsToWindowsTime()
}// convertMillisecondsToWindowsTime()
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,177 +20,200 @@
package com.jacob.com;
/**
* This class creates the scaffolding for event callbacks.
* Every instance of tis acts as a wrapper around some java object
* that wants callbacks from the microsoft side. It represents
* the connection between Java and COM for callbacks.
* This class creates the scaffolding for event callbacks. Every instance of tis
* acts as a wrapper around some java object that wants callbacks from the
* microsoft side. It represents the connection between Java and COM for
* callbacks.
* <p>
* The callback mechanism will take any event that it receives and
* try and find a java method with the same name that accepts the
* Variant... as a parameter. It will then wrap the call back data
* in the Variant array and call the java method of the object
* that this DispatchEvents object was initialized with.
* The callback mechanism will take any event that it receives and try and find
* a java method with the same name that accepts the Variant... as a parameter.
* It will then wrap the call back data in the Variant array and call the java
* method of the object that this DispatchEvents object was initialized with.
* <p>
* Instances of this class are created with "sink object" that
* will receive the event messages. The sink object is wrapped in
* an Invocation handler that actually receives the messages and then
* forwards them on to the "sink object". The constructors recognize when
* an instance of InvocationProxy is passed in and do not create
* a new InvocationProxy as a wrapper. They instead use the passed in
* InvocationProxy.
* Instances of this class are created with "sink object" that will receive the
* event messages. The sink object is wrapped in an Invocation handler that
* actually receives the messages and then forwards them on to the "sink
* object". The constructors recognize when an instance of InvocationProxy is
* passed in and do not create a new InvocationProxy as a wrapper. They instead
* use the passed in InvocationProxy.
*
*/
public class DispatchEvents extends JacobObject {
/**
* pointer to an MS data struct.
* The COM layer knows the name of this variable and puts the windows
* memory pointer here.
*/
int m_pConnPtProxy = 0;
/**
* the wrapper for the event sink.
* This object is the one that will be sent a message when an event
* occurs in the MS layer. Normally, the InvocationProxy will forward
* the messages to a wrapped object that it contains.
*/
InvocationProxy mInvocationProxy = null;
/**
* This is the most commonly used constructor.
* <p>
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* <p>
* Can be used on any object that implements IProvideClassInfo.
*
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink) {
this(sourceOfEvent, eventSink, null );
}
/**
* pointer to an MS data struct. The COM layer knows the name of this
* variable and puts the windows memory pointer here.
*/
int m_pConnPtProxy = 0;
/**
* None of the samples use this constructor.
* <p>
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* <p>
* Used when the program doesn't implement IProvideClassInfo. It provides
* a way to find the TypeLib in the registry based on the programId. The TypeLib
* is looked up in the registry on the path
* HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/(CLID drived from progid)/ProgID/Typelib
*
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
* @param progId program id in the registry that has a TypeLib subkey.
* The progrId is mapped to a CLSID that is they used to look up the key to the Typelib
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink, String progId) {
this(sourceOfEvent, eventSink, progId, null );
}
/**
* the wrapper for the event sink. This object is the one that will be sent
* a message when an event occurs in the MS layer. Normally, the
* InvocationProxy will forward the messages to a wrapped object that it
* contains.
*/
InvocationProxy mInvocationProxy = null;
/**
* Creates the event callback linkage between the the
* MS program represented by the Dispatch object and the
* Java object that will receive the callback.
* <p>
* This method was added because Excel doesn't implement IProvideClassInfo
* and the registry entry for Excel.Application doesn't include a typelib key.
*
* <pre>
* DispatchEvents de =
* new DispatchEvents(someDispatch,someEventHAndler,
* "Excel.Application",
* "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
* </pre>
* @param sourceOfEvent Dispatch object who's MS app will generate callbacks
* @param eventSink Java object that wants to receive the events
* @param progId , mandatory if the typelib is specified
* @param typeLib The location of the typelib to use
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink, String progId, String typeLib)
{
if (JacobObject.isDebugEnabled()){
System.out.println(
"DispatchEvents: Registering "+ eventSink + "for events ");
/**
* This is the most commonly used constructor.
* <p>
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
* <p>
* Can be used on any object that implements IProvideClassInfo.
*
* @param sourceOfEvent
* Dispatch object who's MS app will generate callbacks
* @param eventSink
* Java object that wants to receive the events
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink) {
this(sourceOfEvent, eventSink, null);
}
/**
* None of the samples use this constructor.
* <p>
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
* <p>
* Used when the program doesn't implement IProvideClassInfo. It provides a
* way to find the TypeLib in the registry based on the programId. The
* TypeLib is looked up in the registry on the path
* HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/(CLID drived from
* progid)/ProgID/Typelib
*
* @param sourceOfEvent
* Dispatch object who's MS app will generate callbacks
* @param eventSink
* Java object that wants to receive the events
* @param progId
* program id in the registry that has a TypeLib subkey. The
* progrId is mapped to a CLSID that is they used to look up the
* key to the Typelib
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink,
String progId) {
this(sourceOfEvent, eventSink, progId, null);
}
/**
* Creates the event callback linkage between the the MS program represented
* by the Dispatch object and the Java object that will receive the
* callback.
* <p>
* This method was added because Excel doesn't implement IProvideClassInfo
* and the registry entry for Excel.Application doesn't include a typelib
* key.
*
* <pre>
* DispatchEvents de = new DispatchEvents(someDispatch, someEventHAndler,
* &quot;Excel.Application&quot;,
* &quot;C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE&quot;);
* </pre>
*
* @param sourceOfEvent
* Dispatch object who's MS app will generate callbacks
* @param eventSink
* Java object that wants to receive the events
* @param progId ,
* mandatory if the typelib is specified
* @param typeLib
* The location of the typelib to use
*/
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink,
String progId, String typeLib) {
if (JacobObject.isDebugEnabled()) {
System.out.println("DispatchEvents: Registering " + eventSink
+ "for events ");
}
if (eventSink instanceof InvocationProxy) {
mInvocationProxy = (InvocationProxy) eventSink;
} else {
mInvocationProxy = getInvocationProxy(eventSink);
}
if (mInvocationProxy != null) {
init3(sourceOfEvent, mInvocationProxy, progId, typeLib);
if (mInvocationProxy != null) {
init3(sourceOfEvent, mInvocationProxy, progId, typeLib);
} else {
if (JacobObject.isDebugEnabled()){
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("Cannot register null event sink for events");
}
throw new IllegalArgumentException("Cannot register null event sink for events");
throw new IllegalArgumentException(
"Cannot register null event sink for events");
}
}
}
/**
* Returns an instance of the proxy configured with pTargetObject as its target
* @param pTargetObject
* @return InvocationProxy an instance of the proxy this DispatchEvents will send to the COM layer
*/
protected InvocationProxy getInvocationProxy(Object pTargetObject){
/**
* Returns an instance of the proxy configured with pTargetObject as its
* target
*
* @param pTargetObject
* @return InvocationProxy an instance of the proxy this DispatchEvents will
* send to the COM layer
*/
protected InvocationProxy getInvocationProxy(Object pTargetObject) {
InvocationProxy newProxy = new InvocationProxyAllVariants();
newProxy.setTarget(pTargetObject);
return newProxy;
}
/**
* hooks up a connection point proxy by progId
* event methods on the sink object will be called
* by name with a signature of <name>(Variant[] args)
*
* You must specify the location of the typeLib.
*
* @param src dispatch that is the source of the messages
* @param sink the object that will receive the messages
* @param progId optional program id. most folks don't need this either
* @param typeLib optional parameter for those programs that don't register their type libs (like Excel)
*/
private native void init3(Dispatch src, Object sink, String progId, String typeLib);
* hooks up a connection point proxy by progId event methods on the sink
* object will be called by name with a signature of <name>(Variant[] args)
*
* You must specify the location of the typeLib.
*
* @param src
* dispatch that is the source of the messages
* @param sink
* the object that will receive the messages
* @param progId
* optional program id. most folks don't need this either
* @param typeLib
* optional parameter for those programs that don't register
* their type libs (like Excel)
*/
private native void init3(Dispatch src, Object sink, String progId,
String typeLib);
/**
* now private so only this object can asccess
* was: call this to explicitly release the com object before gc
*
*/
private native void release();
/*
* (non-Javadoc)
* @see java.lang.Object#finalize()
*/
protected void finalize() {
safeRelease();
}
/*
* (non-Javadoc)
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease(){
if (mInvocationProxy!=null){
mInvocationProxy.setTarget(null);
}
mInvocationProxy = null;
super.safeRelease();
if (m_pConnPtProxy != 0){
release();
m_pConnPtProxy = 0;
} else {
// looks like a double release
if (isDebugEnabled()){debug("DispatchEvents:"+this.hashCode()+" double release");}
}
}
/**
* now private so only this object can asccess was: call this to explicitly
* release the com object before gc
*
*/
private native void release();
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
protected void finalize() {
safeRelease();
}
/*
* (non-Javadoc)
*
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease() {
if (mInvocationProxy != null) {
mInvocationProxy.setTarget(null);
}
mInvocationProxy = null;
super.safeRelease();
if (m_pConnPtProxy != 0) {
release();
m_pConnPtProxy = 0;
} else {
// looks like a double release
if (isDebugEnabled()) {
debug("DispatchEvents:" + this.hashCode() + " double release");
}
}
}
}

View File

@@ -0,0 +1,82 @@
/**
*
*/
package com.jacob.com;
/**
* A bunch of DispatchIds that were pulled out of the Dispatch class for version
* 1.14.
*/
public class DispatchIdentifier {
private DispatchIdentifier() {
// This is utility class so there is no constructor.
}
public static final int DISPID_UNKNOWN = -1;
public static final int DISPID_VALUE = 0;
public static final int DISPID_PROPERTYPUT = -3;
public static final int DISPID_NEWENUM = -4;
public static final int DISPID_EVALUATE = -5;
public static final int DISPID_CONSTRUCTOR = -6;
public static final int DISPID_DESTRUCTOR = -7;
public static final int DISPID_COLLECT = -8;
public static final int DISPID_AUTOSIZE = -500;
public static final int DISPID_BACKCOLOR = -501;
public static final int DISPID_BACKSTYLE = -502;
public static final int DISPID_BORDERCOLOR = -503;
public static final int DISPID_BORDERSTYLE = -504;
public static final int DISPID_BORDERWIDTH = -505;
public static final int DISPID_DRAWMODE = -507;
public static final int DISPID_DRAWSTYLE = -508;
public static final int DISPID_DRAWWIDTH = -509;
public static final int DISPID_FILLCOLOR = -510;
public static final int DISPID_FILLSTYLE = -511;
public static final int DISPID_FONT = -512;
public static final int DISPID_FORECOLOR = -513;
public static final int DISPID_ENABLED = -514;
public static final int DISPID_HWND = -515;
public static final int DISPID_TABSTOP = -516;
public static final int DISPID_TEXT = -517;
public static final int DISPID_CAPTION = -518;
public static final int DISPID_BORDERVISIBLE = -519;
public static final int DISPID_APPEARANCE = -520;
public static final int DISPID_MOUSEPOINTER = -521;
public static final int DISPID_MOUSEICON = -522;
public static final int DISPID_PICTURE = -523;
public static final int DISPID_VALID = -524;
public static final int DISPID_READYSTATE = -525;
public static final int DISPID_REFRESH = -550;
public static final int DISPID_DOCLICK = -551;
public static final int DISPID_ABOUTBOX = -552;
public static final int DISPID_CLICK = -600;
public static final int DISPID_DBLCLICK = -601;
public static final int DISPID_KEYDOWN = -602;
public static final int DISPID_KEYPRESS = -603;
public static final int DISPID_KEYUP = -604;
public static final int DISPID_MOUSEDOWN = -605;
public static final int DISPID_MOUSEMOVE = -606;
public static final int DISPID_MOUSEUP = -607;
public static final int DISPID_ERROREVENT = -608;
public static final int DISPID_READYSTATECHANGE = -609;
public static final int DISPID_AMBIENT_BACKCOLOR = -701;
public static final int DISPID_AMBIENT_DISPLAYNAME = -702;
public static final int DISPID_AMBIENT_FONT = -703;
public static final int DISPID_AMBIENT_FORECOLOR = -704;
public static final int DISPID_AMBIENT_LOCALEID = -705;
public static final int DISPID_AMBIENT_MESSAGEREFLECT = -706;
public static final int DISPID_AMBIENT_SCALEUNITS = -707;
public static final int DISPID_AMBIENT_TEXTALIGN = -708;
public static final int DISPID_AMBIENT_USERMODE = -709;
public static final int DISPID_AMBIENT_UIDEAD = -710;
public static final int DISPID_AMBIENT_SHOWGRABHANDLES = -711;
public static final int DISPID_AMBIENT_SHOWHATCHING = -712;
public static final int DISPID_AMBIENT_DISPLAYASDEFAULT = -713;
public static final int DISPID_AMBIENT_SUPPORTSMNEMONICS = -714;
public static final int DISPID_AMBIENT_AUTOCLIP = -715;
public static final int DISPID_AMBIENT_APPEARANCE = -716;
public static final int DISPID_AMBIENT_CODEPAGE = -725;
public static final int DISPID_AMBIENT_PALETTE = -726;
public static final int DISPID_AMBIENT_CHARSET = -727;
public static final int DISPID_AMBIENT_TRANSFERPRIORITY = -728;
}

View File

@@ -29,58 +29,64 @@ package com.jacob.com;
* construct a separate DispatchProxy instance for each such case!
*/
public class DispatchProxy extends JacobObject {
/**
* Comment for <code>m_pStream</code>
*/
public int m_pStream;
/**
* Comment for <code>m_pStream</code>
*/
public int m_pStream;
/**
* Marshals the passed in dispatch into the stream
* @param localDispatch
*/
public DispatchProxy(Dispatch localDispatch) {
MarshalIntoStream(localDispatch);
}
/**
* Marshals the passed in dispatch into the stream
*
* @param localDispatch
*/
public DispatchProxy(Dispatch localDispatch) {
MarshalIntoStream(localDispatch);
}
/**
*
* @return Dispatch the dispatch retrieved from the stream
*/
public Dispatch toDispatch() {
return MarshalFromStream();
}
/**
*
* @return Dispatch the dispatch retrieved from the stream
*/
public Dispatch toDispatch() {
return MarshalFromStream();
}
private native void MarshalIntoStream(Dispatch d);
private native void MarshalIntoStream(Dispatch d);
private native Dispatch MarshalFromStream();
private native Dispatch MarshalFromStream();
/**
* now private so only this object can asccess
* was: call this to explicitly release the com object before gc
*
*/
private native void release();
/**
* now private so only this object can access was: call this to explicitly
* release the com object before gc
*
*/
private native void release();
/* (non-Javadoc)
* @see java.lang.Object#finalize()
*/
public void finalize() {
safeRelease();
}
/*
* (non-Javadoc)
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease()
{
super.safeRelease();
if (m_pStream != 0){
release();
m_pStream = 0;
} else {
// looks like a double release
if (isDebugEnabled()){debug(this.getClass().getName()+":"+this.hashCode()+" double release");}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
public void finalize() {
safeRelease();
}
/*
* (non-Javadoc)
*
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease() {
super.safeRelease();
if (m_pStream != 0) {
release();
m_pStream = 0;
} else {
// looks like a double release
if (isDebugEnabled()) {
debug(this.getClass().getName() + ":" + this.hashCode()
+ " double release");
}
}
}
}

View File

@@ -23,121 +23,134 @@ package com.jacob.com;
* An implementation of IEnumVariant based on code submitted by Thomas Hallgren
* (mailto:Thomas.Hallgren@eoncompany.com)
*/
public class EnumVariant extends JacobObject implements java.util.Enumeration {
private int m_pIEnumVARIANT;
public class EnumVariant extends JacobObject implements
java.util.Enumeration<Variant> {
private int m_pIEnumVARIANT;
private final Variant[] m_recBuf = new Variant[1];
private final Variant[] m_recBuf = new Variant[1];
// this only gets called from JNI
//
protected EnumVariant(int pIEnumVARIANT) {
m_pIEnumVARIANT = pIEnumVARIANT;
}
// this only gets called from JNI
//
protected EnumVariant(int pIEnumVARIANT) {
m_pIEnumVARIANT = pIEnumVARIANT;
}
/**
* @param disp
*/
public EnumVariant(Dispatch disp) {
int[] hres = new int[1];
Variant evv = Dispatch.invokev(disp,
Dispatch.DISPID_NEWENUM,
Dispatch.Get,
new Variant[0], hres);
if (evv.getvt() != Variant.VariantObject)
//
// The DISPID_NEWENUM did not result in a valid object
//
throw new ComFailException("Can't obtain EnumVARIANT");
/**
* @param disp
*/
public EnumVariant(Dispatch disp) {
int[] hres = new int[1];
Variant evv = Dispatch.invokev(disp, DispatchIdentifier.DISPID_NEWENUM,
Dispatch.Get, new Variant[0], hres);
if (evv.getvt() != Variant.VariantObject)
//
// The DISPID_NEWENUM did not result in a valid object
//
throw new ComFailException("Can't obtain EnumVARIANT");
EnumVariant tmp = evv.toEnumVariant();
m_pIEnumVARIANT = tmp.m_pIEnumVARIANT;
tmp.m_pIEnumVARIANT = 0;
}
EnumVariant tmp = evv.toEnumVariant();
m_pIEnumVARIANT = tmp.m_pIEnumVARIANT;
tmp.m_pIEnumVARIANT = 0;
}
/**
* Implements java.util.Enumeration
* @return boolean true if there are more elements in ths enumeration
*/
public boolean hasMoreElements() {
{
if (m_recBuf[0] == null) {
if (this.Next(m_recBuf) <= 0)
return false;
}
return true;
}
}
/**
* Implements java.util.Enumeration
*
* @return boolean true if there are more elements in this enumeration
*/
public boolean hasMoreElements() {
{
if (m_recBuf[0] == null) {
if (this.Next(m_recBuf) <= 0)
return false;
}
return true;
}
}
/**
* Implements java.util.Enumeration
* @return next element in the enumeration
*/
public Object nextElement() {
Object last = m_recBuf[0];
if (last == null) {
if (this.Next(m_recBuf) <= 0)
throw new java.util.NoSuchElementException();
last = m_recBuf[0];
}
m_recBuf[0] = null;
return last;
}
/**
* Implements java.util.Enumeration
*
* @return next element in the enumeration
*/
public Variant nextElement() {
Variant last = m_recBuf[0];
if (last == null) {
if (this.Next(m_recBuf) <= 0)
throw new java.util.NoSuchElementException();
last = m_recBuf[0];
}
m_recBuf[0] = null;
return last;
}
/**
* Get next element in collection or null if at end
* @return Variant that is next in the collection
*/
public Variant Next() {
if (hasMoreElements())
return (Variant) nextElement();
return null;
}
/**
* Get next element in collection or null if at end
*
* @return Variant that is next in the collection
* @deprecated use nextElement() instead
*/
@Deprecated
public Variant Next() {
if (hasMoreElements())
return nextElement();
return null;
}
/**
* @param receiverArray
* @return don't know what the int is that is returned, help!
*/
public native int Next(Variant[] receiverArray);
/**
* This should be private and wrapped to protect JNI layer.
*
* @param receiverArray
* @return Returns the next variant object pointer as an int from windows
* layer
*/
public native int Next(Variant[] receiverArray);
/**
* @param count
*/
public native void Skip(int count);
/**
* This should be private and wrapped to protect JNI layer.
*
* @param count
* number to skip
*/
public native void Skip(int count);
/**
*
*/
public native void Reset();
/**
* This should be private and wrapped to protect JNI layer
*/
public native void Reset();
/**
* now private so only this object can asccess
* was: call this to explicitly release the com object before gc
*
*/
private native void release();
/**
* now private so only this object can access was: call this to explicitly
* release the com object before gc
*
*/
private native void release();
/*
* (non-Javadoc)
* @see java.lang.Object#finalize()
*/
protected void finalize()
{
safeRelease();
}
/*
* (non-Javadoc)
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease()
{
super.safeRelease();
if (m_pIEnumVARIANT != 0){
this.release();
m_pIEnumVARIANT = 0;
} else {
// looks like a double release
if (isDebugEnabled()){debug(this.getClass().getName()+":"+this.hashCode()+" double release");}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
protected void finalize() {
safeRelease();
}
/*
* (non-Javadoc)
*
* @see com.jacob.com.JacobObject#safeRelease()
*/
public void safeRelease() {
super.safeRelease();
if (m_pIEnumVARIANT != 0) {
this.release();
m_pIEnumVARIANT = 0;
} else {
// looks like a double release
if (isDebugEnabled()) {
debug(this.getClass().getName() + ":" + this.hashCode()
+ " double release");
}
}
}
}

View File

@@ -23,20 +23,19 @@ package com.jacob.com;
* @version $Id$
* @author joe
*
* DispatchEvents wraps this class around any event handlers
* before making the JNI call that sets up the link with EventProxy.
* This means that EventProxy.cpp just calls invoke(String,Variant[])
* against the instance of this class. Then this class does
* reflection against the event listener to call the actual event methods.
* The event methods can return void or return a Variant. Any
* value returned will be passed back to the calling windows module
* DispatchEvents wraps this class around any event handlers before making the
* JNI call that sets up the link with EventProxy. This means that
* EventProxy.cpp just calls invoke(String,Variant[]) against the instance of
* this class. Then this class does reflection against the event listener to
* call the actual event methods. The event methods can return void or return a
* Variant. Any value returned will be passed back to the calling windows module
* by the Jacob JNI layer.
* <p>
*
* The void returning signature is the standard legacy signature.
* The Variant returning signature was added in 1.10 to support event handlers
* returning values.
*
* The void returning signature is the standard legacy signature. The Variant
* returning signature was added in 1.10 to support event handlers returning
* values.
*
*/
public abstract class InvocationProxy {
@@ -44,58 +43,66 @@ public abstract class InvocationProxy {
* the object we will try and forward to.
*/
protected Object mTargetObject = null;
/**
* dummy constructor for subclasses that don't actually wrap
* anything and just want to override the invoke() method
* dummy constructor for subclasses that don't actually wrap anything and
* just want to override the invoke() method
*/
protected InvocationProxy(){
protected InvocationProxy() {
super();
}
/**
* The method actually invoked by EventProxy.cpp.
* The method name is calculated by the underlying JNI code from the MS windows
* Callback function name. The method is assumed to take an array of Variant
* objects. The method may return a Variant or be a void. Those are the only
* two options that will not blow up.
* <p>
* Subclasses that override this should make sure mTargetObject is not null before processing.
*
* @param methodName name of method in mTargetObject we will invoke
* @param targetParameters Variant[] that is the single parameter to the method
*/
public abstract Variant invoke(String methodName, Variant targetParameters[]);
/**
* used by EventProxy.cpp to create variant objects in the right thread
* @return Variant object that will be used by the COM layer
*/
public Variant getVariant(){
return new VariantViaEvent();
}
/**
* Sets the target for this InvocationProxy.
* @param pTargetObject
* @throws IllegalArgumentException if target is not publicly accessable
*/
public void setTarget(Object pTargetObject){
if (JacobObject.isDebugEnabled()){
JacobObject.debug(
"InvocationProxy: setting target "+pTargetObject);
/**
* The method actually invoked by EventProxy.cpp. The method name is
* calculated by the underlying JNI code from the MS windows Callback
* function name. The method is assumed to take an array of Variant objects.
* The method may return a Variant or be a void. Those are the only two
* options that will not blow up.
* <p>
* Subclasses that override this should make sure mTargetObject is not null
* before processing.
*
* @param methodName
* name of method in mTargetObject we will invoke
* @param targetParameters
* Variant[] that is the single parameter to the method
* @return an object that will be returned to the com event caller
*/
public abstract Variant invoke(String methodName,
Variant targetParameters[]);
/**
* used by EventProxy.cpp to create variant objects in the right thread
*
* @return Variant object that will be used by the COM layer
*/
public Variant getVariant() {
return new VariantViaEvent();
}
/**
* Sets the target for this InvocationProxy.
*
* @param pTargetObject
* @throws IllegalArgumentException
* if target is not publicly accessible
*/
public void setTarget(Object pTargetObject) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("InvocationProxy: setting target "
+ pTargetObject);
}
if (pTargetObject != null){
if (pTargetObject != null) {
// JNI code apparently bypasses this check and could operate against
// protected classes. This seems like a security issue...
// protected classes. This seems like a security issue...
// maybe it was because JNI code isn't in a package?
if (!java.lang.reflect.Modifier.isPublic(
pTargetObject.getClass().getModifiers())){
if (!java.lang.reflect.Modifier.isPublic(pTargetObject.getClass()
.getModifiers())) {
throw new IllegalArgumentException(
"InvocationProxy only public classes can receive event notifications");
"InvocationProxy only public classes can receive event notifications");
}
}
mTargetObject = pTargetObject;
}
}
}

View File

@@ -24,62 +24,69 @@ import java.lang.reflect.Method;
/**
* This class acts as a proxy between the windows event callback mechanism and
* the Java classes that are looking for events. It assumes that
* all of the Java classes that are looking for events implement methods with the
* same names as the windows events and that the implemented methods accept an
* array of variant objects. The methods can return void or a Variant that
* will be returned to the calling layer. All Event methods that will be
* recognized by InvocationProxyAllEvents have the signature
*
* <code> void eventMethodName(Variant[])</code>
* or
* <code> Variant eventMethodName(Variant[])</code>
* the Java classes that are looking for events. It assumes that all of the Java
* classes that are looking for events implement methods with the same names as
* the windows events and that the implemented methods accept an array of
* variant objects. The methods can return void or a Variant that will be
* returned to the calling layer. All Event methods that will be recognized by
* InvocationProxyAllEvents have the signature
*
* <code> void eventMethodName(Variant[])</code> or
* <code> Variant eventMethodName(Variant[])</code>
*/
public class InvocationProxyAllVariants extends InvocationProxy {
/*
* (non-Javadoc)
* @see com.jacob.com.InvocationProxy#invoke(java.lang.String, com.jacob.com.Variant[])
*
* @see com.jacob.com.InvocationProxy#invoke(java.lang.String,
* com.jacob.com.Variant[])
*/
@SuppressWarnings("unchecked")
public Variant invoke(String methodName, Variant targetParameters[]) {
Variant mVariantToBeReturned = null;
if (mTargetObject == null){
if (JacobObject.isDebugEnabled()){
JacobObject.debug(
"InvocationProxy: received notification ("+methodName+") with no target set");
Variant mVariantToBeReturned = null;
if (mTargetObject == null) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("InvocationProxy: received notification ("
+ methodName + ") with no target set");
}
// structured programming guidlines say this return should not be up here
// structured programming guidlines say this return should not be up
// here
return null;
}
Class targetClass = mTargetObject.getClass();
if (methodName == null){
throw new IllegalArgumentException("InvocationProxy: missing method name");
if (methodName == null) {
throw new IllegalArgumentException(
"InvocationProxy: missing method name");
}
if (targetParameters == null){
throw new IllegalArgumentException("InvocationProxy: missing Variant parameters");
if (targetParameters == null) {
throw new IllegalArgumentException(
"InvocationProxy: missing Variant parameters");
}
try {
if (JacobObject.isDebugEnabled()){
JacobObject.debug("InvocationProxy: trying to invoke "+methodName
+" on "+mTargetObject);
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("InvocationProxy: trying to invoke "
+ methodName + " on " + mTargetObject);
}
Method targetMethod;
targetMethod = targetClass.getMethod(methodName,
new Class[] {Variant[].class});
if (targetMethod != null){
new Class[] { Variant[].class });
if (targetMethod != null) {
// protected classes can't be invoked against even if they
// let you grab the method. you could do targetMethod.setAccessible(true);
// let you grab the method. you could do
// targetMethod.setAccessible(true);
// but that should be stopped by the security manager
Object mReturnedByInvocation = null;
mReturnedByInvocation =
targetMethod.invoke(mTargetObject,new Object[] {targetParameters});
if (mReturnedByInvocation == null){
mReturnedByInvocation = targetMethod.invoke(mTargetObject,
new Object[] { targetParameters });
if (mReturnedByInvocation == null) {
mVariantToBeReturned = null;
} else if (!(mReturnedByInvocation instanceof Variant)){
} else if (!(mReturnedByInvocation instanceof Variant)) {
// could try and convert to Variant here.
throw new IllegalArgumentException(
"InvocationProxy: invokation of target method returned "
+"non-null non-variant object: "+mReturnedByInvocation);
+ "non-null non-variant object: "
+ mReturnedByInvocation);
} else {
mVariantToBeReturned = (Variant) mReturnedByInvocation;
}
@@ -88,20 +95,22 @@ public class InvocationProxyAllVariants extends InvocationProxy {
// what causes this exception?
e.printStackTrace();
} catch (NoSuchMethodException e) {
// this happens whenever the listener doesn't implement all the methods
if (JacobObject.isDebugEnabled()){
JacobObject.debug("InvocationProxy: listener ("+mTargetObject+") doesn't implement "
+ methodName);
// this happens whenever the listener doesn't implement all the
// methods
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("InvocationProxy: listener (" + mTargetObject
+ ") doesn't implement " + methodName);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
// we can throw these inside the catch block so need to re-throw it
// we can throw these inside the catch block so need to re-throw it
throw e;
} catch (IllegalAccessException e) {
// can't access the method on the target instance for some reason
if (JacobObject.isDebugEnabled()){
JacobObject.debug("InvocationProxy: probably tried to access public method on non public class"
+ methodName);
if (JacobObject.isDebugEnabled()) {
JacobObject
.debug("InvocationProxy: probably tried to access public method on non public class"
+ methodName);
}
e.printStackTrace();
} catch (InvocationTargetException e) {
@@ -109,6 +118,6 @@ public class InvocationProxyAllVariants extends InvocationProxy {
e.printStackTrace();
}
return mVariantToBeReturned;
}
}

View File

@@ -20,9 +20,9 @@
package com.jacob.com;
/**
* The parent class of all Jacob exceptions.
* They all used to be based off of RuntimeException or ComException
* but it was decided to base them all off of one owned by this project.
* The parent class of all Jacob exceptions. They all used to be based off of
* RuntimeException or ComException but it was decided to base them all off of
* one owned by this project.
*/
public class JacobException extends RuntimeException {
@@ -32,18 +32,18 @@ public class JacobException extends RuntimeException {
private static final long serialVersionUID = -1637125318746002715L;
/**
* Default constructor.
* Calls super with a "No Message Provided" string
* Default constructor. Calls super with a "No Message Provided" string
*/
public JacobException(){
public JacobException() {
super("No Message Provided");
}
/**
* standard constructor
*
* @param message
*/
public JacobException(String message){
public JacobException(String message) {
super(message);
}
}

View File

@@ -19,17 +19,13 @@
*/
package com.jacob.com;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* The superclass of all Jacob objects. It is used to
* create a standard API framework and to facillitate memory management
* for Java and COM memory elements.
* The superclass of all Jacob objects. It is used to create a standard API
* framework and to facilitate memory management for Java and COM memory
* elements.
* <p>
* All instances of this class and subclasses are automatically manged
* by the ROT. This means the ROT cannot be a subclass of JacobObject.
* All instances of this class and subclasses are automatically managed by the
* ROT. This means the ROT cannot be a subclass of JacobObject.
* <p>
* All COM object created by JACOB extend this class so that we can
* automatically release them when the thread is detached from COM - if we leave
@@ -39,116 +35,77 @@ import java.util.Properties;
public class JacobObject {
/**
* holds the build version as retrieved from the version.properties
* file that exists in the JAR.
* This can be retrived by calling the static method getBuildVersion()
* @see getBuildVersion()
* Standard constructor that adds this JacobObject to the memory management
* pool.
*/
private static String buildVersion = "";
public JacobObject() {
ROT.addObject(this);
}
/**
* holds the build date as retrieved from the version.properties
* file that exists in the JAR
* This can be retrived by calling the static method getBuildDate()
* @see getBuildDate()
* Finalizers call this method. This method should release any COM data
* structures in a way that it can be called multiple times. This can happen
* if someone manually calls this and then a finalizer calls it.
*/
private static String buildDate = "";
/**
* Standard constructor that adds this JacobObject
* to the memory management pool.
*/
public JacobObject() {
ROT.addObject(this);
}
public void safeRelease() {
// currently does nothing - subclasses may do something
if (isDebugEnabled()) {
// this used to do a toString() but that is bad for SafeArray
debug("SafeRelease: " + this.getClass().getName());
}
}
/**
* Loads version information from version.properties that was
* built as part of this release.
*
*/
private static void loadVersionProperties(){
Properties versionProps = new Properties();
// can't use system class loader cause won't work in jws
InputStream stream =
JacobObject.class.getClassLoader().getResourceAsStream("version.properties");
try {
versionProps.load(stream);
stream.close();
buildVersion = (String)versionProps.get("version");
buildDate = (String)versionProps.get("build.date");
} catch (IOException ioe){
System.out.println("blah, couldn't load props");
}
}
/**
* loads version.properties and returns the value of versin in it
* @return String value of version in version.properties or "" if none
*/
public static String getBuildDate(){
if (buildDate.equals("")){
loadVersionProperties();
}
return buildDate;
}
/**
* When things go wrong, it is useful to be able to debug the ROT.
*/
private static final boolean DEBUG =
// true;
"true".equalsIgnoreCase(System.getProperty("com.jacob.debug"));
/**
* loads version.properties and returns the value of versin in it
* @return String value of version in version.properties or "" if none
*/
public static String getBuildVersion(){
if (buildVersion.equals("")){
loadVersionProperties();
}
return buildVersion;
}
/**
* Finalizers call this method.
* This method should release any COM data structures in a way
* that it can be called multiple times.
* This can happen if someone manually calls this and then
* a finalizer calls it.
*/
public void safeRelease() {
// currently does nothing - subclasses may do something
if (isDebugEnabled()){
// this used to do a toString() but that is bad for SafeArray
debug("SafeRelease: "+this.getClass().getName());
}
}
/**
* When things go wrong, it is usefull to be able to debug the ROT.
*/
private static final boolean DEBUG =
//true;
"true".equalsIgnoreCase(System.getProperty("com.jacob.debug"));
protected static boolean isDebugEnabled(){
//return true;
return DEBUG;
}
/**
* Very basic debugging fucntion.
* @param istrMessage
*/
protected static void debug(String istrMessage)
{
if(isDebugEnabled())
{
System.out.println(istrMessage
+ " in thread "+ Thread.currentThread().getName());
}
}
protected static boolean isDebugEnabled() {
// return true;
return DEBUG;
}
/**
* Loads JacobVersion.Properties and returns the value of version in it
*
* @deprecated use JacobReleaseInfo.getBuildDate() instead.
* @return String value of version in JacobVersion.Properties or "" if none
*/
@Deprecated
public static String getBuildDate() {
return JacobReleaseInfo.getBuildDate();
}
/**
* Loads JacobVersion.Properties and returns the value of version in it
*
* @deprecated use JacobReleaseInfo.getBuildVersion() instead.
* @return String value of version in JacobVersion.Properties or "" if none
*/
@Deprecated
public static String getBuildVersion() {
return JacobReleaseInfo.getBuildVersion();
}
/**
* Very basic debugging function.
*
* @param istrMessage
*/
protected static void debug(String istrMessage) {
if (isDebugEnabled()) {
System.out.println(istrMessage + " in thread "
+ Thread.currentThread().getName());
}
}
/**
* force the jacob DLL to be loaded whenever this class is referenced
*/
static {
LibraryLoader.loadJacobLibrary();
}
/**
* force the jacob DLL to be loaded whenever this class is referenced
*/
static {
LibraryLoader.loadJacobLibrary();
}
}

View File

@@ -0,0 +1,96 @@
package com.jacob.com;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* An interface to the version properties file. This code was removed from
* JacobObject because it doesn't belong there.
*
*/
public class JacobReleaseInfo {
/**
* holds the build version as retrieved from the version properties file
* that exists in the JAR. This can be retrieved by calling the static
* method getBuildVersion()
*
* @see #getBuildVersion()
*/
private static String buildVersion = "";
/**
* holds the build date as retrieved from the version properties file that
* exists in the JAR This can be retrieved by calling the static method
* getBuildDate()
*
* @see #getBuildDate()
*/
private static String buildDate = "";
/** the name of the jacob version properties file */
private static final String PROPERTY_FILE_NAME = "META-INF/JacobVersion.properties";
/**
* Loads version information from PROPERTY_FILE_NAME that was built as part
* of this release.
*
* @throws IllegalStateException
* when it can't find the version properties file
*/
private static void loadVersionProperties() {
Properties versionProps = new Properties();
// can't use system class loader cause won't work in JavaWebStart
InputStream stream = JacobReleaseInfo.class.getClassLoader()
.getResourceAsStream(PROPERTY_FILE_NAME);
// This should never happen. This is an attempt to make something work
// for WebSphere. They may be using some kind of Servlet loader that
// needs an absolute path based search
if (stream == null) {
stream = JacobReleaseInfo.class.getClassLoader()
.getResourceAsStream("/" + PROPERTY_FILE_NAME);
}
// A report came in that WebSphere had trouble finding the file
// so lets trap it. Plus, it's a good idea anyway.
if (stream == null) {
throw new IllegalStateException(
"Can't find "
+ PROPERTY_FILE_NAME
+ " using JacobReleaseInfo.class.getClassLoader().getResourceAsStream()");
} else {
try {
versionProps.load(stream);
stream.close();
buildVersion = (String) versionProps.get("version");
buildDate = (String) versionProps.get("build.date");
} catch (IOException ioe) {
ioe.printStackTrace();
System.err.println("Warning! Couldn't load props " + ioe);
}
}
}
/**
* loads PROPERT_FILE_NAME and returns the value of version in it
*
* @return String value of version in PROPERT_FILE_NAME or "" if none
*/
public static String getBuildDate() {
if (buildDate.equals("")) {
loadVersionProperties();
}
return buildDate;
}
/**
* loads PROPERT_FILE_NAME and returns the value of version in it
*
* @return String value of version in PROPERT_FILE_NAME or "" if none
*/
public static String getBuildVersion() {
if (buildVersion.equals("")) {
loadVersionProperties();
}
return buildVersion;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
* Copyright (c) 1999-2007 Sourceforge JACOB Project.
* All rights reserved. Originator: Dan Adler (http://danadler.com).
* Get more information about JACOB at http://sourceforge.net/projects/jacob-project
*
@@ -19,44 +19,208 @@
*/
package com.jacob.com;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
/**
* Utility class to centralize the way in which the jacob JNI library is loaded.
*
* <p>If system property {@link #JACOB_DLL_PATH} is defined, the file located there
* will be loaded as the jacob dll. If the system property is not defined, normal
* library paths will be used to load the jacob dll. This means it defaults to the
* previous behavior for existing applications.
* <p>
* The standard behavior for most applications is that LoadLibrary() will be called
* to load the dll. LoadLibary searches directories specified in the variable
* java.library.path . This is why most test cases specify -Djava.library.path in
* their command line arguments
*
* This supports defining the path or library name using system properties or a
* custom resource file. If desired, jacob can auto-detect the correct version
* of the DLL for 32 or 64 bit windows, as long as you have named them
* differently.
*
* <ol>
* <li> If system property {@link #JACOB_DLL_PATH} is defined, the file located
* there will be loaded as the jacob dll using System.load(). </li>
*
* <li> If system property {@link #JACOB_DLL_NAME} is defined, the file located
* there will be loaded as the jacob dll. </li>
* <li> If system property {@link #JACOB_DLL_NAME_X86} and
* {@link #JACOB_DLL_NAME_X64} are defined, the file located there will be
* loaded as the jacob dll, depending on the version of Windows. </li>
*
* <li> If {@link #JACOB_DLL_NAME} is defined in the
* {@code com.jacob.com.JacobLibraryLoader} resource file, the specified dll
* will be loaded from the {@code java.library.path}. </li>
* <li> If {@link #JACOB_DLL_NAME_X86} and {@link #JACOB_DLL_NAME_X64} are
* defined in the {@code com.jacob.com.JacobLibraryLoader} resource file, the
* specified dll will be loaded from the {@code java.library.path}, depending
* on the version of Windows. </li>
*
* <li> If none of the above are true, the default is to load the library named
* "jacob-&lt;version&gt;-&lt;arch&gt" (or
* "jacob-&lt;version&gt;-&lt;arch&rt;.dll") from the {@code java.library.path}.
* </li>
* </ol>
*
* The standard behavior for most applications is that {@code LoadLibrary()}
* will be called to load the dll. {@code LoadLibary()} searches directories
* specified in the variable {@code java.library.path}. This is why most test
* cases specify -Djava.library.path in their command line arguments.
* <p>
* Submitted sourceforge ticket 1493647
* JACOB_DLL_PATH submitted sourceforge ticket 1493647 Added 1.11 <br>
* JACOB_DLL_NAME, JACOB_DLL_NAME_32, JACOB_DLL_NAME_64 submitted sourceforge
* ticket 1845039 Added 1.14M7
*
* @author Scott Dickerson (sjd78)
* @author Jason Smith
*/
public final class LibraryLoader {
/**
* Name of system property (currently <tt>jacob.dll.path</tt>) that may contain
* an absolute path to the JNI library.
* Name of system property (currently <tt>jacob.dll.path</tt>) that may
* contain an absolute path to the JNI library.
*/
public static final String JACOB_DLL_PATH = "jacob.dll.path";
/**
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
* contain an alternate name for the JNI library (default is 'jacob').
*/
public static final String JACOB_DLL_NAME = "jacob.dll.name";
/**
* Load the jacob dll either from an absolute path defined in system property
* {@link #JACOB_DLL_PATH} or as a general library called "<tt>jacob</tt>".
* @throws UnsatisfiedLinkError if the library does not exist.
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
* contain an alternate name for the JNI library (default is 'jacob'), 32
* bit windows.
*/
public static final String JACOB_DLL_NAME_X86 = "jacob.dll.name.x86";
/**
* Name of system property (currently <tt>jacob.dll.name</tt>) that may
* contain an alternate name for the JNI library (default is 'jacob'), 64
* bit windows.
*/
public static final String JACOB_DLL_NAME_X64 = "jacob.dll.name.x64";
/**
* Appended to "jacob" when building DLL name This string must EXACTLY match
* the string in the build.xml file
*/
public static final String DLL_NAME_MODIFIER_32_BIT = "x86";
/**
* Appended to "jacob" when building DLL name This string must EXACTLY match
* the string in the build.xml file
*/
public static final String DLL_NAME_MODIFIER_64_BIT = "x64";
/**
* Load the jacob dll either from an absolute path or by a library name,
* both of which may be defined in various ways.
*
* @throws UnsatisfiedLinkError
* if the library does not exist.
*/
public static void loadJacobLibrary() {
// In some cases, a library that uses Jacob won't be able to set system
// properties
// prior to Jacob being loaded. The resource bundle provides an
// alternate way to
// override DLL name or path that will be loaded with Jacob regardless
// of other
// initialization order.
ResourceBundle resources = null;
Set<String> keys = new HashSet<String>();
try {
resources = ResourceBundle.getBundle(LibraryLoader.class.getName(),
Locale.getDefault(), LibraryLoader.class.getClassLoader());
for (Enumeration<String> i = resources.getKeys(); i
.hasMoreElements();) {
String key = i.nextElement();
keys.add(key);
}
} catch (MissingResourceException e) {
// Do nothing. Expected.
}
// First, check for a defined PATH. System property overrides resource
// bundle.
String path = System.getProperty(JACOB_DLL_PATH);
if (path == null && resources != null && keys.contains(JACOB_DLL_PATH)) {
path = (String) resources.getObject(JACOB_DLL_PATH);
}
if (path != null) {
System.load(path);
}
else {
System.loadLibrary("jacob");
} else {
// Path was not defined, so use the OS mechanism for loading
// libraries.
// Check for a defined NAME. System property overrides resource
// bundle.
String name = null;
if (System.getProperty(JACOB_DLL_NAME) != null) {
name = System.getProperty(JACOB_DLL_NAME);
} else if (System.getProperty(JACOB_DLL_NAME_X86) != null
&& shouldLoad32Bit()) {
name = System.getProperty(JACOB_DLL_NAME_X86);
} else if (System.getProperty(JACOB_DLL_NAME_X64) != null
&& !shouldLoad32Bit()) {
name = System.getProperty(JACOB_DLL_NAME_X64);
} else if (resources != null && keys.contains(JACOB_DLL_NAME)) {
name = resources.getString(JACOB_DLL_NAME);
} else if (resources != null && keys.contains(JACOB_DLL_NAME_X86)
&& shouldLoad32Bit()) {
name = resources.getString(JACOB_DLL_NAME_X86);
} else if (resources != null && keys.contains(JACOB_DLL_NAME_X64)
&& !shouldLoad32Bit()) {
name = resources.getString(JACOB_DLL_NAME_X64);
} else {
// No alternate NAME or PATH was defined, so use the default.
// We will almost always end up here.
name = getPreferredDLLName();
}
// System.out.println("Loading " + name);
System.loadLibrary(name);
}
}
/**
* Developer note: This method MUST be synchronized with the DLL names
* created as part of the build process in build.xml
* <p>
* The DLL name is "jacob\<PLATFORM\>.release"
*
* @return the preferred name of the DLL adjusted for this platform and
* version without the ".dll" extension
*/
public static String getPreferredDLLName() {
if (shouldLoad32Bit()) {
return "jacob" + "-" + JacobReleaseInfo.getBuildVersion() + "-"
+ DLL_NAME_MODIFIER_32_BIT;
} else {
return "jacob" + "-" + JacobReleaseInfo.getBuildVersion() + "- "
+ DLL_NAME_MODIFIER_64_BIT;
}
}
/**
* Detects whether this is a 32-bit JVM.
*
* @return {@code true} if this is a 32-bit JVM.
*/
protected static boolean shouldLoad32Bit() {
// This guesses whether we are running 32 or 64 bit Java.
// This works for Sun and IBM JVMs version 5.0 or later.
// May need to be adjusted for non-Sun JVMs.
String bits = System.getProperty("sun.arch.data.model", "?");
if (bits.equals("32"))
return true;
else if (bits.equals("64"))
return false;
// this works for jRocket
String arch = System.getProperty("java.vm.name", "?");
if (arch.toLowerCase().indexOf("64-bit") >= 0)
return false;
return true;
}
} // LibraryLoader

View File

@@ -20,10 +20,10 @@
package com.jacob.com;
/**
* We provide our own main sta thread to avoid COM tagging a random
* thread as the main STA - this is the thread in which all Apartment
* threaded components will be created if the client chooses an MTA
* threading model for the java side of the app.
* We provide our own main sta thread to avoid COM tagging a random thread as
* the main STA - this is the thread in which all Apartment threaded components
* will be created if the client chooses an MTA threading model for the java
* side of the app.
*/
public class MainSTA extends STA {
}

View File

@@ -20,24 +20,22 @@
package com.jacob.com;
/**
* Thrown by java APIs that are not implemented either because
* they were never implemented or because they are bieng deprecated
* This is a subclass of ComException so callers can still just catch
* ComException.
* Thrown by java APIs that are not implemented either because they were never
* implemented or because they are being deprecated This is a subclass of
* ComException so callers can still just catch ComException.
*/
public class NotImplementedException extends JacobException {
/**
/**
*
*/
private static final long serialVersionUID = -9169900832852356445L;
/**
* @param description
*/
public NotImplementedException(String description) {
super(description);
}
* @param description
*/
public NotImplementedException(String description) {
super(description);
}
}

View File

@@ -28,194 +28,210 @@ import java.util.WeakHashMap;
* The Running Object Table (ROT) maps each thread to a collection of all the
* JacobObjects that were created in that thread. It always operates on the
* current thread so all the methods are static and they implicitly get the
* current thread.
* current thread.
* <p>
* The clearObjects method is used to release all the COM objects created by Jacob
* in the current thread prior to uninitializing COM for that thread.
* The clearObjects method is used to release all the COM objects created by
* Jacob in the current thread prior to uninitializing COM for that thread.
* <p>
* Prior to 1.9, manual garbage collection was the only option in Jacob, but
* from 1.9 onward, setting the com.jacob.autogc system property
* allows the objects referenced by the ROT to be automatically GCed.
* Automatic GC may be preferable in systems with heavy event callbacks.
* from 1.9 onward, setting the com.jacob.autogc system property allows the
* objects referenced by the ROT to be automatically GCed. Automatic GC may be
* preferable in systems with heavy event callbacks.
* <p>
* Is [ 1116101 ] jacob-msg 0284 relevant???
*/
public abstract class ROT {
/**
* Manual garbage collection was the only option pre 1.9
* Can staticly cache the results because only one value
* and we don't let it change during a run
* Manual garbage collection was the only option pre 1.9 Can staticly cache
* the results because only one value and we don't let it change during a
* run
*/
protected static final boolean USE_AUTOMATIC_GARBAGE_COLLECTION =
"true".equalsIgnoreCase( System.getProperty( "com.jacob.autogc" ) );
protected static final boolean USE_AUTOMATIC_GARBAGE_COLLECTION = "true"
.equalsIgnoreCase(System.getProperty("com.jacob.autogc"));
/**
* Suffix added to class name to make up property name that determines if this
* object should be stored in the ROT. This 1.13 "feature" makes it possible
* to cause VariantViaEvent objects to not be added to the ROT in event callbacks.
* Suffix added to class name to make up property name that determines if
* this object should be stored in the ROT. This 1.13 "feature" makes it
* possible to cause VariantViaEvent objects to not be added to the ROT in
* event callbacks.
* <p>
* We don't have a static for the actual property because there is a different property
* for each class that may make use of this feature.
* We don't have a static for the actual property because there is a
* different property for each class that may make use of this feature.
*/
protected static String PUT_IN_ROT_SUFFIX = ".PutInROT";
protected static String PUT_IN_ROT_SUFFIX = ".PutInROT";
/**
* A hash table where each element is another
* HashMap that represents a thread.
* Each thread HashMap contains the com objects created
* in that thread
* A hash table where each element is another HashMap that represents a
* thread. Each thread HashMap contains the com objects created in that
* thread
*/
private static HashMap rot = new HashMap();
private static HashMap<String, Map<JacobObject, String>> rot = new HashMap<String, Map<JacobObject, String>>();
/**
* adds a new thread storage area to rot
*
* @return Map corresponding to the thread that this call was made in
*/
protected synchronized static Map addThread() {
// should use the id here instead of the name because the name can be changed
protected synchronized static Map<JacobObject, String> addThread() {
// should use the id here instead of the name because the name can be
// changed
String t_name = Thread.currentThread().getName();
if ( rot.containsKey( t_name ) ) {
if (rot.containsKey(t_name)) {
// nothing to do
} else {
Map tab = null;
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: Automatic GC flag == " + USE_AUTOMATIC_GARBAGE_COLLECTION );
Map<JacobObject, String> tab = null;
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: Automatic GC flag == "
+ USE_AUTOMATIC_GARBAGE_COLLECTION);
}
if ( !USE_AUTOMATIC_GARBAGE_COLLECTION ) {
tab = new HashMap();
if (!USE_AUTOMATIC_GARBAGE_COLLECTION) {
tab = new HashMap<JacobObject, String>();
} else {
tab = new WeakHashMap();
tab = new WeakHashMap<JacobObject, String>();
}
rot.put( t_name, tab );
rot.put(t_name, tab);
}
return getThreadObjects( false );
return getThreadObjects(false);
}
/**
* returns the pool for this thread if it exists. can create a new
* one if you wish by passing in TRUE
* returns the pool for this thread if it exists. can create a new one if
* you wish by passing in TRUE
*
* @param createIfDoesNotExist
* @return Map the collection that holds the objects created in the current thread
* @return Map the collection that holds the objects created in the current
* thread
*/
protected synchronized static Map getThreadObjects( boolean createIfDoesNotExist ) {
protected synchronized static Map<JacobObject, String> getThreadObjects(
boolean createIfDoesNotExist) {
String t_name = Thread.currentThread().getName();
if ( !rot.containsKey( t_name ) && createIfDoesNotExist ) {
if (!rot.containsKey(t_name) && createIfDoesNotExist) {
addThread();
}
return (Map) rot.get( t_name );
return rot.get(t_name);
}
/**
* Iterates across all of the entries in the Hashmap in the rot
* that corresponds to this thread.
* This calls safeRelease() on each entry and then
* clears the map when done and removes it from the rot.
* All traces of this thread's objects will disapear.
* This is called by COMThread in the tear down and provides a
* synchronous way of releasing memory
* Iterates across all of the entries in the Hashmap in the rot that
* corresponds to this thread. This calls safeRelease() on each entry and
* then clears the map when done and removes it from the rot. All traces of
* this thread's objects will disapear. This is called by COMThread in the
* tear down and provides a synchronous way of releasing memory
*/
protected synchronized static void clearObjects() {
Map tab = getThreadObjects( false );
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: " + rot.keySet().size() + " thread tables exist" );
Map<JacobObject, String> tab = getThreadObjects(false);
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: " + rot.keySet().size()
+ " thread tables exist");
}
if ( tab != null ) {
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: " + tab.keySet().size() + " objects to clear in this thread " );
if (tab != null) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: " + tab.keySet().size()
+ " objects to clear in this thread ");
}
// walk the values
Iterator it = tab.keySet().iterator();
while ( it.hasNext() ) {
JacobObject o = (JacobObject) it.next();
if ( o != null
// can't use this cause creates a Variant if calling SafeAray
// and we get an exceptin modifying the collection while iterating
Iterator<JacobObject> it = tab.keySet().iterator();
while (it.hasNext()) {
JacobObject o = it.next();
if (o != null
// can't use this cause creates a Variant if calling SafeAray
// and we get an exception modifying the collection while
// iterating
// && o.toString() != null
) {
if ( JacobObject.isDebugEnabled() ) {
if ( o instanceof SafeArray ) {
// SafeArray create more objects when calling toString()
// which causes a concurrent modification exception in HashMap
JacobObject.debug( "ROT: removing " + o.getClass().getName() );
if (JacobObject.isDebugEnabled()) {
if (o instanceof SafeArray) {
// SafeArray create more objects when calling
// toString()
// which causes a concurrent modification exception
// in HashMap
JacobObject.debug("ROT: removing "
+ o.getClass().getName());
} else {
// Variant toString() is probably always bad in here
JacobObject.debug( "ROT: removing " + o.hashCode() + "->" + o.getClass().getName() );
JacobObject.debug("ROT: removing " + o.hashCode()
+ "->" + o.getClass().getName());
}
}
o.safeRelease();
}
// used to be an iterator.remove() but why bother when we're nuking them all anyway?
// used to be an iterator.remove() but why bother when we're
// nuking them all anyway?
}
// empty the collection
tab.clear();
// remove the collection from rot
rot.remove( Thread.currentThread().getName() );
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: thread table cleared and removed" );
rot.remove(Thread.currentThread().getName());
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: thread table cleared and removed");
}
} else {
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: nothing to clear!" );
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: nothing to clear!");
}
}
}
/**
* @deprecated the java model leave the responsibility of clearing up objects
* to the Garbage Collector. Our programming model should not require that the
* user specifically remove object from the thread.
* @deprecated the java model leave the responsibility of clearing up
* objects to the Garbage Collector. Our programming model
* should not require that the user specifically remove object
* from the thread.
*
* This will remove an object from the ROT
* @param o
*/
protected synchronized static void removeObject( JacobObject o ) {
@Deprecated
protected synchronized static void removeObject(JacobObject o) {
String t_name = Thread.currentThread().getName();
Map tab = (Map) rot.get( t_name );
if ( tab != null ) {
tab.remove( o );
Map<JacobObject, String> tab = rot.get(t_name);
if (tab != null) {
tab.remove(o);
}
o.safeRelease();
}
/**
* adds an object to the HashMap for the current thread
*
* @param o
*/
protected synchronized static void addObject( JacobObject o ) {
protected synchronized static void addObject(JacobObject o) {
// check the system property to see if this class is put in the ROT
// the default value is "true" which simulates the old behavior
String shouldIncludeClassInROT =
System.getProperty(o.getClass().getName() + PUT_IN_ROT_SUFFIX,"true");
if (shouldIncludeClassInROT.equalsIgnoreCase("false")){
if (JacobObject.isDebugEnabled()){
JacobObject.debug("JacobObject: New instance of "+o.getClass().getName()+" not added to ROT");
}
} else {
Map tab = getThreadObjects( false );
if ( tab == null ) {
String shouldIncludeClassInROT = System.getProperty(o.getClass()
.getName()
+ PUT_IN_ROT_SUFFIX, "true");
if (shouldIncludeClassInROT.equalsIgnoreCase("false")) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("JacobObject: New instance of "
+ o.getClass().getName() + " not added to ROT");
}
} else {
Map<JacobObject, String> tab = getThreadObjects(false);
if (tab == null) {
// this thread has not been initialized as a COM thread
// so make it part of MTA for backwards compatibility
ComThread.InitMTA( false );
tab = getThreadObjects( true );
ComThread.InitMTA(false);
tab = getThreadObjects(true);
}
if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug(
"ROT: adding " + o + "->" + o.getClass().getName() +
" table size prior to addition:" + tab.size() );
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("ROT: adding " + o + "->"
+ o.getClass().getName()
+ " table size prior to addition:" + tab.size());
}
if ( tab != null ) {
tab.put( o, null );
if (tab != null) {
tab.put(o, null);
}
}
}
}
/**
* ROT can't be a subclass of JacobObject because of the way ROT pools are managed
* so we force a DLL load here by referncing JacobObject
* ROT can't be a subclass of JacobObject because of the way ROT pools are
* managed so we force a DLL load here by referencing JacobObject
*/
static {
LibraryLoader.loadJacobLibrary();
}
}

View File

@@ -25,74 +25,77 @@ package com.jacob.com;
* component that wants to run in an STA other than the main STA.
*/
public class STA extends Thread {
/**
* referenced by STA.cpp
*/
public int threadID;
/**
* referenced by STA.cpp
*/
public int threadID;
/**
* constructor for STA
*/
public STA() {
start(); // start the thread
}
/**
* constructor for STA
*/
public STA() {
start(); // start the thread
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
public void run() {
// init COM
ComThread.InitSTA();
if (OnInit()) {
// this call blocks in the win32 message loop
// until quitMessagePump is called
doMessagePump();
}
OnQuit();
// uninit COM
ComThread.Release();
}
/*
* (non-Javadoc)
*
* @see java.lang.Thread#run()
*/
public void run() {
// init COM
ComThread.InitSTA();
if (OnInit()) {
// this call blocks in the win32 message loop
// until quitMessagePump is called
doMessagePump();
}
OnQuit();
// uninit COM
ComThread.Release();
}
/**
* Override this method to create and initialize any COM component that you
* want to run in this thread. If anything fails, return false to terminate
* the thread.
* @return always returns true
*/
public boolean OnInit() {
return true;
}
/**
* Override this method to create and initialize any COM component that you
* want to run in this thread. If anything fails, return false to terminate
* the thread.
*
* @return always returns true
*/
public boolean OnInit() {
return true;
}
/**
* Override this method to destroy any resource before the thread exits and
* COM in uninitialized
*/
public void OnQuit() {
// there is nothing to see here
}
/**
* Override this method to destroy any resource before the thread exits and
* COM in uninitialized
*/
public void OnQuit() {
// there is nothing to see here
}
/**
* calls quitMessagePump
*/
public void quit() {
quitMessagePump();
}
/**
* calls quitMessagePump
*/
public void quit() {
quitMessagePump();
}
/**
* run a message pump for the main STA
*/
public native void doMessagePump();
/**
* run a message pump for the main STA
*/
public native void doMessagePump();
/**
* quit message pump for the main STA
*/
public native void quitMessagePump();
/**
* quit message pump for the main STA
*/
public native void quitMessagePump();
/**
* STA isn't a subclass of JacobObject so a reference to it doesn't load
* the DLL without this
*/
static {
LibraryLoader.loadJacobLibrary();
}
/**
* STA isn't a subclass of JacobObject so a reference to it doesn't load the
* DLL without this
*/
static {
LibraryLoader.loadJacobLibrary();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,471 @@
/**
*
*/
package com.jacob.com;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.Date;
/**
* A utility class used to convert between Java objects and Variants
*/
public final class VariantUtilities {
private VariantUtilities() {
// utility class with only static methods don't need constructors
}
/**
* Populates a variant object from a java object. This method attempts to
* figure out the appropriate Variant type
*
* @param targetVariant
* @param pValueObject
* @param fByRef
*/
protected static void populateVariant(Variant targetVariant,
Object pValueObject, boolean fByRef) {
if (pValueObject == null) {
targetVariant.putEmpty();
} else if (pValueObject instanceof Integer) {
if (fByRef) {
targetVariant.putIntRef(((Integer) pValueObject).intValue());
} else {
targetVariant.putInt(((Integer) pValueObject).intValue());
}
} else if (pValueObject instanceof Short) {
if (fByRef) {
targetVariant.putShortRef(((Short) pValueObject).shortValue());
} else {
targetVariant.putShort(((Short) pValueObject).shortValue());
}
} else if (pValueObject instanceof String) {
if (fByRef) {
targetVariant.putStringRef((String) pValueObject);
} else {
targetVariant.putString((String) pValueObject);
}
} else if (pValueObject instanceof Boolean) {
if (fByRef) {
targetVariant.putBooleanRef(((Boolean) pValueObject)
.booleanValue());
} else {
targetVariant.putBoolean(((Boolean) pValueObject)
.booleanValue());
}
} else if (pValueObject instanceof Double) {
if (fByRef) {
targetVariant.putDoubleRef(((Double) pValueObject)
.doubleValue());
} else {
targetVariant.putDouble(((Double) pValueObject).doubleValue());
}
} else if (pValueObject instanceof Float) {
if (fByRef) {
targetVariant.putFloatRef(((Float) pValueObject).floatValue());
} else {
targetVariant.putFloat(((Float) pValueObject).floatValue());
}
} else if (pValueObject instanceof BigDecimal) {
if (fByRef) {
targetVariant.putDecimalRef(((BigDecimal) pValueObject));
} else {
targetVariant.putDecimal(((BigDecimal) pValueObject));
}
} else if (pValueObject instanceof Byte) {
if (fByRef) {
targetVariant.putByteRef(((Byte) pValueObject).byteValue());
} else {
targetVariant.putByte(((Byte) pValueObject).byteValue());
}
} else if (pValueObject instanceof Date) {
if (fByRef) {
targetVariant.putDateRef((Date) pValueObject);
} else {
targetVariant.putDate((Date) pValueObject);
}
} else if (pValueObject instanceof Long) {
if (fByRef) {
targetVariant.putLongRef(((Long) pValueObject).longValue());
} else {
targetVariant.putLong(((Long) pValueObject).longValue());
}
} else if (pValueObject instanceof Currency) {
if (fByRef) {
targetVariant.putCurrencyRef(((Currency) pValueObject));
} else {
targetVariant.putCurrency(((Currency) pValueObject));
}
} else if (pValueObject instanceof SafeArray) {
if (fByRef) {
targetVariant.putSafeArrayRef((SafeArray) pValueObject);
} else {
targetVariant.putSafeArray((SafeArray) pValueObject);
}
} else if (pValueObject instanceof Dispatch) {
if (fByRef) {
targetVariant.putDispatchRef((Dispatch) pValueObject);
} else {
targetVariant.putDispatch((Dispatch) pValueObject);
}
} else if (pValueObject instanceof Variant) {
// newly added 1.12-pre6 to support VT_VARIANT
targetVariant.putVariant(pValueObject);
} else {
// should really throw an illegal argument exception if its an
// invalid type
if (fByRef) {
targetVariant.putObjectRef(pValueObject);
} else {
targetVariant.putObject(pValueObject);
}
}
}
/**
* Map arguments based on msdn documentation. This method relies on the
* variant constructor except for arrays.
*
* @param objectToBeMadeIntoVariant
* @return Variant that represents the object
*/
@SuppressWarnings("unchecked")
protected static Variant objectToVariant(Object objectToBeMadeIntoVariant) {
if (objectToBeMadeIntoVariant == null) {
return new Variant();
} else if (objectToBeMadeIntoVariant instanceof Variant) {
// if a variant was passed in then be a slacker and just return it
return (Variant) objectToBeMadeIntoVariant;
} else if (objectToBeMadeIntoVariant.getClass().isArray()) {
// automatically convert arrays using reflection
SafeArray sa = null;
int len1 = Array.getLength(objectToBeMadeIntoVariant);
Object first = Array.get(objectToBeMadeIntoVariant, 0);
if (first.getClass().isArray()) {
int max = 0;
for (int i = 0; i < len1; i++) {
Object e1 = Array.get(objectToBeMadeIntoVariant, i);
int len2 = Array.getLength(e1);
if (max < len2) {
max = len2;
}
}
sa = new SafeArray(Variant.VariantVariant, len1, max);
for (int i = 0; i < len1; i++) {
Object e1 = Array.get(objectToBeMadeIntoVariant, i);
for (int j = 0; j < Array.getLength(e1); j++) {
sa.setVariant(i, j, objectToVariant(Array.get(e1, j)));
}
}
} else {
sa = new SafeArray(Variant.VariantVariant, len1);
for (int i = 0; i < len1; i++) {
sa.setVariant(i, objectToVariant(Array.get(
objectToBeMadeIntoVariant, i)));
}
}
Variant returnVariant = new Variant();
populateVariant(returnVariant, sa, false);
return returnVariant;
} else {
// rely on populateVariant to throw an exception if its an
// invalid type
Variant returnVariant = new Variant();
populateVariant(returnVariant, objectToBeMadeIntoVariant, false);
return returnVariant;
}
}
/**
* converts an array of objects into an array of Variants by repeatedly
* calling obj2Variant(Object)
*
* @param arrayOfObjectsToBeConverted
* @return Variant[]
*/
protected static Variant[] objectsToVariants(
Object[] arrayOfObjectsToBeConverted) {
Variant vArg[] = new Variant[arrayOfObjectsToBeConverted.length];
for (int i = 0; i < arrayOfObjectsToBeConverted.length; i++) {
vArg[i] = objectToVariant(arrayOfObjectsToBeConverted[i]);
}
return vArg;
}
/**
* Convert a JACOB Variant value to a Java object (type conversions).
* provided in Sourceforge feature request 959381. A fix was done to handle
* byRef bug report 1607878.
* <p>
* Unlike other toXXX() methods, it does not do a type conversion except for
* special data types (it shouldn't do any!)
* <p>
* Converts Variant.VariantArray types to SafeArrays
*
* @return Corresponding Java object of the type matching the Variant type.
* @throws IllegalStateException
* if no underlying windows data structure
* @throws NotImplementedException
* if unsupported conversion is requested
* @throws JacobException
* if the calculated result was a JacobObject usually as a
* result of error
*/
protected static Object variantToObject(Variant sourceData) {
Object result = null;
short type = sourceData.getvt(); // variant type
if ((type & Variant.VariantArray) == Variant.VariantArray) { // array
// returned?
SafeArray array = null;
type = (short) (type - Variant.VariantArray);
// From SF Bug 1840487
// This did call toSafeArray(false) but that meant
// this was the only variantToObject() that didn't have its own
// copy of the data so you would end up with weird run time
// errors after some GC. So now we just get stupid about it and
// always make a copy just like toSafeArray() does.
array = sourceData.toSafeArray();
result = array;
} else { // non-array object returned
switch (type) {
case Variant.VariantEmpty: // 0
case Variant.VariantNull: // 1
break;
case Variant.VariantShort: // 2
result = new Short(sourceData.getShort());
break;
case Variant.VariantShort | Variant.VariantByref: // 2
result = new Short(sourceData.getShortRef());
break;
case Variant.VariantInt: // 3
result = new Integer(sourceData.getInt());
break;
case Variant.VariantInt | Variant.VariantByref: // 3
result = new Integer(sourceData.getIntRef());
break;
case Variant.VariantFloat: // 4
result = new Float(sourceData.getFloat());
break;
case Variant.VariantFloat | Variant.VariantByref: // 4
result = new Float(sourceData.getFloatRef());
break;
case Variant.VariantDouble: // 5
result = new Double(sourceData.getDouble());
break;
case Variant.VariantDouble | Variant.VariantByref: // 5
result = new Double(sourceData.getDoubleRef());
break;
case Variant.VariantCurrency: // 6
result = sourceData.getCurrency();
break;
case Variant.VariantCurrency | Variant.VariantByref: // 6
result = sourceData.getCurrencyRef();
break;
case Variant.VariantDate: // 7
result = sourceData.getJavaDate();
break;
case Variant.VariantDate | Variant.VariantByref: // 7
result = sourceData.getJavaDateRef();
break;
case Variant.VariantString: // 8
result = sourceData.getString();
break;
case Variant.VariantString | Variant.VariantByref: // 8
result = sourceData.getStringRef();
break;
case Variant.VariantDispatch: // 9
result = sourceData.getDispatch();
break;
case Variant.VariantDispatch | Variant.VariantByref: // 9
result = sourceData.getDispatchRef(); // Can dispatches even
// be byRef?
break;
case Variant.VariantError: // 10
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantError");
break;
case Variant.VariantBoolean: // 11
result = new Boolean(sourceData.getBoolean());
break;
case Variant.VariantBoolean | Variant.VariantByref: // 11
result = new Boolean(sourceData.getBooleanRef());
break;
case Variant.VariantVariant: // 12 they are always by ref
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantVariant without ByRef");
break;
case Variant.VariantVariant | Variant.VariantByref: // 12
result = sourceData.getVariant();
break;
case Variant.VariantObject: // 13
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantObject");
break;
case Variant.VariantDecimal: // 14
result = sourceData.getDecimal();
break;
case Variant.VariantDecimal | Variant.VariantByref: // 14
result = sourceData.getDecimalRef();
break;
case Variant.VariantByte: // 17
result = new Byte(sourceData.getByte());
break;
case Variant.VariantByte | Variant.VariantByref: // 17
result = new Byte(sourceData.getByteRef());
break;
case Variant.VariantLongInt: // 20
result = new Long(sourceData.getLong());
break;
case Variant.VariantLongInt | Variant.VariantByref: // 20
result = new Long(sourceData.getLongRef());
break;
case Variant.VariantTypeMask: // 4095
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantTypeMask");
break;
case Variant.VariantArray: // 8192
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantArray");
break;
case Variant.VariantByref: // 16384
result = new NotImplementedException(
"toJavaObject() Not implemented for VariantByref");
break;
default:
result = new NotImplementedException("Unknown return type: "
+ type);
// there was a "return result" here that caused defect 1602118
// so it was removed
break;
}// switch (type)
if (result instanceof JacobException) {
throw (JacobException) result;
}
}
return result;
}// toJava()
/**
* Verifies that we have a scale 0 <= x <= 28 and now more than 96 bits of
* data. The roundToMSDecimal method will attempt to adjust a BigDecimal to
* pass this set of tests
*
* @param in
* @throws IllegalArgumentException
* if out of bounds
*/
protected static void validateDecimalScaleAndBits(BigDecimal in) {
BigInteger allWordBigInt = in.unscaledValue();
if (in.scale() > 28) {
// should this cast to a string and call putStringRef()?
throw new IllegalArgumentException(
"VT_DECIMAL only supports a maximum scale of 28 and the passed"
+ " in value has a scale of " + in.scale());
} else if (in.scale() < 0) {
// should this cast to a string and call putStringRef()?
throw new IllegalArgumentException(
"VT_DECIMAL only supports a minimum scale of 0 and the passed"
+ " in value has a scale of " + in.scale());
} else if (allWordBigInt.bitLength() > 12 * 8) {
throw new IllegalArgumentException(
"VT_DECIMAL supports a maximum of "
+ 12
* 8
+ " bits not counting scale and the number passed in has "
+ allWordBigInt.bitLength());
} else {
// no bounds problem to be handled
}
}
/**
* Largest possible number with scale set to 0
*/
private static final BigDecimal LARGEST_DECIMAL = new BigDecimal(
new BigInteger("ffffffffffffffffffffffff", 16));
/**
* Smallest possible number with scale set to 0. MS doesn't support negative
* scales like BigDecimal.
*/
private static final BigDecimal SMALLEST_DECIMAL = new BigDecimal(
new BigInteger("ffffffffffffffffffffffff", 16).negate());
/**
* Does any validation that couldn't have been fixed by rounding or scale
* modification.
*
* @param in
* The BigDecimal to be validated
* @throws IllegalArgumentException
* if the number is too large or too small or null
*/
protected static void validateDecimalMinMax(BigDecimal in) {
if (in == null) {
throw new IllegalArgumentException(
"null is not a supported Decimal value.");
} else if (LARGEST_DECIMAL.compareTo(in) < 0) {
throw new IllegalArgumentException(
"Value too large for VT_DECIMAL data type:" + in.toString()
+ " integer: " + in.toBigInteger().toString(16)
+ " scale: " + in.scale());
} else if (SMALLEST_DECIMAL.compareTo(in) > 0) {
throw new IllegalArgumentException(
"Value too small for VT_DECIMAL data type:" + in.toString()
+ " integer: " + in.toBigInteger().toString(16)
+ " scale: " + in.scale());
}
}
/**
* Rounds the scale and bit length so that it will pass
* validateDecimalScaleBits(). Developers should call this method if they
* really want MS Decimal and don't want to lose precision.
* <p>
* Changing the scale on a number that can fit in an MS Decimal can change
* the number's representation enough that it will round to a number too
* large to be represented by an MS VT_DECIMAL
*
* @param sourceDecimal
* @return BigDecimal a new big decimal that was rounded to fit in an MS
* VT_DECIMAL
*/
public static BigDecimal roundToMSDecimal(BigDecimal sourceDecimal) {
BigInteger sourceDecimalIntComponent = sourceDecimal.unscaledValue();
BigDecimal destinationDecimal = new BigDecimal(
sourceDecimalIntComponent, sourceDecimal.scale());
int roundingModel = BigDecimal.ROUND_HALF_UP;
validateDecimalMinMax(destinationDecimal);
// First limit the number of digits and then the precision.
// Try and round to 29 digits because we can sometimes do that
BigInteger allWordBigInt;
allWordBigInt = destinationDecimal.unscaledValue();
if (allWordBigInt.bitLength() > 96) {
destinationDecimal = destinationDecimal.round(new MathContext(29));
// see if 29 digits uses more than 96 bits
if (allWordBigInt.bitLength() > 96) {
// Dang. It was over 97 bits so shorten it one more digit to
// stay <= 96 bits
destinationDecimal = destinationDecimal.round(new MathContext(
28));
}
}
// the bit manipulations above may change the scale so do it afterwards
// round the scale to the max MS can support
if (destinationDecimal.scale() > 28) {
destinationDecimal = destinationDecimal.setScale(28, roundingModel);
}
if (destinationDecimal.scale() < 0) {
destinationDecimal = destinationDecimal.setScale(0, roundingModel);
}
return destinationDecimal;
}
}

View File

@@ -19,15 +19,16 @@
*/
package com.jacob.com;
/**
* a public class to variant that is used
* to track which variant objects are created by event callbacks
* This is soley used for that purpose.
/**
* a public class to variant that is used to track which variant objects are
* created by event callbacks This is solely used for that purpose.
*/
public class VariantViaEvent extends Variant {
public VariantViaEvent(){
super();
}
/**
* Standard constructor used by JNI event handling layer
*/
public VariantViaEvent() {
super();
}
}

View File

@@ -23,24 +23,25 @@ package com.jacob.com;
* thrown in util.cpp
*/
public class WrongThreadException extends JacobException {
/**
/**
* identifier generated by Eclipse
*/
private static final long serialVersionUID = 6308780364980228692L;
/**
* standard 0 arg constructor with no message
*
*/
public WrongThreadException() {
super("No Message Provided.");
}
* standard 0 arg constructor with no message
*
*/
public WrongThreadException() {
super("No Message Provided.");
}
/**
* standard constructor with a string message
* @param s
*/
public WrongThreadException(String s) {
super(s);
}
/**
* standard constructor with a string message
*
* @param s
*/
public WrongThreadException(String s) {
super(s);
}
}

View File

@@ -4,56 +4,112 @@ import com.jacob.activeX.ActiveXComponent;
import com.jacob.test.BaseTestCase;
/**
* This exercises the two Dispatch factor methods that let you
* control whether you create a new running COM object or connect to an existing one
* This exercises the two Dispatch factor methods that let you control whether
* you create a new running COM object or connect to an existing one
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ActiveXComponentFactoryTest extends BaseTestCase {
public void testActiveXComponentFactory(){
/**
* This test is supposed to verify we get multiple instances when we mean
* too. Unfortunately, it requires that the runner of the test verify via
* the "Windows Task Manager"
*/
public void testMultipleInstances() {
ComThread.InitMTA();
String mApplicationId = "Word.Application";
ActiveXComponent instance1 = ActiveXComponent
.createNewInstance(mApplicationId);
ActiveXComponent instance2 = ActiveXComponent
.createNewInstance(mApplicationId);
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
}
instance1.invoke("Quit", new Variant[] {});
instance2.invoke("Quit", new Variant[] {});
ComThread.Release();
}
/**
* This test is supposed to verify we can force multiple items through a
* single running instance. It requires that a user physically watch the
* "Windows Task Manager" to verify only one copy of MS Word is executing
*/
public void testOnlyOneInstance() {
ComThread.InitMTA();
String mApplicationId = "Word.Application";
ActiveXComponent instance1 = new ActiveXComponent(mApplicationId);
ActiveXComponent instance2 = ActiveXComponent
.connectToActiveInstance(mApplicationId);
assertNotNull(instance2);
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
}
instance1.invoke("Quit", new Variant[] {});
ComThread.Release();
}
/**
* Test that verifies function of the ActiveXComponentFactory
*/
public void testActiveXComponentFactory() {
ComThread.InitSTA(true);
try {
System.out.println("This test only works if MS Word is NOT already running");
System.out
.println("This test only works if MS Word is NOT already running");
String mApplicationId = "Word.Application";
ActiveXComponent mTryConnectingFirst = ActiveXComponent.connectToActiveInstance(mApplicationId);
if (mTryConnectingFirst != null ){
mTryConnectingFirst.invoke("Quit",new Variant[] {});
System.out.println("Was able to connect to MSWord when hadn't started it");
ActiveXComponent mTryConnectingFirst = ActiveXComponent
.connectToActiveInstance(mApplicationId);
if (mTryConnectingFirst != null) {
mTryConnectingFirst.invoke("Quit", new Variant[] {});
System.out
.println("Was able to connect to MSWord when hadn't started it");
} else {
System.out.println("Correctly could not connect to running MSWord");
System.out
.println("Correctly could not connect to running MSWord");
}
System.out.println(" Word Starting");
ActiveXComponent mTryStartingSecond = ActiveXComponent.createNewInstance(mApplicationId);
if (mTryStartingSecond == null){
ActiveXComponent mTryStartingSecond = ActiveXComponent
.createNewInstance(mApplicationId);
if (mTryStartingSecond == null) {
System.out.println("was unable to start up MSWord ");
} else {
System.out.println("Correctly could start MSWord");
}
ActiveXComponent mTryConnectingThird = ActiveXComponent.connectToActiveInstance(mApplicationId);
if (mTryConnectingThird == null ){
ActiveXComponent mTryConnectingThird = ActiveXComponent
.connectToActiveInstance(mApplicationId);
if (mTryConnectingThird == null) {
fail("Was unable able to connect to MSWord after previous startup");
} else {
System.out.println("Stopping MSWord");
// stop it so we can fail trying to connect to a running
mTryConnectingThird.invoke("Quit",new Variant[] {});
mTryConnectingThird.invoke("Quit", new Variant[] {});
}
Thread.sleep(2000);
ActiveXComponent mTryConnectingFourth = ActiveXComponent.connectToActiveInstance(mApplicationId);
if (mTryConnectingFourth != null ){
mTryConnectingFourth.invoke("Quit",new Variant[] {});
ActiveXComponent mTryConnectingFourth = ActiveXComponent
.connectToActiveInstance(mApplicationId);
if (mTryConnectingFourth != null) {
mTryConnectingFourth.invoke("Quit", new Variant[] {});
fail("Was able to connect to MSWord that was stopped");
} else {
System.out.println("Correctly could not connect to running MSWord");
System.out
.println("Correctly could not connect to running MSWord");
}
} catch (InterruptedException ie){
} catch (InterruptedException ie) {
} catch (ComException e) {
e.printStackTrace();
fail("Caught COM exception");
} finally {
//System.out.println("About to sleep for 2 seconds so we can bask in the glory of this success");
//Thread.sleep(2000);
// System.out.println("About to sleep for 2 seconds so we can bask
// in the glory of this success");
// Thread.sleep(2000);
ComThread.Release();
ComThread.quitMainSTA();
}

View File

@@ -9,37 +9,45 @@ import junit.framework.TestCase;
/**
* test cases that should exercise the new date conversion code
* <p>
* This test does not require any command line options because it is only a utility test
* This test does not require any command line options because it is only a
* utility test
*/
public class DateUtilitiesTest extends TestCase {
public void testDateUtilities(){
Date now = new Date();
double comTimeForNow = DateUtilities.convertDateToWindowsTime(now);
Date retrievedNow = DateUtilities.convertWindowsTimeToDate(comTimeForNow);
if (!now.equals(retrievedNow)){
fail("DateUtilities Date Test failed " +now+ " != " +retrievedNow );
} else {
System.out.println("DateUtilities Date Test passed");
}
}
public void testBeginningOfWindowsTime(){
// this is a magic time in the windows world
Date beginningOfWindowsTime =
new GregorianCalendar(1899, Calendar.DECEMBER, 30).getTime();
double comTimeForBeginningOfWindowsTime =
DateUtilities.convertDateToWindowsTime(beginningOfWindowsTime);
if (comTimeForBeginningOfWindowsTime > 0){
fail("Beginning of windows time test failed "
+comTimeForBeginningOfWindowsTime);
} else {
System.out.println("Beginning of windows time test passed");
}
}
/**
* verify date conversion to and from java
*/
public void testDateUtilities() {
Date now = new Date();
double comTimeForNow = DateUtilities.convertDateToWindowsTime(now);
Date retrievedNow = DateUtilities
.convertWindowsTimeToDate(comTimeForNow);
if (!now.equals(retrievedNow)) {
fail("DateUtilities Date Test failed " + now + " != "
+ retrievedNow);
} else {
System.out.println("DateUtilities Date Test passed");
}
}
/**
* Verify that the start of time is when we think it is.
*/
public void testBeginningOfWindowsTime() {
// this is a magic time in the windows world
Date beginningOfWindowsTime = new GregorianCalendar(1899,
Calendar.DECEMBER, 30).getTime();
double comTimeForBeginningOfWindowsTime = DateUtilities
.convertDateToWindowsTime(beginningOfWindowsTime);
if (comTimeForBeginningOfWindowsTime > 0) {
fail("Beginning of windows time test failed "
+ comTimeForBeginningOfWindowsTime);
} else {
System.out.println("Beginning of windows time test passed");
}
}
}

View File

@@ -3,31 +3,35 @@ package com.jacob.com;
import com.jacob.test.BaseTestCase;
/**
* This test verifies that the Dispatch object protects itself when
* the constructor is called with a null program id.
* Prior to this protection, the VM might crash.m
* This test verifies that the Dispatch object protects itself when the
* constructor is called with a null program id. Prior to this protection, the
* VM might crash.m
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class DispatchNullProgramId extends BaseTestCase {
public void testNullProgramId(){
/**
* Verify that dispatch constructors are protected from null program ids.
*/
public void testNullProgramId() {
try {
String nullParam = null;
new Dispatch(nullParam);
fail("the dispatch failed to protect itself from null program ids");
} catch (IllegalArgumentException iae){
System.out.println(
"the dispatch protected itself from null program ids");
} catch (IllegalArgumentException iae) {
System.out
.println("the dispatch protected itself from null program ids");
}
try {
String nullParam = "";
new Dispatch(nullParam);
fail("the dispatch failed to protect itself from empty string program ids");
} catch (IllegalArgumentException iae){
System.out.println(
"the dispatch protected itself from empty string program ids");
} catch (IllegalArgumentException iae) {
System.out
.println("the dispatch protected itself from empty string program ids");
}
}
}

View File

@@ -1,24 +1,20 @@
package com.jacob.com;
import java.util.Date;
import com.jacob.test.BaseTestCase;
/**
* Test some of the Dispatch utility methods
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* <p>
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class DispatchTest extends BaseTestCase {
public void testDispatch() {
Date testDate = new Date();
Variant fromDate = Dispatch.obj2variant(testDate);
Date returnedDate = fromDate.getJavaDate();
//System.out.println("test date is "+testDate);
//System.out.println("VariantDate is "+fromDate.getJavaDate());
assertTrue("Could not call obj2variant(Date) and get it to work",
testDate.equals(returnedDate));
}
/**
* Dummy test until someone gets their act together
*/
public void testDispatch() {
// what should we test
}
}

View File

@@ -4,27 +4,38 @@ import com.jacob.test.BaseTestCase;
/**
* Test armoring of dispatch static methods
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* <p>
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class DispatchValidDispatchTest extends BaseTestCase {
public void testThrowIllegalArgumentException() {
try {
Dispatch.call(null, 0);
fail("Failed to throw IllegalArgumentException");
} catch (IllegalArgumentException iae){
System.out.println("Caught correct IllegalArgumentException: "+iae);
}
}
public void testThrowIllegalStateException() {
try {
Dispatch foo = new Dispatch();
Dispatch.call(foo, 0);
fail("Failed to throw IllegalStateException");
} catch (IllegalStateException ise){
System.out.println("Caught correct IllegalStateException "+ise);
}
}
/**
* force an IllegalArgumentException to verify the utility method throws
* correctly.
*/
public void testThrowIllegalArgumentException() {
try {
Dispatch.call(null, 0);
fail("Failed to throw IllegalArgumentException");
} catch (IllegalArgumentException iae) {
System.out.println("Caught correct IllegalArgumentException: "
+ iae);
}
}
/**
* force an IllegalStateException to verify the utility method throws
* correctly.
*/
public void testThrowIllegalStateException() {
try {
Dispatch foo = new Dispatch();
Dispatch.call(foo, 0);
fail("Failed to throw IllegalStateException");
} catch (IllegalStateException ise) {
System.out.println("Caught correct IllegalStateException " + ise);
}
}
}

View File

@@ -5,16 +5,18 @@ import com.jacob.test.BaseTestCase;
/**
* This will eventually be changed to a unit test.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class JacobObjectTest extends BaseTestCase {
public void testBuildVersion(){
System.out.println("build version is "+JacobObject.getBuildVersion());
System.out.println("build date is "+JacobObject.getBuildDate());
}
/**
* verify the build version and date functions work correctly
*/
public void testBuildVersion() {
System.out.println("build version is " + JacobReleaseInfo.getBuildVersion());
System.out.println("build date is " + JacobReleaseInfo.getBuildDate());
}
}

View File

@@ -0,0 +1,79 @@
package com.jacob.com;
import junit.framework.TestCase;
/**
* Tests Library loader architecture methods This test requires that jacob.jar
* be compiled and added to the classpath. You will need to refresh the release
* directory so that eclipse knows about jacob.jar. Otherwise you will get a
* "jar not found" dialog.
*
* <p>
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*
* @author clay_shooter
*
*/
public class LibraryLoaderTest extends TestCase {
/**
* verify the architecture switches work
*/
public void testArchitectureVersions() {
System.out.println("running on 32Bit? VM"
+ LibraryLoader.shouldLoad32Bit());
// verify no null pointer is thrown
LibraryLoader.shouldLoad32Bit();
}
/**
* verify LibraryLoader.JACOB_DLL_NAME is read by LibraryLoader
*/
public void testJacobDllNameSystemProperty() {
// fill with bad dll name
System.setProperty(LibraryLoader.JACOB_DLL_NAME, "xxx");
try {
LibraryLoader.loadJacobLibrary();
fail("Should have been unable to load dll with name xxx");
} catch (UnsatisfiedLinkError ule) {
// yes, this is what we want to see when using a bad name
}
// no way to clear a system property once set so lets try setting to
// default
System.setProperty(LibraryLoader.JACOB_DLL_NAME, LibraryLoader
.getPreferredDLLName());
try {
LibraryLoader.loadJacobLibrary();
} catch (UnsatisfiedLinkError ule) {
fail("Should have been able to load dll after setting "
+ LibraryLoader.JACOB_DLL_NAME + " to "
+ LibraryLoader.getPreferredDLLName() + " "
+ ule.getMessage());
}
}
/**
* Verifies that we get a preferred DLL name with X86 since we really only
* run the unit tests on 32 bit platforms.
*/
public void testDLLNameContainsProcessorAndVersion() {
System.out.println(LibraryLoader.getPreferredDLLName());
if (LibraryLoader.shouldLoad32Bit()) {
// we build the package and run the unit tests on X86
assertTrue(LibraryLoader.getPreferredDLLName()
+ "should have contained "
+ LibraryLoader.DLL_NAME_MODIFIER_32_BIT, LibraryLoader
.getPreferredDLLName().contains(
LibraryLoader.DLL_NAME_MODIFIER_32_BIT));
} else {
// we build the package and run the unit tests on X86
assertTrue(LibraryLoader.getPreferredDLLName()
+ "should have contained "
+ LibraryLoader.DLL_NAME_MODIFIER_64_BIT, LibraryLoader
.getPreferredDLLName().contains(
LibraryLoader.DLL_NAME_MODIFIER_64_BIT));
}
}
}

View File

@@ -14,6 +14,9 @@ import com.jacob.test.BaseTestCase;
*/
public class ROT2Test extends BaseTestCase {
/**
* runs a multi-threaded test
*/
public void testDoesNotBlowUp() {
ROT2TestThread threads[] = new ROT2TestThread[4];
for (int i = 0; i < threads.length; i++) {
@@ -29,12 +32,14 @@ public class ROT2Test extends BaseTestCase {
*/
public class ROT2TestThread extends Thread {
private java.util.List ThreadObjects;
private java.util.List<Variant> ThreadObjects;
private int initialRunSize = 0;
/**
* @param arg0
* @param iStartCount
* the initial number of threads
*/
public ROT2TestThread(String arg0, int iStartCount) {
super(arg0);
@@ -43,7 +48,7 @@ public class ROT2Test extends BaseTestCase {
}
/**
* A semi-complexe serie of steps to put the ROT under stress. 1)
* A semi-complex series of steps to put the ROT under stress. 1)
* discard half the objects we've created 2) if size is greater than 1
* but not a even number, add 1 new object 3) stop when size is 1.
*
@@ -54,7 +59,7 @@ public class ROT2Test extends BaseTestCase {
// so the gc can't collect them
// we need to create these in the thread so they end up in the right
// ROT table
ThreadObjects = new java.util.ArrayList(initialRunSize);
ThreadObjects = new java.util.ArrayList<Variant>(initialRunSize);
for (int i = 0; i < initialRunSize; i++) {
// create the object
Variant aNewVariant = new Variant(getName() + "_" + i);
@@ -105,8 +110,8 @@ public class ROT2Test extends BaseTestCase {
}
/**
* Another test would be to override this to always return the same name.
* That would really screw the ROT!
* Another test would be to override this to always return the same
* name. That would really screw the ROT!
*
* @see java.lang.Object#toString()
*/

View File

@@ -3,8 +3,9 @@ package com.jacob.com;
import com.jacob.test.BaseTestCase;
/**
* This tries to exercise ROT's garbage collection This is named this way because
* the build.xml ignores files ending in Test when building the binary zip file
* This tries to exercise ROT's garbage collection This is named this way
* because the build.xml ignores files ending in Test when building the binary
* zip file
*
* This will eventually be changed to a unit test.
*
@@ -15,6 +16,9 @@ import com.jacob.test.BaseTestCase;
*/
public class ROT3Test extends BaseTestCase {
/**
* runs a multi-threaded test
*/
public void testROTVersion3() {
ROT3TestThread threads[] = new ROT3TestThread[4];
for (int i = 0; i < threads.length; i++) {
@@ -30,12 +34,14 @@ public class ROT3Test extends BaseTestCase {
*/
public class ROT3TestThread extends Thread {
private java.util.List variansCreatedInThisThread;
private java.util.List<Variant> variansCreatedInThisThread;
private int initialRunSize = 0;
/**
* @param arg0
* @param iStartCount
* the number of initial threads
*/
public ROT3TestThread(String arg0, int iStartCount) {
super(arg0);
@@ -44,18 +50,20 @@ public class ROT3Test extends BaseTestCase {
}
/**
* A semi-complexe serie of steps to put the ROT under stress. 1)
* A semi-complex series of steps to put the ROT under stress. 1)
* discard half the objects we've created 2) if size is greater than 1
* but not a even number, add 1 new object 3) stop when size is 1.
*
* @see java.lang.Runnable#run()
*/
@SuppressWarnings("deprecation")
public void run() {
// something that keeps object references around
// so the gc can't collect them
// we need to create these in the thread so they end up in the right
// ROT table
variansCreatedInThisThread = new java.util.ArrayList(initialRunSize);
variansCreatedInThisThread = new java.util.ArrayList<Variant>(
initialRunSize);
for (int i = 0; i < initialRunSize; i++) {
// create the object
Variant aNewVariant = new Variant(getName() + "_" + i);
@@ -92,9 +100,8 @@ public class ROT3Test extends BaseTestCase {
if (!ROT.USE_AUTOMATIC_GARBAGE_COLLECTION) {
// uses deprecated API to set up a special situation
// because this is an ROT test
ROT
.removeObject((JacobObject) variansCreatedInThisThread
.get(i - 1));
ROT.removeObject(variansCreatedInThisThread
.get(i - 1));
}
variansCreatedInThisThread.remove(i - 1);
}

View File

@@ -1,121 +1,133 @@
package com.jacob.com;
import com.jacob.test.BaseTestCase;
/**
* This tries to exercise ROT's garbage collection
*
* This will eventually be changed to a unit test.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ROTTest extends BaseTestCase {
/**
* verify the SystemProperty (classname).PutInROT functions as expected.
* A value of false means instances of the class are not put in the ROT
* Any o ther value means they are
*/
public void testDontFillROTSystemProperty(){
debug("testDontFillROTSystemProperty: started");
// Make sure the class is loaded before running any of the tests
// class to load and any pre-defined Variants (FALSE and TRUE) to be created immediately
VariantViaEvent.class.getName();
if (ROT.getThreadObjects(true).entrySet().size() < 1){
debug("Failure: ROT should have objects in it as soon as Variant class loaded.");
}
/**
* verify the SystemProperty (classname).PutInROT functions as expected. A
* value of false means instances of the class are not put in the ROT Any o
* ther value means they are
*/
public void testDontFillROTSystemProperty() {
debug("testDontFillROTSystemProperty: started");
// Make sure the class is loaded before running any of the tests
// class to load and any pre-defined Variants (FALSE and TRUE) to be
// created immediately
VariantViaEvent.class.getName();
if (ROT.getThreadObjects(true).entrySet().size() < 1) {
debug("Failure: ROT should have objects in it as soon as Variant class loaded.");
}
System.setProperty(VariantViaEvent.class.getName()+ROT.PUT_IN_ROT_SUFFIX,"false");
int countPriorToTest = ROT.getThreadObjects(true).entrySet().size();
new VariantViaEvent();
int countAfterAddWithoutROT = ROT.getThreadObjects(true).entrySet().size();
if (countAfterAddWithoutROT != countPriorToTest){
debug("Failure: count prior: "+countPriorToTest+
" and count after without ROT was: "+countAfterAddWithoutROT);
}
System.setProperty(VariantViaEvent.class.getName()+ROT.PUT_IN_ROT_SUFFIX,"true");
new VariantViaEvent();
int countAfterAddWithROT = ROT.getThreadObjects(true).entrySet().size();
if (countAfterAddWithROT != (countPriorToTest+1)){
debug("Failure: count prior: "+countPriorToTest+
" and count after with ROT was: "+countAfterAddWithROT);
}
debug("testDontFillROTSystemProperty: completed");
}
System.setProperty(VariantViaEvent.class.getName()
+ ROT.PUT_IN_ROT_SUFFIX, "false");
int countPriorToTest = ROT.getThreadObjects(true).entrySet().size();
new VariantViaEvent();
int countAfterAddWithoutROT = ROT.getThreadObjects(true).entrySet()
.size();
if (countAfterAddWithoutROT != countPriorToTest) {
debug("Failure: count prior: " + countPriorToTest
+ " and count after without ROT was: "
+ countAfterAddWithoutROT);
}
/**
* Needs documentation. This test looks broken
*
*/
public void testGCBehavior(){
int sizeBeforeBuild = 0;
int sizeAfterBuild = 0;
int sizeBeforeGC = 0;
int sizeAfterGC = 0;
int loopSize = 10000;
int sizeExpectedAfterBuild = 0;
System.setProperty(VariantViaEvent.class.getName()
+ ROT.PUT_IN_ROT_SUFFIX, "true");
new VariantViaEvent();
int countAfterAddWithROT = ROT.getThreadObjects(true).entrySet().size();
if (countAfterAddWithROT != (countPriorToTest + 1)) {
debug("Failure: count prior: " + countPriorToTest
+ " and count after with ROT was: " + countAfterAddWithROT);
}
debug("testDontFillROTSystemProperty: completed");
}
debug("testGCBehavior: started");
debug("creating 10,000 object sets");
// cause classes to get loaded and any static instances to be created
SafeArray.class.getName();
Variant.class.getName();
sizeBeforeBuild = ROT.getThreadObjects(false).size();
sizeExpectedAfterBuild = ((loopSize*3)+sizeBeforeBuild);
for ( int i = 0 ; i < loopSize; i++){
SafeArray a1 = new SafeArray(Variant.VariantVariant, 2);
a1.setVariant(0, new Variant("foo"));
a1.setVariant(1, new Variant("bar"));
}
sizeAfterBuild = ROT.getThreadObjects(false).size();
if (sizeAfterBuild < sizeExpectedAfterBuild){
debug("Something got GC'd: "+sizeAfterBuild);
} else if (sizeAfterBuild > sizeExpectedAfterBuild){
debug("More: "+sizeAfterBuild+" than expected: "+sizeExpectedAfterBuild);
} else {
debug("They're all there");
}
// add more to the VM
debug("Flooding Memory to force GC");
for ( int i = 0 ; i <= loopSize*2; i++){
new String("this is just some text to see if we can force gc "+i);
}
// storage will hold weak references until the next JacobObject is created
System.gc();
sizeBeforeGC = ROT.getThreadObjects(false).size();
debug("Objects left after flood and gc but before adding a new object that clean's up weak references: "+sizeBeforeGC);
debug("Creating single object. This adds one and causes ROT to clean up GC'd");
new JacobObject();
sizeAfterGC = ROT.getThreadObjects(false).size();
debug("Objects left after adding one (caused weak ref objects to be removed): "+sizeAfterGC);
new JacobObject();
if (ROT.getThreadObjects(false).size() != sizeAfterGC+1){
debug("Unexpected number of objects after adding only one more "+ROT.getThreadObjects(false).size());
} else {
debug("Found number expected after adding one more " +(sizeAfterGC+1) );
}
ROT.clearObjects();
if (ROT.getThreadObjects(false) == null){
debug("ROT pool was destroyed as expected after clearObjects called.");
} else {
debug("ROT pool for thread still exists when it shouldn't");
}
//========= part two ================================
debug("Verifying doesn't blow up with double release");
for ( int i = 0 ; i <= 10000; i++){
new JacobObject();
}
// force safeRelease call on all objects
ROT.clearObjects();
// now force the gc to go collect them, running safeRelease again
System.gc();
debug("testGCBehavior: finished");
}
private static void debug(String message){
System.out.println(Thread.currentThread().getName()+" "+message);
}
/**
* Needs documentation. This test looks broken
*
*/
public void testGCBehavior() {
int sizeBeforeBuild = 0;
int sizeAfterBuild = 0;
int sizeBeforeGC = 0;
int sizeAfterGC = 0;
int loopSize = 10000;
int sizeExpectedAfterBuild = 0;
debug("testGCBehavior: started");
debug("creating 10,000 object sets");
// cause classes to get loaded and any static instances to be created
SafeArray.class.getName();
Variant.class.getName();
sizeBeforeBuild = ROT.getThreadObjects(false).size();
sizeExpectedAfterBuild = ((loopSize * 3) + sizeBeforeBuild);
for (int i = 0; i < loopSize; i++) {
SafeArray a1 = new SafeArray(Variant.VariantVariant, 2);
a1.setVariant(0, new Variant("foo"));
a1.setVariant(1, new Variant("bar"));
}
sizeAfterBuild = ROT.getThreadObjects(false).size();
if (sizeAfterBuild < sizeExpectedAfterBuild) {
debug("Something got GC'd: " + sizeAfterBuild);
} else if (sizeAfterBuild > sizeExpectedAfterBuild) {
debug("More: " + sizeAfterBuild + " than expected: "
+ sizeExpectedAfterBuild);
} else {
debug("They're all there");
}
// add more to the VM
debug("Flooding Memory to force GC");
for (int i = 0; i <= loopSize * 2; i++) {
new String("this is just some text to see if we can force gc " + i);
}
// storage will hold weak references until the next JacobObject is
// created
System.gc();
sizeBeforeGC = ROT.getThreadObjects(false).size();
debug("Objects left after flood and gc but before adding a new object that clean's up weak references: "
+ sizeBeforeGC);
debug("Creating single object. This adds one and causes ROT to clean up GC'd");
new JacobObject();
sizeAfterGC = ROT.getThreadObjects(false).size();
debug("Objects left after adding one (caused weak ref objects to be removed): "
+ sizeAfterGC);
new JacobObject();
if (ROT.getThreadObjects(false).size() != sizeAfterGC + 1) {
debug("Unexpected number of objects after adding only one more "
+ ROT.getThreadObjects(false).size());
} else {
debug("Found number expected after adding one more "
+ (sizeAfterGC + 1));
}
ROT.clearObjects();
if (ROT.getThreadObjects(false) == null) {
debug("ROT pool was destroyed as expected after clearObjects called.");
} else {
debug("ROT pool for thread still exists when it shouldn't");
}
// ========= part two ================================
debug("Verifying doesn't blow up with double release");
for (int i = 0; i <= 10000; i++) {
new JacobObject();
}
// force safeRelease call on all objects
ROT.clearObjects();
// now force the gc to go collect them, running safeRelease again
System.gc();
debug("testGCBehavior: finished");
}
private static void debug(String message) {
System.out.println(Thread.currentThread().getName() + " " + message);
}
}

View File

@@ -7,53 +7,64 @@ import com.jacob.test.BaseTestCase;
/**
* test cases that should exercise the new date conversion code
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class VariantDateTest extends BaseTestCase {
public void testVariantDate() {
Date now = new Date();
Variant holder = new Variant();
holder.putDate(now);
Date retrievedNow = holder.getJavaDate();
if (!now.equals(retrievedNow)){
fail("Variant Date Test failed " +now+ " != " +retrievedNow );
} else {
System.out.println("Variant Date Test passed");
}
}
public void testVariantDateToJavaObject(){
Date now = new Date();
Variant holder = new Variant(now);
for ( int i = 0; i < 30000; i++){
Variant dateVariant = new Variant(now);
Date retrievedNow = holder.getJavaDate();
retrievedNow = dateVariant.getJavaDate();
if (!now.equals(retrievedNow)){
fail("Variant Date Test (1) failed " +now+ " != " +retrievedNow );
} else {
//System.out.println("Variant Date Test (1) passed");
}
// verify auto typecasting works
retrievedNow = (Date)dateVariant.toJavaObject();
if (!now.equals(retrievedNow)){
fail("Variant Date Test (2) failed " +now+ " != " +retrievedNow );
} else {
//System.out.println("Variant Date Test (2) passed "+retrievedNow);
}
Variant intVariant = new Variant(4);
Object variantReturn = intVariant.toJavaObject();
// degenerate test to make sure date isn't always returned
if (variantReturn instanceof Date ){
System.out.println("int variant returned date");
}
}
System.out.print("Test finished. All tests passed.");
}
/**
* verify the conversion of Variants into java dates
*/
public void testVariantDate() {
Date now = new Date();
Variant holder = new Variant();
holder.putDate(now);
Date retrievedNow = holder.getJavaDate();
if (!now.equals(retrievedNow)) {
fail("Variant Date Test failed " + now + " != " + retrievedNow);
} else {
System.out.println("Variant Date Test passed");
}
}
/**
* verify that the Variant constructor accepts Java dates and converts them
* correctly
*/
public void testVariantDateToJavaObject() {
Date now = new Date();
Variant holder = new Variant(now);
for (int i = 0; i < 30000; i++) {
Variant dateVariant = new Variant(now);
Date retrievedNow = holder.getJavaDate();
retrievedNow = dateVariant.getJavaDate();
if (!now.equals(retrievedNow)) {
fail("Variant Date Test (1) failed " + now + " != "
+ retrievedNow);
} else {
// System.out.println("Variant Date Test (1) passed");
}
// verify auto typecasting works
retrievedNow = (Date) dateVariant.toJavaObject();
if (!now.equals(retrievedNow)) {
fail("Variant Date Test (2) failed " + now + " != "
+ retrievedNow);
} else {
// System.out.println("Variant Date Test (2) passed
// "+retrievedNow);
}
Variant intVariant = new Variant(4);
Object variantReturn = intVariant.toJavaObject();
// degenerate test to make sure date isn't always returned
if (variantReturn instanceof Date) {
System.out.println("int variant returned date");
}
}
System.out.print("Test finished. All tests passed.");
}
}

View File

@@ -1,6 +1,7 @@
package com.jacob.com;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import com.jacob.test.BaseTestCase;
@@ -9,474 +10,658 @@ import com.jacob.test.BaseTestCase;
* runs through some of the get and set methods on Variant
*
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class VariantTest extends BaseTestCase {
/**
* This verifies that toJavaObject() works for all of the
* main data types when they exist as a byRef version.
* This verifies that toJavaObject() works for all of the main data types
* when they exist as a byRef version.
* <p>
* It compares the toJavaObject() for a byref against the
* toJavaObject() for the regular.
*
* It compares the toJavaObject() for a byref against the toJavaObject() for
* the regular.
*
*/
public void testByRefToJavaObject(){
public void testByRefToJavaObject() {
Variant v = null;
Variant vByRef = null;
v = new Variant(new Float(53.3),false);
vByRef = new Variant(new Float(53.3),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
v = new Variant(new Float(53.3), false);
vByRef = new Variant(new Float(53.3), true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
v = new Variant(new Double(53.3),false);
vByRef = new Variant(new Double(53.3),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Boolean(true),false);
vByRef = new Variant(new Boolean(true),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Integer(53),false);
vByRef = new Variant(new Integer(53),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Short((short)53),false);
vByRef = new Variant(new Short((short)53),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
v = new Variant(new Double(53.3), false);
vByRef = new Variant(new Double(53.3), true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
v = new Variant("53.33",false);
vByRef = new Variant("53.33",true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
v = new Variant(new Boolean(true), false);
vByRef = new Variant(new Boolean(true), true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
v = new Variant(new Integer(53), false);
vByRef = new Variant(new Integer(53), true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
v = new Variant(new Short((short) 53), false);
vByRef = new Variant(new Short((short) 53), true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
v = new Variant("53.33", false);
vByRef = new Variant("53.33", true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
// Ugh, you have to pick a magic number whose scale is less than 28
// 53.53 had a scale of 64 and 53.52 had a scale of 47
BigDecimal testDecimal = new BigDecimal(53.50);
v = new Variant(testDecimal,false);
vByRef = new Variant(testDecimal,true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
v = new Variant(testDecimal, false);
vByRef = new Variant(testDecimal, true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
Date now = new Date();
v = new Variant(now,false);
vByRef = new Variant(now,true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
v = new Variant(now, false);
vByRef = new Variant(now, true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
// need to do currency also
}
/**
* try and test VT_I8. This should only work on 64 bit machines
*/
public void testLong() {
Variant v = null;
Variant vByRef = null;
long longNumber = 1L << 40;
v = new Variant(new Long(longNumber), false);
vByRef = new Variant(new Long(longNumber), true);
assertEquals("Could recover long number " + longNumber, v.getLong(),
longNumber);
assertEquals("Could not make long number " + longNumber
+ " come out the same for get and getByRef()",
v.toJavaObject(), vByRef.toJavaObject());
v = new Variant("" + longNumber);
v.changeType(Variant.VariantLongInt);
assertEquals("Conversion from string to long didn't work ",
v.getLong(), longNumber);
}
/**
* do some testing around currencies
*/
public void testCurrencyHandling() {
Variant v = null;
Variant vByRef = null;
// need to do currency also
// currency is an integer scaled up by 10,000 to give 4 digits to the
// right of the decimal
int currencyScale = 10000;
long twentyThousand = 20000 * currencyScale;
Currency twentyThousandAsCurrency = new Currency(twentyThousand);
v = new Variant(twentyThousandAsCurrency, false);
vByRef = new Variant(twentyThousandAsCurrency, true);
if (!(v.toJavaObject() instanceof Currency)) {
fail("v.toJavaObject was not Long for currency but was: "
+ v.toJavaObject());
}
if (!v.toJavaObject().equals(vByRef.toJavaObject())) {
fail(v.toString() + " could not make type " + v.getvt() + " and "
+ vByRef.getvt() + " java objects come out the same");
}
long twentyThousandDotSeven = twentyThousand + 700;
Currency twentyThousandDotSevenAsCurrency = new Currency(
twentyThousandDotSeven);
// use the primitive constructor
v = new Variant(twentyThousandDotSevenAsCurrency);
assertEquals("failed test with " + twentyThousandDotSeven,
twentyThousandDotSeven, v.getCurrency().longValue());
}
/**
* 4/2007 bug report toObject on dispatch tries to call getDispatchRef
* instead of getDispatch so toString() on dispatch blows up.
*
*
*/
public void testDispatchToJavaObject(){
public void testDispatchToJavaObject() {
Variant v2 = new Variant();
v2.putNothing();
// this test fails even though the exact same code below works fine
//v2.toJavaObject();
// v2.toJavaObject();
}
/**
* see what happens when we conver to by ref
*
*
*/
public void testSomeChangeVT(){
public void testSomeChangeVT() {
Variant v;
// the code shows e shouldn't need to use a returned Variant but the test says we do
// the code shows e shouldn't need to use a returned Variant but the
// test says we do
Variant vConverted;
v = new Variant(53.3);
short originalVT = v.getvt();
short modifier;
modifier = Variant.VariantShort;
vConverted = v.changeType(modifier);
if (vConverted.getvt() != modifier){
fail("Failed to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
if (vConverted.getvt() != modifier) {
fail("Failed to change Variant " + originalVT + " using mask "
+ modifier + " resulted in " + vConverted.getvt());
}
modifier = Variant.VariantString;
vConverted = v.changeType(modifier);
if (vConverted.getvt() != modifier){
fail("Failed to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
if (vConverted.getvt() != modifier) {
fail("Failed to change Variant " + originalVT + " using mask "
+ modifier + " resulted in " + vConverted.getvt());
}
// can't convert to byref!
modifier = Variant.VariantByref | Variant.VariantShort;
modifier = Variant.VariantByref | Variant.VariantShort;
vConverted = v.changeType(modifier);
if (vConverted.getvt() == modifier){
fail("Should not have been able to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
if (vConverted.getvt() == modifier) {
fail("Should not have been able to change Variant " + originalVT
+ " using mask " + modifier + " resulted in "
+ vConverted.getvt());
}
}
/**
* make sure variant with no backing store works.
*
*
*/
public void testUninitializedVariant(){
public void testUninitializedVariant() {
Variant v;
// Variants created without parameters are auto set to VariantEmpty
v = new Variant();
try {
if (v.getvt() == Variant.VariantEmpty){
if (v.getvt() == Variant.VariantEmpty) {
// successful
// System.out.println("Variant initialized without parameters correctly set to empty");
// System.out.println("Variant initialized without parameters
// correctly set to empty");
} else {
throw new RuntimeException("getvt() on uninitialized variant shoud have returned VariantEmpty, instead returned "+v.getvt());
throw new RuntimeException(
"getvt() on uninitialized variant shoud have returned VariantEmpty, instead returned "
+ v.getvt());
}
} catch (IllegalStateException ise){
throw new RuntimeException("getvt() on uninitialized variant shoud have succeeded, but instead threw exception");
} catch (IllegalStateException ise) {
throw new RuntimeException(
"getvt() on uninitialized variant shoud have succeeded, but instead threw exception");
}
try {
v.toString();
} catch (IllegalStateException ise){
} catch (IllegalStateException ise) {
fail("toString() should never throw a runtime exception");
throw new RuntimeException("toString() should not blow up even with uninitialized Variant");
throw new RuntimeException(
"toString() should not blow up even with uninitialized Variant");
}
}
/**
*
* verify the toString() method does not do type conversion
*/
public void testToStringDoesNotConvert(){
public void testToStringDoesNotConvert() {
Variant v;
v = new Variant(true);
v.toString();
if (v.getvt() != Variant.VariantBoolean){
throw new RuntimeException("toString() converted boolean to something else");
if (v.getvt() != Variant.VariantBoolean) {
throw new RuntimeException(
"toString() converted boolean to something else");
} else {
//fail("toString() correctly does not convert type");
// fail("toString() correctly does not convert type");
}
if (v.getBoolean() != true){
fail("toString() converted boolean true to "+ v.getBoolean());
if (v.getBoolean() != true) {
fail("toString() converted boolean true to " + v.getBoolean());
}
v = new Variant(false);
v.toString();
if (v.getvt() != Variant.VariantBoolean){
throw new RuntimeException("toString() converted boolean to something else");
if (v.getvt() != Variant.VariantBoolean) {
throw new RuntimeException(
"toString() converted boolean to something else");
} else {
//fail("toString() correctly does not convert type");
// fail("toString() correctly does not convert type");
}
if (v.getBoolean() != false){
fail("toString() converted boolean false to "+ v.getBoolean());
if (v.getBoolean() != false) {
fail("toString() converted boolean false to " + v.getBoolean());
}
}
public void testSafeReleaseBoolean(){
/**
* Verify that booleans can be released. Part of the suite that checks all
* types.
*/
public void testSafeReleaseBoolean() {
Variant v;
v = new Variant(true);
//System.out.println("Newly created Variant ("+ v.getBoolean()+") "+
// "trying to create access violation but it doesn't seem to be easy");
// System.out.println("Newly created Variant ("+ v.getBoolean()+") "+
// "trying to create access violation but it doesn't seem to be easy");
v.safeRelease();
try {
v.getBoolean();
fail("IllegalStateException should have been thrown when querying safeReleased object");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after safeRelease");
} catch (IllegalStateException ise) {
// System.out.println("IllegalStateException correctly thrown after
// safeRelease");
}
v = new Variant(true);
for ( int i = 0 ; i < 10; i ++){
new Variant ("xxx"+i);
for (int i = 0; i < 10; i++) {
new Variant("xxx" + i);
new Variant(i);
new Variant ("yyy"+i);
new Variant("yyy" + i);
}
ComThread.Release();
try {
v.getBoolean();
fail("IllegalStateException should have been thrown when querying ComThread.Release");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after ComThread.Release");
} catch (IllegalStateException ise) {
// System.out.println("IllegalStateException correctly thrown after
// ComThread.Release");
}
}
/**
* verify the constant values aren't released with safeRelease
*
*
*/
public void testSafeReleaseConstant(){
//System.out.println("Using Static constant Variant - should never throw access violation");
public void testSafeReleaseConstant() {
// System.out.println("Using Static constant Variant - should never
// throw access violation");
Variant.VT_TRUE.safeRelease();
if (Variant.VT_TRUE.getBoolean() != true){
if (Variant.VT_TRUE.getBoolean() != true) {
fail("VT_TRUE has been broken by SafeRelease()");
throw new RuntimeException("test failed");
} else {
//System.out.println("VT_TRUE survived SafeRelease()");
// System.out.println("VT_TRUE survived SafeRelease()");
}
for ( int i = 0 ; i < 10; i ++){
new Variant ("xxx"+i);
for (int i = 0; i < 10; i++) {
new Variant("xxx" + i);
new Variant(i);
new Variant ("yyy"+i);
new Variant("yyy" + i);
}
ComThread.Release();
if (Variant.VT_TRUE.getBoolean() != true){
if (Variant.VT_TRUE.getBoolean() != true) {
fail("VT_TRUE has been broken by ComThread.Release()");
throw new RuntimeException("test failed");
} else {
//System.out.println("VT_TRUE survived ComThread.Release()");
// System.out.println("VT_TRUE survived ComThread.Release()");
}
}
/**
* this used to try and and create an access violation but that
* didn't work and now the methods on the Variant are smarter about
* working after a release
*
* this used to try and and create an access violation but that didn't work
* and now the methods on the Variant are smarter about working after a
* release
*
*/
public void testSafeReleaseString(){
String mTestString = "Guitar Hero";
public void testSafeReleaseString() {
String mTestString = "Guitar Hero";
Variant v = new Variant(mTestString);
//System.out.println("Newly created Variant ("+ v.getString()+") "+
// "about to safe release and then access");
// System.out.println("Newly created Variant ("+ v.getString()+") "+
// "about to safe release and then access");
v.safeRelease();
try {
v.getString();
fail("IllegalStateException should have been thrown when querying safeReleased object");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after safeRelease");
} catch (IllegalStateException ise) {
// System.out.println("IllegalStateException correctly thrown after
// safeRelease");
}
}
/**
* verifies objectIsAConstant works as expected
*
*/
public void testObjectIsAConstant(){
Variant v = new Variant("d");
if (!v.objectIsAConstant(Variant.VT_FALSE)){
fail("did not recognize VT_FALSE");
}
if (!v.objectIsAConstant(Variant.VT_TRUE)){
fail("did not recognize VT_TRUE");
}
if (!v.objectIsAConstant(Variant.VT_MISSING)){
fail("did not recognize VT_MISSING");
}
if (!v.objectIsAConstant(Variant.DEFAULT)){
fail("did not recognize DEFAULT");
}
if (v.objectIsAConstant(new Variant(true))){
fail("confused a boolean with VT_TRUE");
}
if (v.objectIsAConstant(new Variant(false))){
fail("confused a boolean with VT_FALSE");
}
}
}
/**
* verifies objectIsAConstant works as expected
*
*/
public void testObjectIsAConstant() {
Variant v = new Variant("d");
if (!v.objectIsAConstant(Variant.VT_FALSE)) {
fail("did not recognize VT_FALSE");
}
if (!v.objectIsAConstant(Variant.VT_TRUE)) {
fail("did not recognize VT_TRUE");
}
if (!v.objectIsAConstant(Variant.VT_MISSING)) {
fail("did not recognize VT_MISSING");
}
if (!v.objectIsAConstant(Variant.DEFAULT)) {
fail("did not recognize DEFAULT");
}
if (v.objectIsAConstant(new Variant(true))) {
fail("confused a boolean with VT_TRUE");
}
if (v.objectIsAConstant(new Variant(false))) {
fail("confused a boolean with VT_FALSE");
}
}
/**
* tests put and get methods looking for obvious defects
*
*
*/
public void testPutsAndGets(){
public void testPutsAndGets() {
Variant v = new Variant();
v.putInt((int)10);
assertEquals("int test failed", (int)10, v.getInt());
v.putInt(10);
assertEquals("int test failed", 10, v.getInt());
v.putShort((short)20);
assertEquals("short test failed", (short)20, v.getShort());
v.putByte((byte)30);
assertEquals("byte test failed", (byte)30, v.getByte());
v.putShort((short) 20);
assertEquals("short test failed", (short) 20, v.getShort());
v.putByte((byte) 30);
assertEquals("byte test failed", (byte) 30, v.getByte());
v.putFloat(40);
if (v.getFloat() != 40.0){
if (v.getFloat() != 40.0) {
fail("float test failed");
}
v.putDouble(50);
if (v.getDouble() != 50.0){
if (v.getDouble() != 50.0) {
fail("double test failed");
}
v.putString("1234.567");
assertEquals("string test failed","1234.567", v.getString());
assertEquals("string test failed", "1234.567", v.getString());
v.putBoolean(true);
assertEquals("failed boolean test(true)",true, v.getBoolean());
assertEquals("failed boolean test(true)", true, v.getBoolean());
v.putBoolean(false);
assertEquals("failed boolean test(false)",false,v.getBoolean());
assertEquals("failed boolean test(false)", false, v.getBoolean());
long originalValue = 123456789123456789L;
v.putCurrency(new Currency(originalValue));
assertEquals("failed currency test", 123456789123456789L, v
.getCurrency().longValue());
v.putCurrency(123456789123456789L);
assertEquals("failed currency test",123456789123456789L, v.getCurrency());
BigDecimal testDecimal = new BigDecimal("22.222");
v.putDecimal(testDecimal);
assertEquals("failed BigDecimal test", testDecimal,v.getDecimal());
assertEquals("failed BigDecimal test", testDecimal, v.getDecimal());
Date ourDate = new Date();
v.putDate(ourDate);
Date retrievedDate = v.getJavaDate();
if (!retrievedDate.equals(ourDate)){
if (!retrievedDate.equals(ourDate)) {
fail("failed java date load and unload");
}
v.putNull();
if (!v.isNull()){
if (!v.isNull()) {
fail("failed detecting set null");
}
v.putString("something other than null");
if (v.isNull()){
if (v.isNull()) {
fail("failed null replacement with string");
}
v.putEmpty();
if (!v.isNull()){
if (!v.isNull()) {
fail("failed detecting set empty as null");
}
v.putString("something other than null");
if (v.isNull()){
if (v.isNull()) {
fail("failed empty replacement with string as isNull");
}
Variant v2 = new Variant();
v2.putNothing();
if (v2.getvt() != Variant.VariantDispatch){
if (v2.getvt() != Variant.VariantDispatch) {
fail("putNothing was supposed to set the type to VariantDispatch");
}
if (!v2.isNull()){
if (!v2.isNull()) {
fail("putNothing is supposed to cause isNull() to return true");
}
// this line blows up in the test above
if (v2.toJavaObject() == null){
if (v2.toJavaObject() == null) {
fail("putNothing() followed by toJavaObject() should return a Dispatch");
}
}
/**
* Spin up a lot of threads and have them all create variants
* 3/2007 there have been several reports in multi-threaded servers that show init() failing
*
* verify decimal works right
*/
public void testManyThreadedInit(){
VariantInitTestThread threads[] = new VariantInitTestThread[75];
System.out.println("Starting thread test ("+threads.length
public void testDecimalConversion() {
Variant v = new Variant();
v.changeType(Variant.VariantDecimal);
for (int i = 10; i >= -10; i--) {
v.putDecimal(new BigDecimal(i));
// first see if we can get it back as decimal
assertEquals("conversion back to decimal failed " + i,
new BigDecimal(i), v.getDecimal());
v.changeType(Variant.VariantFloat);
// now see if a float conversion would work
assertEquals("conversion to float failed " + i, new Float(i), v
.getFloat());
// now convert it back to decimal for reassignment
v.changeType(Variant.VariantDecimal);
assertTrue("Failed conversion of type back to Decimal " + i, v
.getvt() == Variant.VariantDecimal);
}
}
/**
* for(BigDecimal i in 79228162514264337593543950330.0 ..
* 79228162514264337593543950341.0) { com.jacob.com.Variant dv = new
* com.jacob.com.Variant(i, false) println i + " : " + dv.getDecimal() }
*
*/
public void testLargeDecimals() {
// the largest decimal number, not in hex is
// 7922816251426433759354395033.0
BigInteger theStartDigits = new BigInteger("ffffffffffffffffffffff00",
16);
BigInteger theMaxDigits = new BigInteger("ffffffffffffffffffffffff", 16);
BigDecimal startDecimal = new BigDecimal(theStartDigits);
BigDecimal endDecimal = new BigDecimal(theMaxDigits);
BigDecimal incrementDecimal = new BigDecimal(1);
BigDecimal testDecimal = startDecimal;
Variant testVariant;
while (endDecimal.compareTo(testDecimal) >= 0) {
testVariant = new Variant(testDecimal, false);
BigDecimal result = testVariant.getDecimal();
assertEquals(testDecimal, result);
testDecimal = testDecimal.add(incrementDecimal);
}
// test Decimal is now too large
try {
new Variant(testDecimal, false);
} catch (IllegalArgumentException iae) {
// System.out.println("Caught expected exception");
}
// lets try something different. we can call putVariant with rounding
// enabled
testVariant = new Variant();
testVariant.changeType(Variant.VariantDecimal);
try {
testVariant.putDecimal(endDecimal.setScale(30));
fail("Should have thrown exception with scale of 30 and no rounding");
} catch (IllegalArgumentException iae) {
// should have caught this exception
}
// now we test with a negative scale. Note that you can't do with
// without some magic, in this case scientific notation
try {
testVariant.putDecimal(new BigDecimal("700E24"));
assertTrue(new BigDecimal("700E24").compareTo(testVariant
.getDecimal()) == 0);
} catch (IllegalArgumentException iae) {
// should have caught this exception
}
testVariant.putDecimal(VariantUtilities
.roundToMSDecimal(new BigDecimal("700E24")));
// use compareTo because it takes into account varying scales
assertTrue(new BigDecimal("700E24").compareTo(testVariant.getDecimal()) == 0);
// This passes because the number is within range.
testVariant.putDecimal(endDecimal);
// this should pass because we have rounding turned on
// it turns out the max number gets more digits when
// it's scale is set to 30. so we can't use the max number when there is
// a scale
BigDecimal modifiedDecimal = endDecimal;
System.out.println("integer piece starts as "
+ modifiedDecimal.unscaledValue().toString(16) + " scale=: "
+ modifiedDecimal.scale());
System.out.println("integer piece after rounding without scale is "
+ VariantUtilities.roundToMSDecimal(modifiedDecimal)
.unscaledValue().toString(16) + " scale=: "
+ modifiedDecimal.scale());
System.out.println("integer piece after rounding with scale 30 is "
+ VariantUtilities.roundToMSDecimal(
modifiedDecimal.setScale(30)).unscaledValue().toString(
16) + " scale=: " + modifiedDecimal.scale());
try {
testVariant.putDecimal(VariantUtilities
.roundToMSDecimal(modifiedDecimal.setScale(30)));
fail("should have thrown an exception for a number whose scale "
+ "change created too many digits to be represented.");
} catch (IllegalArgumentException iae) {
// should catch an exception here because the rounding after scale
// change would have made the number too large
}
System.out.println("");
modifiedDecimal = endDecimal.subtract(incrementDecimal);
System.out.println("integer piece starts as "
+ modifiedDecimal.unscaledValue().toString(16) + " scale=: "
+ modifiedDecimal.scale());
System.out.println("integer piece after rounding without scale is "
+ VariantUtilities.roundToMSDecimal(modifiedDecimal)
.unscaledValue().toString(16) + " scale=: "
+ modifiedDecimal.scale());
System.out.println("integer piece after rounding with scale 30 is "
+ VariantUtilities.roundToMSDecimal(
modifiedDecimal.setScale(30)).unscaledValue().toString(
16) + " scale=: " + modifiedDecimal.scale());
testVariant.putDecimal(VariantUtilities
.roundToMSDecimal(modifiedDecimal.setScale(30)));
System.out.println("");
}
/**
* Spin up a lot of threads and have them all create variants 3/2007 there
* have been several reports in multi-threaded servers that show init()
* failing
*
*/
public void testManyThreadedInit() {
VariantInitTestThread threads[] = new VariantInitTestThread[75];
System.out.println("Starting thread test (" + threads.length
+ " threads each creating 10000 objects)."
+ " This may take 30 seconds or more.");
for (int i = 0; i < threads.length; i++)
{
threads[i] = new VariantInitTestThread("thread-" + i, 10000);
}
for (int i = 0; i < threads.length; i++)
{
threads[i].start();
}
int numComplete = 0;
while (numComplete < threads.length){
// give the works time to work
try {
Thread.sleep(333);
} catch (InterruptedException ie){
for (int i = 0; i < threads.length; i++) {
threads[i] = new VariantInitTestThread("thread-" + i, 10000);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
int numComplete = 0;
while (numComplete < threads.length) {
// give the works time to work
try {
Thread.sleep(333);
} catch (InterruptedException ie) {
// do nothing
}
numComplete = 0;
for ( int i = 0; i < threads.length; i++){
if (threads[i].isComplete){
numComplete++;
}
}
//System.out.print("["+numComplete+"/"+threads.length+"]");
}
numComplete = 0;
for (int i = 0; i < threads.length; i++) {
if (threads[i].isComplete) {
numComplete++;
}
}
// System.out.print("["+numComplete+"/"+threads.length+"]");
}
System.out.println("Finished thread test");
}
/**
* a class to create variants in seperate threads
* @author joe
*
*/
class VariantInitTestThread extends Thread
{
private boolean isComplete = false;
private int initialRunSize = 0;
/**
* @param arg0
*/
public VariantInitTestThread(String newThreadName, int iStartCount)
{
super(newThreadName);
initialRunSize = iStartCount;
}
public boolean isComplete(){
return isComplete;
}
/**
* Blow out a bunch of Variants
*
* @see java.lang.Runnable#run()
*/
public void run()
{
for (int variantIndex = 0; variantIndex < initialRunSize; variantIndex ++ ){
try {
Thread.yield();
Thread.sleep(0);
} catch (InterruptedException ie){
/**
* a class to create variants in separate threads
*
*/
class VariantInitTestThread extends Thread {
private boolean isComplete = false;
private int initialRunSize = 0;
/**
* @param newThreadName
* the name for the thread
* @param iStartCount
* number of threads to start with
*/
public VariantInitTestThread(String newThreadName, int iStartCount) {
super(newThreadName);
initialRunSize = iStartCount;
}
/**
* getter so master can see if thread is done
*
* @return state of complete flag
*/
public boolean isComplete() {
return isComplete;
}
/**
* Blow out a bunch of Variants
*
* @see java.lang.Runnable#run()
*/
public void run() {
for (int variantIndex = 0; variantIndex < initialRunSize; variantIndex++) {
try {
Thread.yield();
Thread.sleep(0);
} catch (InterruptedException ie) {
// do nothing
}
//System.out.println(Thread.currentThread().getName());
Variant testSubject = new Variant(variantIndex);
testSubject.getvt();
testSubject.getInt();
}
isComplete = true;
}
// System.out.println(Thread.currentThread().getName());
Variant testSubject = new Variant(variantIndex);
testSubject.getvt();
testSubject.getInt();
}
isComplete = true;
}
}
}

View File

@@ -0,0 +1,33 @@
package com.jacob.com;
import java.util.Date;
import com.jacob.test.BaseTestCase;
/**
* This class should test some of the converter capabilities
*
*/
public class VariantUtilitiesTest extends BaseTestCase {
/**
* verify that dispatch can convert from object to variant and that the
* variant holds the right value
*/
public void testConverters() {
Date testDate = new Date();
Variant fromDate = VariantUtilities.objectToVariant(testDate);
Date returnedDate = fromDate.getJavaDate();
// System.out.println("test date is "+testDate);
// System.out.println("VariantDate is "+fromDate.getJavaDate());
assertTrue("Could not call obj2variant(Date) and get it to work",
testDate.equals(returnedDate));
Currency someMoney = new Currency(12349876L);
Variant fromMoney = VariantUtilities.objectToVariant(someMoney);
Currency someMoneyConverted = fromMoney.getCurrency();
assertTrue("Could not call obj2variant(Long) and get it to work",
someMoney.equals(someMoneyConverted));
System.out.println("currency returned was: " + someMoneyConverted);
}
}

View File

@@ -7,6 +7,9 @@ import junit.framework.TestCase;
import com.jacob.com.JacobObject;
/**
* This base test class may require that the unittest package be
* 'jacob-project/unittest' be on the classpath to find some resources.
*
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options. Or try these:
@@ -35,10 +38,11 @@ public class BaseTestCase extends TestCase {
/**
* this test exists just to test the setup.
*/
public void testSetup(){
public void testSetup() {
JacobObject foo = new JacobObject();
assertNotNull(foo);
}
/**
*
* @return a simple VB script that generates the result "3"
@@ -49,15 +53,17 @@ public class BaseTestCase extends TestCase {
}
/**
* Converts the class name into a path and appends the resource name.
* Used to derive the path to a resouce in the file system
* where the resource is co-located with the referenced class.
* Converts the class name into a path and appends the resource name. Used
* to derive the path to a resource in the file system where the resource is
* co-located with the referenced class.
*
* @param resourceName
* @param classInSamePackageAsResource
* @return a class loader compatible fully qualified file system path to a resource
* @return a class loader compatible fully qualified file system path to a
* resource
*/
public String getJavaFilePathToPackageResource(String resourceName,
@SuppressWarnings("unchecked")
private String getJavaFilePathToPackageResource(String resourceName,
Class classInSamePackageAsResource) {
String classPackageName = classInSamePackageAsResource.getName();
@@ -65,14 +71,15 @@ public class BaseTestCase extends TestCase {
if (i == -1) {
classPackageName = "";
} else {
classPackageName = classPackageName.substring(0,i);
classPackageName = classPackageName.substring(0, i);
}
// change all "." to ^ for later conversion to "/" so we can append resource names with "."
// change all "." to ^ for later conversion to "/" so we can append
// resource names with "."
classPackageName = classPackageName.replace('.', '^');
System.out.println("classPackageName: " + classPackageName);
String fullPathToResource;
if (classPackageName.length()> 0){
if (classPackageName.length() > 0) {
fullPathToResource = classPackageName + "^" + resourceName;
} else {
fullPathToResource = resourceName;
@@ -81,30 +88,35 @@ public class BaseTestCase extends TestCase {
fullPathToResource = fullPathToResource.replace('^', '/');
System.out.println("fullPathToResource: " + fullPathToResource);
URL urlToLibrary =
classInSamePackageAsResource.getClassLoader().getResource(fullPathToResource);
assertNotNull("URL to resource "+resourceName+" should not be null",urlToLibrary);
URL urlToLibrary = classInSamePackageAsResource.getClassLoader()
.getResource(fullPathToResource);
assertNotNull("URL to resource " + resourceName
+ " should not be null."
+ " You probably need to add 'unittest' to the"
+ " classpath so the tests can find resources", urlToLibrary);
String fullPathToResourceAsFile = urlToLibrary.getFile();
System.out.println("url to library: "+urlToLibrary);
System.out.println("fullPathToResourceAsFile: "+fullPathToResourceAsFile);
System.out.println("url to library: " + urlToLibrary);
System.out.println("fullPathToResourceAsFile: "
+ fullPathToResourceAsFile);
return fullPathToResourceAsFile;
}
/**
* Converts the class name into a path and appends the resource name.
* Used to derive the path to a resouce in the file system
* where the resource is co-located with the referenced class.
* Converts the class name into a path and appends the resource name. Used
* to derive the path to a resource in the file system where the resource is
* co-located with the referenced class.
*
* @param resourceName
* @param classInSamePackageAsResource
* @return returns the path in the file system of the requested resource in windows c
* compatible format
* @return returns the path in the file system of the requested resource in
* windows c compatible format
*/
public String getWindowsFilePathToPackageResource(
String resourceName, Class classInSamePackageAsResource) {
String javaFilePath = getJavaFilePathToPackageResource(
resourceName, classInSamePackageAsResource);
@SuppressWarnings("unchecked")
public String getWindowsFilePathToPackageResource(String resourceName,
Class classInSamePackageAsResource) {
String javaFilePath = getJavaFilePathToPackageResource(resourceName,
classInSamePackageAsResource);
javaFilePath = javaFilePath.replace('/', '\\');
return javaFilePath.substring(1);
}
@@ -115,10 +127,11 @@ public class BaseTestCase extends TestCase {
* @param classInSamePackageAsResource
* @return a resource located in the same package as the passed in class
*/
public Object getPackageResource(String resourceName,
@SuppressWarnings( { "unused", "unchecked" })
private Object getPackageResource(String resourceName,
Class classInSamePackageAsResource) {
String fullPathToResource = getJavaFilePathToPackageResource(resourceName,
classInSamePackageAsResource);
String fullPathToResource = getJavaFilePathToPackageResource(
resourceName, classInSamePackageAsResource);
ClassLoader localClassLoader = classInSamePackageAsResource
.getClassLoader();
if (null == localClassLoader) {
@@ -129,16 +142,16 @@ public class BaseTestCase extends TestCase {
}
/**
* load a library from same place in the file system that the class was
* loaded from.
* load a library from same place in the file system that the class was
* loaded from.
* <p>
* This is an attempt to let unit tests run without having to run
* regsvr32.
* This is an attempt to let unit tests run without having to run regsvr32.
*
* @param libraryName
* @param classInSamePackageAsResource
*/
public void loadLibraryFromClassPackage(String libraryName,
@SuppressWarnings( { "unchecked", "unused" })
private void loadLibraryFromClassPackage(String libraryName,
Class classInSamePackageAsResource) {
String libraryNameWithSuffix = "";
String fullLibraryNameWithPath = "";
@@ -149,12 +162,13 @@ public class BaseTestCase extends TestCase {
} else {
fail("can't create full library name " + libraryName);
}
// generate the path the classloader would use to find this on the classpath
// generate the path the classloader would use to find this on the
// classpath
fullLibraryNameWithPath = getJavaFilePathToPackageResource(
libraryNameWithSuffix, classInSamePackageAsResource);
System.load(fullLibraryNameWithPath);
// requires that the dll be on the library path
//System.loadLibrary(fullLibraryNameWithPath);
// System.loadLibrary(fullLibraryNameWithPath);
}
}

View File

@@ -5,24 +5,30 @@ import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
/**
* This test verifies patch SF 1794811 .
* It shows how unicode filenames throw exceptions in 1.13M4 and earlier.
* This test verifies patch SF 1794811 . It shows how unicode filenames throw
* exceptions in 1.13M4 and earlier.
*
* @author justme84
*
*
*/
public class UnicodeErrorTest extends BaseTestCase {
/**
* verifies that messages can now have unicode in them like when the file
* names have unicode characters
*/
public void testUnicodeCharactersInErrorMessage() {
ActiveXComponent application = new ActiveXComponent("Word.Application");
ActiveXComponent documents = application.getPropertyAsComponent("Documents");
ActiveXComponent documents = application
.getPropertyAsComponent("Documents");
String fileName = "abc\u0411\u0412\u0413\u0414def";
try {
documents.invoke("Open", fileName);
fail("Should have thrown an exception");
} catch (ComException e) {
assertTrue("Error message should contain file name with unicode " +
"characters in it. "+e.getMessage(),
e.getMessage().indexOf(fileName) > 0);
assertTrue("Error message should contain file name with unicode "
+ "characters in it. " + e.getMessage(), e.getMessage()
.indexOf(fileName) > 0);
}
}
}

View File

@@ -2,6 +2,7 @@ package com.jacob.test.events;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.InvocationProxy;
@@ -10,41 +11,34 @@ import com.jacob.test.BaseTestCase;
/**
* This test was lifted from a forum posting and shows how you can't listen to
* Excel events (added post 1.9.1 Eclipse Settings.) This also uses the 1.9.1
* InvocationProxy to receive the events.
* Excel events (added post 1.9.1 Eclipse Settings.) This also uses the 1.9.1
* InvocationProxy to receive the events. The test was modified in 1.14 to show
* how to hook up multiple event listeners to various Excel components
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ExcelEventTest extends BaseTestCase {
/**
* load up excel, register for events and make stuff happen
*
* @param args
*/
public void testExcelWithInvocationProxy() {
String pid = "Excel.Application";
ComThread.InitSTA();
// we are going to listen to events on Application.
// You can probably also listen Excel.Sheet and Excel.Chart
String excelApplicationProgramId = "Excel.Application";
String excelSheetProgramId = "Excel.Sheet";
String typeLibLocation = "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE";
// Grab The Component.
ActiveXComponent axc = new ActiveXComponent(pid);
try {
// Add a listener (doesn't matter what it is).
DispatchEvents de;
if (typeLibLocation == null) {
de = new DispatchEvents(axc, new ExcelEvents());
} else {
de = new DispatchEvents(axc, new ExcelEvents(), pid,
typeLibLocation);
}
if (de == null) {
System.out
.println("No exception thrown but no dispatch returned for Excel events");
} else {
// Yea!
System.out.println("Successfully attached to " + pid);
ActiveXComponent axc = new ActiveXComponent(excelApplicationProgramId);
hookupListener(axc, excelApplicationProgramId, typeLibLocation);
}
try {
System.out.println("version=" + axc.getProperty("Version"));
System.out.println("version=" + Dispatch.get(axc, "Version"));
@@ -52,6 +46,7 @@ public class ExcelEventTest extends BaseTestCase {
Dispatch workbooks = axc.getPropertyAsComponent("Workbooks");
Dispatch workbook = Dispatch.get(workbooks, "Add").toDispatch();
Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
hookupListener(sheet, excelSheetProgramId, typeLibLocation);
Dispatch a1 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { "A1" }, new int[1]).toDispatch();
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
@@ -60,36 +55,83 @@ public class ExcelEventTest extends BaseTestCase {
System.out.println("Inserting calculation 2xA1 into A2");
Dispatch.put(a1, "Value", "123.456");
Dispatch.put(a2, "Formula", "=A1*2");
System.out.println("Retrieved a1 from excel:" + Dispatch.get(a1, "Value"));
System.out.println("Retrieved a2 from excel:" + Dispatch.get(a2, "Value"));
System.out.println("Retrieved a1 from excel:"
+ Dispatch.get(a1, "Value"));
System.out.println("Retrieved a2 from excel:"
+ Dispatch.get(a2, "Value"));
Variant f = new Variant(false);
Dispatch.call(workbook, "Close", f);
axc.invoke("Quit", new Variant[] {});
} catch (ComException cfe) {
cfe.printStackTrace();
fail("Failed to attach to " + pid + ": "
fail("Failed to attach to " + excelApplicationProgramId + ": "
+ cfe.getMessage());
}
try {
// the sleep is required to let everything clear out after the quit
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ComThread.Release();
}
/**
* extracted the listener hookup so we could try multiple listeners.
*
* @param axc
* @param programId
* @param typeLibLocation
*/
private void hookupListener(Dispatch axc, String programId,
String typeLibLocation) {
// Add a listener (doesn't matter what it is).
DispatchEvents applicationEvents;
if (typeLibLocation == null) {
applicationEvents = new DispatchEvents(axc, new ExcelEvents(
programId));
} else {
applicationEvents = new DispatchEvents(axc, new ExcelEvents(
programId), programId, typeLibLocation);
}
if (applicationEvents == null) {
System.out
.println("No exception thrown but no dispatch returned for Excel events");
} else {
// Yea!
System.out.println("Successfully attached to " + programId);
}
}
public class ExcelEvents extends InvocationProxy {
/**
* Constructor so we can create an instance that implements invoke()
* Proxy class to verify we receive expected events
*/
public ExcelEvents() {
}
public class ExcelEvents extends InvocationProxy {
/**
* Override the invoke method to log all the events so that we don't have to
* implement all of the specific events.
*/
public Variant invoke(String methodName, Variant targetParameter[]) {
System.out.println("Received event from Windows program" + methodName);
return null;
}
private String listenerPrefix = "-";
}
/**
* Constructor so we can create an instance that implements invoke()
*
* @param interfaceIdentifier
* a string that identifies which listener is speaking
*/
public ExcelEvents(String interfaceIdentifier) {
listenerPrefix = interfaceIdentifier;
}
/**
* Override the invoke method to log all the events so that we don't
* have to implement all of the specific events.
*/
public Variant invoke(String methodName, Variant targetParameter[]) {
System.out.println("Received event from " + listenerPrefix + ": "
+ methodName);
return null;
}
}
}

View File

@@ -6,212 +6,406 @@ import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* This test runs fine against jdk 1.4 and 1.5
*
* This demonstrates the new event handling code in jacob 1.7
* This example will open up IE and print out some of the events
* it listens to as it havigates to web sites.
* contributed by Niels Olof Bouvin mailto:n.o.bouvin@daimi.au.dk
* and Henning Jae jehoej@daimi.au.dk
* This demonstrates the new event handling code in jacob 1.7 This example will
* open up IE and print out some of the events it listens to as it havigates to
* web sites. contributed by Niels Olof Bouvin mailto:n.o.bouvin@daimi.au.dk and
* Henning Jae jehoej@daimi.au.dk
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class IETest extends BaseTestCase {
/**
* runs the IE test and feeds it commands
*/
public void testRunIE() {
// this line starts the pump but it runs fine without it
ComThread.startMainSTA();
// remove this line and it dies
///ComThread.InitMTA(true);
IETestThread aThread = new IETestThread();
aThread.start();
while (aThread.isAlive()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// doen with the sleep
//e.printStackTrace();
}
}
System.out.println("Main: Thread quit, about to quit main sta in thread "
+Thread.currentThread().getName());
// this line only does someting if startMainSTA() was called
ComThread.quitMainSTA();
System.out.println("Main: did quit main sta in thread "
+Thread.currentThread().getName());
if (aThread.threadFailedWithException != null){
fail("caught an unexpected exception "+aThread.threadFailedWithException);
}
}
// this line starts the pump but it runs fine without it
ComThread.startMainSTA();
// remove this line and it dies
// /ComThread.InitMTA(true);
IETestThread aThread = new IETestThread();
aThread.start();
while (aThread.isAlive()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// doen with the sleep
// e.printStackTrace();
}
}
System.out
.println("Main: Thread quit, about to quit main sta in thread "
+ Thread.currentThread().getName());
// this line only does someting if startMainSTA() was called
ComThread.quitMainSTA();
System.out.println("Main: did quit main sta in thread "
+ Thread.currentThread().getName());
if (aThread.threadFailedWithException != null) {
fail("caught an unexpected exception "
+ aThread.threadFailedWithException);
}
}
}
class IETestThread extends Thread
{
class IETestThread extends Thread {
/** flag that says we got a quit message from IE */
public static boolean quitHandled = false;
/**
* holds any caught exception so the main/test case can see them
*/
public Throwable threadFailedWithException = null;
public IETestThread(){
super();
}
public void run()
{
// this used to be 5 seconds but sourceforge is slow
int delay = 5000; // msec
// paired with statement below that blows up
ComThread.InitMTA();
ActiveXComponent ie = new ActiveXComponent("InternetExplorer.Application");
try {
Dispatch.put(ie, "Visible", new Variant(true));
Dispatch.put(ie, "AddressBar", new Variant(true));
System.out.println("IETestThread: " + Dispatch.get(ie, "Path"));
Dispatch.put(ie, "StatusText", new Variant("My Status Text"));
System.out.println("IETestThread: About to hookup event listener");
IEEvents ieE = new IEEvents();
new DispatchEvents(ie, ieE,"InternetExplorer.Application.1");
System.out.println("IETestThread: Did hookup event listener");
/// why is this here? Was there some other code here in the past?
Variant optional = new Variant();
optional.putNoParam();
System.out.println("IETestThread: About to call navigate to sourceforge");
Dispatch.call(ie, "Navigate", new Variant("http://sourceforge.net/projects/jacob-project"));
System.out.println("IETestThread: Did call navigate to sourceforge");
try { Thread.sleep(delay); } catch (Exception e) {}
System.out.println("IETestThread: About to call navigate to yahoo");
Dispatch.call(ie, "Navigate", new Variant("http://groups.yahoo.com/group/jacob-project"));
System.out.println("IETestThread: Did call navigate to yahoo");
try { Thread.sleep(delay); } catch (Exception e) {}
} catch (Exception e) {
threadFailedWithException = e;
e.printStackTrace();
} catch (Throwable re){
threadFailedWithException = re;
re.printStackTrace();
} finally {
System.out.println("IETestThread: About to send Quit");
ie.invoke("Quit", new Variant[] {});
System.out.println("IETestThread: Did send Quit");
}
// this blows up when it tries to release a DispatchEvents object
// I think this is because there is still one event we should get back
// "OnQuit" that will came after we have released the thread pool
// this is probably messed up because DispatchEvent object will have been
// freed before the callback
// commenting out ie.invoke(quit...) causes this to work without error
// this code tries to wait until the quit has been handled but that doesn't work
System.out.println("IETestThread: Waiting until we've received the quit callback");
while (!quitHandled){
try { Thread.sleep(delay/5);} catch (InterruptedException e) {}
}
System.out.println("IETestThread: Received the quit callback");
// wait a little while for it to end
//try {Thread.sleep(delay); } catch (InterruptedException e) {}
System.out.println("IETestThread: about to call ComThread.Release in thread " +
Thread.currentThread().getName());
ComThread.Release();
}
/**
* constructor for the test thread
*/
public IETestThread() {
super();
}
/**
* The events class must be publicly accessable for reflection to work.
* The list of available events is located at http://msdn2.microsoft.com/en-us/library/aa768280.aspx
*/
public class IEEvents
{
public void BeforeNavigate2(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): BeforeNavigate2 "+args.length);
}
public void run() {
// this used to be 5 seconds but sourceforge is slow
int delay = 5000; // msec
// paired with statement below that blows up
ComThread.InitMTA();
ActiveXComponent ie = new ActiveXComponent(
"InternetExplorer.Application");
try {
Dispatch.put(ie, "Visible", new Variant(true));
Dispatch.put(ie, "AddressBar", new Variant(true));
System.out.println("IETestThread: " + Dispatch.get(ie, "Path"));
Dispatch.put(ie, "StatusText", new Variant("My Status Text"));
public void CommandStateChange(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): CommandStateChange "+args.length);
}
System.out.println("IETestThread: About to hookup event listener");
IEEvents ieE = new IEEvents();
new DispatchEvents(ie, ieE, "InternetExplorer.Application.1");
System.out.println("IETestThread: Did hookup event listener");
// / why is this here? Was there some other code here in the past?
Variant optional = new Variant();
optional.putNoParam();
public void DocumentComplete(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DocumentComplete "+args.length);
}
System.out
.println("IETestThread: About to call navigate to sourceforge");
Dispatch.call(ie, "Navigate", new Variant(
"http://sourceforge.net/projects/jacob-project"));
System.out
.println("IETestThread: Did call navigate to sourceforge");
try {
Thread.sleep(delay);
} catch (Exception e) {
}
System.out.println("IETestThread: About to call navigate to yahoo");
Dispatch.call(ie, "Navigate", new Variant(
"http://groups.yahoo.com/group/jacob-project"));
System.out.println("IETestThread: Did call navigate to yahoo");
try {
Thread.sleep(delay);
} catch (Exception e) {
}
} catch (Exception e) {
threadFailedWithException = e;
e.printStackTrace();
} catch (Throwable re) {
threadFailedWithException = re;
re.printStackTrace();
} finally {
System.out.println("IETestThread: About to send Quit");
ie.invoke("Quit", new Variant[] {});
System.out.println("IETestThread: Did send Quit");
}
// this blows up when it tries to release a DispatchEvents object
// I think this is because there is still one event we should get back
// "OnQuit" that will came after we have released the thread pool
// this is probably messed up because DispatchEvent object will have
// been
// freed before the callback
// commenting out ie.invoke(quit...) causes this to work without error
// this code tries to wait until the quit has been handled but that
// doesn't work
System.out
.println("IETestThread: Waiting until we've received the quit callback");
while (!quitHandled) {
try {
Thread.sleep(delay / 5);
} catch (InterruptedException e) {
}
}
System.out.println("IETestThread: Received the quit callback");
// wait a little while for it to end
// try {Thread.sleep(delay); } catch (InterruptedException e) {}
System.out
.println("IETestThread: about to call ComThread.Release in thread "
+ Thread.currentThread().getName());
public void DownloadBegin(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DownloadBegin "+args.length);
}
ComThread.Release();
}
public void DownloadComplete(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): DownloadComplete "+args.length);
}
/**
* The events class must be publicly accessable for reflection to work. The
* list of available events is located at
* http://msdn2.microsoft.com/en-us/library/aa768280.aspx
*/
public class IEEvents {
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void BeforeNavigate2(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): BeforeNavigate2 "
+ args.length);
}
public void NavigateError(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NavigateError "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void CommandStateChange(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName()
+ "): CommandStateChange " + args.length);
}
public void NavigateComplete2(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NavigateComplete "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void DocumentComplete(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): DocumentComplete "
+ args.length);
}
public void NewWindow2(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NewWindow2 "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void DownloadBegin(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): DownloadBegin "
+ args.length);
}
public void OnFullScreen(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnFullScreen "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void DownloadComplete(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): DownloadComplete "
+ args.length);
}
public void OnMenuBar(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnMenuBar "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void NavigateError(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): NavigateError "
+ args.length);
}
public void OnQuit(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnQuit "+args.length);
IETestThread.quitHandled = true;
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void NavigateComplete2(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): NavigateComplete "
+ args.length);
}
public void OnStatusBar(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnStatusBar "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void NewWindow2(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): NewWindow2 "
+ args.length);
}
public void OnTheaterMode(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnTheaterMode "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnFullScreen(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnFullScreen "
+ args.length);
}
public void OnToolBar(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnToolBar "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnMenuBar(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnMenuBar "
+ args.length);
}
public void OnVisible(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnVisible "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnQuit(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnQuit "
+ args.length);
IETestThread.quitHandled = true;
}
public void ProgressChange(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): ProgressChange "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnStatusBar(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnStatusBar "
+ args.length);
}
public void PropertyChange(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): PropertyChange "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnTheaterMode(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnTheaterMode "
+ args.length);
}
public void SetSecureLockIcon(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): setSecureLockIcon "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnToolBar(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnToolBar "
+ args.length);
}
public void StatusTextChange(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): StatusTextChange "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void OnVisible(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): OnVisible "
+ args.length);
}
public void TitleChange(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): TitleChange "+args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void ProgressChange(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): ProgressChange "
+ args.length);
}
public void WindowClosing(Variant[] args) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): WindowClosing "+args.length);
}
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void PropertyChange(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): PropertyChange "
+ args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void SetSecureLockIcon(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName()
+ "): setSecureLockIcon " + args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void StatusTextChange(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): StatusTextChange "
+ args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void TitleChange(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): TitleChange "
+ args.length);
}
/**
* Internet explorer event this proxy can receive
*
* @param args
* the COM Variant objects that this event passes in.
*/
public void WindowClosing(Variant[] args) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): WindowClosing "
+ args.length);
}
}
}

View File

@@ -6,213 +6,284 @@ import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* This test runs fine against jdk 1.4 and 1.5
*
* This demonstrates the new event handling code in jacob 1.7
* This example will open up IE and print out some of the events
* it listens to as it havigates to web sites.
* contributed by Niels Olof Bouvin mailto:n.o.bouvin@daimi.au.dk
* and Henning Jae jehoej@daimi.au.dk
* This demonstrates the new event handling code in jacob 1.7 This example will
* open up IE and print out some of the events it listens to as it havigates to
* web sites. contributed by Niels Olof Bouvin mailto:n.o.bouvin@daimi.au.dk and
* Henning Jae jehoej@daimi.au.dk
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class IETestActiveXProxy extends BaseTestCase {
public void testIEActiveProxyCallback() {
// this line starts the pump but it runs fine without it
ComThread.startMainSTA();
// remove this line and it dies
///ComThread.InitMTA(true);
IETestActiveProxyThread aThread = new IETestActiveProxyThread();
aThread.start();
while (aThread.isAlive()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// doen with the sleep
//e.printStackTrace();
}
}
System.out.println("Main: Thread quit, about to quit main sta in thread "
+Thread.currentThread().getName());
// this line only does someting if startMainSTA() was called
ComThread.quitMainSTA();
System.out.println("Main: did quit main sta in thread "
+Thread.currentThread().getName());
if (aThread.threadFailedWithException != null){
fail("caught an unexpected exception "+aThread.threadFailedWithException);
}
}
/**
* the main test method that builds up the connection and runs the test
*/
public void testIEActiveProxyCallback() {
// this line starts the pump but it runs fine without it
ComThread.startMainSTA();
// remove this line and it dies
// /ComThread.InitMTA(true);
IETestActiveProxyThread aThread = new IETestActiveProxyThread();
aThread.start();
while (aThread.isAlive()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// doen with the sleep
// e.printStackTrace();
}
}
System.out
.println("Main: Thread quit, about to quit main sta in thread "
+ Thread.currentThread().getName());
// this line only does someting if startMainSTA() was called
ComThread.quitMainSTA();
System.out.println("Main: did quit main sta in thread "
+ Thread.currentThread().getName());
if (aThread.threadFailedWithException != null) {
fail("caught an unexpected exception "
+ aThread.threadFailedWithException);
}
}
}
class IETestActiveProxyThread extends Thread
{
class IETestActiveProxyThread extends Thread {
/** says that the quit message has been received from the target application */
public static boolean quitHandled = false;
/**
* holds any caught exception so the main/test case can see them
*/
public Throwable threadFailedWithException = null;
public IETestActiveProxyThread(){
super();
}
public void run()
{
// this used to be 5 seconds but sourceforge is slow
int delay = 5000; // msec
// paired with statement below that blows up
ComThread.InitMTA();
ActiveXComponent ie = new ActiveXComponent("InternetExplorer.Application");
try {
Dispatch.put(ie, "Visible", new Variant(true));
Dispatch.put(ie, "AddressBar", new Variant(true));
System.out.println("IETestActiveProxyThread: " + Dispatch.get(ie, "Path"));
Dispatch.put(ie, "StatusText", new Variant("My Status Text"));
System.out.println("IETestActiveProxyThread: About to hookup event listener");
IEEventsActiveProxy ieE = new IEEventsActiveProxy();
new ActiveXDispatchEvents(ie, ieE,"InternetExplorer.Application.1");
System.out.println("IETestActiveProxyThread: Did hookup event listener");
/// why is this here? Was there some other code here in the past?
Variant optional = new Variant();
optional.putNoParam();
System.out.println("IETestActiveProxyThread: About to call navigate to sourceforge");
Dispatch.call(ie, "Navigate", new Variant("http://sourceforge.net/projects/jacob-project"));
System.out.println("IETestActiveProxyThread: Did call navigate to sourceforge");
try { Thread.sleep(delay); } catch (Exception e) {}
System.out.println("IETestActiveProxyThread: About to call navigate to yahoo");
Dispatch.call(ie, "Navigate", new Variant("http://groups.yahoo.com/group/jacob-project"));
System.out.println("IETestActiveProxyThread: Did call navigate to yahoo");
try { Thread.sleep(delay); } catch (Exception e) {}
} catch (Exception e) {
threadFailedWithException = e;
e.printStackTrace();
} catch (Throwable re){
threadFailedWithException = re;
re.printStackTrace();
} finally {
System.out.println("IETestActiveProxyThread: About to send Quit");
ie.invoke("Quit", new Variant[] {});
System.out.println("IETestActiveProxyThread: Did send Quit");
}
// this blows up when it tries to release a DispatchEvents object
// I think this is because there is still one event we should get back
// "OnQuit" that will came after we have released the thread pool
// this is probably messed up because DispatchEvent object will have been
// freed before the callback
// commenting out ie.invoke(quit...) causes this to work without error
// this code tries to wait until the quit has been handled but that doesn't work
System.out.println("IETestActiveProxyThread: Waiting until we've received the quit callback");
while (!quitHandled){
try { Thread.sleep(delay/5);} catch (InterruptedException e) {}
}
System.out.println("IETestActiveProxyThread: Received the quit callback");
// wait a little while for it to end
//try {Thread.sleep(delay); } catch (InterruptedException e) {}
System.out.println("IETestActiveProxyThread: about to call ComThread.Release in thread " +
Thread.currentThread().getName());
ComThread.Release();
}
/** the thread's constructor */
public IETestActiveProxyThread() {
super();
}
/**
* The events class must be publicly accessable for reflection to work.
* The list of available events is located at http://msdn2.microsoft.com/en-us/library/aa768280.aspx
*/
public class IEEventsActiveProxy
{
public void BeforeNavigate2(Dispatch pDisp, String url, Integer flags,
String targetFrameName, Variant postData, String headers, Boolean cancel) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): BeforeNavigate2 "+url);
}
public void run() {
// this used to be 5 seconds but sourceforge is slow
int delay = 5000; // msec
// paired with statement below that blows up
ComThread.InitMTA();
ActiveXComponent ie = new ActiveXComponent(
"InternetExplorer.Application");
try {
Dispatch.put(ie, "Visible", new Variant(true));
Dispatch.put(ie, "AddressBar", new Variant(true));
System.out.println("IETestActiveProxyThread: "
+ Dispatch.get(ie, "Path"));
Dispatch.put(ie, "StatusText", new Variant("My Status Text"));
public void CommandStateChange(Integer command, Boolean enable) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): CommandStateChange "+command);
}
System.out
.println("IETestActiveProxyThread: About to hookup event listener");
IEEventsActiveProxy ieE = new IEEventsActiveProxy();
new ActiveXDispatchEvents(ie, ieE, "InternetExplorer.Application.1");
System.out
.println("IETestActiveProxyThread: Did hookup event listener");
// / why is this here? Was there some other code here in the past?
Variant optional = new Variant();
optional.putNoParam();
public void DocumentComplete(Dispatch pDisp, String url) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DocumentComplete "+url);
}
System.out
.println("IETestActiveProxyThread: About to call navigate to sourceforge");
Dispatch.call(ie, "Navigate", new Variant(
"http://sourceforge.net/projects/jacob-project"));
System.out
.println("IETestActiveProxyThread: Did call navigate to sourceforge");
try {
Thread.sleep(delay);
} catch (Exception e) {
}
System.out
.println("IETestActiveProxyThread: About to call navigate to yahoo");
Dispatch.call(ie, "Navigate", new Variant(
"http://groups.yahoo.com/group/jacob-project"));
System.out
.println("IETestActiveProxyThread: Did call navigate to yahoo");
try {
Thread.sleep(delay);
} catch (Exception e) {
}
} catch (Exception e) {
threadFailedWithException = e;
e.printStackTrace();
} catch (Throwable re) {
threadFailedWithException = re;
re.printStackTrace();
} finally {
System.out.println("IETestActiveProxyThread: About to send Quit");
ie.invoke("Quit", new Variant[] {});
System.out.println("IETestActiveProxyThread: Did send Quit");
}
// this blows up when it tries to release a DispatchEvents object
// I think this is because there is still one event we should get back
// "OnQuit" that will came after we have released the thread pool
// this is probably messed up because DispatchEvent object will have
// been
// freed before the callback
// commenting out ie.invoke(quit...) causes this to work without error
// this code tries to wait until the quit has been handled but that
// doesn't work
System.out
.println("IETestActiveProxyThread: Waiting until we've received the quit callback");
while (!quitHandled) {
try {
Thread.sleep(delay / 5);
} catch (InterruptedException e) {
}
}
System.out
.println("IETestActiveProxyThread: Received the quit callback");
// wait a little while for it to end
// try {Thread.sleep(delay); } catch (InterruptedException e) {}
System.out
.println("IETestActiveProxyThread: about to call ComThread.Release in thread "
+ Thread.currentThread().getName());
public void DownloadBegin() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DownloadBegin ");
}
ComThread.Release();
}
public void DownloadComplete() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DownloadComplete ");
}
/**
* The events class must be publicly accessable for reflection to work. The
* list of available events is located at
* http://msdn2.microsoft.com/en-us/library/aa768280.aspx
*/
public class IEEventsActiveProxy {
public void NavigateComplete2(Dispatch pDisp, String url) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): NavigateComplete "+url);
}
public void BeforeNavigate2(Dispatch pDisp, String url, Integer flags,
String targetFrameName, Variant postData, String headers,
Boolean cancel) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): BeforeNavigate2 "
+ url);
}
public void NavigateError(Dispatch pDispatch, String url, String targetFrameName, Integer statusCode, Boolean Cancel) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NavigateError "+statusCode);
}
public void CommandStateChange(Integer command, Boolean enable) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName()
+ "): CommandStateChange " + command);
}
public void NewWindow2(Dispatch pDisp, Boolean cancel) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): NewWindow2 "+pDisp);
}
public void DocumentComplete(Dispatch pDisp, String url) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): DocumentComplete "
+ url);
}
public void OnFullScreen(Boolean fullScreen) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnFullScreen "+fullScreen);
}
public void DownloadBegin() {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): DownloadBegin ");
}
public void OnMenuBar(Boolean menuBar) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnMenuBar "+menuBar);
}
public void DownloadComplete() {
System.out
.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName()
+ "): DownloadComplete ");
}
public void OnQuit() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnQuit ");
IETestActiveProxyThread.quitHandled = true;
}
public void NavigateComplete2(Dispatch pDisp, String url) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): NavigateComplete "
+ url);
}
public void OnStatusBar(Boolean statusBar) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnStatusBar "+statusBar);
}
public void NavigateError(Dispatch pDispatch, String url,
String targetFrameName, Integer statusCode, Boolean Cancel) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): NavigateError "
+ statusCode);
}
public void OnTheaterMode(Boolean theaterMode) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnTheaterMode "+theaterMode);
}
public void NewWindow2(Dispatch pDisp, Boolean cancel) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): NewWindow2 "
+ pDisp);
}
public void OnToolBar(Boolean onToolBar) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnToolBar "+onToolBar);
}
public void OnFullScreen(Boolean fullScreen) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnFullScreen "
+ fullScreen);
}
public void OnVisible(Boolean onVisible) {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): onVisible "+ onVisible);
}
public void OnMenuBar(Boolean menuBar) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnMenuBar "
+ menuBar);
}
public void ProgressChange() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): ProgressChange ");
}
public void OnQuit() {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnQuit ");
IETestActiveProxyThread.quitHandled = true;
}
public void PropertyChange() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): PropertyChange ");
}
public void OnStatusBar(Boolean statusBar) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnStatusBar "
+ statusBar);
}
public void SetSecureLockIcon(Integer secureLockIcon) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): setSecureLockIcon "+secureLockIcon);
}
public void OnTheaterMode(Boolean theaterMode) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnTheaterMode "
+ theaterMode);
}
public void StatusTextChange() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): StatusTextChange ");
}
public void OnToolBar(Boolean onToolBar) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): OnToolBar "
+ onToolBar);
}
public void TitleChange() {
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): TitleChange ");
}
public void OnVisible(Boolean onVisible) {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): onVisible "
+ onVisible);
}
public void WindowClosing(Boolean isChildWindow) {
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): WindowClosing "+isChildWindow);
}
}
public void ProgressChange() {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): ProgressChange ");
}
public void PropertyChange() {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): PropertyChange ");
}
public void SetSecureLockIcon(Integer secureLockIcon) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName()
+ "): setSecureLockIcon " + secureLockIcon);
}
public void StatusTextChange() {
System.out
.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName()
+ "): StatusTextChange ");
}
public void TitleChange() {
System.out.println("IEEventsActiveProxy Received ("
+ Thread.currentThread().getName() + "): TitleChange ");
}
public void WindowClosing(Boolean isChildWindow) {
System.out.println("IEEvents Received ("
+ Thread.currentThread().getName() + "): WindowClosing "
+ isChildWindow);
}
}
}

View File

@@ -9,19 +9,20 @@ import com.jacob.test.BaseTestCase;
/**
* This test was lifted from a forum posting and shows how you can't listen to
* Excel events (added post 1.9.1 Eclipse Settings.)
* That test was modified make this a MSWord event listener to demonstrate
* that the InvocationProxy code works with MS Word Events
* This also uses the 1.10
* InvocationProxy to receive the events.
* Excel events (added post 1.9.1 Eclipse Settings.) That test was modified make
* this a MSWord event listener to demonstrate that the InvocationProxy code
* works with MS Word Events This also uses the 1.10 InvocationProxy to receive
* the events.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class WordEventTest extends BaseTestCase {
/**
* load up word, register for events and make stuff happen
*
* @param args
*/
public void testCaptureWordEvents() {
@@ -49,38 +50,44 @@ public class WordEventTest extends BaseTestCase {
// this is different from the ExcelEventTest because it uses
// the jacob active X api instead of the Dispatch api
System.out.println("version=" + axc.getPropertyAsString("Version"));
axc.setProperty("Visible",true);
ActiveXComponent documents = axc.getPropertyAsComponent("Documents");
if (documents == null){
axc.setProperty("Visible", true);
ActiveXComponent documents = axc
.getPropertyAsComponent("Documents");
if (documents == null) {
fail("unable to get documents");
}
axc.invoke("Quit", new Variant[] {});
} catch (ComException cfe) {
cfe.printStackTrace();
fail("Failed to attach to " + pid + ": " + cfe.getMessage());
fail("Failed to attach to " + pid + ": " + cfe.getMessage());
}
System.out.println(
"Someone needs to add some MSWord commands to this to " +
"make some on screen stuff happens so the tester " +
"thinks we tested something");
}
public class WordEvents extends InvocationProxy {
/**
* Constructor so we can create an instance that implements invoke()
*/
public WordEvents() {
System.out
.println("Someone needs to add some MSWord commands to this to "
+ "make some on screen stuff happens so the tester "
+ "thinks we tested something");
}
/**
* override the invoke() method to log all the events without writing a bunch of code
* a class that receives messages from word
*/
public Variant invoke(String methodName, Variant targetParameter[]) {
System.out.println("Received event from Windows program" + methodName);
return null;
}
public class WordEvents extends InvocationProxy {
/**
* Constructor so we can create an instance that implements invoke()
*/
public WordEvents() {
}
}
/**
* override the invoke() method to log all the events without writing a
* bunch of code
*/
public Variant invoke(String methodName, Variant targetParameter[]) {
System.out.println("Received event from Windows program"
+ methodName);
return null;
}
}
}

View File

@@ -0,0 +1,236 @@
package com.jacob.test.excel;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* this test verifies that you can call toString() on a Variant extracted from
* Excel that contains a 2 dimensional array of doubles. 1.14M5 and earlier blew
* up on this because two objects pointed at the same windows memory space SF 1840487
*/
public class ControllerTest extends BaseTestCase {
private Controller controller;
protected void setUp() {
controller = new Controller();
}
public void testGetColumnA() {
List<String> list = controller.getColumnA(super
.getWindowsFilePathToPackageResource("teste.xls", this
.getClass()));
assertEquals(50, list.size());
}
public void testGetColumnB() {
List<String> list = controller.getColumnB(super
.getWindowsFilePathToPackageResource("teste.xls", this
.getClass()));
assertEquals(40, list.size());
}
/**
* This class looks bad because it is a compressed version that was
* originally in 3 different files as part of a bug submission. I didn't
* want to simplify it because it might no longer demonstrate the problem we
* were trying to fix
*/
public class Controller {
private List<String> columnA;
private List<String> columnB;
public List<String> getColumnA(String pathToTest) {
load(pathToTest);
return columnA;
}
public List<String> getColumnB(String pathToTest) {
load(pathToTest);
return columnB;
}
public void load(String pathToTest) {
if (columnA == null || columnB == null) {
File excelFile = new File(pathToTest);
executaExcelCallBack(excelFile.getAbsolutePath(), "password");
}
}
public void executaExcelCallBack(String path, String password) {
// ComThread.InitSTA();
ComThread.InitMTA();
ActiveXComponent excel = new ActiveXComponent("Excel.Application");
try {
excel.setProperty("Visible", false);
Dispatch workbooks = excel.getProperty("Workbooks")
.toDispatch();
Dispatch workbook = Dispatch.call(workbooks, "Open", path, // FileName
3, // UpdateLinks
false, // Readonly
5, // Format
password // Password
).toDispatch();
Dispatch sheets = Dispatch.call(workbook, "Worksheets")
.toDispatch();
System.out.println("Before executa");
executa(excel, sheets);
System.out.println("After executa");
Dispatch.call(workbook, "Close", new Variant(false));
Dispatch.call(workbooks, "Close");
System.out.println("After Close");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Before Quit");
excel.invoke("Quit", new Variant[] {});
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("After Quit, Before Release()");
ComThread.Release();
System.out.println("After Release()");
}
}
/**
* Constante para configurar a planilha em modo "Calculation" autom<6F>tico
*/
public static final int CALC_AUTOMATICO = -4105;
/**
* Constante para configurar a planilha em modo "Calculation" manual
*/
public static final int CALC_MANUAL = -4135;
/**
* Escreve um determinado valor em uma c<>lula da pasta em quest<73>o. O
* valor <20> escrito configurando a propriedade Value da c<>lula
*
* @param celula -
* c<>lula para escrever novo valor
* @param sheet -
* pasta da planilha em quest<73>o
* @param valor -
* valor a ser escrito na celula
*/
public void informarValorCelula(String celula, Dispatch sheet,
String valor) {
System.out.println("Entered informarValorCelula");
Dispatch cel = obterCelula(celula, sheet);
Dispatch.put(cel, "Value", valor);
System.out.println("Exiting informarValorCelula");
}
/**
* Obtem o valor de contido em uma c<>lula. O valor representa o conte<74>do
* da propriedade Value da c<>lula
*
* @param celula -
* c<>lula a ser lida
* @param sheet -
* pasta da planilha que cont<6E>m a c<>lula
* @return - conte<74>do da propriedade Value
*/
public Variant obterValorCelula(String celula, Dispatch sheet) {
System.out.println("Entered obterValorCelula");
Dispatch d = obterCelula(celula, sheet);
Variant returnedValue = Dispatch.get(d, "Value");
System.out.println("Exiting obterValorCelula");
return returnedValue;
}
/**
* Obtem refer<65>ncia para a c<>lua ou conjunto de c<>lulas especificado no
* parametro
*
* @param celula -
* Refer<65>ncia para c<>lula ou conjunto de c<>lulas. A String
* "A1" referencia a coluna A e linha 1. A Sting "A1:A10"
* referencia as c<>lulas compreendidas no intervalo entre a
* c<>lua A1 e a c<>lula A10
* @param sheet -
* pasta da planilha qye cont<6E>m as c<>lulas
* @return - referencia para um c<>lula ou conjunto de c<>lulas,
* dependendo do par<61>metro passado
*/
public Dispatch obterCelula(String celula, Dispatch sheet) {
System.out.println("Entered obterCelula");
Dispatch d = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { celula }, new int[1]).toDispatch();
System.out.println("Exiting obterCelula");
return d;
}
/**
* Obtem os valores de um conjunto de c<>lulas
*
* @param celulas -
* Refer<65>ncia para conjunto de c<>lulas
* @param sheet -
* Pasta que cont<6E>m as c<>lulas referenciadas
* @return - Lista onde cada elemento <20> o valor de uma c<>lula
* referenciada na conjunto
*/
public List<String> obterValoresRange(String celulas, Dispatch sheet) {
List<String> valores = new LinkedList<String>();
// obtem valor das celulas como um Variant
Variant var = obterValorCelula(celulas, sheet);
// toString da Variant <20> interpretado por um StringTokenizer e os
// tokens
// inseridos na lista de retorno
String arrayAsString = null;
System.out
.println("Calling toString() on the Variant that is an array will blow up "
+ var.getvt() + " --> " + arrayAsString);
arrayAsString = var.toString();
StringTokenizer st = new StringTokenizer(arrayAsString, "\n");
while (st.hasMoreTokens()) {
valores.add(st.nextToken().trim());
}
return valores;
}
/**
* M<>todo para execu<63><75>o de a<><61>o a ser executada em planilha excel.
*
* @param xl -
* Referencia para aplica<63><61>o excel
* @param sheets -
* Referencia para conjunto de pastas da planilha
*/
public void executa(ActiveXComponent xl, Dispatch sheets) {
System.out.println("Entered private ExcellCallBack executa()");
Dispatch sheet = Dispatch.call(sheets, "Item", "Plan1")
.toDispatch();
columnA = obterValoresRange("A1:A50", sheet);
columnB = obterValoresRange("B1:B40", sheet);
System.out.println("Exiting private ExcellCallBack executa()");
}
}
}

Binary file not shown.

View File

@@ -1,13 +1,13 @@
package com.jacob.test.powerpoint;
/**
* $Id$
*
* This is really more of a multi threaded tester
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
/**
* $Id$
*
* This is really more of a multi threaded tester
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComFailException;
import com.jacob.com.ComThread;
@@ -17,117 +17,136 @@ import com.jacob.test.BaseTestCase;
/**
*
* power point test program posted to sourceforge to demonstrate memory problem.
* The submitter stated they had the problem on windows 2000 with office 2000
* I have been unable to duplicate on windows XP with office 2003.
* I am comitting this to the tree just in case we need to come back to it.
* The submitter stated they had the problem on windows 2000 with office 2000 I
* have been unable to duplicate on windows XP with office 2003. I am comitting
* this to the tree just in case we need to come back to it.
* <P>
* This relies on BaseTestCase to provide the root path to the file under test
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class PowerpointTest extends BaseTestCase {
public class PowerpointTest extends BaseTestCase {
private static final int NUM_THREADS = 5;
protected static final int NUM_ITERATIONS = 50;
protected static final int NUM_ITERATIONS = 50;
/**
* main program that lets us run this as a test
* @param args
*/
public void testPowerpoint() {
ComThread.InitMTA();
ActiveXComponent component = new ActiveXComponent("Powerpoint.Application");
Dispatch comPowerpoint = component.getObject();
try {
PowerpointTestThread[] threads = new PowerpointTestThread[NUM_THREADS];
for (int i=0; i<NUM_THREADS; i++) {
threads[i] = new PowerpointTestThread(i+1, comPowerpoint);
threads[i].start();
}
boolean allThreadsFinished = false;
while (!allThreadsFinished) {
allThreadsFinished = true;
for (int i=0; i<NUM_THREADS; i++) {
if (threads[i].isAlive()) {
allThreadsFinished = false;
break;
}
}
if (!allThreadsFinished) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// no op
}
}
}
Dispatch.call(comPowerpoint,"Quit");
for (int i = 0 ; i < NUM_THREADS; i++){
if (threads[i].threadFailedWithException != null){
fail ("caught unexpected exception in thread "+
threads[i].threadFailedWithException);
}
}
} finally {
ComThread.Release();
}
}
public class PowerpointTestThread extends Thread {
/**
* holds any caught exception so the main/test case can see them
* main program that lets us run this as a test
*
* @param args
*/
public Throwable threadFailedWithException = null;
private int threadID;
private Dispatch comPowerpoint;
public PowerpointTestThread(int threadID, Dispatch comPowerpoint) {
super("TestThread "+threadID);
this.threadID = threadID;
this.comPowerpoint = comPowerpoint;
}
public void run() {
System.out.println("Thread \""+Thread.currentThread().getName()+"\" started");
System.out.flush();
ComThread.InitMTA();
try {
for (int i=0; i<NUM_ITERATIONS; i++) {
if (i % 10 == 0) {
System.out.println(Thread.currentThread().getName()+": Iteration "+i);
System.out.flush();
}
Dispatch comPresentations = Dispatch.get(comPowerpoint,"Presentations").toDispatch();
Dispatch comPresentation = Dispatch.call(comPresentations,
"Open",
getWindowsFilePathToPackageResource("test"+threadID+".ppt",this.getClass()),
new Integer(0),
new Integer(0),
new Integer(0)).toDispatch();
Dispatch.call(comPresentation, "Close");
}
} catch (ComFailException cfe){
threadFailedWithException = cfe;
System.err.println(Thread.currentThread().getName()+"\" while working on: "+
getWindowsFilePathToPackageResource("test"+threadID+".ppt",this.getClass()));
cfe.printStackTrace();
} catch (Exception e) {
threadFailedWithException = e;
System.err.println("Error in Thread \""+Thread.currentThread().getName()+"\":");
e.printStackTrace();
} finally {
ComThread.Release();
System.out.println("Thread \""+Thread.currentThread().getName()+"\" finished");
System.out.flush();
}
}
}
public void testPowerpoint() {
ComThread.InitMTA();
ActiveXComponent component = new ActiveXComponent(
"Powerpoint.Application");
Dispatch comPowerpoint = component.getObject();
try {
PowerpointTestThread[] threads = new PowerpointTestThread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new PowerpointTestThread(i + 1, comPowerpoint);
threads[i].start();
}
boolean allThreadsFinished = false;
while (!allThreadsFinished) {
allThreadsFinished = true;
for (int i = 0; i < NUM_THREADS; i++) {
if (threads[i].isAlive()) {
allThreadsFinished = false;
break;
}
}
if (!allThreadsFinished) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// no op
}
}
}
Dispatch.call(comPowerpoint, "Quit");
for (int i = 0; i < NUM_THREADS; i++) {
if (threads[i].threadFailedWithException != null) {
fail("caught unexpected exception in thread "
+ threads[i].threadFailedWithException);
}
}
} finally {
ComThread.Release();
}
}
/**
* the thread class that runs power point
*/
public class PowerpointTestThread extends Thread {
/**
* holds any caught exception so the main/test case can see them
*/
public Throwable threadFailedWithException = null;
private int threadID;
private Dispatch comPowerpoint;
/**
* thread constructor
*
* @param threadID
* @param comPowerpoint
*/
public PowerpointTestThread(int threadID, Dispatch comPowerpoint) {
super("TestThread " + threadID);
this.threadID = threadID;
this.comPowerpoint = comPowerpoint;
}
public void run() {
System.out.println("Thread \"" + Thread.currentThread().getName()
+ "\" started");
System.out.flush();
ComThread.InitMTA();
try {
for (int i = 0; i < NUM_ITERATIONS; i++) {
if (i % 10 == 0) {
System.out.println(Thread.currentThread().getName()
+ ": Iteration " + i);
System.out.flush();
}
Dispatch comPresentations = Dispatch.get(comPowerpoint,
"Presentations").toDispatch();
Dispatch comPresentation = Dispatch.call(
comPresentations,
"Open",
getWindowsFilePathToPackageResource("test"
+ threadID + ".ppt", this.getClass()),
new Integer(0), new Integer(0), new Integer(0))
.toDispatch();
Dispatch.call(comPresentation, "Close");
}
} catch (ComFailException cfe) {
threadFailedWithException = cfe;
System.err.println(Thread.currentThread().getName()
+ "\" while working on: "
+ getWindowsFilePathToPackageResource("test" + threadID
+ ".ppt", this.getClass()));
cfe.printStackTrace();
} catch (Exception e) {
threadFailedWithException = e;
System.err.println("Error in Thread \""
+ Thread.currentThread().getName() + "\":");
e.printStackTrace();
} finally {
ComThread.Release();
System.out.println("Thread \""
+ Thread.currentThread().getName() + "\" finished");
System.out.flush();
}
}
}
}

View File

@@ -6,67 +6,195 @@ import com.jacob.test.BaseTestCase;
/**
* SafeArrayTest Program
*
* This is more of an exerciser. It doesn't verify that it gets back
* what it expects like a junit test would
*
* This is more of an exerciser. It doesn't verify that it gets back what it
* expects like a junit test would
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*
*/
public class SafeArrayBasicTest extends BaseTestCase {
public void testBasicSafeArray(){
//System.runFinalizersOnExit(true);
SafeArray sa = new SafeArray(Variant.VariantVariant, 3);
sa.fromShortArray(new short[] { 1, 2, 3 });
System.out.println("sa short=" + sa);
int[] ai = sa.toIntArray();
for (int i = 0; i < ai.length; i++) {
System.out.println("toInt=" + ai[i]);
/**
*
*/
public void testShortSafeArray() {
short sourceData[] = new short[] { 1, 2, 3 };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromShortArray(sourceData);
short[] extractedFromSafeArray = saUnderTest.toShortArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
double[] ad = sa.toDoubleArray();
for (int i = 0; i < ad.length; i++) {
System.out.println("toDouble=" + ad[i]);
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getShort(2));
// test conversion
int[] extractedFromSafeArrayInt = saUnderTest.toIntArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArrayInt[i]);
}
sa.fromIntArray(new int[] { 100000, 200000, 300000 });
System.out.println("sa int=" + sa);
ai = sa.toIntArray();
for (int i = 0; i < ai.length; i++) {
System.out.println("toInt=" + ai[i]);
// test conversion
double[] extractedFromSafeArrayDouble = saUnderTest.toDoubleArray();
for (int i = 0; i < extractedFromSafeArrayDouble.length; i++) {
assertEquals("" + i, new Double(sourceData[i]).doubleValue(),
extractedFromSafeArrayDouble[i]);
}
ad = sa.toDoubleArray();
for (int i = 0; i < ad.length; i++) {
System.out.println("toDouble=" + ad[i]);
// test conversion
Variant extractedFromSafeArrayVariant[] = saUnderTest.toVariantArray();
for (int i = 0; i < extractedFromSafeArrayVariant.length; i++) {
assertEquals("" + i, sourceData[i],
extractedFromSafeArrayVariant[i].getShort());
}
Variant av[] = sa.toVariantArray();
for (int i = 0; i < av.length; i++) {
System.out.println("toVariant=" + av[i]);
}
/**
*
*/
public void testIntSafeArray() {
int sourceData[] = new int[] { 100000, 200000, 300000 };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromIntArray(sourceData);
int[] extractedFromSafeArray = saUnderTest.toIntArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
sa.fromDoubleArray(new double[] { 1.5, 2.5, 3.5 });
System.out.println("sa double=" + sa);
sa.fromFloatArray(new float[] { 1.5F, 2.5F, 3.5F });
System.out.println("sa float=" + sa);
sa.fromBooleanArray(new boolean[] { true, false, true, false });
System.out.println("sa bool=" + sa);
av = sa.toVariantArray();
for (int i = 0; i < av.length; i++) {
System.out.println("toVariant=" + av[i]);
}
sa.fromCharArray(new char[] { 'a', 'b', 'c', 'd' });
System.out.println("sa char=" + sa);
sa.fromStringArray(new String[] { "hello", "from", "java", "com" });
System.out.println("sa string=" + sa);
av = sa.toVariantArray();
for (int i = 0; i < av.length; i++) {
System.out.println("toVariant=" + av[i]);
}
sa.fromVariantArray(new Variant[] {
new Variant(1), new Variant(2.3), new Variant("hi") });
System.out.println("sa variant=" + sa);
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getInt(2));
}
/**
*
*/
public void testLongSafeArray() {
long sourceData[] = new long[] { 2L << 40, 3L << 41, 4L << 42 };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromLongArray(sourceData);
long[] extractedFromSafeArray = saUnderTest.toLongArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getLong(2));
}
/**
*
*/
public void testDoubleSafeArray() {
double sourceData[] = new double[] { 1.5, 2.5, 3.5 };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromDoubleArray(sourceData);
double[] extractedFromSafeArray = saUnderTest.toDoubleArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getDouble(2));
}
/**
*
*/
public void testFloatSafeArray() {
float sourceData[] = new float[] { 1.5F, 2.5F, 3.5F };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromFloatArray(sourceData);
float[] extractedFromSafeArray = saUnderTest.toFloatArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
}
/**
*
*/
public void testBooleanSafeArray() {
boolean sourceData[] = new boolean[] { true, false, true, false };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromBooleanArray(sourceData);
boolean[] extractedFromSafeArray = saUnderTest.toBooleanArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getBoolean(2));
// test conversion
Variant extractedFromSafeArrayVariant[] = saUnderTest.toVariantArray();
for (int i = 0; i < extractedFromSafeArrayVariant.length; i++) {
assertEquals("" + i, sourceData[i],
extractedFromSafeArrayVariant[i].getBoolean());
}
}
/**
*
*/
public void testCharSafeArray() {
char sourceData[] = new char[] { 'a', 'b', 'c', 'd' };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromCharArray(sourceData);
char[] extractedFromSafeArray = saUnderTest.toCharArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getChar(2));
}
/**
*
*/
public void testStringSaveArray() {
String sourceData[] = new String[] { "hello", "from", "java", "com" };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromStringArray(sourceData);
String[] extractedFromSafeArray = saUnderTest.toStringArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i], extractedFromSafeArray[i]);
}
assertEquals("single get failed: ", sourceData[2], saUnderTest
.getString(2));
// test conversion
Variant extractedFromSafeArrayVariant[] = saUnderTest.toVariantArray();
for (int i = 0; i < extractedFromSafeArrayVariant.length; i++) {
assertEquals("" + i, sourceData[i],
extractedFromSafeArrayVariant[i].getString());
}
}
/**
*
*/
public void testVariantSafeArray() {
Variant sourceData[] = new Variant[] { new Variant(1),
new Variant(2.3), new Variant("hi") };
SafeArray saUnderTest = new SafeArray(Variant.VariantVariant, 3);
saUnderTest.fromVariantArray(sourceData);
Variant[] extractedFromSafeArray = saUnderTest.toVariantArray();
for (int i = 0; i < extractedFromSafeArray.length; i++) {
assertEquals("" + i, sourceData[i].toString(),
extractedFromSafeArray[i].toString());
}
assertEquals("single get failed: ", sourceData[2].toString(),
saUnderTest.getVariant(2).toString());
}
/**
* test method that verifies setting of bounds in multi-dimensional arrays
*/
public void testSafeArrayNumDimensions() {
int[] lowerBounds = new int[] { 0, 0, 0 };
int[] dimensionSizes = new int[] { 3, 3, 3 };
@@ -75,13 +203,29 @@ public class SafeArrayBasicTest extends BaseTestCase {
dimensionSizes);
System.out.println("Num Dimensions = " + sa3x3.getNumDim());
for (int i = 1; i <= sa3x3.getNumDim(); i++) {
System.out.println("Dimension number = " + i);
System.out.println("Lower bound = " + sa3x3.getLBound(i));
System.out.println("Upper bound = " + sa3x3.getUBound(i));
for (int safeArrayDimension = 1; safeArrayDimension <= sa3x3
.getNumDim(); safeArrayDimension++) {
int configArrayIndex = safeArrayDimension - 1;
assertEquals("unexpected lower bound value ",
lowerBounds[configArrayIndex], sa3x3
.getLBound(safeArrayDimension));
assertEquals("unexpeced upper bound value ",
(dimensionSizes[configArrayIndex] - 1)
+ lowerBounds[configArrayIndex], sa3x3
.getUBound(safeArrayDimension));
}
}
int fill = 0;
/**
* test the set and get method on multi-dimensional arrays
*/
public void testSafeArrayMultiDimension() {
int[] lowerBounds = new int[] { 0, 0, 0 };
int[] dimensionSizes = new int[] { 3, 3, 3 };
SafeArray sa3x3 = new SafeArray(Variant.VariantVariant, lowerBounds,
dimensionSizes);
int[] indices = new int[] { 0, 0, 0 };
for (int i = 0; i < 3; i++) {
@@ -90,10 +234,17 @@ public class SafeArrayBasicTest extends BaseTestCase {
indices[1] = j;
for (int k = 0; k < 3; k++) {
indices[2] = k;
int fill = 0;
fill = i * 100 + j * 10 + k;
sa3x3.setInt(indices, fill);
System.out.println("sa[" + i + "][" + j + "][" + k + "] = "
+ sa3x3.getInt(indices));
assertEquals(fill, sa3x3.getInt(indices));
long fillLong = 0L;
// Pick a number bigger than 2^31
fillLong = 100000000000000L * fill;
sa3x3.setLong(indices, fillLong);
assertEquals(fillLong, sa3x3.getLong(indices));
}
}
}

View File

@@ -267,7 +267,7 @@ public class SafeArrayContents extends BaseTestCase {
fail("Failed to catch expected exception");
} catch (ComFailException cfe) {
// do nothing
//cfe.printStackTrace();
// cfe.printStackTrace();
}
}
}

View File

@@ -7,6 +7,9 @@ import com.jacob.com.SafeArray;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* Test class to verify dispatch with SafeArray
*/
public class SafeArrayDispatchTest extends BaseTestCase {
public void testDispatchWithSafeArray() {
try {
@@ -36,7 +39,7 @@ public class SafeArrayDispatchTest extends BaseTestCase {
assertTrue(result.toString().equals("6"));
} catch (ComException e) {
e.printStackTrace();
fail("script failure "+e);
fail("script failure " + e);
}
}
}

View File

@@ -3,191 +3,175 @@ package com.jacob.test.safearray;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.JacobObject;
import com.jacob.com.JacobReleaseInfo;
import com.jacob.com.SafeArray;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* This test program demonstrates a weak in the setString(int[],String) method in SafeArray.
* To see the leak:
* This test program demonstrates a weak in the setString(int[],String) method
* in SafeArray. To see the leak:
* <ul>
* <li>Bring up the windows task manager and click on the performance tab.
* <li>Run the test program
* </ul>
* You should see the Page File Usage History graph rise at te end of every cycle.
* Running the same program with setString(r,c,String) does not show the same symptoms
* You should see the Page File Usage History graph rise at te end of every
* cycle. Running the same program with setString(r,c,String) does not show the
* same symptoms
*/
public class SafeArrayLeak extends BaseTestCase {
public class SafeArrayLeak extends BaseTestCase {
/**
/**
* ----------------------------------------------------------------------------------------------------------------------------
*
* ----------------------------------------------------------------------------------------------------------------------------
*/
public void testLeakWithSetString() {
ActiveXComponent xl = null;
Dispatch workbooks = null;
Dispatch workbook = null;
Dispatch workSheets = null;
Dispatch sheet = null;
Dispatch tabCells = null;
SafeArray sa = null;
//-Dcom.jacob.autogc=true
System.out.println("Jacob version: "+JacobObject.getBuildVersion());
for(int t = 0; t < 10; t++) {
// look at a large range of cells
ActiveXComponent xl = null;
Dispatch workbooks = null;
Dispatch workbook = null;
Dispatch workSheets = null;
Dispatch sheet = null;
Dispatch tabCells = null;
SafeArray sa = null;
// -Dcom.jacob.autogc=true
System.out.println("Jacob version: " + JacobReleaseInfo.getBuildVersion());
for (int t = 0; t < 10; t++) {
// look at a large range of cells
String position = "A7:DM8934";
try {
xl = new ActiveXComponent("Excel.Application");
System.out.println("Excel version=" + xl.getProperty("Version"));
try {
xl = new ActiveXComponent("Excel.Application");
System.out
.println("Excel version=" + xl.getProperty("Version"));
xl.setProperty("Visible", new Variant(false));
workbooks = xl.getProperty("Workbooks").toDispatch();
workbook = Dispatch.get(workbooks,"Add").toDispatch();
workbook = Dispatch.get(workbooks, "Add").toDispatch();
workSheets = Dispatch.get(workbook, "Worksheets").toDispatch();
sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
// grab the whole range specified above.
tabCells = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { position },
new int[1]).toDispatch();
tabCells = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { position }, new int[1]).toDispatch();
sa = Dispatch.get(tabCells, "Value").toSafeArray(true);
System.out.println("Ub0=" + sa.getUBound(1)); // nbCol
System.out.println("Ub1=" + sa.getUBound(2)); // nbLgn
// number of rows
int nbLgn = sa.getUBound(2);
// number of columns
int nbCol = sa.getUBound(1);
int[] colLgn = new int[] { 0, 0 };
// now set a value on every cell in the range we retrieved
for(int i = 1; i <= nbLgn; i++) {
for (int i = 1; i <= nbLgn; i++) {
colLgn[1] = i;
for(int j = 1; j <= nbCol; j++) {
for (int j = 1; j <= nbCol; j++) {
colLgn[0] = j;
// this one works with out a leak 1.13-M3
//sa.setString(j, i, "test");
// sa.setString(j, i, "test");
// This one leaks with 1.13-M3 and earlier
sa.setString(colLgn, "test");
}
}
Dispatch.put(tabCells, "Value", sa);
Variant f = new Variant(false);
Dispatch.call(workbook, "Close", f);
System.out.println("Close");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if (sa != null) {
try {
sa.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
sa = null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sa != null) {
try {
sa.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
sa = null;
}
}
if (tabCells != null) {
try {
tabCells.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
tabCells = null;
}
}
if (sheet != null) {
try {
sheet.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
sheet = null;
}
}
if (workSheets != null) {
try {
workSheets.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workSheets = null;
}
try {
tabCells.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
tabCells = null;
}
}
if (sheet != null) {
try {
sheet.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
sheet = null;
}
}
if (workSheets != null) {
try {
workSheets.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
workSheets = null;
}
}
if (workbook != null) {
try {
workbook.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workbook = null;
}
}
if (workbooks != null) {
try {
workbooks.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workbooks = null;
}
}
if (xl != null) {
try {
xl.invoke("Quit", new Variant[] {});
}
catch(Exception e) {
e.printStackTrace();
}
try {
xl.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
xl = null;
}
}
ComThread.Release();
}
}
try {
workbook.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
workbook = null;
}
}
if (workbooks != null) {
try {
workbooks.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
workbooks = null;
}
}
if (xl != null) {
try {
xl.invoke("Quit", new Variant[] {});
} catch (Exception e) {
e.printStackTrace();
}
try {
xl.safeRelease();
} catch (Exception e) {
e.printStackTrace();
} finally {
xl = null;
}
}
ComThread.Release();
}
}
}
}

View File

@@ -7,111 +7,83 @@ import com.jacob.test.BaseTestCase;
/**
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* <p>
* SF 1085370
In my understatnding, an instance of SafeArray java
class has a
value of a pointer to VARIANT structure that contains a
pointer to
a SAFEARRAY strucuture.
On the other hand, we can create a Variant object from
the
SafeArray object like this:
SafeArray sa = ...;
Variant val = new Variant(sa);
the val object has a pointer to another VARIANT
structure that
contains a pointer to the same SAFEARRAY structure.
In this case, the val object has a pointer to another
VARIANT that
contains a pointer to the same SAFEARRAY like this:
+-----------+
|SafeArray | +------------+
| m_pV--->VARIANT(a) |
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +^--------+
|
+-----------+ |
|Variant | +------------+ |
| m_pVariant--->VARIANT(b) | |
+-----------+ | VT_ARRAY| |
| parray-----+
+------------+
When previous objects are rereased by
ComThread.Release(),
first the VARIANT(a) is released by VariantClear()
function,
and second the VARIANT(b) is released by VariantClear()
function too.
But the SAFEARRAY was already released by the
VARIANT(a).
So, in my enviroment (WinXP + J2SDK 1.4.1) the
following java program
is sometimes crash with EXCEPTION_ACCESS_VIOLATION.
To solve this problem, it is nessesary to copy the
SAFEARRAY like this:
+-----------+
|Variant | +------------+
| m_pVariant--->VARIANT(a) |
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +|--------+
|
+-----------+ | copySA()
|SafeArray | +------------+ |
| m_pV--->VARIANT(b) | V
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +---------+
*
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* SF 1085370 In my understatnding, an instance of SafeArray java class has a
* value of a pointer to VARIANT structure that contains a pointer to a
* SAFEARRAY strucuture.
*
* On the other hand, we can create a Variant object from the SafeArray object
* like this: SafeArray sa = ...; Variant val = new Variant(sa); the val object
* has a pointer to another VARIANT structure that contains a pointer to the
* same SAFEARRAY structure.
*
* In this case, the val object has a pointer to another VARIANT that contains a
* pointer to the same SAFEARRAY like this:
*
* +-----------+ |SafeArray | +------------+ | m_pV--->VARIANT(a) |
* +-----------+ | VT_ARRAY| +---------+ | parray---->SAFEARRAY| +------------+
* +^--------+ | +-----------+ | |Variant | +------------+ | |
* m_pVariant--->VARIANT(b) | | +-----------+ | VT_ARRAY| | | parray-----+
* +------------+
*
* When previous objects are rereased by ComThread.Release(), first the
* VARIANT(a) is released by VariantClear() function, and second the VARIANT(b)
* is released by VariantClear() function too. But the SAFEARRAY was already
* released by the VARIANT(a).
*
* So, in my enviroment (WinXP + J2SDK 1.4.1) the following java program is
* sometimes crash with EXCEPTION_ACCESS_VIOLATION.
*
*
* To solve this problem, it is nessesary to copy the SAFEARRAY like this:
*
* +-----------+ |Variant | +------------+ | m_pVariant--->VARIANT(a) |
* +-----------+ | VT_ARRAY| +---------+ | parray---->SAFEARRAY| +------------+
* +|--------+ | +-----------+ | copySA() |SafeArray | +------------+ | |
* m_pV--->VARIANT(b) | V +-----------+ | VT_ARRAY| +---------+ |
* parray---->SAFEARRAY| +------------+ +---------+
*
* <p>
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class SafeArrayReleaseTest extends BaseTestCase {
final static int MAX = 300;
public void testSaveArrayRelease() {
int count;
System.out.println("Starting test for max = "+MAX);
for(count = 1; count<MAX; count++)
{
int i = 0;
try
{
ComThread.InitMTA();
for (i = 0; i < count; i++)
{
SafeArray a1 = new SafeArray(Variant.VariantVariant, 2);
a1.setVariant(0, new Variant("foo"));
a1.setVariant(1, new Variant("bar"));
Variant v = new Variant(a1);
SafeArray a2 = v.toSafeArray(true);
if (a2 == null){
System.out.println("got null back from toSafeArray()");
}
}
ComThread.Release();
System.gc();
//System.out.print(".");
}
catch (Exception e)
{
fail("Test fails with i = " + i + " (max = "+MAX+")");
}
}
System.gc();
System.out.println("\nTest ends with count = " + count + " (max = "+MAX+")");
}
final static int MAX = 300;
/**
* verifies the release works on SafeArray
*/
public void testSaveArrayRelease() {
int count;
System.out.println("Starting test for max = " + MAX);
for (count = 1; count < MAX; count++) {
int i = 0;
try {
ComThread.InitMTA();
for (i = 0; i < count; i++) {
SafeArray a1 = new SafeArray(Variant.VariantVariant, 2);
a1.setVariant(0, new Variant("foo"));
a1.setVariant(1, new Variant("bar"));
Variant v = new Variant(a1);
SafeArray a2 = v.toSafeArray(true);
if (a2 == null) {
System.out.println("got null back from toSafeArray()");
}
}
ComThread.Release();
System.gc();
// System.out.print(".");
} catch (Exception e) {
fail("Test fails with i = " + i + " (max = " + MAX + ")");
}
}
System.gc();
System.out.println("\nTest ends with count = " + count + " (max = "
+ MAX + ")");
}
}

View File

@@ -1,21 +1,26 @@
package com.jacob.test.safearray;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.SafeArray;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* This does simple tests with SafeArray using Excel as a source
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
* <p>
* This relies on BaseTestCase to provide the root path to the file under test
*/
public class SafeArrayViaExcel extends BaseTestCase {
/**
* verify safe arrays work with standard applications, Excel in this case
*/
public void testSafeArrayViaExcel() {
// deprecated
// System.runFinalizersOnExit(true);
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
try {
@@ -26,8 +31,9 @@ public class SafeArrayViaExcel extends BaseTestCase {
Dispatch workbook = Dispatch.call(
workbooks,
"Open",
getWindowsFilePathToPackageResource("SafeArrayViaExcel.xls",this.getClass()))
.toDispatch();
getWindowsFilePathToPackageResource(
"SafeArrayViaExcel.xls", this.getClass()))
.toDispatch();
System.out.println("Opened File - SafeArrayViaExcel.xls\n");
Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
cell = Dispatch.invoke(sheet, "Range", Dispatch.Get,
@@ -61,7 +67,7 @@ public class SafeArrayViaExcel extends BaseTestCase {
System.out.println("Closed File\n");
} catch (Exception e) {
e.printStackTrace();
fail("Caught Exception "+e);
fail("Caught Exception " + e);
} finally {
xl.invoke("Quit", new Variant[] {});
}

View File

@@ -1,8 +1,12 @@
package com.jacob.test.vbscript;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* In this case the component is created and used in the same thread and it's an
@@ -33,7 +37,7 @@ public class ScriptTest extends BaseTestCase {
String scriptCommand = getSampleVPScriptForEval();
String lang = "VBScript";
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
sControl = (Dispatch) sC.getObject();
sControl = sC.getObject();
Dispatch.put(sControl, "Language", lang);
ScriptTestErrEvents te = new ScriptTestErrEvents();
de = new DispatchEvents(sControl, te);

View File

@@ -1,8 +1,14 @@
package com.jacob.test.vbscript;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.DispatchProxy;
import com.jacob.com.STA;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* This example demonstrates how to make calls between two different STA's.
@@ -21,8 +27,9 @@ import com.jacob.activeX.*;
* multiple threads to access a Dispatch pointer, then create that many
* DispatchProxy objects.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ScriptTest2 extends BaseTestCase {
@@ -31,8 +38,8 @@ public class ScriptTest2 extends BaseTestCase {
ComThread.InitSTA();
ScriptTestSTA script = new ScriptTestSTA();
try {
Thread.sleep(1000);
} catch (InterruptedException ie){
Thread.sleep(1000);
} catch (InterruptedException ie) {
// should we get this?
}
@@ -50,7 +57,7 @@ public class ScriptTest2 extends BaseTestCase {
System.out.println("called quit");
} catch (ComException e) {
e.printStackTrace();
fail("caught exception"+e);
fail("caught exception" + e);
} finally {
Integer I = null;
for (int i = 1; i < 1000000; i++) {
@@ -63,11 +70,11 @@ public class ScriptTest2 extends BaseTestCase {
public class ScriptTestSTA extends STA {
public DispatchEvents de = null;
public DispatchEvents de = null;
public Dispatch sControl = null;
public Dispatch sControl = null;
public DispatchProxy sCon = null;
public DispatchProxy sCon = null;
public boolean OnInit() {
try {

View File

@@ -26,8 +26,9 @@ import com.jacob.test.BaseTestCase;
* multiple threads to access a Dispatch pointer, then create that many
* DispatchProxy objects.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ScriptTest2ActiveX extends BaseTestCase {
public static ActiveXComponent sC;
@@ -42,9 +43,9 @@ public class ScriptTest2ActiveX extends BaseTestCase {
ScriptTest2ActiveXSTA script = new ScriptTest2ActiveXSTA();
try {
Thread.sleep(1000);
} catch (InterruptedException ie){
// should we get this?
}
} catch (InterruptedException ie) {
// should we get this?
}
// get a thread-local Dispatch from sCon
ActiveXComponent sc = new ActiveXComponent(sCon.toDispatch());
@@ -60,7 +61,7 @@ public class ScriptTest2ActiveX extends BaseTestCase {
System.out.println("called quit");
} catch (ComException e) {
e.printStackTrace();
fail("blew up with Com Exception "+e);
fail("blew up with Com Exception " + e);
} finally {
Integer I = null;
for (int i = 1; i < 1000000; i++) {

View File

@@ -1,8 +1,12 @@
package com.jacob.test.vbscript;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* Here we create the ScriptControl component in a separate MTA thread and then
@@ -10,8 +14,9 @@ import com.jacob.activeX.*;
* MTA thread. If you try to create it as an STA then you will not be able to
* make calls into a component running in another thread.
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ScriptTest3 extends BaseTestCase {
@@ -29,13 +34,15 @@ public class ScriptTest3 extends BaseTestCase {
ScriptTest3Inner script = new ScriptTest3Inner();
script.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ie){
Thread.sleep(1000);
} catch (InterruptedException ie) {
// should we get this?
}
Variant result = Dispatch.call(sControl, "Eval", getSampleVPScriptForEval());
System.out.println("eval(" + getSampleVPScriptForEval() + ") = " + result);
Variant result = Dispatch.call(sControl, "Eval",
getSampleVPScriptForEval());
System.out.println("eval(" + getSampleVPScriptForEval() + ") = "
+ result);
System.out.println("setting quit");
ScriptTest3.quit = true;
} catch (ComException e) {
@@ -54,13 +61,14 @@ public class ScriptTest3 extends BaseTestCase {
System.out.println("OnInit");
String lang = "VBScript";
sC = new ActiveXComponent("ScriptControl");
sControl = (Dispatch) sC.getObject();
sControl = sC.getObject();
Dispatch.put(sControl, "Language", lang);
ScriptTestErrEvents te = new ScriptTestErrEvents();
de = new DispatchEvents(sControl, te);
System.out.println("sControl=" + sControl);
while (!quit)
while (!quit) {
sleep(100);
}
ComThread.Release();
} catch (Exception e) {
e.printStackTrace();

View File

@@ -1,8 +1,11 @@
package com.jacob.test.vbscript;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* Here we create the ScriptControl component in a separate MTA thread and then
@@ -33,9 +36,8 @@ public class ScriptTest3ActiveX extends BaseTestCase {
}
Variant result = sC.invoke("Eval", getSampleVPScriptForEval());
System.out
.println("eval(" + getSampleVPScriptForEval()
+ ") = " + result);
System.out.println("eval(" + getSampleVPScriptForEval() + ") = "
+ result);
System.out.println("setting quit");
ScriptTest3ActiveX.quit = true;
} catch (ComException e) {
@@ -58,8 +60,9 @@ public class ScriptTest3ActiveX extends BaseTestCase {
ScriptTestErrEvents te = new ScriptTestErrEvents();
de = new DispatchEvents(sC, te);
System.out.println("sControl=" + sC);
while (!quit)
while (!quit) {
sleep(100);
}
ComThread.Release();
} catch (Exception e) {
e.printStackTrace();

View File

@@ -1,52 +1,53 @@
package com.jacob.test.vbscript;
import com.jacob.com.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComException;
import com.jacob.com.ComThread;
import com.jacob.com.DispatchEvents;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
import com.jacob.activeX.*;
/**
* In this case the component is created and used in the same thread
* and it's an Apartment Threaded component, so we call InitSTA.
* In this case the component is created and used in the same thread and it's an
* Apartment Threaded component, so we call InitSTA.
* <p>
* May need to run with some command line options (including from inside
* Eclipse). Look in the docs area at the Jacob usage document for command line
* options.
*/
public class ScriptTestActiveX extends BaseTestCase {
public void testActiveXScript() {
public void testActiveXScript() {
ComThread.InitSTA(true);
DispatchEvents de = null;
DispatchEvents de = null;
try {
String lang = "VBScript";
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
sC.setProperty("Language",lang);
ScriptTestErrEvents te = new ScriptTestErrEvents();
de = new DispatchEvents(sC, te);
if (de == null){
System.out.println("null returned when trying to create DispatchEvents");
}
Variant result;
result = sC.invoke("Eval",getSampleVPScriptForEval());
// call it twice to see the objects reused
result = sC.invoke("Eval",getSampleVPScriptForEval());
// call it 3 times to see the objects reused
result = sC.invoke("Eval",getSampleVPScriptForEval());
System.out.println("eval("+getSampleVPScriptForEval()+") = "+ result);
} catch (ComException e) {
e.printStackTrace();
}
finally
{
Integer I = null;
for(int i=1;i<1000000;i++)
{
I = new Integer(i);
}
System.out.println(I);
try {
String lang = "VBScript";
ActiveXComponent sC = new ActiveXComponent("ScriptControl");
sC.setProperty("Language", lang);
ScriptTestErrEvents te = new ScriptTestErrEvents();
de = new DispatchEvents(sC, te);
if (de == null) {
System.out
.println("null returned when trying to create DispatchEvents");
}
Variant result;
result = sC.invoke("Eval", getSampleVPScriptForEval());
// call it twice to see the objects reused
result = sC.invoke("Eval", getSampleVPScriptForEval());
// call it 3 times to see the objects reused
result = sC.invoke("Eval", getSampleVPScriptForEval());
System.out.println("eval(" + getSampleVPScriptForEval() + ") = "
+ result);
} catch (ComException e) {
e.printStackTrace();
} finally {
Integer I = null;
for (int i = 1; i < 1000000; i++) {
I = new Integer(i);
}
System.out.println(I);
ComThread.Release();
ComThread.quitMainSTA();
}
}
}
}
}

View File

@@ -4,17 +4,16 @@ import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* Extracted from ScriptTest so everyone can see this
* Made a test solely because it made the ant test easier
* Extracted from ScriptTest so everyone can see this Made a test solely because
* it made the ant test easier
*/
public class ScriptTestErrEvents extends BaseTestCase {
public void Error(Variant[] args)
{
System.out.println("java callback for error!");
}
public void Timeout(Variant[] args)
{
System.out.println("java callback for error!");
}
public void Error(Variant[] args) {
System.out.println("java callback for error!");
}
public void Timeout(Variant[] args) {
System.out.println("java callback for error!");
}
}

View File

@@ -8,7 +8,7 @@ package com.jacob.test.windowsmedia;
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
import com.jacob.activeX.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.test.BaseTestCase;
public class WMPlayer extends BaseTestCase {