You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by fc...@apache.org on 2011/06/14 17:40:56 UTC

svn commit: r1135652 - in /incubator/stanbol/trunk: commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/ enhancer/generic/jsonld/ enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/ enhancer/generic/jsonld/src/test/j...

Author: fchrist
Date: Tue Jun 14 15:40:56 2011
New Revision: 1135652

URL: http://svn.apache.org/viewvc?rev=1135652&view=rev
Log:
STANBOL-220 STANBOL-221 Added first version of a JSON-LD parser. Extended JSON-LD API with JsonLdIRI. Added unit tests.

Added:
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdIRI.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdParser.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdParserTest.java
Modified:
    incubator/stanbol/trunk/commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/JsonLdSerializerProviderTest.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/pom.xml
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLd.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdResource.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonSerializer.java
    incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdTest.java

Modified: incubator/stanbol/trunk/commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/JsonLdSerializerProviderTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/JsonLdSerializerProviderTest.java?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/JsonLdSerializerProviderTest.java (original)
+++ incubator/stanbol/trunk/commons/web/base/src/test/java/org/apache/stanbol/commons/web/base/writers/JsonLdSerializerProviderTest.java Tue Jun 14 15:40:56 2011
@@ -163,7 +163,7 @@ public class JsonLdSerializerProviderTes
         jsonldProvider.setUseTypeCoercion(true);
         jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
 
-        String expected = "{\"#\":{\"dbpedia\":\"http:\\/\\/dbpedia.org\\/ontology\\/\",\"dcterms\":\"http:\\/\\/purl.org\\/dc\\/terms\",\"enhancer\":\"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\"xmlns\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\"#types\":{\"http:\\/\\/fise.iks-project.eu\\/ontology\\/end\":\"xmlns:int\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/selected-text\":\"xmlns:string\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/selection-context\":\"xmlns:string\",\"http:\\/\\/fise.iks-project.eu\\/ontology\\/start\":\"xmlns:int\",\"http:\\/\\/purl.org\\/dc\\/terms\\/created\":\"xmlns:dateTime\"}},\"@\":\"<urn:iks-project:enhancer:test:text-annotation:Person>\",\"a\":[\"<enhancer:Enhancement>\",\"<enhancer:TextAnnotation>\"],\"dcterms:\\/created\":\"" + this.expectedW3CFormattedDate + "\",\"dcterms:\\/creator\":\"<urn:iks-project:enhancer:test:dummyEngine>\",\"dcterms:\\/type\":\"<dbpedia:Person>\",\"enhancer:end\":20,\"enhancer:selected-text\":\"Pa
 trick Marshall\",\"enhancer:selection-context\":\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\",\"enhancer:start\":4}";
+        String expected = "{\"#\":{\"dbpedia\":\"http:\\/\\/dbpedia.org\\/ontology\\/\",\"dcterms\":\"http:\\/\\/purl.org\\/dc\\/terms\",\"enhancer\":\"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\"xmlns\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\"#types\":{\"dcterms:\\/created\":\"xmlns:dateTime\",\"enhancer:end\":\"xmlns:int\",\"enhancer:selected-text\":\"xmlns:string\",\"enhancer:selection-context\":\"xmlns:string\",\"enhancer:start\":\"xmlns:int\"}},\"@\":\"<urn:iks-project:enhancer:test:text-annotation:Person>\",\"a\":[\"<enhancer:Enhancement>\",\"<enhancer:TextAnnotation>\"],\"dcterms:\\/created\":\"" + this.expectedW3CFormattedDate + "\",\"dcterms:\\/creator\":\"<urn:iks-project:enhancer:test:dummyEngine>\",\"dcterms:\\/type\":\"<dbpedia:Person>\",\"enhancer:end\":20,\"enhancer:selected-text\":\"Patrick Marshall\",\"enhancer:selection-context\":\"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University 
 of Otago.\",\"enhancer:start\":4}";
         String result = serializedGraph.toString();
         Assert.assertEquals(expected, result);
     }    
@@ -208,7 +208,7 @@ public class JsonLdSerializerProviderTes
         jsonldProvider.setUseTypeCoercion(true);
         jsonldProvider.serialize(serializedGraph, ci.getMetadata(), formatIdentifier);
 
-        String expected = "{\n    \"#\": {\n        \"dbpedia\": \"http:\\/\\/dbpedia.org\\/ontology\\/\",\n        \"dcterms\": \"http:\\/\\/purl.org\\/dc\\/terms\",\n        \"enhancer\": \"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\n        \"xmlns\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\n        \"#types\": {\n            \"http:\\/\\/fise.iks-project.eu\\/ontology\\/end\": \"xmlns:int\",\n            \"http:\\/\\/fise.iks-project.eu\\/ontology\\/selected-text\": \"xmlns:string\",\n            \"http:\\/\\/fise.iks-project.eu\\/ontology\\/selection-context\": \"xmlns:string\",\n            \"http:\\/\\/fise.iks-project.eu\\/ontology\\/start\": \"xmlns:int\",\n            \"http:\\/\\/purl.org\\/dc\\/terms\\/created\": \"xmlns:dateTime\"\n        }\n    },\n    \"@\": \"<urn:iks-project:enhancer:test:text-annotation:Person>\",\n    \"a\": [\n        \"<enhancer:Enhancement>\",\n        \"<enhancer:TextAnnotation>\"\n    ],\n    \"dcterms:\\/created\": \"" +
  this.expectedW3CFormattedDate + "\",\n    \"dcterms:\\/creator\": \"<urn:iks-project:enhancer:test:dummyEngine>\",\n    \"dcterms:\\/type\": \"<dbpedia:Person>\",\n    \"enhancer:end\": 20,    \"enhancer:selected-text\": \"Patrick Marshall\",\n    \"enhancer:selection-context\": \"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\",\n    \"enhancer:start\": \n}";
+        String expected = "{\n    \"#\": {\n        \"dbpedia\": \"http:\\/\\/dbpedia.org\\/ontology\\/\",\n        \"dcterms\": \"http:\\/\\/purl.org\\/dc\\/terms\",\n        \"enhancer\": \"http:\\/\\/fise.iks-project.eu\\/ontology\\/\",\n        \"xmlns\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\n        \"#types\": {\n            \"dcterms:\\/created\": \"xmlns:dateTime\",\n            \"enhancer:end\": \"xmlns:int\",\n            \"enhancer:selected-text\": \"xmlns:string\",\n            \"enhancer:selection-context\": \"xmlns:string\",\n            \"enhancer:start\": \"xmlns:int\"\n        }\n    },\n    \"@\": \"<urn:iks-project:enhancer:test:text-annotation:Person>\",\n    \"a\": [\n        \"<enhancer:Enhancement>\",\n        \"<enhancer:TextAnnotation>\"\n    ],\n    \"dcterms:\\/created\": \"" + this.expectedW3CFormattedDate + "\",\n    \"dcterms:\\/creator\": \"<urn:iks-project:enhancer:test:dummyEngine>\",\n    \"dcterms:\\/type\": \"<dbpedia:Person>\",\
 n    \"enhancer:end\": 20,\n    \"enhancer:selected-text\": \"Patrick Marshall\",\n    \"enhancer:selection-context\": \"Dr. Patrick Marshall (1869 - November 1950) was a geologist who lived in New Zealand and worked at the University of Otago.\",\n    \"enhancer:start\": 4\n}";
         String result = serializedGraph.toString();
         Assert.assertEquals(expected, result);
     }

