| /* -*-C++-*- |
| ********************************************************************** |
| * |
| * File: LmRoutineJava.cpp |
| * Description: |
| * |
| * Created: 08/22/2003 |
| * Language: C++ |
| * |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| **********************************************************************/ |
| |
| |
| #include "lmjni.h" |
| #include "ComRtUtils.h" |
| #include "LmRoutineJava.h" |
| #include "LmJavaExceptionReporter.h" |
| #include "LmAssert.h" |
| #include "LmUtility.h" |
| #include "ComObjectName.h" |
| #include "ComSqlId.h" |
| |
| ////////////////////////////////////////////////////////////////////// |
| // |
| // Class LmRoutineJava |
| // If we get errors in creating this object, fill diagsArea and return |
| // error. Caller is responsbile to cleanup by calling destructor. |
| // |
| ////////////////////////////////////////////////////////////////////// |
| LmRoutineJava::LmRoutineJava( |
| const char *sqlName, |
| const char *externalName, |
| const char *librarySqlName, |
| ComUInt32 numSqlParam, |
| LmParameter *returnValue, |
| ComUInt32 maxResultSets, |
| char *routineSig, |
| ComRoutineParamStyle paramStyle, |
| ComRoutineTransactionAttributes transactionAttrs, |
| ComRoutineSQLAccess sqlAccessMode, |
| ComRoutineExternalSecurity externalSecurity, |
| Int32 routineOwnerId, |
| const char *parentQid, |
| ComUInt32 inputRowLen, |
| ComUInt32 outputRowLen, |
| const char *currentUserName, |
| const char *sessionUserName, |
| LmParameter *parameters, |
| LmLanguageManagerJava *lm, |
| LmHandle routine, |
| LmContainer *container, |
| ComDiagsArea *da) |
| : LmRoutine(container, routine, sqlName, externalName, librarySqlName, |
| numSqlParam, maxResultSets, |
| COM_LANGUAGE_JAVA, paramStyle, transactionAttrs, sqlAccessMode, |
| externalSecurity, |
| routineOwnerId, |
| parentQid, inputRowLen, outputRowLen, |
| currentUserName, sessionUserName, |
| parameters, lm), |
| javaParams_(NULL), |
| retType_(LmJavaType::JT_NONE), |
| defaultCatSch_(FALSE), |
| connectionList_(collHeap()) |
| { |
| JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_; |
| |
| setUdrForJavaMain((str_cmp_ne(externalName, "main") == 0) ? TRUE : FALSE); |
| |
| // this is the internal SPJ used in CREATE PROCEDURE |
| // mark it for examining Java exceptions to determine SQL diagnostics later |
| |
| if ((str_cmp_ne(container->getName(), "org.trafodion.sql.udr.LmUtility") == 0) && |
| (str_cmp_ne(externalName, "validateMethod") == 0)) |
| setIsInternalSPJ(TRUE); |
| else |
| setIsInternalSPJ(FALSE); |
| |
| if (paramStyle == COM_STYLE_JAVA_OBJ) |
| return; |
| |
| // Get method return type. |
| retType_ = LmJavaType(returnValue).getType(); |
| |
| // |
| // Now setup the parameters to the method. |
| // |
| // UDR-MAIN gets special treatment |
| // |
| // Allocate only one jvalue because main() takes only |
| // one parameter of type String[]. |
| // |
| // Then create java.lang.String array of size numSqlParam_ |
| // which equals to numSqlParam |
| // |
| if (isUdrForJavaMain()) |
| { |
| numParamsInSig_ = 1; // Number of parameters in Java main method |
| |
| javaParams_ = new (collHeap()) jvalue[1]; |
| memset((char*)javaParams_, 0, sizeof(jvalue)); |
| |
| ((jvalue *)javaParams_)->l = jni->NewObjectArray((jsize)numSqlParam_, |
| (jclass)lm->stringClass_, |
| NULL); |
| if (((jvalue *)javaParams_)->l == NULL) |
| { |
| *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY); |
| getLM()->exceptionReporter_->checkJVMException(da, 0); |
| } |
| |
| return; |
| } |
| |
| // For a Java main method we would have already returned and |
| // do not get this far. Logic in the rest of this method does |
| // not need to consider main methods as a special case. |
| |
| // Get the total number of parameters present in the method |
| // signature. |
| LmJavaSignature lmSig(routineSig, collHeap()); |
| Int32 result = lmSig.getParamCount(); |
| if( result < (Int32)numSqlParam_ ) { |
| *da << DgSqlCode(-LME_INTERNAL_ERROR) |
| << DgString0(": LmJavaSignature::getParamCount() returned an invalid value."); |
| return; |
| } |
| numParamsInSig_ = (ComUInt32)result; |
| |
| // |
| // Setup Paramters for Non-main methods |
| // |
| // Allocate Java method parameter array for SQL |
| // and result set params |
| if (numParamsInSig_ > 0) |
| { |
| javaParams_ = new (collHeap()) jvalue[numParamsInSig_]; |
| memset((char*)javaParams_, 0, numParamsInSig_ * sizeof(jvalue)); |
| } |
| |
| |
| // Allocate a 1-element array for each OUT/INOUT mode parameter. |
| jvalue *jval = (jvalue*)javaParams_; |
| |
| Int32 i = 0; |
| for (i = 0; i < (Int32)numSqlParam_; i++) |
| { |
| LmParameter &p = lmParams_[i]; |
| |
| if (p.direction() == COM_INPUT_COLUMN) |
| continue; |
| |
| jobjectArray ja = NULL; |
| |
| switch (LmJavaType(&p).getType()) |
| { |
| case LmJavaType::JT_SHORT: |
| jval[i].l = (jobject)jni->NewShortArray(1); |
| break; |
| |
| case LmJavaType::JT_INT: |
| jval[i].l = (jobject)jni->NewIntArray(1); |
| break; |
| |
| case LmJavaType::JT_LONG: |
| jval[i].l = (jobject)jni->NewLongArray(1); |
| break; |
| |
| case LmJavaType::JT_FLOAT: |
| jval[i].l = (jobject)jni->NewFloatArray(1); |
| break; |
| |
| case LmJavaType::JT_DOUBLE: |
| jval[i].l = (jobject)jni->NewDoubleArray(1); |
| break; |
| |
| case LmJavaType::JT_LANG_STRING: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->stringClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_MATH_BIGDEC: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->bigdecClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_SQL_DATE: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->dateClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_SQL_TIME: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->timeClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_SQL_TIMESTAMP: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->stampClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_LANG_INTEGER: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->intClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_LANG_LONG: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->longClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_LANG_FLOAT: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->floatClass_, NULL); |
| break; |
| |
| case LmJavaType::JT_LANG_DOUBLE: |
| ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->doubleClass_, NULL); |
| break; |
| |
| default: |
| char str[LMJ_ERR_SIZE_256]; |
| sprintf (str, |
| ": Unknown parameter type at parameter position %d.", |
| i+1); |
| *da << DgSqlCode(-LME_INTERNAL_ERROR) |
| << DgString0(str); |
| return; |
| }// switch() |
| |
| if (ja != NULL) |
| jval[i].l = ja; |
| |
| if (jval[i].l == NULL) |
| { |
| // OutOfMemory is the only error that could happen here. |
| *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY); |
| |
| getLM()->exceptionReporter_->checkJVMException(da, 0); |
| return; |
| } |
| |
| } // for() |
| |
| // Allocate a 1-element array for each result set parameter. |
| for (i = (Int32)numSqlParam_; i < (Int32)numParamsInSig_; i++) |
| { |
| jobjectArray ja = NULL; |
| |
| ja = jni->NewObjectArray(1, (jclass)lm->resultSetClass_, NULL); |
| if (ja != NULL) |
| jval[i].l = ja; |
| |
| if (jval[i].l == NULL) |
| { |
| // OutOfMemory is the only error that could happen here. |
| *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY); |
| |
| getLM()->exceptionReporter_->checkJVMException(da, 0); |
| return; |
| } |
| } |
| |
| return; |
| } |
| |
| LmRoutineJava::~LmRoutineJava() |
| { |
| JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_; |
| jvalue *jval = (jvalue*)javaParams_; |
| |
| // Free LmResultSet objects |
| // This will also close the Java result set objects |
| // and the Java connections that they are part of. |
| cleanupResultSets(); |
| |
| // Free LmConnection objects for default connections |
| // Closes any open default connections that do not have |
| // result sets associated with them |
| closeDefConnWithNoRS(); |
| |
| connectionList_.clear(); |
| |
| // Release array refs for params, indicated |
| // by non-null object. |
| for (Int32 i = 0; i < (Int32)numParamsInSig_; i++) |
| { |
| if (jval[i].l != NULL) |
| jni->DeleteLocalRef(jval[i].l); |
| } |
| |
| // Free the Java parameter array |
| if (javaParams_) |
| NADELETEBASIC((jvalue *)javaParams_, collHeap()); |
| } |
| |
| // Generates a new authentication token for Definer Rights SPJ usage. |
| // The format of the token fields is as follows: |
| // o \5, \6 - identifies that it is a DR SPJ token - 2 bytes |
| // o Definer user ID - routine owner Id - 7 bytes - leading zero padded |
| // o UDR server Process Node id - 3 bytes - leading zero padded |
| // o UDR server Process Pid - 6 bytes - leading zero padded |
| // o Invoker password/token passed from executor - 68 bytes |
| const int DR_SPJ_TOKEN_PREFIX_LEN = 2; |
| const int DR_SPJ_TOKEN_USER_ID_LEN = 7; |
| const int DR_SPJ_TOKEN_NODE_LEN = ComSqlId::CPU_LEN; // 3 |
| const int DR_SPJ_TOKEN_PID_LEN = ComSqlId::PIN_LEN; // 6 |
| const int DR_SPJ_TOKEN_INVOKER_TOKEN_LEN = 68; |
| const int DR_SPJ_TOKEN_SEPARATOR_LEN = 1; |
| const int DR_SPJ_TOKEN_LEN = |
| DR_SPJ_TOKEN_PREFIX_LEN + |
| DR_SPJ_TOKEN_SEPARATOR_LEN + |
| DR_SPJ_TOKEN_USER_ID_LEN + |
| DR_SPJ_TOKEN_SEPARATOR_LEN + |
| DR_SPJ_TOKEN_NODE_LEN + |
| DR_SPJ_TOKEN_SEPARATOR_LEN + |
| DR_SPJ_TOKEN_PID_LEN + |
| DR_SPJ_TOKEN_SEPARATOR_LEN + |
| DR_SPJ_TOKEN_INVOKER_TOKEN_LEN; |
| |
| LmResult LmRoutineJava::handleFinalCall(ComDiagsArea *diagsArea) |
| { |
| // this method is not yet used for Java |
| return LM_OK; |
| } |
| |
| LmResult LmRoutineJava::generateDefAuthToken(char *defAuthToken, ComDiagsArea *da) |
| { |
| // Get the NODE, PID information for the UDR server process |
| const int MAX_PROGRAM_DIR_LEN = 1024; |
| char myProgramDir[MAX_PROGRAM_DIR_LEN+1]; |
| short myProcessType; |
| Int32 myNode; |
| char myNodeName[MAX_SEGMENT_NAME_LEN+1]; |
| Lng32 myNodeNum; |
| short myNodeNameLen = MAX_SEGMENT_NAME_LEN; |
| char myProcessName[PROCESSNAME_STRING_LEN]; |
| Int64 myProcessStartTime; |
| pid_t myPid; |
| Lng32 retStatus = ComRtGetProgramInfo(myProgramDir, MAX_PROGRAM_DIR_LEN, |
| myProcessType, |
| myNode, |
| myPid, |
| myNodeNum, |
| myNodeName, myNodeNameLen, |
| myProcessStartTime, |
| myProcessName); |
| if (retStatus) |
| { |
| char errStr[LMJ_ERR_SIZE_256]; |
| sprintf (errStr, ": Error returned from ComRtGetProgramInfo. Error is: %d.", retStatus); |
| *da << DgSqlCode(-LME_INTERNAL_ERROR) |
| << DgString0(errStr); |
| return LM_ERR; |
| } |
| |
| sprintf (defAuthToken, |
| "%s%s:%07d:%03u:%06u:%.68s", |
| "\005", "\006", |
| getRoutineOwnerId(), |
| myNode, |
| myPid, |
| getLM()->userPassword_ |
| ); |
| return LM_OK; |
| } |
| |
| |
| LmResult LmRoutineJava::invokeRoutine(void *inputRow, |
| void *outputRow, |
| ComDiagsArea *da) |
| { |
| // Delete the LmResultSet objects for re-invocations |
| // This will also close the Java result set objects |
| // and the Java connections that they are part of |
| cleanupResultSets(da); |
| |
| // This will close any default connections that do not have |
| // result sets associated with them |
| closeDefConnWithNoRS(da); |
| |
| // Cleanup the list maintained in LmUtlity.cpp file that will get |
| // populated with default connection objects that may get created |
| // during this routine's invocation. |
| lmUtilityInitConnList((JNIEnv*)getLM()->jniEnv_, (jmethodID)getLM()->connCloseId_); |
| |
| // Set the default catalog & schema as system properties. These |
| // values are then retrieved by LmSQLMXDriver class for setting |
| // it on a getConnection() call |
| if (getDefaultCatSchFlag()) |
| { |
| // Determine the catalog & schema values that will be in effect for |
| // this UDR. If the values are set globally(with catalog/schema |
| // props in CQD) they are used else the catalog/schema of |
| // the UDR are used. |
| const char *catalog = |
| (getLM()->sysCatalog_) ? getLM()->sysCatalog_ : udrCatalog_; |
| const char *schema = |
| (getLM()->sysSchema_) ? getLM()->sysSchema_ : udrSchema_; |
| |
| if (getLM()->setSystemProperty("sqlmx.udr.catalog", catalog, da) == LM_ERR) |
| return LM_ERR; |
| if (getLM()->setSystemProperty("sqlmx.udr.schema", schema, da) == LM_ERR) |
| return LM_ERR; |
| } |
| |
| const char *parentQid; |
| if ((parentQid = getParentQid()) == NULL) |
| parentQid = "NONE"; |
| if (getLM()->setSystemProperty("sqlmx.udr.parentQid", parentQid, da) == LM_ERR) |
| return LM_ERR; |
| // Set SQL access mode in LmUtility. This will be checked while SPJ |
| // is trying to make a JDBC connection. |
| lmUtilitySetSqlAccessMode(getSqlAccessMode()); |
| |
| // Set Transaction Attribute in LmUtility. This will be checked while SPJ |
| // is trying to join a transaction. |
| lmUtilitySetTransactionAttrs(getTransactionAttrs()); |
| |
| LmResult result = LM_OK; |
| |
| // Set the Definer Authentication Token as system property for |
| // Definer Rights SPJs. This value is then retrieved by LmSQLMXDriver class |
| // for setting the password property in getConnection() call. |
| if ( externalSecurity_ == COM_ROUTINE_EXTERNAL_SECURITY_DEFINER ) |
| { |
| char *defAuthToken = new (collHeap()) char[DR_SPJ_TOKEN_LEN + 1]; |
| result = generateDefAuthToken(defAuthToken, da); |
| if (result != LM_ERR) |
| result = getLM()->setSystemProperty("sqlmx.udr.defAuthToken", defAuthToken, da); |
| NADELETEBASIC(defAuthToken, collHeap()); |
| if (result == LM_ERR) |
| { |
| char errStr[LMJ_ERR_SIZE_256]; |
| sprintf (errStr, |
| ": Error returned from setting System Property: %s.", |
| "sqlmx.udr.defAuthToken"); |
| *da << DgSqlCode(-LME_INTERNAL_ERROR) |
| << DgString0(errStr); |
| return LM_ERR; |
| } |
| } |
| |
| lm_->setRoutineIsActive(TRUE); |
| |
| switch (retType_) |
| { |
| case LmJavaType::JT_VOID: |
| result = voidRoutine(outputRow, NULL); |
| break; |
| default: |
| // Other return types are not supported. In the future if we |
| // support routines with non-void return types we will need to |
| // add case blocks to this switch statement. |
| LM_ASSERT(0); |
| break; |
| } |
| |
| lm_->setRoutineIsActive(FALSE); |
| |
| // Reset the sqlmx.udr.defAuthToken system property for |
| // Definer Rights SPJs. |
| if ( externalSecurity_ == COM_ROUTINE_EXTERNAL_SECURITY_DEFINER ) |
| { |
| result = getLM()->clearSystemProperty("sqlmx.udr.defAuthToken", da); |
| if (result == LM_ERR) |
| { |
| char errStr[LMJ_ERR_SIZE_256]; |
| sprintf (errStr, |
| ": Error returned from Resetting System Property: %s.", |
| "sqlmx.udr.defAuthToken"); |
| *da << DgSqlCode(-LME_INTERNAL_ERROR) |
| << DgString0(errStr); |
| return LM_ERR; |
| } |
| } |
| |
| // Get the list containing the default connection objects |
| // from LmUtility.cpp and create a LmConnection object for |
| // each item in that list. |
| NAList<jobject> &connList = lmUtilityGetConnList(); |
| while(connList.entries()) |
| { |
| jobject conn = connList[0]; |
| LmConnection *lmConn = |
| new (collHeap()) LmConnection(getLM(), conn, |
| LmConnection::DEFAULT_CONN, getTransactionAttrs()); |
| |
| connectionList_.insert( lmConn ); |
| connList.removeAt(0); |
| } |
| |
| // reset SQL Access mode to COM_UNKNOWN_ROUTINE_SQL_ACCESS |
| lmUtilitySetSqlAccessMode(COM_UNKNOWN_ROUTINE_SQL_ACCESS); |
| |
| // reset Transaction Attributes to COM_UNKNOWN_ROUTINE_TRANSACTION_ATTRIBUTE |
| lmUtilitySetTransactionAttrs(COM_UNKNOWN_ROUTINE_TRANSACTION_ATTRIBUTE); |
| |
| return result; |
| } |
| |
| // Deletes the LmResultSet object at a given index. |
| void LmRoutineJava::cleanupLmResultSet(ComUInt32 index, |
| ComDiagsArea *diagsArea) |
| { |
| LM_ASSERT(index < resultSetList_.entries()); |
| |
| ((LmResultSetJava *)resultSetList_[index])->close( diagsArea ); |
| resultSetList_.removeAt(index); |
| } |
| |
| // Deletes the given LmResultSet object. |
| // Any error during the close will be reported in the |
| // diagsArea, if available. Asserts on an invalid pointer. |
| void LmRoutineJava::cleanupLmResultSet(LmResultSet *resultSet, |
| ComDiagsArea *diagsArea) |
| { |
| for (ComUInt32 index=0; index < resultSetList_.entries(); index++) |
| { |
| if (resultSetList_[index] == resultSet) |
| { |
| ((LmResultSetJava *)resultSetList_[index])->close(diagsArea); |
| resultSetList_.removeAt(index); |
| |
| return; |
| } |
| } |
| |
| // passed in resultset param is not a valid LmResultSet pointer. |
| LM_ASSERT(0); |
| } |
| |
| // Deletes all the LmResultSet objects from the resultSetList_ |
| // and empties the list. |
| void LmRoutineJava::cleanupResultSets(ComDiagsArea *diagsArea) |
| { |
| // Free LmResultSetJava objects |
| while( resultSetList_.entries() ) |
| cleanupLmResultSet( (ComUInt32) 0, diagsArea ); |
| |
| resultSetList_.clear(); |
| } |
| |
| // Closes any default connections in connectionList_, |
| // which do not have any result sets associated with |
| // them. |
| void LmRoutineJava::closeDefConnWithNoRS(ComDiagsArea *diagsArea) |
| { |
| ComUInt32 i = 0; |
| |
| while( i < connectionList_.entries() ) |
| { |
| LmConnection *lmConn = connectionList_[i]; |
| if( lmConn->connType() == LmConnection::DEFAULT_CONN && |
| lmConn->readyToClose() ) |
| { |
| lmConn->close( diagsArea ); |
| connectionList_.removeAt(i); |
| } |
| else |
| i++; // Increment only when LmConnection::close() is |
| // not called. |
| } |
| } |
| |
| // This method checks if the passed in java.sql.ResultSet object |
| // reference (newRS) is already part of a LmResultSetJava |
| // object in the resultSetList_. |
| // |
| // The parameter newRS should not be NULL. |
| // Returns TRUE if a match is found FALSE otherwise |
| NABoolean LmRoutineJava::isDuplicateRS( LmHandle newRS ) |
| { |
| JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_; |
| LmResultSetJava *lmRS; |
| jobject newRSRef = (jobject)newRS; |
| ComUInt32 indx; |
| |
| LM_ASSERT(newRS != NULL); |
| |
| for (indx = 0; indx < resultSetList_.entries(); indx++) |
| { |
| lmRS = (LmResultSetJava *)resultSetList_[indx]; |
| |
| // IsSameObject() JNI call compares the object references |
| // of it's parameters |
| if (jni->IsSameObject( (jobject)lmRS->getResultSet(), newRSRef )) |
| return TRUE; |
| |
| } // End for loop |
| |
| return FALSE; |
| } |
| |
| // This method creates a LmResultSetJava object for the |
| // passed in java.sql.ResultSet object (newRS) and inserts |
| // it into resultSetList_. |
| // |
| // Parameters: |
| // newRS - A java.sql.ResultSet object |
| // paramPos - The position (1-based) of newRS |
| // in the Java method signature. |
| // da - ComDiagsArea object to report any errors. |
| // This object should not be NULL. |
| LmResult LmRoutineJava::populateResultSetInfo(LmHandle newRS, Int32 paramPos, |
| ComDiagsArea *da) |
| { |
| LmResult result = LM_OK; |
| jobject newRSRef = (jobject)newRS; |
| |
| LM_ASSERT(da != NULL); |
| |
| // SPJ method can return same java.sql.ResultSet object in |
| // multiple OUT params but we ignore such duplicates. |
| // We also ignore a NULL java.sql.ResultSet object. |
| if( newRSRef == NULL || isDuplicateRS( newRSRef )) |
| return result; |
| |
| LmResultSetJava::LmResultSetInfoStatus rsInfoStatus; |
| |
| LmResultSetJava *newLmRS = |
| new (collHeap()) LmResultSetJava( getLM(), |
| (LmHandle)newRSRef, |
| paramPos, |
| getNameForDiags(), |
| rsInfoStatus, |
| connectionList_, |
| da ); |
| |
| // If the constructor returned a success status then insert |
| // the newLmRS object into resultSetList_ otherwise delete it. |
| if( rsInfoStatus == LmResultSetJava::RS_INFO_OK ) { |
| |
| // Order the objects inserted in the resultSetList_ based on |
| // the order in which the result set cursors were opened. |
| ComUInt32 i; |
| LmResultSetJava *lmRS; |
| for( i = 0; i < resultSetList_.entries(); i++ ) |
| { |
| lmRS = (LmResultSetJava *)resultSetList_[i]; |
| if( newLmRS->rsCounter_ < lmRS->rsCounter_ ) |
| break; |
| } |
| resultSetList_.insertAt( i, newLmRS ); |
| } |
| else { |
| delete newLmRS; |
| newLmRS = NULL; |
| |
| // Ignore closed result sets |
| if( rsInfoStatus == LmResultSetJava::RS_INFO_CLOSED ) |
| result = LM_OK; |
| else |
| result = LM_ERR; |
| } |
| |
| return result; |
| } |
| |
| // Deletes the LmResultSetJava objects in resultSetList_ |
| // which are over and above the routine's decalred max result set value. |
| void LmRoutineJava::deleteLmResultSetsOverMax(ComDiagsArea *diagsArea) |
| { |
| ComUInt32 toDelete = 0; |
| |
| if( resultSetList_.entries() > maxResultSets_ ) |
| toDelete = resultSetList_.entries() - maxResultSets_; |
| |
| while( toDelete-- ) |
| cleanupLmResultSet( maxResultSets_, diagsArea ); |
| |
| return; |
| } |
| |
| // check validity of the object after calling the constructor |
| ComBoolean LmRoutineJava::isValid() const |
| { |
| if (retType_ > LmJavaType::JT_NONE && |
| retType_ <= LmJavaType::JT_LAST) |
| return TRUE; |
| return FALSE; |
| } |
| |
| ////////////////////////////////////////////////////////////////////// |
| // voidRoutine: invoke a static Java method that returns void |
| ////////////////////////////////////////////////////////////////////// |
| LmResult LmRoutineJava::voidRoutine(void *dataPtr, LmParameter *) |
| { |
| JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_; |
| |
| jni->CallStaticVoidMethodA((jclass)getContainerHandle(), |
| (jmethodID)routine_, |
| (jvalue*)javaParams_); |
| return LM_OK; |
| } |