See More

/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://eng.tada.se/osprojects/COPYRIGHT.html * * @author Thomas Hallgren */ #include #include #include "pljava/PgObject_priv.h" #include "pljava/type/String.h" static bool s_loopLock = false; static jclass s_Class_class = 0; static jmethodID s_Class_getName = 0; /* effectiveClassPath is set at initialization time (in Backend.c) */ const char* effectiveClassPath; void PgObject_free(PgObject object) { Finalizer finalizer = object->m_class->finalize; if(finalizer != 0) finalizer(object); pfree(object); } PgObject PgObjectClass_allocInstance(PgObjectClass clazz, MemoryContext ctx) { Size sz = clazz->instanceSize; PgObject infant = (PgObject)MemoryContextAlloc(ctx, sz); memset(infant, 0, sz); infant->m_class = clazz; return infant; } void PgObjectClass_init(PgObjectClass clazz, const char* name, Size instanceSize, Finalizer finalizer) { clazz->name = name; clazz->instanceSize = instanceSize; clazz->finalize = finalizer; } PgObjectClass PgObjectClass_create(const char* name, Size instanceSize, Finalizer finalizer) { PgObjectClass self = (PgObjectClass)MemoryContextAlloc(TopMemoryContext, sizeof(struct PgObjectClass_)); memset(self, 0, sizeof(struct PgObjectClass_)); PgObjectClass_init(self, name, instanceSize, finalizer); return self; } PgObjectClass PgObject_getClass(PgObject self) { return self->m_class; } const char* PgObjectClass_getName(PgObjectClass self) { return self->name; } void _PgObject_pureVirtualCalled(PgObject object) { ereport(ERROR, (errmsg("Pure virtual method called"))); } static char* PgObject_getClassName(jclass cls) { jstring jstr; char* tmp; if(s_Class_getName == 0) { if(s_loopLock) return ""; s_loopLock = true; s_Class_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Class")); s_Class_getName = PgObject_getJavaMethod(s_Class_class, "getName", "()Ljava/lang/String;"); s_loopLock = false; } jstr = (jstring)JNI_callObjectMethod(cls, s_Class_getName); tmp = String_createNTS(jstr); JNI_deleteLocalRef(jstr); return tmp; } void PgObject_throwMemberError(jclass cls, const char* memberName, const char* signature, bool isMethod, bool isStatic) { JNI_exceptionDescribe(); JNI_exceptionClear(); ereport(ERROR, ( errmsg("Unable to find%s %s %s.%s with signature %s", (isStatic ? " static" : ""), (isMethod ? "method" : "field"), PgObject_getClassName(cls), memberName, signature))); } jclass PgObject_getJavaClass(const char* className) { jclass cls = JNI_findClass(className); if(cls == 0) { if(JNI_exceptionCheck()) { JNI_exceptionDescribe(); JNI_exceptionClear(); } ereport(ERROR, ( errmsg("Unable to load class %s using CLASSPATH '%s'", className, effectiveClassPath == 0 ? "null" : effectiveClassPath))); } return cls; } void PgObject_registerNatives(const char* className, JNINativeMethod* methods) { jclass cls = PgObject_getJavaClass(className); PgObject_registerNatives2(cls, methods); JNI_deleteLocalRef(cls); } void PgObject_registerNatives2(jclass cls, JNINativeMethod* methods) { #ifndef GCJ jint nMethods = 0; JNINativeMethod* m = methods; while(m->name != 0) { m++; nMethods++; } if(JNI_registerNatives(cls, methods, nMethods) != 0) { JNI_exceptionDescribe(); JNI_exceptionClear(); ereport(ERROR, ( errmsg("Unable to register native methods"))); } #endif } jmethodID PgObject_getJavaMethod(jclass cls, const char* methodName, const char* signature) { jmethodID m = JNI_getMethodID(cls, methodName, signature); if(m == 0) PgObject_throwMemberError(cls, methodName, signature, true, false); return m; } jmethodID PgObject_getStaticJavaMethod(jclass cls, const char* methodName, const char* signature) { jmethodID m = JNI_getStaticMethodID(cls, methodName, signature); if(m == 0) PgObject_throwMemberError(cls, methodName, signature, true, true); return m; } jfieldID PgObject_getJavaField(jclass cls, const char* fieldName, const char* signature) { jfieldID m = JNI_getFieldID(cls, fieldName, signature); if(m == 0) PgObject_throwMemberError(cls, fieldName, signature, false, false); return m; } jfieldID PgObject_getStaticJavaField(jclass cls, const char* fieldName, const char* signature) { jfieldID m = JNI_getStaticFieldID(cls, fieldName, signature); if(m == 0) PgObject_throwMemberError(cls, fieldName, signature, false, true); return m; } HeapTuple PgObject_getValidTuple(int cacheId, Oid tupleId, const char* tupleType) { HeapTuple tuple = SearchSysCache(cacheId, ObjectIdGetDatum(tupleId), 0, 0, 0); if(!HeapTupleIsValid(tuple)) ereport(ERROR, (errmsg("cache lookup failed for %s %u", tupleType, tupleId))); return tuple; }