### Eclipse Workspace Patch 1.0 #P jackrabbit-core Index: src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (revision 1241895) +++ src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (working copy) @@ -20,6 +20,7 @@ import org.apache.jackrabbit.core.cluster.ClusterNode; import org.apache.jackrabbit.core.data.DataStore; import org.apache.jackrabbit.core.data.DataStoreFactory; +import org.apache.jackrabbit.core.data.MultiDataStore; import org.apache.jackrabbit.core.fs.FileSystem; import org.apache.jackrabbit.core.fs.FileSystemException; import org.apache.jackrabbit.core.fs.FileSystemFactory; @@ -966,6 +967,23 @@ * ... * </DataStore> * + * Its also possible to configure a multi data store. The configuration uses following format: + *
+     *   <DataStore class="org.apache.jackrabbit.core.data.MultiDataStore">
+     *     <param name="primary" value="org.apache.jackrabbit.core.data.db.XXDataStore">
+     *       <DataStore class="org.apache.jackrabbit.core.data.db.XXDataStore">
+     *         <param name="..." value="...">
+     *         ...
+     *       </DataStore>
+     *     </param>
+     *     <param name="archive" value="org.apache.jackrabbit.core.data.db.XXDataStore">
+     *       <DataStore class="org.apache.jackrabbit.core.data.db.XXDataStore">
+     *         <param name="..." value="...">
+     *         ...
+     *       </DataStore>
+     *     </param>
+     *   </DataStore>
+     * 
*

