summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2008-04-29 12:07:06 +0000
committerFrederic Peters <fpeters@entrouvert.com>2008-04-29 12:07:06 +0000
commitb2c6027ad1a0e13257906fc5efbf4c5386d3f1cb (patch)
treee3565e6ba4736e17ed6a3e02f3a8151aed72572e
parent3d7c20873cfd488c67645457594a27f8026f9d54 (diff)
downloadlasso-b2c6027ad1a0e13257906fc5efbf4c5386d3f1cb.tar.gz
lasso-b2c6027ad1a0e13257906fc5efbf4c5386d3f1cb.tar.xz
lasso-b2c6027ad1a0e13257906fc5efbf4c5386d3f1cb.zip
[project @ fpeters@0d.be-20080222093656-l6a09ccadxdz9qrs]
merging benjamin branch Original author: Frederic Peters <fpeters@0d.be> Date: 2008-02-22 10:36:56.421000+01:00
-rw-r--r--bindings/bindings.py6
-rw-r--r--bindings/java/GObject.java37
-rw-r--r--bindings/java/Makefile.am55
-rw-r--r--bindings/java/TODO3
-rw-r--r--bindings/java/tests/BindingTests.java113
-rw-r--r--bindings/java/tests/LoginTest.java61
-rw-r--r--bindings/lang_java.py366
-rw-r--r--bindings/lang_java_wrapper_top.c998
-rw-r--r--bindings/overrides.xml4
9 files changed, 1027 insertions, 616 deletions
diff --git a/bindings/bindings.py b/bindings/bindings.py
index 971deafd..e274b7f7 100644
--- a/bindings/bindings.py
+++ b/bindings/bindings.py
@@ -430,6 +430,12 @@ def main():
java_binding = lang_java.JavaBinding(binding)
java_binding.generate();
+ elif options.language == 'java-list':
+ import lang_java
+
+ java_binding = lang_java.JavaBinding(binding)
+ java_binding.print_list_of_files();
+
if __name__ == '__main__':
main()
diff --git a/bindings/java/GObject.java b/bindings/java/GObject.java
index ccb59c22..a7815a72 100644
--- a/bindings/java/GObject.java
+++ b/bindings/java/GObject.java
@@ -1,4 +1,5 @@
package com.entrouvert.lasso;
+import java.util.*;
class GObject {
private long cptr;
@@ -6,4 +7,40 @@ class GObject {
protected GObject(long ptr) {
cptr = ptr;
}
+ protected Map arrayToMap(Object[] arr) {
+ Map map = new HashMap();
+ if (arr == null)
+ return map;
+ if (arr.length % 2 != 0)
+ throw new IllegalArgumentException("arr must of an even size");
+ int i;
+ for (i=0;i<arr.length;i+=2) {
+ map.put(arr[i],arr[i+1]);
+ }
+ return map;
+ }
+ protected void mapToArray(Map map, Object[] arr) {
+ int s = map.size();
+ if (map == null)
+ return;
+ Iterator it;
+ it = map.entrySet().iterator();
+ int i = 0;
+ while (it.hasNext() && i < 2*s) {
+ Map.Entry e = (Map.Entry)it.next();
+ arr[i++] = (Object)e.getKey();
+ arr[i++] = (Object)e.getValue();
+ }
+ }
+ protected void listToArray(List list, Object[] arr) {
+ Iterator it = list.iterator();
+ int s = arr.length;
+ int i = 0;
+ while (it.hasNext() && i < s) {
+ arr[i++] = (Object)it.next();
+ }
+ }
+ protected void finalize() throws Throwable {
+ LassoJNI.destroy(cptr);
+ }
}
diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am
index ace56f6e..e045c6b9 100644
--- a/bindings/java/Makefile.am
+++ b/bindings/java/Makefile.am
@@ -3,39 +3,66 @@ INCLUDES = -I$(top_srcdir) \
-I$(top_builddir) \
$(SASL_CFLAGS)
+AM_JAVACFLAGS=-C
+CLASSPATH_ENV= CLASSPATH=.:lasso.jar:/usr/share/java/junit.jar
+
java_extension_LTLIBRARIES = libjnilasso.la
-java_extensiondir = ${libdir}
+java_extensiondir = ${libdir}/java
+
+java_lasso_source_files = $(shell python $(top_srcdir)/bindings/bindings.py -l java-list --src-dir=$(top_srcdir)/lasso/)
+
+lasso_jardir=$(prefix)/share/java
+lasso_jar_DATA=lasso.jar
+lasso_jar_class_files = $(java_lasso_source_files:.java=.class)
+
+JAVAH=gcjh
+
+$(lasso_jar_class_files): %.class: %.java
+ $(JAVAC) -C -classpath . -d . $<
+
+all_jar_class_files = $(shell find com/entrouvert/lasso -name '*.class' | sed 's%\$$%\\$$%g')
+
+lasso.jar: $(all_jar_class_files)
+ $(JAR) -cf $@ $(all_jar_class_files)
-nodist_java_extension_DATA =
+# Doc
+apidir = $(docbasedir)/lasso/java-api
+
+doc:
+ -mkdir .doc
+ -javadoc -link http://java.sun.com/j2se/1.4.2/docs/api -public -d .doc -sourcepath . -subpackages com.entrouvert.lasso
+ mv .doc doc
+
+
+com_entrouvert_lasso_LassoJNI.h: $(lasso_jar_class_files)
+ $(JAVAH) -jni -d . --classpath=. com.entrouvert.lasso.LassoJNI
libjnilasso_la_CFLAGS = $(LASSO_CORE_CFLAGS) -I$(top_srcdir) -I$(top_builddir)
libjnilasso_la_LDFLAGS = -export-dynamic -prefer-pic -module -avoid-version
libjnilasso_la_LIBADD = $(top_builddir)/lasso/liblasso.la $(LASSO_LIBS)
-nodist_libjnilasso_la_SOURCES = com_entrouvert_lasso_LassoJNI.c
+nodist_libjnilasso_la_SOURCES = com_entrouvert_lasso_LassoJNI.c
BUILT_SOURCES = com_entrouvert_lasso_LassoJNI.c com_entrouvert_lasso_LassoJNI.h
-%.class: %.java
- javac -d . -cp . $<
-
-com_entrouvert_lasso_LassoJNI.h: com/entrouvert/lasso/LassoJNI.class
- javah -d . -jni --classpath=. com.entrouvert.lasso.LassoJNI
-
-com/entrouvert/lasso/LassoJNI.java com/entrouvert/lasso/LassoConstants.java com_entrouvert_lasso_LassoJNI.c: $(srcdir)/../lang_java_wrapper_top.c $(srcdir)/../lang_java.py
+$(java_lasso_source_files) com_entrouvert_lasso_LassoJNI.c: ../lang_java_wrapper_top.c ../lang_java.py
$(PYTHON) $(top_srcdir)/bindings/bindings.py -l java --src-dir=$(top_srcdir)/lasso/
cp $(srcdir)/GObject.java com/entrouvert/lasso
-doc/index.html:
- javadoc -link http://java.sun.com/j2se/1.4.2/docs/api -public -d doc -sourcepath . -subpackages com.entrouvert.lasso
+check: JAVAROOT=.
-publish: doc/index.html
+doc-publish: doc
tar czf doc.tgz -C doc .
scp doc.tgz bdauvergne@perso.entrouvert.org:
ssh bdauvergne@perso.entrouvert.org tar czf -C public_html/java-binding-doc doc.tgz
rm doc.tgz
clean-local:
- -rm -f doc/* com_entrouvert_lasso_LassoJNI.c com/entrouvert/lasso/*.java com/entrouvert/lasso/*.class com_entrouvert_lasso_LassoJNI.h
+ -rm -f com_entrouvert_lasso_LassoJNI.c com/entrouvert/lasso/*.java com/entrouvert/lasso/*.class com_entrouvert_lasso_LassoJNI.h lasso.jar
+ -rm -rf doc
+ -rm tests/*.class
+
+
+check_JAVA = tests/BindingTests.java tests/LoginTest.java
endif
diff --git a/bindings/java/TODO b/bindings/java/TODO
index 9e0c346f..09b4a5c6 100644
--- a/bindings/java/TODO
+++ b/bindings/java/TODO
@@ -11,4 +11,5 @@
-> recencer par fonction les erreurs émises DONE
-> remonter les infos dans le graphe DONE
* doc DONE
-* renvoyer des listes et des hashmap au lieu de tableaux
+* renvoyer des listes et des hashmap au lieu de tableaux DONE
+* utiliser les numéros de version de lasso dans la doc/noms de fichiers
diff --git a/bindings/java/tests/BindingTests.java b/bindings/java/tests/BindingTests.java
index 53a508df..10b08f2b 100644
--- a/bindings/java/tests/BindingTests.java
+++ b/bindings/java/tests/BindingTests.java
@@ -42,22 +42,9 @@ import java.util.*;
public class BindingTests extends TestCase {
- String[] toStringArray(Object[] array) {
- String[] str = new String[array.length];
- int i;
- for (i=0;i<array.length;i++)
- str[i] = (String)array[i];
- return str;
- }
- SamlAssertion[] toSamlAssertionArray(Object[] array) {
- SamlAssertion[] str = new SamlAssertion[array.length];
- int i;
- for (i=0;i<array.length;i++)
- str[i] = (SamlAssertion)array[i];
- return str;
- }
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
+ System.gc();
}
public static Test suite() {
@@ -120,27 +107,33 @@ public class BindingTests extends TestCase {
assertEquals(respondWith.get(0), "first string");
assertEquals(respondWith.get(1), "second string");
assertEquals(respondWith.get(2), "third string");
- authnRequest.setRespondWith(toStringArray(respondWith.toArray()));
- assertEquals(authnRequest.getRespondWith()[0], "first string");
- assertEquals(authnRequest.getRespondWith()[1], "second string");
- assertEquals(authnRequest.getRespondWith()[2], "third string");
+ authnRequest.setRespondWith(respondWith);
+ assertEquals(authnRequest.getRespondWith().get(0), "first string");
+ assertEquals(authnRequest.getRespondWith().get(1), "second string");
+ assertEquals(authnRequest.getRespondWith().get(2), "third string");
assertEquals(respondWith.get(0), "first string");
assertEquals(respondWith.get(1), "second string");
assertEquals(respondWith.get(2), "third string");
respondWith = null;
- assertEquals(authnRequest.getRespondWith()[0], "first string");
- assertEquals(authnRequest.getRespondWith()[1], "second string");
- assertEquals(authnRequest.getRespondWith()[2], "third string");
- respondWith = Arrays.asList(authnRequest.getRespondWith());
+ assertEquals(authnRequest.getRespondWith().get(0), "first string");
+ assertEquals(authnRequest.getRespondWith().get(1), "second string");
+ assertEquals(authnRequest.getRespondWith().get(2), "third string");
+ respondWith = authnRequest.getRespondWith();
assertEquals(respondWith.get(0), "first string");
assertEquals(respondWith.get(1), "second string");
assertEquals(respondWith.get(2), "third string");
respondWith = null;
- assertEquals(authnRequest.getRespondWith()[0], "first string");
- assertEquals(authnRequest.getRespondWith()[1], "second string");
- assertEquals(authnRequest.getRespondWith()[2], "third string");
+ assertEquals(authnRequest.getRespondWith().get(0), "first string");
+ assertEquals(authnRequest.getRespondWith().get(1), "second string");
+ assertEquals(authnRequest.getRespondWith().get(2), "third string");
+ authnRequest.removeFromRespondWith("second string");
+ assertEquals(authnRequest.getRespondWith().get(0), "first string");
+ assertEquals(authnRequest.getRespondWith().get(1), "third string");
+ authnRequest.addToRespondWith("second string");
+ assertEquals(authnRequest.getRespondWith().get(0), "first string");
+ assertEquals(authnRequest.getRespondWith().get(1), "third string");
+ assertEquals(authnRequest.getRespondWith().get(2), "second string");
authnRequest.setRespondWith(null);
- System.out.println("coin"+authnRequest.getRespondWith());
assertNull(authnRequest.getRespondWith());
authnRequest = null;
@@ -174,34 +167,25 @@ public class BindingTests extends TestCase {
assertEquals(((SamlAssertion) assertions.get(0)).getAssertionId(), "assertion 1");
assertEquals(((SamlAssertion) assertions.get(1)).getAssertionId(), "assertion 2");
assertEquals(((SamlAssertion) assertions.get(2)).getAssertionId(), "assertion 3");
- response.setAssertion(toSamlAssertionArray(assertions.toArray()));
- assertEquals(((SamlAssertion) response.getAssertion()[0]).getAssertionId(),
- "assertion 1");
- assertEquals(((SamlAssertion) response.getAssertion()[1]).getAssertionId(),
- "assertion 2");
- assertEquals(((SamlAssertion) response.getAssertion()[2]).getAssertionId(),
- "assertion 3");
+ response.setAssertion(assertions);
+ assertEquals(((SamlAssertion) response.getAssertion().get(0)).getAssertionId(), "assertion 1");
+ assertEquals(((SamlAssertion) response.getAssertion().get(1)).getAssertionId(), "assertion 2");
+ assertEquals(((SamlAssertion) response.getAssertion().get(2)).getAssertionId(), "assertion 3");
assertEquals(((SamlAssertion) assertions.get(0)).getAssertionId(), "assertion 1");
assertEquals(((SamlAssertion) assertions.get(1)).getAssertionId(), "assertion 2");
assertEquals(((SamlAssertion) assertions.get(2)).getAssertionId(), "assertion 3");
assertions = null;;
- assertEquals(((SamlAssertion) response.getAssertion()[0]).getAssertionId(),
- "assertion 1");
- assertEquals(((SamlAssertion) response.getAssertion()[1]).getAssertionId(),
- "assertion 2");
- assertEquals(((SamlAssertion) response.getAssertion()[2]).getAssertionId(),
- "assertion 3");
- assertions = Arrays.asList(response.getAssertion());
+ assertEquals(((SamlAssertion) response.getAssertion().get(0)).getAssertionId(), "assertion 1");
+ assertEquals(((SamlAssertion) response.getAssertion().get(1)).getAssertionId(), "assertion 2");
+ assertEquals(((SamlAssertion) response.getAssertion().get(2)).getAssertionId(), "assertion 3");
+ assertions = response.getAssertion();
assertEquals(((SamlAssertion) assertions.get(0)).getAssertionId(), "assertion 1");
assertEquals(((SamlAssertion) assertions.get(1)).getAssertionId(), "assertion 2");
assertEquals(((SamlAssertion) assertions.get(2)).getAssertionId(), "assertion 3");
assertions = null;
- assertEquals(((SamlAssertion) response.getAssertion()[0]).getAssertionId(),
- "assertion 1");
- assertEquals(((SamlAssertion) response.getAssertion()[1]).getAssertionId(),
- "assertion 2");
- assertEquals(((SamlAssertion) response.getAssertion()[2]).getAssertionId(),
- "assertion 3");
+ assertEquals(((SamlAssertion) response.getAssertion().get(0)).getAssertionId(), "assertion 1");
+ assertEquals(((SamlAssertion) response.getAssertion().get(1)).getAssertionId(), "assertion 2");
+ assertEquals(((SamlAssertion) response.getAssertion().get(2)).getAssertionId(), "assertion 3");
response.setAssertion(null);
assertNull(response.getAssertion());
@@ -215,15 +199,9 @@ public class BindingTests extends TestCase {
assertNull(authnRequest.getExtension());
- String actionString1 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n"
- + " <action>do 1</action>\n"
- + "</lib:Extension>";
- String actionString2 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n"
- + " <action>do 2</action>\n"
- + "</lib:Extension>";
- String actionString3 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n"
- + " <action>do 3</action>\n"
- + "</lib:Extension>";
+ String actionString1 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n" + " <action>do 1</action>\n" + "</lib:Extension>";
+ String actionString2 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n" + " <action>do 2</action>\n" + "</lib:Extension>";
+ String actionString3 = "<lib:Extension xmlns:lib=\"urn:liberty:iff:2003-08\">\n" + " <action>do 3</action>\n" + "</lib:Extension>";
List extension = new ArrayList();
assertEquals(extension.size(), 0);
extension.add(actionString1);
@@ -239,25 +217,25 @@ public class BindingTests extends TestCase {
assertEquals(extension.get(0), actionString1);
assertEquals(extension.get(1), actionString2);
assertEquals(extension.get(2), actionString3);
- authnRequest.setExtension(toStringArray(extension.toArray()));
- assertEquals(authnRequest.getExtension()[0], actionString1);
- assertEquals(authnRequest.getExtension()[1], actionString2);
- assertEquals(authnRequest.getExtension()[2], actionString3);
+ authnRequest.setExtension(extension);
+ assertEquals(authnRequest.getExtension().get(0), actionString1);
+ assertEquals(authnRequest.getExtension().get(1), actionString2);
+ assertEquals(authnRequest.getExtension().get(2), actionString3);
assertEquals(extension.get(0), actionString1);
assertEquals(extension.get(1), actionString2);
assertEquals(extension.get(2), actionString3);
extension = null;
- assertEquals(authnRequest.getExtension()[0], actionString1);
- assertEquals(authnRequest.getExtension()[1], actionString2);
- assertEquals(authnRequest.getExtension()[2], actionString3);
- extension = Arrays.asList(authnRequest.getExtension());
+ assertEquals(authnRequest.getExtension().get(0), actionString1);
+ assertEquals(authnRequest.getExtension().get(1), actionString2);
+ assertEquals(authnRequest.getExtension().get(2), actionString3);
+ extension = authnRequest.getExtension();
assertEquals(extension.get(0), actionString1);
assertEquals(extension.get(1), actionString2);
assertEquals(extension.get(2), actionString3);
extension = null;
- assertEquals(authnRequest.getExtension()[0], actionString1);
- assertEquals(authnRequest.getExtension()[1], actionString2);
- assertEquals(authnRequest.getExtension()[2], actionString3);
+ assertEquals(authnRequest.getExtension().get(0), actionString1);
+ assertEquals(authnRequest.getExtension().get(1), actionString2);
+ assertEquals(authnRequest.getExtension().get(2), actionString3);
authnRequest.setExtension(null);
assertNull(authnRequest.getExtension());
@@ -272,8 +250,7 @@ public class BindingTests extends TestCase {
assertNull(login.getRequest());
login.setRequest((SamlpRequestAbstract) new LibAuthnRequest());
((LibAuthnRequest) login.getRequest()).setConsent(LassoConstants.LASSO_LIB_CONSENT_OBTAINED);
- assertEquals(((LibAuthnRequest) login.getRequest()).getConsent(),
- LassoConstants.LASSO_LIB_CONSENT_OBTAINED);
+ assertEquals(((LibAuthnRequest) login.getRequest()).getConsent(), LassoConstants.LASSO_LIB_CONSENT_OBTAINED);
login.setRequest(null);
assertNull(login.getRequest());
diff --git a/bindings/java/tests/LoginTest.java b/bindings/java/tests/LoginTest.java
index 755ffd7b..d3d29d49 100644
--- a/bindings/java/tests/LoginTest.java
+++ b/bindings/java/tests/LoginTest.java
@@ -42,30 +42,30 @@ import com.entrouvert.lasso.*;
public class LoginTest extends TestCase {
public String generateIdentityProviderDump() {
Server server = new Server(
- "../../tests/data/idp1-la/metadata.xml",
- "../../tests/data/idp1-la/private-key-raw.pem",
+ "../../../tests/data/idp1-la/metadata.xml",
+ "../../../tests/data/idp1-la/private-key-raw.pem",
null,
- "../../tests/data/idp1-la/certificate.pem");
+ "../../../tests/data/idp1-la/certificate.pem");
server.addProvider(
- lasso.PROVIDER_ROLE_SP,
- "../../tests/data/sp1-la/metadata.xml",
- "../../tests/data/sp1-la/public-key.pem",
- "../../tests/data/ca1-la/certificate.pem");
+ LassoConstants.LASSO_PROVIDER_ROLE_SP,
+ "../../../tests/data/sp1-la/metadata.xml",
+ "../../../tests/data/sp1-la/public-key.pem",
+ "../../../tests/data/ca1-la/certificate.pem");
String serverDump = server.dump();
return serverDump;
}
public String generateServiceProviderDump() {
Server server = new Server(
- "../../tests/data/sp1-la/metadata.xml",
- "../../tests/data/sp1-la/private-key-raw.pem",
+ "../../../tests/data/sp1-la/metadata.xml",
+ "../../../tests/data/sp1-la/private-key-raw.pem",
null,
- "../../tests/data/sp1-la/certificate.pem");
+ "../../../tests/data/sp1-la/certificate.pem");
server.addProvider(
- lasso.PROVIDER_ROLE_IDP,
- "../../tests/data/idp1-la/metadata.xml",
- "../../tests/data/idp1-la/public-key.pem",
- "../../tests/data/ca1-la/certificate.pem");
+ LassoConstants.LASSO_PROVIDER_ROLE_IDP,
+ "../../../tests/data/idp1-la/metadata.xml",
+ "../../../tests/data/idp1-la/public-key.pem",
+ "../../../tests/data/ca1-la/certificate.pem");
String serverDump = server.dump();
return serverDump;
}
@@ -97,11 +97,11 @@ public class LoginTest extends TestCase {
assertNotNull(spDump);
sp = Server.newFromDump(spDump);
spLogin = new Login(sp);
- spLogin.initAuthnRequest("https://idp1/metadata", lasso.HTTP_METHOD_REDIRECT);
+ spLogin.initAuthnRequest("https://idp1/metadata", LassoConstants.LASSO_HTTP_METHOD_REDIRECT);
authnRequest = (LibAuthnRequest) spLogin.getRequest();
authnRequest.setIsPassive(false);
- authnRequest.setNameIdPolicy(lasso.LIB_NAMEID_POLICY_TYPE_FEDERATED);
- authnRequest.setConsent(lasso.LIB_CONSENT_OBTAINED);
+ authnRequest.setNameIdPolicy(LassoConstants.LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED);
+ authnRequest.setConsent(LassoConstants.LASSO_LIB_CONSENT_OBTAINED);
relayState = "fake";
authnRequest.setRelayState(relayState);
spLogin.buildAuthnRequestMsg();
@@ -120,15 +120,15 @@ public class LoginTest extends TestCase {
userAuthenticated = true;
userConsentObtained = false;
idpLogin.validateRequestMsg(userAuthenticated, userConsentObtained);
- authenticationMethod = lasso.SAML_AUTHENTICATION_METHOD_PASSWORD;
+ authenticationMethod = LassoConstants.LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD;
idpLogin.buildAssertion(
authenticationMethod,
null, // authenticationInstant
null, // reauthenticateOnOrAfter
null, // notBefore
null);// notOnOrAfter
- assertEquals(lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART, idpLogin.getProtocolProfile());
- idpLogin.buildArtifactMsg(lasso.HTTP_METHOD_REDIRECT);
+ assertEquals(LassoConstants.LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART, idpLogin.getProtocolProfile());
+ idpLogin.buildArtifactMsg(LassoConstants.LASSO_HTTP_METHOD_REDIRECT);
idpIdentityDump = idpLogin.getIdentity().dump();
assertNotNull(idpIdentityDump);
idpSessionDump = idpLogin.getSession().dump();
@@ -139,12 +139,13 @@ public class LoginTest extends TestCase {
nameIdentifier = ((SamlNameIdentifier)idpLogin.getNameIdentifier()).getContent();
artifact = idpLogin.getAssertionArtifact();
assertNotNull(artifact);
- method = lasso.HTTP_METHOD_REDIRECT;
+ method = LassoConstants.LASSO_HTTP_METHOD_REDIRECT;
// Service provider assertion consumer.
spDump = generateServiceProviderDump();
assertNotNull(spDump);
sp = Server.newFromDump(spDump);
+ soapEndpoint = spLogin.getMsgUrl();
spLogin = new Login(sp);
spLogin.initRequest(responseQuery, method);
spLogin.buildRequestMsg();
@@ -154,8 +155,8 @@ public class LoginTest extends TestCase {
assertNotNull(soapRequestMsg);
// Identity provider SOAP endpoint.
- requestType = lasso.getRequestTypeFromSoapMsg(soapRequestMsg);
- assertEquals(lasso.REQUEST_TYPE_LOGIN, requestType);
+ requestType = LassoJNI.getRequestTypeFromSoapMsg(soapRequestMsg);
+ assertEquals(LassoConstants.LASSO_REQUEST_TYPE_LOGIN, requestType);
idpDump = generateIdentityProviderDump();
assertNotNull(idpDump);
idp = Server.newFromDump(idpDump);
@@ -181,9 +182,9 @@ public class LoginTest extends TestCase {
assertNotNull(spSession);
spSessionDump = spSession.dump();
assertNotNull(spSessionDump);
- assertion = (SamlAssertion) spSession.getAssertions("https://idp1/metadata").getItem(0);
+ assertion = (SamlAssertion) spSession.getAssertions("https://idp1/metadata").get(0);
authenticationMethod = assertion.getAuthenticationStatement().getAuthenticationMethod();
- assertEquals(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, authenticationMethod);
+ assertEquals(LassoConstants.LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD, authenticationMethod);
// Service provider logout.
spDump = generateServiceProviderDump();
@@ -195,14 +196,14 @@ public class LoginTest extends TestCase {
spLogout.setIdentityFromDump(spIdentityDump);
assertNotNull(spSessionDump);
spLogout.setSessionFromDump(spSessionDump);
- spLogout.initRequest(null, lasso.HTTP_METHOD_ANY);
+ spLogout.initRequest(null, LassoConstants.LASSO_HTTP_METHOD_ANY);
spLogout.buildRequestMsg();
soapEndpoint = spLogout.getMsgUrl();
soapRequestMsg = spLogout.getMsgBody();
// Identity provider SOAP endpoint.
- requestType = lasso.getRequestTypeFromSoapMsg(soapRequestMsg);
- assertEquals(lasso.REQUEST_TYPE_LOGOUT, requestType);
+ requestType = LassoJNI.getRequestTypeFromSoapMsg(soapRequestMsg);
+ assertEquals(LassoConstants.LASSO_REQUEST_TYPE_LOGOUT, requestType);
idpDump = generateIdentityProviderDump();
assertNotNull(idpDump);
idp = Server.newFromDump(idpDump);
@@ -235,10 +236,8 @@ public class LoginTest extends TestCase {
}
public static void main(String args[]) {
- System.out.println(System.mapLibraryName("jlasso"));
- lasso.init();
junit.textui.TestRunner.run(suite());
- lasso.shutdown();
+ System.gc();
}
}
diff --git a/bindings/lang_java.py b/bindings/lang_java.py
index 21e6f955..026a9e43 100644
--- a/bindings/lang_java.py
+++ b/bindings/lang_java.py
@@ -29,6 +29,12 @@ import utils
lasso_package_name = 'com.entrouvert.lasso'
lasso_java_path = 'com/entrouvert/lasso/'
+debug = 0
+
+def with_return_owner(d):
+ c = d.copy()
+ c['return_owner'] = 1
+ return c
def generate_arg_list(self,args):
def arg_to_decl(arg):
@@ -88,11 +94,40 @@ def wrapper_decl(name, jnitype, fd):
print >> fd, 'JNIEXPORT %s JNICALL %s(JNIEnv *env, jclass clss' % \
(jnitype,jniname),
+def is_collection(type):
+ return type in ('GList*','GHashTable*')
+
+def is_string_type(type):
+ return type in ['char*', 'const char*', 'gchar*', 'const gchar*']
+
class JavaBinding:
def __init__(self, binding_data):
self.binding_data = binding_data
- def is_pygobject(self, t):
+ def print_list_of_files(self):
+ l = ['GObject.java','LassoConstants.java','LassoJNI.java','LassoException.java', 'LassoUndefinedException.java', 'LassoUnimplementedException.java']
+ for c in self.binding_data.structs:
+ class_name = convert_class_name(c.name)
+ l.append(class_name + '.java')
+ for c in self.binding_data.constants:
+ type, orig = c
+ if 'LASSO_ERROR_' in orig or '_ERROR_' not in orig:
+ continue
+ name, super = error_to_exception(orig)
+ l.append(name + '.java')
+ if not super + '.java' in l:
+ l.append(super + '.java')
+ l = [ lasso_java_path + p for p in l]
+ for p in l:
+ print p,
+ print
+ print
+
+ def is_int_type(self, type):
+ return type in ['gboolean','int','gint'] + self.binding_data.enums
+
+
+ def is_gobject_type(self, t):
return t not in ['char*', 'const char*', 'gchar*', 'const gchar*',
'GList*', 'GHashTable*',
'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums
@@ -162,7 +197,8 @@ public abstract interface LassoConstants {
package %s;
public final class LassoJNI {
-public static native void init2();
+protected static native void init2();
+protected static native void destroy(long cptr);
''' % lasso_package_name
def generate_JNI_constants(self, fd):
print >>fd, '/* Constants getters */'
@@ -252,8 +288,9 @@ public static native void init2();
print >> fd, ' public static native void %s(GObject obj, %s[] value);' % (name,jtype)
name = '%s_add' % prefix
print >> fd, ' public static native void %s(GObject obj, %s value);' % (name,jtype)
- name = '%s_remove' % prefix
- print >> fd, ' public static native void %s(GObject obj, %s value);' % (name,jtype)
+ if not m[2].get('elem_type') in ('xmlNode*',):
+ name = '%s_remove' % prefix
+ print >> fd, ' public static native void %s(GObject obj, %s value);' % (name,jtype)
elif mtype == 'GHashTable*':
name = '%s_get' % prefix
print >> fd, ' public static native %s[] %s(GObject obj);' % (jtype,name)
@@ -261,10 +298,10 @@ public static native void init2();
print >> fd, ' public static native void %s(GObject obj, %s[] value);' % (name,jtype)
name = '%s_add' % prefix
print >> fd, ' public static native void %s(GObject obj, String key, %s value);' % (name,jtype)
- name = '%s_remove' % prefix
- print >> fd, ' public static native void %s(GObject obj, String key);' % (name)
- name = '%s_get_by_name' % prefix
- print >> fd, ' public static native %s[] %s(GObject obj, String key);' % (jtype,name)
+# name = '%s_remove' % prefix
+# print >> fd, ' public static native void %s(GObject obj, String key);' % (name)
+# name = '%s_get_by_name' % prefix
+# print >> fd, ' public static native %s[] %s(GObject obj, String key);' % (jtype,name)
else:
name = '%s_get' % prefix
print >> fd, ' public static native %s %s(GObject obj);' % (jtype,name)
@@ -336,61 +373,57 @@ public static native void init2();
print >>fd, '}'
print >> fd, '/* End of declaration of constants */'
- def jni_return_type(self, vtype):
- if vtype == 'gboolean':
+ def jni_return_type(self, type):
+ if type == 'gboolean':
return 'jboolean'
- elif vtype in ['int','gint'] + self.binding_data.enums:
+ elif type in ['int','gint'] + self.binding_data.enums:
return 'jint'
- elif vtype in ('char*', 'gchar*', 'const char*', 'const gchar*'):
+ elif type in ('char*', 'gchar*', 'const char*', 'const gchar*'):
return 'jstring'
- elif vtype in ('GList*','GHashTable*'):
+ elif type in ('GList*','GHashTable*'):
return 'jobjectArray'
- elif vtype == 'xmlNode*':
+ elif type == 'xmlNode*':
return 'jstring'
- elif not vtype:
+ elif not type:
return 'void'
else:
return 'jobject'
- def c_to_java_value(self, name, vtype, options):
- if vtype == 'gboolean':
- return '(jboolean)%s' % name
- elif vtype in ['int', 'gint'] + self.binding_data.enums:
- return '(jint)%s' % name
- elif vtype in ('char*', 'gchar*'):
- return 'string_to_jstring(env, %s)' % name
- elif vtype in ('const char*', 'const gchar*'):
- return 'string_to_jstring(env, %s)' % name
- elif vtype in ('GList*',):
+ def c_to_java_value(self, left, right, type, options):
+ if type == 'gboolean':
+ return '%s = (jboolean)%s' % (left,right)
+ elif type in ['int', 'gint'] + self.binding_data.enums:
+ return '%s = (jint)%s' % (left, right)
+ elif is_string_type(type):
+ return 'string_to_jstring(env, %s, &%s)' % (right, left)
+ elif type in ('GList*',):
elem_type = options.get('elem_type')
if elem_type == 'char*':
- return 'get_list_of_strings(env, %s)' % name
+ return 'get_list_of_strings(env, %s, &%s)' % (right, left)
elif elem_type == 'xmlNode*':
- return 'get_list_of_xml_nodes(env, %s)' % name
+ return 'get_list_of_xml_nodes(env, %s, &%s)' % (right, left)
else:
- return 'get_list_of_objects(env, %s)' % name
- elif vtype in ('GHashTable*',):
+ return 'get_list_of_objects(env, %s, &%s)' % (right, left)
+ elif type in ('GHashTable*',):
elem_type = options.get('elem_type')
if elem_type == 'char*':
- return 'get_hash_of_strings(env, %s)' % name
+ return 'get_hash_of_strings(env, %s, &%s)' % (right, left)
else:
- return 'get_hash_of_objects(env, %s)' % name
- elif vtype == 'xmlNode*':
- return 'xml_node_to_jstring(env, %s)' % name
+ return 'get_hash_of_objects(env, %s, &%s)' % (right, left)
+ elif type == 'xmlNode*':
+ return 'xml_node_to_jstring(env, %s, &%s)' % (right, left)
else:
- if 'return_owner' in options:
- return 'gobject_to_jobject(env, (GObject*)%s);' % name
+ if options.get('return_owner'):
+ return 'gobject_to_jobject(env, (GObject*)%s, &%s);' % (right, left)
else:
- return 'gobject_to_jobject_and_ref(env, (GObject*)%s);' % name
-
- def java_to_c_value(self, left, right, vtype, options):
- if vtype in ['gboolean','int', 'gint'] + self.binding_data.enums:
- return '%s = (%s)%s;' % (left,vtype,right)
- elif vtype in ('char*', 'gchar*'):
- return '%s = (%s) jstring_to_string_dup(env, %s);' % (left,vtype,right)
- elif vtype in ('const char*', 'const gchar*'):
- return '%s = (%s) jstring_to_string(env, %s);' % (left,vtype,right)
- elif vtype in ('GList*',):
+ return 'gobject_to_jobject_and_ref(env, (GObject*)%s, &%s);' % (right, left)
+
+ def java_to_c_value(self, left, right, type, options):
+ if type in ['gboolean','int', 'gint'] + self.binding_data.enums:
+ return '%s = (%s)%s;' % (left,type,right)
+ elif is_string_type(type):
+ return 'jstring_to_string(env, %s, (char**)&%s);' % (right,left)
+ elif type in ('GList*',):
elem_type = options.get('elem_type')
if elem_type == 'char*':
return 'set_list_of_strings(env, &%s,%s);' % (left,right)
@@ -398,19 +431,16 @@ public static native void init2();
return 'set_list_of_xml_nodes(env, &%s, %s);' % (left, right)
else:
return 'set_list_of_objects(env, &%s, %s);' % (left, right)
- elif vtype in ('GHashTable*',):
+ elif type in ('GHashTable*',):
elem_type = options.get('elem_type')
if elem_type == 'char*':
return 'set_hash_of_strings(env, %s, %s);' % (left,right)
else:
return 'set_hash_of_objects(env, %s, %s);' % (left,right)
- elif vtype == 'xmlNode*':
- return '%s = jstring_to_xml_node(env, %s);' % (left, right)
+ elif type == 'xmlNode*':
+ return 'jstring_to_xml_node(env, %s, &%s);' % (right, left)
else:
- if 'return_owner' in options:
- return '%s = (%s)jobject_to_gobject(env, %s);' % (left,vtype,right)
- else:
- return '%s = (%s)jobject_to_gobject_and_ref(env, %s);' % (left,vtype,right)
+ return 'jobject_to_gobject(env, %s, (GObject**)&%s);' % (right, left)
def generate_wrapper_function(self, m, fd):
print >> fd, '/* Wrapper function for ',
@@ -447,12 +477,12 @@ public static native void init2();
print >> fd, ' {'
idx = 0
if m.return_type:
- print >> fd, '%s ret;' % jtype
+ print >> fd, ' %s ret;' % jtype
# Declare C args
for arg in m.args:
idx = idx + 1
arg_type, arg_name, arg_options = arg
- print >> fd, ' %s %s;' % (arg_type,arg_name)
+ print >> fd, ' %s %s;' % (arg_type.replace('const ',''),arg_name)
# Declare return vars
if m.return_type:
print >> fd, ' %s return_value;' % m.return_type
@@ -461,33 +491,50 @@ public static native void init2();
for arg in m.args:
idx = idx + 1
arg_type, arg_name, arg_options = arg
- option = arg_options.copy()
- option['return_owner'] = 1
- print >> fd, ' %s' % self.java_to_c_value(arg_name, 'jarg%s' % idx, arg_type, option)
+ print >> fd, ' %s' % self.java_to_c_value(arg_name, 'jarg%s' % idx, arg_type, arg_options)
+ if debug:
+ print >> fd, ' printf("%s' % name,
+ arglist = ''
+ for arg in m.args:
+ arg_type, arg_name, arg_options = arg
+ arglist = arglist + ', %s' % arg_name
+ if self.is_int_type(arg_type):
+ print >> fd, '%i',
+ elif is_string_type(arg_type):
+ print >> fd, '%s',
+ else:
+ print >> fd, '%p',
+ print >> fd, '\\n"%s);' % arglist
# Call function
print >> fd, ' ',
if m.return_type:
print >> fd, 'return_value = (%s)' % m.return_type,
print >> fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args]))
- options = {}
# Free const char * args
idx=0
for arg in m.args:
idx=idx+1
arg_type, arg_name, arg_options = arg
- if arg_type in ('const gchar*', 'const char*'):
- print >> fd, ' release_utf_string(env, jarg%s, %s);' % (idx,arg_name)
+ if is_string_type(arg_type):
+ print >> fd, ' if (%s)' % arg_name
+ print >> fd, ' g_free(%s);' % arg_name
# Return
if m.return_type:
if m.name.endswith('_new'):
- print >> fd, ' return (jlong) return_value;'
+ print >> fd, ' ret = (jlong)(int) return_value;'
else:
+ options = {}
if m.return_owner:
- options['return_owner'] = 1
- print >> fd, ' ret = %s;' % self.c_to_java_value('return_value', m.return_type, options)
- if m.return_type == 'GList*' and not m.return_owner:
- print >> fd, ' free_glist(return_value, NULL);'
+ options = with_return_owner({})
+ print >> fd, ' %s;' % self.c_to_java_value('ret','return_value', m.return_type, options)
+ if m.return_owner:
+ if m.return_type == 'GList*':
+ print >> fd, ' free_glist(&return_value, NULL);'
+ elif is_string_type(m.return_type):
+ print >> fd, ' if (return_value)'
+ print >> fd, ' g_free(return_value);'
+ print >> fd, ' return ret;'
print >> fd, ' }'
def generate_wrapper_getter_setter(self, c, fd):
@@ -500,23 +547,42 @@ public static native void init2();
print >> fd,'/* Getter for %s %s.%s */' % (mtype,klassname,m[1])
wrapper_decl("%s_get" % prefix, jtype, fd)
print >> fd, ', jobject jobj)\n {'
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
+ print >> fd, ' %s *gobj;' % klassname
+ print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+ if debug:
+ print >> fd, ' printf("%s_get %%p %%p\\n", gobj, gobj->%s);' % (prefix, m[1])
+ print >> fd, ' %s ret = 0;' % jtype
print >> fd, ' if (gobj) {'
- print >> fd, ' return %s;' % self.c_to_java_value ('gobj->%s' % m[1], mtype, m[2])
+ print >> fd, ' %s;' % self.c_to_java_value ('ret','gobj->%s' % m[1], mtype, m[2])
print >> fd, ' } else {'
print >> fd, ' (*env)->ThrowNew(env, "java/lang/NullPointerException", "no gobject correspond to the given object");'
- print >> fd, ' return 0;'
print >> fd, ' }'
+ print >> fd, ' return ret;'
print >> fd, '}'
print >> fd, ''
# setter
print >> fd,'/* Setter for %s %s.%s */' % (mtype,klassname,m[1])
wrapper_decl("%s_set" % prefix, 'void', fd)
print >> fd, ', jobject jobj, %s value)\n {' % self.jni_return_type(mtype)
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
- if mtype in ('char*', 'const char*', 'gchar*', 'const gchar*'):
- print >> fd, ' g_free(gobj->%s);' % m[1]
+ print >> fd, ' %s *gobj;' % klassname
+ if debug:
+ print >> fd, ' printf("%s_set %%p %%p\\n", gobj, value);' % prefix
+ print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+ print >> fd, ' if (!gobj) {'
+ print >> fd, ' (*env)->ThrowNew(env, "java/lang/NullPointerException", "no gobject correspond to the given object");'
+ print >> fd, ' }'
+ if not self.is_int_type(mtype) and not is_collection(mtype):
+ print >> fd, ' if (gobj->%s) {' % m[1]
+ if is_string_type(mtype):
+ print >> fd, ' g_free(gobj->%s);' % m[1]
+ else:
+ print >> fd, ' g_object_unref(gobj->%s);' % m[1]
+ print >> fd, ' }'
print >> fd, ' %s' % self.java_to_c_value('gobj->%s' % m[1], 'value', mtype, m[2])
+ if self.is_gobject_type(mtype):
+ print >> fd, ' if (gobj->%s) {' % m[1]
+ print >> fd, ' g_object_ref(gobj->%s);' % m[1]
+ print >> fd, ' }'
print >> fd, '}'
# add/remove
if mtype in ('GList*', ):
@@ -525,8 +591,9 @@ public static native void init2();
elem_type = m[2].get('elem_type')
wrapper_decl("%s_add" % prefix, 'void', fd)
print >> fd, ', jobject jobj, %s value)\n {' % jni_elem_type(elem_type)
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
- if elem_type in ('char*','gchar*'):
+ print >> fd, ' %s *gobj;' % klassname
+ print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+ if is_string_type(elem_type):
print >> fd, ' add_to_list_of_strings(env, &gobj->%s,value);' % m[1]
elif elem_type in ('xmlNode*',):
print >> fd, ' add_to_list_of_xml_nodes(env, &gobj->%s,value);' % m[1]
@@ -534,17 +601,17 @@ public static native void init2();
print >> fd, ' add_to_list_of_objects(env, &gobj->%s,value);' % m[1]
print >> fd, '}'
# remove
- print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1])
- wrapper_decl("%s_remove" % prefix, 'void', fd)
- print >> fd, ', jobject jobj, %s value)\n {' % jni_elem_type(elem_type)
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
- if elem_type in ('char*','gchar*'):
- print >> fd, ' remove_from_list_of_strings(env, &gobj->%s,value);' % m[1]
- elif elem_type in ('xmlNode*',):
- print >> fd, ' remove_from_list_of_xml_nodes(env, &gobj->%s,value);' % m[1]
- else:
- print >> fd, ' remove_from_list_of_objects(env, &gobj->%s,value);' % m[1]
- print >> fd, '}'
+ if elem_type not in ('xmlNode*',):
+ print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1])
+ wrapper_decl("%s_remove" % prefix, 'void', fd)
+ print >> fd, ', jobject jobj, %s value)\n {' % jni_elem_type(elem_type)
+ print >> fd, ' %s *gobj;' % klassname
+ print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+ if elem_type in ('char*','gchar*'):
+ print >> fd, ' remove_from_list_of_strings(env, &gobj->%s,value);' % m[1]
+ else:
+ print >> fd, ' remove_from_list_of_objects(env, &gobj->%s,value);' % m[1]
+ print >> fd, '}'
# add/remove/get_by_name
if mtype in ('GHashTable*',):
# add
@@ -552,32 +619,35 @@ public static native void init2();
elem_type = m[2].get('elem_type')
wrapper_decl("%s_add" % prefix, 'void', fd)
print >> fd, ', jobject jobj, jstring key, %s value)\n {' % jni_elem_type(elem_type)
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
+ print >> fd, ' %s *gobj;' % klassname
+ print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
if elem_type in ('char*','gchar*'):
print >> fd, ' add_to_hash_of_strings(env, gobj->%s,value,key);' % m[1]
else:
print >> fd, ' add_to_hash_of_objects(env, gobj->%s,value,key);' % m[1]
print >> fd, '}'
- # remove
- print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1])
- wrapper_decl("%s_remove" % prefix, 'void', fd)
- print >> fd, ', jobject jobj, jstring key)\n {'
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
- if elem_type in ('char*','gchar*'):
- print >> fd, ' remove_from_hash_of_strings(env, gobj->%s,key);' % m[1]
- else:
- print >> fd, ' remove_from_hash_of_objects(env, gobj->%s,key);' % m[1]
- print >> fd, '}'
- # get by name
- print >> fd,'/* Get by name for %s %s.%s */' % (mtype,klassname,m[1])
- wrapper_decl("%s_get_by_name" % prefix, jni_elem_type(elem_type) , fd)
- print >> fd, ', jobject jobj, jstring key)\n {'
- print >> fd, ' %s *gobj = (%s*)jobject_to_gobject(env, jobj);' % (klassname,klassname)
- if elem_type in ('char*','gchar*'):
- print >> fd, ' return get_hash_of_strings_by_name(env, gobj->%s,key);' % m[1]
- else:
- print >> fd, ' return get_hash_of_objects_by_name(env, gobj->%s,key);' % m[1]
- print >> fd, '}'
+# # remove
+# print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1])
+# wrapper_decl("%s_remove" % prefix, 'void', fd)
+# print >> fd, ', jobject jobj, jstring key)\n {'
+# print >> fd, ' %s *gobj;' % klassname
+# print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+# if elem_type in ('char*','gchar*'):
+# print >> fd, ' remove_from_hash_of_strings(env, gobj->%s,key);' % m[1]
+# else:
+# print >> fd, ' remove_from_hash_of_objects(env, gobj->%s,key);' % m[1]
+# print >> fd, '}'
+# # get by name
+# print >> fd,'/* Get by name for %s %s.%s */' % (mtype,klassname,m[1])
+# wrapper_decl("%s_get_by_name" % prefix, jni_elem_type(elem_type) , fd)
+# print >> fd, ', jobject jobj, jstring key)\n {'
+# print >> fd, ' %s *gobj;' % klassname
+# print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
+# if elem_type in ('char*','gchar*'):
+# print >> fd, ' return get_hash_of_strings_by_name(env, gobj->%s,key);' % m[1]
+# else:
+# print >> fd, ' return get_hash_of_objects_by_name(env, gobj->%s,key);' % m[1]
+# print >> fd, '}'
#
def generate_exception_switch_case(self, fd, name, orig):
@@ -654,6 +724,7 @@ public static native void init2();
path = lasso_java_path + '%s.java' % class_name
fd = open(path,'w')
print >> fd, 'package %s;' % lasso_package_name
+ print >> fd, 'import java.util.*;'
print >> fd, ''
#print 'class %s extends %s {' % (class_name,parent_name)
print >> fd, 'public class %s extends %s {' % (class_name,parent_name)
@@ -690,31 +761,46 @@ public static native void init2();
jname = utils.format_as_camelcase('_'+name)
jtype = self.JNI_member_type(m)
if type == 'GList*':
- print >> fd, ' public void set%s(%s[] value) {' % (jname,jtype)
- print >> fd, ' LassoJNI.%s_set(this, value);' % prefix
+ print >> fd, ' public void set%s(List list) {' % jname
+ print >> fd, ' %s[] arr = null;' % jtype
+ print >> fd, ' if (list != null) {'
+ print >> fd, ' arr = new %s[list.size()];' % jtype
+ print >> fd, ' listToArray(list, arr);'
+ print >> fd, ' }'
+ print >> fd, ' LassoJNI.%s_set(this, arr);' % prefix
print >> fd, ' }'
- print >> fd, ' public %s[] get%s() {' % (jtype,jname)
- print >> fd, ' return LassoJNI.%s_get(this);' % prefix
+ print >> fd, ' public List get%s() {' % jname
+ print >> fd, ' %s[] arr = LassoJNI.%s_get(this);' % (jtype,prefix)
+ print >> fd, ' if (arr != null)'
+ print >> fd, ' return Arrays.asList(arr);'
+ print >> fd, ' else'
+ print >> fd, ' return null;'
print >> fd, ' }'
print >> fd, ' public void addTo%s(%s value) {' % (jname,jtype)
print >> fd, ' LassoJNI.%s_add(this, value);' % prefix
print >> fd, ' }'
- print >> fd, ' public void removeFrom%s(%s value) {' % (jname,jtype)
- print >> fd, ' LassoJNI.%s_remove(this, value);' % prefix
- print >> fd, ' }'
+ if m[2].get('elem_type') not in ('xmlNode*',):
+ print >> fd, ' public void removeFrom%s(%s value) {' % (jname,jtype)
+ print >> fd, ' LassoJNI.%s_remove(this, value);' % prefix
+ print >> fd, ' }'
elif type == 'GHashTable*':
- print >> fd, ' public void set%s(%s[] value) {' % (jname,jtype)
- print >> fd, ' LassoJNI.%s_set(this, value);' % prefix
+ print >> fd, ' public void set%s(Map map) {' % jname
+ print >> fd, ' %s[] arr = null;' % jtype
+ print >> fd, ' if (map != null) {'
+ print >> fd, ' arr = new %s[map.size()*2];' % jtype
+ print >> fd, ' mapToArray(map,arr);'
+ print >> fd, ' }'
+ print >> fd, ' LassoJNI.%s_set(this, arr);' % prefix
print >> fd, ' }'
- print >> fd, ' public %s[] get%s() {' % (jtype,jname)
- print >> fd, ' return LassoJNI.%s_get(this);' % prefix
+ print >> fd, ' public Map get%s() {' % jname
+ print >> fd, ' return arrayToMap(LassoJNI.%s_get(this));' % prefix
print >> fd, ' }'
print >> fd, ' public void addTo%s(String key, %s value) {' % (jname,jtype)
print >> fd, ' LassoJNI.%s_add(this, key, value);' % prefix
print >> fd, ' }'
- print >> fd, ' public void removeFrom%s(String key) {' % (jname)
- print >> fd, ' LassoJNI.%s_remove(this, key);' % prefix
- print >> fd, ' }'
+# print >> fd, ' public void removeFrom%s(String key) {' % (jname)
+# print >> fd, ' LassoJNI.%s_remove(this, key);' % prefix
+# print >> fd, ' }'
#print ' void set%s(%s[] value)' % (jname,jtype)
#print ' %s[] get%s()' % (jtype,jname)
#print ' void addTo%s(String key, %s value)' % (jname,jtype)
@@ -741,7 +827,7 @@ public static native void init2();
wrapper.initial_indent = first
wrapper.subsequent_indent = ' * '
str = re.sub(r'\bNULL\b','null', str)
- str = re.sub(r'#Lasso(\w+)',r'{@link \1}',str)
+ str = re.sub(r'#Lasso(\w+)',r'{@@link \1}',str)
str = re.sub(r'[^.]*must *be *freed *by[^.]*\.?', '', str)
str = re.sub(r'[^.]*internally[^.]*\.?[^.]*freed[^.]*\.?', '', str)
@@ -760,20 +846,32 @@ public static native void init2();
err = error_to_exception(err)[0]
print >> fd, normalize(err,' * @throws ')
print >> fd, ' **/'
- print >> fd, ' public %s %s(%s) {' % (return_type,mname,generate_arg_list(self,args[1:]))
- print >> fd, ' ',
- if m.return_type:
- print >> fd, 'return',
- arglist = generate_arg_list2(args[1:])
- if arglist:
- arglist = ', ' + arglist
- if m.errors:
- print >> fd, 'LassoException.throwError(',
- print >> fd,'LassoJNI.%s(this%s)' % (jni_name,arglist),
- if m.errors:
- print >> fd, ');'
+ if m.return_type == 'GList*':
+ print >> fd, ' public List %s(%s) {' % (mname,generate_arg_list(self,args[1:]))
+ arglist = generate_arg_list2(args[1:])
+ if arglist:
+ arglist = ', ' + arglist
+ print >> fd, ' Object[] arr = LassoJNI.%s(this%s);' % (jni_name,arglist)
+ print >> fd, ' if (arr != null)'
+ print >> fd, ' return Arrays.asList(arr);'
+ print >> fd, ' else'
+ print >> fd, ' return null;'
+ print >> fd, ' }'
else:
- print >> fd, ';'
- print >> fd, ' }'
+ print >> fd, ' public %s %s(%s) {' % (return_type,mname,generate_arg_list(self,args[1:]))
+ print >> fd, ' ',
+ if m.return_type:
+ print >> fd, 'return',
+ arglist = generate_arg_list2(args[1:])
+ if arglist:
+ arglist = ', ' + arglist
+ if m.errors:
+ print >> fd, 'LassoException.throwError(',
+ print >> fd,'LassoJNI.%s(this%s)' % (jni_name,arglist),
+ if m.errors:
+ print >> fd, ');'
+ else:
+ print >> fd, ';'
+ print >> fd, ' }'
print >> fd, '}'
fd.close()
diff --git a/bindings/lang_java_wrapper_top.c b/bindings/lang_java_wrapper_top.c
index 123bb996..60048e53 100644
--- a/bindings/lang_java_wrapper_top.c
+++ b/bindings/lang_java_wrapper_top.c
@@ -4,519 +4,781 @@
#include "com_entrouvert_lasso_LassoJNI.h"
#include <string.h>
-static GQuark lasso_wrapper_key;
-typedef jobject (*Converter)(JNIEnv *env, void *);
-typedef void *(*OutConverter)(JNIEnv *env, jobject);
-
-/* String handling */
-static jstring string_to_jstring(JNIEnv *env, const char *str);
-static jstring string_to_jstring_and_free(JNIEnv *env, char *str);
-static const char* jstring_to_string(JNIEnv *env, jstring str);
-static void release_utf_string(JNIEnv *env, jstring str, const char *utfstr);
-
-/* xmlNode handling */
-static jstring xml_node_to_jstring(JNIEnv *env, xmlNode *xmlnode);
-static xmlNode* jstring_to_xml_node(JNIEnv *env, jstring string);
-
-/* Lasso object handling */
-/* Reference counting:
- *
- * new jobject make ++refcount
- *
- */
-
-static GObject* jobject_to_gobject(JNIEnv *env, jobject *obj);
-static GObject* jobject_to_gobject_and_ref(JNIEnv *env, jobject *obj);
-static jobject gobject_to_jobject(JNIEnv *env, GObject *obj);
-static jobject gobject_to_jobject_and_ref(JNIEnv *env, GObject *obj);
-
-/* List handling */
-static void free_glist(GList **list, GFunc free_function) ;
-static jobjectArray get_list(JNIEnv *, char *,GList *, Converter);
-#define get_list_of_strings(env,list) get_list(env,"java/lang/String",list,(Converter)string_to_jstring)
-#define get_list_of_xml_nodes(env,list) get_list(env,"java/lang/String",list,(Converter)xml_node_to_jstring)
-#define get_list_of_objects(env,list) get_list(env,"java/lang/Object",list,(Converter)gobject_to_jobject_and_ref)
-static void set_list(JNIEnv*,GList **, jobjectArray jarr,GFunc free_function, OutConverter);
+#define LASSO_ROOT "com/entrouvert/lasso/"
+#define check_exception (*env)->ExceptionCheck(env)
+#define g_return_val_if_exception(value) if ((*env)->ExceptionCheck(env)) return (value);
+#define g_return_if_exception() if ((*env)->ExceptionCheck(env)) return;
+#define convert_jlong_to_gobject(value) ((GObject*)(ptrdiff_t)value)
+#define g_error_if_fail(value) { if (!(value)) { g_on_error_query("LassoJNI"); } }
+#define PTR_TO_JLONG(x) (jlong)((ptrdiff_t)x)
+
+static GQuark lasso_wrapper_key = 0;
+typedef int (*Converter)(JNIEnv *env, void *from, jobject *to);
+typedef int *(*OutConverter)(JNIEnv *env, jobject from, gpointer *to);
+
+/* Static declarations */
+static int gpointer_equal(gpointer p1, gpointer p2);
+static int new_object_with_gobject(JNIEnv *env, GObject *obj, char *clsName, jobject *jobj);
+static int jstring_to_local_string(JNIEnv *env, jstring jstr, const char **str);
+static void release_local_string(JNIEnv *env, jstring str, const char *utf_str);
+static int get_jlong_field(JNIEnv *env, jobject obj, char *field, jlong *dest);
+static jclass get_jclass_by_name(JNIEnv *env, char *name);
+static int get_array_element(JNIEnv *env, jobjectArray arr, jsize i, jobject *dest);
+static int set_array_element(JNIEnv *env, jobjectArray arr, jsize i, jobject value);
+static int get_array_size(JNIEnv *env, jobjectArray arr, jsize *dest);
+static int create_object_array(JNIEnv *env, char *clsName, jsize size, jobjectArray *jarr);
+static jobject get_shadow_object(JNIEnv *env, GObject *obj);
+static void set_shadow_object(JNIEnv *env, GObject *obj, jobject shadow_object);
+static void exception(JNIEnv *env, char *message);
+static int string_to_jstring(JNIEnv *env, const char* str, jstring *jstr);
+static int string_to_jstring_and_free(JNIEnv *env, char* str, jstring *jstr);
+static int jstring_to_string(JNIEnv *env, jstring jstr, char **str);
+static int xml_node_to_jstring(JNIEnv *env, xmlNode *xmlnode, jstring *jstr);
+static int jstring_to_xml_node(JNIEnv *env, jstring jstr, xmlNode **xmlnode);
+static int gobject_to_jobject_aux(JNIEnv *env, GObject *obj, gboolean doRef, jobject *job);
+static int gobject_to_jobject(JNIEnv *env, GObject *obj, jobject *jobj);
+static int gobject_to_jobject_and_ref(JNIEnv *env, GObject *obj, jobject *jobj);
+
+static int jobject_to_gobject(JNIEnv *env, jobject obj, GObject **gobj);
+static int jobject_to_gobject_for_list(JNIEnv *env, jobject *obj, GObject **gobj);
+static void free_glist(GList **list, GFunc free_function);
+static int get_list(JNIEnv *env, char *clsName, GList *list, Converter convert, jobjectArray *jarr);
+static int set_list(JNIEnv *env, GList **list, jobjectArray jarr, GFunc free_function, OutConverter convert);
+static int remove_from_list(JNIEnv *env,GList **list,jobject obj,GFunc free_function,GCompareFunc compare,OutConverter convert);
+static int add_to_list(JNIEnv* env, GList** list, jobject obj, OutConverter convert);
+static int get_hash(JNIEnv *env, char *clsName, GHashTable *hashtable, Converter convert, jobjectArray *jarr);
+static int set_hash_of_objects(JNIEnv *env, GHashTable *hashtable, jobjectArray jarr);
+static int set_hash_of_strings(JNIEnv *env, GHashTable *hashtable, jobjectArray jarr);
+static int remove_from_hash(JNIEnv *env, GHashTable *hashtable, jstring jkey);
+static int add_to_hash(JNIEnv *env, GHashTable *hashtable, jstring jkey, jobject jvalue, OutConverter convert, GFunc free_function);
+static int get_hash_by_name(JNIEnv *env, GHashTable *hashtable, jstring jkey, Converter convert, jobject *jvalue);
+#define get_list_of_strings(env,list,jarr) get_list(env,"java/lang/String",list,(Converter)string_to_jstring,jarr)
+#define get_list_of_xml_nodes(env,list,jarr) get_list(env,"java/lang/String",list,(Converter)xml_node_to_jstring,jarr)
+#define get_list_of_objects(env,list,jarr) get_list(env,"java/lang/Object",list,(Converter)gobject_to_jobject_and_ref,jarr)
#define set_list_of_strings(env,list,jarr) set_list(env,list,jarr,(GFunc)g_free,(OutConverter)jstring_to_string)
#define set_list_of_xml_nodes(env,list,jarr) set_list(env,list,jarr,(GFunc)xmlFreeNode,(OutConverter)jstring_to_xml_node)
-#define set_list_of_objects(env,list,jarr) set_list(env,list,jarr,(GFunc)g_object_unref,(OutConverter)jobject_to_gobject_and_ref)
-static void remove_from_list(JNIEnv*,GList**,jobject,GFunc,GCompareFunc,OutConverter);
-#define remove_from_list_of_strings(env,list,obj) remove_from_list(env,list,obj,(GFunc)g_free,(GCompareFunc)strcmp,(OutConverter)jstring_to_string)
-#define remove_from_list_of_xml_nodes(env,list,obj) remove_from_list(env,list,obj,(GFunc)xmlFreeNode,(GCompareFunc)strcmp,(OutConverter)jstring_to_xml_node)
-#define remove_from_list_of_objects(env,list,obj) remove_from_list(env,list,obj,(GFunc)g_object_unref,(GCompareFunc)strcmp,(OutConverter)jobject_to_gobject_and_ref)
-static void add_to_list(JNIEnv*,GList**,void *,OutConverter);
+#define set_list_of_objects(env,list,jarr) set_list(env,list,jarr,(GFunc)g_object_unref,(OutConverter)jobject_to_gobject_for_list)
+// remove_from_list_of_strings is now implemented directly
+//#define remove_from_list_of_strings(env,list,obj) remove_from_list(env,list,obj,(GFunc)g_free,(GCompareFunc)strcmp,(OutConverter)jstring_to_local_string)
+//#define remove_from_list_of_xml_nodes(env,list,obj) remove_from_list(env,list,obj,(GFunc)xmlFreeNode,(GCompareFunc)strcmp,(OutConverter)jstring_to_xml_node)
+#define remove_from_list_of_objects(env,list,obj) remove_from_list(env,list,obj,(GFunc)g_object_unref,(GCompareFunc)gpointer_equal,(OutConverter)jobject_to_gobject)
#define add_to_list_of_strings(env,list,obj) add_to_list(env,list,obj,(OutConverter)jstring_to_string)
#define add_to_list_of_xml_nodes(env,list,obj) add_to_list(env,list,obj,(OutConverter)jstring_to_xml_node)
-#define add_to_list_of_objects(env,list,obj) add_to_list(env,list,obj,(OutConverter)jobject_to_gobject_and_ref)
-
-/* hashtable handling */
-/* Use property array cell[i % 2 = 0] = keys and cell[i % 2 = 1] = values */
-static jobjectArray get_hash(JNIEnv *env, char *clsName, GHashTable *hashtable, Converter convert);
-#define get_hash_of_strings(env,hash) get_hash(env,"java/lang/String",hash,(Converter)string_to_jstring)
-#define get_hash_of_objects(env,hash) get_hash(env,"java/lang/String",hash,(Converter)gobject_to_jobject_and_ref)
-static void set_hash(JNIEnv *env, GHashTable *hashtable, jobjectArray arr, OutConverter convert);
-#define set_hash_of_strings(env,hash,arr) set_hash(env,hash,arr,(OutConverter)jstring_to_string)
-#define set_hash_of_objects(env,hash,arr) set_hash(env,hash,arr,(OutConverter)jobject_to_gobject_and_ref)
-static void remove_from_hash(JNIEnv *env, GHashTable *hashtable, jstring key);
-#define remove_from_hash_of_strings(env,hash,key) remove_from_hash(env,hash,key)
-#define remove_from_hash_of_objects(env,hash,key) remove_from_hash(env,hash,key)
-static void add_to_hash(JNIEnv *env, GHashTable *hashtable, jstring key, jobject obj, OutConverter convert);
+// Use jobject_to_gobject_for_list because ref count must be augmented by one when inserted inside a list
+#define add_to_list_of_objects(env,list,obj) add_to_list(env,list,obj,(OutConverter)jobject_to_gobject_for_list)
+#define get_hash_of_strings(env,hash,jarr) get_hash(env,"java/lang/String",hash,(Converter)string_to_jstring, jarr)
+#define get_hash_of_objects(env,hash,jarr) get_hash(env,"java/lang/String",hash,(Converter)gobject_to_jobject_and_ref, jarr)
+//#define remove_from_hash_of_strings(env,hash,key) remove_from_hash(env,hash,key)
+//#define remove_from_hash_of_objects(env,hash,key) remove_from_hash(env,hash,key)
#define add_to_hash_of_strings(env,hash,key,obj) add_to_hash(env,hash,key,obj,(OutConverter)jstring_to_string)
-#define add_to_hash_of_objects(env,hash,key,obj) add_to_hash(env,hash,key,obj,(OutConverter)jobject_to_gobject_and_ref)
-static jobject get_hash_by_name(JNIEnv *env, GHashTable *hashtable, jstring key, Converter convert);
-#define get_hash_of_strings_by_name(end,hash,key) get_hash_by_name(end,hash,key,(Converter)string_to_jstring)
-#define get_hash_of_objects_by_name(end,hash,key) get_hash_by_name(end,hash,key,(Converter)gobject_to_jobject_and_ref)
+#define add_to_hash_of_objects(env,hash,key,obj) add_to_hash(env,hash,key,obj,(OutConverter)jobject_to_gobject_for_list)
+//#define get_hash_of_strings_by_name(end,hash,key) get_hash_by_name(end,hash,key,(Converter)string_to_jstring)
+//#define get_hash_of_objects_by_name(end,hash,key) get_hash_by_name(end,hash,key,(Converter)gobject_to_jobject_and_ref)
+
+/* Helper functions to access JNI interface functions */
+static int
+gpointer_equal(gpointer p1, gpointer p2) {
+ return p1 != p2;
+}
+static int
+new_object_with_gobject(JNIEnv *env, GObject *obj, char *clsName, jobject *jobj) {
+ jclass cls;
+ jmethodID mid;
+ g_error_if_fail(env && clsName && obj && G_IS_OBJECT(obj));
+ g_return_val_if_fail(cls = (*env)->FindClass(env, clsName), 0);
+ g_return_val_if_fail(mid = (*env)->GetMethodID(env, cls, "<init>", "(J)V"), 0);
+ g_return_val_if_fail(*jobj = (*env)->NewObject(env, cls, mid, PTR_TO_JLONG(obj)), 0);
+ return 1;
+}
+/** Convert a java string to a jstring */
+static int
+jstring_to_local_string(JNIEnv *env, jstring jstr, const char **str)
+{
+ g_error_if_fail(env);
-/* utility functions */
-static jlong
-get_jlong_field(JNIEnv *env, jobject *obj, char *field)
+ if (jstr) {
+ *str = (*env)->GetStringUTFChars(env, jstr, NULL);
+ g_return_val_if_fail(*str, 0);
+ } else {
+ *str = NULL;
+ }
+ return 1;
+}
+/** Release a local string. IT'S MANDATORY TO CALL THIS !!! */
+static void
+release_local_string(JNIEnv *env, jstring str, const char *utf_str) {
+ g_error_if_fail(env);
+
+ if (utf_str && str) {
+ (*env)->ReleaseStringUTFChars(env, str, utf_str);
+ }
+}
+static int
+get_jlong_field(JNIEnv *env, jobject obj, char *field, jlong *dest)
{
jclass cls;
jfieldID fid;
cls = (*env)->GetObjectClass(env, obj);
- if (cls == NULL)
- return 0;
+ g_return_val_if_fail(cls, 0);
fid = (*env)->GetFieldID(env, cls, field, "J");
- if (fid == NULL)
- return 0;
- return (*env)->GetLongField(env, obj, fid);
+ g_return_val_if_fail(fid, 0);
+ *dest = (*env)->GetLongField(env, obj, fid);
+ g_return_val_if_exception(0);
+
+ return 1;
}
static jclass
get_jclass_by_name(JNIEnv *env, char *name) {
return (*env)->FindClass(env,name);
}
+static int
+get_array_element(JNIEnv *env, jobjectArray arr, jsize i, jobject *dest) {
+ *dest = (*env)->GetObjectArrayElement(env, arr, i);
+ g_return_val_if_fail(! (*env)->ExceptionCheck(env), 0);
+ return 1;
+}
+static int
+set_array_element(JNIEnv *env, jobjectArray arr, jsize i, jobject value) {
+ (*env)->SetObjectArrayElement(env, arr, i, value);
+ g_return_val_if_exception(0);
+ return 1;
+}
+static int
+get_array_size(JNIEnv *env, jobjectArray jarr, jsize *dest) {
+ *dest = (*env)->GetArrayLength(env, jarr);
+ g_return_val_if_exception(0);
+ return 1;
+}
+static int
+create_object_array(JNIEnv *env, char *clsName, jsize size, jobjectArray *jarr) {
+ jclass cls;
-/* string handling impl */
-static jstring
-string_to_jstring(JNIEnv *env, const char* str)
-{
- if (str)
- return (*env)->NewStringUTF(env, str);
- else
+ g_error_if_fail(env && clsName && jarr);
+
+ cls = get_jclass_by_name(env, clsName);
+ g_return_val_if_fail(cls, 0);
+ *jarr = (*env)->NewObjectArray(env, size, get_jclass_by_name(env, clsName), NULL);
+ g_return_val_if_fail(*jarr, 0);
+ return 1;
+}
+static int nullWeakRef(JNIEnv *env, jweak weakRef) {
+ return weakRef && (*env)->IsSameObject(env, weakRef, NULL);
+}
+/** Return the shadow object associated with the gobject.
+ * If the weak global reference is dead, frees it.
+ * If not shadow object is present, return NULL. */
+static jobject
+get_shadow_object(JNIEnv *env, GObject *obj) {
+ jweak weakRef;
+
+ g_error_if_fail (obj && env);
+ weakRef = (jweak)g_object_get_qdata(obj, lasso_wrapper_key);
+ if (weakRef == NULL) {
+ return NULL;
+ } else if (nullWeakRef(env, weakRef)) {
+ /** Remove null weak ref. */
+ (*env)->DeleteWeakGlobalRef(env, weakRef);
+ g_object_set_qdata(obj, lasso_wrapper_key, NULL);
return NULL;
+ } else {
+ return (*env)->NewLocalRef(env, weakRef);
+ }
+}
+/** Sets the java shadow object associated with the GObject obj.
+ * If a shadow object is already present, frees its weak global reference.
+ * Replacing a non NULL weak global reference by another one should not happend.
+ * It means that two java shadow object for the same GObject exist at the same time
+ */
+static void
+set_shadow_object(JNIEnv *env, GObject *obj, jobject shadow_object) {
+ jweak weakRef;
+ jweak old_weakRef;
+
+ g_error_if_fail(obj && env);
+
+ old_weakRef = (jweak)g_object_get_qdata(obj, lasso_wrapper_key);
+ if (old_weakRef) {
+ if (shadow_object != NULL && ! (*env)->IsSameObject(env, old_weakRef, NULL)) {
+ g_warning("remplacement d'un shadow object non nulle par un shadow object non nulle %p %p", shadow_object, old_weakRef);
+ }
+ (*env)->DeleteWeakGlobalRef(env, old_weakRef);
+ }
+ g_object_set_qdata(obj, lasso_wrapper_key, NULL);
+ if (shadow_object) {
+ weakRef = (*env)->NewWeakGlobalRef(env, shadow_object);
+ g_object_set_qdata(obj, lasso_wrapper_key, weakRef);
+ }
+}
+/** Throw a new RuntimeException containing this message. */
+static void
+exception(JNIEnv *env, char *message) {
+ jclass cls = (*env)->FindClass(env, "java/lang/RuntimeException");
+ if (cls != NULL) {
+ (*env)->ThrowNew(env, "java/lang/RuntimeException", message);
+ }
+ (*env)->DeleteLocalRef(env, cls);
}
-static jstring
-string_to_jstring_and_free(JNIEnv *env, char* str)
-{
+/* Conversion fonctions */
+/** Convert a C string to java string. NULL is a valid C string giving a null
+ * java object. */
+static int
+string_to_jstring(JNIEnv *env, const char* str, jstring *jstr) {
if (str) {
- jstring ret = (*env)->NewStringUTF(env, str);
- g_free(str);
- return ret;
+ *jstr = (*env)->NewStringUTF(env, str);
+ g_return_val_if_fail(jstr, 0);
} else {
- return NULL;
+ *jstr = NULL;
}
+ return 1;
}
-static const char *
-jstring_to_string(JNIEnv *env, jstring str)
-{
+/** Convert a string to a java string then free it. Don't frees it
+ * if conversion failed. */
+static int
+string_to_jstring_and_free(JNIEnv *env, char* str, jstring *jstr) {
+ g_return_val_if_fail(string_to_jstring(env, str, jstr), 0);
if (str)
- return (*env)->GetStringUTFChars(env, str, NULL);
- else
- return NULL;
-}
-
-static const char *
-jstring_to_string_dup(JNIEnv *env, jstring jstr)
-{
- const char *str = jstring_to_string(env, jstr);
- char * ret = NULL;
-
- if (! str)
- return NULL;
-
- ret = g_strdup(str);
- release_utf_string(env, jstr, str);
- return ret;
+ g_free(str);
+ return 1;
}
-static void
-release_utf_string(JNIEnv *env, jstring str, const char *utf_str) {
- if (utf_str && str)
- (*env)->ReleaseStringUTFChars(env, str, utf_str);
+/** Convert a jstring to a C string and copy it. Returned string is owner by the caller.*/
+static int
+jstring_to_string(JNIEnv *env, jstring jstr, char **str) {
+ const char *local_str;
+ char * ret;
+
+ g_return_val_if_fail(jstring_to_local_string(env, jstr, &local_str), 0);
+ if (local_str) {
+ *str = g_strdup(local_str);
+ release_local_string(env, jstr, local_str);
+ if (!str) {
+ /* Maybe launch a OutOfMemoryException. */
+ exception(env, "could not alloc a copy of a jstring");
+ return 0;
+ }
+ } else {
+ *str = NULL;
+ }
+ return 1;
}
/* xmlNode handling */
-static jstring
-xml_node_to_jstring(JNIEnv *env, xmlNode *xmlnode)
-{
+static int
+xml_node_to_jstring(JNIEnv *env, xmlNode *xmlnode, jstring *jstr) {
xmlOutputBufferPtr buf;
- if (! xmlnode || ! env) {
- return NULL;
+ g_error_if_fail(env);
+ if (! xmlnode) {
+ *jstr = NULL;
+ return 1;
}
buf = xmlAllocOutputBuffer(NULL);
if (buf) {
- jstring ret = NULL;
+ int ret = 1;
xmlNodeDumpOutput(buf, NULL, xmlnode, 0, 1, NULL);
xmlOutputBufferFlush(buf);
+ char *str;
if (buf->conv == NULL) {
- ret = string_to_jstring(env, (char*)buf->buffer->content);
+ str = (char*)buf->buffer->content;
} else {
- ret = string_to_jstring(env, (char*)buf->conv->content);
+ str = buf->conv->content;
}
+ ret = string_to_jstring(env, str, jstr);
xmlOutputBufferClose(buf);
return ret;
} else {
- return NULL;
+ exception(env, "could not alloc an xml output buffer");
+ return 0;
}
+ return 1;
}
-static xmlNode*
-jstring_to_xml_node(JNIEnv *env, jstring string) {
- xmlDoc *doc;
- xmlNode *node;
- const char *str;
-
- str = jstring_to_string(env, string);
- if (str == NULL)
- return NULL;
-
- doc = xmlReadDoc((unsigned char *)str, NULL, NULL, XML_PARSE_NONET);
- node = xmlDocGetRootElement(doc);
- if (node != NULL) {
- node = xmlCopyNode(node, 1);
+/** Convert a java string to an xml node. Return 0 if it failed with an exception
+ * throwed. */
+static int
+jstring_to_xml_node(JNIEnv *env, jstring jstr, xmlNode **xmlnode) {
+ xmlDoc *doc = NULL;
+ xmlNode *node = NULL;
+ const char *local_str;
+ int ret = 1;
+
+ g_error_if_fail(env && xmlnode);
+ g_return_val_if_fail(jstring_to_local_string(env, jstr, &local_str), 0);
+
+ if (local_str) {
+ doc = xmlReadDoc((unsigned char *)local_str, NULL, NULL, XML_PARSE_NONET);
+ if (!doc) {
+ exception(env, "could not read an xml document");
+ ret = 0;
+ goto out;
+ }
+ node = xmlDocGetRootElement(doc);
+ if (node != NULL) {
+ node = xmlCopyNode(node, 1);
+ }
}
- xmlFreeDoc(doc);
- release_utf_string(env, string, str);
-
- return node;
+out:
+ *xmlnode = node;
+ if (doc)
+ xmlFreeDoc(doc);
+ if (jstr && local_str)
+ release_local_string(env, jstr, local_str);
+ return ret;
}
/* lasso objects handling impl */
-static jobject
-gobject_to_jobject_aux(JNIEnv *env, GObject *obj, gboolean doRef) {
- jobject *self;
-#define LASSO_ROOT "com/entrouvert/lasso/"
+static void
+create_class_name(char *dest, const char *typename) {
+ char *ret;
+
+ ret = strstr(typename, "Lasso");
+ if (ret) {
+ typename = ret+5;
+ }
+ strncpy(dest+sizeof(LASSO_ROOT)-1, typename,50);
+ dest[sizeof(LASSO_ROOT)+49] = 0;
+}
+/** Convert the GObject obj to a java object encapsulating it.
+ * If obj is NULL, return NULL.
+ * Throws if obj is not a GObject or if anyhting fail. */
+static int
+gobject_to_jobject_aux(JNIEnv *env, GObject *obj, gboolean doRef, jobject *jobj) {
+ jweak weakRef = NULL;
+ jobject self = NULL;
+ int ret = 1;
+
if (obj == NULL) {
- return NULL;
+ goto out;
+ }
+
+ if (! G_IS_OBJECT(obj)) {
+ exception(env, "tried to convert something that is not a GObject to a Java object");
+ ret = 0;
+ goto out;
}
- self = (jobject)g_object_get_qdata(obj, lasso_wrapper_key);
- if (self == NULL) {
- jclass nodeCls;
- jmethodID cid;
+ /* Try to get an already created java object. */
+ self = get_shadow_object(env, obj);
+ if (self) {
+ goto out;
+ } else {
+ /* Create the shadow object */
char clsName[sizeof(LASSO_ROOT)+50] = LASSO_ROOT;
- const char *typename = G_OBJECT_TYPE_NAME(obj);
- if (! typename) // Moche
- return NULL;
- typename = typename + 5;
- strncpy(clsName+sizeof(LASSO_ROOT)-1, typename,50);
- clsName[sizeof(LASSO_ROOT)+49] = 0;
- nodeCls = (*env)->FindClass(env, clsName);
- if (nodeCls == NULL) {
- return NULL;
- }
- cid = (*env)->GetMethodID(env, nodeCls, "<init>", "(J)V");
- if (cid == NULL) {
- return NULL;
- }
- self = (*env)->NewObject(env, nodeCls, cid, (jlong)(unsigned int)obj);
- if (self == NULL) {
- return NULL;
+ const char *typename;
+
+ typename = G_OBJECT_TYPE_NAME(obj);
+ create_class_name(clsName, typename);
+ if (! new_object_with_gobject(env, obj, clsName, &self)) {
+ ret = 0;
+ goto out;
}
- g_object_set_qdata_full(obj, lasso_wrapper_key, self, NULL);
+ set_shadow_object(env, obj, self);
+ /** If all goes well increment reference count eventually. */
if (doRef) {
g_object_ref(obj);
}
}
- return self;
+out:
+ *jobj = self;
+ return ret;
}
/** Get or create a new java object encapsulating this lasso GObject, do not increase ref count if created. */
-static jobject
-gobject_to_jobject(JNIEnv *env, GObject *obj) {
- return gobject_to_jobject_aux(env, obj, FALSE);
+static int
+gobject_to_jobject(JNIEnv *env, GObject *obj, jobject *jobj) {
+ return gobject_to_jobject_aux(env, obj, FALSE, jobj);
}
/** Get or create a new java object encapsulating this lasso GObject, increase ref count if created. */
-static jobject
-gobject_to_jobject_and_ref(JNIEnv *env, GObject *obj) {
- return gobject_to_jobject_aux(env, obj, TRUE);
+static int
+gobject_to_jobject_and_ref(JNIEnv *env, GObject *obj, jobject *jobj) {
+ return gobject_to_jobject_aux(env, obj, TRUE, jobj);
}
-/** Get the gobject encapsulated by the java object obj */
-static GObject*
-jobject_to_gobject(JNIEnv *env, jobject *obj) {
- return (GObject*)(int)get_jlong_field(env, obj, "cptr");
+/** Get the gobject encapsulated by the java object obj. If cptr is
+ * null return NULL.
+ * It throws and return 0 if anything fail unexpectedly. */
+static int
+jobject_to_gobject(JNIEnv *env, jobject obj, GObject **gobj) {
+ jlong value;
+ GObject *gobject;
+
+ g_error_if_fail(env);
+
+ if (! obj) {
+ *gobj = NULL;
+ return 1;
+ }
+ g_return_val_if_fail(get_jlong_field(env, obj, "cptr", &value), 0);
+ gobject = convert_jlong_to_gobject(value);
+ if (gobject && ! G_IS_OBJECT(gobject)) {
+#define s "jobject->cptr is not a pointer on a gobject: XXXXXXXXXXXXXXXXXXXXXXX"
+ char str[] = s;
+ snprintf(str, sizeof(s)-1, "jobject->cptr is not a pointer on a gobject = %p", gobject);
+ exception(env, str);
+#undef s
+ return 0;
+ } else {
+ *gobj = gobject;
+ return 1;
+ }
}
/** Get the gobject encapsulated by the java object obj and increase its ref count. The only
* use for this function is composed with set_list_of_objects or set_hash_of_object. */
-static GObject*
-jobject_to_gobject_and_ref(JNIEnv *env, jobject *obj) {
- GObject *ret;
-
- ret = jobject_to_gobject(env, obj);
- if (ret) {
- g_object_ref(obj);
+static int
+jobject_to_gobject_for_list(JNIEnv *env, jobject *obj, GObject **gobj) {
+ g_return_val_if_fail(jobject_to_gobject(env, obj, gobj), 0);
+ if (*gobj) {
+ g_object_ref(*gobj);
}
-
- return ret;
+ return 1;
}
+
/* List handling */
static void
free_glist(GList **list, GFunc free_function) {
- if (!list)
- return;
+ g_return_if_fail(list);
if (*list) {
if (free_function) {
g_list_foreach(*list, free_function, NULL);
}
g_list_free(*list);
}
- if (list)
- *list = NULL;
+ *list = NULL;
}
-static jobjectArray
-get_list(JNIEnv *env, char *clsName, GList *list, Converter convert) {
- jsize l = g_list_length(list),i;
- jobjectArray jarr;
+/** Get an object array from a GList*, convert C object to java object using
+ * the convert function.
+ *
+ * Can throw. If list is null or empty, return NULL.
+ */
+static int
+get_list(JNIEnv *env, char *clsName, GList *list, Converter convert, jobjectArray *jarr) {
+ jsize l,i;
jclass cls;
- if (!env || !list || !clsName || !convert) {
- return NULL;
+ g_error_if_fail (env && clsName && convert);
+ l = g_list_length(list);
+ if (!l) {
+ *jarr = NULL;
+ goto out;
}
cls = get_jclass_by_name(env, clsName);
- if (!cls) {
- return NULL;
- }
-
- jarr = (*env)->NewObjectArray(env, l, get_jclass_by_name(env, clsName), NULL);
- if (! jarr) {
- return NULL;
- }
+ g_return_val_if_fail(cls, 0);
+ g_return_val_if_fail(create_object_array(env, clsName, l, jarr), 0);
for (i=0;i<l;i++) {
jobject item;
- item = convert(env, list->data);
- if ((*env)->ExceptionOccurred(env)) {
- return NULL;
- }
- (*env)->SetObjectArrayElement(env, jarr, i, item);
- if ((*env)->ExceptionOccurred(env)) {
- return NULL;
- }
+ g_return_val_if_fail(convert(env, list->data, &item), 0);
+ g_return_val_if_fail(set_array_element(env, *jarr, i, item), 0);
list = g_list_next(list);
}
- return jarr;
+out:
+ return 1;
}
-static void
+/** Sets a GList* field using a java array of object. Use free_function if an old list exist.
+ * Use convert to convert the java objects to C values. */
+static int
set_list(JNIEnv *env, GList **list, jobjectArray jarr, GFunc free_function, OutConverter convert) {
jobject element;
jsize size;
jsize i;
-
- if (!list || !free_function || !convert || !env)
- return;
-
- free_glist(list, free_function);
- if (!jarr) {
- *list = NULL;
- return;
- }
- size = (*env)->GetArrayLength(env, jarr);
- for (i=0; i < size; i++) {
- element = (*env)->GetObjectArrayElement(env, jarr, i);
- if ((*env)->ExceptionOccurred(env)) {
- free_glist(list, free_function);
- return;
+ GList *new = NULL;
+
+ g_error_if_fail (list && free_function && convert && env);
+ if (jarr) {
+ if (! get_array_size(env, jarr, &size))
+ goto error;
+ for (i=0; i < size; i++) {
+ gpointer result;
+
+ if (! get_array_element(env, jarr, i, &element)
+ || ! convert(env, element, &result)) {
+ goto error;
+ }
+ new = g_list_append(new, result);
}
- *list = g_list_append(*list, convert(env, element));
}
-}
-static void
-remove_from_list(JNIEnv *env,GList **list,jobject obj,GFunc free_function,GCompareFunc compare,OutConverter convert) {
- void *c;
+ free_glist(list, free_function);
+ *list = new;
+ return 1;
+
+error:
+ free_glist(&new, free_function);
+ return 0;
+}
+/** Remove a value obtained via the convert function on obj from *list.
+ * It is searched inside *list using the compare function.
+ * If pointer is found, it is freed using the free_function.
+ * Return 0 if an exception was throwed.
+ **/
+static int
+remove_from_list(JNIEnv *env, GList **list, jobject obj, GFunc free_function, GCompareFunc compare, OutConverter convert) {
+ gpointer data;
GList *found;
- c = convert(env, obj);
- if ((*env)->ExceptionOccurred(env)) {
- return;
- }
- found = g_list_find_custom(*list, c, compare);
+ g_error_if_fail(env && list && compare && convert && free_function);
+ g_return_val_if_fail(obj, 1);
+ g_return_val_if_fail(convert(env, obj, &data), 0);
+ found = g_list_find_custom(*list, data, compare);
if (found) {
free_function(found->data, NULL);
*list = g_list_delete_link(*list, found);
}
+ return 1;
}
-static void
-add_to_list(JNIEnv* env,GList** list,jobject obj, OutConverter convert) {
- void *data;
+static int
+remove_from_list_of_strings(JNIEnv *env, GList **list, jstring jstr) {
+ const char *local_string;
+ GList *found;
- data = convert(env, obj);
- if ((*env)->ExceptionOccurred(env)) {
- return;
+ g_error_if_fail(env && list);
+ g_return_val_if_fail(jstr, 1);
+ g_return_val_if_fail(jstring_to_local_string(env, jstr, &local_string), 0);
+ found = g_list_find_custom(*list, local_string, (GCompareFunc)strcmp);
+ if (found) {
+ g_free(found->data);
+ *list = g_list_delete_link(*list, found);
}
- *list = g_list_append(*list, data);
+ release_local_string(env, jstr, local_string);
+ return 1;
}
-
-struct Aux {
- JNIEnv *env;
- Converter convert;
- gboolean crashed;
- int idx;
- jobjectArray jarr;
-};
-static void
-get_hash_aux(gpointer key, gpointer data, gpointer udata)
-{
- struct Aux *aux = (struct Aux*)udata;
- JNIEnv *env = aux->env;
- jobjectArray jarr = aux->jarr;
-
- if (! aux->crashed) {
- jstring jkey;
- jobject jvalue;
-
- jkey = string_to_jstring(env, key);
- if (!jkey) {
- aux->crashed = TRUE;
- return;
- }
- jvalue = aux->convert(env, data);
- if ((*env)->ExceptionOccurred(env)) {
- aux->crashed = TRUE;
- return;
- }
- (*env)->SetObjectArrayElement(env, jarr, aux->idx, jkey);
- if ((*env)->ExceptionOccurred(env)) {
- aux->crashed = TRUE;
- return;
- }
- (*env)->SetObjectArrayElement(env, jarr, aux->idx+1, jvalue);
- if ((*env)->ExceptionOccurred(env)) {
- aux->crashed = TRUE;
- return;
- }
- aux->idx += 2;
- }
+/** Add obj to GList *list.
+ * Returns 1.
+ * Returns 0 and throws if anything fail.
+ */
+static int
+add_to_list(JNIEnv* env, GList** list, jobject obj, OutConverter convert) {
+ gpointer data;
+
+ g_error_if_fail(env && list && convert);
+ g_return_val_if_fail(convert(env, obj, &data),0);
+ if (data)
+ *list = g_list_append(*list, data);
+ return 1;
}
/* Ghash table handling impl */
-/** Set a hash table from an array of size multiple of 2 */
-static jobjectArray
-get_hash(JNIEnv *env, char *clsName, GHashTable *hashtable,Converter convert)
+/** Create a java array from a GHashTable, using the convert function. */
+static int
+get_hash(JNIEnv *env, char *clsName, GHashTable *hashtable, Converter convert, jobjectArray *jarr)
{
- jsize l;
- jobjectArray jarr;
+ jsize l,i;
jclass cls;
- struct Aux udata = {env, convert, FALSE, 0, NULL };
- if (!env || !hashtable || !clsName || !convert) {
- return NULL;
- }
+ GList *keys = NULL, *values = NULL;
+ int ret = 1;
+
+ g_error_if_fail (env && hashtable && convert);
l = g_hash_table_size(hashtable);
- cls = get_jclass_by_name(env, clsName);
- if (!cls) {
- return NULL;
+ g_return_val_if_fail(create_object_array(env, clsName, 2*l, jarr), 0);
+ keys = g_hash_table_get_keys(hashtable);
+ values = g_hash_table_get_values(hashtable);
+ if (! (keys && values)) {
+ ret = 0;
+ exception(env, "cannot allocate for converting GHashTable to an array");
+ goto out;
}
-
- udata.jarr = (*env)->NewObjectArray(env, l, get_jclass_by_name(env, clsName), NULL);
- if (! jarr) {
- return NULL;
+ for (i=0; i < 2*l && keys && values; i+=2) {
+ jstring key;
+ jobject value;
+
+ if (! (string_to_jstring(env, (char*)keys->data, &key)
+ && convert(env, (gpointer)values->data, &value)
+ && set_array_element(env, *jarr, i, key)
+ && set_array_element(env, *jarr, i+1, value))) {
+ ret = 0;
+ goto out;
+ }
+ keys = g_list_next(keys);
+ values = g_list_next(values);
}
- g_hash_table_foreach (hashtable, (GHFunc)get_hash_aux, &udata);
- if (udata.crashed)
- return NULL;
- return udata.jarr;
+out:
+ if (keys)
+ g_list_free(keys);
+ if (values)
+ g_list_free(values);
+ return ret;
+}
+/** Fill a GHashTable with content of java array arr.
+ * Even indexed element coressponds to keys (jstring) and
+ * odd indexed one to value (GObject).
+ * Returns 1.
+ * Returns 0 and thows an exception if anything fail.
+ */
+static int
+set_hash_of_objects(JNIEnv *env, GHashTable *hashtable, jobjectArray jarr)
+{
+ jsize l, i;
+ gpointer *array;
+
+ g_error_if_fail (env && hashtable);
+ if (jarr) {
+ /** First increment ref count of object in jarr */
+ g_return_val_if_fail(get_array_size(env, jarr, &l), 0);
+ if (l % 2 != 0) {
+ exception(env, "java array not of an even size");
+ return 0;
+ }
+ for (i = 1; i < l; i += 2) {
+ jobject jobj;
+ GObject *gobj;
+
+ g_return_val_if_fail(get_array_element(env, jarr, i, &jobj), 0);
+ g_return_val_if_fail(jobject_to_gobject(env, jobj, &gobj), 0);
+ g_object_ref(gobj);
+ }
+ }
+ /** Remove old values, if hashtable is well initialized it should unref objects automatically. */
+ g_hashtable_remove_all(hashtable);
+ /** Insert new values */
+ if (jarr) {
+ for (i = 0; i < l; i += 2) {
+ jstring jkey;
+ char *key;
+ jobject jvalue;
+ GObject *value;
+
+ g_return_val_if_fail(get_array_element(env, jarr, i, &jkey), 0);
+ g_return_val_if_fail(get_array_element(env, jarr, i+1, &jvalue), 0);
+ g_return_val_if_fail(jstring_to_string(env, jkey, &key), 0);
+ if (! jobject_to_gobject(env, jvalue, &value)) {
+ if (key)
+ g_free(key);
+ g_hashtable_remove_all(hashtable);
+ return 0;
+ }
+ /* Can use insert because hash table is empty */
+ g_hash_table_insert (hashtable, key, value);
+ (*env)->DeleteLocalRef(env, jkey);
+ (*env)->DeleteLocalRef(env, jvalue);
+ }
+ }
+ return 1;
}
-static void set_hash(JNIEnv *env, GHashTable *hashtable, jobjectArray arr, OutConverter convert) {
+/** Insert a java String array, containing
+ * keys at odd indexes, and values at even indexes into an existing
+ * GHashTable. Old entries are lost, but hopefully deallocated by
+ * the hashtable free functions --- setted at creation, see GLib
+ * documentation.
+ *
+ * @param env the JNI context given by the JVM
+ * @param hashtable an existing GHashTable
+ * @param a ref to a java object Array of size multiple of two
+ *
+ * @return 1 if successful, 0 if anything bad happen.
+ */
+static int
+set_hash_of_strings(JNIEnv *env, GHashTable *hashtable, jobjectArray jarr) {
jsize l,i;
- if (! env || ! hashtable || ! arr || ! convert)
- return;
+ g_error_if_fail (env && hashtable);
- l = (*env)->GetArrayLength(env, arr);
- if ((*env)->ExceptionOccurred(env) || l % 2 != 0) {
- return;
- }
g_hash_table_remove_all(hashtable);
- for (i = 0; i < l; i += 2) {
- jobject key,item;
- const char *skey;
- void *value;
-
- key = (*env)->GetObjectArrayElement(env, arr, i);
- if ((*env)->ExceptionOccurred(env)) {
- return;
- }
- item = (*env)->GetObjectArrayElement(env, arr, i);
- if ((*env)->ExceptionOccurred(env)) {
- return;
- }
- value = convert(env, item);
- if ((*env)->ExceptionOccurred(env)) {
- return;
+ if (jarr) {
+ g_return_val_if_fail(get_array_size(env, jarr, &l), 0);
+ if (l % 2 != 0) {
+ exception(env, "java array not of an even size");
+ return 0;
}
- skey = jstring_to_string(env, (jstring)key);
- if ((*env)->ExceptionOccurred(env)) {
- return;
+ for (i = 0; i < l; i += 2) {
+ jstring jkey;
+ char *key;
+ jstring jvalue;
+ char *value;
+
+ g_return_val_if_fail(get_array_element(env, jarr, i, &jkey)
+ && get_array_element(env, jarr, i+1, &jvalue)
+ && jstring_to_string(env, jkey, &key), 0);
+ if (! key) {
+ exception(env, "key is null");
+ return 0;
+ }
+ if (! jstring_to_string(env, jvalue, &value), 0) {
+ if (key)
+ g_free(key);
+ g_hash_table_remove_all(hashtable);
+ return 0;
+ }
+ /* Can use insert because hash table is empty */
+ g_hash_table_insert(hashtable, key, value);
+ (*env)->DeleteLocalRef(env, jkey);
+ (*env)->DeleteLocalRef(env, jvalue);
}
- g_hash_table_insert(hashtable, g_strdup(skey), value);
- release_utf_string(env, key, skey);
}
+ return 1;
}
-static void remove_from_hash(JNIEnv *env, GHashTable *hashtable, jstring key) {
- const char *str;
- if (! env || !hashtable || !key) {
- return;
- }
- str = jstring_to_string(env, key);
- if (!str) {
- return;
- }
- g_hash_table_remove(hashtable, str);
- release_utf_string(env, key, str);
+/** Remove the value for the given key from hashtable. */
+static int
+remove_from_hash(JNIEnv *env, GHashTable *hashtable, jstring jkey) {
+ const char *key;
+
+ g_error_if_fail (env && hashtable);
+
+ g_return_val_if_fail(jstring_to_local_string(env, jkey, &key), 0);
+ g_hash_table_remove(hashtable, key);
+ release_local_string(env, jkey, key);
+ return 1;
}
-static void add_to_hash(JNIEnv *env, GHashTable *hashtable, jstring key, jobject obj, OutConverter convert)
+/** Add a jobject to an hashtable */
+static int
+add_to_hash(JNIEnv *env, GHashTable *hashtable, jstring jkey, jobject jvalue, OutConverter convert, GFunc free_function)
{
- void *data;
- const char *str;
-
- if (!env || !hashtable || !key || !obj || !convert) {
- return;
- }
- data = convert(env, obj);
- if ((*env)->ExceptionOccurred(env)) {
- return;
- }
- str = jstring_to_string(env,key);
- if (!str) {
- return;
- }
- g_hash_table_insert(hashtable, g_strdup(str), data);
- release_utf_string(env, key, str);
+ void *value = NULL;
+ char *key = NULL;
+
+ g_error_if_fail (env && hashtable && key && convert);
+
+ if (! (convert(env, jvalue, &value)
+ && jstring_to_string(env, jkey, &key)))
+ goto error;
+
+ g_hash_table_replace(hashtable, key, value);
+ return 1;
+error:
+ if (key)
+ g_free(key);
+ if (value)
+ free_function(value, NULL);
+ return 0;
}
-static jobject
-get_hash_by_name(JNIEnv *env, GHashTable *hashtable, jstring key, Converter convert)
+static int
+get_hash_by_name(JNIEnv *env, GHashTable *hashtable, jstring jkey, Converter convert, jobject *jvalue)
{
- void *data;
- const char *str;
+ const char *key;
+ gpointer value;
- if (! env || !hashtable || !key || !convert) {
- return NULL;
- }
- str = jstring_to_string(env,key);
- if (!str) {
- return NULL;
- }
- data = g_hash_table_lookup(hashtable,str);
- release_utf_string(env, key, str);
- return convert(env, data);
+ g_error_if_fail (env && hashtable && convert);
+
+ g_return_val_if_fail(jstring_to_local_string(env, jkey, &key), 0);
+ value = g_hash_table_lookup(hashtable, key);
+ release_local_string(env, jkey, key);
+ return convert(env, value, jvalue);
}
/* JNI Functions */
JNIEXPORT void JNICALL Java_com_entrouvert_lasso_LassoJNI_init2(JNIEnv *env, jclass cls) {
lasso_wrapper_key = g_quark_from_static_string("JavaLasso::wrapper");
}
+JNIEXPORT void JNICALL Java_com_entrouvert_lasso_LassoJNI_destroy(JNIEnv *env, jclass cls, jlong cptr) {
+ GObject *obj = (GObject*)(ptrdiff_t)cptr;
+ set_shadow_object(env, obj, NULL);
+ g_object_unref(obj);
+}
+JNIEXPORT void JNICALL Java_com_entrouvert_lasso_LassoJNI_set_1shadow_1object(JNIEnv *env, jclass cls, jlong cptr, jobject shadow_object) {
+ GObject *gobj;
+
+ gobj = convert_jlong_to_gobject(cptr);
+ set_shadow_object(env, gobj, shadow_object);
+}
diff --git a/bindings/overrides.xml b/bindings/overrides.xml
index 418ee2e9..8cfa9ffc 100644
--- a/bindings/overrides.xml
+++ b/bindings/overrides.xml
@@ -18,6 +18,8 @@
<!-- LassoWsfProfile -->
<func name="lasso_wsf_profile_get_identity" return_owner="false" />
<func name="lasso_wsf_profile_get_session" return_owner="false" />
+ <!-- LassoIdentity -->
+ <func name="lasso_identity_get_federation" return_owner="false" />
<!-- LassoServer -->
<func name="lasso_server_new">
<param name="private_key" optional="true"/>
@@ -78,6 +80,8 @@
<func name="lasso_lib_federation_termination_notification_new_full" return_type="LassoLibFederationTerminationNotification*"/>
<func name="lasso_lib_name_identifier_mapping_request_new_full" return_type="LassoLibNameIdentifierMappingRequest*"/>
<func name="lasso_lib_register_name_identifier_request_new_full" return_type="LassoLibRegisterNameIdentifierRequest*"/>
+ <!-- LassoServer -->
+ <func name="lasso_server_get_provider" return_owner="false" />
<!-- Exceptions -->
<exception>