B-1_14-DEV merge back to main
This commit is contained in:
@@ -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
|
||||
|
||||
180
build.xml
180
build.xml
@@ -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=".">
|
||||
@@ -49,15 +49,17 @@
|
||||
|
||||
<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="src.java.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.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.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,10 +430,10 @@
|
||||
<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="LICENSE.* ${generated.filename.version} 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.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>
|
||||
@@ -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' >
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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"> </td>
|
||||
<td width="87%" valign="top"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" colspan="2"><b>Patches</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%" valign="top"> </td>
|
||||
<td width="87%" valign="top"> </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"> </td>
|
||||
<td width="87%" valign="top"> </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>
|
||||
|
||||
@@ -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<platform>.<version.>.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> </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> </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> </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> </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><class_name>.PutInROT</h3>
|
||||
</td></tr>
|
||||
|
||||
<tr><td> </td><td valign="top">
|
||||
<h4><class_name>.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> </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> </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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,15 +4,16 @@ 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.
|
||||
@@ -23,43 +24,51 @@ import java.io.InputStream;
|
||||
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.
|
||||
* 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.
|
||||
* 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");
|
||||
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)) {
|
||||
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());
|
||||
// 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)
|
||||
{
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
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();
|
||||
}
|
||||
|
||||
/** default constructor */
|
||||
public MathTest() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
@@ -42,11 +55,26 @@ class MathTest {
|
||||
System.out.println("v.toDispatch=" + v.toDispatch());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 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");
|
||||
}
|
||||
|
||||
@@ -19,23 +19,25 @@
|
||||
*/
|
||||
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
|
||||
{
|
||||
class Access {
|
||||
/**
|
||||
* the main loop for the test
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
public static void main(String[] args) throws Exception {
|
||||
ComThread.InitSTA();
|
||||
// original test used this
|
||||
// ActiveXComponent ax = new ActiveXComponent("DAO.PrivateDBEngine");
|
||||
@@ -44,7 +46,8 @@ class Access
|
||||
// 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
|
||||
// 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
|
||||
@@ -61,12 +64,12 @@ class Access
|
||||
|
||||
/**
|
||||
* Open a database
|
||||
*
|
||||
* @param ax
|
||||
* @param fileName
|
||||
* @return dispatch object that was opened
|
||||
*/
|
||||
public static Dispatch open(ActiveXComponent ax, String fileName)
|
||||
{
|
||||
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 };
|
||||
@@ -76,20 +79,21 @@ class Access
|
||||
|
||||
/**
|
||||
* Close a database
|
||||
* @param openDB db to be closed
|
||||
*
|
||||
* @param openDB
|
||||
* db to be closed
|
||||
*/
|
||||
public static void close(Dispatch openDB)
|
||||
{
|
||||
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)
|
||||
{
|
||||
public static Variant getValues(Dispatch recset) {
|
||||
Dispatch.callSub(recset, "moveFirst");
|
||||
Variant vi = new Variant(4096);
|
||||
Variant v = Dispatch.call(recset, "GetRows", vi);
|
||||
@@ -98,17 +102,16 @@ class Access
|
||||
|
||||
/**
|
||||
* should return ?? for the passed in ??
|
||||
*
|
||||
* @param qd
|
||||
* @return Variant results of query?
|
||||
*/
|
||||
public static Variant getByQueryDef(Dispatch qd)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
System.out.print(cols[i] + " ");
|
||||
}
|
||||
System.out.println("");
|
||||
@@ -118,11 +121,11 @@ class Access
|
||||
|
||||
/**
|
||||
* gets the columns form the rec set
|
||||
*
|
||||
* @param recset
|
||||
* @return list of column names
|
||||
*/
|
||||
public static String[] getColumns(Dispatch recset)
|
||||
{
|
||||
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];
|
||||
@@ -131,8 +134,8 @@ class Access
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
/**
|
||||
* Sets the "ActiveConnection" object
|
||||
*
|
||||
* @param ppvObject
|
||||
* the new connection
|
||||
*/
|
||||
public void setActiveConnection(Connection ppvObject) {
|
||||
Dispatch.put(this, "ActiveConnection", ppvObject);
|
||||
}
|
||||
|
||||
public String getCommandText()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return the results from "CommandText"
|
||||
*/
|
||||
public String getCommandText() {
|
||||
return Dispatch.get(this, "CommandText").toString();
|
||||
}
|
||||
|
||||
public void setCommandText(String pbstr)
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param pbstr
|
||||
* the new "CommandText"
|
||||
*/
|
||||
public void setCommandText(String pbstr) {
|
||||
Dispatch.put(this, "CommandText", pbstr);
|
||||
}
|
||||
|
||||
public int getCommandTimeout()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return the results of "CommandTimeout"
|
||||
*/
|
||||
public int getCommandTimeout() {
|
||||
return Dispatch.get(this, "CommandTimeout").getInt();
|
||||
}
|
||||
|
||||
public void setCommandTimeout(int plTimeout)
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param plTimeout
|
||||
* the new "CommandTimeout"
|
||||
*/
|
||||
public void setCommandTimeout(int plTimeout) {
|
||||
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
|
||||
}
|
||||
|
||||
public boolean getPrepared()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return results from "Prepared"
|
||||
*/
|
||||
public boolean getPrepared() {
|
||||
return Dispatch.get(this, "Prepared").getBoolean();
|
||||
}
|
||||
|
||||
public void setPrepared(boolean 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()
|
||||
{
|
||||
/**
|
||||
* "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 "Parameters"
|
||||
*/
|
||||
public Variant getParameters() {
|
||||
return Dispatch.get(this, "Parameters");
|
||||
}
|
||||
|
||||
public void setCommandType(int plCmdType)
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param plCmdType
|
||||
* new "CommandType"
|
||||
*/
|
||||
public void setCommandType(int plCmdType) {
|
||||
Dispatch.put(this, "CommandType", new Variant(plCmdType));
|
||||
}
|
||||
|
||||
public int getCommandType()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return current "CommandType"
|
||||
*/
|
||||
public int getCommandType() {
|
||||
return Dispatch.get(this, "CommandType").getInt();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return "Name"
|
||||
*/
|
||||
public String getName() {
|
||||
return Dispatch.get(this, "Name").toString();
|
||||
}
|
||||
|
||||
public void setName(String pbstrName)
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param pbstrName
|
||||
* new "Name"
|
||||
*/
|
||||
public void setName(String pbstrName) {
|
||||
Dispatch.put(this, "Name", pbstrName);
|
||||
}
|
||||
|
||||
public int getState()
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return curent "State"
|
||||
*/
|
||||
public int getState() {
|
||||
return Dispatch.get(this, "State").getInt();
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
/**
|
||||
* cancel whatever it is we're doing
|
||||
*/
|
||||
public void Cancel() {
|
||||
Dispatch.call(this, "Cancel");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ package com.jacob.samples.ado;
|
||||
|
||||
// Enum: CommandTypeEnum
|
||||
|
||||
public interface CommandTypeEnum
|
||||
{
|
||||
public interface CommandTypeEnum {
|
||||
public static final int adCmdUnspecified = -1;
|
||||
public static final int adCmdUnknown = 8;
|
||||
public static final int adCmdText = 1;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
public Variant getProperties() {
|
||||
return Dispatch.get(this, "Properties");
|
||||
}
|
||||
|
||||
public String getConnectionString()
|
||||
{
|
||||
public String getConnectionString() {
|
||||
return Dispatch.get(this, "ConnectionString").toString();
|
||||
}
|
||||
|
||||
public void setConnectionString(String pbstr)
|
||||
{
|
||||
public void setConnectionString(String pbstr) {
|
||||
Dispatch.put(this, "ConnectionString", pbstr);
|
||||
}
|
||||
|
||||
public int getCommandTimeout()
|
||||
{
|
||||
public int getCommandTimeout() {
|
||||
return Dispatch.get(this, "CommandTimeout").getInt();
|
||||
}
|
||||
|
||||
public void setCommandTimeout(int plTimeout)
|
||||
{
|
||||
public void setCommandTimeout(int plTimeout) {
|
||||
Dispatch.put(this, "CommandTimeout", new Variant(plTimeout));
|
||||
}
|
||||
|
||||
public int getConnectionTimeout()
|
||||
{
|
||||
public int getConnectionTimeout() {
|
||||
return Dispatch.get(this, "ConnectionTimeout").getInt();
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(int plTimeout)
|
||||
{
|
||||
public void setConnectionTimeout(int plTimeout) {
|
||||
Dispatch.put(this, "ConnectionTimeout", new Variant(plTimeout));
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
public String getVersion() {
|
||||
return Dispatch.get(this, "Version").toString();
|
||||
}
|
||||
|
||||
public void 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));
|
||||
public Variant Execute(String CommandText, Variant RecordsAffected,
|
||||
int Options) {
|
||||
return Dispatch.call(this, CommandText, RecordsAffected, new Variant(
|
||||
Options));
|
||||
}
|
||||
|
||||
public int BeginTrans()
|
||||
{
|
||||
public int BeginTrans() {
|
||||
return Dispatch.call(this, "BeginTrans").getInt();
|
||||
}
|
||||
|
||||
public void CommitTrans()
|
||||
{
|
||||
public void CommitTrans() {
|
||||
Dispatch.call(this, "CommitTrans");
|
||||
}
|
||||
|
||||
public void 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()
|
||||
{
|
||||
public void Open() {
|
||||
Dispatch.call(this, "Open");
|
||||
}
|
||||
|
||||
public Variant getErrors()
|
||||
{
|
||||
public Variant getErrors() {
|
||||
return Dispatch.get(this, "Errors");
|
||||
}
|
||||
|
||||
public String getDefaultDatabase()
|
||||
{
|
||||
public String getDefaultDatabase() {
|
||||
return Dispatch.get(this, "DefaultDatabase").toString();
|
||||
}
|
||||
|
||||
public void setDefaultDatabase(String pbstr)
|
||||
{
|
||||
public void setDefaultDatabase(String pbstr) {
|
||||
Dispatch.put(this, "DefaultDatabase", pbstr);
|
||||
}
|
||||
|
||||
public int getIsolationLevel()
|
||||
{
|
||||
public int getIsolationLevel() {
|
||||
return Dispatch.get(this, "IsolationLevel").getInt();
|
||||
}
|
||||
|
||||
public void setIsolationLevel(int Level)
|
||||
{
|
||||
public void setIsolationLevel(int Level) {
|
||||
Dispatch.put(this, "IsolationLevel", new Variant(Level));
|
||||
}
|
||||
|
||||
public int getAttributes()
|
||||
{
|
||||
public int getAttributes() {
|
||||
return Dispatch.get(this, "Attributes").getInt();
|
||||
}
|
||||
|
||||
public void setAttributes(int plAttr)
|
||||
{
|
||||
public void setAttributes(int plAttr) {
|
||||
Dispatch.put(this, "Attributes", new Variant(plAttr));
|
||||
}
|
||||
|
||||
public int getCursorLocation()
|
||||
{
|
||||
public int getCursorLocation() {
|
||||
return Dispatch.get(this, "CursorLocation").getInt();
|
||||
}
|
||||
|
||||
public void setCursorLocation(int plCursorLoc)
|
||||
{
|
||||
public void setCursorLocation(int plCursorLoc) {
|
||||
Dispatch.put(this, "CursorLocation", new Variant(plCursorLoc));
|
||||
}
|
||||
|
||||
public int getMode()
|
||||
{
|
||||
public int getMode() {
|
||||
return Dispatch.get(this, "Mode").getInt();
|
||||
}
|
||||
|
||||
public void setMode(int plMode)
|
||||
{
|
||||
public void setMode(int plMode) {
|
||||
Dispatch.put(this, "Mode", new Variant(plMode));
|
||||
}
|
||||
|
||||
public String getProvider()
|
||||
{
|
||||
public String getProvider() {
|
||||
return Dispatch.get(this, "Provider").toString();
|
||||
}
|
||||
|
||||
public void setProvider(String pbstr)
|
||||
{
|
||||
public void setProvider(String pbstr) {
|
||||
Dispatch.put(this, "Provider", pbstr);
|
||||
}
|
||||
|
||||
public int getState()
|
||||
{
|
||||
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()
|
||||
{
|
||||
public void Cancel() {
|
||||
Dispatch.call(this, "Cancel");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +1,100 @@
|
||||
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()
|
||||
{
|
||||
public Variant getProperties() {
|
||||
return Dispatch.get(this, "Properties");
|
||||
}
|
||||
|
||||
public int getActualSize()
|
||||
{
|
||||
public int getActualSize() {
|
||||
return Dispatch.get(this, "ActualSize").getInt();
|
||||
}
|
||||
|
||||
public int getAttributes()
|
||||
{
|
||||
public int getAttributes() {
|
||||
return Dispatch.get(this, "Attributes").getInt();
|
||||
}
|
||||
|
||||
public int getDefinedSize()
|
||||
{
|
||||
public int getDefinedSize() {
|
||||
return Dispatch.get(this, "DefinedSize").getInt();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
public String getName() {
|
||||
return Dispatch.get(this, "Name").toString();
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
public int getType() {
|
||||
return Dispatch.get(this, "Type").getInt();
|
||||
}
|
||||
|
||||
public Variant getValue()
|
||||
{
|
||||
public Variant getValue() {
|
||||
return Dispatch.get(this, "Value");
|
||||
}
|
||||
|
||||
public void setValue(Variant pvar)
|
||||
{
|
||||
public void setValue(Variant pvar) {
|
||||
Dispatch.put(this, "Value", pvar);
|
||||
}
|
||||
|
||||
public byte getPrecision()
|
||||
{
|
||||
public byte getPrecision() {
|
||||
return Dispatch.get(this, "Precision").getByte();
|
||||
}
|
||||
|
||||
public byte getNumericScale()
|
||||
{
|
||||
public byte getNumericScale() {
|
||||
return Dispatch.get(this, "NumericScale").getByte();
|
||||
}
|
||||
|
||||
public void AppendChunk(Variant Data)
|
||||
{
|
||||
public void AppendChunk(Variant Data) {
|
||||
Dispatch.call(this, "AppendChunk", Data);
|
||||
}
|
||||
|
||||
public Variant GetChunk(int Length)
|
||||
{
|
||||
public Variant GetChunk(int Length) {
|
||||
return Dispatch.call(this, "GetChunk", new Variant(Length));
|
||||
}
|
||||
|
||||
public Variant getOriginalValue()
|
||||
{
|
||||
public Variant getOriginalValue() {
|
||||
return Dispatch.get(this, "OriginalValue");
|
||||
}
|
||||
|
||||
public Variant getUnderlyingValue()
|
||||
{
|
||||
public Variant getUnderlyingValue() {
|
||||
return Dispatch.get(this, "UnderlyingValue");
|
||||
}
|
||||
|
||||
public Variant getDataFormat()
|
||||
{
|
||||
public Variant getDataFormat() {
|
||||
return Dispatch.get(this, "DataFormat");
|
||||
}
|
||||
|
||||
public void setDataFormat(Variant ppiDF)
|
||||
{
|
||||
public void setDataFormat(Variant ppiDF) {
|
||||
Dispatch.put(this, "DataFormat", ppiDF);
|
||||
}
|
||||
|
||||
public void setPrecision(byte pb)
|
||||
{
|
||||
public void setPrecision(byte pb) {
|
||||
Dispatch.put(this, "Precision", new Variant(pb));
|
||||
}
|
||||
|
||||
public void setNumericScale(byte pb)
|
||||
{
|
||||
public void setNumericScale(byte pb) {
|
||||
Dispatch.put(this, "NumericScale", new Variant(pb));
|
||||
}
|
||||
|
||||
public void setType(int pDataType)
|
||||
{
|
||||
public void setType(int pDataType) {
|
||||
Dispatch.put(this, "Type", new Variant(pDataType));
|
||||
}
|
||||
|
||||
public void setDefinedSize(int pl)
|
||||
{
|
||||
public void setDefinedSize(int pl) {
|
||||
Dispatch.put(this, "DefinedSize", new Variant(pl));
|
||||
}
|
||||
|
||||
public void setAttributes(int pl)
|
||||
{
|
||||
public void setAttributes(int pl) {
|
||||
Dispatch.put(this, "Attributes", new Variant(pl));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +1,42 @@
|
||||
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()
|
||||
{
|
||||
public int getCount() {
|
||||
return Dispatch.get(this, "Count").getInt();
|
||||
}
|
||||
|
||||
public Variant _NewEnum()
|
||||
{
|
||||
public Variant _NewEnum() {
|
||||
return Dispatch.call(this, "_NewEnum");
|
||||
}
|
||||
|
||||
public void 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)
|
||||
{
|
||||
public void Delete(Variant Index) {
|
||||
Dispatch.call(this, "Delete", Index);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,409 +1,342 @@
|
||||
package com.jacob.samples.ado;
|
||||
import com.jacob.com.*;
|
||||
|
||||
public class Recordset extends Dispatch
|
||||
{
|
||||
public 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()
|
||||
{
|
||||
public Variant getProperties() {
|
||||
return Dispatch.get(this, "Properties");
|
||||
}
|
||||
|
||||
public int getAbsolutePosition()
|
||||
{
|
||||
public int getAbsolutePosition() {
|
||||
return Dispatch.get(this, "AbsolutePosition").getInt();
|
||||
}
|
||||
|
||||
public void setAbsolutePosition(int pl)
|
||||
{
|
||||
public void setAbsolutePosition(int pl) {
|
||||
Dispatch.put(this, "AbsolutePosition", new Variant(pl));
|
||||
}
|
||||
|
||||
public Connection getActiveConnection()
|
||||
{
|
||||
return new Connection(Dispatch.get(this, "ActiveConnection").toDispatch());
|
||||
public Connection getActiveConnection() {
|
||||
return new Connection(Dispatch.get(this, "ActiveConnection")
|
||||
.toDispatch());
|
||||
}
|
||||
|
||||
public void setActiveConnection(Connection ppvObject)
|
||||
{
|
||||
public void setActiveConnection(Connection ppvObject) {
|
||||
Dispatch.put(this, "ActiveConnection", ppvObject);
|
||||
}
|
||||
|
||||
public void setActiveConnection(Variant ppvObject)
|
||||
{
|
||||
public void setActiveConnection(Variant ppvObject) {
|
||||
Dispatch.put(this, "ActiveConnection", ppvObject);
|
||||
}
|
||||
|
||||
public boolean getBOF()
|
||||
{
|
||||
public boolean getBOF() {
|
||||
return Dispatch.get(this, "BOF").getBoolean();
|
||||
}
|
||||
|
||||
public Variant getBookmark()
|
||||
{
|
||||
public Variant getBookmark() {
|
||||
return Dispatch.get(this, "Bookmark");
|
||||
}
|
||||
|
||||
public void setBookmark(Variant pvBookmark)
|
||||
{
|
||||
public void setBookmark(Variant pvBookmark) {
|
||||
Dispatch.put(this, "Bookmark", pvBookmark);
|
||||
}
|
||||
|
||||
public int getCacheSize()
|
||||
{
|
||||
public int getCacheSize() {
|
||||
return Dispatch.get(this, "CacheSize").getInt();
|
||||
}
|
||||
|
||||
public void setCacheSize(int pl)
|
||||
{
|
||||
public void setCacheSize(int pl) {
|
||||
Dispatch.put(this, "CacheSize", new Variant(pl));
|
||||
}
|
||||
|
||||
public int getCursorType()
|
||||
{
|
||||
public int getCursorType() {
|
||||
return Dispatch.get(this, "CursorType").getInt();
|
||||
}
|
||||
|
||||
public void setCursorType(int pl)
|
||||
{
|
||||
public void setCursorType(int pl) {
|
||||
Dispatch.put(this, "CursorType", new Variant(pl));
|
||||
}
|
||||
|
||||
public boolean getEOF()
|
||||
{
|
||||
public boolean getEOF() {
|
||||
return Dispatch.get(this, "EOF").getBoolean();
|
||||
}
|
||||
|
||||
public Fields getFields()
|
||||
{
|
||||
public Fields getFields() {
|
||||
return new Fields(Dispatch.get(this, "Fields").toDispatch());
|
||||
}
|
||||
|
||||
public int getLockType()
|
||||
{
|
||||
public int getLockType() {
|
||||
return Dispatch.get(this, "LockType").getInt();
|
||||
}
|
||||
|
||||
public void setLockType(int plLockType)
|
||||
{
|
||||
public void setLockType(int plLockType) {
|
||||
Dispatch.put(this, "LockType", new Variant(plLockType));
|
||||
}
|
||||
|
||||
public int getMaxRecords()
|
||||
{
|
||||
public int getMaxRecords() {
|
||||
return Dispatch.get(this, "MaxRecords").getInt();
|
||||
}
|
||||
|
||||
public void setMaxRecords(int pl)
|
||||
{
|
||||
public void setMaxRecords(int pl) {
|
||||
Dispatch.put(this, "MaxRecords", new Variant(pl));
|
||||
}
|
||||
|
||||
public int getRecordCount()
|
||||
{
|
||||
public int getRecordCount() {
|
||||
return Dispatch.get(this, "RecordCount").getInt();
|
||||
}
|
||||
|
||||
public void setSource(Object pvSource)
|
||||
{
|
||||
public void setSource(Object pvSource) {
|
||||
Dispatch.put(this, "Source", pvSource);
|
||||
}
|
||||
|
||||
public void setSource(String pvSource)
|
||||
{
|
||||
public void setSource(String pvSource) {
|
||||
Dispatch.put(this, "Source", pvSource);
|
||||
}
|
||||
|
||||
public Variant getSource()
|
||||
{
|
||||
public Variant getSource() {
|
||||
return Dispatch.get(this, "Source");
|
||||
}
|
||||
|
||||
public void AddNew(Variant FieldList, Variant Values)
|
||||
{
|
||||
public void AddNew(Variant FieldList, Variant Values) {
|
||||
Dispatch.call(this, "AddNew", FieldList, Values);
|
||||
}
|
||||
|
||||
public void CancelUpdate()
|
||||
{
|
||||
public void CancelUpdate() {
|
||||
Dispatch.call(this, "CancelUpdate");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
public void Close() {
|
||||
Dispatch.call(this, "Close");
|
||||
}
|
||||
|
||||
public void Delete(int AffectRecords)
|
||||
{
|
||||
public void Delete(int AffectRecords) {
|
||||
Dispatch.call(this, "Delete", new Variant(AffectRecords));
|
||||
}
|
||||
|
||||
public Variant GetRows(int Rows, Variant Start, Variant Fields)
|
||||
{
|
||||
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()
|
||||
{
|
||||
public Variant GetRows() {
|
||||
return Dispatch.call(this, "GetRows");
|
||||
}
|
||||
|
||||
public void Move(int NumRecords, Variant Start)
|
||||
{
|
||||
public void Move(int NumRecords, Variant Start) {
|
||||
Dispatch.call(this, "Move", new Variant(NumRecords), Start);
|
||||
}
|
||||
|
||||
public void MoveNext()
|
||||
{
|
||||
public void MoveNext() {
|
||||
Dispatch.call(this, "MoveNext");
|
||||
}
|
||||
|
||||
public void MovePrevious()
|
||||
{
|
||||
public void MovePrevious() {
|
||||
Dispatch.call(this, "MovePrevious");
|
||||
}
|
||||
|
||||
public void MoveFirst()
|
||||
{
|
||||
public void MoveFirst() {
|
||||
Dispatch.call(this, "MoveFirst");
|
||||
}
|
||||
|
||||
public void 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)
|
||||
{
|
||||
public void Open(Variant Source, Variant ActiveConnection) {
|
||||
Dispatch.call(this, "Open", Source, ActiveConnection);
|
||||
}
|
||||
|
||||
public void Requery(int Options)
|
||||
{
|
||||
public void Requery(int Options) {
|
||||
Dispatch.call(this, "Requery", new Variant(Options));
|
||||
}
|
||||
|
||||
public void Update(Variant Fields, Variant Values)
|
||||
{
|
||||
public void Update(Variant Fields, Variant Values) {
|
||||
Dispatch.call(this, "Update", Fields, Values);
|
||||
}
|
||||
|
||||
public int getAbsolutePage()
|
||||
{
|
||||
public int getAbsolutePage() {
|
||||
return Dispatch.get(this, "AbsolutePage").getInt();
|
||||
}
|
||||
|
||||
public void setAbsolutePage(int pl)
|
||||
{
|
||||
public void setAbsolutePage(int pl) {
|
||||
Dispatch.put(this, "AbsolutePage", new Variant(pl));
|
||||
}
|
||||
|
||||
public int getEditMode()
|
||||
{
|
||||
public int getEditMode() {
|
||||
return Dispatch.get(this, "EditMode").getInt();
|
||||
}
|
||||
|
||||
public Variant getFilter()
|
||||
{
|
||||
public Variant getFilter() {
|
||||
return Dispatch.get(this, "Filter");
|
||||
}
|
||||
|
||||
public void setFilter(Variant Criteria)
|
||||
{
|
||||
public void setFilter(Variant Criteria) {
|
||||
Dispatch.put(this, "Filter", Criteria);
|
||||
}
|
||||
|
||||
public int getPageCount()
|
||||
{
|
||||
public int getPageCount() {
|
||||
return Dispatch.get(this, "PageCount").getInt();
|
||||
}
|
||||
|
||||
public int getPageSize()
|
||||
{
|
||||
public int getPageSize() {
|
||||
return Dispatch.get(this, "PageSize").getInt();
|
||||
}
|
||||
|
||||
public void setPageSize(int pl)
|
||||
{
|
||||
public void setPageSize(int pl) {
|
||||
Dispatch.put(this, "PageSize", new Variant(pl));
|
||||
}
|
||||
|
||||
public String getSort()
|
||||
{
|
||||
public String getSort() {
|
||||
return Dispatch.get(this, "Sort").toString();
|
||||
}
|
||||
|
||||
public void setSort(String Criteria)
|
||||
{
|
||||
public void setSort(String Criteria) {
|
||||
Dispatch.put(this, "Sort", Criteria);
|
||||
}
|
||||
|
||||
public int getStatus()
|
||||
{
|
||||
public int getStatus() {
|
||||
return Dispatch.get(this, "Status").getInt();
|
||||
}
|
||||
|
||||
public int getState()
|
||||
{
|
||||
public int getState() {
|
||||
return Dispatch.get(this, "State").getInt();
|
||||
}
|
||||
|
||||
public void UpdateBatch(int AffectRecords)
|
||||
{
|
||||
public void UpdateBatch(int AffectRecords) {
|
||||
Dispatch.call(this, "UpdateBatch", new Variant(AffectRecords));
|
||||
}
|
||||
|
||||
public void CancelBatch(int AffectRecords)
|
||||
{
|
||||
public void CancelBatch(int AffectRecords) {
|
||||
Dispatch.call(this, "CancelBatch", new Variant(AffectRecords));
|
||||
}
|
||||
|
||||
public int getCursorLocation()
|
||||
{
|
||||
public int getCursorLocation() {
|
||||
return Dispatch.get(this, "CursorLocation").getInt();
|
||||
}
|
||||
|
||||
public void setCursorLocation(int 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)
|
||||
{
|
||||
public Variant getCollect(Variant Index) {
|
||||
return Dispatch.get(this, "Collect");
|
||||
}
|
||||
|
||||
public void setCollect(Variant Index, Variant pvar)
|
||||
{
|
||||
public void setCollect(Variant Index, Variant pvar) {
|
||||
Dispatch.call(this, "Collect", Index, pvar);
|
||||
}
|
||||
|
||||
public int getMarshalOptions()
|
||||
{
|
||||
public int getMarshalOptions() {
|
||||
return Dispatch.get(this, "MarshalOptions").getInt();
|
||||
}
|
||||
|
||||
public void setMarshalOptions(int pl)
|
||||
{
|
||||
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 Find(String Criteria, int SkipRecords, int SearchDirection,
|
||||
Variant Start) {
|
||||
Dispatch.call(this, "Find", Criteria, new Variant(SkipRecords),
|
||||
new Variant(SearchDirection), Start);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
public void Cancel() {
|
||||
Dispatch.call(this, "Cancel");
|
||||
}
|
||||
|
||||
public Variant getDataSource()
|
||||
{
|
||||
public Variant getDataSource() {
|
||||
return Dispatch.get(this, "DataSource");
|
||||
}
|
||||
|
||||
public void setDataSource(Variant ppunkDataSource)
|
||||
{
|
||||
public void setDataSource(Variant ppunkDataSource) {
|
||||
Dispatch.put(this, "DataSource", ppunkDataSource);
|
||||
}
|
||||
|
||||
public void Save(String FileName, int PersistFormat)
|
||||
{
|
||||
public void Save(String FileName, int PersistFormat) {
|
||||
Dispatch.call(this, "Save", FileName, new Variant(PersistFormat));
|
||||
}
|
||||
|
||||
public Variant getActiveCommand()
|
||||
{
|
||||
public Variant getActiveCommand() {
|
||||
return Dispatch.get(this, "ActiveCommand");
|
||||
}
|
||||
|
||||
public void setStayInSync(boolean pb)
|
||||
{
|
||||
public void setStayInSync(boolean pb) {
|
||||
Dispatch.put(this, "StayInSync", new Variant(pb));
|
||||
}
|
||||
|
||||
public boolean getStayInSync()
|
||||
{
|
||||
public boolean getStayInSync() {
|
||||
return Dispatch.get(this, "StayInSync").getBoolean();
|
||||
}
|
||||
|
||||
public String GetString(int StringFormat, int NumRows, String ColumnDelimeter, String RowDelimeter, String NullExpr)
|
||||
{
|
||||
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();
|
||||
new Variant(NumRows), ColumnDelimeter, RowDelimeter, NullExpr)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getDataMember()
|
||||
{
|
||||
public String getDataMember() {
|
||||
return Dispatch.get(this, "DataMember").toString();
|
||||
}
|
||||
|
||||
public void setDataMember(String pl)
|
||||
{
|
||||
public void setDataMember(String pl) {
|
||||
Dispatch.put(this, "DataMember", new Variant(pl));
|
||||
}
|
||||
|
||||
public int CompareBookmarks(Variant Bookmark1, Variant Bookmark2)
|
||||
{
|
||||
return Dispatch.call(this, "CompareBookmarks", Bookmark1, Bookmark2).getInt();
|
||||
public int CompareBookmarks(Variant Bookmark1, Variant Bookmark2) {
|
||||
return Dispatch.call(this, "CompareBookmarks", Bookmark1, Bookmark2)
|
||||
.getInt();
|
||||
}
|
||||
|
||||
public Recordset Clone(int LockType)
|
||||
{
|
||||
return new Recordset(Dispatch.call(this, "Clone",
|
||||
new Variant(LockType)).toDispatch());
|
||||
public Recordset Clone(int LockType) {
|
||||
return new Recordset(Dispatch
|
||||
.call(this, "Clone", new Variant(LockType)).toDispatch());
|
||||
}
|
||||
|
||||
public void Resync(int AffectRecords, int ResyncValues)
|
||||
{
|
||||
Dispatch.call(this, "Resync", new Variant(AffectRecords), new Variant(ResyncValues));
|
||||
public void Resync(int AffectRecords, int ResyncValues) {
|
||||
Dispatch.call(this, "Resync", new Variant(AffectRecords), new Variant(
|
||||
ResyncValues));
|
||||
}
|
||||
|
||||
public void Seek(Variant KeyValues, int SeekOption)
|
||||
{
|
||||
public void Seek(Variant KeyValues, int SeekOption) {
|
||||
Dispatch.call(this, "Seek", KeyValues, new Variant(SeekOption));
|
||||
}
|
||||
|
||||
public void setIndex(String pl)
|
||||
{
|
||||
public void setIndex(String pl) {
|
||||
Dispatch.put(this, "Index", new Variant(pl));
|
||||
}
|
||||
|
||||
public String getIndex()
|
||||
{
|
||||
public String getIndex() {
|
||||
return Dispatch.get(this, "Index)").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
package com.jacob.samples.ado;
|
||||
import com.jacob.com.*;
|
||||
|
||||
public class test
|
||||
{
|
||||
public static void printRS(Recordset rs)
|
||||
{
|
||||
import com.jacob.com.Variant;
|
||||
|
||||
public class test {
|
||||
public static void printRS(Recordset rs) {
|
||||
Fields fs = rs.getFields();
|
||||
|
||||
for (int i=0;i<fs.getCount();i++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
while (!rs.getEOF()) {
|
||||
for (int i = 0; i < fs.getCount(); i++) {
|
||||
Field f = fs.getItem(i);
|
||||
Variant v = f.getValue();
|
||||
System.out.print(v + " ");
|
||||
@@ -28,8 +24,7 @@ public class test
|
||||
}
|
||||
|
||||
// open a recordset directly
|
||||
public static void getRS(String con, String query)
|
||||
{
|
||||
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));
|
||||
@@ -38,8 +33,7 @@ public class test
|
||||
|
||||
// create connection and command objects and use them
|
||||
// to get a recordset
|
||||
public static void getCommand(String con, String query)
|
||||
{
|
||||
public static void getCommand(String con, String query) {
|
||||
System.out.println("Command+Connection -> Recordset");
|
||||
Connection c = new Connection();
|
||||
c.setConnectionString(con);
|
||||
@@ -53,8 +47,7 @@ public class test
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
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
|
||||
// whoever wrote this example should explain what this was intended to
|
||||
// do
|
||||
// System.runFinalizersOnExit(true);
|
||||
|
||||
ActiveXComponent mf = new ActiveXComponent("MultiFace.Face");
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
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)
|
||||
{
|
||||
/**
|
||||
* 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");
|
||||
@@ -24,11 +32,9 @@ public class ExcelDispatchTest {
|
||||
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();
|
||||
new Object[] { "A1" }, new int[1]).toDispatch();
|
||||
Dispatch a2 = Dispatch.invoke(sheet, "Range", Dispatch.Get,
|
||||
new Object[] {"A2"},
|
||||
new int[1]).toDispatch();
|
||||
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"));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -22,7 +22,8 @@ public class WordDocumentProperties {
|
||||
|
||||
private Dispatch builtInDocProps;
|
||||
|
||||
//the doucments object is important in any real app but this demo doesn't use it
|
||||
// the doucments object is important in any real app but this demo doesn't
|
||||
// use it
|
||||
// private Dispatch documents;
|
||||
|
||||
private Dispatch document;
|
||||
@@ -49,7 +50,7 @@ public class WordDocumentProperties {
|
||||
wordObject = objWord.getObject();
|
||||
|
||||
// Create a Dispatch Parameter to hide the document that is opened
|
||||
Dispatch.put((Dispatch) wordObject, "Visible", new Variant(false));
|
||||
Dispatch.put(wordObject, "Visible", new Variant(false));
|
||||
|
||||
// Instantiate the Documents Property
|
||||
Dispatch documents = objWord.getProperty("Documents").toDispatch();
|
||||
@@ -97,8 +98,8 @@ public class WordDocumentProperties {
|
||||
*/
|
||||
public String getCustomProperty(String cusPropName) {
|
||||
try {
|
||||
cusPropName = Dispatch.call((Dispatch) custDocprops, "Item",
|
||||
cusPropName).toString();
|
||||
cusPropName = Dispatch.call(custDocprops, "Item", cusPropName)
|
||||
.toString();
|
||||
} catch (ComException e) {
|
||||
// Do nothing
|
||||
cusPropName = null;
|
||||
@@ -115,7 +116,7 @@ public class WordDocumentProperties {
|
||||
*/
|
||||
public String getBuiltInProperty(String builtInPropName) {
|
||||
try {
|
||||
builtInPropName = Dispatch.call((Dispatch) builtInDocProps, "Item",
|
||||
builtInPropName = Dispatch.call(builtInDocProps, "Item",
|
||||
builtInPropName).toString();
|
||||
} catch (ComException e) {
|
||||
// Do nothing
|
||||
@@ -127,6 +128,7 @@ public class WordDocumentProperties {
|
||||
|
||||
/**
|
||||
* simple main program that gets some properties and prints them out
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -5,10 +5,13 @@ 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) {
|
||||
@@ -21,13 +24,16 @@ public class Outlook {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static void recurseFolders(int iIndent, Dispatch o) {
|
||||
|
||||
if (o == null) return;
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
Dispatch oFolders = Dispatch.get(o, "Folders").toDispatch();
|
||||
// System.out.println("oFolders=" + oFolders);
|
||||
if (oFolders == null) return;
|
||||
if (oFolders == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatch oFolder = Dispatch.get(oFolders, "GetFirst").toDispatch();
|
||||
do {
|
||||
@@ -44,7 +50,13 @@ public class Outlook {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* standard run loop
|
||||
*
|
||||
* @param asArgs
|
||||
* command line arguments
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String asArgs[]) throws Exception {
|
||||
System.out.println("Outlook: IN");
|
||||
|
||||
@@ -66,4 +78,3 @@ public class Outlook {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@ 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
|
||||
*
|
||||
@@ -20,7 +22,8 @@ import com.jacob.com.Variant;
|
||||
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;
|
||||
@@ -30,6 +33,9 @@ public class DiskUtils {
|
||||
|
||||
/**
|
||||
* Standard constructor
|
||||
*
|
||||
* @param drive
|
||||
* the drive to run the test against.
|
||||
*/
|
||||
public DiskUtils(String drive) {
|
||||
setUp(drive);
|
||||
@@ -37,12 +43,14 @@ public class DiskUtils {
|
||||
|
||||
/**
|
||||
* 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");
|
||||
fileSystemApp = new ActiveXComponent("Scripting.FileSystemObject");
|
||||
myDrive = Dispatch.call(fileSystemApp, "GetDrive", drive)
|
||||
.toDispatch();
|
||||
}
|
||||
@@ -57,6 +65,7 @@ public class DiskUtils {
|
||||
|
||||
/**
|
||||
* convenience method
|
||||
*
|
||||
* @return driver serial number
|
||||
*/
|
||||
public int getSerialNumber() {
|
||||
@@ -64,10 +73,11 @@ public class DiskUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@@ -82,9 +92,10 @@ public class DiskUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@@ -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("C");
|
||||
System.out.println("Disk serial number is: "+ utilConnection.getSerialNumber());
|
||||
System.out.println("FileSystem is: "+ utilConnection.getFileSystemType());
|
||||
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 total size is: "
|
||||
+ utilConnection.getTotalSize());
|
||||
System.out.println("Disk free space is: "
|
||||
+ utilConnection.getFreeSpace());
|
||||
utilConnection.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,17 @@ import com.jacob.com.Variant;
|
||||
*/
|
||||
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.
|
||||
@@ -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();
|
||||
|
||||
@@ -1,38 +1,54 @@
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a DispatchEvents boject to register o as a listener
|
||||
* 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");
|
||||
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());
|
||||
ActiveXComponent documents = new ActiveXComponent(getProperty(
|
||||
"Documents").toDispatch());
|
||||
Variant[] args = new Variant[1];
|
||||
args[0] = new Variant(f.getPath());
|
||||
documents.invoke("Open", args);
|
||||
@@ -42,9 +58,15 @@ public class VisioApp extends ActiveXComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tells Visio to save the drawing
|
||||
*
|
||||
* @throws VisioException
|
||||
*/
|
||||
public void save() throws VisioException {
|
||||
try {
|
||||
ActiveXComponent document = new ActiveXComponent(getProperty("ActiveDocument").toDispatch());
|
||||
ActiveXComponent document = new ActiveXComponent(getProperty(
|
||||
"ActiveDocument").toDispatch());
|
||||
document.invoke("Save");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -53,20 +75,28 @@ public class VisioApp extends ActiveXComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* terminates visio
|
||||
* 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());
|
||||
ActiveXComponent document = new ActiveXComponent(getProperty(
|
||||
"ActiveDocument").toDispatch());
|
||||
document.invoke("Close");
|
||||
invoke("Quit");
|
||||
}
|
||||
|
||||
/**
|
||||
* runs the Visio export command
|
||||
*
|
||||
* @param f
|
||||
* @throws VisioException
|
||||
*/
|
||||
public void export(File f) throws VisioException {
|
||||
try {
|
||||
ActiveXComponent document = new ActiveXComponent(getProperty("ActivePage").toDispatch());
|
||||
ActiveXComponent document = new ActiveXComponent(getProperty(
|
||||
"ActivePage").toDispatch());
|
||||
Variant[] args = new Variant[1];
|
||||
args[0] = new Variant(f.getPath());
|
||||
document.invoke("Export", args);
|
||||
@@ -75,6 +105,12 @@ public class VisioApp extends ActiveXComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
||||
@@ -1,32 +1,51 @@
|
||||
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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/**
|
||||
* Wrapper around Visio
|
||||
*
|
||||
* @throws VisioException
|
||||
*/
|
||||
private VisioAppFacade() throws VisioException {
|
||||
this.app = new VisioApp();
|
||||
app.addEventListener(new VisioEventAdapter(app));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton instance of Visio
|
||||
* @throws VisioException
|
||||
*/
|
||||
public static VisioAppFacade getInstance() throws VisioException {
|
||||
if (instance == null) {
|
||||
instance = new VisioAppFacade();
|
||||
@@ -34,6 +53,13 @@ public class VisioAppFacade {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -50,6 +76,13 @@ public class VisioAppFacade {
|
||||
return preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -79,6 +112,13 @@ public class VisioAppFacade {
|
||||
} while (read > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
@@ -100,19 +140,39 @@ public class VisioAppFacade {
|
||||
return preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a temporary viso file
|
||||
*
|
||||
* @return created visio temporary file
|
||||
* @throws IOException
|
||||
*/
|
||||
private File getTempVisioFile() throws IOException {
|
||||
return File.createTempFile("java", VISIO_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);
|
||||
}
|
||||
|
||||
/** exit visio */
|
||||
public void quit() {
|
||||
app.quit();
|
||||
instance = null;
|
||||
|
||||
@@ -1,20 +1,34 @@
|
||||
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.
|
||||
* Look in the docs area at the Jacob usage document for command line
|
||||
* options.
|
||||
*/
|
||||
public class VisioDemo extends JFrame implements ActionListener, WindowListener {
|
||||
|
||||
@@ -37,7 +51,6 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
// 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()) {
|
||||
@@ -104,7 +117,9 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
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
|
||||
.setCurrentDirectory(new File(System
|
||||
.getProperty("user.dir")));
|
||||
chooser.setFileFilter(new VisioFileFilter());
|
||||
int returnVal = chooser.showOpenDialog(this);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
@@ -117,8 +132,10 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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() {
|
||||
@@ -132,6 +149,7 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
}
|
||||
return visioProxy;
|
||||
}
|
||||
|
||||
private void showSelectedFilePreview() throws VisioException {
|
||||
if (selectedFile != null) {
|
||||
byte[] image = getVisio().createPreview(selectedFile);
|
||||
@@ -160,6 +178,7 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
visioProxy.quit();
|
||||
}
|
||||
}
|
||||
|
||||
public void windowClosing(WindowEvent e) {
|
||||
}
|
||||
|
||||
@@ -172,6 +191,7 @@ public class VisioDemo extends JFrame implements ActionListener, WindowListener
|
||||
public void windowIconified(WindowEvent e) {
|
||||
System.out.println("Fooboo");
|
||||
}
|
||||
|
||||
public void windowOpened(WindowEvent e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
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 {
|
||||
|
||||
@@ -16,23 +20,28 @@ public class VisioEventAdapter implements VisioEventListener {
|
||||
System.out.println("Event listener constructed");
|
||||
}
|
||||
|
||||
public void BeforeQuit(Variant[] args){ }
|
||||
public void BeforeQuit(Variant[] args) {
|
||||
}
|
||||
|
||||
public void DocumentChanged(Variant[] args) {
|
||||
System.out.println("documentChanged()");
|
||||
}
|
||||
|
||||
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) {
|
||||
System.out.println("DocumentOpened()");
|
||||
}
|
||||
|
||||
public void DocumentSaved(Variant[] args){ }
|
||||
public void DocumentSaved(Variant[] args) {
|
||||
}
|
||||
|
||||
public void DocumentSavedAs(Variant[] args){ }
|
||||
public void DocumentSavedAs(Variant[] args) {
|
||||
}
|
||||
|
||||
public Variant QueryCancelDocumentClose(Variant[] args) {
|
||||
System.out.println("QueryCancelDocumentClose()");
|
||||
@@ -40,12 +49,13 @@ public class VisioEventAdapter implements VisioEventListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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");
|
||||
System.out
|
||||
.println("Saving document, hiding and telling visio not to quit");
|
||||
try {
|
||||
app.save();
|
||||
app.setVisible(false);
|
||||
@@ -56,4 +66,3 @@ public class VisioEventAdapter implements VisioEventListener {
|
||||
return new Variant(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
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 {
|
||||
|
||||
@@ -30,4 +31,3 @@ public interface VisioEventListener {
|
||||
|
||||
public Variant QueryCancelQuit(Variant[] args);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
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 {
|
||||
/**
|
||||
|
||||
@@ -19,35 +19,39 @@
|
||||
*/
|
||||
package com.jacob.activeX;
|
||||
|
||||
import com.jacob.com.*;
|
||||
import com.jacob.com.Dispatch;
|
||||
import com.jacob.com.JacobObject;
|
||||
import com.jacob.com.Variant;
|
||||
|
||||
/**
|
||||
* This class provides a higher level, more object like, wrapper for
|
||||
* top of the Dispatch object. The Dispatch class's method essentially
|
||||
* directly map to Microsoft C API including the first parameter that is
|
||||
* almost always the target of the message.
|
||||
* ActiveXComponent assumes the target of every message is the MS
|
||||
* COM object behind the ActiveXComponent. This removes the need
|
||||
* to pass the Dispatch object into every method.
|
||||
* This class provides a higher level, more object like, wrapper for top of the
|
||||
* Dispatch object. The Dispatch class's method essentially directly map to
|
||||
* Microsoft C API including the first parameter that is almost always the
|
||||
* target of the message. ActiveXComponent assumes the target of every message
|
||||
* is the MS COM object behind the ActiveXComponent. This removes the need to
|
||||
* pass the Dispatch object into every method.
|
||||
* <p>
|
||||
* It is really up to the developer as to whether they want to
|
||||
* use the Dispatch interface or the ActiveXComponent interface.
|
||||
* It is really up to the developer as to whether they want to use the Dispatch
|
||||
* interface or the ActiveXComponent interface.
|
||||
* <p>
|
||||
* This class simulates com.ms.activeX.ActiveXComponent only in
|
||||
* the senese that it is used for creating Dispatch objects
|
||||
* This class simulates com.ms.activeX.ActiveXComponent only in the sense that
|
||||
* it is used for creating Dispatch objects
|
||||
*/
|
||||
public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* Normally used to create a new connection to a microsoft application.
|
||||
* The passed in parameter is the name of the program as registred
|
||||
* in the registry. It can also be the object name.
|
||||
* Normally used to create a new connection to a microsoft application. The
|
||||
* passed in parameter is the name of the program as registered in the
|
||||
* registry. It can also be the object name.
|
||||
* <p>
|
||||
* This constructor causes a new Windows object of the requested
|
||||
* type to be created. The windows CoCreate() function gets called
|
||||
* to create the underlying windows object.
|
||||
* This constructor causes a new Windows object of the requested type to be
|
||||
* created. The windows CoCreate() function gets called to create the
|
||||
* underlying windows object.
|
||||
*
|
||||
* <pre>
|
||||
* new ActiveXComponent("ScriptControl");
|
||||
* </pre>
|
||||
*
|
||||
* <pre>new ActiveXComponent("ScriptControl");</pre>
|
||||
* @param programId
|
||||
*/
|
||||
public ActiveXComponent(String programId) {
|
||||
@@ -55,9 +59,9 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an active X component that is built on top of the
|
||||
* COM pointers held in the passed in dispatch.
|
||||
* This widends the Dispatch object to pick up the ActiveXComponent API
|
||||
* Creates an active X component that is built on top of the COM pointers
|
||||
* held in the passed in dispatch. This widens the Dispatch object to pick
|
||||
* up the ActiveXComponent API
|
||||
*
|
||||
* @param dispatchToBeWrapped
|
||||
*/
|
||||
@@ -74,8 +78,9 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Probably was a cover for something else in the past.
|
||||
* Should be deprecated.
|
||||
* Probably was a cover for something else in the past. Should be
|
||||
* deprecated.
|
||||
*
|
||||
* @return Now it actually returns this exact same object.
|
||||
*/
|
||||
public Dispatch getObject() {
|
||||
@@ -83,14 +88,13 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Most code should use the standard ActiveXComponent(String) contructor
|
||||
* and not this factory method. This method exists for applications
|
||||
* that need special behavior.
|
||||
* <B>Experimental in release 1.9.2.</B>
|
||||
* Most code should use the standard ActiveXComponent(String) contructor and
|
||||
* not this factory method. This method exists for applications that need
|
||||
* special behavior. <B>Experimental in release 1.9.2.</B>
|
||||
* <p>
|
||||
* Factory that returns a Dispatch object wrapped around the result
|
||||
* of a CoCreate() call. This differs from the standard constructor
|
||||
* in that it throws no exceptions and returns null on failure.
|
||||
* Factory that returns a Dispatch object wrapped around the result of a
|
||||
* CoCreate() call. This differs from the standard constructor in that it
|
||||
* throws no exceptions and returns null on failure.
|
||||
* <p>
|
||||
* This will fail for any prog id with a ":" in it.
|
||||
*
|
||||
@@ -105,28 +109,30 @@ public class ActiveXComponent extends Dispatch {
|
||||
} catch (Exception e) {
|
||||
mCreatedDispatch = null;
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("Unable to co-create instance of "+pRequestedProgramId);
|
||||
JacobObject.debug("Unable to co-create instance of "
|
||||
+ pRequestedProgramId);
|
||||
}
|
||||
}
|
||||
return mCreatedDispatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Most code should use the standard ActiveXComponent(String) contructor
|
||||
* and not this factory method. This method exists for applications
|
||||
* that need special behavior.
|
||||
* <B>Experimental in release 1.9.2.</B>
|
||||
* Most code should use the standard ActiveXComponent(String) constructor and
|
||||
* not this factory method. This method exists for applications that need
|
||||
* special behavior. <B>Experimental in release 1.9.2.</B>
|
||||
* <p>
|
||||
* Factory that returns a Dispatch wrapped around the result
|
||||
* of a getActiveObject() call. This differs from the standard constructor
|
||||
* in that it throws no exceptions and returns null on failure.
|
||||
* Factory that returns a Dispatch wrapped around the result of a
|
||||
* getActiveObject() call. This differs from the standard constructor in
|
||||
* that it throws no exceptions and returns null on failure.
|
||||
* <p>
|
||||
* This will fail for any prog id with a ":" in it
|
||||
*
|
||||
* @param pRequestedProgramId
|
||||
* @return Dispatch pointer to a COM object or null if wasn't already running
|
||||
* @return Dispatch pointer to a COM object or null if wasn't already
|
||||
* running
|
||||
*/
|
||||
public static ActiveXComponent connectToActiveInstance(String pRequestedProgramId){
|
||||
public static ActiveXComponent connectToActiveInstance(
|
||||
String pRequestedProgramId) {
|
||||
ActiveXComponent mCreatedDispatch = null;
|
||||
try {
|
||||
mCreatedDispatch = new ActiveXComponent();
|
||||
@@ -134,7 +140,8 @@ public class ActiveXComponent extends Dispatch {
|
||||
} catch (Exception e) {
|
||||
mCreatedDispatch = null;
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("Unable to attach to running instance of "+pRequestedProgramId);
|
||||
JacobObject.debug("Unable to attach to running instance of "
|
||||
+ pRequestedProgramId);
|
||||
}
|
||||
}
|
||||
return mCreatedDispatch;
|
||||
@@ -147,8 +154,8 @@ public class ActiveXComponent extends Dispatch {
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
|
||||
/*============================================================
|
||||
/*
|
||||
* ============================================================
|
||||
*
|
||||
* start of instance based calls to the COM layer
|
||||
* ===========================================================
|
||||
@@ -156,27 +163,31 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as a Variant
|
||||
*
|
||||
* @param propertyName
|
||||
* @return variant value of property
|
||||
*/
|
||||
public Variant getProperty(String propertyName)
|
||||
{
|
||||
public Variant getProperty(String propertyName) {
|
||||
return Dispatch.get(this, propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as an ActiveX component
|
||||
*
|
||||
* @param propertyName
|
||||
* @return Dispatch representing the object under the property name
|
||||
*/
|
||||
public ActiveXComponent getPropertyAsComponent(String propertyName) {
|
||||
return new ActiveXComponent(Dispatch.get(this,propertyName).toDispatch());
|
||||
return new ActiveXComponent(Dispatch.get(this, propertyName)
|
||||
.toDispatch());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as a Boolean
|
||||
* @param propertyName property we are looking up
|
||||
*
|
||||
* @param propertyName
|
||||
* property we are looking up
|
||||
* @return boolean value of property
|
||||
*/
|
||||
public boolean getPropertyAsBoolean(String propertyName) {
|
||||
@@ -185,7 +196,9 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as a byte
|
||||
* @param propertyName property we are looking up
|
||||
*
|
||||
* @param propertyName
|
||||
* property we are looking up
|
||||
* @return byte value of property
|
||||
*/
|
||||
public byte getPropertyAsByte(String propertyName) {
|
||||
@@ -194,6 +207,7 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as a String
|
||||
*
|
||||
* @param propertyName
|
||||
* @return String value of property
|
||||
*/
|
||||
@@ -204,6 +218,7 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* retrieves a property and returns it as a int
|
||||
*
|
||||
* @param propertyName
|
||||
* @return the property value as an int
|
||||
*/
|
||||
@@ -213,27 +228,31 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* sets a property on this object
|
||||
* @param propertyName property name
|
||||
* @param arg variant value to be set
|
||||
*
|
||||
* @param propertyName
|
||||
* property name
|
||||
* @param arg
|
||||
* variant value to be set
|
||||
*/
|
||||
public void setProperty(String propertyName, Variant arg)
|
||||
{
|
||||
public void setProperty(String propertyName, Variant arg) {
|
||||
Dispatch.put(this, propertyName, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets a property on this object
|
||||
* @param propertyName property name
|
||||
* @param arg variant value to be set
|
||||
*
|
||||
* @param propertyName
|
||||
* property name
|
||||
* @param arg
|
||||
* variant value to be set
|
||||
*/
|
||||
public void setProperty(String propertyName, Dispatch arg)
|
||||
{
|
||||
public void setProperty(String propertyName, Dispatch arg) {
|
||||
Dispatch.put(this, propertyName, arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sets a property to be the value of the string
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propertyValue
|
||||
*/
|
||||
@@ -243,8 +262,10 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* sets a property as a boolean value
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propValue the boolean value we want the prop set to
|
||||
* @param propValue
|
||||
* the boolean value we want the prop set to
|
||||
*/
|
||||
public void setProperty(String propertyName, boolean propValue) {
|
||||
this.setProperty(propertyName, new Variant(propValue));
|
||||
@@ -252,8 +273,10 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* sets a property as a boolean value
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propValue the boolean value we want the prop set to
|
||||
* @param propValue
|
||||
* the boolean value we want the prop set to
|
||||
*/
|
||||
public void setProperty(String propertyName, byte propValue) {
|
||||
this.setProperty(propertyName, new Variant(propValue));
|
||||
@@ -261,8 +284,10 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* sets the property as an int value
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propValue the int value we want the prop to be set to.
|
||||
* @param propValue
|
||||
* the int value we want the prop to be set to.
|
||||
*/
|
||||
public void setProperty(String propertyName, int propValue) {
|
||||
this.setProperty(propertyName, new Variant(propValue));
|
||||
@@ -280,8 +305,11 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* used by the doc and application listeners to get intelligent logging
|
||||
* @param description event description
|
||||
* @param args args passed in (variants)
|
||||
*
|
||||
* @param description
|
||||
* event description
|
||||
* @param args
|
||||
* args passed in (variants)
|
||||
*
|
||||
*/
|
||||
public void logCallbackEvent(String description, Variant[] args) {
|
||||
@@ -296,32 +324,29 @@ public class ActiveXComponent extends Dispatch {
|
||||
// break out the byref bits if they are on this
|
||||
if ((argType & Variant.VariantByref) == Variant.VariantByref) {
|
||||
// show the type and the fact that its byref
|
||||
argString += "("+(args[i].getvt() & ~Variant.VariantByref)+
|
||||
"/"+Variant.VariantByref+")";
|
||||
argString += "("
|
||||
+ (args[i].getvt() & ~Variant.VariantByref) + "/"
|
||||
+ Variant.VariantByref + ")";
|
||||
} else {
|
||||
// show the type
|
||||
argString += "(" + argType + ")";
|
||||
}
|
||||
argString += "=";
|
||||
if (argType == Variant.VariantDispatch) {
|
||||
Dispatch foo = (Dispatch)args[i].getDispatch();
|
||||
Dispatch foo = (args[i].getDispatch());
|
||||
argString += foo;
|
||||
} else if ((argType & Variant.VariantBoolean) ==
|
||||
Variant.VariantBoolean){
|
||||
} else if ((argType & Variant.VariantBoolean) == Variant.VariantBoolean) {
|
||||
// do the boolean thing
|
||||
if ((argType & Variant.VariantByref) ==
|
||||
Variant.VariantByref){
|
||||
if ((argType & Variant.VariantByref) == Variant.VariantByref) {
|
||||
// boolean by ref
|
||||
argString += args[i].getBooleanRef();
|
||||
} else {
|
||||
// boolean by value
|
||||
argString += args[i].getBoolean();
|
||||
}
|
||||
} else if ((argType & Variant.VariantString) ==
|
||||
Variant.VariantString){
|
||||
} else if ((argType & Variant.VariantString) == Variant.VariantString) {
|
||||
// do the string thing
|
||||
if ((argType & Variant.VariantByref) ==
|
||||
Variant.VariantByref){
|
||||
if ((argType & Variant.VariantByref) == Variant.VariantByref) {
|
||||
// string by ref
|
||||
argString += args[i].getStringRef();
|
||||
} else {
|
||||
@@ -336,13 +361,16 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* covers for dispatch call methods
|
||||
*=============================================================*/
|
||||
* =============================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and no parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @return ActiveXComponent representing the results of the call
|
||||
*/
|
||||
@@ -352,6 +380,7 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and single parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter
|
||||
* @return ActiveXComponent representing the results of the call
|
||||
@@ -363,6 +392,7 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and single parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
@@ -370,12 +400,13 @@ public class ActiveXComponent extends Dispatch {
|
||||
*/
|
||||
public ActiveXComponent invokeGetComponent(String callAction,
|
||||
Variant parameter1, Variant parameter2) {
|
||||
return new ActiveXComponent(invoke(callAction,
|
||||
parameter1, parameter2).toDispatch());
|
||||
return new ActiveXComponent(invoke(callAction, parameter1, parameter2)
|
||||
.toDispatch());
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and single parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
@@ -383,15 +414,14 @@ public class ActiveXComponent extends Dispatch {
|
||||
* @return ActiveXComponent representing the results of the call
|
||||
*/
|
||||
public ActiveXComponent invokeGetComponent(String callAction,
|
||||
Variant parameter1,
|
||||
Variant parameter2,
|
||||
Variant parameter3){
|
||||
return new ActiveXComponent(invoke(callAction,
|
||||
parameter1, parameter2, parameter3).toDispatch());
|
||||
Variant parameter1, Variant parameter2, Variant parameter3) {
|
||||
return new ActiveXComponent(invoke(callAction, parameter1, parameter2,
|
||||
parameter3).toDispatch());
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and single parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
@@ -400,18 +430,15 @@ public class ActiveXComponent extends Dispatch {
|
||||
* @return ActiveXComponent representing the results of the call
|
||||
*/
|
||||
public ActiveXComponent invokeGetComponent(String callAction,
|
||||
Variant parameter1,
|
||||
Variant parameter2,
|
||||
Variant parameter3,
|
||||
Variant parameter1, Variant parameter2, Variant parameter3,
|
||||
Variant parameter4) {
|
||||
return new ActiveXComponent(invoke(callAction,
|
||||
parameter1, parameter2, parameter3, parameter4)
|
||||
.toDispatch());
|
||||
return new ActiveXComponent(invoke(callAction, parameter1, parameter2,
|
||||
parameter3, parameter4).toDispatch());
|
||||
}
|
||||
|
||||
/**
|
||||
* invokes a single parameter call on this dispatch
|
||||
* that returns no value
|
||||
* invokes a single parameter call on this dispatch that returns no value
|
||||
*
|
||||
* @param actionCommand
|
||||
* @param parameter
|
||||
* @return a Variant but that may be null for some calls
|
||||
@@ -421,7 +448,9 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call to the passed in action with a single boolean parameter
|
||||
* makes a dispatch call to the passed in action with a single boolean
|
||||
* parameter
|
||||
*
|
||||
* @param actionCommand
|
||||
* @param parameter
|
||||
* @return Variant result
|
||||
@@ -432,6 +461,7 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* makes a dispatch call to the passed in action with a single int parameter
|
||||
*
|
||||
* @param actionCommand
|
||||
* @param parameter
|
||||
* @return Variant result of the invoke (Dispatch.call)
|
||||
@@ -441,33 +471,37 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call to the passed in action with a string and integer parameter
|
||||
* (this was put in for some application)
|
||||
* makes a dispatch call to the passed in action with a string and integer
|
||||
* parameter (this was put in for some application)
|
||||
*
|
||||
* @param actionCommand
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
* @return Variant result
|
||||
*/
|
||||
public Variant invoke(String actionCommand, String parameter1, int parameter2){
|
||||
return Dispatch.call(this, actionCommand, parameter1, new Variant(parameter2));
|
||||
public Variant invoke(String actionCommand, String parameter1,
|
||||
int parameter2) {
|
||||
return Dispatch.call(this, actionCommand, parameter1, new Variant(
|
||||
parameter2));
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call to the passed in action with two
|
||||
* integer parameters
|
||||
* makes a dispatch call to the passed in action with two integer parameters
|
||||
* (this was put in for some application)
|
||||
*
|
||||
* @param actionCommand
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
* @return a Variant but that may be null for some calls
|
||||
*/
|
||||
public Variant invoke(String actionCommand,
|
||||
int parameter1, int parameter2){
|
||||
return Dispatch.call(this, actionCommand,
|
||||
new Variant(parameter1),new Variant(parameter2));
|
||||
public Variant invoke(String actionCommand, int parameter1, int parameter2) {
|
||||
return Dispatch.call(this, actionCommand, new Variant(parameter1),
|
||||
new Variant(parameter2));
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and single parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter
|
||||
* @return a Variant but that may be null for some calls
|
||||
@@ -478,36 +512,35 @@ public class ActiveXComponent extends Dispatch {
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and two parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
* @return a Variant but that may be null for some calls
|
||||
*/
|
||||
public Variant invoke(String callAction,
|
||||
Variant parameter1,
|
||||
public Variant invoke(String callAction, Variant parameter1,
|
||||
Variant parameter2) {
|
||||
return Dispatch.call(this, callAction, parameter1, parameter2);
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and two parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
* @param parameter3
|
||||
* @return Variant result data
|
||||
*/
|
||||
public Variant invoke(String callAction,
|
||||
Variant parameter1,
|
||||
Variant parameter2,
|
||||
Variant parameter3){
|
||||
return Dispatch.call(this,callAction,
|
||||
parameter1, parameter2, parameter3);
|
||||
public Variant invoke(String callAction, Variant parameter1,
|
||||
Variant parameter2, Variant parameter3) {
|
||||
return Dispatch.call(this, callAction, parameter1, parameter2,
|
||||
parameter3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calls call() with 4 variant parameters
|
||||
*
|
||||
* @param callAction
|
||||
* @param parameter1
|
||||
* @param parameter2
|
||||
@@ -515,18 +548,15 @@ public class ActiveXComponent extends Dispatch {
|
||||
* @param parameter4
|
||||
* @return Variant result data
|
||||
*/
|
||||
public Variant invoke(String callAction,
|
||||
Variant parameter1,
|
||||
Variant parameter2,
|
||||
Variant parameter3,
|
||||
Variant parameter4){
|
||||
return Dispatch.call(this,callAction,
|
||||
parameter1, parameter2, parameter3, parameter4);
|
||||
public Variant invoke(String callAction, Variant parameter1,
|
||||
Variant parameter2, Variant parameter3, Variant parameter4) {
|
||||
return Dispatch.call(this, callAction, parameter1, parameter2,
|
||||
parameter3, parameter4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* makes a dispatch call for the passed in action and no parameter
|
||||
*
|
||||
* @param callAction
|
||||
* @return a Variant but that may be null for some calls
|
||||
*/
|
||||
@@ -535,16 +565,15 @@ public class ActiveXComponent extends Dispatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is really a cover for call(String,Variant[]) that should be eliminated
|
||||
* call with a variable number of args mainly used for quit.
|
||||
* This is really a cover for call(String,Variant[]) that should be
|
||||
* eliminated call with a variable number of args mainly used for quit.
|
||||
*
|
||||
* @param name
|
||||
* @param args
|
||||
* @return Variant returned by the invoke (Dispatch.callN)
|
||||
*/
|
||||
public Variant invoke(String name, Variant[] args)
|
||||
{
|
||||
public Variant invoke(String name, Variant[] args) {
|
||||
return Dispatch.callN(this, name, args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -26,10 +26,10 @@ 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -38,11 +38,14 @@ 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
|
||||
* 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);
|
||||
@@ -51,39 +54,47 @@ public class ActiveXDispatchEvents extends DispatchEvents {
|
||||
/**
|
||||
* 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 ???
|
||||
* 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) {
|
||||
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.
|
||||
* 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 =
|
||||
* >ActiveXDispatchEvents de =
|
||||
* new ActiveXDispatchEvents(someDispatch,someEventHAndler,
|
||||
* "Excel.Application",
|
||||
* "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE");
|
||||
* "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)
|
||||
{
|
||||
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) {
|
||||
|
||||
@@ -29,60 +29,67 @@ 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
|
||||
* 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> 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
|
||||
// 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");
|
||||
throw new IllegalArgumentException(
|
||||
"InvocationProxy: missing method name");
|
||||
}
|
||||
if (targetParameters == null) {
|
||||
throw new IllegalArgumentException("InvocationProxy: missing Variant parameters");
|
||||
throw new IllegalArgumentException(
|
||||
"InvocationProxy: missing Variant parameters");
|
||||
}
|
||||
try {
|
||||
Method targetMethod;
|
||||
Object parametersAsJavaObjects[] = getParametersAsJavaObjects(targetParameters);
|
||||
Class parametersAsJavaClasses[] = getParametersAsJavaClasses(parametersAsJavaObjects);
|
||||
targetMethod = targetClass.getMethod(methodName, parametersAsJavaClasses);
|
||||
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);
|
||||
mReturnedByInvocation = targetMethod.invoke(mTargetObject,
|
||||
parametersAsJavaObjects);
|
||||
if (mReturnedByInvocation == null) {
|
||||
mVariantToBeReturned = null;
|
||||
} else if (!(mReturnedByInvocation instanceof Variant)) {
|
||||
@@ -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());
|
||||
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
|
||||
@@ -113,13 +122,17 @@ public class ActiveXInvocationProxy extends InvocationProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
throw new IllegalArgumentException(
|
||||
"This only works with an array of parameters");
|
||||
}
|
||||
int numParameters = parametersAsJavaObjects.length;
|
||||
Class parametersAsJavaClasses[] = new Class[numParameters];
|
||||
@@ -137,12 +150,14 @@ 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");
|
||||
throw new IllegalArgumentException(
|
||||
"This only works with an array of parameters");
|
||||
}
|
||||
int numParameters = targetParameters.length;
|
||||
Object parametersAsJavaObjects[] = new Object[numParameters];
|
||||
@@ -152,10 +167,12 @@ public class ActiveXInvocationProxy extends InvocationProxy {
|
||||
parametersAsJavaObjects[parameterIndex] = null;
|
||||
} else {
|
||||
try {
|
||||
parametersAsJavaObjects[parameterIndex] = oneParameterObject.toJavaObject();
|
||||
parametersAsJavaObjects[parameterIndex] = oneParameterObject
|
||||
.toJavaObject();
|
||||
} catch (NotImplementedException nie) {
|
||||
throw new IllegalArgumentException("Can't convert parameter "+parameterIndex+
|
||||
" type "+oneParameterObject.getvt()
|
||||
throw new IllegalArgumentException(
|
||||
"Can't convert parameter " + parameterIndex
|
||||
+ " type " + oneParameterObject.getvt()
|
||||
+ " to java object: " + nie.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -163,5 +180,4 @@ public class ActiveXInvocationProxy extends InvocationProxy {
|
||||
return parametersAsJavaObjects;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -22,18 +22,27 @@ 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
|
||||
**/
|
||||
public abstract class ComException extends JacobException {
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* No documentation is available at this time. Someone should document this
|
||||
* field
|
||||
*/
|
||||
protected String m_source;
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ public class ComFailException extends ComException {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param hrNew
|
||||
*/
|
||||
public ComFailException(int hrNew) {
|
||||
@@ -38,6 +39,7 @@ public class ComFailException extends ComException {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param hrNew
|
||||
* @param message
|
||||
*/
|
||||
@@ -58,6 +60,7 @@ public class ComFailException extends ComException {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param hrNew
|
||||
* @param description
|
||||
* @param source
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
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;
|
||||
@@ -58,6 +57,7 @@ public abstract class ComThread {
|
||||
* 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) {
|
||||
@@ -68,6 +68,7 @@ public abstract class ComThread {
|
||||
* 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) {
|
||||
@@ -93,6 +94,7 @@ public abstract class ComThread {
|
||||
/**
|
||||
* Initialize the current java thread to be part of the MTA/STA COM
|
||||
* Apartment
|
||||
*
|
||||
* @param createMainSTA
|
||||
* @param mode
|
||||
*/
|
||||
@@ -103,34 +105,47 @@ public abstract class ComThread {
|
||||
// to avoid COM creating its own
|
||||
startMainSTA();
|
||||
}
|
||||
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: before Init: "+mode);}
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("ComThread: before Init: " + mode);
|
||||
}
|
||||
doCoInitialize(mode);
|
||||
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after Init: "+mode);}
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("ComThread: after Init: " + mode);
|
||||
}
|
||||
ROT.addThread();
|
||||
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after ROT.addThread: "+mode); }
|
||||
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"); }
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("ComThread: before clearObjects");
|
||||
}
|
||||
ROT.clearObjects();
|
||||
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: before UnInit"); }
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("ComThread: before UnInit");
|
||||
}
|
||||
doCoUninitialize();
|
||||
if (JacobObject.isDebugEnabled()){JacobObject.debug("ComThread: after UnInit"); }
|
||||
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.
|
||||
* @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)
|
||||
{
|
||||
@Deprecated
|
||||
public static synchronized void RemoveObject(JacobObject o) {
|
||||
ROT.removeObject(o);
|
||||
}
|
||||
|
||||
@@ -145,8 +160,8 @@ public abstract class ComThread {
|
||||
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.
|
||||
* 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();
|
||||
|
||||
91
src/com/jacob/com/Currency.java
Normal file
91
src/com/jacob/com/Currency.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* java / windows date conversion utilities
|
||||
*
|
||||
* @author joe
|
||||
*
|
||||
*/
|
||||
@@ -31,6 +32,7 @@ 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
|
||||
*/
|
||||
@@ -39,14 +41,13 @@ public class DateUtilities {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,15 +69,16 @@ 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");
|
||||
throw new IllegalArgumentException(
|
||||
"cannot convert null to windows time");
|
||||
}
|
||||
return convertMillisecondsToWindowsTime(javaDate.getTime());
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,54 +20,53 @@
|
||||
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.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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
|
||||
* @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);
|
||||
@@ -76,48 +75,59 @@ public class DispatchEvents extends JacobObject {
|
||||
/**
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
* @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) {
|
||||
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.
|
||||
* 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.
|
||||
* 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");
|
||||
* 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
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
public DispatchEvents(Dispatch sourceOfEvent, Object eventSink,
|
||||
String progId, String typeLib) {
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
System.out.println(
|
||||
"DispatchEvents: Registering "+ eventSink + "for events ");
|
||||
System.out.println("DispatchEvents: Registering " + eventSink
|
||||
+ "for events ");
|
||||
}
|
||||
if (eventSink instanceof InvocationProxy) {
|
||||
mInvocationProxy = (InvocationProxy) eventSink;
|
||||
@@ -130,14 +140,18 @@ public class DispatchEvents extends JacobObject {
|
||||
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
|
||||
* 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
|
||||
* @return InvocationProxy an instance of the proxy this DispatchEvents will
|
||||
* send to the COM layer
|
||||
*/
|
||||
protected InvocationProxy getInvocationProxy(Object pTargetObject) {
|
||||
InvocationProxy newProxy = new InvocationProxyAllVariants();
|
||||
@@ -146,28 +160,34 @@ public class DispatchEvents extends JacobObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* 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)
|
||||
* @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);
|
||||
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
|
||||
* 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() {
|
||||
@@ -176,6 +196,7 @@ public class DispatchEvents extends JacobObject {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.jacob.com.JacobObject#safeRelease()
|
||||
*/
|
||||
public void safeRelease() {
|
||||
@@ -189,7 +210,9 @@ public class DispatchEvents extends JacobObject {
|
||||
m_pConnPtProxy = 0;
|
||||
} else {
|
||||
// looks like a double release
|
||||
if (isDebugEnabled()){debug("DispatchEvents:"+this.hashCode()+" double release");}
|
||||
if (isDebugEnabled()) {
|
||||
debug("DispatchEvents:" + this.hashCode() + " double release");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
82
src/com/jacob/com/DispatchIdentifier.java
Normal file
82
src/com/jacob/com/DispatchIdentifier.java
Normal 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;
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class DispatchProxy extends JacobObject {
|
||||
|
||||
/**
|
||||
* Marshals the passed in dispatch into the stream
|
||||
*
|
||||
* @param localDispatch
|
||||
*/
|
||||
public DispatchProxy(Dispatch localDispatch) {
|
||||
@@ -55,13 +56,15 @@ public class DispatchProxy extends JacobObject {
|
||||
private native Dispatch MarshalFromStream();
|
||||
|
||||
/**
|
||||
* now private so only this object can asccess
|
||||
* was: call this to explicitly release the com object before gc
|
||||
* 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)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#finalize()
|
||||
*/
|
||||
public void finalize() {
|
||||
@@ -70,17 +73,20 @@ public class DispatchProxy extends JacobObject {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.jacob.com.JacobObject#safeRelease()
|
||||
*/
|
||||
public void 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");}
|
||||
if (isDebugEnabled()) {
|
||||
debug(this.getClass().getName() + ":" + this.hashCode()
|
||||
+ " double release");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ 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 {
|
||||
public class EnumVariant extends JacobObject implements
|
||||
java.util.Enumeration<Variant> {
|
||||
private int m_pIEnumVARIANT;
|
||||
|
||||
private final Variant[] m_recBuf = new Variant[1];
|
||||
@@ -39,10 +40,8 @@ public class EnumVariant extends JacobObject implements java.util.Enumeration {
|
||||
*/
|
||||
public EnumVariant(Dispatch disp) {
|
||||
int[] hres = new int[1];
|
||||
Variant evv = Dispatch.invokev(disp,
|
||||
Dispatch.DISPID_NEWENUM,
|
||||
Dispatch.Get,
|
||||
new Variant[0], hres);
|
||||
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
|
||||
@@ -56,7 +55,8 @@ public class EnumVariant extends JacobObject implements java.util.Enumeration {
|
||||
|
||||
/**
|
||||
* Implements java.util.Enumeration
|
||||
* @return boolean true if there are more elements in ths enumeration
|
||||
*
|
||||
* @return boolean true if there are more elements in this enumeration
|
||||
*/
|
||||
public boolean hasMoreElements() {
|
||||
{
|
||||
@@ -70,10 +70,11 @@ public class EnumVariant extends JacobObject implements java.util.Enumeration {
|
||||
|
||||
/**
|
||||
* Implements java.util.Enumeration
|
||||
*
|
||||
* @return next element in the enumeration
|
||||
*/
|
||||
public Object nextElement() {
|
||||
Object last = m_recBuf[0];
|
||||
public Variant nextElement() {
|
||||
Variant last = m_recBuf[0];
|
||||
if (last == null) {
|
||||
if (this.Next(m_recBuf) <= 0)
|
||||
throw new java.util.NoSuchElementException();
|
||||
@@ -85,59 +86,71 @@ public class EnumVariant extends JacobObject implements java.util.Enumeration {
|
||||
|
||||
/**
|
||||
* 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 (Variant) nextElement();
|
||||
return nextElement();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be private and wrapped to protect JNI layer.
|
||||
*
|
||||
* @param receiverArray
|
||||
* @return don't know what the int is that is returned, help!
|
||||
* @return Returns the next variant object pointer as an int from windows
|
||||
* layer
|
||||
*/
|
||||
public native int Next(Variant[] receiverArray);
|
||||
|
||||
/**
|
||||
* This should be private and wrapped to protect JNI layer.
|
||||
*
|
||||
* @param count
|
||||
* number to skip
|
||||
*/
|
||||
public native void Skip(int count);
|
||||
|
||||
/**
|
||||
*
|
||||
* 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
|
||||
* 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()
|
||||
{
|
||||
protected void finalize() {
|
||||
safeRelease();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.jacob.com.JacobObject#safeRelease()
|
||||
*/
|
||||
public void 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");}
|
||||
if (isDebugEnabled()) {
|
||||
debug(this.getClass().getName() + ":" + this.hashCode()
|
||||
+ " double release");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,19 +23,18 @@ 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 {
|
||||
@@ -46,29 +45,35 @@ public abstract class InvocationProxy {
|
||||
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() {
|
||||
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.
|
||||
* 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.
|
||||
* 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
|
||||
* @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[]);
|
||||
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() {
|
||||
@@ -77,20 +82,22 @@ public abstract class InvocationProxy {
|
||||
|
||||
/**
|
||||
* Sets the target for this InvocationProxy.
|
||||
*
|
||||
* @param pTargetObject
|
||||
* @throws IllegalArgumentException if target is not publicly accessable
|
||||
* @throws IllegalArgumentException
|
||||
* if target is not publicly accessible
|
||||
*/
|
||||
public void setTarget(Object pTargetObject) {
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug(
|
||||
"InvocationProxy: setting target "+pTargetObject);
|
||||
JacobObject.debug("InvocationProxy: setting target "
|
||||
+ pTargetObject);
|
||||
}
|
||||
if (pTargetObject != null) {
|
||||
// JNI code apparently bypasses this check and could operate against
|
||||
// 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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* 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> 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");
|
||||
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");
|
||||
throw new IllegalArgumentException(
|
||||
"InvocationProxy: missing method name");
|
||||
}
|
||||
if (targetParameters == null) {
|
||||
throw new IllegalArgumentException("InvocationProxy: missing Variant parameters");
|
||||
throw new IllegalArgumentException(
|
||||
"InvocationProxy: missing Variant parameters");
|
||||
}
|
||||
try {
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("InvocationProxy: trying to invoke "+methodName
|
||||
+" on "+mTargetObject);
|
||||
JacobObject.debug("InvocationProxy: trying to invoke "
|
||||
+ methodName + " on " + mTargetObject);
|
||||
}
|
||||
Method targetMethod;
|
||||
targetMethod = targetClass.getMethod(methodName,
|
||||
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});
|
||||
mReturnedByInvocation = targetMethod.invoke(mTargetObject,
|
||||
new Object[] { targetParameters });
|
||||
if (mReturnedByInvocation == null) {
|
||||
mVariantToBeReturned = null;
|
||||
} 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,10 +95,11 @@ 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
|
||||
// this happens whenever the listener doesn't implement all the
|
||||
// methods
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug("InvocationProxy: listener ("+mTargetObject+") doesn't implement "
|
||||
+ methodName);
|
||||
JacobObject.debug("InvocationProxy: listener (" + mTargetObject
|
||||
+ ") doesn't implement " + methodName);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
@@ -100,7 +108,8 @@ public class InvocationProxyAllVariants extends InvocationProxy {
|
||||
} 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"
|
||||
JacobObject
|
||||
.debug("InvocationProxy: probably tried to access public method on non public class"
|
||||
+ methodName);
|
||||
}
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -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,8 +32,7 @@ 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() {
|
||||
super("No Message Provided");
|
||||
@@ -41,6 +40,7 @@ public class JacobException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* standard constructor
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public JacobException(String message) {
|
||||
|
||||
@@ -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,77 +35,17 @@ 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()
|
||||
*/
|
||||
private static String buildVersion = "";
|
||||
/**
|
||||
* 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()
|
||||
*/
|
||||
private static String buildDate = "";
|
||||
|
||||
/**
|
||||
* Standard constructor that adds this JacobObject
|
||||
* to the memory management pool.
|
||||
* Standard constructor that adds this JacobObject to the memory management
|
||||
* pool.
|
||||
*/
|
||||
public JacobObject() {
|
||||
ROT.addObject(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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
|
||||
@@ -120,7 +56,7 @@ public class JacobObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* When things go wrong, it is usefull to be able to debug the ROT.
|
||||
* When things go wrong, it is useful to be able to debug the ROT.
|
||||
*/
|
||||
private static final boolean DEBUG =
|
||||
// true;
|
||||
@@ -130,16 +66,38 @@ public class JacobObject {
|
||||
// return true;
|
||||
return DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Very basic debugging fucntion.
|
||||
* 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());
|
||||
protected static void debug(String istrMessage) {
|
||||
if (isDebugEnabled()) {
|
||||
System.out.println(istrMessage + " in thread "
|
||||
+ Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,5 +108,4 @@ public class JacobObject {
|
||||
LibraryLoader.loadJacobLibrary();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
96
src/com/jacob/com/JacobReleaseInfo.java
Normal file
96
src/com/jacob/com/JacobReleaseInfo.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
*
|
||||
* <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.
|
||||
* 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-<version>-<arch>" (or
|
||||
* "jacob-<version>-<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>
|
||||
* 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
|
||||
* <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 {
|
||||
// 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();
|
||||
}
|
||||
else {
|
||||
System.loadLibrary("jacob");
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -20,10 +20,9 @@
|
||||
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 {
|
||||
|
||||
@@ -39,5 +38,4 @@ public class NotImplementedException extends JacobException {
|
||||
super(description);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,61 +30,64 @@ import java.util.WeakHashMap;
|
||||
* current thread so all the methods are static and they implicitly get the
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
// nothing to do
|
||||
} else {
|
||||
Map tab = null;
|
||||
Map<JacobObject, String> tab = null;
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug( "ROT: Automatic GC flag == " + USE_AUTOMATIC_GARBAGE_COLLECTION );
|
||||
JacobObject.debug("ROT: Automatic GC flag == "
|
||||
+ USE_AUTOMATIC_GARBAGE_COLLECTION);
|
||||
}
|
||||
if (!USE_AUTOMATIC_GARBAGE_COLLECTION) {
|
||||
tab = new HashMap();
|
||||
tab = new HashMap<JacobObject, String>();
|
||||
} else {
|
||||
tab = new WeakHashMap();
|
||||
tab = new WeakHashMap<JacobObject, String>();
|
||||
}
|
||||
rot.put(t_name, tab);
|
||||
}
|
||||
@@ -92,59 +95,68 @@ public abstract class ROT {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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 );
|
||||
Map<JacobObject, String> tab = getThreadObjects(false);
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug( "ROT: " + rot.keySet().size() + " thread tables exist" );
|
||||
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 " );
|
||||
JacobObject.debug("ROT: " + tab.keySet().size()
|
||||
+ " objects to clear in this thread ");
|
||||
}
|
||||
// walk the values
|
||||
Iterator it = tab.keySet().iterator();
|
||||
Iterator<JacobObject> it = tab.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
JacobObject o = (JacobObject) it.next();
|
||||
JacobObject o = 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
|
||||
// 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() );
|
||||
// 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();
|
||||
@@ -161,16 +173,18 @@ public abstract class ROT {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
@Deprecated
|
||||
protected synchronized static void removeObject(JacobObject o) {
|
||||
String t_name = Thread.currentThread().getName();
|
||||
Map tab = (Map) rot.get( t_name );
|
||||
Map<JacobObject, String> tab = rot.get(t_name);
|
||||
if (tab != null) {
|
||||
tab.remove(o);
|
||||
}
|
||||
@@ -179,19 +193,22 @@ public abstract class ROT {
|
||||
|
||||
/**
|
||||
* adds an object to the HashMap for the current thread
|
||||
*
|
||||
* @param 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");
|
||||
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");
|
||||
JacobObject.debug("JacobObject: New instance of "
|
||||
+ o.getClass().getName() + " not added to ROT");
|
||||
}
|
||||
} else {
|
||||
Map tab = getThreadObjects( false );
|
||||
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
|
||||
@@ -199,9 +216,9 @@ public abstract class ROT {
|
||||
tab = getThreadObjects(true);
|
||||
}
|
||||
if (JacobObject.isDebugEnabled()) {
|
||||
JacobObject.debug(
|
||||
"ROT: adding " + o + "->" + o.getClass().getName() +
|
||||
" table size prior to addition:" + tab.size() );
|
||||
JacobObject.debug("ROT: adding " + o + "->"
|
||||
+ o.getClass().getName()
|
||||
+ " table size prior to addition:" + tab.size());
|
||||
}
|
||||
if (tab != null) {
|
||||
tab.put(o, null);
|
||||
@@ -210,12 +227,11 @@ public abstract class ROT {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,9 @@ public class STA extends Thread {
|
||||
start(); // start the thread
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Thread#run()
|
||||
*/
|
||||
public void run() {
|
||||
@@ -57,6 +59,7 @@ public class STA extends Thread {
|
||||
* 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() {
|
||||
@@ -89,8 +92,8 @@ public class STA extends Thread {
|
||||
public native void quitMessagePump();
|
||||
|
||||
/**
|
||||
* STA isn't a subclass of JacobObject so a reference to it doesn't load
|
||||
* the DLL without this
|
||||
* 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
471
src/com/jacob/com/VariantUtilities.java
Normal file
471
src/com/jacob/com/VariantUtilities.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,15 @@
|
||||
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 {
|
||||
|
||||
/**
|
||||
* Standard constructor used by JNI event handling layer
|
||||
*/
|
||||
public VariantViaEvent() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public class WrongThreadException extends JacobException {
|
||||
|
||||
/**
|
||||
* standard constructor with a string message
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
public WrongThreadException(String s) {
|
||||
|
||||
@@ -4,34 +4,87 @@ 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 {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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");
|
||||
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);
|
||||
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);
|
||||
ActiveXComponent mTryConnectingThird = ActiveXComponent
|
||||
.connectToActiveInstance(mApplicationId);
|
||||
if (mTryConnectingThird == null) {
|
||||
fail("Was unable able to connect to MSWord after previous startup");
|
||||
} else {
|
||||
@@ -40,19 +93,22 @@ public class ActiveXComponentFactoryTest extends BaseTestCase {
|
||||
mTryConnectingThird.invoke("Quit", new Variant[] {});
|
||||
}
|
||||
Thread.sleep(2000);
|
||||
ActiveXComponent mTryConnectingFourth = ActiveXComponent.connectToActiveInstance(mApplicationId);
|
||||
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 (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");
|
||||
// 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();
|
||||
|
||||
@@ -9,29 +9,38 @@ 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 {
|
||||
|
||||
/**
|
||||
* verify date conversion to and from java
|
||||
*/
|
||||
public void testDateUtilities() {
|
||||
Date now = new Date();
|
||||
double comTimeForNow = DateUtilities.convertDateToWindowsTime(now);
|
||||
Date retrievedNow = DateUtilities.convertWindowsTimeToDate(comTimeForNow);
|
||||
Date retrievedNow = DateUtilities
|
||||
.convertWindowsTimeToDate(comTimeForNow);
|
||||
if (!now.equals(retrievedNow)) {
|
||||
fail("DateUtilities Date Test failed " +now+ " != " +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);
|
||||
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);
|
||||
@@ -41,5 +50,4 @@ public class DateUtilitiesTest extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 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");
|
||||
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");
|
||||
System.out
|
||||
.println("the dispatch protected itself from empty string program ids");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Dummy test until someone gets their act together
|
||||
*/
|
||||
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));
|
||||
// what should we test
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,30 @@ 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.
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
/**
|
||||
* verify the build version and date functions work correctly
|
||||
*/
|
||||
public void testBuildVersion() {
|
||||
System.out.println("build version is "+JacobObject.getBuildVersion());
|
||||
System.out.println("build date is "+JacobObject.getBuildDate());
|
||||
System.out.println("build version is " + JacobReleaseInfo.getBuildVersion());
|
||||
System.out.println("build date is " + JacobReleaseInfo.getBuildDate());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
79
unittest/com/jacob/com/LibraryLoaderTest.java
Normal file
79
unittest/com/jacob/com/LibraryLoaderTest.java
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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,8 +100,7 @@ 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
|
||||
ROT.removeObject(variansCreatedInThisThread
|
||||
.get(i - 1));
|
||||
}
|
||||
variansCreatedInThisThread.remove(i - 1);
|
||||
|
||||
@@ -1,45 +1,52 @@
|
||||
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
|
||||
* 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
|
||||
// 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");
|
||||
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();
|
||||
int countAfterAddWithoutROT = ROT.getThreadObjects(true).entrySet()
|
||||
.size();
|
||||
if (countAfterAddWithoutROT != countPriorToTest) {
|
||||
debug("Failure: count prior: "+countPriorToTest+
|
||||
" and count after without ROT was: "+countAfterAddWithoutROT);
|
||||
debug("Failure: count prior: " + countPriorToTest
|
||||
+ " and count after without ROT was: "
|
||||
+ countAfterAddWithoutROT);
|
||||
}
|
||||
|
||||
System.setProperty(VariantViaEvent.class.getName()+ROT.PUT_IN_ROT_SUFFIX,"true");
|
||||
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("Failure: count prior: " + countPriorToTest
|
||||
+ " and count after with ROT was: " + countAfterAddWithROT);
|
||||
}
|
||||
debug("testDontFillROTSystemProperty: completed");
|
||||
}
|
||||
@@ -56,7 +63,6 @@ public class ROTTest extends BaseTestCase {
|
||||
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
|
||||
@@ -73,7 +79,8 @@ public class ROTTest extends BaseTestCase {
|
||||
if (sizeAfterBuild < sizeExpectedAfterBuild) {
|
||||
debug("Something got GC'd: " + sizeAfterBuild);
|
||||
} else if (sizeAfterBuild > sizeExpectedAfterBuild) {
|
||||
debug("More: "+sizeAfterBuild+" than expected: "+sizeExpectedAfterBuild);
|
||||
debug("More: " + sizeAfterBuild + " than expected: "
|
||||
+ sizeExpectedAfterBuild);
|
||||
} else {
|
||||
debug("They're all there");
|
||||
}
|
||||
@@ -82,19 +89,24 @@ public class ROTTest extends BaseTestCase {
|
||||
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
|
||||
// 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("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);
|
||||
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());
|
||||
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) );
|
||||
debug("Found number expected after adding one more "
|
||||
+ (sizeAfterGC + 1));
|
||||
}
|
||||
ROT.clearObjects();
|
||||
if (ROT.getThreadObjects(false) == null) {
|
||||
|
||||
@@ -7,11 +7,15 @@ 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 {
|
||||
|
||||
/**
|
||||
* verify the conversion of Variants into java dates
|
||||
*/
|
||||
public void testVariantDate() {
|
||||
Date now = new Date();
|
||||
Variant holder = new Variant();
|
||||
@@ -25,6 +29,10 @@ public class VariantDateTest extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* verify that the Variant constructor accepts Java dates and converts them
|
||||
* correctly
|
||||
*/
|
||||
public void testVariantDateToJavaObject() {
|
||||
Date now = new Date();
|
||||
Variant holder = new Variant(now);
|
||||
@@ -33,16 +41,19 @@ public class VariantDateTest extends BaseTestCase {
|
||||
Date retrievedNow = holder.getJavaDate();
|
||||
retrievedNow = dateVariant.getJavaDate();
|
||||
if (!now.equals(retrievedNow)) {
|
||||
fail("Variant Date Test (1) failed " +now+ " != " +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 );
|
||||
fail("Variant Date Test (2) failed " + now + " != "
|
||||
+ retrievedNow);
|
||||
} else {
|
||||
//System.out.println("Variant Date Test (2) passed "+retrievedNow);
|
||||
// System.out.println("Variant Date Test (2) passed
|
||||
// "+retrievedNow);
|
||||
}
|
||||
|
||||
Variant intVariant = new Variant(4);
|
||||
|
||||
@@ -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,17 +10,18 @@ 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() {
|
||||
@@ -29,48 +31,42 @@ public class VariantTest extends BaseTestCase {
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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
|
||||
@@ -79,21 +75,71 @@ public class VariantTest extends BaseTestCase {
|
||||
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");
|
||||
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");
|
||||
fail(v.toString() + " could not make type " + v.getvt() + " and "
|
||||
+ vByRef.getvt() + " java objects come out the same");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +160,8 @@ public class VariantTest extends BaseTestCase {
|
||||
*/
|
||||
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();
|
||||
@@ -123,19 +170,15 @@ public class VariantTest extends BaseTestCase {
|
||||
modifier = Variant.VariantShort;
|
||||
vConverted = v.changeType(modifier);
|
||||
if (vConverted.getvt() != modifier) {
|
||||
fail("Failed to change Variant "+originalVT
|
||||
+ " using mask "+modifier
|
||||
+ " resulted in "+vConverted.getvt()
|
||||
);
|
||||
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()
|
||||
);
|
||||
fail("Failed to change Variant " + originalVT + " using mask "
|
||||
+ modifier + " resulted in " + vConverted.getvt());
|
||||
}
|
||||
|
||||
// can't convert to byref!
|
||||
@@ -143,9 +186,8 @@ public class VariantTest extends BaseTestCase {
|
||||
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()
|
||||
);
|
||||
+ " using mask " + modifier + " resulted in "
|
||||
+ vConverted.getvt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,23 +202,27 @@ public class VariantTest extends BaseTestCase {
|
||||
try {
|
||||
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");
|
||||
throw new RuntimeException(
|
||||
"getvt() on uninitialized variant shoud have succeeded, but instead threw exception");
|
||||
}
|
||||
try {
|
||||
v.toString();
|
||||
} 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
|
||||
@@ -186,7 +232,8 @@ public class VariantTest extends BaseTestCase {
|
||||
v = new Variant(true);
|
||||
v.toString();
|
||||
if (v.getvt() != Variant.VariantBoolean) {
|
||||
throw new RuntimeException("toString() converted boolean to something else");
|
||||
throw new RuntimeException(
|
||||
"toString() converted boolean to something else");
|
||||
} else {
|
||||
// fail("toString() correctly does not convert type");
|
||||
}
|
||||
@@ -196,7 +243,8 @@ public class VariantTest extends BaseTestCase {
|
||||
v = new Variant(false);
|
||||
v.toString();
|
||||
if (v.getvt() != Variant.VariantBoolean) {
|
||||
throw new RuntimeException("toString() converted boolean to something else");
|
||||
throw new RuntimeException(
|
||||
"toString() converted boolean to something else");
|
||||
} else {
|
||||
// fail("toString() correctly does not convert type");
|
||||
}
|
||||
@@ -205,6 +253,10 @@ public class VariantTest extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that booleans can be released. Part of the suite that checks all
|
||||
* types.
|
||||
*/
|
||||
public void testSafeReleaseBoolean() {
|
||||
Variant v;
|
||||
v = new Variant(true);
|
||||
@@ -216,7 +268,8 @@ public class VariantTest extends BaseTestCase {
|
||||
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");
|
||||
// System.out.println("IllegalStateException correctly thrown after
|
||||
// safeRelease");
|
||||
}
|
||||
v = new Variant(true);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@@ -230,7 +283,8 @@ public class VariantTest extends BaseTestCase {
|
||||
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");
|
||||
// System.out.println("IllegalStateException correctly thrown after
|
||||
// ComThread.Release");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +293,8 @@ public class VariantTest extends BaseTestCase {
|
||||
*
|
||||
*/
|
||||
public void testSafeReleaseConstant() {
|
||||
//System.out.println("Using Static constant Variant - should never throw access violation");
|
||||
// System.out.println("Using Static constant Variant - should never
|
||||
// throw access violation");
|
||||
Variant.VT_TRUE.safeRelease();
|
||||
if (Variant.VT_TRUE.getBoolean() != true) {
|
||||
fail("VT_TRUE has been broken by SafeRelease()");
|
||||
@@ -265,9 +320,9 @@ public class VariantTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@@ -281,7 +336,8 @@ public class VariantTest extends BaseTestCase {
|
||||
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");
|
||||
// System.out.println("IllegalStateException correctly thrown after
|
||||
// safeRelease");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +366,6 @@ public class VariantTest extends BaseTestCase {
|
||||
fail("confused a boolean with VT_FALSE");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,8 +375,8 @@ public class VariantTest extends BaseTestCase {
|
||||
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());
|
||||
@@ -348,14 +403,15 @@ public class VariantTest extends BaseTestCase {
|
||||
v.putBoolean(false);
|
||||
assertEquals("failed boolean test(false)", false, v.getBoolean());
|
||||
|
||||
v.putCurrency(123456789123456789L);
|
||||
assertEquals("failed currency test",123456789123456789L, v.getCurrency());
|
||||
long originalValue = 123456789123456789L;
|
||||
v.putCurrency(new Currency(originalValue));
|
||||
assertEquals("failed currency test", 123456789123456789L, v
|
||||
.getCurrency().longValue());
|
||||
|
||||
BigDecimal testDecimal = new BigDecimal("22.222");
|
||||
v.putDecimal(testDecimal);
|
||||
assertEquals("failed BigDecimal test", testDecimal, v.getDecimal());
|
||||
|
||||
|
||||
Date ourDate = new Date();
|
||||
v.putDate(ourDate);
|
||||
Date retrievedDate = v.getJavaDate();
|
||||
@@ -397,8 +453,133 @@ public class VariantTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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() {
|
||||
@@ -407,12 +588,10 @@ public class VariantTest extends BaseTestCase {
|
||||
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++)
|
||||
{
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i] = new VariantInitTestThread("thread-" + i, 10000);
|
||||
}
|
||||
for (int i = 0; i < threads.length; i++)
|
||||
{
|
||||
for (int i = 0; i < threads.length; i++) {
|
||||
threads[i].start();
|
||||
}
|
||||
int numComplete = 0;
|
||||
@@ -435,35 +614,41 @@ public class VariantTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* a class to create variants in seperate threads
|
||||
* @author joe
|
||||
* a class to create variants in separate threads
|
||||
*
|
||||
*/
|
||||
class VariantInitTestThread extends Thread
|
||||
{
|
||||
class VariantInitTestThread extends Thread {
|
||||
private boolean isComplete = false;
|
||||
|
||||
private int initialRunSize = 0;
|
||||
|
||||
/**
|
||||
* @param arg0
|
||||
* @param newThreadName
|
||||
* the name for the thread
|
||||
* @param iStartCount
|
||||
* number of threads to start with
|
||||
*/
|
||||
public VariantInitTestThread(String newThreadName, int iStartCount)
|
||||
{
|
||||
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()
|
||||
{
|
||||
public void run() {
|
||||
for (int variantIndex = 0; variantIndex < initialRunSize; variantIndex++) {
|
||||
try {
|
||||
Thread.yield();
|
||||
|
||||
33
unittest/com/jacob/com/VariantUtilitiesTest.java
Normal file
33
unittest/com/jacob/com/VariantUtilitiesTest.java
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -39,6 +42,7 @@ public class BaseTestCase extends TestCase {
|
||||
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();
|
||||
@@ -68,7 +74,8 @@ public class BaseTestCase extends TestCase {
|
||||
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;
|
||||
@@ -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("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) {
|
||||
@@ -132,13 +145,13 @@ public class BaseTestCase extends TestCase {
|
||||
* 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,7 +162,8 @@ 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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -11,40 +12,33 @@ 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.
|
||||
* 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,34 +55,81 @@ 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Proxy class to verify we receive expected events
|
||||
*/
|
||||
public class ExcelEvents extends InvocationProxy {
|
||||
|
||||
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() {
|
||||
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.
|
||||
* 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);
|
||||
System.out.println("Received event from " + listenerPrefix + ": "
|
||||
+ methodName);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,21 +6,25 @@ 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();
|
||||
@@ -36,7 +40,8 @@ public class IETest extends BaseTestCase {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Main: Thread quit, about to quit main sta in thread "
|
||||
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();
|
||||
@@ -44,13 +49,14 @@ public class IETest extends BaseTestCase {
|
||||
+ Thread.currentThread().getName());
|
||||
|
||||
if (aThread.threadFailedWithException != null) {
|
||||
fail("caught an unexpected exception "+aThread.threadFailedWithException);
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -58,17 +64,20 @@ class IETestThread extends Thread
|
||||
*/
|
||||
public Throwable threadFailedWithException = null;
|
||||
|
||||
/**
|
||||
* constructor for the test thread
|
||||
*/
|
||||
public IETestThread() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
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");
|
||||
ActiveXComponent ie = new ActiveXComponent(
|
||||
"InternetExplorer.Application");
|
||||
try {
|
||||
Dispatch.put(ie, "Visible", new Variant(true));
|
||||
Dispatch.put(ie, "AddressBar", new Variant(true));
|
||||
@@ -83,14 +92,24 @@ class IETestThread extends Thread
|
||||
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 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"));
|
||||
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) {}
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
threadFailedWithException = e;
|
||||
e.printStackTrace();
|
||||
@@ -105,112 +124,287 @@ class IETestThread extends Thread
|
||||
// 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
|
||||
// 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");
|
||||
// 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) {}
|
||||
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());
|
||||
System.out
|
||||
.println("IETestThread: about to call ComThread.Release in thread "
|
||||
+ Thread.currentThread().getName());
|
||||
|
||||
ComThread.Release();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 class IEEvents
|
||||
{
|
||||
public void BeforeNavigate2(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): BeforeNavigate2 "+args.length);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): BeforeNavigate2 "
|
||||
+ 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName()
|
||||
+ "): CommandStateChange " + 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): DocumentComplete "
|
||||
+ 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): DownloadBegin "
|
||||
+ 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): DownloadComplete "
|
||||
+ 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);
|
||||
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 NavigateComplete2(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NavigateComplete "+args.length);
|
||||
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 NewWindow2(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): NewWindow2 "+args.length);
|
||||
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 OnFullScreen(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnFullScreen "+args.length);
|
||||
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 OnMenuBar(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnMenuBar "+args.length);
|
||||
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 OnQuit(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnQuit "+args.length);
|
||||
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 OnStatusBar(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnStatusBar "+args.length);
|
||||
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 OnTheaterMode(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnTheaterMode "+args.length);
|
||||
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 OnToolBar(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnToolBar "+args.length);
|
||||
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 OnVisible(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): OnVisible "+args.length);
|
||||
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 ProgressChange(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): ProgressChange "+args.length);
|
||||
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 PropertyChange(Variant[] args) {
|
||||
System.out.println("IEEvents Received ("+Thread.currentThread().getName()+"): PropertyChange "+args.length);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): WindowClosing "
|
||||
+ args.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,22 +6,25 @@ 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 {
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@@ -37,20 +40,22 @@ public class IETestActiveXProxy extends BaseTestCase {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Main: Thread quit, about to quit main sta in thread "
|
||||
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);
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -58,39 +63,55 @@ class IETestActiveProxyThread extends Thread
|
||||
*/
|
||||
public Throwable threadFailedWithException = null;
|
||||
|
||||
/** the thread's constructor */
|
||||
public IETestActiveProxyThread() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
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");
|
||||
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"));
|
||||
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");
|
||||
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");
|
||||
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) {}
|
||||
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();
|
||||
@@ -105,113 +126,163 @@ class IETestActiveProxyThread extends Thread
|
||||
// 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
|
||||
// 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");
|
||||
// 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) {}
|
||||
try {
|
||||
Thread.sleep(delay / 5);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
System.out.println("IETestActiveProxyThread: Received the quit callback");
|
||||
}
|
||||
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());
|
||||
System.out
|
||||
.println("IETestActiveProxyThread: about to call ComThread.Release in thread "
|
||||
+ Thread.currentThread().getName());
|
||||
|
||||
ComThread.Release();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 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);
|
||||
String targetFrameName, Variant postData, String headers,
|
||||
Boolean cancel) {
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): BeforeNavigate2 "
|
||||
+ url);
|
||||
}
|
||||
|
||||
public void CommandStateChange(Integer command, Boolean enable) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): CommandStateChange "+command);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName()
|
||||
+ "): CommandStateChange " + command);
|
||||
}
|
||||
|
||||
public void DocumentComplete(Dispatch pDisp, String url) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DocumentComplete "+url);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): DocumentComplete "
|
||||
+ url);
|
||||
}
|
||||
|
||||
public void DownloadBegin() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DownloadBegin ");
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): DownloadBegin ");
|
||||
}
|
||||
|
||||
public void DownloadComplete() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): DownloadComplete ");
|
||||
System.out
|
||||
.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName()
|
||||
+ "): DownloadComplete ");
|
||||
}
|
||||
|
||||
public void NavigateComplete2(Dispatch pDisp, String url) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): NavigateComplete "+url);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): NavigateComplete "
|
||||
+ 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 NavigateError(Dispatch pDispatch, String url,
|
||||
String targetFrameName, Integer statusCode, Boolean Cancel) {
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): NavigateError "
|
||||
+ statusCode);
|
||||
}
|
||||
|
||||
public void NewWindow2(Dispatch pDisp, Boolean cancel) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): NewWindow2 "+pDisp);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): NewWindow2 "
|
||||
+ pDisp);
|
||||
}
|
||||
|
||||
public void OnFullScreen(Boolean fullScreen) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnFullScreen "+fullScreen);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnFullScreen "
|
||||
+ fullScreen);
|
||||
}
|
||||
|
||||
public void OnMenuBar(Boolean menuBar) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnMenuBar "+menuBar);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnMenuBar "
|
||||
+ menuBar);
|
||||
}
|
||||
|
||||
public void OnQuit() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnQuit ");
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnQuit ");
|
||||
IETestActiveProxyThread.quitHandled = true;
|
||||
}
|
||||
|
||||
public void OnStatusBar(Boolean statusBar) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnStatusBar "+statusBar);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnStatusBar "
|
||||
+ statusBar);
|
||||
}
|
||||
|
||||
public void OnTheaterMode(Boolean theaterMode) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnTheaterMode "+theaterMode);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnTheaterMode "
|
||||
+ theaterMode);
|
||||
}
|
||||
|
||||
public void OnToolBar(Boolean onToolBar) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): OnToolBar "+onToolBar);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): OnToolBar "
|
||||
+ onToolBar);
|
||||
}
|
||||
|
||||
public void OnVisible(Boolean onVisible) {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): onVisible "+ onVisible);
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): onVisible "
|
||||
+ onVisible);
|
||||
}
|
||||
|
||||
public void ProgressChange() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): ProgressChange ");
|
||||
System.out.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName() + "): ProgressChange ");
|
||||
}
|
||||
|
||||
public void PropertyChange() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName()
|
||||
+ "): setSecureLockIcon " + secureLockIcon);
|
||||
}
|
||||
|
||||
public void StatusTextChange() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): StatusTextChange ");
|
||||
System.out
|
||||
.println("IEEventsActiveProxy Received ("
|
||||
+ Thread.currentThread().getName()
|
||||
+ "): StatusTextChange ");
|
||||
}
|
||||
|
||||
public void TitleChange() {
|
||||
System.out.println("IEEventsActiveProxy Received ("+Thread.currentThread().getName()+"): 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);
|
||||
System.out.println("IEEvents Received ("
|
||||
+ Thread.currentThread().getName() + "): WindowClosing "
|
||||
+ isChildWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
@@ -50,7 +51,8 @@ public class WordEventTest extends BaseTestCase {
|
||||
// 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");
|
||||
ActiveXComponent documents = axc
|
||||
.getPropertyAsComponent("Documents");
|
||||
if (documents == null) {
|
||||
fail("unable to get documents");
|
||||
}
|
||||
@@ -61,12 +63,15 @@ public class WordEventTest extends BaseTestCase {
|
||||
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");
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* a class that receives messages from word
|
||||
*/
|
||||
public class WordEvents extends InvocationProxy {
|
||||
/**
|
||||
* Constructor so we can create an instance that implements invoke()
|
||||
@@ -75,10 +80,12 @@ public class WordEvents extends InvocationProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* override the invoke() method to log all the events without writing a bunch of code
|
||||
* 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);
|
||||
System.out.println("Received event from Windows program"
|
||||
+ methodName);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
236
unittest/com/jacob/test/excel/ControllerTest.java
Normal file
236
unittest/com/jacob/test/excel/ControllerTest.java
Normal 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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
unittest/com/jacob/test/excel/teste.xls
Normal file
BIN
unittest/com/jacob/test/excel/teste.xls
Normal file
Binary file not shown.
@@ -17,28 +17,30 @@ 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 {
|
||||
private static final int NUM_THREADS = 5;
|
||||
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");
|
||||
ActiveXComponent component = new ActiveXComponent(
|
||||
"Powerpoint.Application");
|
||||
Dispatch comPowerpoint = component.getObject();
|
||||
|
||||
try {
|
||||
@@ -69,8 +71,8 @@ public class PowerpointTest extends BaseTestCase {
|
||||
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);
|
||||
fail("caught unexpected exception in thread "
|
||||
+ threads[i].threadFailedWithException);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -79,6 +81,9 @@ public class PowerpointTest extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* the thread class that runs power point
|
||||
*/
|
||||
public class PowerpointTestThread extends Thread {
|
||||
/**
|
||||
* holds any caught exception so the main/test case can see them
|
||||
@@ -88,6 +93,12 @@ public class PowerpointTestThread extends Thread {
|
||||
private int threadID;
|
||||
private Dispatch comPowerpoint;
|
||||
|
||||
/**
|
||||
* thread constructor
|
||||
*
|
||||
* @param threadID
|
||||
* @param comPowerpoint
|
||||
*/
|
||||
public PowerpointTestThread(int threadID, Dispatch comPowerpoint) {
|
||||
super("TestThread " + threadID);
|
||||
this.threadID = threadID;
|
||||
@@ -95,36 +106,44 @@ public class PowerpointTestThread extends Thread {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("Thread \""+Thread.currentThread().getName()+"\" started");
|
||||
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.println(Thread.currentThread().getName()
|
||||
+ ": Iteration " + i);
|
||||
System.out.flush();
|
||||
}
|
||||
Dispatch comPresentations = Dispatch.get(comPowerpoint,"Presentations").toDispatch();
|
||||
Dispatch comPresentation = Dispatch.call(comPresentations,
|
||||
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();
|
||||
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()));
|
||||
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()+"\":");
|
||||
System.err.println("Error in Thread \""
|
||||
+ Thread.currentThread().getName() + "\":");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
ComThread.Release();
|
||||
System.out.println("Thread \""+Thread.currentThread().getName()+"\" finished");
|
||||
System.out.println("Thread \""
|
||||
+ Thread.currentThread().getName() + "\" finished");
|
||||
System.out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,66 +7,194 @@ 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]);
|
||||
}
|
||||
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]);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -3,20 +3,21 @@ 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 {
|
||||
|
||||
@@ -36,7 +37,7 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
SafeArray sa = null;
|
||||
|
||||
// -Dcom.jacob.autogc=true
|
||||
System.out.println("Jacob version: "+JacobObject.getBuildVersion());
|
||||
System.out.println("Jacob version: " + JacobReleaseInfo.getBuildVersion());
|
||||
|
||||
for (int t = 0; t < 10; t++) {
|
||||
// look at a large range of cells
|
||||
@@ -44,7 +45,8 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
|
||||
try {
|
||||
xl = new ActiveXComponent("Excel.Application");
|
||||
System.out.println("Excel version=" + xl.getProperty("Version"));
|
||||
System.out
|
||||
.println("Excel version=" + xl.getProperty("Version"));
|
||||
|
||||
xl.setProperty("Visible", new Variant(false));
|
||||
workbooks = xl.getProperty("Workbooks").toDispatch();
|
||||
@@ -56,8 +58,7 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
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();
|
||||
new Object[] { position }, new int[1]).toDispatch();
|
||||
|
||||
sa = Dispatch.get(tabCells, "Value").toSafeArray(true);
|
||||
|
||||
@@ -89,20 +90,16 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
Variant f = new Variant(false);
|
||||
Dispatch.call(workbook, "Close", f);
|
||||
System.out.println("Close");
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
|
||||
if (sa != null) {
|
||||
try {
|
||||
sa.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
sa = null;
|
||||
}
|
||||
}
|
||||
@@ -110,11 +107,9 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (tabCells != null) {
|
||||
try {
|
||||
tabCells.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
tabCells = null;
|
||||
}
|
||||
}
|
||||
@@ -122,11 +117,9 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (sheet != null) {
|
||||
try {
|
||||
sheet.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
sheet = null;
|
||||
}
|
||||
}
|
||||
@@ -134,11 +127,9 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (workSheets != null) {
|
||||
try {
|
||||
workSheets.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workSheets = null;
|
||||
}
|
||||
}
|
||||
@@ -146,11 +137,9 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (workbook != null) {
|
||||
try {
|
||||
workbook.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workbook = null;
|
||||
}
|
||||
}
|
||||
@@ -158,11 +147,9 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (workbooks != null) {
|
||||
try {
|
||||
workbooks.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workbooks = null;
|
||||
}
|
||||
}
|
||||
@@ -170,18 +157,15 @@ public class SafeArrayLeak extends BaseTestCase {
|
||||
if (xl != null) {
|
||||
try {
|
||||
xl.invoke("Quit", new Variant[] {});
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
xl.safeRelease();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
xl = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,92 +7,65 @@ 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.
|
||||
* 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|
|
||||
+------------+ +---------+
|
||||
* 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.
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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++)
|
||||
{
|
||||
for (count = 1; count < MAX; count++) {
|
||||
int i = 0;
|
||||
try
|
||||
{
|
||||
try {
|
||||
ComThread.InitMTA();
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
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"));
|
||||
@@ -105,13 +78,12 @@ public class SafeArrayReleaseTest extends BaseTestCase {
|
||||
ComThread.Release();
|
||||
System.gc();
|
||||
// System.out.print(".");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
fail("Test fails with i = " + i + " (max = " + MAX + ")");
|
||||
}
|
||||
}
|
||||
System.gc();
|
||||
System.out.println("\nTest ends with count = " + count + " (max = "+MAX+")");
|
||||
System.out.println("\nTest ends with count = " + count + " (max = "
|
||||
+ MAX + ")");
|
||||
}
|
||||
}
|
||||
@@ -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,7 +31,8 @@ public class SafeArrayViaExcel extends BaseTestCase {
|
||||
Dispatch workbook = Dispatch.call(
|
||||
workbooks,
|
||||
"Open",
|
||||
getWindowsFilePathToPackageResource("SafeArrayViaExcel.xls",this.getClass()))
|
||||
getWindowsFilePathToPackageResource(
|
||||
"SafeArrayViaExcel.xls", this.getClass()))
|
||||
.toDispatch();
|
||||
System.out.println("Opened File - SafeArrayViaExcel.xls\n");
|
||||
Dispatch sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -34,8 +39,10 @@ public class ScriptTest3 extends BaseTestCase {
|
||||
// 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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
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
|
||||
@@ -24,7 +27,8 @@ public class ScriptTestActiveX extends BaseTestCase {
|
||||
ScriptTestErrEvents te = new ScriptTestErrEvents();
|
||||
de = new DispatchEvents(sC, te);
|
||||
if (de == null) {
|
||||
System.out.println("null returned when trying to create DispatchEvents");
|
||||
System.out
|
||||
.println("null returned when trying to create DispatchEvents");
|
||||
}
|
||||
Variant result;
|
||||
result = sC.invoke("Eval", getSampleVPScriptForEval());
|
||||
@@ -32,15 +36,13 @@ public class ScriptTestActiveX extends BaseTestCase {
|
||||
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);
|
||||
System.out.println("eval(" + getSampleVPScriptForEval() + ") = "
|
||||
+ result);
|
||||
} catch (ComException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
Integer I = null;
|
||||
for(int i=1;i<1000000;i++)
|
||||
{
|
||||
for (int i = 1; i < 1000000; i++) {
|
||||
I = new Integer(i);
|
||||
}
|
||||
System.out.println(I);
|
||||
@@ -49,4 +51,3 @@ public class ScriptTestActiveX extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
public void Error(Variant[] args) {
|
||||
System.out.println("java callback for error!");
|
||||
}
|
||||
public void Timeout(Variant[] args)
|
||||
{
|
||||
|
||||
public void Timeout(Variant[] args) {
|
||||
System.out.println("java callback for error!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user