* DataStore is a {@link #parseBeanConfig(Element,String) bean configuration} * element. @@ -985,9 +1003,24 @@ Node child = children.item(i); if (child.getNodeType() == Node.ELEMENT_NODE && DATA_STORE_ELEMENT.equals(child.getNodeName())) { - BeanConfig bc = - parseBeanConfig(parent, DATA_STORE_ELEMENT); + BeanConfig bc = parseBeanConfig(parent, DATA_STORE_ELEMENT); + bc.setValidate(false); DataStore store = bc.newInstance(DataStore.class); + if (store instanceof MultiDataStore) { + String msg = "A MultiDataStore must have configured a primary and archive datastore"; + Node paramNode = child.getChildNodes().item(1); + if (paramNode == null) { + throw new ConfigurationException(msg); + } + DataStore subStore = getDataStoreFactory((Element) paramNode, directory).getDataStore(); + ((MultiDataStore) store).setPrimaryDataStore(subStore); + paramNode = child.getChildNodes().item(3); + if (paramNode == null) { + throw new ConfigurationException(msg); + } + subStore = getDataStoreFactory((Element) paramNode, directory).getDataStore(); + ((MultiDataStore) store).setArchiveDataStore(subStore); + } store.init(directory); return store; } Index: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd =================================================================== --- src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd (revision 0) +++ src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd (working copy) @@ -0,0 +1,64 @@ + + + +%repository-elements; + + + Index: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd =================================================================== --- src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd (revision 0) +++ src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd (working copy) Property changes on: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6.dtd ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd =================================================================== --- src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd (revision 0) +++ src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd (working copy) @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd =================================================================== --- src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd (revision 0) +++ src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd (working copy) Property changes on: src/main/resources/org/apache/jackrabbit/core/config/repository-2.6-elements.dtd ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java (revision 0) +++ src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java (working copy) @@ -0,0 +1,198 @@ +/* + * 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.jackrabbit.core.data; + +import java.io.InputStream; +import java.util.Iterator; + +import javax.jcr.RepositoryException; + +/** + * A MultiDataStore can handle to independent DataStores. Attention: You will + * lost the global single instance mechanism ! It can be used if you have two + * storage systems. One for fast access and a other one like a archive DataStore + * on a slower storage system. All Files will be added to the primary DataStore. + * On read operations first the primary dataStore will be used and if no Record + * is found the archive DataStore will be used. To split up the data between the + * two DataStores use the MultiDataStoreJanitor. The GarabageCollector will only + * remove files from the archive DataStore. + * Configuration: + * + *

+ * <DataStore class="org.apache.jackrabbit.core.data.MultiDataStore">
+ *     <param name="{@link #setPath(String) path}" value="/data/datastore"/>
+ *     <param name="{@link #setMinRecordLength(int) minRecordLength}" value="1024"/>
+ * </DataStore>
+ * 
+ */ +public class MultiDataStore implements DataStore { + + private DataStore primaryDataStore; + private DataStore archiveDataStore; + + /** + * Setter for the primary dataStore + * + * @param dataStore + */ + public void setPrimaryDataStore(DataStore dataStore) { + this.primaryDataStore = dataStore; + } + + /** + * Setter for the archive dataStore + * + * @param dataStore + */ + public void setArchiveDataStore(DataStore dataStore) { + this.archiveDataStore = dataStore; + } + + /** + * Check if a record for the given identifier exists in the primary data store. + * If not found there it will be returned from the archive data store. + * If no record exists, this method returns null. + * + * @param identifier data identifier + * @return the record if found, and null if not + */ + public DataRecord getRecordIfStored(DataIdentifier identifier) + throws DataStoreException { + DataRecord dataRecord = primaryDataStore.getRecordIfStored(identifier); + if (dataRecord == null) { + dataRecord = archiveDataStore.getRecordIfStored(identifier); + } + return dataRecord; + } + + /** + * Returns the identified data record from the primary data store. + * If not found there it will be returned from the archive data store. The given identifier should be + * the identifier of a previously saved data record. Since records are + * never removed, there should never be cases where the identified record + * is not found. Abnormal cases like that are treated as errors and + * handled by throwing an exception. + * + * @param identifier data identifier + * @return identified data record + * @throws DataStoreException if the data store could not be accessed, + * or if the given identifier is invalid + */ + public DataRecord getRecord(DataIdentifier identifier) + throws DataStoreException { + try { + return primaryDataStore.getRecord(identifier); + } catch (DataStoreException e) { + return archiveDataStore.getRecord(identifier); + } + } + + /** + * Creates a new data record in the primary data store. The given binary stream is consumed and + * a binary record containing the consumed stream is created and returned. + * If the same stream already exists in another record, then that record + * is returned instead of creating a new one. + *

+ * The given stream is consumed and not closed by this + * method. It is the responsibility of the caller to close the stream. + * A typical call pattern would be: + *

+     *     InputStream stream = ...;
+     *     try {
+     *         record = store.addRecord(stream);
+     *     } finally {
+     *         stream.close();
+     *     }
+     * 
+ * + * @param stream binary stream + * @return data record that contains the given stream + * @throws DataStoreException if the data store could not be accessed + */ + public DataRecord addRecord(InputStream stream) throws DataStoreException { + return primaryDataStore.addRecord(stream); + } + + /** + * From now on, update the modified date of an object even when accessing it in the archive data store. + * Usually, the modified date is only updated when creating a new object, + * or when a new link is added to an existing object. When this setting is enabled, + * even getLength() will update the modified date. + * + * @param before - update the modified date to the current time if it is older than this value + */ + public void updateModifiedDateOnAccess(long before) { + archiveDataStore.updateModifiedDateOnAccess(before); + } + + /** + * Delete objects that have a modified date older than the specified date from the archive data store. + * + * @param min the minimum time + * @return the number of data records deleted + * @throws DataStoreException + */ + public int deleteAllOlderThan(long min) throws DataStoreException { + return archiveDataStore.deleteAllOlderThan(min); + } + + /** + * Get all identifiers from the archive data store. + * + * @return an iterator over all DataIdentifier objects + * @throws DataStoreException if the list could not be read + */ + public Iterator getAllIdentifiers() + throws DataStoreException { + return archiveDataStore.getAllIdentifiers(); + } + + public void init(String homeDir) throws RepositoryException { + } + + /** + * Get the minimum size of an object that should be stored in the primary data store. + * + * @return the minimum size in bytes + */ + public int getMinRecordLength() { + return primaryDataStore.getMinRecordLength(); + } + + public void close() throws DataStoreException { + DataStoreException lastException = null; + try { + primaryDataStore.close(); + } catch (DataStoreException e) { + lastException = e; + } + try { + archiveDataStore.close(); + } catch (DataStoreException e) { + if (lastException != null) { + lastException = new DataStoreException(lastException); + } + } + if (lastException != null) { + throw lastException; + } + } + + public void clearInUse() { + archiveDataStore.clearInUse(); + } +} Index: src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java (revision 0) +++ src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java (working copy) Property changes on: src/main/java/org/apache/jackrabbit/core/data/MultiDataStore.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property