Author: tripod Date: Tue Jan 25 08:34:30 2005 New Revision: 126386 URL: http://svn.apache.org/viewcvs?view=rev&rev=126386 Log: - adding versioning configuratuin - adapting versioning to new persistence manager api Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/VersioningConfig.java (contents, props changed) incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativeItemStateManager.java (contents, props changed) Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java Tue Jan 25 08:34:30 2005 @@ -21,6 +21,7 @@ import org.apache.jackrabbit.core.config.PersistenceManagerConfig; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.config.WorkspaceConfig; +import org.apache.jackrabbit.core.config.VersioningConfig; import org.apache.jackrabbit.core.fs.BasedFileSystem; import org.apache.jackrabbit.core.fs.FileSystem; import org.apache.jackrabbit.core.fs.FileSystemException; @@ -93,12 +94,12 @@ // configuration of the repository private final RepositoryConfig repConfig; + // the master filesystem private final FileSystem repStore; + // sub file system where the repository stores meta data such as uuid of root node, etc. private final FileSystem metaDataStore; - // sub file system where the repository stores versions - private final FileSystem versionStore; /** * map of workspace names and WorkspaceInfos. @@ -140,18 +141,6 @@ } metaDataStore = new BasedFileSystem(repStore, fsRootPath); - fsRootPath = "/versions"; - try { - if (!repStore.exists(fsRootPath) || !repStore.isFolder(fsRootPath)) { - repStore.createFolder(fsRootPath); - } - } catch (FileSystemException fse) { - String msg = "failed to create folder for repository version store"; - log.error(msg, fse); - throw new RepositoryException(msg, fse); - } - versionStore = new BasedFileSystem(repStore, fsRootPath); - FileSystemResource uuidFile = new FileSystemResource(metaDataStore, "rootUUID"); try { if (uuidFile.exists()) { @@ -267,9 +256,15 @@ } // init version manager - // todo: as soon as dynamic workspaces are available, base on system ws - SessionImpl verSession = getSystemSession(repConfig.getDefaultWorkspaceName()); - pvMgr = new NativePVM(verSession); + VersioningConfig vConfig = repConfig.getVersioningConfig(); + PersistenceManager pm = createPersistenceManager( + vConfig.getHomeDir(), + vConfig.getFileSystem(), + vConfig.getPersistenceManagerConfig(), + rootNodeUUID, + nsReg, + ntReg); + pvMgr = new NativePVM(pm, getNodeTypeRegistry()); vMgr = new VersionManagerImpl(pvMgr); // finally register shutdown hook @@ -622,6 +617,45 @@ return ((NodeImpl) session.getRootNode()).getNode(SYSTEM_ROOT_NAME); } + /** + * Returns the workspace persistence manager + * + * @return the workspace persistence manager + * @throws RepositoryException if the persistence manager could not be instantiated/initialized + */ + public static PersistenceManager createPersistenceManager(File homeDir, + FileSystem fs, + PersistenceManagerConfig pmConfig, + String rootNodeUUID, + NamespaceRegistry nsReg, + NodeTypeRegistry ntReg) + throws RepositoryException { + String className = pmConfig.getClassName(); + Map params = pmConfig.getParameters(); + try { + Class c = Class.forName(className); + PersistenceManager persistMgr = (PersistenceManager) c.newInstance(); + /** + * set the properties of the persistence manager object + * from the param map + */ + BeanMap bm = new BeanMap(persistMgr); + Iterator iter = params.keySet().iterator(); + while (iter.hasNext()) { + Object name = iter.next(); + Object value = params.get(name); + bm.put(name, value); + } + PMContext ctx = new PMContext(homeDir, fs, rootNodeUUID, nsReg, ntReg); + persistMgr.init(ctx); + return persistMgr; + } catch (Exception e) { + log.error("Cannot instantiate implementing class " + className, e); + throw new RepositoryException("Cannot instantiate implementing class " + className, e); + } + } + + //-----------------------------------------------------------< Repository > /** * @see Repository#login(Credentials, String) @@ -792,32 +826,16 @@ * @return the workspace persistence manager * @throws RepositoryException if the persistence manager could not be instantiated/initialized */ - synchronized PersistenceManager getPersistenceManager() throws RepositoryException { + synchronized PersistenceManager getPersistenceManager(PersistenceManagerConfig pmConfig) + throws RepositoryException { if (persistMgr == null) { - PersistenceManagerConfig pmConfig = config.getPersistenceManagerConfig(); - String className = pmConfig.getClassName(); - Map params = pmConfig.getParameters(); - try { - Class c = Class.forName(className); - persistMgr = (PersistenceManager) c.newInstance(); - /** - * set the properties of the persistence manager object - * from the param map - */ - BeanMap bm = new BeanMap(persistMgr); - Iterator iter = params.keySet().iterator(); - while (iter.hasNext()) { - Object name = iter.next(); - Object value = params.get(name); - bm.put(name, value); - } - PMContext ctx = new PMContext(config, rootNodeUUID, nsReg, ntReg); - persistMgr.init(ctx); - } catch (Exception e) { - persistMgr = null; - log.error("Cannot instantiate implementing class " + className, e); - throw new RepositoryException("Cannot instantiate implementing class " + className, e); - } + persistMgr = RepositoryImpl.createPersistenceManager( + new File(config.getHomeDir()), + config.getFileSystem(), + pmConfig, + rootNodeUUID, + nsReg, + ntReg); } return persistMgr; } @@ -846,7 +864,7 @@ if (itemStateMgr == null) { // create item state manager try { - itemStateMgr = new SharedItemStateManager(getPersistenceManager(), rootNodeUUID, ntReg); + itemStateMgr = new SharedItemStateManager(getPersistenceManager(config.getPersistenceManagerConfig()), rootNodeUUID, ntReg); } catch (ItemStateException ise) { String msg = "failed to instantiate persistent item state manager"; log.error(msg, ise); Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java Tue Jan 25 08:34:30 2005 @@ -55,6 +55,8 @@ private static final String WORKSPACE_ELEMENT = "Workspace"; + private static final String VERSIONING_ELEMENT = "Versioning"; + /** * wellknown variables (will be replaced with their respective values * whereever they occur within the configuration) @@ -94,6 +96,11 @@ private String defaultWspName; /** + * the versioning config + */ + private VersioningConfig vConfig; + + /** * private constructor. * * @param is @@ -164,6 +171,10 @@ throw new RepositoryException(msg); } } + + // load versioning config + Element vElement = config.getRootElement().getChild(VERSIONING_ELEMENT); + vConfig = new VersioningConfig(vElement, vars); } /** @@ -257,6 +268,14 @@ */ public WorkspaceConfig getWorkspaceConfig(String name) { return (WorkspaceConfig) wspConfigs.get(name); + } + + /** + * Returns the configuration for the versioning + * @return + */ + public VersioningConfig getVersioningConfig() { + return vConfig; } /** Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/VersioningConfig.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/VersioningConfig.java?view=auto&rev=126386 ============================================================================== --- (empty file) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/VersioningConfig.java Tue Jan 25 08:34:30 2005 @@ -0,0 +1,104 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.config; + +import org.apache.jackrabbit.core.fs.FileSystem; +import org.jdom.Element; + +import javax.jcr.RepositoryException; +import java.util.*; +import java.io.File; + +/** + * This Class implements the configuration object for the versioning. + * + * @author tripod + * @version $Revision:$, $Date:$ + */ +public class VersioningConfig { + + /** attribute name of home dir */ + private static final String ROOTPATH_ATTRIB = "rootPath"; + + /** the homedir for the versioning */ + private final File homeDir; + + /** The FileSystem for the versioing. */ + private final FileSystem fs; + + /** Parameters for configuring the versioning */ + private Map params = new HashMap(); + + /** The PersistenceManagerConfig for the versioning */ + private final PersistenceManagerConfig pmConfig; + + /** + * Creates a new VersioningConfig. + * @param config the config root element for this VersioningConfig. + * @param vars map of variable values. + * @throws RepositoryException if an error occurs while creating the + * SearchConfig. + */ + VersioningConfig(Element config, Map vars) throws RepositoryException { + + // home dir + homeDir = new File(AbstractConfig.replaceVars(config.getAttributeValue(ROOTPATH_ATTRIB), vars)); + + // create FileSystem + Element fsElement = config.getChild(AbstractConfig.FILE_SYSTEM_ELEMENT); + this.fs = AbstractConfig.createFileSystem(fsElement, vars); + + // persistence manager config + Element pmElem = config.getChild(WorkspaceConfig.PERSISTENCE_MANAGER_ELEMENT); + pmConfig = new PersistenceManagerConfig(pmElem, vars); + + // gather params + List paramList = config.getChildren(AbstractConfig.PARAM_ELEMENT); + for (Iterator i = paramList.iterator(); i.hasNext();) { + Element param = (Element) i.next(); + String paramName = param.getAttributeValue(AbstractConfig.NAME_ATTRIB); + String paramValue = param.getAttributeValue(AbstractConfig.VALUE_ATTRIB); + // replace variables in param value + params.put(paramName, AbstractConfig.replaceVars(paramValue, vars)); + } + // seal + params = Collections.unmodifiableMap(params); + } + + /** + * Returns the virtual file system where the workspace stores global state. + * + * @return the virtual file system where the workspace stores global state + */ + public FileSystem getFileSystem() { + return fs; + } + + /** + * Returns the configuration of the persistence manager. + * + * @return the PersistenceManagerConfig for this workspace + */ + public PersistenceManagerConfig getPersistenceManagerConfig() { + return pmConfig; + } + + public File getHomeDir() { + return homeDir; + } + +} Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java Tue Jan 25 08:34:30 2005 @@ -45,7 +45,7 @@ */ public static final String PUBLIC_ID = "-//The Apache Software Foundation//DTD Workspace//EN"; - private static final String PERSISTENCE_MANAGER_ELEMENT = "PersistenceManager"; + static final String PERSISTENCE_MANAGER_ELEMENT = "PersistenceManager"; private static final String SEARCH_INDEX_ELEMENT = "SearchIndex"; /** Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/config.dtd Tue Jan 25 08:34:30 2005 @@ -37,7 +37,7 @@ no workspace yet and for creating additional workspaces through the api --> - + + + + + Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/fs/local/LocalFileSystem.java Tue Jan 25 08:34:30 2005 @@ -47,6 +47,10 @@ rootPath = osPath(path); } + public void setPath(File path) { + rootPath = path.getAbsolutePath(); + } + private String osPath(String genericPath) { if (File.separator.equals(SEPARATOR)) { return genericPath; Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/jndi/BindableRepository.java Tue Jan 25 08:34:30 2005 @@ -24,10 +24,7 @@ import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; +import java.io.*; import java.util.Properties; /** Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/PMContext.java Tue Jan 25 08:34:30 2005 @@ -16,10 +16,11 @@ */ package org.apache.jackrabbit.core.state; -import org.apache.jackrabbit.core.config.WorkspaceConfig; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.core.fs.FileSystem; import javax.jcr.NamespaceRegistry; +import java.io.File; /** * A PMContext is used to provide context information for a @@ -30,9 +31,14 @@ public class PMContext { /** - * workspace configuration + * the physcial home dir */ - private final WorkspaceConfig wspConfig; + private final File physicalHomeDir; + + /** + * the virtual jackrabbit filesystem + */ + private final FileSystem fs; /** * namespace registry @@ -52,28 +58,39 @@ /** * Creates a new PMContext. * - * @param wspConfig configuration of workspace + * @param homeDir the physical home directory + * @param fs the virtual jackrabbit filesystem * @param rootNodeUUID uuid of the root node * @param nsReg namespace registry * @param ntReg node type registry */ - public PMContext(WorkspaceConfig wspConfig, + public PMContext(File homeDir, + FileSystem fs, String rootNodeUUID, NamespaceRegistry nsReg, NodeTypeRegistry ntReg) { - this.wspConfig = wspConfig; + this.physicalHomeDir = homeDir; + this.fs = fs; this.rootNodeUUID = rootNodeUUID; this.nsReg = nsReg; this.ntReg = ntReg; } + /** - * Returns the workspace configuration - * - * @return the workspace configuration + * Returns the physical home directory for this persistence manager + * @return + */ + public File getHomeDir() { + return physicalHomeDir; + } + + /** + * Returns the virtual filesystem for this persistence manager + * @return */ - public WorkspaceConfig getWorkspaceConfig() { - return wspConfig; + public FileSystem getFileSystem() { + return fs; } /** Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/mem/InMemPersistenceManager.java Tue Jan 25 08:34:30 2005 @@ -317,14 +317,14 @@ stateStore = new HashMap(initialCapacity, loadFactor); refsStore = new HashMap(initialCapacity, loadFactor); - wspFS = context.getWorkspaceConfig().getFileSystem(); + wspFS = context.getFileSystem(); /** * store blob's in local file system in a sub directory * of the workspace home directory */ LocalFileSystem blobFS = new LocalFileSystem(); - blobFS.setPath(context.getWorkspaceConfig().getHomeDir() + "/blobs"); + blobFS.setPath(new File(context.getHomeDir(), "blobs")); blobFS.init(); this.blobFS = blobFS; Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/obj/ObjectPersistenceManager.java Tue Jan 25 08:34:30 2005 @@ -426,7 +426,7 @@ throw new IllegalStateException("already initialized"); } - FileSystem wspFS = context.getWorkspaceConfig().getFileSystem(); + FileSystem wspFS = context.getFileSystem(); itemStateFS = new BasedFileSystem(wspFS, "/data"); /** @@ -434,7 +434,7 @@ * of the workspace home directory */ LocalFileSystem blobFS = new LocalFileSystem(); - blobFS.setPath(context.getWorkspaceConfig().getHomeDir() + "/blobs"); + blobFS.setPath(new File(context.getHomeDir(), "blobs")); blobFS.init(); this.blobFS = blobFS; Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/xml/XMLPersistenceManager.java Tue Jan 25 08:34:30 2005 @@ -342,19 +342,11 @@ * @see PersistenceManager#init */ public void init(PMContext context) throws Exception { - init(context.getWorkspaceConfig().getFileSystem(), - context.getWorkspaceConfig().getHomeDir()); - } - - /** - * @see PersistenceManager#init - */ - public void init(FileSystem wspFS, String homeDir) throws Exception { if (initialized) { throw new IllegalStateException("already initialized"); } - itemStateStore = new BasedFileSystem(wspFS, "/data"); + itemStateStore = new BasedFileSystem(context.getFileSystem(), "/data"); //blobStore = new BasedFileSystem(wspFS, "/blobs"); /** @@ -363,7 +355,7 @@ * todo make blob store configurable */ LocalFileSystem blobFS = new LocalFileSystem(); - blobFS.setPath(homeDir + "/blobs"); + blobFS.setPath(new File(context.getHomeDir(), "blobs")); blobFS.init(); blobStore = blobFS; Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java Tue Jan 25 08:34:30 2005 @@ -17,9 +17,11 @@ package org.apache.jackrabbit.core.version; import org.apache.jackrabbit.core.NodeImpl; +import org.apache.jackrabbit.core.QName; import javax.jcr.Node; import javax.jcr.RepositoryException; +import javax.jcr.version.VersionException; import java.util.Iterator; /** @@ -139,4 +141,30 @@ */ public InternalVersion checkin(NodeImpl node) throws RepositoryException; + /** + * + * @param history + * @param versionName + * @throws VersionException + */ + public void removeVersion(InternalVersionHistory history, QName versionName) throws VersionException; + + + /** + * + * @param versionName + * @param label + * @param move + * @return + * @throws VersionException + */ + public InternalVersion addVersionLabel(InternalVersionHistory history, QName versionName, String label, boolean move) throws VersionException; + + /** + * + * @param label + * @return + * @throws VersionException + */ + public InternalVersion removeVersionLabel(InternalVersionHistory history, String label) throws VersionException; } Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalFrozenNodeImpl.java Tue Jan 25 08:34:30 2005 @@ -16,24 +16,25 @@ */ package org.apache.jackrabbit.core.version.persistence; +import org.apache.jackrabbit.core.version.*; import org.apache.jackrabbit.core.*; -import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; -import org.apache.jackrabbit.core.state.ItemStateException; +import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.PropertyState; -import org.apache.jackrabbit.core.version.*; +import org.apache.jackrabbit.core.state.ItemStateException; +import org.apache.jackrabbit.core.state.UpdateOperation; -import javax.jcr.NodeIterator; -import javax.jcr.PropertyIterator; -import javax.jcr.PropertyType; import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeType; +import javax.jcr.PropertyType; +import javax.jcr.PropertyIterator; +import javax.jcr.NodeIterator; import javax.jcr.version.OnParentVersionAction; import javax.jcr.version.VersionException; +import javax.jcr.nodetype.NodeType; +import java.util.List; import java.util.ArrayList; import java.util.Iterator; -import java.util.List; /** * @@ -77,9 +78,9 @@ * @throws javax.jcr.RepositoryException */ protected InternalFrozenNodeImpl(PersistentVersionManager vMgr, - PersistentNode node, - String id, - InternalVersionItem parent) throws RepositoryException { + PersistentNode node, + String id, + InternalVersionItem parent) throws RepositoryException { super(vMgr, parent); this.node = node; this.id = id; @@ -173,7 +174,7 @@ List entries = node.getState().getChildNodeEntries(); InternalFreeze[] freezes = new InternalFreeze[entries.size()]; Iterator iter = entries.iterator(); - int i = 0; + int i=0; while (iter.hasNext()) { NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next(); freezes[i++] = (InternalFreeze) getVersionManager().getItemByInternal(entry.getUUID()); @@ -233,20 +234,23 @@ * @return * @throws RepositoryException */ - protected static PersistentNode checkin(PersistentNode parent, QName name, NodeImpl src, boolean initOnly, boolean forceCopy) + protected static PersistentNode checkin(UpdateOperation upd, + PersistentNode parent, QName name, + NodeImpl src, boolean initOnly, + boolean forceCopy) throws RepositoryException { PersistentNode node; // create new node - node = parent.addNode(name, NativePVM.NT_REP_FROZEN); + node = parent.addNode(upd, name, NativePVM.NT_REP_FROZEN); // initialize the internal properties if (src.isNodeType(NodeTypeRegistry.MIX_REFERENCEABLE)) { - node.setPropertyValue(VersionManager.PROPNAME_FROZEN_UUID, InternalValue.create(src.getUUID())); + node.setPropertyValue(upd, VersionManager.PROPNAME_FROZEN_UUID, InternalValue.create(src.getUUID())); } - node.setPropertyValue(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE, + node.setPropertyValue(upd, VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE, InternalValue.create(((NodeTypeImpl) src.getPrimaryNodeType()).getQName())); if (src.hasProperty(NodeImpl.PROPNAME_MIXINTYPES)) { @@ -255,7 +259,7 @@ for (int i = 0; i < mixins.length; i++) { ivalues[i] = InternalValue.create(((NodeTypeImpl) mixins[i]).getQName()); } - node.setPropertyValues(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, PropertyType.NAME, ivalues); + node.setPropertyValues(upd, VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, PropertyType.NAME, ivalues); } if (!initOnly) { @@ -274,7 +278,7 @@ break; case OnParentVersionAction.VERSION: case OnParentVersionAction.COPY: - node.copyFrom(prop); + node.copyFrom(upd, prop); break; } } @@ -295,16 +299,16 @@ case OnParentVersionAction.VERSION: if (child.isNodeType(NodeTypeRegistry.MIX_VERSIONABLE)) { // create frozen versionable child - PersistentNode newChild = node.addNode(child.getQName(), NativePVM.NT_REP_FROZEN_HISTORY); - newChild.setPropertyValue(VersionManager.PROPNAME_VERSION_HISTORY, + PersistentNode newChild = node.addNode(upd, child.getQName(), NativePVM.NT_REP_FROZEN_HISTORY); + newChild.setPropertyValue(upd, VersionManager.PROPNAME_VERSION_HISTORY, InternalValue.create(child.getVersionHistory().getUUID())); - newChild.setPropertyValue(VersionManager.PROPNAME_BASE_VERSION, + newChild.setPropertyValue(upd, VersionManager.PROPNAME_BASE_VERSION, InternalValue.create(child.getBaseVersion().getUUID())); break; } // else copy case OnParentVersionAction.COPY: - checkin(node, child.getQName(), child, false, true); + checkin(upd, node, child.getQName(), child, false, true); break; } } Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionHistoryImpl.java Tue Jan 25 08:34:30 2005 @@ -20,6 +20,7 @@ import org.apache.jackrabbit.core.NamespaceRegistryImpl; import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.QName; +import org.apache.jackrabbit.core.state.UpdateOperation; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.util.Text; import org.apache.jackrabbit.core.util.uuid.UUID; @@ -228,31 +229,49 @@ * @throws VersionException */ public void removeVersion(QName versionName) throws VersionException { - InternalVersionImpl v = (InternalVersionImpl) getVersion(versionName); - if (v.equals(rootVersion)) { - String msg = "Removal of " + versionName + " not allowed."; - log.error(msg); - throw new VersionException(msg); - } + getVersionManager().removeVersion(this, versionName); + } + + /** + * Removes the indicated version from this VersionHistory. If the specified + * vesion does not exist, if it specifies the root version or if it is + * referenced by any node e.g. as base version, a VersionException is thrown. + *

