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