vtkX3DExporterJavaHelper.cxx 7.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
/*=========================================================================

  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 <jni.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkX3DExporterJavaHelper);

//----------------------------------------------------------------------------
void vtkX3DExporterJavaHelper::SetFastInfosetJarLocation(const char* location)
{
  if ( vtkX3DExporterJavaHelper::FastInfosetJarLocation != 0 )
    {
    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,NULL);
    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,
      "<init>", "([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;
119
    std::string str;
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    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, "<init>", "(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,NULL);
  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;
}