You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opennlp.apache.org by jo...@apache.org on 2011/07/09 18:36:34 UTC

svn commit: r1144699 - in /incubator/opennlp/sandbox/corpus-server: ./ src/main/java/org/apache/opennlp/corpus_server/ src/main/java/org/apache/opennlp/corpus_server/store/ src/main/webapp/WEB-INF/

Author: joern
Date: Sat Jul  9 16:36:33 2011
New Revision: 1144699

URL: http://svn.apache.org/viewvc?rev=1144699&view=rev
Log:
OPENNLP-208 Added derby storage support

Added:
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java   (with props)
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java   (with props)
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java   (contents, props changed)
      - copied, changed from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java   (with props)
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java   (with props)
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java   (contents, props changed)
      - copied, changed from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaStore.java
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java   (contents, props changed)
      - copied, changed from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java
Removed:
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaStore.java
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java
Modified:
    incubator/opennlp/sandbox/corpus-server/pom.xml
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaResource.java
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusResource.java
    incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/UimaUtil.java
    incubator/opennlp/sandbox/corpus-server/src/main/webapp/WEB-INF/web.xml

Modified: incubator/opennlp/sandbox/corpus-server/pom.xml
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/pom.xml?rev=1144699&r1=1144698&r2=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/pom.xml (original)
+++ incubator/opennlp/sandbox/corpus-server/pom.xml Sat Jul  9 16:36:33 2011
@@ -50,6 +50,14 @@
 	</repositories>
 	
 	<dependencies>
+	
+	    <dependency>
+      		<groupId>javax.servlet</groupId>
+      		<artifactId>servlet-api</artifactId>
+      		<version>2.4</version>
+      		<scope>provided</scope>
+    	</dependency>
+    
 		<dependency>
 		    <groupId>com.sun.jersey</groupId>
 		    <artifactId>jersey-server</artifactId>
@@ -63,6 +71,12 @@
 		</dependency>
 
 		<dependency>
+		    <groupId>org.apache.derby</groupId>
+		    <artifactId>derby</artifactId>
+		    <version>10.8.1.2</version>
+		</dependency>
+
+		<dependency>
 			<groupId>org.apache.uima</groupId>
 			<artifactId>uimaj-core</artifactId>
 			<version>2.3.1</version>

