You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by su...@apache.org on 2012/07/30 12:32:34 UTC
svn commit: r1367053 - in
/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub: ./
bundlelist/src/main/bundles/ index/
index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/
revisionmanager/ revisionmanager/src/ revisionmana...
Author: suat
Date: Mon Jul 30 10:32:33 2012
New Revision: 1367053
URL: http://svn.apache.org/viewvc?rev=1367053&view=rev
Log:
STANBOL-498:
-Adapted the FileStore implementation according to newly added "epoch" mechanism in the Store interface
-Created a separate revisionmanager bundle so that other Store implementations can use the same revision management functionality
-Modified other classes (including tests) based on these changes
Added:
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/ (with props)
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml (with props)
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/RevisionManager.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/StoreDBManager.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/RevisionManagerTest.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/StoreDBManagerTest.java
Removed:
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileRevisionManager.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStoreDBManager.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileRevisionManagerTest.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreDBManagerTest.java
Modified:
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/bundlelist/src/main/bundles/list.xml
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/pom.xml
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndex.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndexManager.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/pom.xml
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/pom.xml
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStore.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/index/ldpath/LDPathSemanticIndexManagerTest.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartDeserializerTest.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartSerializerTest.java
incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreTest.java
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/bundlelist/src/main/bundles/list.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/bundlelist/src/main/bundles/list.xml?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/bundlelist/src/main/bundles/list.xml (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/bundlelist/src/main/bundles/list.xml Mon Jul 30 10:32:33 2012
@@ -24,6 +24,11 @@
</bundle>
<bundle>
<groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.contenthub.revisionmanager</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </bundle>
+ <bundle>
+ <groupId>org.apache.stanbol</groupId>
<artifactId>org.apache.stanbol.contenthub.search.featured</artifactId>
<version>0.10.0-incubating-SNAPSHOT</version>
</bundle>
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/pom.xml?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/pom.xml (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/pom.xml Mon Jul 30 10:32:33 2012
@@ -58,11 +58,6 @@
</dependency>
<dependency>
<groupId>org.apache.stanbol</groupId>
- <artifactId>org.apache.stanbol.contenthub.store.solr</artifactId>
- <version>0.10.0-incubating-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.stanbol</groupId>
<artifactId>org.apache.stanbol.commons.stanboltools.datafileprovider</artifactId>
<version>0.10.0-incubating-SNAPSHOT</version>
</dependency>
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndex.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndex.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndex.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndex.java Mon Jul 30 10:32:33 2012
@@ -882,8 +882,10 @@ public class LDPathSemanticIndex impleme
long revision = Long.MIN_VALUE;
boolean noChange = false;
do {
- cs = store.changes(revision, batchSize);
- for (String changed : cs.changed()) {
+ cs = store.changes(store.getEpoch(), revision, batchSize);
+ Iterator<String> changedItr = cs.iterator();
+ while (changedItr.hasNext()) {
+ String changed = changedItr.next();
ContentItem ci = store.get(changed);
if (ci == null) {
performRemove(changed);
@@ -891,7 +893,7 @@ public class LDPathSemanticIndex impleme
performIndex(ci);
}
}
- noChange = cs.changed().isEmpty() ? true : false;
+ noChange = cs.iterator().hasNext() ? false : true;
if (!noChange) {
revision = cs.toRevision();
}
@@ -919,14 +921,14 @@ public class LDPathSemanticIndex impleme
ChangeSet<ContentItem> changeSet = null;
try {
- changeSet = store.changes(revision, batchSize);
+ changeSet = store.changes(store.getEpoch(), revision, batchSize);
} catch (StoreException e) {
logger.error(
"Failed to get changes from FileRevisionManager with start revision: {} and batch size: {}",
revision, batchSize);
}
if (changeSet != null) {
- Iterator<String> changedItems = changeSet.changed().iterator();
+ Iterator<String> changedItems = changeSet.iterator();
boolean persist = true;
while (changedItems.hasNext()) {
String changedItem = changedItems.next();
@@ -952,7 +954,7 @@ public class LDPathSemanticIndex impleme
}
if (persist) {
try {
- if (changeSet.changed().size() != 0) {
+ if (changeSet.iterator().hasNext()) {
persist(changeSet.toRevision());
}
} catch (IndexException e) {
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndexManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndexManager.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndexManager.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/index/src/main/java/org/apache/stanbol/contenthub/index/ldpath/LDPathSemanticIndexManager.java Mon Jul 30 10:32:33 2012
@@ -65,8 +65,6 @@ public class LDPathSemanticIndexManager
private final Logger logger = LoggerFactory.getLogger(LDPathSemanticIndexManager.class);
- private final static String INDEX_METADATA_FOLDER_PATH = "LDPathSemanticIndexMetadata";
-
private File indexMetadataDirectory;
private Map<String,Properties> indexMetadataMap = new HashMap<String,Properties>();
@@ -86,7 +84,7 @@ public class LDPathSemanticIndexManager
this.bundleContext = context.getBundleContext();
ldPathUtils = new LDPathUtils(bundleContext.getBundle(), siteManager);
- indexMetadataDirectory = bundleContext.getDataFile(INDEX_METADATA_FOLDER_PATH);
+ indexMetadataDirectory = bundleContext.getDataFile(LDPathSemanticIndexManager.class.getName());
// if directory for programs does not exist, create it
if (!indexMetadataDirectory.exists()) {
@@ -165,7 +163,7 @@ public class LDPathSemanticIndexManager
props.put(LDPathSemanticIndex.PROP_DESCRIPTION, indexDescription);
return createIndex(props);
}
-
+
/**
* Creates an {@link LDPathSemanticIndex} instance based on the given index metadata. However, provided
* {@link Properties} must include the following items.
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/pom.xml?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/pom.xml (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/pom.xml Mon Jul 30 10:32:33 2012
@@ -38,13 +38,14 @@
<modules>
<module>parent</module>
<module>servicesapi</module>
+ <module>defaults</module>
+ <module>revisionmanager</module>
<module>store/file</module>
+ <module>index</module>
<module>search/solr</module>
<module>search/featured</module>
<module>search/related</module>
- <module>index</module>
<module>web</module>
- <module>defaults</module>
<module>test</module>
<module>bundlelist</module>
</modules>
Propchange: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jul 30 10:32:33 2012
@@ -0,0 +1,4 @@
+target
+.settings
+.classpath
+.project
Added: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml?rev=1367053&view=auto
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml (added)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml Mon Jul 30 10:32:33 2012
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<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>org.apache.stanbol.contenthub.parent</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ <relativePath>../parent</relativePath>
+ </parent>
+
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.contenthub.revisionmanager</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Apache Stanbol Contenthub Revision Manager</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <!-- Derby is only used through the JDBC API but needs to be in
+ the classpath of the caller to be able to create a new DB. -->
+ <Import-Package>
+ org.apache.derby.jdbc,
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <!-- Apache Stanbol dependencies -->
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.cmsadapter.servicesapi</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.commons.semanticindex.servicesapi</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.commons.semanticindex.core</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.cmsadapter.core</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.contenthub.servicesapi</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.7.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.hp.hpl.jena</groupId>
+ <artifactId>jena</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-client</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ </dependencies>
+</project>
+
Propchange: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/pom.xml
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/RevisionManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/RevisionManager.java?rev=1367053&view=auto
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/RevisionManager.java (added)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/RevisionManager.java Mon Jul 30 10:32:33 2012
@@ -0,0 +1,339 @@
+/*
+ * 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.stanbol.contenthub.revisionmanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+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.semanticindex.core.store.ChangeSetImpl;
+import org.apache.stanbol.commons.semanticindex.store.ChangeSet;
+import org.apache.stanbol.commons.semanticindex.store.Store;
+import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.apache.stanbol.enhancer.servicesapi.ContentItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * This class aims to manage the epochs of several {@link Store} implementations and the revisions regarding
+ * to the {@link ContentItem}s stored in {@link Store} instances. The revisions are kept in a single table in
+ * the scope of Apache Derby database. The system time is set as the new revision of the {@link ContentItem}
+ * when the {@link #updateRevision(Store, String)} method is called. Epochs of the Stores are managed in a
+ * single table initialized by {@link StoreDBManager}.
+ * </p>
+ * <p>
+ * In the scope of this RevisionManager {@link Store}s are identified by according to their names which can be
+ * obtained via the {@link Store#getName()} method.
+ * </p>
+ *
+ * @author suat
+ *
+ */
+@Component(immediate = true)
+@Service(value = RevisionManager.class)
+public class RevisionManager {
+ private static Logger log = LoggerFactory.getLogger(RevisionManager.class);
+
+ private String SELECT_REVISION = "SELECT id,revision FROM %s content_item_revision WHERE id = ?";
+
+ private String INSERT_REVISION = "INSERT INTO %s (id, revision) VALUES (?,?)";
+
+ private String UPDATE_REVISION = "UPDATE %s SET revision=? WHERE id=?";
+
+ private String SELECT_CHANGES = "SELECT id, revision FROM %s WHERE revision > ? ORDER BY revision ASC";
+
+ private String SELECT_MORECHANGES = "SELECT id, revision FROM %s WHERE revision >= ? ORDER BY revision ASC";
+
+ private String SELECT_EPOCH = "SELECT * FROM " + StoreDBManager.EPOCH_TABLE_NAME + " WHERE tableName = ?";
+
+ private String INSERT_EPOCH = "INSERT INTO " + StoreDBManager.EPOCH_TABLE_NAME
+ + " (epoch, tableName) values (?, ?)";
+
+ private String UPDATE_EPOCH = "UPDATE " + StoreDBManager.EPOCH_TABLE_NAME
+ + " SET epoch = ? WHERE tableName = ?";
+
+ @Reference
+ StoreDBManager dbManager;
+
+ /**
+ * Updates revision of the {@link ContentItem} specified with the <code>contentItemID</code> parameter and
+ * managed within the given {@code store}. The system time set as the new revision number by
+ * {@link System#currentTimeMillis()}.
+ *
+ * @param store
+ * The {@link Store} instance in which the {@link ContentItem} specified by the
+ * {@code contentItemID} is stored
+ * @param contentItemID
+ * ID of the {@link ContentItem} of which revision to be updated
+ * @throws StoreException
+ */
+ public <Item> void updateRevision(Store<Item> store, String contentItemID) throws StoreException {
+ // get connection
+ Connection con = dbManager.getConnection();
+ String revisionTableName = getStoreID(store);
+
+ // check existence of record for the given content item id
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ boolean recordExist = false;
+ try {
+ ps = con.prepareStatement(String.format(SELECT_REVISION, revisionTableName));
+ ps.setString(1, contentItemID);
+ rs = ps.executeQuery();
+ if (rs.next()) {
+ recordExist = true;
+ }
+
+ } catch (SQLException e) {
+ dbManager.closeConnection(con);
+ log.error("Failed to query revision of content item", e);
+ throw new StoreException("Failed to query revision of content item", e);
+ } finally {
+ dbManager.closeResultSet(rs);
+ dbManager.closeStatement(ps);
+ }
+
+ // update the table
+ try {
+ long newRevision = System.currentTimeMillis();
+ if (!recordExist) {
+ log.debug("New revision: {} for the content item: {} of Store: {} will be added",
+ new Object[] {newRevision, contentItemID, revisionTableName});
+ ps = con.prepareStatement(String.format(INSERT_REVISION, revisionTableName));
+ ps.setString(1, contentItemID);
+ ps.setLong(2, newRevision);
+ } else {
+ log.debug("New revision: {} for the content item: {} of Store: {} will be updated",
+ new Object[] {newRevision, contentItemID, revisionTableName});
+
+ ps = con.prepareStatement(String.format(UPDATE_REVISION, revisionTableName));
+ ps.setLong(1, newRevision);
+ ps.setString(2, contentItemID);
+ }
+ int updatedRecordNum = ps.executeUpdate();
+ // exactly one record should be affected
+ if (updatedRecordNum != 1) {
+ log.warn("Unexpected number of updated records: {}, should be 1", updatedRecordNum);
+ }
+ } catch (SQLException e) {
+ log.error("Failed to update revision", e);
+ throw new StoreException("Failed to update revision", e);
+ } finally {
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+
+ /**
+ * Returns the updates after the given revision number. If the total size of revisions after the given
+ * revision number fit in <code>batchSize</code>, all of the changes for the last revision are also
+ * included in the results. This is because we do not want to include a subset of the changes regarding to
+ * a particular revision in the result.
+ *
+ * @param store
+ * {@link Store} instance for which the changes are requested
+ * @param revision
+ * Starting revision of the to be returned in the results
+ * @param batchSize
+ * Maximum number of changes to be returned. However to return all changes regarding to
+ * particular revisions, the results might not have as much items as specified with this
+ * number. For instance, if there are 10 changes regarding a requested particular revision and
+ * this parameter is specified as 5, the results will include 10 changes.
+ * @return a {@link ChangeSet} including the changes in the specified Store.
+ * @throws StoreException
+ */
+ public <Item> ChangeSet<Item> getChanges(Store<Item> store, long revision, int batchSize) throws StoreException {
+ // get connection
+ Connection con = dbManager.getConnection();
+ String revisionTableName = getStoreID(store);
+
+ // check existence of record for the given content item id
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ ps = con.prepareStatement(String.format(SELECT_CHANGES, revisionTableName),
+ ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ ps.setLong(1, revision);
+ ps.setMaxRows(batchSize + 1);
+ rs = ps.executeQuery();
+
+ Set<String> changedUris = new LinkedHashSet<String>();
+
+ if (!rs.first()) {
+ return new ChangeSetImpl<Item>(store, store.getEpoch(), Long.MIN_VALUE, Long.MAX_VALUE,
+ changedUris);
+ }
+ if (rs.absolute(batchSize + 1)) {
+ long lastRowRevision = rs.getLong(2);
+ rs.previous();
+ long nextToLastRowRevision = rs.getLong(2);
+ rs.beforeFirst();
+ // if we are in the middle of a revision, add all changes in that revision to changedUris
+ if (lastRowRevision == nextToLastRowRevision) {
+ ps = con.prepareStatement(String.format(SELECT_MORECHANGES, revisionTableName),
+ ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ ps.setLong(1, revision);
+ rs = ps.executeQuery();
+
+ while (rs.next()) {
+ changedUris.add(rs.getString(1));
+ }
+ } else {
+ while (rs.next()) {
+ if (rs.isLast()) {
+ break;
+ }
+ changedUris.add(rs.getString(1));
+ }
+ }
+
+ } else {
+ rs.beforeFirst();
+ while (rs.next()) {
+ changedUris.add(rs.getString(1));
+ }
+ }
+
+ // set minimum and maximum revision numbers of the change set
+ if (rs.isLast()) {
+ rs.previous();
+ } else {
+ rs.last();
+ }
+ long to = rs.getLong(2);
+ rs.first();
+ long from = rs.getLong(2);
+
+ return new ChangeSetImpl<Item>(store, store.getEpoch(), from, to, changedUris);
+
+ } catch (SQLException e) {
+ log.error("Failed to get changes", e);
+ throw new StoreException("Failed to get changes", e);
+ } finally {
+ dbManager.closeResultSet(rs);
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+
+ /**
+ * Updates the epoch of the given {@link Store} with the {@link System#currentTimeMillis()}
+ *
+ * @param store
+ * Store instance of which epoch will be updated.
+ * @throws StoreException
+ */
+ public <Item> void updateEpoch(Store<Item> store) throws StoreException {
+ updateEpoch(store, false);
+ }
+
+ private <Item> void updateEpoch(Store<Item> store, boolean insert) throws StoreException {
+ // get connection
+ Connection con = dbManager.getConnection();
+ PreparedStatement ps = null;
+
+ // update the table
+ String storeID = getStoreID(store);
+ try {
+ long newEpoch = System.currentTimeMillis();
+ if (!insert) {
+ log.debug("New epoch: {} for the Store: {} will be updated", newEpoch, storeID);
+ ps = con.prepareStatement(UPDATE_EPOCH);
+ } else {
+ // check existence of the epoch entry for the given Store
+ ResultSet rs = null;
+ boolean recordExist = false;
+ try {
+ ps = con.prepareStatement(SELECT_EPOCH);
+ ps.setString(1, storeID);
+ rs = ps.executeQuery();
+ if (rs.next()) {
+ recordExist = true;
+ }
+
+ } catch (SQLException e) {
+ dbManager.closeConnection(con);
+ log.error("Failed to query revision of content item", e);
+ throw new StoreException("Failed to query revision of content item", e);
+ } finally {
+ dbManager.closeResultSet(rs);
+ dbManager.closeStatement(ps);
+ }
+
+ if (recordExist) {
+ log.debug("New epoch: {} for the Store: {} will be added", newEpoch, storeID);
+ ps = con.prepareStatement(INSERT_EPOCH);
+ } else {
+ // if there already exists an entry in the "epochTable" for the given store, return from
+ // the method
+ return;
+ }
+ }
+ ps.setLong(1, newEpoch);
+ ps.setString(2, storeID);
+ int updatedRecordNum = ps.executeUpdate();
+ // exactly one record should be affected
+ if (updatedRecordNum != 1) {
+ log.warn("Unexpected number of updated records: {}, should be 1", updatedRecordNum);
+ }
+ } catch (SQLException e) {
+ log.error("Failed to update epoch for Store identified as: {}", storeID, e);
+ throw new StoreException(String.format("Failed to update epoch for identified as: %s", storeID),
+ e);
+ } finally {
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+
+ /**
+ * Initializes the revision table for the given {@link Store} if not already done and creates an entry in
+ * the "epochTable" for the given Store. This method is expected to be called while initializing the
+ * {@link Store} implementations. For instance OSGi based Store implementations can call this method
+ * within the @Activate method.
+ *
+ * @param store
+ * Store instance of which revision tables are initialized
+ * @throws StoreException
+ */
+ public <Item> void initializeRevisionTables(Store<Item> store) throws StoreException {
+ // initialize tables if not already
+ dbManager.createRevisionTable(store.getName());
+
+ // add initial epoch for the store
+ updateEpoch(store, true);
+ }
+
+ /**
+ * Returns a string identifying the given {@link Store} instance in the scope of the revision management.
+ * Currently, the name of the Store is used as the identifiers of the Store. The name is obtained through
+ * the {@link Store#getName()} method.
+ *
+ * @param store
+ * @return
+ */
+ public <Item> String getStoreID(Store<Item> store) {
+ return store.getName();
+ }
+}
Added: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/StoreDBManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/StoreDBManager.java?rev=1367053&view=auto
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/StoreDBManager.java (added)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/revisionmanager/src/main/java/org/apache/stanbol/contenthub/revisionmanager/StoreDBManager.java Mon Jul 30 10:32:33 2012
@@ -0,0 +1,266 @@
+/*
+ * 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.stanbol.contenthub.revisionmanager;
+
+import java.net.ConnectException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+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.commons.semanticindex.store.Store;
+import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * This class manages the Apache Derby database tables utilized in the scope of {@link FileStore}. It is
+ * responsible only for existence of the tables. Population of the tables is done by dedicated classes.
+ * </p>
+ * <p>
+ * This class also provides common methods regarding with SQL objects e.g obtaining connection; closing
+ * connection, statement, result set.
+ * </p>
+ *
+ * @author suat
+ *
+ */
+@Component(immediate = true)
+@Service(value = StoreDBManager.class)
+public class StoreDBManager {
+
+ public static final String EPOCH_TABLE_NAME = "epochTable";
+
+ private static Logger log = LoggerFactory.getLogger(StoreDBManager.class);
+
+ private static int MAX_ID_LENGTH = 1024;
+
+ private static String DB_URL;
+
+ @Activate
+ protected void activate(ComponentContext componentContext) throws StoreException {
+ String stanbolHome = componentContext.getBundleContext().getProperty("sling.home");
+ DB_URL = "jdbc:derby:" + stanbolHome + "/contenthub/store/revisions;create=true";
+ // initialize the epoch table
+ createEpochTable();
+ }
+
+ /**
+ * Creates an empty revision table with the given name. Different {@link Store} implementations are
+ * expected to call this method in their initializations with the value to be obtained by
+ * {@link RevisionManager#getStoreID(Store)} method.
+ *
+ * @param tableName
+ * name of the table to be created
+ * @throws StoreException
+ */
+ public void createRevisionTable(String tableName) throws StoreException {
+ Connection con = getConnection();
+ Statement stmt = null;
+ try {
+ // try to create revision table
+ if (!existsTable(tableName)) {
+ String createRevisionTable = "CREATE TABLE " + tableName + " (" + "id VARCHAR("
+ + MAX_ID_LENGTH + ") NOT NULL PRIMARY KEY,"
+ + "revision BIGINT NOT NULL)";
+ stmt = con.createStatement();
+ stmt.executeUpdate(createRevisionTable);
+ log.info("Revision table created for {}.", tableName);
+ } else {
+ log.info("Revision table already exists for {}", tableName);
+ }
+
+ } catch (SQLException e) {
+ log.error(String.format("Failed to create table %s", tableName), e);
+ throw new StoreException(String.format("Failed to create table %s", tableName), e);
+ } finally {
+ closeStatement(stmt);
+ closeConnection(con);
+ }
+ }
+
+ private void createEpochTable() throws StoreException {
+ Connection con = getConnection();
+ Statement stmt = null;
+ try {
+ // try to create revision table
+ if (!existsTable(EPOCH_TABLE_NAME)) {
+ String createRevisionTable = "CREATE TABLE " + EPOCH_TABLE_NAME + " (" + "tableName VARCHAR("
+ + MAX_ID_LENGTH + ") NOT NULL PRIMARY KEY,"
+ + "epoch BIGINT NOT NULL)";
+ stmt = con.createStatement();
+ stmt.executeUpdate(createRevisionTable);
+ log.info("'" + EPOCH_TABLE_NAME + "' table has been created.");
+ } else {
+ log.info("'" + EPOCH_TABLE_NAME + "' table already exists.");
+ }
+
+ } catch (SQLException e) {
+ log.error(String.format("Failed to create table %s", EPOCH_TABLE_NAME), e);
+ throw new StoreException(String.format("Failed to create table %s", EPOCH_TABLE_NAME), e);
+ } finally {
+ closeStatement(stmt);
+ closeConnection(con);
+ }
+ }
+
+ /**
+ * Check for the existence of the specified table
+ *
+ * @param tableName
+ * name of the table to be checked
+ * @return <code>true</code> if the table already exists, otherwise <code>false</code>.
+ * @throws StoreException
+ */
+ public boolean existsTable(String tableName) throws StoreException {
+ boolean exists = false;
+ ResultSet rs = null;
+ Connection con = getConnection();
+ try {
+ con = DriverManager.getConnection(DB_URL);
+ DatabaseMetaData meta = con.getMetaData();
+ rs = meta.getTables(null, null, null, new String[] {"TABLE"});
+ while (rs.next()) {
+ if (rs.getString("TABLE_NAME").equalsIgnoreCase(tableName)) {
+ exists = true;
+ break;
+ }
+ }
+ } catch (SQLException e) {
+ log.error("Failed to check existence of the table: {}", tableName);
+ throw new StoreException(String.format("Failed to check existence of the table: %s", tableName),
+ e);
+ } finally {
+ closeResultSet(rs);
+ closeConnection(con);
+ }
+ return exists;
+ }
+
+ /**
+ * Truncates the content of the table specified with the {@code tableName}
+ *
+ * @param tableName
+ * name of the table to be truncated
+ * @throws StoreException
+ */
+ public void truncateTable(String tableName) throws StoreException {
+ boolean exists = false;
+ ResultSet rs = null;
+ Connection con = getConnection();
+ try {
+ con = DriverManager.getConnection(DB_URL);
+ DatabaseMetaData meta = con.getMetaData();
+ rs = meta.getTables(null, null, null, new String[] {"TABLE"});
+ while (rs.next()) {
+ if (rs.getString("TABLE_NAME").equalsIgnoreCase(tableName)) {
+ exists = true;
+ break;
+ }
+ }
+ } catch (SQLException e) {
+ log.error("Failed to check existence of the table: {}", tableName);
+ throw new StoreException(String.format("Failed to check existence of the table: %s", tableName),
+ e);
+ } finally {
+ closeResultSet(rs);
+ closeConnection(con);
+ }
+ if (!exists) {
+ throw new IllegalArgumentException(String.format("There is no table having name: %s", tableName));
+ }
+ String truncateTable = "TRUNCATE TABLE " + tableName;
+ Statement stmt = null;
+ try {
+ stmt = con.createStatement();
+ stmt.execute(truncateTable);
+ } catch (SQLException e) {
+ log.error("Failed to truncate table: {}", tableName, e);
+ throw new StoreException(String.format("Failed to truncate table: %s", tableName), e);
+ }
+ log.debug("Table having name: {} has been truncated", tableName);
+ }
+
+ /**
+ * Closes the given {@link Connection}
+ *
+ * @param con
+ */
+ public void closeConnection(Connection con) {
+ if (con != null) {
+ try {
+ con.close();
+ } catch (SQLException e) {
+ log.warn("Failed to close connection", e);
+ }
+ }
+ }
+
+ /**
+ * Closes the given {@link Statement}
+ *
+ * @param stmt
+ */
+ public void closeStatement(Statement stmt) {
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ log.warn("Failed to close prepared statement", e);
+ }
+ }
+ }
+
+ /**
+ * Closes the given {@link ResultSet}
+ *
+ * @param rs
+ */
+ public void closeResultSet(ResultSet rs) {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ log.warn("Failed to close result set", e);
+ }
+ }
+ }
+
+ /**
+ * Creates a {@link ConnectException}
+ *
+ * @return the {@link Connection} if successfully established
+ * @throws StoreException
+ */
+ public Connection getConnection() throws StoreException {
+ Connection con = null;
+ try {
+ con = DriverManager.getConnection(DB_URL);
+ } catch (SQLException e) {
+ log.error("Failed to obtain Derby connection", e);
+ throw new StoreException("Failed to obtain Derby connection", e);
+ }
+ return con;
+ }
+}
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/pom.xml?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/pom.xml (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/pom.xml Mon Jul 30 10:32:33 2012
@@ -33,16 +33,6 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
- <configuration>
- <instructions>
- <!-- Derby is only used through the JDBC API but needs to be in
- the classpath of the caller to be able to create a new DB. -->
- <Import-Package>
- org.apache.derby.jdbc,
- *
- </Import-Package>
- </instructions>
- </configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
@@ -81,12 +71,10 @@
<artifactId>rdf.core</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- <version>10.7.1.1</version>
+ <groupId>org.apache.stanbol</groupId>
+ <artifactId>org.apache.stanbol.contenthub.revisionmanager</artifactId>
+ <version>0.10.0-incubating-SNAPSHOT</version>
</dependency>
-
-
<dependency>
<groupId>org.apache.commons</groupId>
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStore.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStore.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStore.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/store/file/src/main/java/org/apache/stanbol/contenthub/store/file/FileStore.java Mon Jul 30 10:32:33 2012
@@ -28,6 +28,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -49,6 +50,7 @@ import org.apache.clerezza.rdf.core.UriR
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
@@ -56,8 +58,11 @@ import org.apache.felix.scr.annotations.
import org.apache.stanbol.commons.indexedgraph.IndexedMGraph;
import org.apache.stanbol.commons.semanticindex.core.store.ChangeSetImpl;
import org.apache.stanbol.commons.semanticindex.store.ChangeSet;
+import org.apache.stanbol.commons.semanticindex.store.EpochException;
import org.apache.stanbol.commons.semanticindex.store.Store;
import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.apache.stanbol.contenthub.revisionmanager.RevisionManager;
+import org.apache.stanbol.contenthub.revisionmanager.StoreDBManager;
import org.apache.stanbol.contenthub.store.file.serializer.ContentPartDeserializer;
import org.apache.stanbol.contenthub.store.file.serializer.ContentPartSerializer;
import org.apache.stanbol.enhancer.servicesapi.Blob;
@@ -106,19 +111,14 @@ import org.slf4j.LoggerFactory;
@Service
@Properties(value = {@Property(name = Constants.SERVICE_RANKING, intValue = 100)})
public class FileStore implements Store<ContentItem> {
- //TODO: IMPORTANT
- // We need to move the Contenthub related business logic out of this class!
- // Otherwise one can not implement/use different store implementations.
- //
- // e.g. the #put(..) method MUST NOT enhance the contentItem. It is only
- // expected to store the parsed content item (without modifications).
- // The logic if the Contenthub needs to enhance ContentItems needs to be
- // outside of the actual Store implementation
-
-
-
- // @Property(name = Constants.SERVICE_RANKING)
- // private int ranking;
+ // TODO: IMPORTANT
+ // We need to move the Contenthub related business logic out of this class!
+ // Otherwise one can not implement/use different store implementations.
+ //
+ // e.g. the #put(..) method MUST NOT enhance the contentItem. It is only
+ // expected to store the parsed content item (without modifications).
+ // The logic if the Contenthub needs to enhance ContentItems needs to be
+ // outside of the actual Store implementation
public static final String RECENTLY_ENHANCED_TABLE_NAME = "recently_enhanced_content_items";
@@ -138,9 +138,19 @@ public class FileStore implements Store<
public static final String FILE_STORE_NAME = "filestore";
- private static final String SELECT_RECENTLY_ENHANCED_ITEMS = "SELECT t1.id, mimeType, enhancementCount, title FROM "
- + FileRevisionManager.REVISION_TABLE_NAME
- + " t1, "
+ private static int MAX_ID_LENGTH = 1024;
+
+ private static final String CREATE_RECENTLY_ENHANCED_TABLE = "CREATE TABLE "
+ + RECENTLY_ENHANCED_TABLE_NAME + " ("
+ + FIELD_ID + " VARCHAR(" + MAX_ID_LENGTH
+ + " ) NOT NULL PRIMARY KEY,"
+ + FIELD_MIME_TYPE + " VARCHAR("
+ + MAX_ID_LENGTH + "),"
+ + FIELD_ENHANCEMENT_COUNT + " BIGINT,"
+ + FIELD_TITLE + " VARCHAR(" + MAX_ID_LENGTH
+ + "))";
+
+ private static final String SELECT_RECENTLY_ENHANCED_ITEMS = "SELECT t1.id, mimeType, enhancementCount, title FROM %s t1, "
+ RECENTLY_ENHANCED_TABLE_NAME
+ " t2 WHERE"
+ " t1.id=t2."
@@ -172,13 +182,13 @@ public class FileStore implements Store<
private File storeFolder;
@Reference
- ContentItemFactory contentItemFactory;
+ private ContentItemFactory contentItemFactory;
@Reference
- FileRevisionManager revisionManager;
+ private RevisionManager revisionManager;
@Reference
- FileStoreDBManager dbManager;
+ private StoreDBManager dbManager;
@Reference
private ContentPartSerializer contentPartSerializer;
@@ -188,7 +198,7 @@ public class FileStore implements Store<
@Reference
private EnhancementJobManager jobManager;
-
+
Map<String,Object> storeProperties;
@Activate
@@ -198,41 +208,61 @@ public class FileStore implements Store<
storeFolder = new File(stanbolHome + "/" + FILE_STORE_FOLDER_PATH + "/" + FILE_STORE_NAME);
if (!storeFolder.exists()) {
storeFolder.mkdirs();
+ } else {
+ if (!storeFolder.isDirectory()) {
+ log.error(String.format("There must be a directory in the path: %s",
+ storeFolder.getAbsolutePath()));
+ throw new IllegalStateException(String.format("There must be a directory in the path: %s",
+ storeFolder.getAbsolutePath()));
+ }
}
+
// init the store properties
- Map<String,Object> properties = new HashMap<String, Object>();
- properties.put(PROPERTY_NAME, getName());
- properties.put(PROPERTY_DESCRIPTION, getDescription());
- properties.put(PROPERTY_ITEM_TYPE, getItemType());
- storeProperties = Collections.unmodifiableMap(properties);
+ Map<String,Object> properties = new HashMap<String,Object>();
+ properties.put(PROPERTY_NAME, getName());
+ properties.put(PROPERTY_DESCRIPTION, getDescription());
+ properties.put(PROPERTY_ITEM_TYPE, getItemType());
+ storeProperties = Collections.unmodifiableMap(properties);
+
+ // create file store revision and recentlyenhanced tables
+ revisionManager.initializeRevisionTables(this);
+ createRecentlyEnhancedTable();
}
+ @Deactivate
protected void deactivate(ComponentContext context) {
- storeProperties = null;
+ storeProperties = null;
}
-
+
/*
- * NOTE: This implementation assume a single FileStore instance.
- * If this is changed this implementations need to be adapted.
+ * NOTE: This implementation assume a single FileStore instance. If this is changed this implementations
+ * need to be adapted.
*/
@Override
public String getName() {
- return "contenthubFileStore";
+ return "contenthubFileStore";
}
-
+
/*
- * NOTE: This implementation assume a single FileStore instance.
- * If this is changed this implementations need to be adapted.
+ * NOTE: This implementation assume a single FileStore instance. If this is changed this implementations
+ * need to be adapted.
*/
@Override
public String getDescription() {
- return "File based Store implementation for ContentItems used by the Stanbol Contenthub";
+ return "File based Store implementation for ContentItems used by the Stanbol Contenthub";
+ }
+
+ @Override
+ public long getEpoch() {
+ // TODO Auto-generated method stub
+ return 0;
}
-
+
@Override
- public Map<String, Object> getProperties() {
- return storeProperties;
+ public Map<String,Object> getProperties() {
+ return storeProperties;
}
+
@Override
public Class<ContentItem> getItemType() {
return ContentItem.class;
@@ -267,9 +297,11 @@ public class FileStore implements Store<
@Override
public void removeAll() throws StoreException {
- ChangeSet<ContentItem> changes = changes(Long.MIN_VALUE, Integer.MAX_VALUE);
+ ChangeSet<ContentItem> changes = changes(Long.MIN_VALUE, Long.MIN_VALUE, Integer.MAX_VALUE);
List<ContentItem> removed = new ArrayList<ContentItem>();
- for (String id : changes.changed()) {
+ Iterator<String> idIterator = changes.iterator();
+ while (idIterator.hasNext()) {
+ String id = idIterator.next();
ContentItem ci = remove(id);
if (ci != null) {
removed.add(ci);
@@ -279,7 +311,7 @@ public class FileStore implements Store<
private void updateTablesForDelete(String id) throws StoreException {
// update revision
- revisionManager.updateRevision(id);
+ revisionManager.updateRevision(this, id);
// update recently_enhanced table
removeFromRecentlyEnhancedTable(id);
}
@@ -392,7 +424,7 @@ public class FileStore implements Store<
// ignore the exception
}
try {
- revisionManager.updateRevision(htmlMetadata.getString(FIELD_ID));
+ revisionManager.updateRevision(this, htmlMetadata.getString(FIELD_ID));
updateRecentlyEnhancedItem(htmlMetadata.getString(FIELD_ID), title,
htmlMetadata.getString(FIELD_MIME_TYPE), htmlMetadata.getLong(FIELD_ENHANCEMENT_COUNT));
} catch (JSONException e) {
@@ -400,65 +432,6 @@ public class FileStore implements Store<
}
}
- private void updateRecentlyEnhancedItem(String contentItemID,
- String title,
- String mimeType,
- long enhancementCount) throws StoreException {
- // get connection
- Connection con = dbManager.getConnection();
-
- // check existence of record for the given content item id
- PreparedStatement ps = null;
- ResultSet rs = null;
- boolean recordExist = false;
- try {
- ps = con.prepareStatement(SELECT_RECENTLY_ENHANCED_ITEM);
- ps.setString(1, contentItemID);
- rs = ps.executeQuery();
- if (rs.next()) {
- recordExist = true;
- }
-
- } catch (SQLException e) {
- dbManager.closeConnection(con);
- log.error("Failed to query information of content item", e);
- throw new StoreException("Failed to query information of content item", e);
- } finally {
- dbManager.closeResultSet(rs);
- dbManager.closeStatement(ps);
- }
-
- // update the table
- try {
- if (!recordExist) {
- log.debug("Content item: {} will be added to recently_enhanced table", contentItemID);
- ps = con.prepareStatement(INSERT_RECENTLY_ENHANCED_ITEM);
- ps.setString(1, contentItemID);
- ps.setString(2, title);
- ps.setString(3, mimeType);
- ps.setLong(4, enhancementCount);
- } else {
- log.debug("Content item: {} will be updated in recently_enhanced table", contentItemID);
- ps = con.prepareStatement(UPDATE_RECENTLY_ENHANCED_ITEM);
- ps.setString(1, mimeType);
- ps.setString(2, title);
- ps.setLong(3, enhancementCount);
- ps.setString(4, contentItemID);
- }
- int updatedRecordNum = ps.executeUpdate();
- // exactly one record should be affected
- if (updatedRecordNum != 1) {
- log.warn("Unexpected number of updated records: {}, should be 1", updatedRecordNum);
- }
- } catch (SQLException e) {
- log.error("Failed to update recently_enhanced table", e);
- throw new StoreException("Failed to update recently_enhanced table", e);
- } finally {
- dbManager.closeStatement(ps);
- dbManager.closeConnection(con);
- }
- }
-
private void archiveContentItem(ContentItem ci) throws StoreException {
String fileName = encodeId(ci.getUri().getUnicodeString());
File file = new File(storeFolder.getPath() + "/" + fileName + ".zip");
@@ -769,10 +742,12 @@ public class FileStore implements Store<
}
@Override
- public ChangeSet<ContentItem> changes(long revision, int batchSize) throws StoreException {
- ChangeSetImpl<ContentItem> changesSet = (ChangeSetImpl<ContentItem>) revisionManager.getChanges(
+ public ChangeSet<ContentItem> changes(long epoch, long revision, int batchSize) throws StoreException {
+ if (getEpoch() != epoch) {
+ throw new EpochException(this, getEpoch(), epoch);
+ }
+ ChangeSetImpl<ContentItem> changesSet = (ChangeSetImpl<ContentItem>) revisionManager.getChanges(this,
revision, batchSize);
- changesSet.setStore(this);
return changesSet;
}
@@ -791,6 +766,65 @@ public class FileStore implements Store<
}
}
+ private void updateRecentlyEnhancedItem(String contentItemID,
+ String title,
+ String mimeType,
+ long enhancementCount) throws StoreException {
+ // get connection
+ Connection con = dbManager.getConnection();
+
+ // check existence of record for the given content item id
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ boolean recordExist = false;
+ try {
+ ps = con.prepareStatement(SELECT_RECENTLY_ENHANCED_ITEM);
+ ps.setString(1, contentItemID);
+ rs = ps.executeQuery();
+ if (rs.next()) {
+ recordExist = true;
+ }
+
+ } catch (SQLException e) {
+ dbManager.closeConnection(con);
+ log.error("Failed to query information of content item", e);
+ throw new StoreException("Failed to query information of content item", e);
+ } finally {
+ dbManager.closeResultSet(rs);
+ dbManager.closeStatement(ps);
+ }
+
+ // update the table
+ try {
+ if (!recordExist) {
+ log.debug("Content item: {} will be added to recently_enhanced table", contentItemID);
+ ps = con.prepareStatement(INSERT_RECENTLY_ENHANCED_ITEM);
+ ps.setString(1, contentItemID);
+ ps.setString(2, title);
+ ps.setString(3, mimeType);
+ ps.setLong(4, enhancementCount);
+ } else {
+ log.debug("Content item: {} will be updated in recently_enhanced table", contentItemID);
+ ps = con.prepareStatement(UPDATE_RECENTLY_ENHANCED_ITEM);
+ ps.setString(1, mimeType);
+ ps.setString(2, title);
+ ps.setLong(3, enhancementCount);
+ ps.setString(4, contentItemID);
+ }
+ int updatedRecordNum = ps.executeUpdate();
+ // exactly one record should be affected
+ if (updatedRecordNum != 1) {
+ log.warn("Unexpected number of updated records: {}, should be 1", updatedRecordNum);
+ }
+ } catch (SQLException e) {
+ log.error("Failed to update recently_enhanced table", e);
+ throw new StoreException("Failed to update recently_enhanced table", e);
+ } finally {
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+
public List<JSONObject> getRecentlyEnhancedItems(int limit, int offset) throws StoreException {
// get connection
Connection con = dbManager.getConnection();
@@ -799,7 +833,8 @@ public class FileStore implements Store<
ResultSet rs = null;
List<JSONObject> recentlyEnhancedList = new ArrayList<JSONObject>();
try {
- ps = con.prepareStatement(SELECT_RECENTLY_ENHANCED_ITEMS);
+ ps = con.prepareStatement(String.format(SELECT_RECENTLY_ENHANCED_ITEMS,
+ revisionManager.getStoreID(this)));
ps.setMaxRows(limit);
ps.setInt(1, offset);
rs = ps.executeQuery();
@@ -825,4 +860,25 @@ public class FileStore implements Store<
return recentlyEnhancedList;
}
+
+ private void createRecentlyEnhancedTable() throws StoreException {
+ Connection con = dbManager.getConnection();
+ Statement stmt = null;
+ try {
+ // try to create recently_enhanced table
+ if (!dbManager.existsTable(RECENTLY_ENHANCED_TABLE_NAME)) {
+ stmt = con.createStatement();
+ stmt.executeUpdate(CREATE_RECENTLY_ENHANCED_TABLE);
+ log.info("RecentlyEnhanced table created.");
+ } else {
+ log.info("RecentlyEnhanced table already exists");
+ }
+ } catch (SQLException e) {
+ log.error("Failed to create recentlyenhanced table", e);
+ throw new StoreException("Failed to create recentlyenhanced table", e);
+ } finally {
+ dbManager.closeStatement(stmt);
+ dbManager.closeConnection(con);
+ }
+ }
}
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/index/ldpath/LDPathSemanticIndexManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/index/ldpath/LDPathSemanticIndexManagerTest.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/index/ldpath/LDPathSemanticIndexManagerTest.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/index/ldpath/LDPathSemanticIndexManagerTest.java Mon Jul 30 10:32:33 2012
@@ -48,8 +48,6 @@ import org.slf4j.LoggerFactory;
public class LDPathSemanticIndexManagerTest {
private static Logger logger = LoggerFactory.getLogger(LDPathSemanticIndexManagerTest.class);
- private final static String INDEX_METADATA_FOLDER_PATH = "LDPathSemanticIndexMetadata";
-
@TestReference
private LDPathSemanticIndexManager ldPathSemanticIndexManager;
@@ -125,7 +123,7 @@ public class LDPathSemanticIndexManagerT
// check IndexMetadata folder exists
File indexMetadataDirectory = bundleContext
.getServiceReference(LDPathSemanticIndexManager.class.getName()).getBundle()
- .getBundleContext().getDataFile(INDEX_METADATA_FOLDER_PATH);
+ .getBundleContext().getDataFile(LDPathSemanticIndexManager.class.getName());
assertTrue("IndexMetadata Directory does not exist", indexMetadataDirectory.exists());
// check IndexMetadata files of indexes before remove index
@@ -179,7 +177,7 @@ public class LDPathSemanticIndexManagerT
File indexMetadataDirectory = bundleContext
.getServiceReference(LDPathSemanticIndexManager.class.getName()).getBundle()
- .getBundleContext().getDataFile(INDEX_METADATA_FOLDER_PATH);
+ .getBundleContext().getDataFile(LDPathSemanticIndexManager.class.getName());
Map<String,Properties> indexMetadataMap = new HashMap<String,Properties>();
// load index metadata to memory
Added: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/RevisionManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/RevisionManagerTest.java?rev=1367053&view=auto
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/RevisionManagerTest.java (added)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/RevisionManagerTest.java Mon Jul 30 10:32:33 2012
@@ -0,0 +1,285 @@
+/*
+ * 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.stanbol.contenthub.test.revisionmanager;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.apache.sling.junit.annotations.SlingAnnotationsTestRunner;
+import org.apache.sling.junit.annotations.TestReference;
+import org.apache.stanbol.commons.semanticindex.store.ChangeSet;
+import org.apache.stanbol.commons.semanticindex.store.Store;
+import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.apache.stanbol.contenthub.revisionmanager.RevisionManager;
+import org.apache.stanbol.contenthub.revisionmanager.StoreDBManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(SlingAnnotationsTestRunner.class)
+public class RevisionManagerTest {
+ private static Logger log = LoggerFactory.getLogger(RevisionManagerTest.class);
+
+ @TestReference
+ private RevisionManager revisionManager;
+
+ @TestReference
+ private StoreDBManager dbManager;
+
+ @TestReference
+ private Store<?> store;
+
+ @Test
+ public void revisionManagerTest() {
+ assertNotNull("Expecting revisionManager to be injected by Sling test runner", revisionManager);
+ }
+
+ @Test
+ public void dbManagerTest() {
+ assertNotNull("Expecting FileStoreDBManager to be injected by Sling test runner", dbManager);
+ }
+
+ @Test
+ public void updateChangeTest() throws StoreException, SQLException {
+ // do the update
+ String contentItemID = "contenthub_test_content_item_id";
+ revisionManager.updateRevision(store, contentItemID);
+
+ // check the update
+ String query = String.format("SELECT id, revision FROM %s WHERE id = ?",
+ revisionManager.getStoreID(store));
+ Connection con = dbManager.getConnection();
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ boolean recordExist = false;
+ long revisionNumber = Long.MAX_VALUE;
+ try {
+ ps = con.prepareStatement(query);
+ ps.setString(1, contentItemID);
+ rs = ps.executeQuery();
+ if (rs.next()) {
+ recordExist = true;
+ revisionNumber = rs.getLong(2);
+ }
+ } finally {
+ dbManager.closeResultSet(rs);
+ dbManager.closeStatement(ps);
+ }
+
+ assertTrue("failed to obtain content item revision", recordExist);
+ assertTrue("wrong revision number", (revisionNumber <= System.currentTimeMillis()));
+
+ // clear the update
+ query = String.format("DELETE FROM %s WHERE id = ?", revisionManager.getStoreID(store));
+ ps = null;
+ try {
+ ps = con.prepareStatement(query);
+ ps.setString(1, contentItemID);
+ int result = ps.executeUpdate();
+ if (result != 1) {
+ log.warn(
+ "Wrong number of updated records while removing the test record. Updated record number: {}",
+ result);
+ }
+ } catch (SQLException e) {
+ log.warn("Failed to remove the test record", e);
+ } finally {
+ dbManager.closeConnection(con);
+ dbManager.closeStatement(ps);
+ }
+ }
+
+ /**
+ * IMPORTANT NOTE: At time of executing the test below, there MUST be no other requests updating the
+ * revision table, otherwise the test will fail.
+ *
+ * @throws InterruptedException
+ * @throws SQLException
+ */
+ @Test
+ public void iterativeChangesTest() throws StoreException, InterruptedException, SQLException {
+ log.warn("DO NOT UPDATE THE STORE: {}DURING EXECUTION OF THIS TEST", store.getName());
+ Connection con = dbManager.getConnection();
+ String contentItemID = "contenthub_test_content_item_id";
+ PreparedStatement ps = null;
+ int insertCount = 0;
+ try {
+ // do the update
+ String query = "INSERT INTO " + revisionManager.getStoreID(store)
+ + " (id, revision) VALUES (?,?)";
+ long startRevision = System.currentTimeMillis();
+ long revision = System.currentTimeMillis();
+ for (int i = 0; i < 5; i++) {
+ // to ensure different revisions
+ ps = con.prepareStatement(query);
+ ps.setString(1, contentItemID + i);
+ ps.setLong(2, ++revision);
+ ps.executeUpdate();
+ ps.clearParameters();
+ insertCount++;
+ }
+
+ // check changes
+ ChangeSet<?> changeSet = revisionManager.getChanges(store, startRevision, 3);
+ Iterator<String> changedItems = changeSet.iterator();
+ int itemCount = 0;
+ while (changedItems.hasNext()) {
+ changedItems.next();
+ itemCount++;
+ }
+ assertTrue("Wrong number of changed items", (itemCount == 3));
+ for (int i = 0; i < 3; i++) {
+ changedItems = changeSet.iterator();
+ itemCount = 0;
+ while (changedItems.hasNext()) {
+ String changedItem = changedItems.next();
+ if (changedItem.equals(contentItemID + i)) break;
+ itemCount++;
+ }
+ assertTrue("Changes does not include correct URIs", itemCount < 3);
+ }
+ assertTrue("Changes does not include correct fromRevision value",
+ (changeSet.fromRevision() == revision - 4));
+ assertTrue("Changes does not include correct toRevision value",
+ (changeSet.toRevision() == revision - 2));
+
+ changeSet = revisionManager.getChanges(store, revision - 2, 3);
+ itemCount = 0;
+ changedItems = changeSet.iterator();
+ while (changedItems.hasNext()) {
+ changedItems.next();
+ itemCount++;
+ }
+ assertTrue("Wrong number of changed items", (itemCount == 2));
+ for (int i = 0; i < 2; i++) {
+ changedItems = changeSet.iterator();
+ itemCount = 0;
+ while (changedItems.hasNext()) {
+ String changedItem = changedItems.next();
+ if (changedItem.equals(contentItemID + (i + 3))) break;
+ itemCount++;
+ }
+ assertTrue("Changes does not include correct URIs", itemCount < 2);
+ }
+
+ assertTrue("Changes does not include correct fromRevision value",
+ (changeSet.fromRevision() == revision - 1));
+ assertTrue("Changes does not include correct toRevision value",
+ (changeSet.toRevision() == revision));
+ } finally {
+ // clear test changes
+ String query = String.format(
+ "DELETE FROM %s WHERE id = ? OR id = ? OR id = ? OR id = ? OR id = ?",
+ revisionManager.getStoreID(store));
+ try {
+ ps = con.prepareStatement(query);
+ for (int i = 0; i < insertCount; i++) {
+ ps.setString(i + 1, contentItemID + i);
+ }
+ int result = ps.executeUpdate();
+ if (result != 5) {
+ log.warn(
+ "Wrong number of updated records while removing the test record. Updated record number: {}",
+ result);
+ }
+ } catch (SQLException e) {
+ log.warn("Failed to remove the test record", e);
+ } finally {
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+ }
+
+ @Test
+ public void batchSizeDoesNotFitToRevisionTest() throws StoreException, SQLException {
+ log.warn("DO NOT UPDATE THE STORE: {} DURING EXECUTION OF THIS TEST", store.getName());
+ Connection con = dbManager.getConnection();
+ String contentItemID = "contenthub_test_content_item_id";
+ PreparedStatement ps = null;
+ int insertCount = 0;
+ try {
+ // do the update
+ String query = "INSERT INTO " + revisionManager.getStoreID(store)
+ + " (id, revision) VALUES (?,?)";
+ long revision = System.currentTimeMillis();
+ for (int i = 0; i < 2; i++) {
+ ps = con.prepareStatement(query);
+ ps.setString(1, contentItemID + i);
+ ps.setLong(2, revision + 1);
+ ps.executeUpdate();
+ ps.clearParameters();
+ insertCount++;
+ }
+
+ // get changes
+ ChangeSet<?> changeSet = revisionManager.getChanges(store, revision, 1);
+ int itemCount = 0;
+ Iterator<String> changedItems = changeSet.iterator();
+ while (changedItems.hasNext()) {
+ changedItems.next();
+ itemCount++;
+ }
+ assertTrue("Wrong number of changed items", (itemCount == 2));
+ for (int i = 0; i < 2; i++) {
+ changedItems = changeSet.iterator();
+ itemCount = 0;
+ while (changedItems.hasNext()) {
+ String changedItem = changedItems.next();
+ if (changedItem.equals(contentItemID + i)) break;
+ itemCount++;
+ }
+ assertTrue("Changes does not include correct URIs", itemCount < 2);
+ }
+ } finally {
+ // clear test changes
+ String query = String.format("DELETE FROM %s WHERE id = ? OR id = ?",
+ revisionManager.getStoreID(store));
+ try {
+ ps = con.prepareStatement(query);
+ for (int i = 0; i < insertCount; i++) {
+ ps.setString(i + 1, contentItemID + i);
+ }
+ int result = ps.executeUpdate();
+ if (result != 2) {
+ log.warn(
+ "Wrong number of updated records while removing the test record. Updated record number: {}",
+ result);
+ }
+ } catch (SQLException e) {
+ log.warn("Failed to remove the test record", e);
+ } finally {
+ dbManager.closeStatement(ps);
+ dbManager.closeConnection(con);
+ }
+ }
+ }
+
+ @Test
+ public void emptyChangesTest() throws StoreException {
+ long revision = System.currentTimeMillis();
+ ChangeSet<?> changeSet = revisionManager.getChanges(store, revision, 1);
+ assertTrue("There must be no changes", !changeSet.iterator().hasNext());
+ }
+}
Added: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/StoreDBManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/StoreDBManagerTest.java?rev=1367053&view=auto
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/StoreDBManagerTest.java (added)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/revisionmanager/StoreDBManagerTest.java Mon Jul 30 10:32:33 2012
@@ -0,0 +1,75 @@
+/*
+ * 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.stanbol.contenthub.test.revisionmanager;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.apache.sling.junit.annotations.SlingAnnotationsTestRunner;
+import org.apache.sling.junit.annotations.TestReference;
+import org.apache.stanbol.commons.semanticindex.store.Store;
+import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.apache.stanbol.contenthub.revisionmanager.RevisionManager;
+import org.apache.stanbol.contenthub.revisionmanager.StoreDBManager;
+import org.apache.stanbol.enhancer.servicesapi.ContentItem;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(SlingAnnotationsTestRunner.class)
+public class StoreDBManagerTest {
+ private static final Logger log = LoggerFactory.getLogger(StoreDBManagerTest.class);
+
+ @TestReference
+ private StoreDBManager dbManager;
+
+ @TestReference
+ private RevisionManager revisionManager;
+
+ @TestReference
+ private Store<ContentItem> store;
+
+ @Test
+ public void dbManagerTest() {
+ assertNotNull("Expecting FileStoreDBManager to be injected by Sling test runner", dbManager);
+ }
+
+ @Test
+ public void testConnection() throws StoreException {
+ Connection connection = dbManager.getConnection();
+ assertTrue("Null connection", connection != null);
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ log.warn("Failed to close test connection");
+ }
+ }
+ }
+
+ @Test
+ public void testTables() throws StoreException {
+ assertTrue("recently_enhanced_content_items does not exist",
+ dbManager.existsTable("recently_enhanced_content_items"));
+ assertTrue(String.format("%s does not exist", revisionManager.getStoreID(store)),
+ dbManager.existsTable(revisionManager.getStoreID(store)));
+ }
+}
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartDeserializerTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartDeserializerTest.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartDeserializerTest.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartDeserializerTest.java Mon Jul 30 10:32:33 2012
@@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory;
@RunWith(SlingAnnotationsTestRunner.class)
public class ContentPartDeserializerTest {
- private static final Logger log = LoggerFactory.getLogger(FileStoreDBManagerTest.class);
+ private static final Logger log = LoggerFactory.getLogger(ContentPartDeserializerTest.class);
@TestReference
ContentPartDeserializer contentPartDeserializer;
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartSerializerTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartSerializerTest.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartSerializerTest.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/ContentPartSerializerTest.java Mon Jul 30 10:32:33 2012
@@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory;
@RunWith(SlingAnnotationsTestRunner.class)
public class ContentPartSerializerTest {
- private static final Logger log = LoggerFactory.getLogger(FileStoreDBManagerTest.class);
+ private static final Logger log = LoggerFactory.getLogger(ContentPartSerializerTest.class);
@TestReference
ContentPartSerializer contentPartSerializer;
Modified: incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreTest.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreTest.java?rev=1367053&r1=1367052&r2=1367053&view=diff
==============================================================================
--- incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreTest.java (original)
+++ incubator/stanbol/branches/contenthub-two-layered-structure/contenthub/test/src/main/java/org/apache/stanbol/contenthub/test/store/file/FileStoreTest.java Mon Jul 30 10:32:33 2012
@@ -36,8 +36,9 @@ import org.apache.sling.junit.annotation
import org.apache.stanbol.commons.indexedgraph.IndexedMGraph;
import org.apache.stanbol.commons.semanticindex.store.Store;
import org.apache.stanbol.commons.semanticindex.store.StoreException;
+import org.apache.stanbol.contenthub.revisionmanager.RevisionManager;
+import org.apache.stanbol.contenthub.revisionmanager.StoreDBManager;
import org.apache.stanbol.contenthub.store.file.FileStore;
-import org.apache.stanbol.contenthub.store.file.FileStoreDBManager;
import org.apache.stanbol.enhancer.servicesapi.Blob;
import org.apache.stanbol.enhancer.servicesapi.ContentItem;
import org.apache.stanbol.enhancer.servicesapi.ContentItemFactory;
@@ -63,7 +64,10 @@ public class FileStoreTest {
private ContentItemFactory contentItemFactory;
@TestReference
- private FileStoreDBManager dbManager;
+ private StoreDBManager dbManager;
+
+ @TestReference
+ private RevisionManager revisionManager;
@Test
public void fileStoreTest() {
@@ -171,7 +175,8 @@ public class FileStoreTest {
f.delete();
// delete the database records
- String query = "DELETE FROM content_item_revisions WHERE id = ?";
+ String query = String.format("DELETE FROM %s WHERE id = ?",
+ revisionManager.getStoreID(store));
Connection connection = dbManager.getConnection();
PreparedStatement ps = null;
try {