00001
00002
00003
00004
00005
00007 #include "stdafx.h"
00008 #include "ComHelp.h"
00009 #include "GMECOM.h"
00010 #include "ComponentConfig.h"
00011 #include "RawComponent.h"
00012 #include "ComponentDll.h"
00013
00014
00015 RawComponent::RawComponent()
00016 {
00017 m_javaVMDll = NULL;
00018 m_createJavaVM = NULL;
00019 m_env = NULL;
00020 m_jvm = NULL;
00021 }
00022
00023 RawComponent::~RawComponent()
00024 {
00025 unloadJavaVM();
00026 }
00027
00028 void RawComponent::loadJavaVM()
00029 {
00030 unloadJavaVM();
00031
00032 char classPath[2000];
00033 char memory[100];
00034 char memory_buf[200];
00035 char buf[2000];
00036 unsigned long bufSize;
00037 HKEY regkey;
00038 DWORD type;
00039
00040
00041 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\GME", 0, KEY_EXECUTE, ®key);
00042 type = REG_SZ;
00043 bufSize = 2000;
00044 if(RegQueryValueEx(regkey, "JavaClassPath", NULL, &type, (LPBYTE)classPath, &bufSize ) != ERROR_SUCCESS){
00045 AfxMessageBox("Cannot find JavaClassPath in registry under HKLM\\SOFTWARE\\GME");
00046 unloadJavaVM();
00047
00048 throw regkey;
00049 }
00050 classPath[bufSize] = '\0';
00051
00052 RegCloseKey(regkey);
00053
00054
00055 sprintf( memory, "" );
00056 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\GME", 0, KEY_EXECUTE, ®key);
00057 type = REG_SZ;
00058 bufSize = sizeof(memory) / sizeof(memory[0]);
00059 if (RegQueryValueEx(regkey, "JavaMemory", NULL, &type, (LPBYTE)memory, &bufSize) == ERROR_SUCCESS)
00060 memory[bufSize] = '\0';
00061 RegCloseKey(regkey);
00062
00063
00064 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java Runtime Environment", 0, KEY_EXECUTE, ®key);
00065 type = REG_SZ;
00066 bufSize = 2000;
00067 if (RegQueryValueEx(regkey, "CurrentVersion", NULL, &type, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS)
00068 buf[bufSize] = '\0';
00069 RegCloseKey(regkey);
00070 char javaVersionPath[2000];
00071 sprintf( javaVersionPath, "SOFTWARE\\JavaSoft\\Java Runtime Environment\\%s", buf );
00072 RegOpenKeyEx(HKEY_LOCAL_MACHINE, javaVersionPath, 0, KEY_EXECUTE, ®key);
00073 bufSize = 2000;
00074 type = REG_SZ;
00075 buf[0] = 0;
00076 if (RegQueryValueEx(regkey, "RuntimeLib", NULL, &type, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS)
00077 buf[bufSize] = '\0';
00078 RegCloseKey(regkey);
00079 if( strlen(buf)==0 )
00080 {
00081 AfxMessageBox("Error loading java. Cannot query jvm.dll path from registry. (Is Java installed?)");
00082 unloadJavaVM();
00083 throw regkey;
00084 }
00085
00086
00087 m_javaVMDll = LoadLibrary(buf);
00088 if(m_javaVMDll == NULL)
00089 {
00090 LPTSTR errorText = NULL;
00091
00092 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
00093 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00094 (LPTSTR)&errorText, 0, NULL);
00095
00096 if (NULL != errorText) {
00097 std::string err = "Error loading java. Cannot load jvm.dll: ";
00098 err += errorText;
00099 AfxMessageBox(err.c_str());
00100 LocalFree(errorText);
00101 } else {
00102 AfxMessageBox("Error loading java. Cannot find jvm.dll.");
00103 }
00104 unloadJavaVM();
00105 throw regkey;
00106 }
00107
00108
00109 m_createJavaVM = (P_JNI_CreateJavaVM) GetProcAddress(m_javaVMDll, "JNI_CreateJavaVM");
00110 m_getCreatedJavaVMs = (P_JNI_GetCreatedJavaVMs) GetProcAddress(m_javaVMDll, "JNI_GetCreatedJavaVMs");
00111 if(m_createJavaVM == NULL || m_getCreatedJavaVMs == NULL )
00112 {
00113 AfxMessageBox("Error loading java. Invalid jvm.dll.");
00114 unloadJavaVM();
00115 throw regkey;
00116 }
00117
00118
00119 jsize machineNum;
00120 jsize buflen = 1;
00121 JavaVMInitArgs args;
00122 JavaVMOption options[5];
00123 args.nOptions = 0;
00124
00125 std::string libraryPathStr;
00126 std::string classPathStr = std::string("-Djava.class.path=") + classPath;
00127 {
00128 char gme_root[MAX_PATH];
00129 size_t gme_root_size;
00130 if (getenv_s(&gme_root_size, gme_root, "GME_ROOT") == 0) {
00131 classPathStr += std::string(";") + gme_root + "\\SDK\\java\\gme.jar";
00132
00133 libraryPathStr = "-Djava.library.path";
00134 libraryPathStr += std::string("=") + gme_root + "\\bin";
00135 libraryPathStr += std::string(";") + gme_root + "\\SDK\\java\\native\\Jaut\\Release";
00136 libraryPathStr += std::string(";") + gme_root + "\\SDK\\java\\native\\Jaut\\Debug";
00137 options[args.nOptions].optionString = const_cast<char*>(libraryPathStr.c_str());
00138 args.nOptions++;
00139 }
00140 }
00141 options[args.nOptions].optionString = const_cast<char*>(classPathStr.c_str());
00142 args.nOptions++;
00143
00144 args.version = JNI_VERSION_1_2;
00145 if( strlen(memory) > 0 )
00146 {
00147 sprintf(memory_buf, "-Xmx%s", memory);
00148 options[args.nOptions].optionString = memory_buf;
00149 args.nOptions++;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 args.options = options;
00160 args.ignoreUnrecognized = JNI_FALSE;
00161
00162 int res = (*m_getCreatedJavaVMs)(&m_jvm,buflen,&machineNum);
00163 if( res == 0 && machineNum>0 )
00164 res = m_jvm->AttachCurrentThread((void **)&m_env,&args);
00165 else
00166 res = (*m_createJavaVM)(&m_jvm, (void**)&m_env, &args);
00167 if(res != 0)
00168 {
00169 char buf[200];
00170 sprintf(buf, "Error loading java. Cannot create java virtual machine. Error code: %d", res);
00171 AfxMessageBox(buf);
00172 unloadJavaVM();
00173 throw regkey;
00174 }
00175 }
00176
00177 void RawComponent::unloadJavaVM()
00178 {
00179 if(m_javaVMDll != NULL)
00180 {
00181 FreeLibrary(m_javaVMDll);
00182 m_javaVMDll = NULL;
00183 }
00184 m_createJavaVM = NULL;
00185 m_getCreatedJavaVMs = NULL;
00186 }
00187
00188
00189
00190
00191
00192 STDMETHODIMP RawComponent::Initialize(struct IMgaProject *)
00193 {
00194 return S_OK;
00195 }
00196
00197
00198
00199 STDMETHODIMP RawComponent::Invoke(IMgaProject* gme, IMgaFCOs *models, long param)
00200 {
00201 #ifdef SUPPORT_OLD_INVOKE
00202 CComPtr<IMgaFCO> focus;
00203 CComVariant parval = param;
00204 return InvokeEx(gme, focus, selected, parvar);
00205 #else
00206 if(interactive) {
00207 AfxMessageBox("This component does not support the obsolete invoke mechanism");
00208 }
00209 return E_MGA_NOT_SUPPORTED;
00210 #endif
00211 }
00212
00213
00214
00215
00216 STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project, IMgaFCO *currentobj,
00217 IMgaFCOs *selectedobjs, long param)
00218 {
00219 COMTRY
00220 {
00221 CComPtr<IMgaTerritory> terr;
00222 COMTHROW(project->CreateTerritory(NULL, &terr));
00223 COMTHROW(project->BeginTransaction(terr));
00224 try
00225 {
00226
00227 loadJavaVM();
00228
00229 CComponentApp * app = (CComponentApp*)AfxGetApp();
00230
00231 jthrowable exc;
00232
00233
00234 jclass entryClass = m_env->FindClass("org/isis/gme/bon/ComponentInvoker");
00235 exc = m_env->ExceptionOccurred();
00236 if (exc) {
00237 throw exc;
00238 }
00239
00240
00241 jmethodID entryMethod = m_env->GetStaticMethodID(entryClass, "invokeEx", "(Ljava/lang/String;Ljava/lang/String;IIII)V");
00242 exc = m_env->ExceptionOccurred();
00243 if (exc) {
00244 throw exc;
00245 }
00246
00247 m_env->CallStaticVoidMethod(entryClass, entryMethod,
00248 m_env->NewStringUTF(this->m_javaClassPath.c_str()),
00249 m_env->NewStringUTF(this->m_javaClass.c_str()), project, currentobj, selectedobjs, param);
00250 exc = m_env->ExceptionOccurred();
00251 if (exc) {
00252 throw exc;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 COMTHROW(project->CommitTransaction());
00264 }
00265 catch(jthrowable jexc){
00266 char buf[200];
00267 m_env->ExceptionClear();
00268 try{
00269 jclass throwableClass = m_env->FindClass("java/lang/Throwable");
00270 if (throwableClass == NULL) {
00271 throw;
00272 }
00273
00274 jmethodID msgMethod = m_env->GetMethodID(throwableClass,"toString","()Ljava/lang/String;");
00275 if (msgMethod == NULL) {
00276 throw;
00277 }
00278
00279 jthrowable exc;
00280 jstring msg = (jstring)m_env->CallObjectMethod(jexc,msgMethod);
00281 exc = m_env->ExceptionOccurred();
00282 if (exc) {
00283 throw exc;
00284 }
00285
00286 const char *str = m_env->GetStringUTFChars(msg, 0);
00287 sprintf(buf, "Java exception occurred at component invokation: %s", str);;
00288 m_env->ReleaseStringUTFChars(msg, str);
00289
00290
00291
00292
00293 AfxMessageBox(buf);
00294 }catch(...){
00295 m_env->ExceptionClear();
00296 AfxMessageBox("Java exception occurred at component invokation, the cause is unrecoverable.");
00297 }
00298
00299 project->AbortTransaction();
00300
00301 }
00302 catch(HKEY){
00303 project->AbortTransaction();
00304 }
00305 catch(...)
00306 {
00307 AfxMessageBox("Internal error while executing java interpreter.");
00308 project->AbortTransaction();
00309 throw;
00310 }
00311 }
00312 COMCATCH(;);
00313 }
00314
00315
00316
00317 STDMETHODIMP RawComponent::ObjectsInvokeEx( IMgaProject *project, IMgaObject *currentobj, IMgaObjects *selectedobjs, long param)
00318 {
00319 if(interactive) {
00320 AfxMessageBox("The ObjectsInvoke method is not implemented");
00321 }
00322 return E_MGA_NOT_SUPPORTED;
00323 }
00324
00325
00326
00327 STDMETHODIMP RawComponent::get_ComponentParameter(BSTR name, VARIANT *pVal)
00328 {
00329 return S_OK;
00330 }
00331
00332 STDMETHODIMP RawComponent::put_ComponentParameter(BSTR name, VARIANT newVal)
00333 {
00334 return S_OK;
00335 }
00336
00337
00338 #ifdef GME_ADDON
00339
00340
00341 STDMETHODIMP RawComponent::GlobalEvent(globalevent_enum event)
00342 {
00343 if(event == GLOBALEVENT_UNDO) {
00344 AfxMessageBox("UNDO!!");
00345 }
00346 return S_OK;
00347 }
00348
00349 STDMETHODIMP RawComponent::ObjectEvent(IMgaObject * obj, unsigned long eventmask, VARIANT v)
00350 {
00351 if(eventmask & OBJEVENT_CREATED) {
00352 CComBSTR objID;
00353 COMTHROW(obj->get_ID(&objID));
00354 AfxMessageBox( "Object created! ObjID: " + CString(objID));
00355 }
00356 return S_OK;
00357 }
00358
00359 #endif