00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef Fennel_JniProxy_Included
00025 #define Fennel_JniProxy_Included
00026
00027 #include "fennel/farrago/JniUtil.h"
00028
00029 #include <map>
00030
00031 FENNEL_BEGIN_NAMESPACE
00032
00033
00034
00035
00046 class FENNEL_FARRAGO_EXPORT JniProxy
00047 {
00048 protected:
00049
00050 std::string constructString(jobject jStringObj)
00051 {
00052 jstring jString = reinterpret_cast<jstring>(jStringObj);
00053 return JniUtil::toStdString(pEnv,jString);
00054 }
00055
00056
00057 jstring constructJavaString(const std::string &stringObj)
00058 {
00059 return pEnv->NewStringUTF(stringObj.c_str());
00060 }
00061
00062 int32_t int32Value(jobject jIntegerObj)
00063 {
00064 return pEnv->CallIntMethod(jIntegerObj, JniUtil::methIntValue);
00065 }
00066
00067 jobject constructJavaInteger(const int32_t &value)
00068 {
00069 return pEnv->CallStaticObjectMethod(
00070 JniUtil::classInteger,
00071 JniUtil::methIntegerValueOf,
00072 static_cast<jint>(value));
00073 }
00074
00075 int64_t int64Value(jobject jLongObj)
00076 {
00077 return pEnv->CallLongMethod(jLongObj, JniUtil::methLongValue);
00078 }
00079
00080 jobject constructJavaLong(const int64_t &value)
00081 {
00082 return pEnv->CallStaticObjectMethod(
00083 JniUtil::classLong,
00084 JniUtil::methLongValueOf,
00085 static_cast<jlong>(value));
00086 }
00087
00088 int16_t int16Value(jobject jShortObj)
00089 {
00090 return pEnv->CallShortMethod(jShortObj, JniUtil::methShortValue);
00091 }
00092
00093 jobject constructJavaShort(const int16_t &value)
00094 {
00095 return pEnv->CallStaticObjectMethod(
00096 JniUtil::classShort,
00097 JniUtil::methShortValueOf,
00098 static_cast<jshort>(value));
00099 }
00100
00101 double doubleValue(jobject jDoubleObj)
00102 {
00103 return pEnv->CallDoubleMethod(jDoubleObj, JniUtil::methDoubleValue);
00104 }
00105
00106 jobject constructJavaDouble(const double &value)
00107 {
00108 return pEnv->CallStaticObjectMethod(
00109 JniUtil::classDouble,
00110 JniUtil::methDoubleValueOf,
00111 static_cast<jdouble>(value));
00112 }
00113
00114 float floatValue(jobject jFloatObj)
00115 {
00116 return pEnv->CallFloatMethod(jFloatObj, JniUtil::methFloatValue);
00117 }
00118
00119 jobject constructJavaFloat(const float &value)
00120 {
00121 return pEnv->CallStaticObjectMethod(
00122 JniUtil::classFloat,
00123 JniUtil::methFloatValueOf,
00124 static_cast<jfloat>(value));
00125 }
00126
00127 bool boolValue(jobject jBooleanObj)
00128 {
00129 return pEnv->CallBooleanMethod(jBooleanObj, JniUtil::methBooleanValue);
00130 }
00131
00132 jobject constructJavaBoolean(const bool &value)
00133 {
00134 return pEnv->CallStaticObjectMethod(
00135 JniUtil::classBoolean,
00136 JniUtil::methBooleanValueOf,
00137 static_cast<jboolean>(value));
00138 }
00139
00140 public:
00144 JniEnvRef pEnv;
00145
00149 jobject jObject;
00150
00151 explicit JniProxy();
00152
00153 virtual ~JniProxy();
00154
00162 void init(JniEnvRef pEnv,jobject jObject);
00163
00167 std::string getInterfaceName()
00168 {
00169 jclass jClass = pEnv->GetObjectClass(jObject);
00170 return JniUtil::getFirstPublicInterfaceName(jClass);
00171 }
00172 };
00173
00188 template <class T>
00189 class JniProxyIter : public boost::shared_ptr<T>
00190 {
00191 public:
00192 jobject jIter;
00193
00194 explicit JniProxyIter()
00195 : boost::shared_ptr<T>(new T)
00196 {
00197
00198 jIter = NULL;
00199 }
00200
00201 void operator ++ ()
00202 {
00203 assert(jIter);
00204 boost::shared_ptr<T>::get()->jObject =
00205 JniUtil::getNextFromIter(boost::shared_ptr<T>::get()->pEnv,jIter);
00206 if (!(boost::shared_ptr<T>::get()->jObject)) {
00207
00208 boost::shared_ptr<T>::reset();
00209 }
00210 }
00211 };
00212
00217 class FENNEL_FARRAGO_EXPORT JniProxyVisitor
00218 {
00219 public:
00220 virtual ~JniProxyVisitor();
00221
00227 virtual void unhandledVisit();
00228 };
00229
00230 class FENNEL_FARRAGO_EXPORT JniProxyVisitTableBase
00231 {
00232 public:
00236 struct VisitorMethod
00237 {
00238 virtual ~VisitorMethod()
00239 {
00240 }
00241
00242 virtual void execute(JniProxyVisitor &visitor,JniProxy &) = 0;
00243 };
00244
00248 typedef boost::shared_ptr<VisitorMethod> SharedVisitorMethod;
00249
00254 typedef std::map<std::string,SharedVisitorMethod> MethodMap;
00255
00259 MethodMap methodMap;
00260
00268 void addMethod(jclass jClass,SharedVisitorMethod pMethod)
00269 {
00270 assert(pMethod);
00271 methodMap[JniUtil::getClassName(jClass)] = pMethod;
00272 }
00273
00274
00284 void accept(JniProxyVisitor &visitor,JniProxy &proxy)
00285 {
00286
00287
00288
00289 std::string className = proxy.getInterfaceName();
00290 SharedVisitorMethod pMethod = methodMap[className];
00291 if (!pMethod) {
00292 throw std::logic_error(
00293 std::string("error: unknown method for proxy class '") +
00294 className + "'");
00295 }
00296 pMethod->execute(visitor,proxy);
00297 }
00298 };
00299
00311 template <class Visitor>
00312 class JniProxyVisitTable : public JniProxyVisitTableBase
00313 {
00314 public:
00319 template<class ProxyImpl>
00320 struct VisitorMethodImpl : public VisitorMethod
00321 {
00322 virtual void execute(JniProxyVisitor &visitor,JniProxy &proxy)
00323 {
00324
00325
00326
00327
00328
00329 ProxyImpl proxyImpl;
00330 proxyImpl.init(proxy.pEnv,proxy.jObject);
00331
00332 Visitor &visitorImpl = dynamic_cast<Visitor &>(visitor);
00333 visitorImpl.visit(proxyImpl);
00334 }
00335 };
00336 };
00337
00338 FENNEL_END_NAMESPACE
00339
00340 #endif
00341
00342