Modified: incubator/stanbol/trunk/enhancer/generic/jsonld/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/pom.xml?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/pom.xml (original)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/pom.xml Tue Jun 14 15:40:56 2011
@@ -1,62 +1,76 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
-	<modelVersion>4.0.0</modelVersion>
+  <modelVersion>4.0.0</modelVersion>
 
-	<parent>
-		<groupId>org.apache.stanbol</groupId>
-		<artifactId>org.apache.stanbol.enhancer.parent</artifactId>
-		<version>0.9-SNAPSHOT</version>
-		<relativePath>../../parent</relativePath>
-	</parent>
-
-	<groupId>org.apache.stanbol</groupId>
-	<artifactId>org.apache.stanbol.jsonld</artifactId>
-	<packaging>bundle</packaging>
-
-	<name>Apache Stanbol JSON-LD API</name>
-	<description>The FISE JSON-LD API</description>
-
-	<inceptionYear>2010</inceptionYear>
-
-    <scm>
-        <connection>
-            scm:svn:http://svn.apache.org/repos/asf/incubator/stanbol/trunk/enhancer/generic/jsonld/
-        </connection>
-        <developerConnection>
-            scm:svn:https://svn.apache.org/repos/asf/incubator/stanbol/trunk/enhancer/generic/jsonld/
-        </developerConnection>
-        <url>http://incubator.apache.org/stanbol/</url>
-    </scm>
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.felix</groupId>
-				<artifactId>maven-bundle-plugin</artifactId>
-				<extensions>true</extensions>
-				<configuration>
-					<instructions>
-						<Export-Package>
-							org.apache.stanbol.jsonld.*;version=${pom.version}
-            			</Export-Package>
-					</instructions>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
-
-	<dependencies>
-		<dependency>
-			<groupId>org.codehaus.jettison</groupId>
-			<artifactId>jettison</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
+  <parent>
+    <groupId>org.apache.stanbol</groupId>
+    <artifactId>org.apache.stanbol.enhancer.parent</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <relativePath>../../parent</relativePath>
+  </parent>
+
+  <groupId>org.apache.stanbol</groupId>
+  <artifactId>org.apache.stanbol.jsonld</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Apache Stanbol JSON-LD API</name>
+  <description>The Stanbol JSON-LD API to create JSON-LD structures, parse them from String representation
+  and to serialize them to Strings.
+  </description>
+
+  <inceptionYear>2010</inceptionYear>
+
+  <scm>
+    <connection>
+      scm:svn:http://svn.apache.org/repos/asf/incubator/stanbol/trunk/enhancer/generic/jsonld/
+    </connection>
+    <developerConnection>
+      scm:svn:https://svn.apache.org/repos/asf/incubator/stanbol/trunk/enhancer/generic/jsonld/
+    </developerConnection>
+    <url>http://incubator.apache.org/stanbol/</url>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.apache.stanbol.jsonld.*;version=${pom.version}
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+    </dependency>
+   
+    <!-- Logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>    
+  </dependencies>
 
 </project>

