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/22 17:46:42 UTC

svn commit: r1138513 - in /incubator/stanbol/trunk/factstore: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/stanbol/ src/main/java/org/apache/stanbol/factstore/ src/main/java/org/apache/stanbol/f...

Author: fchrist
Date: Wed Jun 22 15:46:40 2011
New Revision: 1138513

URL: http://svn.apache.org/viewvc?rev=1138513&view=rev
Log:
STANBOL-237 Initial commit.

First implementation of 'Publish a New Fact Schema' and 'Get Fact Schema'.

Added:
    incubator/stanbol/trunk/factstore/   (with props)
    incubator/stanbol/trunk/factstore/pom.xml
    incubator/stanbol/trunk/factstore/src/
    incubator/stanbol/trunk/factstore/src/main/
    incubator/stanbol/trunk/factstore/src/main/java/
    incubator/stanbol/trunk/factstore/src/main/java/org/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/FactStore.java
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/DerbyFactStore.java
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/FactSchema.java
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/FactStoreWebFragment.java
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactStoreRootResource.java
    incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactsResource.java
    incubator/stanbol/trunk/factstore/src/main/resources/
    incubator/stanbol/trunk/factstore/src/main/resources/org/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/static/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/index.ftl
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/facts_common.ftl
    incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/index.ftl
    incubator/stanbol/trunk/factstore/src/test/
    incubator/stanbol/trunk/factstore/src/test/java/
    incubator/stanbol/trunk/factstore/src/test/java/org/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/FactStoreMock.java
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/DerbyFactStoreTest.java
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/FactSchemaTest.java
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/
    incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/FactsResourceTest.java

Propchange: incubator/stanbol/trunk/factstore/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Jun 22 15:46:40 2011
@@ -0,0 +1,5 @@
+.classpath
+.project
+.settings/
+target/
+