+ * all successors of the removed version become successors of the + * predecessors of the removed version and vice versa. then, the entire + * version node and all its subnodes are removed. + * + * @param versionName + * @throws VersionException + */ + protected void removeVersion(UpdateOperation upd, QName versionName) throws VersionException { try { + InternalVersionImpl v = (InternalVersionImpl) getVersion(versionName); + if (v.equals(rootVersion)) { + String msg = "Removal of " + versionName + " not allowed."; + log.error(msg); + throw new VersionException(msg); + } + // remove from persistance state - node.removeNode(versionName); - node.store(); + node.removeNode(upd, v.getName()); // unregister from labels String[] labels = v.internalGetLabels(); for (int i = 0; i < labels.length; i++) { v.internalRemoveLabel(labels[i]); QName name = new QName("", Text.md5(labels[i])); - labelNode.removeNode(name); + labelNode.removeNode(upd, name); } - // detach from the version graph - v.internalDetach(); + v.internalDetach(upd); // and remove from history versionCache.remove(v.getId()); + + // store changes + node.store(upd); } catch (RepositoryException e) { throw new VersionException("error while storing modifications", e); } @@ -263,6 +282,14 @@ */ public InternalVersion addVersionLabel(QName versionName, String label, boolean move) throws VersionException { + return getVersionManager().addVersionLabel(this, versionName, label, move); + } + + /** + * @see InternalVersionHistory#addVersionLabel(org.apache.jackrabbit.core.QName, String, boolean) + */ + protected InternalVersion addVersionLabel(UpdateOperation upd, QName versionName, String label, boolean move) + throws VersionException { InternalVersion version = getVersion(versionName); if (version == null) { @@ -284,10 +311,10 @@ ((InternalVersionImpl) version).internalAddLabel(label); QName name = new QName("", Text.md5(label)); try { - PersistentNode lNode = labelNode.addNode(name, NodeTypeRegistry.NT_UNSTRUCTURED); - lNode.setPropertyValue(NativePVM.PROPNAME_NAME, InternalValue.create(label)); - lNode.setPropertyValue(NativePVM.PROPNAME_VERSION, InternalValue.create(version.getId())); - labelNode.store(); + PersistentNode lNode = labelNode.addNode(upd, name, NodeTypeRegistry.NT_UNSTRUCTURED); + lNode.setPropertyValue(upd, NativePVM.PROPNAME_NAME, InternalValue.create(label)); + lNode.setPropertyValue(upd, NativePVM.PROPNAME_VERSION, InternalValue.create(version.getId())); + labelNode.store(upd); } catch (RepositoryException e) { throw new VersionException("Error while storing modifications", e); } @@ -298,6 +325,13 @@ * @see InternalVersionHistory#removeVersionLabel(String) */ public InternalVersion removeVersionLabel(String label) throws VersionException { + return getVersionManager().removeVersionLabel(this, label); + } + + /** + * @see InternalVersionHistory#removeVersionLabel(String) + */ + protected InternalVersion removeVersionLabel(UpdateOperation upd, String label) throws VersionException { InternalVersionImpl v = (InternalVersionImpl) labelCache.remove(label); if (v == null) { throw new VersionException("Version label " + label + " is not in version history."); @@ -306,8 +340,8 @@ QName name = new QName("", Text.md5(label)); try { - labelNode.removeNode(name); - labelNode.store(); + labelNode.removeNode(upd, name); + labelNode.store(upd); } catch (RepositoryException e) { throw new VersionException("Unable to store modifications", e); } @@ -324,7 +358,7 @@ * @return * @throws RepositoryException */ - protected InternalVersionImpl checkin(QName name, NodeImpl src) + protected InternalVersionImpl checkin(UpdateOperation upd, QName name, NodeImpl src) throws RepositoryException { // copy predecessors from src node @@ -341,19 +375,19 @@ String versionId = UUID.randomUUID().toString(); QName nodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, versionId); - PersistentNode vNode = node.addNode(nodeName, NativePVM.NT_REP_VERSION); - vNode.setPropertyValue(NativePVM.PROPNAME_VERSION_ID, InternalValue.create(versionId)); - vNode.setPropertyValue(NativePVM.PROPNAME_VERSION_NAME, InternalValue.create(name)); + PersistentNode vNode = node.addNode(upd, nodeName, NativePVM.NT_REP_VERSION); + vNode.setPropertyValue(upd, NativePVM.PROPNAME_VERSION_ID, InternalValue.create(versionId)); + vNode.setPropertyValue(upd, NativePVM.PROPNAME_VERSION_NAME, InternalValue.create(name)); // initialize 'created' and 'predecessors' - vNode.setPropertyValue(VersionManager.PROPNAME_CREATED, InternalValue.create(Calendar.getInstance())); - vNode.setPropertyValues(VersionManager.PROPNAME_PREDECESSORS, PropertyType.STRING, predecessors); + vNode.setPropertyValue(upd, VersionManager.PROPNAME_CREATED, InternalValue.create(Calendar.getInstance())); + vNode.setPropertyValues(upd, VersionManager.PROPNAME_PREDECESSORS, PropertyType.STRING, predecessors); // checkin source node - InternalFrozenNodeImpl.checkin(vNode, VersionManager.NODENAME_FROZEN, src, false, false); + InternalFrozenNodeImpl.checkin(upd, vNode, VersionManager.NODENAME_FROZEN, src, false, false); // and store - node.store(); + node.store(upd); // update version graph InternalVersionImpl version = new InternalVersionImpl(this, vNode); @@ -400,32 +434,32 @@ * @return * @throws RepositoryException */ - protected static InternalVersionHistoryImpl create(PersistentVersionManager vMgr, PersistentNode parent, String historyId, QName name, NodeImpl src) + protected static InternalVersionHistoryImpl create(UpdateOperation upd, PersistentVersionManager vMgr, PersistentNode parent, String historyId, QName name, NodeImpl src) throws RepositoryException { // create history node - PersistentNode pNode = parent.addNode(name, NativePVM.NT_REP_VERSION_HISTORY); - pNode.setPropertyValue(NativePVM.PROPNAME_HISTORY_ID, InternalValue.create(historyId)); + PersistentNode pNode = parent.addNode(upd, name, NativePVM.NT_REP_VERSION_HISTORY); + pNode.setPropertyValue(upd, NativePVM.PROPNAME_HISTORY_ID, InternalValue.create(historyId)); // create label node - pNode.addNode(NativePVM.NODENAME_VERSION_LABELS, NodeTypeRegistry.NT_UNSTRUCTURED); + pNode.addNode(upd, NativePVM.NODENAME_VERSION_LABELS, NodeTypeRegistry.NT_UNSTRUCTURED); // create root version String versionId = UUID.randomUUID().toString(); QName nodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, versionId); - PersistentNode vNode = pNode.addNode(nodeName, NativePVM.NT_REP_VERSION); - vNode.setPropertyValue(NativePVM.PROPNAME_VERSION_ID, InternalValue.create(versionId)); - vNode.setPropertyValue(NativePVM.PROPNAME_VERSION_NAME, InternalValue.create(VersionManager.NODENAME_ROOTVERSION)); + PersistentNode vNode = pNode.addNode(upd, nodeName, NativePVM.NT_REP_VERSION); + vNode.setPropertyValue(upd, NativePVM.PROPNAME_VERSION_ID, InternalValue.create(versionId)); + vNode.setPropertyValue(upd, NativePVM.PROPNAME_VERSION_NAME, InternalValue.create(VersionManager.NODENAME_ROOTVERSION)); // initialize 'created' and 'predecessors' - vNode.setPropertyValue(VersionManager.PROPNAME_CREATED, InternalValue.create(Calendar.getInstance())); - vNode.setPropertyValues(VersionManager.PROPNAME_PREDECESSORS, PropertyType.REFERENCE, new InternalValue[0]); + vNode.setPropertyValue(upd, VersionManager.PROPNAME_CREATED, InternalValue.create(Calendar.getInstance())); + vNode.setPropertyValues(upd, VersionManager.PROPNAME_PREDECESSORS, PropertyType.REFERENCE, new InternalValue[0]); // add also an empty frozen node to the root version - InternalFrozenNodeImpl.checkin(vNode, VersionManager.NODENAME_FROZEN, src, true, false); + InternalFrozenNodeImpl.checkin(upd, vNode, VersionManager.NODENAME_FROZEN, src, true, false); - parent.store(); + parent.store(upd); return new InternalVersionHistoryImpl(vMgr, pNode); } } Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/InternalVersionImpl.java Tue Jan 25 08:34:30 2005 @@ -19,6 +19,7 @@ import org.apache.jackrabbit.core.InternalValue; import org.apache.jackrabbit.core.QName; import org.apache.jackrabbit.core.state.NodeState; +import org.apache.jackrabbit.core.state.UpdateOperation; import org.apache.jackrabbit.core.util.uuid.UUID; import org.apache.jackrabbit.core.version.*; @@ -201,12 +202,12 @@ * * @throws RepositoryException */ - private void storePredecessors() throws RepositoryException { + private void storePredecessors(UpdateOperation upd) throws RepositoryException { InternalValue[] values = new InternalValue[predecessors.size()]; for (int i = 0; i < values.length; i++) { values[i] = InternalValue.create(new UUID(((InternalVersion) predecessors.get(i)).getId())); } - node.setPropertyValues(VersionManager.PROPNAME_PREDECESSORS, PropertyType.STRING, values); + node.setPropertyValues(upd, VersionManager.PROPNAME_PREDECESSORS, PropertyType.STRING, values); } /** @@ -214,18 +215,18 @@ * * @throws RepositoryException */ - void internalDetach() throws RepositoryException { + void internalDetach(UpdateOperation upd) throws RepositoryException { // detach this from all successors InternalVersionImpl[] succ = (InternalVersionImpl[]) getSuccessors(); for (int i = 0; i < succ.length; i++) { - succ[i].internalDetachPredecessor(this); + succ[i].internalDetachPredecessor(upd, this); } // clear properties successors.clear(); predecessors.clear(); labelCache = null; - storePredecessors(); + storePredecessors(upd); } /** @@ -236,7 +237,7 @@ * * @param v the successor to detach */ - private void internalDetachPredecessor(InternalVersion v) throws RepositoryException { + private void internalDetachPredecessor(UpdateOperation upd, InternalVersion v) throws RepositoryException { // remove 'v' from predecessor list for (int i = 0; i < predecessors.size(); i++) { if (predecessors.get(i).equals(v)) { @@ -247,7 +248,7 @@ // attach v's successors predecessors.clear(); predecessors.addAll(Arrays.asList(v.getPredecessors())); - storePredecessors(); + storePredecessors(upd); } /** Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativeItemStateManager.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativeItemStateManager.java?view=auto&rev=126386 ============================================================================== --- (empty file) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativeItemStateManager.java Tue Jan 25 08:34:30 2005 @@ -0,0 +1,405 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.version.persistence; + +import org.apache.jackrabbit.core.state.*; +import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.core.nodetype.NodeDefId; +import org.apache.jackrabbit.core.nodetype.PropDefId; +import org.apache.jackrabbit.core.*; +import org.apache.log4j.Logger; +import org.apache.commons.collections.ReferenceMap; + +import javax.jcr.nodetype.NoSuchNodeTypeException; +import javax.jcr.PropertyType; +import java.util.*; +import java.io.PrintStream; + +/** + * This Class implements... + * + * @author tripod + * @version $Revision:$, $Date:$ + */ +public class NativeItemStateManager extends ItemStateCache + implements ItemStateManager, ItemStateListener { + + /** + * Logger instance + */ + private static Logger log = Logger.getLogger(NativeItemStateManager.class); + + /** + * Persistence Manager to use for loading and storing items + */ + protected final PersistenceManager persistMgr; + + /** + * Keep a hard reference to the root node state + */ + private NodeState root; + + /** + * A cache for NodeReferences objects. + */ + private Map refsCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); + + /** + * Creates a new DefaultItemStateManager instance. + * + * @param persistMgr + * @param rootNodeUUID + * @param ntReg + */ + public NativeItemStateManager(PersistenceManager persistMgr, + String rootNodeUUID, + NodeTypeRegistry ntReg) + throws ItemStateException { + + this.persistMgr = persistMgr; + + try { + root = getNodeState(new NodeId(rootNodeUUID)); + } catch (NoSuchItemStateException e) { + // create root node + root = createRootNodeState(rootNodeUUID, ntReg); + } + } + + /** + * Disposes this SharedItemStateManager and frees resources. + */ + public void dispose() { + // clear cache + evictAll(); + } + + private NodeState createRootNodeState(String rootNodeUUID, + NodeTypeRegistry ntReg) + throws ItemStateException { + + NodeState rootState = createInstance(rootNodeUUID, NodeTypeRegistry.REP_ROOT, null); + + // @todo FIXME need to manually setup root node by creating mandatory jcr:primaryType property + NodeDefId nodeDefId = null; + PropDefId propDefId = null; + + try { + nodeDefId = new NodeDefId(ntReg.getRootNodeDef()); + // FIXME relies on definition of nt:base: + // first property definition in nt:base is jcr:primaryType + propDefId = new PropDefId(ntReg.getNodeTypeDef(NodeTypeRegistry.NT_BASE).getPropertyDefs()[0]); + } catch (NoSuchNodeTypeException nsnte) { + String msg = "failed to create root node"; + log.error(msg, nsnte); + throw new ItemStateException(msg, nsnte); + } + rootState.setDefinitionId(nodeDefId); + + QName propName = new QName(NamespaceRegistryImpl.NS_JCR_URI, "primaryType"); + rootState.addPropertyEntry(propName); + + PropertyState prop = createInstance(propName, rootNodeUUID); + prop.setValues(new InternalValue[]{InternalValue.create(NodeTypeRegistry.REP_ROOT)}); + prop.setType(PropertyType.NAME); + prop.setMultiValued(false); + prop.setDefinitionId(propDefId); + + ArrayList states = new ArrayList(); + states.add(rootState); + states.add(prop); + + // do persist root node (incl. properties) + store(states, Collections.EMPTY_LIST); + + return rootState; + } + + /** + * @param id + * @return + * @throws NoSuchItemStateException + * @throws ItemStateException + */ + protected NodeState getNodeState(NodeId id) + throws NoSuchItemStateException, ItemStateException { + + // check cache + if (isCached(id)) { + return (NodeState) retrieve(id); + } + + // load from persisted state + NodeState state = persistMgr.load(id.getUUID()); + state.setStatus(ItemState.STATUS_EXISTING); + + // put it in cache + cache(state); + + // register as listener + state.addListener(this); + return state; + } + + /** + * @param id + * @return + * @throws NoSuchItemStateException + * @throws ItemStateException + */ + protected PropertyState getPropertyState(PropertyId id) + throws NoSuchItemStateException, ItemStateException { + + // check cache + if (isCached(id)) { + return (PropertyState) retrieve(id); + } + + // load from persisted state + PropertyState state = persistMgr.load(id.getName(), id.getParentUUID()); + state.setStatus(ItemState.STATUS_EXISTING); + + // put it in cache + cache(state); + + // register as listener + state.addListener(this); + return state; + } + + //-----------------------------------------------------< ItemStateManager > + + /** + * @see ItemStateManager#getItemState(ItemId) + */ + public synchronized ItemState getItemState(ItemId id) + throws NoSuchItemStateException, ItemStateException { + + if (id.denotesNode()) { + return getNodeState((NodeId) id); + } else { + return getPropertyState((PropertyId) id); + } + } + + /** + * @see ItemStateManager#hasItemState(ItemId) + */ + public boolean hasItemState(ItemId id) { + if (isCached(id)) { + return true; + } + + try { + return persistMgr.exists(id); + } catch (ItemStateException ise) { + return false; + } + } + + /** + * @see ItemStateManager#getNodeReferences + */ + public synchronized NodeReferences getNodeReferences(NodeId targetId) + throws NoSuchItemStateException, ItemStateException { + + if (refsCache.containsKey(targetId)) { + return (NodeReferences) refsCache.get(targetId); + } + + NodeReferences refs; + + try { + refs = persistMgr.load(targetId); + } catch (NoSuchItemStateException nsise) { + refs = new NodeReferences(targetId); + } + + refsCache.put(targetId, refs); + return refs; + } + + /** + * @see ItemStateManager#beginUpdate + */ + public UpdateOperation beginUpdate() throws ItemStateException { + return new Update(); + } + + //-------------------------------------------------------- other operations + + /** + * Create a new node state instance + * + * @param uuid uuid + * @param nodeTypeName node type name + * @param parentUUID parent UUID + * @return new node state instance + */ + private NodeState createInstance(String uuid, QName nodeTypeName, + String parentUUID) { + + NodeState state = persistMgr.createNew(uuid, nodeTypeName, parentUUID); + state.setStatus(ItemState.STATUS_NEW); + state.addListener(this); + cache(state); + return state; + } + + /** + * Create a new property state instance + * + * @param propName property name + * @param parentUUID parent UUID + * @return new property state instance + */ + private PropertyState createInstance(QName propName, String parentUUID) { + PropertyState state = persistMgr.createNew(propName, parentUUID); + state.setStatus(ItemState.STATUS_NEW); + state.addListener(this); + cache(state); + return state; + } + + /** + * Store modified states and node references, atomically. + * + * @param states states that have been modified + * @param refsCollection collection of refs to store + * @throws ItemStateException if an error occurs + */ + private void store(Collection states, Collection refsCollection) + throws ItemStateException { + + persistMgr.store(states.iterator(), refsCollection.iterator()); + + Iterator iter = states.iterator(); + while (iter.hasNext()) { + ItemState state = (ItemState) iter.next(); + int status = state.getStatus(); + + switch (status) { + case ItemState.STATUS_NEW: + //state.notifyStateCreated(); + state.setStatus(ItemState.STATUS_EXISTING); + break; + + case ItemState.STATUS_EXISTING_REMOVED: + //state.notifyStateDestroyed(); + state.discard(); + break; + + default: + //state.notifyStateUpdated(); + state.setStatus(ItemState.STATUS_EXISTING); + break; + } + } + } + + + //----------------------------------------------------< ItemStateListener > + + /** + * @see ItemStateListener#stateCreated + */ + public void stateCreated(ItemState created) { + cache(created); + } + + /** + * @see ItemStateListener#stateModified + */ + public void stateModified(ItemState modified) { + // not interested + } + + /** + * @see ItemStateListener#stateDestroyed + */ + public void stateDestroyed(ItemState destroyed) { + destroyed.removeListener(this); + evict(destroyed.getId()); + } + + /** + * @see ItemStateListener#stateDiscarded + */ + public void stateDiscarded(ItemState discarded) { + discarded.removeListener(this); + evict(discarded.getId()); + } + + + class Update implements UpdateOperation { + + /** + * Modified states + */ + private final List states = new ArrayList(); + + /** + * Modified references + */ + private final List refsCollection = new ArrayList(); + + /** + * @see UpdateOperation#createNew + */ + public NodeState createNew(String uuid, QName nodeTypeName, + String parentUUID) { + return createInstance(uuid, nodeTypeName, parentUUID); + } + + /** + * @see UpdateOperation#createNew + */ + public PropertyState createNew(QName propName, String parentUUID) { + return createInstance(propName, parentUUID); + } + + /** + * @see UpdateOperation#store + */ + public void store(ItemState state) { + states.add(state); + } + + /** + * @see UpdateOperation#store + */ + public void store(NodeReferences refs) { + refsCollection.add(refs); + } + + /** + * @see UpdateOperation#destroy + */ + public void destroy(ItemState state) { + state.setStatus(ItemState.STATUS_EXISTING_REMOVED); + states.add(state); + } + + /** + * @see UpdateOperation#end + */ + public void end() throws ItemStateException { + NativeItemStateManager.this.store(states, refsCollection); + } + } + +} Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/NativePVM.java Tue Jan 25 08:34:30 2005 @@ -16,30 +16,26 @@ */ package org.apache.jackrabbit.core.version.persistence; -import org.apache.commons.collections.ReferenceMap; +import org.apache.log4j.Logger; +import org.apache.jackrabbit.core.version.*; import org.apache.jackrabbit.core.*; -import org.apache.jackrabbit.core.nodetype.NodeDefId; -import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; -import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; -import org.apache.jackrabbit.core.state.ItemStateException; -import org.apache.jackrabbit.core.state.ItemStateManager; -import org.apache.jackrabbit.core.state.NodeState; -import org.apache.jackrabbit.core.state.UpdateOperation; import org.apache.jackrabbit.core.util.uuid.UUID; -import org.apache.jackrabbit.core.version.*; -import org.apache.log4j.Logger; +import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.core.state.*; +import org.apache.commons.collections.ReferenceMap; import javax.jcr.RepositoryException; import javax.jcr.Value; +import javax.jcr.version.VersionException; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.Map; +import java.util.Iterator; /** * This Class implements the persistent part of the versioning. the * current implementation uses the 'normal' repository content as storage. - *

+ *

* although the nodes need to be mapped again virtually in the real content, * the persistent nodes use a different structure as exposed later. * each versioning element (version history, version, freezes) is stored in a @@ -47,10 +43,10 @@ * a persistentnodestate that represents a version, is the UUID of that version. * the hierarchy is somewhat similar, thus histories contain versions, contain * frozen nodes, etc. - *

+ *

* on startup, the entire structure is traversed, in order to get a mapping * from real to persistent uuids. - *

+ *

* todo: the persistence is not synchronized yet and could lead to multi-threading issues */ public class NativePVM implements PersistentVersionManager { @@ -123,12 +119,7 @@ /** * the state manager for the version storage */ - private ItemStateManager stateMgr; - - /** - * the nodetype manager for the version storage - */ - private NodeTypeManagerImpl ntMgr; + private NativeItemStateManager stateMgr; /** * mapping from virtual uuids to persistent ids of the persistent nodes @@ -140,7 +131,7 @@ * mapping from virtual uuids to persistent ids of the persistent nodes * key=internalId, value=PersistentId */ - private HashMap idsByInternal = new HashMap(); + private HashMap idsByInternal= new HashMap(); /** * list of histories for fast retrieval @@ -155,40 +146,15 @@ /** * Creates a new PersistentVersionManager. * - * @param session + * @param pMgr + * @param ntReg * @throws javax.jcr.RepositoryException */ - public NativePVM(SessionImpl session) throws RepositoryException { - this.stateMgr = ((WorkspaceImpl) session.getWorkspace()).getItemStateManager(); - this.ntMgr = session.getNodeTypeManager(); - + public NativePVM(PersistenceManager pMgr, NodeTypeRegistry ntReg) throws RepositoryException { try { - NodeImpl systemRoot = ((RepositoryImpl) session.getRepository()).getSystemRootNode(session); - // enable this to make the persistence storage visible - if (true) { - // check for versionhistory root - if (!systemRoot.hasNode(VERSION_HISTORY_ROOT_NAME)) { - // if not exist, create - systemRoot.addNode(VERSION_HISTORY_ROOT_NAME, NodeTypeRegistry.NT_UNSTRUCTURED); - systemRoot.save(); - } - NodeState nodeState = (NodeState) stateMgr.getItemState(new NodeId(systemRoot.getNode(VERSION_HISTORY_ROOT_NAME).internalGetUUID())); - historyRoot = new PersistentNode(stateMgr, ntMgr, nodeState); - } else { - if (!stateMgr.hasItemState(PERSISTENT_ROOT_ID)) { - UpdateOperation update = stateMgr.beginUpdate(); - NodeState nodeState = update.createNew(PERSISTENT_ROOT_ID.getUUID(), NodeTypeRegistry.NT_UNSTRUCTURED, null); - nodeState.setDefinitionId(new NodeDefId(ntMgr.getRootNodeDefinition().unwrap())); - // persist state - update.store(nodeState); - // finish update operation - update.end(); - historyRoot = new PersistentNode(stateMgr, ntMgr, nodeState); - } else { - NodeState nodeState = (NodeState) stateMgr.getItemState(PERSISTENT_ROOT_ID); - historyRoot = new PersistentNode(stateMgr, ntMgr, nodeState); - } - } + this.stateMgr = new NativeItemStateManager(pMgr, PERSISTENT_ROOT_ID.getUUID(), ntReg); + NodeState nodeState = (NodeState) stateMgr.getItemState(PERSISTENT_ROOT_ID); + historyRoot = new PersistentNode(stateMgr, nodeState); initVirtualIds(historyRoot.getState()); log.info("loaded " + idsByExternal.size() + " virtual ids."); } catch (ItemStateException e) { @@ -198,7 +164,6 @@ /** * initializes the internal item ids - * * @param parent * @throws RepositoryException * @throws ItemStateException @@ -216,7 +181,6 @@ /** * initializes the internal item ids - * * @param realUUID * @param state * @throws ItemStateException @@ -226,7 +190,7 @@ throws ItemStateException, RepositoryException { PersistentId id = new PersistentId(realUUID, state); if (id.type != PersistentId.TYPE_UNDEFINED) { - synchronized (idsByExternal) { + synchronized(idsByExternal) { idsByExternal.put(id.externalId, id); idsByInternal.put(id.internalId, id); } @@ -239,19 +203,17 @@ /** * returns the persistentid for a given external uuid - * * @param uuid * @return */ private PersistentId getIdByExternal(String uuid) { - synchronized (idsByExternal) { + synchronized(idsByExternal) { return (PersistentId) idsByExternal.get(uuid); } } /** * returns the persustentid for a given internal uuid - * * @param uuid * @return */ @@ -261,13 +223,12 @@ /** * returns the persustentid for a give internal uuid and item type - * * @param uuid * @param type * @return */ private PersistentId getIdByExternal(String uuid, int type) { - synchronized (idsByExternal) { + synchronized(idsByExternal) { PersistentId id = (PersistentId) idsByExternal.get(uuid); return id != null && id.type == type ? id : null; } @@ -285,32 +246,38 @@ // check if version history for that node already exists InternalVersionHistoryImpl hist = (InternalVersionHistoryImpl) getVersionHistory(node.internalGetUUID()); - if (hist != null) { + if (hist!=null) { return hist; } - // create deep path - String uuid = UUID.randomUUID().toString(); - PersistentNode root = historyRoot; - for (int i = 0; i < 3; i++) { - QName name = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid.substring(i * 2, i * 2 + 2)); - if (!root.hasNode(name)) { - root.addNode(name, NodeTypeRegistry.NT_UNSTRUCTURED); - root.store(); + try { + UpdateOperation upd = stateMgr.beginUpdate(); + + // create deep path + String uuid = UUID.randomUUID().toString(); + PersistentNode root = historyRoot; + for (int i=0; i<3; i++) { + QName name = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid.substring(i*2, i*2+2)); + if (!root.hasNode(name)) { + root.addNode(upd, name, NodeTypeRegistry.NT_UNSTRUCTURED); + root.store(upd); + } + root = root.getNode(name, 1); } - root = root.getNode(name, 1); - } - QName historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid); + QName historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid); + + // create new history node in the persistent state + hist = InternalVersionHistoryImpl.create(upd, this, root, uuid, historyNodeName, node); + + // end update + upd.end(); - // create new history node in the persistent state - hist = InternalVersionHistoryImpl.create(this, root, uuid, historyNodeName, node); - try { initVirtualIds(hist.getId(), hist.getNode().getState()); } catch (ItemStateException e) { throw new RepositoryException(e); } - log.info("Created new version history " + uuid + ". NumHistories=" + histories.size()); + log.info("Created new version history " + hist.getId()+ " for " + node.safeGetJCRPath() + ". NumHistories=" + histories.size()); return hist; } @@ -325,7 +292,7 @@ throws RepositoryException { PersistentId pid = getIdByExternal(histId, PersistentId.TYPE_HISTORY); - return pid == null ? null : (InternalVersionHistory) getItem(pid); + return pid==null ? null : (InternalVersionHistory) getItem(pid); } /** @@ -382,7 +349,7 @@ throws RepositoryException { PersistentId pid = getIdByExternal(versionId, PersistentId.TYPE_VERSION); - return pid == null ? null : (InternalVersion) getItem(pid); + return pid==null ? null : (InternalVersion) getItem(pid); } /** @@ -397,7 +364,6 @@ /** * checks, if the item with the given external id exists - * * @param externalId * @return */ @@ -407,7 +373,6 @@ /** * returns the item referred by the external id - * * @param externalId * @return * @throws RepositoryException @@ -415,12 +380,11 @@ public InternalVersionItem getItemByExternal(String externalId) throws RepositoryException { PersistentId pid = getIdByExternal(externalId); - return pid == null ? null : getItem(pid); + return pid==null ? null : getItem(pid); } /** * returns the item referred by the internal id - * * @param internalId * @return * @throws RepositoryException @@ -428,12 +392,11 @@ public InternalVersionItem getItemByInternal(String internalId) throws RepositoryException { PersistentId pid = getIdByInternal(internalId); - return pid == null ? null : getItem(pid); + return pid==null ? null : getItem(pid); } /** * returns the item with the given persistent id - * * @param pid * @return * @throws RepositoryException @@ -441,10 +404,10 @@ private InternalVersionItem getItem(PersistentId pid) throws RepositoryException { - InternalVersionItem item = (InternalVersionItem) items.get(pid); - if (item == null) { + InternalVersionItem item =(InternalVersionItem) items.get(pid); + if (item==null) { PersistentNode pNode = historyRoot.getNodeByUUID(pid.internalId); - if (pNode != null) { + if (pNode!=null) { InternalVersionItem parent = getItemByInternal(pNode.getParentUUID()); if (pid.type == PersistentId.TYPE_FROZEN) { item = new InternalFrozenNodeImpl(this, pNode, pid.externalId, parent); @@ -458,7 +421,7 @@ //return null; } } - if (item != null) { + if (item!=null) { items.put(pid, item); } } @@ -516,13 +479,52 @@ } while (history.hasVersion(new QName("", versionName))); } - InternalVersionImpl v = history.checkin(new QName("", versionName), node); try { + UpdateOperation upd = stateMgr.beginUpdate(); + InternalVersionImpl v = history.checkin(upd, new QName("", versionName), node); + upd.end(); + initVirtualIds(v.getId(), v.getNode().getState()); + + return v; } catch (ItemStateException e) { throw new RepositoryException(e); } - return v; + } + + public void removeVersion(InternalVersionHistory hist, QName name) throws VersionException { + try { + UpdateOperation upd = stateMgr.beginUpdate(); + ((InternalVersionHistoryImpl) hist).removeVersion(upd, name); + upd.end(); + } catch (ItemStateException e) { + throw new VersionException(e); + } + + } + + public InternalVersion addVersionLabel(InternalVersionHistory hist, QName versionName, String label, boolean move) throws VersionException { + try { + UpdateOperation upd = stateMgr.beginUpdate(); + InternalVersion v = + ((InternalVersionHistoryImpl) hist).addVersionLabel(upd, versionName, label, move); + upd.end(); + return v; + } catch (ItemStateException e) { + throw new VersionException(e); + } + } + + public InternalVersion removeVersionLabel(InternalVersionHistory hist, String label) throws VersionException { + try { + UpdateOperation upd = stateMgr.beginUpdate(); + InternalVersion v = + ((InternalVersionHistoryImpl) hist).removeVersionLabel(upd, label); + upd.end(); + return v; + } catch (ItemStateException e) { + throw new VersionException(e); + } } /** @@ -536,19 +538,13 @@ private static final int TYPE_FROZEN = 3; private static final int TYPE_FROZEN_HISTORY = 4; - /** - * the type of the persistent node - */ + /** the type of the persistent node */ private final int type; - /** - * the persistent uuid of the node - */ + /** the persistent uuid of the node */ private final String externalId; - /** - * the persistent uuid of the node - */ + /** the persistent uuid of the node */ private final String internalId; public PersistentId(int type, String external, String internal) { @@ -590,6 +586,33 @@ public boolean isFrozen() { return type == TYPE_FROZEN; + } + } + + private class Update implements UpdateOperation { + + public NodeState createNew(String uuid, QName nodeTypeName, String parentUUID) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public PropertyState createNew(QName propName, String parentUUID) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public void store(ItemState state) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void store(NodeReferences refs) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void destroy(ItemState state) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void end() throws ItemStateException { + //To change body of implemented methods use File | Settings | File Templates. } } Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java?view=diff&rev=126386&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java&r1=126385&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java&r2=126386 ============================================================================== --- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java (original) +++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/PersistentNode.java Tue Jan 25 08:34:30 2005 @@ -20,13 +20,9 @@ import org.apache.jackrabbit.core.state.*; import org.apache.jackrabbit.core.util.uuid.UUID; -import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.nodetype.NoSuchNodeTypeException; -import javax.jcr.nodetype.NodeDef; -import javax.jcr.nodetype.PropertyDef; -import java.util.HashSet; import java.util.List; /** @@ -46,11 +42,6 @@ private final ItemStateManager stateMgr; /** - * the node type manager - */ - private final NodeTypeManagerImpl ntMgr; - - /** * the cached name */ private QName name = null; @@ -59,15 +50,12 @@ * Creates a new persistent node * * @param stateMgr - * @param ntMgr * @param nodeState */ protected PersistentNode(ItemStateManager stateMgr, - NodeTypeManagerImpl ntMgr, NodeState nodeState) { this.nodeState = nodeState; this.stateMgr = stateMgr; - this.ntMgr = ntMgr; } @@ -173,9 +161,9 @@ * @param value * @throws RepositoryException */ - protected void setPropertyValue(QName name, InternalValue value) + protected void setPropertyValue(UpdateOperation upd, QName name, InternalValue value) throws RepositoryException { - setPropertyValues(name, value.getType(), new InternalValue[]{value}, false); + setPropertyValues(upd, name, value.getType(), new InternalValue[]{value}, false); } /** @@ -186,9 +174,9 @@ * @param values * @throws RepositoryException */ - protected void setPropertyValues(QName name, int type, InternalValue[] values) + protected void setPropertyValues(UpdateOperation upd, QName name, int type, InternalValue[] values) throws RepositoryException { - setPropertyValues(name, type, values, true); + setPropertyValues(upd, name, type, values, true); } /** @@ -199,13 +187,14 @@ * @param values * @throws RepositoryException */ - protected void setPropertyValues(QName name, int type, InternalValue[] values, boolean multiple) + protected void setPropertyValues(UpdateOperation upd, QName name, int type, InternalValue[] values, boolean multiple) throws RepositoryException { - PropertyState prop = getOrCreatePropertyState(name, type, multiple); + PropertyState prop = getOrCreatePropertyState(upd, name, type, multiple); prop.setValues(values); } + /** * Retrieves or creates a new property state as child property of this node * @@ -215,7 +204,7 @@ * @return * @throws RepositoryException */ - private PropertyState getOrCreatePropertyState(QName name, int type, boolean multiValued) + private PropertyState getOrCreatePropertyState(UpdateOperation upd, QName name, int type, boolean multiValued) throws RepositoryException { PropertyId propId = new PropertyId(nodeState.getUUID(), name); @@ -223,80 +212,32 @@ try { PropertyState propState = (PropertyState) stateMgr.getItemState(propId); // someone calling this method will always alter the property state, so set status to modified - propState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + if (propState.getStatus()==ItemState.STATUS_EXISTING) { + propState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + } + // although this is not quite correct, we mark node as modified aswell + if (nodeState.getStatus()==ItemState.STATUS_EXISTING) { + nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + } return propState; } catch (ItemStateException e) { throw new RepositoryException("Unable to create property: " + e.toString()); } } else { - PropertyDefImpl def = getApplicablePropertyDef(name, type, multiValued); - //@todo create property state inside an update - PropertyState propState = new PropertyState(name, nodeState.getUUID(), - PropertyState.STATUS_NEW, false); + PropertyState propState = upd.createNew(name, nodeState.getUUID()); propState.setType(type); propState.setMultiValued(multiValued); - propState.setDefinitionId(new PropDefId(def.unwrap())); - + propState.setDefinitionId(PropDefId.valueOf("0")); // need to store nodestate nodeState.addPropertyEntry(name); - nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + if (nodeState.getStatus()==ItemState.STATUS_EXISTING) { + nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + } return propState; } } /** - * retrieves the property definition for the given contraints - * - * @param propertyName - * @param type - * @param multiValued - * @return - * @throws RepositoryException - */ - protected PropertyDefImpl getApplicablePropertyDef(QName propertyName, - int type, boolean multiValued) - throws RepositoryException { - PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(propertyName, type, multiValued); - return ntMgr.getPropDef(new PropDefId(pd)); - } - - /** - * Retrieves the node definition for the given contraints. - * - * @param nodeName - * @param nodeTypeName - * @return - * @throws RepositoryException - */ - protected NodeDefImpl getApplicableChildNodeDef(QName nodeName, QName nodeTypeName) - throws RepositoryException { - ChildNodeDef cnd = getEffectiveNodeType().getApplicableChildNodeDef(nodeName, nodeTypeName); - return ntMgr.getNodeDef(new NodeDefId(cnd)); - } - - /** - * Returns the effective (i.e. merged and resolved) node type representation - * of this node's primary and mixin node types. - * - * @return the effective node type - * @throws RepositoryException - */ - protected EffectiveNodeType getEffectiveNodeType() throws RepositoryException { - // build effective node type of mixins & primary type - NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry(); - // existing mixin's - HashSet set = new HashSet(nodeState.getMixinTypeNames()); - // primary type - set.add(nodeState.getNodeTypeName()); - try { - return ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()])); - } catch (NodeTypeConflictException ntce) { - String msg = "internal error: failed to build effective node type for node " + nodeState.getUUID(); - throw new RepositoryException(msg, ntce); - } - } - - /** * checks if the given child node exists. * * @param name @@ -313,8 +254,8 @@ * @return * @throws RepositoryException */ - protected boolean removeNode(QName name) throws RepositoryException { - return removeNode(name, 1); + protected boolean removeNode(UpdateOperation upd, QName name) throws RepositoryException { + return removeNode(upd, name, 1); } /** @@ -325,12 +266,20 @@ * @return * @throws RepositoryException */ - protected boolean removeNode(QName name, int index) throws RepositoryException { - if (nodeState.removeChildNodeEntry(name, index)) { - nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); - return true; - } else { - return false; + protected boolean removeNode(UpdateOperation upd, QName name, int index) throws RepositoryException { + try { + NodeState.ChildNodeEntry entry = nodeState.getChildNodeEntry(name, index); + if (entry == null) { + return false; + } else { + ItemState state = stateMgr.getItemState(new NodeId(entry.getUUID())); + upd.destroy(state); + nodeState.removeChildNodeEntry(name, index); + nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + return true; + } + } catch (ItemStateException e) { + throw new RepositoryException(e); } } @@ -350,7 +299,7 @@ } try { NodeState state = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID())); - return new PersistentNode(stateMgr, ntMgr, state); + return new PersistentNode(stateMgr, state); } catch (ItemStateException e) { throw new RepositoryException("Unable to getNode: " + e.toString()); } @@ -366,7 +315,7 @@ protected PersistentNode getNodeByUUID(String uuid) throws RepositoryException { try { NodeState state = (NodeState) stateMgr.getItemState(new NodeId(uuid)); - return new PersistentNode(stateMgr, ntMgr, state); + return new PersistentNode(stateMgr, state); } catch (ItemStateException e) { throw new RepositoryException("Unable to getNode: " + e.toString()); } @@ -382,79 +331,35 @@ * @throws ConstraintViolationException * @throws RepositoryException */ - protected PersistentNode addNode(QName nodeName, QName nodeTypeName) + protected PersistentNode addNode(UpdateOperation upd, QName nodeName, QName nodeTypeName) throws NoSuchNodeTypeException, ConstraintViolationException, RepositoryException { - NodeTypeImpl nodeType = ntMgr.getNodeType(nodeTypeName); - NodeDefImpl def; - try { - def = getApplicableChildNodeDef(name, nodeType == null ? null : nodeType.getQName()); - } catch (RepositoryException re) { - // hack, use nt:unstructured as parent - try { - NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry(); - EffectiveNodeType ent = ntReg.getEffectiveNodeType(new QName[]{NodeTypeRegistry.NT_UNSTRUCTURED}); - ChildNodeDef cnd = ent.getApplicableChildNodeDef(name, nodeTypeName); - def = ntMgr.getNodeDef(new NodeDefId(cnd)); - } catch (NodeTypeConflictException e) { - String msg = "no definition found in parent node's node type for new node"; - throw new ConstraintViolationException(msg, re); - } - } - - if (nodeType == null) { - // use default node type - nodeType = (NodeTypeImpl) def.getDefaultPrimaryType(); - } - return createChildNode(nodeName, def, nodeType, null); + return createChildNode(upd, nodeName, nodeTypeName, null); } /** * creates a new child node * * @param name - * @param def - * @param nodeType * @param uuid * @return - * @throws RepositoryException */ - private PersistentNode createChildNode(QName name, NodeDefImpl def, - NodeTypeImpl nodeType, String uuid) - throws RepositoryException { + private PersistentNode createChildNode(UpdateOperation upd, QName name, QName nodeTypeName, String uuid) { String parentUUID = nodeState.getUUID(); // create a new node state - NodeState state = null; if (uuid == null) { uuid = UUID.randomUUID().toString(); // version 4 uuid } - //@todo create node state inside an update - state = new NodeState(uuid, nodeType.getQName(), parentUUID, - NodeState.STATUS_NEW, false); - state.setDefinitionId(new NodeDefId(def.unwrap())); + NodeState state = upd.createNew(uuid, nodeTypeName, parentUUID); + state.setDefinitionId(NodeDefId.valueOf("0")); // create Node instance wrapping new node state - PersistentNode node = new PersistentNode(stateMgr, ntMgr, state); + PersistentNode node = new PersistentNode(stateMgr, state); // add new child node entry nodeState.addChildNodeEntry(name, state.getUUID()); - nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); - - // add 'auto-create' properties defined in node type - PropertyDef[] pda = nodeType.getAutoCreatePropertyDefs(); - for (int i = 0; i < pda.length; i++) { - PropertyDefImpl pd = (PropertyDefImpl) pda[i]; - node.getOrCreatePropertyState(pd.getQName(), pd.getRequiredType(), pd.isMultiple()); - } - - // recursively add 'auto-create' child nodes defined in node type - NodeDef[] nda = nodeType.getAutoCreateNodeDefs(); - for (int i = 0; i < nda.length; i++) { - NodeDefImpl nd = (NodeDefImpl) nda[i]; - node.createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null); + if (nodeState.getStatus()==ItemState.STATUS_EXISTING) { + nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); } - - // store primary type - node.setPropertyValue(ItemImpl.PROPNAME_PRIMARYTYPE, InternalValue.create(nodeType.getQName())); return node; } @@ -471,7 +376,7 @@ for (int i = 0; i < entries.size(); i++) { NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) entries.get(i); NodeState state = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID())); - children[i] = new PersistentNode(stateMgr, ntMgr, state); + children[i] = new PersistentNode(stateMgr, state); } return children; } catch (ItemStateException e) { @@ -484,11 +389,9 @@ * * @throws RepositoryException */ - protected void store() throws RepositoryException { + protected void store(UpdateOperation upd) throws RepositoryException { try { - UpdateOperation update = stateMgr.beginUpdate(); - store(nodeState, update); - update.end(); + store(upd, nodeState); } catch (ItemStateException e) { throw new RepositoryException(e); } @@ -501,16 +404,16 @@ * @param update update operation * @throws ItemStateException */ - private void store(NodeState state, UpdateOperation update) + private void store(UpdateOperation update, NodeState state) throws ItemStateException { - if (state.isTransient()) { + if (state.getStatus()!=ItemState.STATUS_EXISTING) { // first store all transient properties List props = state.getPropertyEntries(); for (int i = 0; i < props.size(); i++) { NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i); PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName())); - if (pstate.isTransient()) { + if (pstate.getStatus()!=ItemState.STATUS_EXISTING) { update.store(pstate); } } @@ -519,7 +422,7 @@ for (int i = 0; i < nodes.size(); i++) { NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) nodes.get(i); NodeState nstate = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID())); - store(nstate, update); + store(update, nstate); } // and store itself update.store(state); @@ -548,13 +451,13 @@ * @throws ItemStateException */ private void reload(NodeState state) throws ItemStateException { - if (state.isTransient()) { + if (state.getStatus()!=ItemState.STATUS_EXISTING) { // first discard all all transient properties List props = state.getPropertyEntries(); for (int i = 0; i < props.size(); i++) { NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i); PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName())); - if (pstate.isTransient()) { + if (pstate.getStatus()!=ItemState.STATUS_EXISTING) { pstate.discard(); } } @@ -576,30 +479,14 @@ * @param prop * @throws RepositoryException */ - protected void copyFrom(PropertyImpl prop) throws RepositoryException { + protected void copyFrom(UpdateOperation upd, PropertyImpl prop) throws RepositoryException { if (prop.getDefinition().isMultiple()) { InternalValue[] values = prop.internalGetValues(); int type = values.length>0 ? values[0].getType() : prop.getDefinition().getRequiredType(); - setPropertyValues(prop.getQName(), type, values); + setPropertyValues(upd, prop.getQName(), type, values); } else { - setPropertyValue(prop.getQName(), prop.internalGetValue()); + setPropertyValue(upd, prop.getQName(), prop.internalGetValue()); } } - /** - * sets the mixing node type and adds the respective property - * - * @param mixins - * @throws RepositoryException - */ - protected void setMixinNodeTypes(QName[] mixins) throws RepositoryException { - HashSet set = new HashSet(); - InternalValue[] values = new InternalValue[mixins.length]; - for (int i = 0; i < mixins.length; i++) { - set.add(mixins[i]); - values[i] = InternalValue.create(mixins[i]); - } - nodeState.setMixinTypeNames(set); - setPropertyValues(ItemImpl.PROPNAME_MIXINTYPES, PropertyType.NAME, values); - } }