Modified: incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLd.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLd.java?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLd.java (original)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLd.java Tue Jun 14 15:40:56 2011
@@ -9,12 +9,22 @@ import java.util.Map;
 import java.util.TreeMap;
 
 /**
- * JSON-LD serialization API.
+ * The JsonLd class provides an API to create a JSON-LD object structure and to serialize this structure.
  * 
- * @author fabianc
+ * <p>
+ * This implementation is based on the JSON-LD specification version 20110201. Available online at <a
+ * href="http://www.json-ld.org/spec/ED/20110201/">http://www.json-ld.org/spec/ED/20110201/</a>.
+ * 
+ * @author Fabian Christ
  */
 public class JsonLd {
 
+    public static final String CONTEXT = "@context";
+    public static final String TYPES = "#types";
+    public static final String PROFILE = "@profile";
+    public static final String SUBJECT = "@";
+    public static final String IRI = "@iri";
+
     // Map Namespace -> Prefix
     private Map<String,String> namespacePrefixMap = new HashMap<String,String>();
 
@@ -22,11 +32,8 @@ public class JsonLd {
     private Map<String,JsonLdResource> resourceMap = new TreeMap<String,JsonLdResource>(new JsonComparator());
 
     /**
-     * Flag to control whether the namespace prefix map should be used to shorten IRIs to prefix notation
-     * during serialization. Default value is <code>true</code>.<br />
-     * <br />
-     * <b>Note:</b> If you already put values into this JSON-LD instance with prefix notation, you should set
-     * this to <code>false</code> before starting the serialization.
+     * Flag to control whether the namespace prefix map should be used to shorten URIs to CURIEs during
+     * serialization. Default value is <code>true</code>.
      */
     private boolean applyNamespaces = true;
 
@@ -37,11 +44,44 @@ public class JsonLd {
     private boolean useJointGraphs = true;
 
     /**
-     * Flag to control whether type coercion should be applied. Default value is <code>true</code>.
+     * Flag to control whether type coercion should be applied on serialization. Default value is
+     * <code>false</code>.
      */
     private boolean useTypeCoercion = false;
 
     /**
+     * Flag that indicates whether this JSON-LD object represents a JSON-LD profile.
+     */
+    private final boolean representsProfile;
+
+    public JsonLd() {
+        this.representsProfile = false;
+    }
+
+    public JsonLd(boolean representsProfile) {
+        this.representsProfile = representsProfile;
+    }
+
+    /**
+     * Adds the given resource to this JsonLd object using the resource's subject as key. If the key is NULL
+     * and there does not exist a resource with an empty String as key the resource will be added using
+     * an empty String ("") as key. Otherwise an @IllegalArgumentException is thrown.
+     * 
+     * @param resource
+     */
+    public void put(JsonLdResource resource) {
+        if (resource.getSubject() != null) {
+            this.resourceMap.put(resource.getSubject(), resource);
+        }
+        else if (!this.resourceMap.containsKey("")) {
+            this.resourceMap.put("", resource);
+        }
+        else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
      * Add the given resource to this JsonLd object using the resourceId as key.
      * 
      * @param resourceId
@@ -51,6 +91,14 @@ public class JsonLd {
         this.resourceMap.put(resourceId, resource);
     }
 
+    /**
+     * Serializes the JSON-LD object structures to a String.
+     * 
+     * <p>
+     * If you want to have a formatted output with indentation, use the toString(int indent) variant.
+     * 
+     * @return JSON-LD as unformatted String.
+     */
     @Override
     public String toString() {
         if (useJointGraphs) {
@@ -64,6 +112,14 @@ public class JsonLd {
         }
     }
 
+    /**
+     * Serializes the JSON-LD object structure to a beautified String using indentation. The output is
+     * formatted using the specified indentation size.
+     * 
+     * @param indent
+     *            Number of whitespace chars used for indentation.
+     * @return JSON-LD as formatted String.
+     */
     public String toString(int indent) {
         if (useJointGraphs) {
             Map<String,Object> json = createJointGraph();
@@ -97,8 +153,13 @@ public class JsonLd {
                 }
 
                 // put subject
-                if (resource.getSubject() != null) {
-                    subjectObject.put("@", resource.getSubject());
+                if (resource.getSubject() != null && !resource.getSubject().isEmpty()) {
+                    subjectObject.put(SUBJECT, handleCURIEs(resource.getSubject()));
+                }
+
+                // put profile
+                if (resource.getProfile() != null && !resource.getProfile().isEmpty()) {
+                    subjectObject.put(PROFILE, handleCURIEs(resource.getProfile()));
                 }
 
                 // put types
@@ -130,9 +191,16 @@ public class JsonLd {
 
                 JsonLdResource resource = resourceMap.get(subject);
 
-                // put subject
-                if (resource.getSubject() != null) {
-                    subjectObject.put("@", resource.getSubject());
+                // put subject if this is not a profile
+                if (!this.representsProfile) {
+                    if (resource.getSubject() != null && !resource.getSubject().isEmpty()) {
+                        subjectObject.put(SUBJECT, handleCURIEs(resource.getSubject()));
+                    }
+                }
+
+                // put profile
+                if (resource.getProfile() != null && !resource.getProfile().isEmpty()) {
+                    subjectObject.put(PROFILE, handleCURIEs(resource.getProfile()));
                 }
 
                 // put types
@@ -180,7 +248,7 @@ public class JsonLd {
         if (!resource.getTypes().isEmpty()) {
             List<String> types = new ArrayList<String>();
             for (String type : resource.getTypes()) {
-                types.add(applyNamespace(type));
+                types.add(handleCURIEs(type));
             }
             if (types.size() == 1) {
                 subjectObject.put("a", types.get(0));
@@ -197,84 +265,207 @@ public class JsonLd {
             }
         }
     }
-    
+
     private void putCoercionTypes(Map<String,Object> jsonObject, Map<String,String> coercionMap) {
         if (!coercionMap.isEmpty()) {
-            if (this.applyNamespaces) {
-                Map<String,String> nsCoercionMap = new TreeMap<String,String>(new JsonComparator()); 
-                for (String property : coercionMap.keySet()) {
-                    nsCoercionMap.put(property, applyNamespace(coercionMap.get(property)));
-                }
-                jsonObject.put("#types", nsCoercionMap);
-            }
-            else {
-                jsonObject.put("#types", coercionMap);
+            Map<String,String> nsCoercionMap = new TreeMap<String,String>(new JsonComparator());
+            for (String property : coercionMap.keySet()) {
+                nsCoercionMap.put(handleCURIEs(property), handleCURIEs(coercionMap.get(property)));
             }
+            jsonObject.put("#types", nsCoercionMap);
         }
     }
 
     private void putProperties(Map<String,Object> jsonObject, JsonLdResource resource) {
-        for (String property : resource.getPropertyMap().keySet()) {
-            Object value = resource.getPropertyMap().get(property);
+        putProperties(jsonObject, resource.getPropertyMap(), resource.getCoercionMap());
+    }
+
+    private void putProperties(Map<String,Object> outputObject,
+                               Map<String,Object> inputMap,
+                               Map<String,String> coercionMap) {
+        for (String property : inputMap.keySet()) {
+            Object value = inputMap.get(property);
             if (value instanceof String) {
                 String strValue = (String) value;
-                if (!this.useTypeCoercion) {
-                    String type = resource.getCoercionTypeOf(property);
+                if (coercionMap != null) {
+                    String type = coercionMap.get(property);
                     if (type != null) {
-                        strValue = formatWithType(strValue, type);
+                        if (this.useTypeCoercion) {
+                            strValue = (String)doCoerce(strValue, type);
+                        } else {
+                            strValue = unCoerce(strValue, type);
+                        }
                     }
                 }
-                value = applyNamespace(strValue);
-                jsonObject.put(applyNamespace(property), value);
-            } else if (value instanceof String[]) {
-                String[] stringArray = (String[]) value;
-                List<String> valueList = new ArrayList<String>();
-                for (String uri : stringArray) {
-                    valueList.add(applyNamespace(uri));
-                }
-                List<Object> jsonArray = new ArrayList<Object>(valueList);
-                jsonObject.put(applyNamespace(property), jsonArray);
+                value = handleCURIEs(strValue);
+                outputObject.put(handleCURIEs(property), value);
             } else if (value instanceof Object[]) {
-                Object[] objectArray = (Object[]) value;
-                List<Object> jsonArray = new ArrayList<Object>();
-                for (Object object : objectArray) {
-                    jsonArray.add(object);
-                }
-                jsonObject.put(applyNamespace(property), jsonArray);
+                Object[] arrayValue = (Object[]) value;
+                putProperties(outputObject, property, arrayValue, coercionMap);
+            } else if (value instanceof Map<?,?>) {
+                Map<String,Object> valueMap = (Map<String,Object>) value;
+                Map<String,Object> subOutputObject = new HashMap<String,Object>();
+                outputObject.put(handleCURIEs(property), subOutputObject);
+                putProperties(subOutputObject, valueMap, coercionMap);
+            } else if (value instanceof JsonLdIRI) {
+                JsonLdIRI iriValue = (JsonLdIRI) value;
+                Map<String,Object> iriObject = new HashMap<String,Object>();
+                iriObject.put("@iri", handleCURIEs(iriValue.getIRI()));
+                outputObject.put(handleCURIEs(property), iriObject);
             } else {
-                if (!this.useTypeCoercion) {
-                    String type = resource.getCoercionTypeOf(property);
+                if (coercionMap != null) {
+                    String type = coercionMap.get(property);
                     if (type != null) {
-                        String strValue = formatWithType(value.toString(), type);
-                        jsonObject.put(applyNamespace(property), applyNamespace(strValue));
-                    }
-                    else {
-                        jsonObject.put(applyNamespace(property), value);
+                        Object objValue = null;
+                        if (this.useTypeCoercion) {
+                            objValue = doCoerce(value.toString(), type);
+                        } else {
+                            objValue = unCoerce(value.toString(), type);
+                        }
+                        
+                        if (objValue instanceof String) {
+                            String strValue = (String) objValue;
+                            outputObject.put(handleCURIEs(property), handleCURIEs(strValue));
+                        }
+                        else {
+                            outputObject.put(handleCURIEs(property), objValue);
+                        }
+                    } else {
+                        outputObject.put(handleCURIEs(property), value);
                     }
                 } else {
-                    jsonObject.put(applyNamespace(property), value);
+                    outputObject.put(handleCURIEs(property), value);
                 }
             }
         }
     }
 
-    private String formatWithType(String strValue, String type) {
-        strValue = "\"" + strValue + "\"^^<" + type + ">";
+    private void putProperties(Map<String,Object> outputObject,
+                               String property,
+                               Object[] arrayValue,
+                               Map<String,String> coercionMap) {
+        if (arrayValue instanceof String[]) {
+            String[] stringArray = (String[]) arrayValue;
+            List<String> valueList = new ArrayList<String>();
+            for (String uri : stringArray) {
+                valueList.add(handleCURIEs(uri));
+            }
+            outputObject.put(handleCURIEs(property), valueList);
+        } else {
+            List<Object> valueList = new ArrayList<Object>();
+            for (Object object : arrayValue) {
+                if (object instanceof Map<?,?>) {
+                    // The value of an array element is a Map. Handle maps recursively.
+                    Map<String,Object> inputMap = (Map<String,Object>) object;
+                    Map<String,Object> subOutputObject = new HashMap<String,Object>();
+                    valueList.add(subOutputObject);
+                    putProperties(subOutputObject, inputMap, coercionMap);
+                } else if (object instanceof JsonLdIRI) {
+                    JsonLdIRI iriValue = (JsonLdIRI) object;
+                    Map<String,Object> iriObject = new HashMap<String,Object>();
+                    iriObject.put("@iri", handleCURIEs(iriValue.getIRI()));
+                    valueList.add(iriObject);
+                } else {
+                    // Don't know what it is - just add it
+                    valueList.add(object);
+                }
+            }
+
+            // Add the converted values
+            outputObject.put(handleCURIEs(property), valueList);
+        }
+    }
+
+    /**
+     * Appends the type to the Value if not present.
+     * 
+     * @param strValue
+     * @param type
+     * @return
+     */
+    private String unCoerce(String strValue, String type) {
+        String typeSuffix = "^^" + unCURIE((type));
+        if (!strValue.endsWith(typeSuffix)) {
+            strValue = "\"" + strValue + "\"^^<" + type + ">";
+        }
+        return strValue;
+    }
+
+    /**
+     * Removes the type from the value and handles conversion to Integer and Boolean.
+     * 
+     * @param strValue
+     * @param type
+     * @return
+     */
+    private Object doCoerce(String strValue, String type) {
+        String typeSuffix = "^^" + unCURIE((type));
+        strValue = strValue.replace(typeSuffix, "");
+        strValue = strValue.replaceAll("\"", "");
+        return convertValueType(strValue);
+    }
+
+    /**
+     * Converts a given object to Integer or Boolean if the object is instance of one of those types.
+     * 
+     * @param strValue
+     * @return
+     */
+    private Object convertValueType(String strValue) {
+        // check if value can be interpreted as integer
+        try {
+            return Integer.valueOf(strValue);
+        }
+        catch (Throwable t) {};
+        
+        // check if value can be interpreted as boolean
+        if (strValue.equalsIgnoreCase("true") || strValue.equalsIgnoreCase("false")) {
+            return Boolean.valueOf(strValue);
+        }
+        
         return strValue;
     }
+    
+    /**
+     * Convert URI to CURIE if namespaces should be applied and CURIEs to URIs if namespaces should not be
+     * applied.
+     * 
+     * @param uri
+     *            That may be in CURIE form.
+     * @return
+     */
+    private String handleCURIEs(String uri) {
+        if (this.applyNamespaces) {
+            uri = doCURIE(uri);
+        } else {
+            uri = unCURIE(uri);
+        }
 
-    private String applyNamespace(String uri) {
-        if (applyNamespaces) {
-            for (String namespace : namespacePrefixMap.keySet()) {
-                String prefix = namespacePrefixMap.get(namespace) + ":";
-                uri = uri.replaceAll(namespace, prefix);
+        return uri;
+    }
+
+    private String doCURIE(String uri) {
+        for (String namespace : namespacePrefixMap.keySet()) {
+            String prefix = namespacePrefixMap.get(namespace) + ":";
+            if (!uri.startsWith(prefix)) {
+                uri = uri.replace(namespace, prefix);
+            }
+        }
+        return uri;
+    }
+
+    private String unCURIE(String uri) {
+        for (String namespace : namespacePrefixMap.keySet()) {
+            String prefix = namespacePrefixMap.get(namespace) + ":";
+            if (uri.startsWith(prefix)) {
+                uri = uri.replace(prefix, namespace);
             }
         }
         return uri;
     }
 
     /**
-     * Return the JSON-LD Resource for the given subject.
+     * Return the JSON-LD resource for the given subject.
      */
     public JsonLdResource getResource(String subject) {
         return resourceMap.get(subject);
@@ -372,4 +563,12 @@ public class JsonLd {
         this.useTypeCoercion = useTypeCoercion;
     }
 
+    /**
+     * Check whether this JSON-LD object represents a JSON-LD profile.
+     * 
+     * @return <code>true</code> if this is a profile, <code>false</code> otherwise.
+     */
+    public boolean representsProfile() {
+        return this.representsProfile;
+    }
 }

Added: incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdIRI.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdIRI.java?rev=1135652&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdIRI.java (added)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdIRI.java Tue Jun 14 15:40:56 2011
@@ -0,0 +1,15 @@
+package org.apache.stanbol.jsonld;
+
+public class JsonLdIRI {
+
+    private final String IRI;
+
+    public JsonLdIRI(String IRI) {
+        this.IRI = IRI;
+    }
+    
+    public String getIRI() {
+        return IRI;
+    }
+
+}

Added: incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdParser.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdParser.java?rev=1135652&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdParser.java (added)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdParser.java Tue Jun 14 15:40:56 2011
@@ -0,0 +1,231 @@
+package org.apache.stanbol.jsonld;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The JsonLdParser can be used to parse a given JSON-LD String representation
+ * into a JSON-LD data structure.
+ *
+ * @author Fabian Christ
+ */
+public class JsonLdParser {
+
+    private static Logger logger = LoggerFactory.getLogger(JsonLdParser.class);
+
+    /**
+     * Parse the given String into a JSON-LD data structure.
+     * 
+     * @param jsonLdString A JSON-LD String.
+     * @return JSON-LD data structure.
+     */
+    public static JsonLd parse(String jsonLdString) {
+        JsonLd jld = null;
+
+        JSONObject jo = parseJson(jsonLdString);
+        if (jo != null) {
+            if (jo.has(JsonLd.CONTEXT)) {
+                try {
+                    JSONObject ctx = jo.getJSONObject(JsonLd.CONTEXT);
+                    if (ctx.has(JsonLd.TYPES)) {
+                        jld = new JsonLd(true);
+                    }
+                } catch (JSONException e) { /* ignore */}
+            }
+            if (jld == null) {
+                jld = new JsonLd();
+            }
+            parseSubject(jo, jld, 1, null);
+        }
+
+        return jld;
+    }
+
+    /**
+     * Parses a single subject.
+     * 
+     * @param jo
+     *            JSON object that holds the subject's data.
+     * @param jld
+     *            JsonLd object to add the created subject resource.
+     */
+    private static void parseSubject(JSONObject jo, JsonLd jld, int bnodeCount, String profile) {
+
+        // The root subject is used for cases where no explicit subject is specified. We need
+        // at least one dummy subject (bnode) to support type coercion because types are assigned to
+        // subjects.
+        JsonLdResource subject = new JsonLdResource();
+
+        try {
+            if (jo.has(JsonLd.CONTEXT)) {
+                JSONObject context = jo.getJSONObject(JsonLd.CONTEXT);
+                for (int i = 0; i < context.names().length(); i++) {
+                    String name = context.names().getString(i).toLowerCase();
+                    if (name.equals(JsonLd.TYPES)) {
+                        JSONObject typeObject = context.getJSONObject(name);
+                        for (int j = 0; j < typeObject.names().length(); j++) {
+                            String property = typeObject.names().getString(j);
+                            String type = typeObject.getString(property);
+                            subject.putCoercionType(property, type);
+                        }
+                    } else {
+                        jld.addNamespacePrefix(context.getString(name), name);
+                    }
+                }
+
+                jo.remove(JsonLd.CONTEXT);
+            }
+
+            // If there is a local profile specified for this subject, we
+            // use that one. Otherwise we assign the profile given by the parameter.
+            if (jo.has(JsonLd.PROFILE)) {
+                String localProfile = unCURIE(jo.getString(JsonLd.PROFILE), jld.getNamespacePrefixMap());
+                profile = localProfile;
+                jo.remove(JsonLd.PROFILE);
+            }
+            subject.setProfile(profile);
+
+            if (jo.has(JsonLd.SUBJECT)) {
+                // Check for N subjects
+                Object subjectObject = jo.get(JsonLd.SUBJECT);
+                if (subjectObject instanceof JSONArray) {
+                    // There is an array of subjects. We create all subjects
+                    // in sequence.
+                    JSONArray subjects = (JSONArray) subjectObject;
+                    for (int i = 0; i < subjects.length(); i++) {
+                        parseSubject(subjects.getJSONObject(i), jld, bnodeCount++, profile);
+                    }
+                } else {
+                    String subjectName = unCURIE(jo.getString(JsonLd.SUBJECT), jld.getNamespacePrefixMap());
+                    subject.setSubject(subjectName);
+                }
+                jo.remove(JsonLd.SUBJECT);
+            } else {
+                // No subject specified. We create a dummy bnode
+                // and add this subject.
+                subject.setSubject("_:bnode" + bnodeCount);
+                jld.put(subject.getSubject(), subject);
+            }
+
+            // Iterate through the rest of properties and unCURIE property values
+            // depending on their type
+            if (jo.names() != null && jo.names().length() > 0) {
+                for (int i = 0; i < jo.names().length(); i++) {
+                    String property = jo.names().getString(i);
+                    Object valueObject = jo.get(property);
+                    if (valueObject instanceof JSONObject) {
+                        JSONObject jsonValue = (JSONObject) valueObject;
+                        subject.putProperty(property, convertToMapAndList(jsonValue, jld
+                                .getNamespacePrefixMap()));
+                    } else if (valueObject instanceof String) {
+                        String stringValue = (String) valueObject;
+                        subject.putProperty(property, unCURIE(stringValue, jld.getNamespacePrefixMap()));
+                    } else {
+                        subject.putProperty(property, valueObject);
+                    }
+                }
+            }
+
+        } catch (JSONException e) {
+            logger.error("There were JSON problems when parsing the JSON-LD String", e);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Converts a JSON object into a Map or List data structure.
+     * 
+     * <p>
+     * The JSON-LD implementation is based on Map and List data types. If the input is a JSONObject, it will
+     * be converted into a Map&lt;String, Object>. If the input is a JSONArray, it will be converted into a
+     * List&lt;Object>. Otherwise the input will be returned untouched.
+     * 
+     * @param input
+     *            Object that will be converted.
+     * @return
+     */
+    private static Object convertToMapAndList(Object input, Map<String,String> namespacePrefixMap) {
+        if (input instanceof JSONObject) {
+            JSONObject jo = (JSONObject) input;
+
+            // Handle IRIs
+            if (jo.has(JsonLd.IRI)) {
+                try {
+                    return new JsonLdIRI(unCURIE(jo.getString(JsonLd.IRI), namespacePrefixMap));
+                } catch (JSONException e) {
+                    return null;
+                }
+            }
+            else {
+                // Handle arbitrary JSON
+                return convertToMap(jo, namespacePrefixMap);
+            }
+        } else if (input instanceof String) {
+            return unCURIE((String) input, namespacePrefixMap);
+        } else {
+            return input;
+        }
+    }
+
+    /**
+     * Converts a JSONOBject into a Map&lt;String, Object>.
+     * 
+     * @param jo
+     *            JSONOBject to be converted.
+     * @return A Map that represents the same information as the JSONOBject.
+     */
+    private static Map<String,Object> convertToMap(JSONObject jo, Map<String,String> namespacePrefixMap) {
+        Map<String,Object> jsonMap = null;
+        try {
+            if (jo.names() != null && jo.names().length() > 0) {
+                jsonMap = new HashMap<String,Object>();
+                for (int i = 0; i < jo.names().length(); i++) {
+                    String name = jo.names().getString(i);
+                    jsonMap.put(name, convertToMapAndList(jo.get(name), namespacePrefixMap));
+                }
+            }
+        } catch (JSONException e) { /* ignored */}
+        return jsonMap;
+    }
+
+    /**
+     * Uses the underlying Jettison to parse a JSON object.
+     * 
+     * @param jsonString
+     *            JSON String representation.
+     * @return
+     */
+    private static JSONObject parseJson(String jsonString) {
+        JSONObject jo = null;
+        try {
+            jo = new JSONObject(jsonString);
+        } catch (JSONException e) {
+            logger.debug("Could not parse JSON string: {}", jsonString, e);
+        }
+
+        return jo;
+    }
+
+    /**
+     * Replaces the CURIE prefixes with the namespace to create full qualified IRIs.
+     * 
+     * @param curie
+     *            The CURIE to create an IRI from.
+     * @param namespacePrefixMap
+     *            A Map with known namespaces.
+     * @return
+     */
+    private static String unCURIE(String curie, Map<String,String> namespacePrefixMap) {
+        for (String namespace : namespacePrefixMap.keySet()) {
+            String prefix = namespacePrefixMap.get(namespace) + ":";
+            curie = curie.replaceAll(prefix, namespace);
+        }
+        return curie;
+    }
+}

Modified: incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdResource.java?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdResource.java (original)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonLdResource.java Tue Jun 14 15:40:56 2011
@@ -12,6 +12,7 @@ import java.util.Map;
 public class JsonLdResource {
 
     private String subject;
+    private String profile;
     private List<String> types = new ArrayList<String>();
     private Map<String, String> coercionMap = new HashMap<String, String>();
     private Map<String, Object> propertyMap = new HashMap<String, Object>();
@@ -24,6 +25,14 @@ public class JsonLdResource {
         this.subject = subject;
     }
 
+    public String getProfile() {
+        return profile;
+    }
+
+    public void setProfile(String profile) {
+        this.profile = profile;
+    }
+
     public void addType(String type) {
         types.add(type);
     }

Modified: incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonSerializer.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonSerializer.java?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonSerializer.java (original)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/main/java/org/apache/stanbol/jsonld/JsonSerializer.java Tue Jun 14 15:40:56 2011
@@ -3,16 +3,15 @@ package org.apache.stanbol.jsonld;
 import java.util.List;
 import java.util.Map;
 
-
 /**
- * Class to serialize a JSON object structure whereby the JSON structure is
- * defined by the basic data types Map and List.
- *
+ * Class to serialize a JSON object structure whereby the JSON structure is defined by the basic data types
+ * Map and List.
+ * 
  * @author Fabian Christ
  */
 public class JsonSerializer {
 
-    public static String toString(Map<String, Object> jsonMap) {
+    public static String toString(Map<String,Object> jsonMap) {
         StringBuffer sb = new StringBuffer();
 
         appendJsonMap(jsonMap, sb, 0, 0);
@@ -21,7 +20,7 @@ public class JsonSerializer {
         return sb.toString();
     }
 
-    public static String toString(Map<String, Object> jsonMap, int indent) {
+    public static String toString(Map<String,Object> jsonMap, int indent) {
         StringBuffer sb = new StringBuffer();
 
         appendJsonMap(jsonMap, sb, indent, 0);
@@ -45,8 +44,8 @@ public class JsonSerializer {
 
         return sb.toString();
     }
-    
-    private static void appendJsonMap(Map<String, Object> jsonMap, StringBuffer sb, int indent, int level) {
+
+    private static void appendJsonMap(Map<String,Object> jsonMap, StringBuffer sb, int indent, int level) {
         sb.append('{');
         level = increaseIndentationLevel(sb, indent, level);
         for (String key : jsonMap.keySet()) {
@@ -77,20 +76,18 @@ public class JsonSerializer {
             appendQuoted(strValue, sb);
             sb.append(',');
             appendLinefeed(sb, indent);
-        }
-        else if (object instanceof Map<?,?>) {
-            Map<String, Object> mapValue = (Map<String, Object>) object;
+        } else if (object instanceof Map<?,?>) {
+            Map<String,Object> mapValue = (Map<String,Object>) object;
             appendJsonMap(mapValue, sb, indent, level);
-        }
-        else if (object instanceof List<?>) {
+        } else if (object instanceof List<?>) {
             List<Object> lstValue = (List<Object>) object;
             appendList(lstValue, sb, indent, level);
             sb.append(',');
             appendLinefeed(sb, indent);
-        }
-        else {
+        } else {
             sb.append(object.toString());
             sb.append(',');
+            appendLinefeed(sb, indent);
         }
     }
 
@@ -112,44 +109,44 @@ public class JsonSerializer {
         for (int i = 0; i < string.length(); i++) {
             char ch = string.charAt(i);
             switch (ch) {
-            case '\\':
-            case '"':
-                sb.append('\\');
-                sb.append(ch);
-                break;
-            case '/':
-                sb.append('\\');
-                sb.append(ch);
-                break;
-            case '\b':
-                sb.append("\\b");
-                break;
-            case '\t':
-                sb.append("\\t");
-                break;
-            case '\n':
-                sb.append("\\n");
-                break;
-            case '\f':
-                sb.append("\\f");
-                break;
-            case '\r':
-                sb.append("\\r");
-                break;
-            default:
-                if (ch < ' ') {
-                    String str = "000" + Integer.toHexString(ch);
-                    sb.append("\\u" + str.substring(str.length() - 4));
-                } else {
+                case '\\':
+                case '"':
+                    sb.append('\\');
+                    sb.append(ch);
+                    break;
+                case '/':
+                    sb.append('\\');
                     sb.append(ch);
-                }
+                    break;
+                case '\b':
+                    sb.append("\\b");
+                    break;
+                case '\t':
+                    sb.append("\\t");
+                    break;
+                case '\n':
+                    sb.append("\\n");
+                    break;
+                case '\f':
+                    sb.append("\\f");
+                    break;
+                case '\r':
+                    sb.append("\\r");
+                    break;
+                default:
+                    if (ch < ' ') {
+                        String str = "000" + Integer.toHexString(ch);
+                        sb.append("\\u" + str.substring(str.length() - 4));
+                    } else {
+                        sb.append(ch);
+                    }
             }
         }
         sb.append('"');
     }
 
     private static void appendIndentation(StringBuffer sb, int indent, int level) {
-        for (int i=0; i<(indent*level); i++) {
+        for (int i = 0; i < (indent * level); i++) {
             sb.append(' ');
         }
     }
@@ -177,18 +174,17 @@ public class JsonSerializer {
     }
 
     /**
-     * During the serialization there are added ',' and line breaks '\n' by
-     * default that need to be deleted when not needed, e.g. at the end
-     * of a list.
+     * During the serialization there are added ',' and line breaks '\n' by default that need to be deleted
+     * when not needed, e.g. at the end of a list.
      * 
      * @param sb
      * @param indent
      */
     private static void removeOddChars(StringBuffer sb, int indent) {
         if (sb.length() > 2) {
-            sb.deleteCharAt(sb.length()-1);
+            sb.deleteCharAt(sb.length() - 1);
             if (indent > 0) {
-                sb.deleteCharAt(sb.length()-1);
+                sb.deleteCharAt(sb.length() - 1);
             }
         }
     }

Added: incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdParserTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdParserTest.java?rev=1135652&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdParserTest.java (added)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdParserTest.java Tue Jun 14 15:40:56 2011
@@ -0,0 +1,124 @@
+package org.apache.stanbol.jsonld;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class JsonLdParserTest {
+
+    @Test
+    public void testParseProfile() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"#types\":{\"person\":\"iks:person\",\"organization\":\"iks:organization\"}}}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"#types\":{\"organization\":\"iks:organization\",\"person\":\"iks:person\"}}}";
+        assertEquals(expected, actual);
+        assertTrue(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+
+    @Test
+    public void testParseWithProfile() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@profile\":\"iks:employeeOf\",\"person\":{\"@iri\":\"upb:bnagel\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":\"_:bnode1\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:bnagel\"}}";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @Test
+    public void testParse3() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@profile\":\"iks:employeeOf\",\"@\":[{\"person\":{\"@iri\":\"upb:bnagel\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}},{\"person\":{\"@iri\":\"upb:fchrist\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}}]}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(false);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":[{\"@\":\"_:bnode1\",\"@profile\":\"http:\\/\\/iks-project.eu\\/ont\\/employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"http:\\/\\/upb.de\\/persons\\/bnagel\"}},{\"@\":\"_:bnode2\",\"@profile\":\"http:\\/\\/iks-project.eu\\/ont\\/employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"http:\\/\\/upb.de\\/persons\\/fchrist\"}}]}";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @Test
+    public void testParse4() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@profile\":\"iks:employeeOf\",\"@\":[{\"person\":{\"@iri\":\"upb:bnagel\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}},{\"person\":{\"@iri\":\"upb:fchrist\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}}]}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(true);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":[{\"@\":\"_:bnode1\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:bnagel\"}},{\"@\":\"_:bnode2\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:fchrist\"}}]}";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @Test
+    public void testParse5() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@profile\":\"iks:employeeOf\",\"@\":[{\"person\":{\"@iri\":\"upb:bnagel\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}},{\"person\":{\"@iri\":\"upb:fchrist\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}}]}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseJointGraphs(false);
+        
+        String actual = jsonLd.toString();
+        String expected = "[{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":\"_:bnode1\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:bnagel\"}},{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":\"_:bnode2\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:fchrist\"}}]";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @Test
+    public void testParse6() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@\":[{\"@profile\":\"iks:employeeOf\",\"person\":{\"@iri\":\"upb:bnagel\"},\"organization\":{\"@iri\":\"http://uni-paderborn.de\"}},{\"@profile\":\"iks:friendOf\",\"person\":{\"@iri\":\"upb:bnagel\"},\"friend\":{\"@iri\":\"upb:fchrist\"}}]}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseJointGraphs(true);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":[{\"@\":\"_:bnode1\",\"@profile\":\"iks:employeeOf\",\"organization\":{\"@iri\":\"http:\\/\\/uni-paderborn.de\"},\"person\":{\"@iri\":\"upb:bnagel\"}},{\"@\":\"_:bnode2\",\"@profile\":\"iks:friendOf\",\"friend\":{\"@iri\":\"upb:fchrist\"},\"person\":{\"@iri\":\"upb:bnagel\"}}]}";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @Test
+    public void testParse7() {
+        String jsonldInput = "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"upb\":\"http://upb.de/persons/\"},\"@profile\":\"iks:employeeOf\",\"person\":\"Benjamin\",\"organization\":\"UniPaderborn\"}";
+        
+        JsonLd jsonLd = JsonLdParser.parse(jsonldInput);
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseJointGraphs(true);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"iks\":\"http:\\/\\/iks-project.eu\\/ont\\/\",\"upb\":\"http:\\/\\/upb.de\\/persons\\/\"},\"@\":\"_:bnode1\",\"@profile\":\"iks:employeeOf\",\"organization\":\"UniPaderborn\",\"person\":\"Benjamin\"}";
+        assertEquals(expected, actual);
+        assertFalse(jsonLd.representsProfile());
+        assertNotNull(jsonLd);
+    }
+    
+    @SuppressWarnings("unused")
+    private void toConsole(String actual) {
+        System.out.println(actual);
+        String s = actual;
+        s = s.replaceAll("\\\\", "\\\\\\\\");
+        s = s.replace("\"", "\\\"");
+        s = s.replace("\n", "\\n");
+        System.out.println(s);
+    }
+}

Modified: incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdTest.java?rev=1135652&r1=1135651&r2=1135652&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdTest.java (original)
+++ incubator/stanbol/trunk/enhancer/generic/jsonld/src/test/java/org/apache/stanbol/jsonld/JsonLdTest.java Tue Jun 14 15:40:56 2011
@@ -1,6 +1,9 @@
 package org.apache.stanbol.jsonld;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
 
 import org.junit.After;
 import org.junit.Before;
@@ -39,7 +42,7 @@ public class JsonLdTest {
         assertEquals(expected, actual);
         
         String actualIndent = jsonLd.toString(4);
-        String expectedIndent = "{\n    \"#\": {\n        \"myvocab\": \"http:\\/\\/example.org\\/myvocab#\"\n    },\n    \"a\": \"foaf:Person\",\n    \"foaf:homepage\": \"<http:\\/\\/manu.sporny.org\\/>\",\n    \"foaf:name\": \"Manu Sporny\",\n    \"myvocab:credits\": 500,    \"sioc:avatar\": \"<http:\\/\\/twitter.com\\/account\\/profile_image\\/manusporny>\"\n}";
+        String expectedIndent = "{\n    \"#\": {\n        \"myvocab\": \"http:\\/\\/example.org\\/myvocab#\"\n    },\n    \"a\": \"foaf:Person\",\n    \"foaf:homepage\": \"<http:\\/\\/manu.sporny.org\\/>\",\n    \"foaf:name\": \"Manu Sporny\",\n    \"myvocab:credits\": 500,\n    \"sioc:avatar\": \"<http:\\/\\/twitter.com\\/account\\/profile_image\\/manusporny>\"\n}";
         assertEquals(expectedIndent, actualIndent);
     }
 
@@ -47,6 +50,7 @@ public class JsonLdTest {
     public void testSpecExample2_JointGraph() {
         JsonLd jsonLd = new JsonLd();
         jsonLd.setUseTypeCoercion(false);
+        jsonLd.setUseJointGraphs(true);
         jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
 
         JsonLdResource r1 = new JsonLdResource();
@@ -223,6 +227,90 @@ public class JsonLdTest {
         String expectedIndent = "{\n    \"#\": {\n        \"dc\": \"http:\\/\\/purl.org\\/dc\\/terms\\/\",\n        \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"dc:modified\": \"2010-05-29T14:17:39+02:00^^xsd:dateTime\"\n}";
         assertEquals(expectedIndent, actualIndent);
     }
+    
+    @Test
+    public void testSpecExample5TypedLiteralsCoercion() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setApplyNamespaces(false);
+        jsonLd.setUseTypeCoercion(true);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        String nick = "\"stu\"^^http://www.w3.org/2001/XMLSchema#string";
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nick);
+        r1.getCoercionMap().put("http://xmlns.com/foaf/0.1/nick", "xsd:string");
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\"#types\":{\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string\"}},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\":\"stu\"}";
+        assertEquals(expected, actual);
+    }
+    
+    @Test
+    public void testSpecExample5TypedLiteralsNsCoercion() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseTypeCoercion(true);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        String nick = "\"stu\"^^http://www.w3.org/2001/XMLSchema#string";
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nick);
+        r1.getCoercionMap().put("http://xmlns.com/foaf/0.1/nick", "xsd:string");
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\"#types\":{\"foaf:nick\":\"xsd:string\"}},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"foaf:nick\":\"stu\"}";
+        assertEquals(expected, actual);
+    }
+    
+    @Test
+    public void testSpecExample5TypedLiteralsNoCoercion() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setApplyNamespaces(false);
+        jsonLd.setUseTypeCoercion(false);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        String nick = "\"stu\"^^http://www.w3.org/2001/XMLSchema#string";
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nick);
+        r1.getCoercionMap().put("http://xmlns.com/foaf/0.1/nick", "xsd:string");
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\":\"\\\"stu\\\"^^http:\\/\\/www.w3.org\\/2001\\/XMLSchema#string\"}";
+        assertEquals(expected, actual);
+    }
+    
+    @Test
+    public void testSpecExample5TypedLiteralsNsNoCoercion() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseTypeCoercion(false);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        String nick = "\"stu\"^^http://www.w3.org/2001/XMLSchema#string";
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nick);
+        r1.getCoercionMap().put("http://xmlns.com/foaf/0.1/nick", "xsd:string");
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"foaf:nick\":\"\\\"stu\\\"^^xsd:string\"}";
+        assertEquals(expected, actual);
+    }
 
     @Test
     public void testSpecExample6MultipleObjects() {
@@ -245,7 +333,7 @@ public class JsonLdTest {
         String expectedIndent = "{\n    \"#\": {\n        \"foaf\": \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\n        \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"@\": \"<http:\\/\\/example.org\\/people#joebob>\",\n    \"foaf:nick\": [\n        \"\\\"stu\\\"^^xsd:string\",\n        \"\\\"groknar\\\"^^xsd:string\",\n        \"\\\"radface\\\"^^xsd:string\"\n    ]\n}";
         assertEquals(expectedIndent, actualIndent);
     }
-
+    
     @Test
     public void testSpecExample7NoNSApply() {
         JsonLd jsonLd = new JsonLd();
@@ -293,7 +381,144 @@ public class JsonLdTest {
         assertEquals(expectedIndent, actualIndent);
     }
 
+    @Test
+    public void testComplexArrays() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(false);
 
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+        jsonLd.addNamespacePrefix("http://nickworld.com/nicks/", "nick");
+        
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        
+        Map<String,Object> nick1 = new HashMap<String,Object>();
+        nick1.put("@iri", "nick:stu");
+        
+        Map<String,Object> nick2 = new HashMap<String,Object>();
+        nick2.put("@iri", "nick:pet");
+        
+        Map<String,Object> nick3 = new HashMap<String,Object>();
+        nick3.put("@iri", "nick:flo");
+        
+        Object [] nicks = new Object [] {nick1, nick2, nick3};
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nicks);
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"nick\":\"http:\\/\\/nickworld.com\\/nicks\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\":[{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/stu\"},{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/pet\"},{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/flo\"}]}";
+        assertEquals(expected, actual);
+
+        String actualIndent = jsonLd.toString(4);
+        String expectedIndent = "{\n    \"#\": {\n        \"foaf\": \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\n        \"nick\": \"http:\\/\\/nickworld.com\\/nicks\\/\",\n        \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"@\": \"<http:\\/\\/example.org\\/people#joebob>\",\n    \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\": [\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/stu\"\n        },\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/pet\"\n        },\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/flo\"\n        }\n    ]\n}";
+        assertEquals(expectedIndent, actualIndent);
+    }
+    
+    @Test
+    public void testComplexArraysWithIRIs() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(false);
+
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+        jsonLd.addNamespacePrefix("http://nickworld.com/nicks/", "nick");
+        
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        
+        JsonLdIRI nick1 = new JsonLdIRI("nick:stu");
+        JsonLdIRI nick2 = new JsonLdIRI("nick:pet");
+        JsonLdIRI nick3 = new JsonLdIRI("nick:flo");
+        
+        Object [] nicks = new Object [] {nick1, nick2, nick3};
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nicks);
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"nick\":\"http:\\/\\/nickworld.com\\/nicks\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\":[{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/stu\"},{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/pet\"},{\"@iri\":\"http:\\/\\/nickworld.com\\/nicks\\/flo\"}]}";
+        assertEquals(expected, actual);
+
+        String actualIndent = jsonLd.toString(4);
+        String expectedIndent = "{\n    \"#\": {\n        \"foaf\": \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\n        \"nick\": \"http:\\/\\/nickworld.com\\/nicks\\/\",\n        \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"@\": \"<http:\\/\\/example.org\\/people#joebob>\",\n    \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/nick\": [\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/stu\"\n        },\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/pet\"\n        },\n        {\n            \"@iri\": \"http:\\/\\/nickworld.com\\/nicks\\/flo\"\n        }\n    ]\n}";
+        assertEquals(expectedIndent, actualIndent);
+    }
+    
+    @Test
+    public void testComplexArraysWithIRIsWithNS() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setUseTypeCoercion(true);
+        jsonLd.setApplyNamespaces(true);
+
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+        jsonLd.addNamespacePrefix("http://nickworld.com/nicks/", "nick");
+        
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setSubject("<http://example.org/people#joebob>");
+        
+        JsonLdIRI nick1 = new JsonLdIRI("nick:stu");
+        JsonLdIRI nick2 = new JsonLdIRI("nick:pet");
+        JsonLdIRI nick3 = new JsonLdIRI("nick:flo");
+        
+        Object [] nicks = new Object [] {nick1, nick2, nick3};
+        r1.putProperty("http://xmlns.com/foaf/0.1/nick", nicks);
+        jsonLd.put("r1", r1);
+
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"nick\":\"http:\\/\\/nickworld.com\\/nicks\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@\":\"<http:\\/\\/example.org\\/people#joebob>\",\"foaf:nick\":[{\"@iri\":\"nick:stu\"},{\"@iri\":\"nick:pet\"},{\"@iri\":\"nick:flo\"}]}";
+        assertEquals(expected, actual);
+
+        String actualIndent = jsonLd.toString(4);
+        String expectedIndent = "{\n    \"#\": {\n        \"foaf\": \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\n        \"nick\": \"http:\\/\\/nickworld.com\\/nicks\\/\",\n        \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"\n    },\n    \"@\": \"<http:\\/\\/example.org\\/people#joebob>\",\n    \"foaf:nick\": [\n        {\n            \"@iri\": \"nick:stu\"\n        },\n        {\n            \"@iri\": \"nick:pet\"\n        },\n        {\n            \"@iri\": \"nick:flo\"\n        }\n    ]\n}";
+        assertEquals(expectedIndent, actualIndent);
+    }
+    
+    @Test
+    public void testProfile() {
+        JsonLd jsonLd = new JsonLd(true);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+        
+        JsonLdResource r1 = new JsonLdResource();
+        r1.setProfile("testprofile");
+        r1.setSubject("_:bnode1");
+        jsonLd.put(r1);
+        
+        assertTrue(jsonLd.representsProfile());
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\"},\"@profile\":\"testprofile\"}";
+        assertEquals(expected, actual);
+    }
+    
+    @Test
+    public void testIntegerValue() {
+        JsonLd jsonLd = new JsonLd();
+        jsonLd.setApplyNamespaces(true);
+        jsonLd.setUseTypeCoercion(true);
+        
+        jsonLd.addNamespacePrefix("http://www.w3.org/2001/XMLSchema#", "xsd");
+        jsonLd.addNamespacePrefix("http://xmlns.com/foaf/0.1/", "foaf");
+        
+        JsonLdResource r1 = new JsonLdResource();
+        r1.putCoercionType("foaf:age", "http:\\/\\/www.w3.org\\/2001\\/XMLSchema#int");
+        r1.setSubject("_:bnode1");
+        r1.putProperty("foaf:age", 31);
+        jsonLd.put(r1);
+        
+        String actual = jsonLd.toString();
+        String expected = "{\"#\":{\"foaf\":\"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\"xsd\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\"#types\":{\"foaf:age\":\"http:\\\\\\/\\\\\\/www.w3.org\\\\\\/2001\\\\\\/XMLSchema#int\"}},\"@\":\"_:bnode1\",\"foaf:age\":31}";
+        assertEquals(expected, actual);
+        
+        String actualIndented = jsonLd.toString(2);
+        String expectedIndented = "{\n  \"#\": {\n    \"foaf\": \"http:\\/\\/xmlns.com\\/foaf\\/0.1\\/\",\n    \"xsd\": \"http:\\/\\/www.w3.org\\/2001\\/XMLSchema#\",\n    \"#types\": {\n      \"foaf:age\": \"http:\\\\\\/\\\\\\/www.w3.org\\\\\\/2001\\\\\\/XMLSchema#int\"\n    }\n  },\n  \"@\": \"_:bnode1\",\n  \"foaf:age\": 31\n}";
+        assertEquals(expectedIndented, actualIndented);
+    }
+    
     @SuppressWarnings("unused")
     private void toConsole(String actual) {
         System.out.println(actual);