Added: incubator/stanbol/trunk/factstore/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/pom.xml?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/pom.xml (added)
+++ incubator/stanbol/trunk/factstore/pom.xml Wed Jun 22 15:46:40 2011
@@ -0,0 +1,148 @@
+<?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">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.stanbol</groupId>
+    <artifactId>stanbol-parent</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <relativePath>../parent</relativePath>
+  </parent>
+
+  <groupId>org.apache.stanbol</groupId>
+  <artifactId>org.apache.stanbol.factstore</artifactId>
+  <version>0.9-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <name>Apache Stanbol FactStore</name>
+  <description>The FactStore stores n-ary relations (facts) about entities and provides a query language for
+  those relations.</description>
+
+  <scm>
+    <connection>
+      scm:svn:http://svn.apache.org/repos/asf/incubator/stanbol/trunk/factstore
+    </connection>
+    <developerConnection>
+      scm:svn:https://svn.apache.org/repos/asf/incubator/stanbol/trunk/factstore
+    </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.factstore.api.*
+            </Export-Package>
+            <Import-Package>
+              <!-- apache derby -->
+              org.apache.derby.jdbc,
+              *
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.stanbol</groupId>
+      <artifactId>org.apache.stanbol.commons.web.base</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.stanbol</groupId>
+      <artifactId>org.apache.stanbol.commons.jsonld</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr.annotations</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.ws.rs</groupId>
+      <artifactId>jsr311-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.codehaus.jettison</groupId>
+      <artifactId>jettison</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.freemarker</groupId>
+      <artifactId>freemarker</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+
+    <!-- Version will be removed once dependencies are added to stanbol-parent -->
+    <dependency>
+      <groupId>org.apache.derby</groupId>
+      <artifactId>derby</artifactId>
+      <version>10.7.1.1</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.stanbol</groupId>
+      <artifactId>org.apache.stanbol.commons.testing.http</artifactId>
+      <version>0.9-SNAPSHOT</version>
+      <scope>test</scope>    
+    </dependency>
+  </dependencies>
+
+</project>

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/FactStore.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/FactStore.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/FactStore.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/api/FactStore.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,15 @@
+package org.apache.stanbol.factstore.api;
+
+import org.apache.stanbol.factstore.model.FactSchema;
+
+public interface FactStore {
+
+    public int getMaxFactSchemaURNLength();
+    
+    public boolean existsFactSchema(String factSchemaURN) throws Exception;
+
+    public FactSchema getFactSchema(String factSchemaURN);
+
+    public void createFactSchema(FactSchema factSchema) throws Exception;
+    
+}

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/DerbyFactStore.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/DerbyFactStore.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/DerbyFactStore.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/derby/DerbyFactStore.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,321 @@
+package org.apache.stanbol.factstore.derby;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.stanbol.factstore.api.FactStore;
+import org.apache.stanbol.factstore.model.FactSchema;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the FactStore interface based on an Apache Derby relational database.
+ * 
+ * @author Fabian Christ
+ */
+@Component(immediate = true)
+@Service
+public class DerbyFactStore implements FactStore {
+
+    private static Logger logger = LoggerFactory.getLogger(DerbyFactStore.class);
+
+    private static int MAX_FACTSCHEMAURN_LENGTH = 96;
+
+    private static final String CreateTableFactSchemata = "CREATE TABLE factschemata ( id INT GENERATED ALWAYS AS IDENTITY CONSTRAINT factschema_id PRIMARY KEY, name VARCHAR(128) NOT NULL )";
+    private static final String CreateTableFactRoles = "CREATE TABLE factroles ( id INT GENERATED ALWAYS AS IDENTITY CONSTRAINT factrole_id PRIMARY KEY, factschema_id INT NOT NULL CONSTRAINT factschema_foreign_key REFERENCES factschemata ON DELETE CASCADE ON UPDATE RESTRICT, name VARCHAR(128) NOT NULL, type VARCHAR(512) NOT NULL )";
+
+    public static final String DB_URL = "jdbc:derby:factstore;create=true";
+
+    @Activate
+    protected void activate(ComponentContext cc) throws Exception {
+        logger.info("Activating FactStore...");
+
+        logger.info("Connecting to Derby DB {}", DB_URL);
+        Connection con = null;
+        try {
+            con = DriverManager.getConnection(DB_URL);
+
+            if (con != null) {
+                logger.info("Derby connection established.");
+
+                try {
+                    if (!existsTable("factschemata", con)) {
+                        List<String> sqls = new ArrayList<String>();
+                        sqls.add(CreateTableFactSchemata);
+                        sqls.add(CreateTableFactRoles);
+
+                        this.executeUpdate(sqls, con);
+
+                        logger.info("Created FactStore meta tables.");
+                    }
+                } catch (Exception e) {
+                    throw new Exception("Error creating meta data tables", e);
+                }
+            }
+        } catch (Exception e) {
+            throw new Exception("Derby DB error. Can't activate.", e);
+        } finally {
+            if (con != null) {
+                try {
+                    con.close();
+                } catch (SQLException e) {
+                    /* ignore */
+                }
+            }
+        }
+
+        logger.info("FactStore activated.");
+    }
+
+    @Override
+    public int getMaxFactSchemaURNLength() {
+        return MAX_FACTSCHEMAURN_LENGTH;
+    }
+
+    @Override
+    public boolean existsFactSchema(String factSchemaURN) throws Exception {
+        String factSchemaB64 = Base64.encodeBase64URLSafeString(factSchemaURN.getBytes());
+        boolean tableExists = false;
+        Connection con = null;
+        try {
+            con = DriverManager.getConnection(DB_URL);
+            tableExists = this.existsTable(factSchemaB64, con);
+        } catch (Exception e) {
+            throw new Exception("Error checking table existence", e);
+        } finally {
+            if (con != null) {
+                try {
+                    con.close();
+                } catch (SQLException e) {
+                    /* ignore */
+                }
+            }
+        }
+
+        return tableExists;
+    }
+
+    private boolean existsTable(String tableName, Connection con) throws Exception {
+        boolean exists = false;
+
+        ResultSet res = null;
+        try {
+            con = DriverManager.getConnection(DB_URL);
+            DatabaseMetaData meta = con.getMetaData();
+            res = meta.getTables(null, null, null, new String[] {"TABLE"});
+            while (res.next()) {
+                if (res.getString("TABLE_NAME").equalsIgnoreCase(tableName)) {
+                    exists = true;
+                    break;
+                }
+            }
+        } catch (SQLException e) {
+            logger.error("Error while reading tables' metadata to check if table '{}' exists", tableName);
+            throw new Exception("Error while reading tables' metadata", e);
+        } finally {
+            try {
+                res.close();
+            } catch (Throwable t) { /* ignore */}
+        }
+
+        return exists;
+    }
+    
+    @Override
+    public FactSchema getFactSchema(String factSchemaURN) {
+        FactSchema factSchema = null;
+        
+        Connection con = null;
+        try {
+            con = DriverManager.getConnection(DB_URL);
+            PreparedStatement ps = null;
+            ResultSet rs = null;
+            try {
+                String selectFactSchema = "SELECT factschemata.name AS schemaURN, factroles.name AS role, factroles.type AS type FROM factroles JOIN factschemata ON ( factschemata.id = factroles.factschema_id ) WHERE factschemata.name = ?";
+                ps = con.prepareStatement(selectFactSchema);
+                ps.setString(1, factSchemaURN);
+                rs = ps.executeQuery();
+                
+                boolean first = true;
+                while (rs.next()) {
+                    if (first) {
+                        factSchema = new FactSchema();
+                        factSchema.setFactSchemaURN(rs.getString("schemaURN"));
+                        first = false;
+                    }
+                    String typeFromDB = rs.getString("type");
+                    String [] types = typeFromDB.split(",");
+                    if (types.length > 0) {
+                        for (String type : types) {
+                            factSchema.addRole(rs.getString("role"), type);
+                        }
+                    }
+                    else {
+                        factSchema.addRole(rs.getString("role"), typeFromDB);
+                    }
+                }
+            } catch (SQLException e) {
+                throw new Exception("Error while selecting fact schema meta data", e);
+            } finally {
+                if (rs != null) {
+                    try {
+                        rs.close();
+                    } catch (SQLException e) {
+                        /* ignore */
+                    }
+                }
+                if (ps != null) {
+                    try {
+                        ps.close();
+                    } catch (SQLException e) {
+                        /* ignore */
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error while creating fact schema", e);
+            factSchema = null;
+        } finally {
+            try {
+                con.close();
+            } catch (Throwable t) { /* ignore */}
+        }
+        
+        return factSchema;
+    }
+
+    @Override
+    public void createFactSchema(FactSchema factSchema) throws Exception {
+        // TODO Implement roll back behavior (transaction)
+
+        String factSchemaB64 = Base64.encodeBase64URLSafeString(factSchema.getFactSchemaURN().getBytes());
+
+        List<String> createFactSchemaTable = this.toSQLfromSchema(factSchemaB64, factSchema);
+
+        Connection con = null;
+        try {
+            con = DriverManager.getConnection(DB_URL);
+            this.executeUpdate(createFactSchemaTable, con);
+            this.insertFactSchemaMetadata(factSchema, con);
+        } catch (Exception e) {
+            throw new Exception("Error while creating fact schema", e);
+        } finally {
+            try {
+                con.close();
+            } catch (Throwable t) { /* ignore */}
+        }
+
+        logger.info("Fact schema {} created as {}", factSchema.getFactSchemaURN(), factSchemaB64);
+    }
+
+    private void insertFactSchemaMetadata(FactSchema factSchema, Connection con) throws Exception {
+        PreparedStatement ps = null;
+        try {
+            String insertFactSchema = "INSERT INTO factschemata (name) VALUES ( ? )";
+            ps = con.prepareStatement(insertFactSchema, PreparedStatement.RETURN_GENERATED_KEYS);
+            ps.setString(1, factSchema.getFactSchemaURN());
+            ps.executeUpdate();
+            ResultSet rs = ps.getGeneratedKeys();
+
+            int factSchemaId = -1;
+            if (rs.next()) {
+                factSchemaId = rs.getInt(1);
+            }
+            if (factSchemaId < 0) {
+                throw new Exception("Could not obtain fact schema ID after insert");
+            }
+
+            logger
+                    .info("Inserted new fact schema {} with ID {}", factSchema.getFactSchemaURN(),
+                        factSchemaId);
+
+            String insertFactRoles = "INSERT INTO factroles (factschema_id, name, type) VALUES ( ?, ?, ? )";
+            ps = con.prepareStatement(insertFactRoles);
+            for (String role : factSchema.getRoles()) {
+                ps.setInt(1, factSchemaId);
+                ps.setString(2, role);
+                
+                StringBuilder typeList = new StringBuilder();
+                boolean first = true;
+                for (String type : factSchema.getTypesOfRole(role)) {
+                    if (!first) {
+                        typeList.append(",");
+                    }
+                    typeList.append(type);
+                    first = false;
+                }
+                ps.setString(3, typeList.toString());
+
+                ps.addBatch();
+            }
+            ps.executeBatch();
+        } catch (SQLException e) {
+            throw new Exception("Error while inserting fact schema meta data", e);
+        } finally {
+            if (ps != null) {
+                try {
+                    ps.close();
+                } catch (SQLException e) {
+                    /* ignore */
+                }
+            }
+        }
+    }
+
+    protected List<String> toSQLfromSchema(String factSchemaB64, FactSchema factSchema) throws Exception {
+        List<String> sqls = new ArrayList<String>();
+
+        // TODO Add SQL command for index creation
+
+        StringBuilder createTableSQL = new StringBuilder("CREATE TABLE ");
+        createTableSQL.append(factSchemaB64).append(' ');
+        createTableSQL.append('(');
+        createTableSQL.append("id INT GENERATED ALWAYS AS IDENTITY");
+
+        for (String role : factSchema.getRoles()) {
+            createTableSQL.append(", ");
+            createTableSQL.append(role);
+            createTableSQL.append(" VARCHAR(1024)");
+        }
+        createTableSQL.append(')');
+
+        sqls.add(createTableSQL.toString());
+
+        return sqls;
+    }
+
+    private void executeUpdate(List<String> sqls, Connection con) throws Exception {
+        for (String sql : sqls) {
+            int res = -1;
+            Statement statement = null;
+            try {
+                statement = con.createStatement();
+                res = statement.executeUpdate(sql);
+                if (res < 0) {
+                    logger.error("Negative result after executing SQL '{}'", sql);
+                    throw new Exception("Negative result after executing SQL");
+                }
+            } catch (SQLException e) {
+                logger.error("Error executing SQL '{}'", sql, e);
+                throw new Exception("Error executing SQL", e);
+            } finally {
+                try {
+                    statement.close();
+                } catch (Throwable t) { /* ignore */}
+            }
+        }
+    }
+
+}

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/FactSchema.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/FactSchema.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/FactSchema.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/model/FactSchema.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,71 @@
+package org.apache.stanbol.factstore.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.stanbol.commons.jsonld.JsonLdProfile;
+
+public class FactSchema {
+
+    private String factSchemaURN;
+    
+    private Map<String, List<String>> roleMap = new HashMap<String,List<String>>();
+
+    public String getFactSchemaURN() {
+        return factSchemaURN;
+    }
+
+    public void setFactSchemaURN(String factSchemaURN) {
+        this.factSchemaURN = factSchemaURN;
+    }
+
+    public void addRole(String role, String type) {
+        if (this.roleMap.get(role) == null) {
+            this.roleMap.put(role, new ArrayList<String>());
+        }
+        List<String> types = this.roleMap.get(role);
+        types.add(type);
+    }
+    
+    public Set<String> getRoles() {
+        return this.roleMap.keySet();
+    }
+
+    public List<String> getTypesOfRole(String role) {
+        return this.roleMap.get(role);
+    }
+    
+    public JsonLdProfile toJsonLdProfile() {
+        JsonLdProfile profile = new JsonLdProfile();
+        
+        for (String role : this.roleMap.keySet()) {
+            profile.addTypes(role, this.roleMap.get(role));
+        }
+        
+        return profile;
+    }
+    
+    public static FactSchema fromJsonLdProfile(String factSchemaURN, JsonLdProfile jsonLd) {
+        if (factSchemaURN == null || factSchemaURN.isEmpty()) {
+            throw new IllegalArgumentException("Fact schema URN must not be empty");
+        }
+
+        FactSchema factSchema = new FactSchema();
+        factSchema.setFactSchemaURN(factSchemaURN);
+        for (String role : jsonLd.getTypes()) {
+            // we have to unCURIE the types here to be sure it is not stored as a CURIE
+            List<String> types = jsonLd.getTypes(role);
+            for (String type : types) {
+                type = jsonLd.unCURIE(type);
+                factSchema.addRole(role, type);
+            }
+            
+        }
+
+        return factSchema;
+    }
+    
+}

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/FactStoreWebFragment.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/FactStoreWebFragment.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/FactStoreWebFragment.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/FactStoreWebFragment.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,102 @@
+package org.apache.stanbol.factstore.web;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.stanbol.commons.web.base.LinkResource;
+import org.apache.stanbol.commons.web.base.NavigationLink;
+import org.apache.stanbol.commons.web.base.ScriptResource;
+import org.apache.stanbol.commons.web.base.WebFragment;
+import org.apache.stanbol.factstore.api.FactStore;
+import org.apache.stanbol.factstore.web.resource.FactStoreRootResource;
+import org.apache.stanbol.factstore.web.resource.FactsResource;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+
+import freemarker.cache.ClassTemplateLoader;
+import freemarker.cache.TemplateLoader;
+
+/**
+ * The FactStore web fragment registers the FactStore documentation and REST
+ * resources at the global Stanbol Jersey module.
+ * 
+ * @author Fabian Christ
+ */
+@Component(immediate = true, metatype = true)
+@Service
+public class FactStoreWebFragment implements WebFragment {
+
+    private static final String NAME = "factstore";
+    
+    private static final String STATIC_RESOURCE_PATH = "/org/apache/stanbol/factstore/web/static";
+
+    private static final String TEMPLATE_PATH = "/org/apache/stanbol/factstore/web/templates";
+
+    private BundleContext bundleContext;
+    
+    @Reference
+    FactStore factStore;
+    
+    @Activate
+    protected void activate(ComponentContext ctx) {
+        this.bundleContext = ctx.getBundleContext();
+    }
+
+    @Override
+    public BundleContext getBundleContext() {
+        return this.bundleContext;
+    }
+
+    @Override
+    public Set<Class<?>> getJaxrsResourceClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+        classes.add(FactStoreRootResource.class);
+        classes.add(FactsResource.class);
+        return classes;
+    }
+
+    @Override
+    public Set<Object> getJaxrsResourceSingletons() {
+        return Collections.emptySet();
+    }
+    
+    @Override
+    public List<LinkResource> getLinkResources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+    
+    @Override
+    public List<NavigationLink> getNavigationLinks() {
+        List<NavigationLink> navList = new ArrayList<NavigationLink>();
+        navList.add(new NavigationLink("factstore", "/factstore", null, 30));
+        return navList;
+    }
+    
+    @Override
+    public List<ScriptResource> getScriptResources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getStaticResourceClassPath() {
+        return STATIC_RESOURCE_PATH;
+    }
+
+    @Override
+    public TemplateLoader getTemplateLoader() {
+        return new ClassTemplateLoader(getClass(), TEMPLATE_PATH);
+    }
+
+}

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactStoreRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactStoreRootResource.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactStoreRootResource.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactStoreRootResource.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,23 @@
+package org.apache.stanbol.factstore.web.resource;
+
+import static javax.ws.rs.core.MediaType.TEXT_HTML;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.apache.stanbol.commons.web.base.resource.BaseStanbolResource;
+
+import com.sun.jersey.api.view.Viewable;
+
+@Path("/factstore")
+public class FactStoreRootResource extends BaseStanbolResource {
+    
+    @GET
+    @Produces(TEXT_HTML)
+    public Response get() {
+        return Response.ok(new Viewable("index", this), TEXT_HTML).build();
+    }
+    
+}

Added: incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactsResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactsResource.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactsResource.java (added)
+++ incubator/stanbol/trunk/factstore/src/main/java/org/apache/stanbol/factstore/web/resource/FactsResource.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,122 @@
+package org.apache.stanbol.factstore.web.resource;
+
+import static javax.ws.rs.core.MediaType.TEXT_HTML;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.stanbol.commons.jsonld.JsonLdProfile;
+import org.apache.stanbol.commons.jsonld.JsonLdProfileParser;
+import org.apache.stanbol.commons.web.base.ContextHelper;
+import org.apache.stanbol.commons.web.base.resource.BaseStanbolResource;
+import org.apache.stanbol.factstore.api.FactStore;
+import org.apache.stanbol.factstore.model.FactSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.api.view.Viewable;
+
+@Path("/factstore/facts")
+public class FactsResource extends BaseStanbolResource {
+
+    private static Logger logger = LoggerFactory.getLogger(FactsResource.class);
+
+    private final FactStore factStore;
+
+    public FactsResource(@Context ServletContext context) {
+        this.factStore = ContextHelper.getServiceFromContext(FactStore.class, context);
+    }
+
+    @GET
+    @Produces(MediaType.TEXT_HTML)
+    public Response get() {
+        return Response.ok(new Viewable("index", this), TEXT_HTML).build();
+    }
+
+    @GET
+    @Path("/{factSchemaURN}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getFactSchema(@PathParam("factSchemaURN") String factSchemaURN) {
+        Response validationResponse = standardValidation(factSchemaURN);
+        if (validationResponse != null) {
+            return validationResponse;
+        }
+
+        FactSchema factSchema = this.factStore.getFactSchema(factSchemaURN);
+        if (factSchema == null) {
+            return Response.status(Status.NOT_FOUND).entity("Could not find fact schema " + factSchemaURN)
+                    .build();
+        }
+
+        return Response.ok(factSchema.toJsonLdProfile().toString()).build();
+    }
+
+    @PUT
+    @Path("/{factSchemaURN}")
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response putFactSchema(String jsonLdProfileString, @PathParam("factSchemaURN") String factSchemaURN) {
+        Response validationResponse = standardValidation(factSchemaURN);
+        if (validationResponse != null) {
+            return validationResponse;
+        }
+
+        JsonLdProfile profile = null;
+        try {
+            profile = JsonLdProfileParser.parseProfile(jsonLdProfileString);
+        } catch (Exception e) { /* ignore this exception here - it was logged by the parser */}
+
+        if (profile == null) {
+            return Response.status(Status.BAD_REQUEST).entity(
+                "Could not parse provided JSON-LD Profile structure.").build();
+        }
+
+        try {
+            if (this.factStore.existsFactSchema(factSchemaURN)) {
+                return Response.status(Status.CONFLICT).entity(
+                    "The fact schema " + factSchemaURN + " already exists.").build();
+            }
+        } catch (Exception e) {
+            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(
+                "Error while checking existence of fact schema " + factSchemaURN).build();
+        }
+
+        try {
+            this.factStore.createFactSchema(FactSchema.fromJsonLdProfile(factSchemaURN, profile));
+        } catch (Exception e) {
+            logger.error("Error creating new fact schema {}", factSchemaURN, e);
+            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(
+                "Error while creating new fact in database.").build();
+        }
+
+        return Response.status(Status.CREATED).build();
+    }
+
+    private Response standardValidation(String factSchemaURN) {
+        if (this.factStore == null) {
+            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(
+                "The FactStore is not configured properly").build();
+        }
+
+        if (factSchemaURN == null || factSchemaURN.isEmpty()) {
+            return Response.status(Status.BAD_REQUEST).entity("No fact schema URN specified.").build();
+        }
+
+        if (factSchemaURN.length() > this.factStore.getMaxFactSchemaURNLength()) {
+            return Response.status(Status.BAD_REQUEST).entity(
+                "The fact schema URN " + factSchemaURN + " is too long. A maximum of "
+                        + this.factStore.getMaxFactSchemaURNLength() + " characters is allowed").build();
+        }
+
+        return null;
+    }
+}

Added: incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/index.ftl?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/index.ftl (added)
+++ incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactStoreRootResource/index.ftl Wed Jun 22 15:46:40 2011
@@ -0,0 +1,31 @@
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="FactStore" hasrestapi=true> 
+
+<div class="panel" id="webview">
+<p>The FactStore implements a store for facts plus the ability to query for single facts and for combinations
+of facts which is equal to the required IKS reasoning capability. In summary, the FactStore implements:</p>
+
+<ul>
+	<li>Persistence storage for n-ary facts about entities</li>
+    <li>Query language to query for a single fact</li>
+    <li>Query language to query for combinations of facts (reasoning)</li> 
+</ul>
+
+<p>The FactStore specification proposal can be found online at the
+<a href="http://wiki.iks-project.eu/index.php/FactStore_Specification" target="_blank">IKS Wiki page</a>.</p>
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Service Endpoints</h3>
+
+<p>The FactStore supports the following service endpoints:</p>
+
+<ul>
+	<li>Store @ <a href="${it.publicBaseUri}factstore/facts">/factstore/facts</a></li>
+</ul>
+
+</div>
+
+</...@common.page>
+</#escape>

Added: incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/facts_common.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/facts_common.ftl?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/facts_common.ftl (added)
+++ incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/facts_common.ftl Wed Jun 22 15:46:40 2011
@@ -0,0 +1,15 @@
+<#macro page>
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="FactStore Facts" hasrestapi=false> 
+
+<div class="panel" id="restapi">
+<h3>Service Endpoint <a href="${it.publicBaseUri}factstore/facts">/factstore/facts</a></h3>
+
+<#nested>
+
+</div>
+
+</...@common.page>
+</#escape>
+</#macro>
\ No newline at end of file

Added: incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/index.ftl?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/index.ftl (added)
+++ incubator/stanbol/trunk/factstore/src/main/resources/org/apache/stanbol/factstore/web/templates/org/apache/stanbol/factstore/web/resource/FactsResource/index.ftl Wed Jun 22 15:46:40 2011
@@ -0,0 +1,51 @@
+<#import "facts_common.ftl" as common>
+<#escape x as x?html>
+<@common.page> 
+
+<a name="Publish_a_New_Fact_Schema" id="Publish_a_New_Fact_Schema"></a><h4>Publish a New Fact Schema</h4>
+<table>
+	<tr>
+		<th valign="top">Description: </th>
+		<td>Allows clients to publish new fact schemata to the FactStore. Each fact is an n-tuple where each
+		element of that tuple defines a certain type of entity. A fact schema defines which types of entities
+		and their roles are part of instances of that fact.</td>
+	</tr>
+	<tr>
+		<th valign="top">Path: </th>
+		<td>/factstore/facts/{fact-schema-name}</td>
+	</tr>
+	<tr>
+		<th valign="top">Method:</th>
+		<td>PUT with data type application/json returns HTTP 201 (created) on success.</td>
+	</tr>
+	<tr>
+		<th valign="top">Data:</th>
+		<td>The fact schema is sent as the PUT payload in JSON-LD format as a JSON-LD profile. The name of the
+		fact is given by the URL. The elements of the schema are defined in the "#types" section of the
+		JSON-LD "#context". Each element is specified using a unique role name for that entity plus the entity
+		type specified by an URN.</td>
+	</tr>
+	<tr>
+		<th valign="top">Example:</th>
+		<td>PUT /factstore/facts/http%3A%2F%2Fiks-project.eu%2Font%2FemployeeOf<br />
+			with the following data
+<pre>{
+ "@context" :
+ {
+  "iks"     : "http://iks-project.eu/ont/",
+  "#types"  :
+  {
+    "person"       : "iks:person",
+    "organization" : "iks:organization"
+  }
+ }
+}</pre>
+		<p>will create the new fact schema for &quot;employeeOf&quot; at the given URL which is in decoded
+		   representation: /factstore/facts/http://iks-project.eu/ont/employeeOf</p>
+		</td>
+	</tr>
+</table>
+
+
+</...@common.page>
+</#escape>

Added: incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/FactStoreMock.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/FactStoreMock.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/FactStoreMock.java (added)
+++ incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/FactStoreMock.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,32 @@
+package org.apache.stanbol.factstore;
+
+import org.apache.stanbol.commons.jsonld.JsonLdCommon;
+import org.apache.stanbol.factstore.api.FactStore;
+import org.apache.stanbol.factstore.model.FactSchema;
+
+public class FactStoreMock implements FactStore {
+
+    public void createFactSchema(String factSchemaURN, JsonLdCommon jsonLd) throws Exception {}
+
+    public boolean existsFactSchema(String factSchemaURN) throws Exception {
+        return false;
+    }
+
+    @Override
+    public int getMaxFactSchemaURNLength() {
+        return 96;
+    }
+
+    @Override
+    public void createFactSchema(FactSchema factSchema) throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public FactSchema getFactSchema(String factSchemaURN) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Added: incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/DerbyFactStoreTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/DerbyFactStoreTest.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/DerbyFactStoreTest.java (added)
+++ incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/derby/DerbyFactStoreTest.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,40 @@
+package org.apache.stanbol.factstore.derby;
+
+import java.util.List;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.stanbol.commons.jsonld.JsonLdProfile;
+import org.apache.stanbol.factstore.model.FactSchema;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DerbyFactStoreTest {
+
+    @Test
+    public void testToSQLFromProfile() throws Exception {
+        DerbyFactStore fs = new DerbyFactStore();
+        JsonLdProfile jsonLd = new JsonLdProfile();
+        jsonLd.addNamespacePrefix("http://iks-project.eu/ont/", "iks");
+        
+        jsonLd.addType("person", "iks:person");
+        jsonLd.addType("organization", "iks:organization");
+        
+        String profile = "http://iks-project.eu/ont/employeeOf";
+        String profileB64 = Base64.encodeBase64URLSafeString(profile.getBytes());
+        
+        String expected = "CREATE TABLE aHR0cDovL2lrcy1wcm9qZWN0LmV1L29udC9lbXBsb3llZU9m (id INT GENERATED ALWAYS AS IDENTITY, person VARCHAR(1024), organization VARCHAR(1024))";
+        List<String> sqls = fs.toSQLfromSchema(profileB64, FactSchema.fromJsonLdProfile(profile, jsonLd));
+        Assert.assertEquals(1, sqls.size());
+        Assert.assertEquals(expected, sqls.get(0));
+    }
+
+    @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);
+    }
+}

Added: incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/FactSchemaTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/FactSchemaTest.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/FactSchemaTest.java (added)
+++ incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/model/FactSchemaTest.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,30 @@
+package org.apache.stanbol.factstore.model;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class FactSchemaTest {
+
+    @Test
+    public void testToJsonLd() {
+        FactSchema factSchema = new FactSchema();
+        factSchema.setFactSchemaURN("http://this.isatest.de/test");
+        factSchema.addRole("friend", "http://my.ontology.net/person");
+        factSchema.addRole("person", "http://my.ontology.net/person");
+        
+        String expected = "{\n  \"@context\": {\n    \"#types\": {\n      \"friend\": \"http:\\/\\/my.ontology.net\\/person\",\n      \"person\": \"http:\\/\\/my.ontology.net\\/person\"\n    }\n  }\n}";
+        String actual = factSchema.toJsonLdProfile().toString(2);
+        Assert.assertEquals(expected, actual);
+    }
+    
+    @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);
+    }
+}

