/*========================================================================= Program: Visualization Toolkit Module: vtkX3DExporterJavaHelper.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkX3DExporterJavaHelper.h" #include "vtkObjectFactory.h" #include //---------------------------------------------------------------------------- vtkStandardNewMacro(vtkX3DExporterJavaHelper); //---------------------------------------------------------------------------- void vtkX3DExporterJavaHelper::SetFastInfosetJarLocation(const char* location) { delete [] vtkX3DExporterJavaHelper::FastInfosetJarLocation; vtkX3DExporterJavaHelper::FastInfosetJarLocation = 0; if ( location ) { vtkX3DExporterJavaHelper::FastInfosetJarLocation = new char[ strlen(location) + 1 ]; strcpy(vtkX3DExporterJavaHelper::FastInfosetJarLocation, location); } } char* vtkX3DExporterJavaHelper::FastInfosetJarLocation = 0; //---------------------------------------------------------------------------- #define vtkX3DCheckJNIObject(str, className) \ if ( !className ) \ {\ cerr << "Cannot find required " << str << ": " << #className << endl; \ } //---------------------------------------------------------------------------- class vtkX3DExporterJavaHelperInternal { public: vtkX3DExporterJavaHelperInternal() : JavaVirtualMachine(0), JavaEnvironment(0), X3DBinaryConverterClass_Write(0), X3DBinaryConverterClass_Close(0), X3DBinaryConverterObject(0) { } JavaVM* JavaVirtualMachine; JNIEnv* JavaEnvironment; jmethodID X3DBinaryConverterClass_Write; jmethodID X3DBinaryConverterClass_Close; jobject X3DBinaryConverterObject; jcharArray ConvertToJChar(JNIEnv* env, const char* message) { const size_t len = strlen(message); jcharArray array = env->NewCharArray(len); jchar *jarray = env->GetCharArrayElements(array,nullptr); size_t cc; for ( cc = 0; cc < len; ++ cc ) { jarray[cc] = message[cc]; } env->ReleaseCharArrayElements(array,jarray,0); return array; } jobject CreateString(JNIEnv* env, const char* message) { jclass java_lang_String = env->FindClass("java/lang/String"); jmethodID java_lang_String_Constructor_From_Array = env->GetMethodID(java_lang_String, "", "([C)V"); jcharArray inputFileNameArray = this->ConvertToJChar(env, message); jobject inputFileNameString = env->NewObject( java_lang_String, java_lang_String_Constructor_From_Array, inputFileNameArray); env->DeleteLocalRef(inputFileNameArray); return inputFileNameString; } }; //---------------------------------------------------------------------------- vtkX3DExporterJavaHelper::vtkX3DExporterJavaHelper() { this->Internal = new vtkX3DExporterJavaHelperInternal; JavaVM* VMs; jsize numVMs = 0; jint status = JNI_GetCreatedJavaVMs(&VMs, 10, &numVMs); if ( numVMs > 0 ) { this->Internal->JavaVirtualMachine = VMs; status = this->Internal->JavaVirtualMachine->GetEnv( (void**)&this->Internal->JavaEnvironment, JNI_VERSION_1_2); if ( status != 0 ) { vtkErrorMacro("Cannot attach to the Java Virtual Machine"); delete this->Internal; return; } } if ( !this->Internal->JavaEnvironment ) { JavaVMInitArgs args; JavaVMOption options[1]; //status = JNI_GetDefaultJavaVMInitArgs(&vm_args); /* There is a new JNI_VERSION_1_4, but it doesn't add anything for the purposes of our example. */ args.version = JNI_VERSION_1_2; args.nOptions = 1; std::string str; if ( vtkX3DExporterJavaHelper::FastInfosetJarLocation ) { str = "-Djava.class.path="; str += vtkX3DExporterJavaHelper::FastInfosetJarLocation; } else { str = "-Djava.class.path=FastInfoset.jar"; } char* classPath = new char[str.size()+1]; strcpy(classPath, str.c_str()); options[0].optionString = classPath; args.options = options; args.ignoreUnrecognized = JNI_FALSE; jint res = JNI_CreateJavaVM(&this->Internal->JavaVirtualMachine, (void **)&this->Internal->JavaEnvironment, &args); delete [] classPath; if ( res != 0 ) { vtkErrorMacro("Cannot create VM: " << res); delete this->Internal; return; } } vtkX3DCheckJNIObject("VM", this->Internal->JavaEnvironment); } //---------------------------------------------------------------------------- vtkX3DExporterJavaHelper::~vtkX3DExporterJavaHelper() { if ( this->Internal ) { //this->Internal->JavaVirtualMachine->DestroyJavaVM(); delete this->Internal; } } //---------------------------------------------------------------------------- int vtkX3DExporterJavaHelper::OpenFile(const char* fileName) { if ( !this->Internal ) { return 0; } jclass x3dConverterClass = this->Internal->JavaEnvironment->FindClass("vtkX3DBinaryConverter"); vtkX3DCheckJNIObject("Class", x3dConverterClass); jmethodID constructorId = this->Internal->JavaEnvironment->GetMethodID( x3dConverterClass, "", "(Ljava/lang/String;)V"); vtkX3DCheckJNIObject("Constructor", constructorId); this->Internal->X3DBinaryConverterClass_Write = this->Internal->JavaEnvironment->GetMethodID( x3dConverterClass, "Write", "([B)V"); vtkX3DCheckJNIObject("Write Method", this->Internal->X3DBinaryConverterClass_Write); this->Internal->X3DBinaryConverterClass_Close = this->Internal->JavaEnvironment->GetMethodID( x3dConverterClass, "Close", "()V"); vtkX3DCheckJNIObject("Close Method", this->Internal->X3DBinaryConverterClass_Close); jobject outputFileName = this->Internal->CreateString(this->Internal->JavaEnvironment, fileName); vtkX3DCheckJNIObject("File Name String", outputFileName); this->Internal->X3DBinaryConverterObject = this->Internal->JavaEnvironment->NewObject( x3dConverterClass, constructorId, outputFileName); vtkX3DCheckJNIObject("X3D Converter Object", this->Internal->X3DBinaryConverterObject); return 1; } //---------------------------------------------------------------------------- int vtkX3DExporterJavaHelper::Write(const char* data, vtkIdType length) { if ( !this->Internal ) { return 0; } jbyteArray array = this->Internal->JavaEnvironment->NewByteArray(length); jbyte *jarray = this->Internal->JavaEnvironment->GetByteArrayElements(array,nullptr); vtkIdType cc; for ( cc = 0; cc < length; ++ cc ) { jarray[cc] = data[cc]; } this->Internal->JavaEnvironment->ReleaseByteArrayElements(array,jarray,0); this->Internal->JavaEnvironment->CallVoidMethod(this->Internal->X3DBinaryConverterObject, this->Internal->X3DBinaryConverterClass_Write, array); return 1; } //---------------------------------------------------------------------------- int vtkX3DExporterJavaHelper::Close() { if ( !this->Internal ) { return 0; } this->Internal->JavaEnvironment->CallVoidMethod(this->Internal->X3DBinaryConverterObject, this->Internal->X3DBinaryConverterClass_Close); return 1; }