[PPL-devel] [GIT] ppl/ppl(master): Added native methods toString() and setStringifier() to class Variable.
Enea Zaffanella
zaffanella at cs.unipr.it
Tue Aug 7 19:11:11 CEST 2012
Module: ppl/ppl
Branch: master
Commit: af3298eea9b68aaaada91f7d6af72d8d6520c215
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=af3298eea9b68aaaada91f7d6af72d8d6520c215
Author: Enea Zaffanella <zaffanella at cs.unipr.it>
Date: Tue Aug 7 19:06:57 2012 +0200
Added native methods toString() and setStringifier() to class Variable.
Implemented variable output function using the customizable stringifier.
---
interfaces/Java/jni/ppl_java_common.cc | 44 ++++++++++++++++++++
interfaces/Java/jni/ppl_java_common.defs.hh | 16 +++++++
interfaces/Java/jni/ppl_java_globals.cc | 42 +++++++++++++++++++
.../Java/parma_polyhedra_library/Makefile.am | 1 +
.../Java/parma_polyhedra_library/Variable.java | 25 +++++++++--
5 files changed, 123 insertions(+), 5 deletions(-)
diff --git a/interfaces/Java/jni/ppl_java_common.cc b/interfaces/Java/jni/ppl_java_common.cc
index b3447c3..d97c53c 100644
--- a/interfaces/Java/jni/ppl_java_common.cc
+++ b/interfaces/Java/jni/ppl_java_common.cc
@@ -34,6 +34,8 @@ Java_Class_Cache cached_classes;
Java_FMID_Cache cached_FMIDs;
Java_Class_Cache::Java_Class_Cache() {
+ // Java Virtual Machine pointer.
+ jvm = NULL;
// Non-PPL classes.
Boolean = NULL;
Integer = NULL;
@@ -75,6 +77,7 @@ Java_Class_Cache::Java_Class_Cache() {
PPL_Object = NULL;
Relation_Symbol = NULL;
Variable = NULL;
+ Variable_Stringifier = NULL;
Variables_Set = NULL;
}
@@ -93,6 +96,8 @@ Java_Class_Cache::init_cache(JNIEnv* env, jclass& field, const char* name) {
void
Java_Class_Cache::init_cache(JNIEnv* env) {
assert(env != NULL);
+ // Java Virtual Machine pointer.
+ env->GetJavaVM(&jvm);
// Non-PPL classes.
init_cache(env, Boolean, "java/lang/Boolean");
init_cache(env, Integer, "java/lang/Integer");
@@ -155,6 +160,8 @@ Java_Class_Cache::init_cache(JNIEnv* env) {
init_cache(env, PPL_Object, "parma_polyhedra_library/PPL_Object");
init_cache(env, Relation_Symbol, "parma_polyhedra_library/Relation_Symbol");
init_cache(env, Variable, "parma_polyhedra_library/Variable");
+ // NOTE: initialization of concrete Variable_Stringifier is responsibility
+ // of static (native) method Variable.setStringifier.
init_cache(env, Variables_Set, "parma_polyhedra_library/Variables_Set");
}
@@ -170,6 +177,8 @@ Java_Class_Cache::clear_cache(JNIEnv* env, jclass& field) {
void
Java_Class_Cache::clear_cache(JNIEnv* env) {
assert(env != NULL);
+ // Clearing the JVM pointer.
+ jvm = NULL;
// Non-PPL classes.
clear_cache(env, Boolean);
clear_cache(env, Integer);
@@ -209,6 +218,7 @@ Java_Class_Cache::clear_cache(JNIEnv* env) {
clear_cache(env, PPL_Object);
clear_cache(env, Relation_Symbol);
clear_cache(env, Variable);
+ clear_cache(env, Variable_Stringifier);
clear_cache(env, Variables_Set);
}
@@ -1195,6 +1205,40 @@ build_java_artificial_parameter
return ret;
}
+void
+Java_Variable_output_function(std::ostream& s, Variable v) {
+ // Use cached Java Virtual Machine pointer to retrieve JNI env.
+ JavaVM* jvm = cached_classes.jvm;
+ JNIEnv *env = 0;
+ jvm->AttachCurrentThread((void **)&env, NULL);
+ CHECK_EXCEPTION_ASSERT(env);
+ // Retrieve stringifier object.
+ jclass var_class = cached_classes.Variable;
+ jfieldID fID = cached_FMIDs.Variable_stringifier_ID;
+ jobject stringifier = env->GetStaticObjectField(var_class, fID);
+ CHECK_RESULT_THROW(env, stringifier);
+ // Use it to get the Java string for the variable.
+ jmethodID mID = cached_FMIDs.Variable_Stringifier_stringify_ID;
+#ifndef NDEBUG
+ {
+ // Dynamically retrieve stringifier class and use it to compute
+ // the corresponding method ID, so as to compare it with cached one.
+ jclass dyn_class = env->GetObjectClass(stringifier);
+ jmethodID dyn_mID = env->GetMethodID(dyn_class, "stringify",
+ "(I)Ljava/lang/String;");
+ CHECK_RESULT_ASSERT(env, mID == dyn_mID);
+ }
+#endif // #ifndef NDEBUG
+ jstring bi_string
+ = (jstring) env->CallObjectMethod(stringifier, mID, v.id());
+ CHECK_EXCEPTION_THROW(env);
+ // Convert the string and print it on C++ stream.
+ const char* nativeString = env->GetStringUTFChars(bi_string, 0);
+ CHECK_RESULT_THROW(env, nativeString);
+ s << nativeString;
+ env->ReleaseStringUTFChars(bi_string, nativeString);
+}
+
} // namespace Java
} // namespace Interfaces
diff --git a/interfaces/Java/jni/ppl_java_common.defs.hh b/interfaces/Java/jni/ppl_java_common.defs.hh
index 990d4f8..805c5e5 100644
--- a/interfaces/Java/jni/ppl_java_common.defs.hh
+++ b/interfaces/Java/jni/ppl_java_common.defs.hh
@@ -189,6 +189,8 @@ handle_exception(JNIEnv* env);
*/
class Java_Class_Cache {
public:
+ // The Java VM pointer (not a class, but sometimes needed).
+ JavaVM* jvm;
// Non-PPL types.
jclass Boolean;
jclass Integer;
@@ -230,6 +232,7 @@ public:
jclass PPL_Object;
jclass Relation_Symbol;
jclass Variable;
+ jclass Variable_Stringifier;
jclass Variables_Set;
//! Default constructor.
@@ -400,7 +403,10 @@ struct Java_FMID_Cache {
jmethodID Relation_Symbol_ordinal_ID;
// Variable.
jfieldID Variable_varid_ID;
+ jfieldID Variable_stringifier_ID;
jmethodID Variable_init_ID;
+ // Variable_Stringifier.
+ jmethodID Variable_Stringifier_stringify_ID;
// Variables_Set.
jmethodID Variables_Set_init_ID;
jmethodID Variables_Set_add_ID;
@@ -622,6 +628,16 @@ jobject
build_java_variable(JNIEnv* env, const Variable var);
/*! \brief
+ The customizable variable output function for Java interface.
+
+ Customization is obtained by providing an object implementing interface
+ <CODE>Variable_Stringifier</CODE> and attaching it to class
+ <CODE>Variable</CODE> using static method <CODE>setStringifier</CODE>.
+*/
+void
+Java_Variable_output_function(std::ostream& s, Variable v);
+
+/*! \brief
Builds a C++ Coefficient
from Java parma_polyhedra_library::Coefficient \p j_coeff.
*/
diff --git a/interfaces/Java/jni/ppl_java_globals.cc b/interfaces/Java/jni/ppl_java_globals.cc
index 47b679a..a071be4 100644
--- a/interfaces/Java/jni/ppl_java_globals.cc
+++ b/interfaces/Java/jni/ppl_java_globals.cc
@@ -678,6 +678,10 @@ Java_parma_1polyhedra_1library_Variable_initIDs
jfieldID fID = env->GetFieldID(j_variable_class, "varid", "I");
CHECK_RESULT_ASSERT(env, fID);
cached_FMIDs.Variable_varid_ID = fID;
+ fID = env->GetStaticFieldID(j_variable_class, "stringifier",
+ "Lparma_polyhedra_library/Variable_Stringifier;");
+ CHECK_RESULT_ASSERT(env, fID);
+ cached_FMIDs.Variable_stringifier_ID = fID;
jmethodID mID = env->GetMethodID(j_variable_class, "<init>", "(I)V");
CHECK_RESULT_ASSERT(env, mID);
cached_FMIDs.Variable_init_ID = mID;
@@ -1252,6 +1256,44 @@ Java_parma_1polyhedra_1library_MIP_1Problem_ascii_1dump
}
JNIEXPORT jstring JNICALL
+Java_parma_1polyhedra_1library_Variable_toString
+(JNIEnv* env, jobject j_this) {
+ using namespace Parma_Polyhedra_Library::IO_Operators;
+ Variable ppl_var = build_cxx_variable(env, j_this);
+ std::ostringstream s;
+ s << ppl_var;
+ return env->NewStringUTF(s.str().c_str());
+}
+
+JNIEXPORT void JNICALL
+Java_parma_1polyhedra_1library_Variable_setStringifier
+(JNIEnv* env, jclass j_variable_class, jobject j_stringifier) {
+ // Store j_stringifier in the corresponding static field.
+ env->SetStaticObjectField(j_variable_class,
+ cached_FMIDs.Variable_stringifier_ID,
+ j_stringifier);
+ if (j_stringifier == NULL) {
+ // No stringifier object: reset cache values.
+ cached_classes.Variable_Stringifier = NULL;
+ cached_FMIDs.Variable_Stringifier_stringify_ID = NULL;
+ // Reset default C++ output function.
+ Variable::set_output_function(&Variable::default_output_function);
+ }
+ else {
+ // Update cache with values computed for concrete class.
+ jclass vs_class = env->GetObjectClass(j_stringifier);
+ CHECK_RESULT_ASSERT(env, vs_class);
+ cached_classes.Variable_Stringifier = vs_class;
+ jmethodID mID = env->GetMethodID(vs_class, "stringify",
+ "(I)Ljava/lang/String;");
+ CHECK_RESULT_ASSERT(env, mID);
+ cached_FMIDs.Variable_Stringifier_stringify_ID = mID;
+ // Set C++ output function to the Java wrapper.
+ Variable::set_output_function(&Java_Variable_output_function);
+ }
+}
+
+JNIEXPORT jstring JNICALL
Java_parma_1polyhedra_1library_Linear_1Expression_toString
(JNIEnv* env, jobject j_this) {
using namespace Parma_Polyhedra_Library::IO_Operators;
diff --git a/interfaces/Java/parma_polyhedra_library/Makefile.am b/interfaces/Java/parma_polyhedra_library/Makefile.am
index 7031ed5..1f848cf 100644
--- a/interfaces/Java/parma_polyhedra_library/Makefile.am
+++ b/interfaces/Java/parma_polyhedra_library/Makefile.am
@@ -186,6 +186,7 @@ $(srcdir)/PPL_Object.java \
$(srcdir)/Relation_Symbol.java \
$(srcdir)/Timeout_Exception.java \
$(srcdir)/Variable.java \
+$(srcdir)/Variable_Stringifier.java \
$(srcdir)/Variables_Set.java
# NOTE: do _NOT_ add Fake_Class_for_Doxygen.java to this list.
diff --git a/interfaces/Java/parma_polyhedra_library/Variable.java b/interfaces/Java/parma_polyhedra_library/Variable.java
index 7d1d66f..ea13aa0 100644
--- a/interfaces/Java/parma_polyhedra_library/Variable.java
+++ b/interfaces/Java/parma_polyhedra_library/Variable.java
@@ -59,15 +59,30 @@ public class Variable implements Comparable<Variable> {
return varid;
}
- /*! \brief
- Returns a negative number if \p this comes first than \p v,
- a zero if \p this equals \p v, a positive number if
- if \p this comes first than \p v.
- */
+ /*! \brief
+ Returns a negative number if \p this is smaller than \p v,
+ a zero if \p this equals \p v, a positive number if \p v
+ is greater than \p v.
+ */
public int compareTo(Variable v) {
return varid - v.varid;
}
+ //! Optional customization provider for \c toString.
+ private static Variable_Stringifier stringifier;
+
+ /*! \brief
+ Sets the variable stringifier object.
+
+ A variable stringifier object provides customization for the
+ \c toString method; if no variable stringifier object is set
+ (or if it is set to a null refeerence value), the PPL default
+ variable output function will be used.
+ */
+ public static native void setStringifier(Variable_Stringifier vs);
+
+ public native String toString();
+
private static native void initIDs();
static {
initIDs();
More information about the PPL-devel
mailing list