Modified: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaResource.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaResource.java?rev=1144699&r1=1144698&r2=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaResource.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaResource.java Sat Jul  9 16:36:33 2011
@@ -26,6 +26,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
+import org.apache.opennlp.corpus_server.store.CorporaStore;
+
 @Path("/corpora")
 public class CorporaResource {
 	
@@ -42,12 +44,20 @@ public class CorporaResource {
 	@Path("_createCorpus")
 	public void createCorpus(@QueryParam("corpusName") String corpusName,
 			byte[] typeSystemBytes) throws IOException {
-		CorporaStore.getStore().addCorpus(corpusName, typeSystemBytes);
+	  
+	  CorpusServer corpusServer = CorpusServer.getInstance();
+	  CorporaStore store = corpusServer.getStore();
+	  
+	  store.createCorpus(corpusName, typeSystemBytes);
 	}
-	
-	@Path("{corpus}")
+
+  @Path("{corpus}")
 	public CorpusResource getCorpus(
-			@PathParam("corpus") String corpus) {
-		return new CorpusResource(corpus);
+			@PathParam("corpus") String corpus) throws IOException {
+    
+      CorpusServer corpusServer = CorpusServer.getInstance();
+      CorporaStore store = corpusServer.getStore();
+    
+      return new CorpusResource(store.getCorpus(corpus));
 	}
 }

Modified: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusResource.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusResource.java?rev=1144699&r1=1144698&r2=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusResource.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusResource.java Sat Jul  9 16:36:33 2011
@@ -31,14 +31,15 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
+import org.apache.opennlp.corpus_server.store.CorpusStore;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 import org.xml.sax.SAXException;
 
 public class CorpusResource {
 
-	private final String corpus;
+	private final CorpusStore corpus;
 	
-	public CorpusResource(String corpus) {
+	public CorpusResource(CorpusStore corpus) {
 		this.corpus = corpus;
 	}
 	
@@ -52,8 +53,7 @@ public class CorpusResource {
 	@Path("{casId}")
 	public void addCAS(@PathParam("casId") String casId, 
 			byte[] cas) throws IOException {
-		CorpusStore corpusStore = CorporaStore.getStore().getCorpus(corpus);
-		corpusStore.addCAS(casId, cas);
+		corpus.addCAS(casId, cas);
 	}
 	
 	/**
@@ -65,8 +65,7 @@ public class CorpusResource {
 	@Path("{casId}")
 	public void updateCAS(@PathParam("casId") String casId, 
 			byte[] cas) throws IOException {
-		CorpusStore corpusStore = CorporaStore.getStore().getCorpus(corpus);
-		corpusStore.addCAS(casId, cas);
+		corpus.updateCAS(casId, cas);
 	}
 	
 	/**
@@ -77,9 +76,8 @@ public class CorpusResource {
 	@GET
 	@Produces(MediaType.TEXT_XML)
 	@Path("{casId}")
-	public byte[] getCAS(@PathParam("casId") String casId) {
-		CorpusStore corpusStore = CorporaStore.getStore().getCorpus(corpus);
-		return corpusStore.getCAS(casId);
+	public byte[] getCAS(@PathParam("casId") String casId) throws IOException{
+		return corpus.getCAS(casId);
 	}
 
 	/**
@@ -89,18 +87,15 @@ public class CorpusResource {
 	@GET
 	@Produces(MediaType.TEXT_XML)
 	@Path("_typesystem")
-	public byte[] getTypeSystem() {
-		CorpusStore corpusStore = CorporaStore.getStore().getCorpus(corpus);
-		
-		TypeSystemDescription typeSystem = corpusStore.getTypeSystem();
+	public byte[] getTypeSystem() throws IOException {
+		TypeSystemDescription typeSystem = corpus.getTypeSystem();
 
 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
 		
 		try {
 			typeSystem.toXML(bytes);
 		} catch (SAXException e) {
-			// TODO: Throw exception here to report error ...
-			e.printStackTrace();
+		  throw new IOException(e);
 		} catch (IOException e) {
 			throw new IllegalStateException("Writing to memory must not fail!");
 		}
@@ -111,8 +106,7 @@ public class CorpusResource {
 	@GET
 	@Produces(MediaType.APPLICATION_JSON)
 	@Path("_search")
-	public Collection<String> search(@QueryParam("q") String q) {
-		CorpusStore corpusStore = CorporaStore.getStore().getCorpus(corpus);
-		return corpusStore.search(q);
+	public Collection<String> search(@QueryParam("q") String q) throws IOException{
+		return corpus.search(q);
 	}
 }

Added: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java?rev=1144699&view=auto
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java (added)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java Sat Jul  9 16:36:33 2011
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.opennlp.corpus_server;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.opennlp.corpus_server.store.CorporaStore;
+import org.apache.opennlp.corpus_server.store.DerbyCorporaStore;
+
+public class CorpusServer implements ServletContextListener {
+
+  private final static Logger LOGGER = Logger.getLogger(
+      CorpusServer.class .getName());
+  
+  private static CorpusServer instance;
+  
+  private CorporaStore store;
+  
+  @Override
+  public void contextInitialized(ServletContextEvent sce) {
+    
+    instance = this;
+    store = new DerbyCorporaStore();
+    try {
+      store.initialize();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+  
+  @Override
+  public void contextDestroyed(ServletContextEvent sce) {
+    if (store != null)
+      try {
+        store.shutdown();
+      } catch (IOException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+  }
+
+  public CorporaStore getStore() {
+    return store;
+  }
+  
+  public static CorpusServer getInstance() {
+    return instance;
+  }
+}

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusServer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/UimaUtil.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/UimaUtil.java?rev=1144699&r1=1144698&r2=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/UimaUtil.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/UimaUtil.java Sat Jul  9 16:36:33 2011
@@ -42,7 +42,7 @@ import org.xml.sax.SAXException;
 
 public class UimaUtil {
 
-  static TypeSystemDescription createTypeSystemDescription(InputStream in) {
+  public static TypeSystemDescription createTypeSystemDescription(InputStream in) {
 
     // Note:
     // Type System location is not set correctly,
@@ -67,7 +67,7 @@ public class UimaUtil {
     return typeSystemDesciptor;
   }
 
-  static CAS createEmptyCAS(TypeSystemDescription typeSystem) {
+  public static CAS createEmptyCAS(TypeSystemDescription typeSystem) {
     ResourceSpecifierFactory resourceSpecifierFactory = UIMAFramework
         .getResourceSpecifierFactory();
     TypePriorities typePriorities = resourceSpecifierFactory
@@ -90,7 +90,7 @@ public class UimaUtil {
     return cas;
   }
 
-  static void deserializeXmiCAS(CAS cas, InputStream xmiIn) throws IOException {
+  public static void deserializeXmiCAS(CAS cas, InputStream xmiIn) throws IOException {
 
     SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
     saxParserFactory.setValidating(false);

Added: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java?rev=1144699&view=auto
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java (added)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java Sat Jul  9 16:36:33 2011
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.opennlp.corpus_server.store;
+
+import java.io.IOException;
+
+/**
+ * The Corpora Store is the central storage which manages the corpora.
+ */
+public interface CorporaStore {
+
+  /**
+   * Initializes the corpora store. Must be called before any other method
+   * of the store is called.
+   */
+  void initialize() throws IOException;
+  
+  /**
+   * Creates a new corpus. 
+   * <p>
+   * To create a corpus a unique name must be provided to refer to it
+   * and a type system to enforce that all CASes are compliant.
+   * 
+   * @param corpusName
+   * @param typeSystemBytes
+   */
+  void createCorpus(String corpusName, byte typeSystemBytes[]) throws IOException;
+  
+  /**
+   * Retrieves a corpus of the given name from the store.
+   * 
+   * @param corpusId the name of the coprus to retrieve
+   * 
+   * @return the corpus or null if it does not exist
+   */
+  CorpusStore getCorpus(String corpusId) throws IOException;
+  
+  /**
+   * Indicates that the store will no longer be used and no more
+   * methods will be called.
+   */
+  void shutdown() throws IOException;
+}

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorporaStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java (from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java)
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java?p2=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java&p1=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java&r1=1142743&r2=1144699&rev=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java Sat Jul  9 16:36:33 2011
@@ -15,59 +15,23 @@
  * limitations under the License.
  */
 
-package org.apache.opennlp.corpus_server;
+package org.apache.opennlp.corpus_server.store;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.uima.cas.CAS;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 
-/**
- * Dummy in memory corpus store.
- */
-public class CorpusStore {
 
-	private final String corpusName;
-	private final TypeSystemDescription typeSystem;
-	
-	private Map<String, byte[]> casStore = new HashMap<String, byte[]>();
-	
-	CorpusStore(String corpusName, TypeSystemDescription typeSystem) {
-		this.corpusName = corpusName;
-		this.typeSystem = typeSystem;
-	}
-	
-	public byte[] getCAS(String casId) {
-		return casStore.get(casId);
-	}
-	
-	// TODO: Add exception declaration to propagte errors back to client ...
-	public void addCAS(String casID, byte[] content) {
-		
-		// Note:
-		// Directly store data as xmi, but deserialization is needed to index and validate it!
-		
-		CAS cas = UimaUtil.createEmptyCAS(typeSystem);
-		
-		try {
-			UimaUtil.deserializeXmiCAS(cas, new ByteArrayInputStream(content));
-		} catch (IOException e) {
-			// TODO: Send error back to client ...
-			e.printStackTrace();
-		}
-		
-		casStore.put(casID, content);
-	}
-	
-	public TypeSystemDescription getTypeSystem() {
-		return typeSystem;
-	}
-	
-	public Collection<String> search(String query) {
-		return casStore.keySet();
-	}
+public interface CorpusStore {
+  
+  byte[] getCAS(String casId) throws IOException;
+  
+  void addCAS(String casID, byte[] content) throws IOException;
+  
+  void updateCAS(String casID, byte[] content) throws IOException;
+  
+  TypeSystemDescription getTypeSystem() throws IOException;
+  
+  Collection<String> search(String query) throws IOException;
 }

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/CorpusStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java?rev=1144699&view=auto
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java (added)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java Sat Jul  9 16:36:33 2011
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.opennlp.corpus_server.store;
+
+import java.io.IOException;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.sql.DataSource;
+
+import org.apache.derby.jdbc.EmbeddedDataSource40;
+
+public class DerbyCorporaStore implements CorporaStore {
+
+  private final static Logger LOGGER = Logger.getLogger(
+      DerbyCorporaStore.class .getName());
+  
+  private DataSource dataSource = null;
+
+  @Override
+  public void initialize() {
+
+    EmbeddedDataSource40 ds = new EmbeddedDataSource40(); 
+    ds.setDatabaseName("XmiCasDB7");
+    ds.setCreateDatabase("create");
+    
+    dataSource = ds;
+  }
+
+  @Override
+  public void createCorpus(String corpusName, byte[] typeSystemBytes)
+      throws IOException {
+    
+    try {
+      Connection conn = dataSource.getConnection();
+      Statement s = conn.createStatement();
+      s.execute("create table " + corpusName + 
+          "(name varchar(1024), cas blob, unique (name))");
+
+      // Insert the type system
+      PreparedStatement ps = conn.prepareStatement("insert into " + corpusName
+          + " values (?, ?)");
+
+      ps.setString(1, "_typesystem");
+
+      Blob b = conn.createBlob();
+      b.setBytes(1, typeSystemBytes);
+      ps.setBlob(2, b);
+
+      ps.executeUpdate();
+
+      conn.commit();
+      
+      ps.close();
+      conn.close();
+
+    } catch (SQLException e) {
+      
+      if (LOGGER.isLoggable(Level.SEVERE)) {
+        LOGGER.log(Level.SEVERE, "Failed to create corpus: " + 
+            corpusName, e);
+      }
+      
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public CorpusStore getCorpus(String corpusId) {
+    return new DerbyCorpusStore(dataSource, corpusId);
+  }
+
+  @Override
+  public void shutdown() throws IOException {
+    try {
+      DriverManager.getConnection("jdbc:derby:;shutdown=true");
+    } catch (SQLException e) {
+      if (((e.getErrorCode() == 50000) && ("XJ015".equals(e.getSQLState())))) {
+        // We got the expected exception
+
+        // Note that for single database shutdown, the expected
+        // SQL state is "08006", and the error code is 45000.
+      } else {
+        // if the error code or SQLState is different, we have
+        // an unexpected exception (shutdown failed)
+        throw new IOException(e);
+      }
+    }
+  }
+}

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorporaStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java?rev=1144699&view=auto
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java (added)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java Sat Jul  9 16:36:33 2011
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.opennlp.corpus_server.store;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.sql.DataSource;
+
+import org.apache.opennlp.corpus_server.UimaUtil;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+
+public class DerbyCorpusStore implements CorpusStore {
+
+  private final static Logger LOGGER = Logger.getLogger(
+      DerbyCorpusStore.class .getName());
+
+  private DataSource dataSource;
+  
+  private String corpusName;
+  
+  DerbyCorpusStore(DataSource dataSource, String corpusName) {
+    this.dataSource = dataSource;
+    this.corpusName = corpusName;
+  }
+  
+  @Override
+  public byte[] getCAS(String casId) throws IOException {
+    
+    byte casBytes[]  = null;
+    
+    try {
+      Connection conn = dataSource.getConnection();
+      Statement s = conn.createStatement();
+      ResultSet casResult = s.executeQuery("select * FROM " + corpusName +
+          " WHERE name='" + casId + "'");
+      
+      if (casResult.next()) {
+        casBytes = casResult.getBytes(2);
+      }
+      
+      casResult.close();
+      s.close();
+      conn.close();
+      
+    } catch (SQLException e) {
+      
+      if (LOGGER.isLoggable(Level.SEVERE)) {
+        LOGGER.log(Level.SEVERE, "Failed to retrieve CAS: " + 
+            casId, e);
+      }
+      
+      throw new IOException(e);
+    }
+    
+    return casBytes;
+  }
+
+  @Override
+  public void addCAS(String casID, byte[] content) throws IOException {
+    
+    try {
+      Connection conn = dataSource.getConnection();
+      PreparedStatement ps = conn.prepareStatement("insert into " + 
+          corpusName + " values (?, ?)");
+      
+      ps.setString(1, casID);
+      
+      Blob b = conn.createBlob();
+      b.setBytes(1, content);
+      ps.setBlob(2, b);
+      
+      ps.executeUpdate();
+      
+      conn.commit();
+      
+      ps.close();
+      conn.close();
+    } catch (SQLException e) {
+      
+      if (LOGGER.isLoggable(Level.SEVERE)) {
+        LOGGER.log(Level.SEVERE, "Failed to add CAS: " + 
+            casID, e);
+      }
+      
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void updateCAS(String casID, byte[] content) throws IOException {
+    try {
+      Connection conn = dataSource.getConnection();
+      PreparedStatement ps = conn.prepareStatement("update " + 
+          corpusName + " set cas = ? where name = ?");
+      
+      ps.setString(2, casID);
+      
+      Blob b = conn.createBlob();
+      b.setBytes(1, content);
+      ps.setBlob(1, b);
+      
+      ps.executeUpdate();
+      
+      conn.commit();
+      
+      ps.close();
+      conn.close();
+    } catch (SQLException e) {
+      
+      if (LOGGER.isLoggable(Level.SEVERE)) {
+        LOGGER.log(Level.SEVERE, "Failed to add CAS: " + 
+            casID, e);
+      }
+      
+      throw new IOException(e);
+    }
+  }
+  
+  @Override
+  public TypeSystemDescription getTypeSystem() throws IOException {
+    
+    TypeSystemDescription tsDescription = null;
+    
+    try {
+      Connection conn = dataSource.getConnection();
+      Statement s = conn.createStatement();
+      ResultSet tsResult = s.executeQuery("select * FROM " + corpusName + 
+          " WHERE name='_typesystem'");
+      
+      if (tsResult.next()) {
+        byte tsBytes[] = tsResult.getBytes(2);
+        tsDescription = UimaUtil.createTypeSystemDescription(
+            new ByteArrayInputStream(tsBytes));
+      }
+      
+      tsResult.close();
+      s.close();
+      conn.close();
+    } catch (SQLException e) {
+      
+      if (LOGGER.isLoggable(Level.SEVERE)) {
+        LOGGER.log(Level.SEVERE, "Failed to retrieve type system", e);
+      }
+      
+      throw new IOException(e);
+    }
+    
+    return tsDescription;
+  }
+
+  @Override
+  public Collection<String> search(String query) {
+    return null;
+  }
+}

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/DerbyCorpusStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java (from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaStore.java)
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java?p2=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java&p1=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaStore.java&r1=1142743&r2=1144699&rev=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorporaStore.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java Sat Jul  9 16:36:33 2011
@@ -15,36 +15,44 @@
  * limitations under the License.
  */
 
-package org.apache.opennlp.corpus_server;
+package org.apache.opennlp.corpus_server.store;
 
 import java.io.ByteArrayInputStream;
 import java.util.HashMap;
 import java.util.Map;
 
-public class CorporaStore {
+import org.apache.opennlp.corpus_server.UimaUtil;
+
+public class MemoryCorporaStore implements CorporaStore {
+	
+	private static MemoryCorporaStore instance;
 	
-	private static CorporaStore instance;
+	private Map<String, MemoryCorpusStore> corpora = new HashMap<String, MemoryCorpusStore>();
 	
-	private Map<String, CorpusStore> corpora = new HashMap<String, CorpusStore>();
+	public void initialize() {
+	}
+	
+	public void shutdown() {
+	}
 	
-	public static synchronized CorporaStore getStore() {
+	public static synchronized MemoryCorporaStore getStore() {
 		
 		if (instance == null) {
-			instance = new CorporaStore();
+			instance = new MemoryCorporaStore();
 		}
 		
 		return instance;
 	}
 	
 	// Note: Add one twice, overwrites an existing one!
-	public void addCorpus(String corpusName,
+	public void createCorpus(String corpusName,
 			byte typeSystemBytes[]) {
-		corpora.put(corpusName, new CorpusStore(corpusName, 
+		corpora.put(corpusName, new MemoryCorpusStore(corpusName, 
 				UimaUtil.createTypeSystemDescription(
 				new ByteArrayInputStream(typeSystemBytes))));
 	}
 	
-	public CorpusStore getCorpus(String corpusId) {
+	public MemoryCorpusStore getCorpus(String corpusId) {
 		return corpora.get(corpusId);
 	}
 }

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorporaStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java (from r1142743, incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java)
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java?p2=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java&p1=incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java&r1=1142743&r2=1144699&rev=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/CorpusStore.java (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java Sat Jul  9 16:36:33 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.opennlp.corpus_server;
+package org.apache.opennlp.corpus_server.store;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -23,20 +23,21 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.opennlp.corpus_server.UimaUtil;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 
 /**
  * Dummy in memory corpus store.
  */
-public class CorpusStore {
+public class MemoryCorpusStore implements CorpusStore {
 
 	private final String corpusName;
 	private final TypeSystemDescription typeSystem;
 	
 	private Map<String, byte[]> casStore = new HashMap<String, byte[]>();
 	
-	CorpusStore(String corpusName, TypeSystemDescription typeSystem) {
+	MemoryCorpusStore(String corpusName, TypeSystemDescription typeSystem) {
 		this.corpusName = corpusName;
 		this.typeSystem = typeSystem;
 	}
@@ -63,6 +64,11 @@ public class CorpusStore {
 		casStore.put(casID, content);
 	}
 	
+	@Override
+	public void updateCAS(String casID, byte[] content) throws IOException {
+	  addCAS(casID, content);
+	}
+	
 	public TypeSystemDescription getTypeSystem() {
 		return typeSystem;
 	}

Propchange: incubator/opennlp/sandbox/corpus-server/src/main/java/org/apache/opennlp/corpus_server/store/MemoryCorpusStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/opennlp/sandbox/corpus-server/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/opennlp/sandbox/corpus-server/src/main/webapp/WEB-INF/web.xml?rev=1144699&r1=1144698&r2=1144699&view=diff
==============================================================================
--- incubator/opennlp/sandbox/corpus-server/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/opennlp/sandbox/corpus-server/src/main/webapp/WEB-INF/web.xml Sat Jul  9 16:36:33 2011
@@ -24,6 +24,11 @@
 	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 	id="WebApp_ID" version="2.5">
 	<display-name>OpenNLP Corpus Server</display-name>
+	
+	<listener>
+    	<listener-class>org.apache.opennlp.corpus_server.CorpusServer</listener-class>
+  	</listener>
+  
 	<servlet>
 		<servlet-name>Jersey REST Service</servlet-name>
 		<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>