/************************************************************************** * Copyright (c) 2001 by Acunia N.V. All rights reserved. * * * * This software is copyrighted by and is the sole property of Acunia N.V. * * and its licensors, if any. All rights, title, ownership, or other * * interests in the software remain the property of Acunia N.V. and its * * licensors, if any. * * * * This software may only be used in accordance with the corresponding * * license agreement. Any unauthorized use, duplication, transmission, * * distribution or disclosure of this software is expressly forbidden. * * * * This Copyright notice may not be removed or modified without prior * * written consent of Acunia N.V. * * * * Acunia N.V. reserves the right to modify this software without notice. * * * * Acunia N.V. * * Vanden Tymplestraat 35 info@acunia.com * * 3000 Leuven http://www.acunia.com * * Belgium - EUROPE * **************************************************************************/ // Tags: JLS1.0 package gnu.testlet.wonka.jni; import gnu.testlet.Testlet; import gnu.testlet.TestHarness; public class JNIMemberAccessTest extends ContainerFunctions implements Testlet { // load the native library// static { System.loadLibrary("JNIMemberAccessTest"); } /*********************************************************************************************************************/ /** * our variables: */ protected static TestHarness harness; int ourInt; String ourString; boolean[] ourArray = new boolean[3]; SimpleContainer ourSimpleContainer = new SimpleContainer(); /*********************************************************************************************************************/ /** * Tests on accessing the member variables above through a JNI call */ private void testMemberVariableAccess() { harness.checkPoint("Direct access member <primitive int> via native calls"); //integer ourInt = 1300; harness.check(getMemberInteger(), ourInt); setMemberInteger(1301); harness.check(ourInt, 1301); harness.checkPoint("Direct access member <String> via native calls"); //string ourString = "Leopold I"; harness.check(getMemberString(), ourString); setMemberString("Leopold II"); harness.check (ourString, "Leopold II"); harness.checkPoint("Direct access member <array> via native calls"); // boolean array ourArray = buildBoolArray(true, true, false); boolean[] testarray = getMemberArray(); checkBoolArray(testarray, ourArray, harness); testarray = buildBoolArray(true, false, true); setMemberArray(testarray); checkBoolArray(ourArray, testarray, harness); harness.checkPoint("Direct access member <class SimpleContainer> via native calls"); // simple container ourSimpleContainer = buildSimpleContainer(500, "alfred", buildBoolArray(true, false, false)); SimpleContainer testcontainer = getMemberSimpleContainer(); compareSimpleContainer(testcontainer, ourSimpleContainer, harness); testcontainer = buildSimpleContainer(501, "Berthold", buildBoolArray(false, true, true)); setMemberSimpleContainer(testcontainer); compareSimpleContainer(ourSimpleContainer, testcontainer, harness); } // natives for the member access functions: (return or assign the member variable mentioned) /// jni call that returns the member integer ourint private native int getMemberInteger(); /// jni call that sets the member integer ourint to a specified value private native void setMemberInteger(int i); /// jni call that returns the member string ourstring private native String getMemberString (); /// jni call that sets the member string ourstring to a specified value private native void setMemberString (String s); /// jni call that returns the member array ourarray private native boolean[] getMemberArray(); /// jni call that sets the member array ourarray to a specified array of values private native void setMemberArray(boolean[] bx); /// jni call that returns the member container class ourcontainer private native SimpleContainer getMemberSimpleContainer (); /// jni call that sets the member container class instance ourcontainer to a specified container contents private native void setMemberSimpleContainer (SimpleContainer c); /*********************************************************************************************************************/ /** * test on calling class functions from within JNI calls. The functions get or set the variables so their output can directly be checked. */ private void testMemberFunctionAccess() { harness.checkPoint("Direct access function <primitive int> via native calls"); //integer ourInt = 1302; harness.check(getInverseInteger(), -1302); setInverseInteger(1303); harness.check(ourInt, -1303); harness.checkPoint("Direct access function <String> via native calls"); //string String teststring = "Albert I"; String inversestring = inverse(teststring); ourString= teststring; harness.check(getInverseString(), inversestring); teststring = "Leopold III"; inversestring = inverse(teststring); setInverseString(teststring); harness.check (ourString, inversestring); harness.checkPoint("Direct access function <array> via native calls"); // boolean array boolean[] testarray = buildBoolArray(false, true, false); boolean[] inversearray = inverse(testarray); ourArray = testarray; checkBoolArray(getInverseArray(), inversearray, harness); testarray = buildBoolArray(false, false, true); inversearray = inverse(testarray); setInverseArray(testarray); checkBoolArray(ourArray, inversearray, harness); harness.checkPoint("Direct access function <class SimpleContainer> via native calls"); // simple container SimpleContainer testcontainer = buildSimpleContainer(502, "Clara", buildBoolArray(false, false, false)); SimpleContainer inversecontainer = inverse(testcontainer); ourSimpleContainer = testcontainer; testcontainer = getInverseSimpleContainer(); compareSimpleContainer(testcontainer, inversecontainer, harness); testcontainer = buildSimpleContainer(503, "Dieter", buildBoolArray(true, true, true)); inversecontainer = inverse(testcontainer); setInverseSimpleContainer(testcontainer); compareSimpleContainer(ourSimpleContainer, inversecontainer, harness); } /** natives for the member access functions: (call the 'inverse'-functions on the member variable mentioned to get or set the 'inverse' of the values */ /// call getIntegerInverse and return its value private native int getInverseInteger(); /// call setIntegerInverse with the given value private native void setInverseInteger(int i); /// call getStringInverse and return its value private native String getInverseString (); /// call setStringInverse with the given value private native void setInverseString (String s); /// call getArrayInverse and return its value private native boolean[] getInverseArray(); /// call setArrayInverse with the given value private native void setInverseArray(boolean[] bx); /// call getContainerInverse and return its value private native SimpleContainer getInverseSimpleContainer(); /// call setContainerInverse with the given value private native void setInverseSimpleContainer(SimpleContainer c); /** the 'inverse' functions to be called by the JNI interfaces: <br> => return the 'inverse' of the value of variable mentioned, <br> => assign the variable to the 'inverse' of the given value */ /// return the inverse of outInt private int getIntegerInverse() {return inverse(ourInt); } /// set ourInt to the inverse of the given value private void setIntegerInverse(int i) {ourInt = inverse(i); } /// return the inverse of outString private String getStringInverse() {return inverse(ourString);} /// set ourString to the inverse of the given value private void setStringInverse(String s) {ourString = inverse(s); } /// return the inverse of outArray private boolean[] getArrayInverse() {return inverse(ourArray); } /// set ourArray to the inverse of the given value private void setArrayInverse(boolean[] bx) {ourArray = inverse(bx); } /// return the inverse of outContainer private SimpleContainer getContainerInverse() {return inverse(ourSimpleContainer); } /// set ourContainer to the inverse of the given value private void setContainerInverse(SimpleContainer c) {ourSimpleContainer = inverse(c); }; /*********************************************************************************************************************/ /** * test on calling static class functions from inside JNI function calls */ private void testStaticFunctionAccess() { //integer harness.checkPoint("Direct static function on <primitive int> via native calls"); int testint = 1304; harness.check(getInverse(testint), inverse(testint)); //string harness.checkPoint("Direct static function on <String> via native calls"); String teststring = "Boudewijn I"; harness.check(getInverse(teststring), inverse(teststring)); // boolean array harness.checkPoint("Direct static function on <array> via native calls"); boolean[] testarray = buildBoolArray(true, true, false); checkBoolArray(getInverse(testarray), inverse(testarray), harness); // simple container harness.checkPoint("Direct static function on <class SimpleContainer> via native calls"); SimpleContainer testcontainer = buildSimpleContainer(504, "Emil", buildBoolArray(true, false, true)); compareSimpleContainer(getInverse(testcontainer), inverse(testcontainer), harness); } /** natives for the static access functions: call the 'inverse'-functions on the member variable mentioned and pass the return value if needed */ ///call inverse(int) from within JNI and return the result private native int getInverse(int i); ///call inverse(string) from within JNI and return the result private native String getInverse(String s); ///call inverse(array) from within JNI and return the result private native boolean[] getInverse(boolean[] bx); ///call inverse(container) from within JNI and return the result private native SimpleContainer getInverse(SimpleContainer c); /** the 'static' functions to be called by the JNI interfaces: return the 'inverse' of the given integer, string, array or container value */ ///returns -i static int inverse(int i) {return (0-i);} /* static byte inverse(byte i) {return (byte)(0-i);} static short inverse(short i) {return (short)(0-i);} static char inverse(char i) {return (char)(0-i);} static long inverse(long i) {return (0-i);} static double inverse(double i) {return (double)(0-i);} static float inverse(float i) {return (float)(0-i);} static boolean inverse(boolean i) {return (boolean)(0-i);} */ /// return string circled first character moved to the end static String inverse(String s) {return (s.substring(1) + s.substring(0,1));} /// return 3-boolean array all values inverted static boolean[] inverse(boolean[] bx) { boolean[] bi = { !bx[0], !bx[1], !bx[2]}; return bi; } /// return simplecontainer with inverted integer, string,arrray and static int value static SimpleContainer inverse(SimpleContainer c){ SimpleContainer ci = new SimpleContainer(); ci.number = inverse(c.number); ci.name = inverse(c.name); ci.preferences = inverse(c.preferences); return ci; } /*********************************************************************************************************************/ /** * test on accessing the curent class function and the 'super' function it overrides fromwithin jni calls */ private void testSuperclassAccess() { /**we'll define two instances of the function <protected byte getClassVersion()> returning (byte)1 in the base class and (byte)2 in the derived one. Then we'll call two native functions that respectingly call the base and the derived function */ byte baseversion = getBaseVersion(); byte currentversion = getCurrentVersion(); harness.check(currentversion == getVersion(), "Derived function returns "+currentversion+" instead of expected "+getVersion() ); harness.check(baseversion != getVersion(), "Base function call returns derived functin output "+getVersion() ); harness.check(baseversion == super.getVersion(),"Base function call returns "+baseversion+" instead of expected"+super.getVersion() ); } /// call the base classes 'super'function of getVersion() fromwithin jni private native byte getBaseVersion(); /// call the current function getVersion fromwithin jni private native byte getCurrentVersion(); /// derived function : returns (byte)2 whereas the base-class's function returnes (byte)1 protected byte getVersion() {return((byte)2); } /*********************************************************************************************************************/ /** * TestRunner interface : perform the tests described and pass the results to the testharness */ public void test (TestHarness newharness) { harness = newharness; harness.setclass("JNI member & function access"); SimpleContainer.common = -1492; testMemberVariableAccess(); testMemberFunctionAccess(); testStaticFunctionAccess(); testSuperclassAccess(); } }