Added: incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/FactsResourceTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/FactsResourceTest.java?rev=1138513&view=auto
==============================================================================
--- incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/FactsResourceTest.java (added)
+++ incubator/stanbol/trunk/factstore/src/test/java/org/apache/stanbol/factstore/web/resource/FactsResourceTest.java Wed Jun 22 15:46:40 2011
@@ -0,0 +1,81 @@
+package org.apache.stanbol.factstore.web.resource;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.stanbol.commons.testing.http.BundleContextMock;
+import org.apache.stanbol.commons.testing.http.ServletContextMock;
+import org.apache.stanbol.factstore.FactStoreMock;
+import org.apache.stanbol.factstore.api.FactStore;
+import org.apache.stanbol.factstore.web.resource.FactsResource;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+public class FactsResourceTest {
+
+    private ServletContextMock servletContext;
+
+    @Before
+    public void initMocks() {
+        this.servletContext = new ServletContextMock();
+        BundleContextMock bc = (BundleContextMock) this.servletContext.getAttribute(BundleContext.class
+                .getName());
+        bc.putService(FactStore.class.getName(), new FactStoreMock());
+    }
+
+    @Test
+    public void testGet() {
+        FactsResource fr = new FactsResource(this.servletContext);
+        Response response = fr.get();
+        assertTrue(response.getStatus() == Status.OK.getStatusCode());
+    }
+
+    @Test
+    public void testPutFactSchemaNoSchemaURI() {
+        FactsResource fr = new FactsResource(this.servletContext);
+
+        Response response = fr.putFactSchema("", null);
+        assertTrue(response.getStatus() == Status.BAD_REQUEST.getStatusCode());
+    }
+
+    @Test
+    public void testPutFactSchemaNoJSON() {
+        FactsResource fr = new FactsResource(this.servletContext);
+
+        Response response = fr.putFactSchema("no JSON-LD string", "test2");
+        assertTrue(response.getStatus() == Status.BAD_REQUEST.getStatusCode());
+    }
+
+    @Test
+    public void testPutFactSchemaNoJSONSchema() {
+        FactsResource fr = new FactsResource(this.servletContext);
+
+        Response response = fr.putFactSchema("{}", "test2");
+        assertTrue(response.getStatus() == Status.BAD_REQUEST.getStatusCode());
+    }
+
+    @Test
+    public void testTooLongURN() {
+        FactsResource fr = new FactsResource(this.servletContext);
+
+        Response response = fr
+                .putFactSchema(
+                    "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"#types\":{\"person\":\"iks:person\",\"organization\":\"iks:organization\"}}}",
+                    "http://www.test.de/this/urn/is/a/bit/too/long/to/be/used/in/this/fact/store/implementation/with/derby");
+        assertTrue(response.getStatus() == Status.BAD_REQUEST.getStatusCode());
+    }
+
+    @Test
+    public void testPutFactSchemaValidInput() {
+        FactsResource fr = new FactsResource(this.servletContext);
+
+        Response response = fr
+                .putFactSchema(
+                    "{\"@context\":{\"iks\":\"http://iks-project.eu/ont/\",\"#types\":{\"person\":\"iks:person\",\"organization\":\"iks:organization\"}}}",
+                    "test2");
+        assertTrue(response.getStatus() == Status.CREATED.getStatusCode());
+    }
+}