JniProxy.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/farrago/JniProxy.h#15 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // This file contains the generic support for proxies generated by
00034 // net.sf.farrago.fennel.ProxyGen.
00035 
00046 class FENNEL_FARRAGO_EXPORT JniProxy
00047 {
00048 protected:
00049     // helper for methods which return strings
00050     std::string constructString(jobject jStringObj)
00051     {
00052         jstring jString = reinterpret_cast<jstring>(jStringObj);
00053         return JniUtil::toStdString(pEnv,jString);
00054     }
00055 
00056     // helper for setters which take strings (returns local JNI reference)
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         // by default, no iteration support
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             // iteration exhausted, so become singular
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         // NOTE:  it's OK to use operator [] here since it's an error to call
00287         // with the wrong proxy type, so in the non-error case we should always
00288         // find something
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             // This accomplishes an effective downcast by reinstantiating proxy
00325             // as the correct type.  The abstract proxy and the specific proxy
00326             // alias the same underlying Java object, but it's important to
00327             // realize that the proxies themselves don't share the same
00328             // identity.
00329             ProxyImpl proxyImpl;
00330             proxyImpl.init(proxy.pEnv,proxy.jObject);
00331             // This binds to the correct visit overload.
00332             Visitor &visitorImpl = dynamic_cast<Visitor &>(visitor);
00333             visitorImpl.visit(proxyImpl);
00334         }
00335     };
00336 };
00337 
00338 FENNEL_END_NAMESPACE
00339 
00340 #endif
00341 
00342 // End JniProxy.h

Generated on Mon Jun 22 04:00:19 2009 for Fennel by  doxygen 1.5.1