jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r126386 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: . config fs/local jndi state state/mem state/obj state/xml version version/persistence
Date Tue, 25 Jan 2005 16:34:32 GMT
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 <code>WorkspaceInfo<code>s.
@@ -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 <code>FileSystem</code> for the versioing. */
+    private final FileSystem fs;
+
+    /** Parameters for configuring the versioning */
+    private Map params = new HashMap();
+
+    /** The <code>PersistenceManagerConfig</code> for the versioning */
+    private final PersistenceManagerConfig pmConfig;
+
+    /**
+     * Creates a new <code>VersioningConfig</code>.
+     * @param config the config root element for this <code>VersioningConfig</code>.
+     * @param vars map of variable values.
+     * @throws RepositoryException if an error occurs while creating the
+     *  <code>SearchConfig</code>.
+     */
+    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 <code>PersistenceManagerConfig</code> 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
 -->
-<!ELEMENT Repository (FileSystem,Workspaces,Workspace)>
+<!ELEMENT Repository (FileSystem,Workspaces,Workspace,Versioning)>
 
 <!--
     a virtual file system
@@ -90,3 +90,12 @@
     (used by the QueryManager)
 -->
 <!ELEMENT SearchIndex (param*,FileSystem)>
+
+<!--
+the Versioning element specifies the location and persistence manager
+that is used to store versions
+    -->
+<!ELEMENT Versioning (FileSystem, PersistenceManager)>
+<!ATTLIST Versioning
+rootPath CDATA #REQUIRED
+>

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 <code>PMContext</code> 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 <code>PMContext</code>.
      *
-     * @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.
+     * <p/>
+     * 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 <code>NodeReferences</code> objects.
+     */
+    private Map refsCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
+
+    /**
+     * Creates a new <code>DefaultItemStateManager</code> 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 <code>SharedItemStateManager</code> 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.
- * <p/>
+ * <p>
  * 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.
- * <p/>
+ * <p>
  * on startup, the entire structure is traversed, in order to get a mapping
  * from real to persistent uuids.
- * <p/>
+ * <p>
  * 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);
-    }
 }

Mime
View raw message