You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2005/03/02 18:18:19 UTC

svn commit: r155930 - in incubator/jackrabbit/trunk: applications/test/ src/conf/ src/java/org/apache/jackrabbit/core/ src/java/org/apache/jackrabbit/core/config/ src/java/org/apache/jackrabbit/core/nodetype/ src/java/org/apache/jackrabbit/core/security/

Author: stefan
Date: Wed Mar  2 09:18:13 2005
New Revision: 155930

URL: http://svn.apache.org/viewcvs?view=rev&rev=155930
Log:
AccessManager implementation configurable in repository.xml

Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java   (with props)
Modified:
    incubator/jackrabbit/trunk/applications/test/repository.xml
    incubator/jackrabbit/trunk/src/conf/repository.xml
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SystemSession.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AbstractConfig.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AccessManager.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/SimpleAccessManager.java

Modified: incubator/jackrabbit/trunk/applications/test/repository.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/applications/test/repository.xml?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/applications/test/repository.xml (original)
+++ incubator/jackrabbit/trunk/applications/test/repository.xml Wed Mar  2 09:18:13 2005
@@ -14,6 +14,9 @@
             used by the repository to persist global state such as
             registered namespaces, custom node types, etc..
 
+            a Security element that specifies the name of the app-entry
+            in the JAAS config and the access manager
+
             a Workspaces element that specifies to the location of
             workspaces root directory and the name of default workspace
 
@@ -25,10 +28,10 @@
             a SearchIndex element that is used for configuring per workspace
             Indexing-related settings
 
-            a Versioning element that is used for configuring 
+            a Versioning element that is used for configuring
             versioning-related settings
     -->
-    <!ELEMENT Repository (FileSystem,Workspaces,Workspace,Versioning)>
+    <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning)>
 
     <!--
         a virtual file system
@@ -38,6 +41,25 @@
       class CDATA #REQUIRED>
 
     <!--
+        the Security element specifies the name (appName attribute)
+        of the JAAS configuration app-entry for this repository. 
+
+        it also specifies the access manager to be used (AccessManager element).
+    -->
+    <!ELEMENT Security (AccessManager)>
+    <!ATTLIST Security
+      appName CDATA #REQUIRED>
+
+    <!--
+        the AccessManager element configures the access manager to be used by
+        this repository instance; the class attribute specifies the FQN of the
+        class implementing the AccessManager interface
+    -->
+    <!ELEMENT AccessManager (param*)>
+    <!ATTLIST AccessManager
+      class CDATA #REQUIRED>
+
+    <!--
         generic parameter (name/value pair)
     -->
     <!ELEMENT param EMPTY>
@@ -70,7 +92,7 @@
     <!--
         the PersistenceManager element configures the persistence manager
         to be used for the workspace; the class attribute specifies the
-        FQN of the class implementing PersistenceManager interface
+        FQN of the class implementing the PersistenceManager interface
     -->
     <!ELEMENT PersistenceManager (param*)>
     <!ATTLIST PersistenceManager
@@ -94,6 +116,7 @@
       rootPath CDATA #REQUIRED
     >
 ]>
+<!-- Example Repository Configuration File -->
 <Repository>
     <!--
         virtual file system where the repository stores global state
@@ -102,6 +125,20 @@
     <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
         <param name="path" value="${rep.home}/repository"/>
     </FileSystem>
+
+    <!--
+        security configuration
+    -->
+    <Security appName="Jackrabbit">
+        <!--
+            access manager:
+            class: FQN of class implementing the AccessManager interface
+        -->
+        <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+            <!-- <param name="config" value="${rep.home}/access.xml"/> -->
+        </AccessManager>
+    </Security>
+
     <!--
         location of workspaces root directory and name of default workspace
     -->
@@ -113,7 +150,7 @@
     <Workspace name="${wsp.name}">
         <!--
             virtual file system of the workspace:
-            class: FQN of class implementing FileSystem interface
+            class: FQN of class implementing the FileSystem interface
         -->
         <FileSystem class="com.day.jackrabbit.fs.cq.CQFileSystem">
             <param name="path" value="${wsp.home}/wspStore.dat"/>
@@ -122,8 +159,23 @@
             <param name="autoSync" value="false"/>
         </FileSystem>
         <!--
-            persistence of the workspace:
-            class: FQN of class implementing PersistenceManager interface
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+            <param name="path" value="${wsp.home}"/>
+        </FileSystem>
+        -->
+        <!--
+            persistence manager of the workspace:
+            class: FQN of class implementing the PersistenceManager interface
+        -->
+        <!--
+        <PersistenceManager class="org.apache.jackrabbit.core.state.xml.XMLPersistenceManager"/>
+        -->
+        <!--
+        <PersistenceManager class="org.apache.jackrabbit.core.state.mem.InMemPersistenceManager">
+            <param name="initialCapacity" value="100000"/>
+            <param name="loadFactor" value="0.3"/>
+            <param name="persistent" value="true"/>
+        </PersistenceManager>
         -->
         <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
         <!--
@@ -134,7 +186,7 @@
             <param name="minMergeDocs" value="1000"/>
             <param name="maxMergeDocs" value="10000"/>
             <param name="mergeFactor" value="10"/>
-            
+
             <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
                 <param name="path" value="${wsp.home}/index"/>
             </FileSystem>
@@ -155,9 +207,15 @@
             <param name="blockSize" value="128"/>
             <param name="autoSync" value="false"/>
         </FileSystem>
-
+    
         <!--
-            Configures the persistence manager to be used for persisting version state.
+            <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+                <param name="path" value="${rep.home}/version"/>
+            </FileSystem>
+        -->
+        
+        <!--
+            Configures the perisistence manager to be used for persisting version state.
             Please note that the current versioning implementation is based on
             a 'normal' persistence manager, but this could change in future
             implementations.
@@ -165,5 +223,4 @@
         <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager"/>
 
     </Versioning>
-
 </Repository>

Modified: incubator/jackrabbit/trunk/src/conf/repository.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/conf/repository.xml?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/conf/repository.xml (original)
+++ incubator/jackrabbit/trunk/src/conf/repository.xml Wed Mar  2 09:18:13 2005
@@ -14,6 +14,9 @@
             used by the repository to persist global state such as
             registered namespaces, custom node types, etc..
 
+            a Security element that specifies the name of the app-entry
+            in the JAAS config and the access manager
+
             a Workspaces element that specifies to the location of
             workspaces root directory and the name of default workspace
 
@@ -25,10 +28,10 @@
             a SearchIndex element that is used for configuring per workspace
             Indexing-related settings
 
-            a Versioning element that is used for configuring 
+            a Versioning element that is used for configuring
             versioning-related settings
     -->
-    <!ELEMENT Repository (FileSystem,Workspaces,Workspace)>
+    <!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning)>
 
     <!--
         a virtual file system
@@ -38,6 +41,25 @@
       class CDATA #REQUIRED>
 
     <!--
+        the Security element specifies the name (appName attribute)
+        of the JAAS configuration app-entry for this repository. 
+
+        it also specifies the access manager to be used (AccessManager element).
+    -->
+    <!ELEMENT Security (AccessManager)>
+    <!ATTLIST Security
+      appName CDATA #REQUIRED>
+
+    <!--
+        the AccessManager element configures the access manager to be used by
+        this repository instance; the class attribute specifies the FQN of the
+        class implementing the AccessManager interface
+    -->
+    <!ELEMENT AccessManager (param*)>
+    <!ATTLIST AccessManager
+      class CDATA #REQUIRED>
+
+    <!--
         generic parameter (name/value pair)
     -->
     <!ELEMENT param EMPTY>
@@ -70,7 +92,7 @@
     <!--
         the PersistenceManager element configures the persistence manager
         to be used for the workspace; the class attribute specifies the
-        FQN of the class implementing PersistenceManager interface
+        FQN of the class implementing the PersistenceManager interface
     -->
     <!ELEMENT PersistenceManager (param*)>
     <!ATTLIST PersistenceManager
@@ -103,6 +125,20 @@
     <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
         <param name="path" value="${rep.home}/repository"/>
     </FileSystem>
+
+    <!--
+        security configuration
+    -->
+    <Security appName="Jackrabbit">
+        <!--
+            access manager:
+            class: FQN of class implementing the AccessManager interface
+        -->
+        <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+            <!-- <param name="config" value="${rep.home}/access.xml"/> -->
+        </AccessManager>
+    </Security>
+
     <!--
         location of workspaces root directory and name of default workspace
     -->
@@ -114,7 +150,7 @@
     <Workspace name="${wsp.name}">
         <!--
             virtual file system of the workspace:
-            class: FQN of class implementing FileSystem interface
+            class: FQN of class implementing the FileSystem interface
         -->
         <FileSystem class="com.day.jackrabbit.fs.cq.CQFileSystem">
             <param name="path" value="${wsp.home}/wspStore.dat"/>
@@ -129,7 +165,7 @@
         -->
         <!--
             persistence manager of the workspace:
-            class: FQN of class implementing PersistenceManager interface
+            class: FQN of class implementing the PersistenceManager interface
         -->
         <!--
         <PersistenceManager class="org.apache.jackrabbit.core.state.xml.XMLPersistenceManager"/>

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemImpl.java Wed Mar  2 09:18:13 2005
@@ -17,13 +17,34 @@
 package org.apache.jackrabbit.core;
 
 import org.apache.commons.collections.ReferenceMap;
-import org.apache.jackrabbit.core.nodetype.*;
+import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
+import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.nodetype.PropertyDefImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.core.state.*;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.ItemStateListener;
+import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.SessionItemStateManager;
 import org.apache.jackrabbit.core.util.uuid.UUID;
 import org.apache.log4j.Logger;
 
-import javax.jcr.*;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Item;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NodeDef;
@@ -31,7 +52,12 @@
 import javax.jcr.nodetype.PropertyDef;
 import javax.jcr.version.VersionException;
 import javax.jcr.version.VersionHistory;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 
 /**
  * <code>ItemImpl</code> implements the <code>Item</code> interface.

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&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java Wed Mar  2 09:18:13 2005
@@ -83,9 +83,6 @@
     private static final String PROPERTIES_RESOURCE = "rep.properties";
     private final Properties repProps;
 
-    // name of jaas config entry
-    public static final String JAAS_CONFIG_APPNAME = "Jackrabbit";
-
     // names of well known repository properties
     public static final String STATS_NODE_COUNT_PROPERTY = "jcr.repository.stats.nodes.count";
     public static final String STATS_PROP_COUNT_PROPERTY = "jcr.repository.stats.properties.count";
@@ -641,8 +638,9 @@
             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);
+            String msg = "Cannot instantiate implementing class " + className;
+            log.error(msg, e);
+            throw new RepositoryException(msg, e);
         }
     }
 
@@ -670,7 +668,7 @@
                 new CredentialsCallbackHandler(credentials);
         LoginContext lc;
         try {
-            lc = new LoginContext(JAAS_CONFIG_APPNAME, cbHandler);
+            lc = new LoginContext(repConfig.getAppName(), cbHandler);
             lc.login();
         } catch (javax.security.auth.login.LoginException le) {
             throw new LoginException(le.getMessage());
@@ -849,7 +847,7 @@
         synchronized PersistenceManager getPersistenceManager(PersistenceManagerConfig pmConfig)
                 throws RepositoryException {
             if (persistMgr == null) {
-                persistMgr = RepositoryImpl.createPersistenceManager(new File(config.getHomeDir()),
+                persistMgr = createPersistenceManager(new File(config.getHomeDir()),
                         config.getFileSystem(),
                         pmConfig,
                         rootNodeUUID,

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java Wed Mar  2 09:18:13 2005
@@ -16,15 +16,17 @@
  */
 package org.apache.jackrabbit.core;
 
+import org.apache.commons.collections.BeanMap;
 import org.apache.commons.collections.ReferenceMap;
+import org.apache.jackrabbit.core.config.AccessManagerConfig;
 import org.apache.jackrabbit.core.config.WorkspaceConfig;
-import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.core.security.SimpleAccessManager;
 import org.apache.jackrabbit.core.nodetype.NodeDefId;
 import org.apache.jackrabbit.core.nodetype.NodeDefImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
 import org.apache.jackrabbit.core.observation.EventStateCollection;
+import org.apache.jackrabbit.core.security.AMContext;
+import org.apache.jackrabbit.core.security.AccessManager;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.SessionItemStateManager;
 import org.apache.jackrabbit.core.state.UpdatableItemStateManager;
@@ -64,6 +66,7 @@
 import javax.jcr.version.VersionException;
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -244,10 +247,39 @@
      * Create the access manager.
      *
      * @return access manager
+     * @throws RepositoryException if an error occurs
      */
     protected AccessManager createAccessManager(Subject subject,
-                                                HierarchyManager hierMgr) {
-        return new SimpleAccessManager(subject, hierMgr);
+                                                HierarchyManager hierMgr)
+            throws RepositoryException {
+        AccessManagerConfig amConfig = rep.getConfig().getAccessManagerConfig();
+        String className = amConfig.getClassName();
+        Map params = amConfig.getParameters();
+        try {
+            Class c = Class.forName(className);
+            AccessManager accessMgr = (AccessManager) c.newInstance();
+            /**
+             * set the properties of the access manager object
+             * from the param map
+             */
+            BeanMap bm = new BeanMap(accessMgr);
+            Iterator iter = params.keySet().iterator();
+            while (iter.hasNext()) {
+                Object name = iter.next();
+                Object value = params.get(name);
+                bm.put(name, value);
+            }
+            AMContext ctx = new AMContext(new File(rep.getConfig().getHomeDir()),
+                    rep.getConfig().getFileSystem(),
+                    subject,
+                    hierMgr);
+            accessMgr.init(ctx);
+            return accessMgr;
+        } catch (Exception e) {
+            String msg = "failed to instantiate AccessManager implementation: " + className;
+            log.error(msg, e);
+            throw new RepositoryException(msg, e);
+        }
     }
 
     /**
@@ -426,9 +458,9 @@
         try {
             sanityCheck();
         } catch (RepositoryException re) {
-            String msg = "failed to check READ permission on " + absPath;
+            String msg = "failed to check permissions on " + absPath;
             log.warn(msg, re);
-            throw new AccessControlException(READ_ACTION);
+            throw new AccessControlException(actions);
         }
 
         // build the set of actions to be checked
@@ -495,20 +527,17 @@
 
         /**
          * "remove" action:
-         * requires WRITE permission on parent item
+         * requires REMOVE permission on target item
          */
         if (set.contains(REMOVE_ACTION)) {
             try {
                 if (targetPath == null) {
                     targetPath = Path.create(absPath, getNamespaceResolver(), true);
                 }
-                if (parentPath == null) {
-                    parentPath = targetPath.getAncestor(1);
-                }
-                if (parentId == null) {
-                    parentId = hierMgr.resolvePath(parentPath);
+                if (targetId == null) {
+                    targetId = hierMgr.resolvePath(targetPath);
                 }
-                accessMgr.checkPermission(parentId, AccessManager.WRITE);
+                accessMgr.checkPermission(targetId, AccessManager.REMOVE);
             } catch (PathNotFoundException pnfe) {
                 // parent does not exist, throw exception
                 throw new AccessControlException(REMOVE_ACTION);
@@ -517,7 +546,7 @@
                 log.warn(msg, mpe);
                 throw new AccessControlException(REMOVE_ACTION);
             } catch (RepositoryException re) {
-                String msg = "failed to check WRITE permission on parent of " + absPath;
+                String msg = "failed to check REMOVE permission on " + absPath;
                 log.warn(msg, re);
                 throw new AccessControlException(REMOVE_ACTION);
             }
@@ -1012,6 +1041,13 @@
             }
             loginContext = null;
         }
+
+        try {
+            accessMgr.close();
+        } catch (Exception e) {
+            log.warn("error while closing AccessManager", e);
+        }
+
         // finally notify listeners that session has been closed
         notifyLoggedOut();
     }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SystemSession.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SystemSession.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SystemSession.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SystemSession.java Wed Mar  2 09:18:13 2005
@@ -17,8 +17,8 @@
 package org.apache.jackrabbit.core;
 
 import org.apache.jackrabbit.core.config.WorkspaceConfig;
+import org.apache.jackrabbit.core.security.AMContext;
 import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.core.security.SimpleAccessManager;
 import org.apache.jackrabbit.core.security.SystemPrincipal;
 import org.apache.log4j.Logger;
 
@@ -72,18 +72,24 @@
      * Overridden in order to create custom access manager
      *
      * @return access manager
+     * @throws RepositoryException
      */
     protected AccessManager createAccessManager(Subject subject,
-                                                HierarchyManager hierMgr) {
-        //return new SystemAccessManager(subject, hierMgr);
-        return super.createAccessManager(subject, hierMgr);
+                                                HierarchyManager hierMgr)
+            throws RepositoryException {
+        /**
+         * use own AccessManager implementation rather than relying on
+         * configurable AccessManager to handle SystemPrincipal privileges
+         * correctly
+         */
+        return new SystemAccessManager();
+        //return super.createAccessManager(subject, hierMgr);
     }
 
     //--------------------------------------------------------< inner classes >
-    private class SystemAccessManager extends SimpleAccessManager {
+    private class SystemAccessManager implements AccessManager {
 
-        SystemAccessManager(Subject subject, HierarchyManager hierMgr) {
-            super(subject, hierMgr);
+        SystemAccessManager() {
         }
 
         //----------------------------------------------------< AccessManager >
@@ -103,6 +109,20 @@
                 throws ItemNotFoundException, RepositoryException {
             // allow everything
             return true;
+        }
+
+        /**
+         * @see AccessManager#init(AMContext)
+         */
+        public void init(AMContext context) throws Exception {
+            // nop
+        }
+
+        /**
+         * @see AccessManager#close()
+         */
+        public void close() throws Exception {
+            // nop
         }
     }
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java Wed Mar  2 09:18:13 2005
@@ -451,7 +451,7 @@
             if (!accessMgr.isGranted(targetState.getId(), AccessManager.READ)) {
                 throw new PathNotFoundException(hierMgr.safeGetJCRPath(nodePath));
             }
-            if (!accessMgr.isGranted(parentState.getId(), AccessManager.WRITE)) {
+            if (!accessMgr.isGranted(targetState.getId(), AccessManager.REMOVE)) {
                 throw new AccessDeniedException(hierMgr.safeGetJCRPath(parentPath) + ": not allowed to remove node");
             }
         } catch (ItemNotFoundException infe) {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AbstractConfig.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AbstractConfig.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AbstractConfig.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AbstractConfig.java Wed Mar  2 09:18:13 2005
@@ -132,7 +132,7 @@
         return s;
     }
 
-    //------------------------------------------------------< EntityResolver >
+    //-------------------------------------------------------< EntityResolver >
     /**
      * @see EntityResolver#resolveEntity(String, String)
      */

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java?view=auto&rev=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java Wed Mar  2 09:18:13 2005
@@ -0,0 +1,90 @@
+/*
+ * 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.jdom.Element;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A <code>AccessManagerConfig</code> represents the configuration of an
+ * <code>AccessManager</code>.
+ *
+ * @see RepositoryConfig#getAccessManagerConfig()
+ */
+public class AccessManagerConfig {
+
+    private static final String CLASS_ATTRIB = "class";
+
+    /**
+     * FQN of class implementing the <code>AccessManager</code> interface
+     */
+    private final String className;
+
+    /**
+     * Parameters for configuring the persistence manager.
+     */
+    private final Map params;
+
+    /**
+     * Creates a new <code>PersistenceManagerConfig</code>.
+     *
+     * @param config the config root element for this <code>PersistenceManagerConfig</code>.
+     * @param vars   map of variable values.
+     */
+    AccessManagerConfig(Element config, Map vars) {
+        // FQN of persistence manager class
+        className = config.getAttributeValue(CLASS_ATTRIB);
+
+        // read the PersistenceManager properties from the
+        // <param/> elements in the config
+        Map params = new HashMap();
+        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));
+        }
+        this.params = Collections.unmodifiableMap(params);
+    }
+
+    /**
+     * Returns configuration parameters. Each entry in the map represents
+     * a name/value pair where both name and value are <code>String</code>s.
+     *
+     * @return Map of configuration parameters.
+     */
+    public Map getParameters() {
+        return params;
+    }
+
+    /**
+     * Returns the FQN of a class implementing the <code>PersistenceManager</code> interface
+     *
+     * @return FQN of persistence manager class
+     */
+    public String getClassName() {
+        return className;
+    }
+
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/config/AccessManagerConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

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&r1=155929&r2=155930
==============================================================================
--- 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 Wed Mar  2 09:18:13 2005
@@ -49,6 +49,10 @@
      */
     public static final String PUBLIC_ID = "-//The Apache Software Foundation//DTD Repository//EN";
 
+    private static final String SECURITY_ELEMENT = "Security";
+    private static final String APP_NAME_ATTRIB = "appName";
+    private static final String ACCESS_MANAGER_ELEMENT = "AccessManager";
+
     private static final String WORKSPACES_ELEMENT = "Workspaces";
     private static final String ROOT_PATH_ATTRIB = "rootPath";
     private static final String DEFAULT_WORKSPACE_ATTRIB = "defaultWorkspace";
@@ -84,6 +88,11 @@
     private FileSystem repFS;
 
     /**
+     * the name of the JAAS configuration app-entry for this repository 
+     */
+    private String appName;
+
+    /**
      * workspaces config root directory (i.e. folder that contains
      * a subfolder with a workspace configuration file for every workspace
      * in the repository)
@@ -96,6 +105,11 @@
     private String defaultWspName;
 
     /**
+     * configuration for the access manager
+     */
+    private AccessManagerConfig amConfig;
+
+    /**
      * the versioning config
      */
     private VersioningConfig vConfig;
@@ -130,6 +144,12 @@
         Element fsConfig = config.getRootElement().getChild(FILE_SYSTEM_ELEMENT);
         repFS = createFileSystem(fsConfig, vars);
 
+        // security & access manager config
+        Element secEleme = config.getRootElement().getChild(SECURITY_ELEMENT);
+        appName = secEleme.getAttributeValue(APP_NAME_ATTRIB);
+        Element amElem = secEleme.getChild(ACCESS_MANAGER_ELEMENT);
+        amConfig = new AccessManagerConfig(amElem, vars);
+
         // workspaces
         Element wspsElem = config.getRootElement().getChild(WORKSPACES_ELEMENT);
         wspConfigRootDir = replaceVars(wspsElem.getAttributeValue(ROOT_PATH_ATTRIB), vars);
@@ -231,6 +251,15 @@
     }
 
     /**
+     * Returns the name of the JAAS configuration app-entry for this repository.
+     *
+     * @return the name of the JAAS configuration app-entry for this repository
+     */
+    public String getAppName() {
+        return appName;
+    }
+
+    /**
      * Returns workspaces config root directory (i.e. the folder that contains
      * a subfolder with a workspace configuration file for every workspace
      * in the repository).
@@ -272,19 +301,29 @@
 
     /**
      * Returns the configuration for the versioning
-     * @return
+     *
+     * @return a <code>VersioningConfig</code> object
      */
     public VersioningConfig getVersioningConfig() {
         return vConfig;
     }
 
     /**
+     * Returns the access manager configuration
+     *
+     * @return an <code>AccessManagerConfig</code> object
+     */
+    public AccessManagerConfig getAccessManagerConfig() {
+        return amConfig;
+    }
+
+    /**
      * Creates a new workspace configuration with the specified name.
      *
      * @param name workspace name
+     * @return a new <code>WorkspaceConfig</code> object.
      * @throws RepositoryException if the specified name already exists or
      *                             if an error occured during the creation.
-     * @return a new <code>WorkspaceConfig</code> object.
      */
     public synchronized WorkspaceConfig createWorkspaceConfig(String name) throws RepositoryException {
         if (wspConfigs.containsKey(name)) {
@@ -335,7 +374,7 @@
         return wspConfig;
     }
 
-    //------------------------------------------------------< EntityResolver >
+    //-------------------------------------------------------< EntityResolver >
     /**
      * @see org.xml.sax.EntityResolver#resolveEntity(String, String)
      */

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java Wed Mar  2 09:18:13 2005
@@ -25,7 +25,11 @@
 import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
 
 /**
  * An <code>EffectiveNodeType</code> represents one or more
@@ -40,7 +44,7 @@
     // node type registry
     private final NodeTypeRegistry ntReg;
 
-    // list of exlicitly aggregated {i.e. merged) node types
+    // list of explicitly aggregated {i.e. merged) node types
     private final TreeSet mergedNodeTypes;
     // list of implicitly aggregated {through inheritance) node types
     private final TreeSet inheritedNodeTypes;

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java?view=auto&rev=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java Wed Mar  2 09:18:13 2005
@@ -0,0 +1,107 @@
+/*
+ * 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.security;
+
+import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.fs.FileSystem;
+
+import javax.security.auth.Subject;
+import java.io.File;
+
+/**
+ * An <code>AMContext</code> is used to provide context information for an
+ * <code>AccessManager</code>.
+ *
+ * @see AccessManager#init(AMContext)
+ */
+public class AMContext {
+
+    /**
+     * the physcial home dir
+     */
+    private final File physicalHomeDir;
+
+    /**
+     * the virtual jackrabbit filesystem
+     */
+    private final FileSystem fs;
+
+    /**
+     * Subject whose access rights the access manager should reflect
+     */
+    private final Subject subject;
+
+    /**
+     * hierarchy manager for resolving ItemId-to-Path mapping
+     */
+    private final HierarchyManager hierMgr;
+
+    /**
+     * Creates a new <code>AMContext</code>.
+     *
+     * @param homeDir the physical home directory
+     * @param fs      the virtual jackrabbit filesystem
+     * @param subject subject whose access rights should be reflected
+     * @param hierMgr hierarchy manager
+     */
+    public AMContext(File homeDir,
+                     FileSystem fs,
+                     Subject subject,
+                     HierarchyManager hierMgr) {
+        this.physicalHomeDir = homeDir;
+        this.fs = fs;
+        this.subject = subject;
+        this.hierMgr = hierMgr;
+    }
+
+
+    /**
+     * Returns the physical home directory
+     *
+     * @return the physical home directory
+     */
+    public File getHomeDir() {
+        return physicalHomeDir;
+    }
+
+    /**
+     * Returns the virtual filesystem
+     *
+     * @return the virtual filesystem
+     */
+    public FileSystem getFileSystem() {
+        return fs;
+    }
+
+    /**
+     * Returns the subject
+     *
+     * @return the subject
+     */
+    public Subject getSubject() {
+        return subject;
+    }
+
+    /**
+     * Returns the hierarchy manager
+     *
+     * @return the hierarchy manager
+     */
+    public HierarchyManager getHierarchyManager() {
+        return hierMgr;
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AMContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AccessManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AccessManager.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AccessManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/AccessManager.java Wed Mar  2 09:18:13 2005
@@ -19,8 +19,8 @@
 import org.apache.jackrabbit.core.ItemId;
 
 import javax.jcr.AccessDeniedException;
-import javax.jcr.RepositoryException;
 import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
 
 /**
  * The <code>AccessManager</code> can be queried to determines whether permission
@@ -28,26 +28,50 @@
  */
 public interface AccessManager {
 
-    /** READ permission constant */
+    /**
+     * READ permission constant
+     */
     public static final int READ = 1;
-    /** WRITE permission constant */
+    /**
+     * WRITE permission constant
+     */
     public static final int WRITE = 2;
+    /**
+     * REMOVE permission constant
+     */
+    public static final int REMOVE = 4;
+
+    /**
+     * Initialize this access manager.
+     *
+     * @param context access manager context
+     * @throws Exception if an error occurs
+     */
+    public void init(AMContext context) throws Exception;
+
+    /**
+     * Close this access manager. After having closed an access manager,
+     * further operations on this object are treated as illegal and throw
+     *
+     * @throws Exception if an error occurs
+     */
+    public void close() throws Exception;
 
     /**
      * Determines whether the specified <code>permissions</code> are granted
      * on the item with the specified <code>id</code> (i.e. the <i>target</i> item).
      *
-     * @param id the id of the target item
+     * @param id          the id of the target item
      * @param permissions A combination of one or more of the following constants
-     * encoded as a bitmask value:
-     * <ul>
-     * <li><code>READ</code></li>
-     * <li><code>WRITE</code></li>
-     * </ul>
-     *
+     *                    encoded as a bitmask value:
+     *                    <ul>
+     *                    <li><code>READ</code></li>
+     *                    <li><code>WRITE</code></li>
+     *                    <li><code>REMOVE</code></li>
+     *                    </ul>
      * @throws AccessDeniedException if permission is denied
      * @throws ItemNotFoundException if the target item does not exist
-     * @throws RepositoryException it an error occurs
+     * @throws RepositoryException   it an error occurs
      */
     public void checkPermission(ItemId id, int permissions)
             throws AccessDeniedException, ItemNotFoundException, RepositoryException;
@@ -56,11 +80,17 @@
      * Determines whether the specified <code>permissions</code> are granted
      * on the item with the specified <code>id</code> (i.e. the <i>target</i> item).
      *
-     * @param id the id of the target item
+     * @param id          the id of the target item
      * @param permissions A combination of one or more of the following constants
+     *                    encoded as a bitmask value:
+     *                    <ul>
+     *                    <li><code>READ</code></li>
+     *                    <li><code>WRITE</code></li>
+     *                    <li><code>REMOVE</code></li>
+     *                    </ul>
      * @return <code>true</code> if permission is granted; otherwise <code>false</code>
      * @throws ItemNotFoundException if the target item does not exist
-     * @throws RepositoryException it an error occurs
+     * @throws RepositoryException   it an error occurs
      */
     public boolean isGranted(ItemId id, int permissions)
             throws ItemNotFoundException, RepositoryException;

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/SimpleAccessManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/SimpleAccessManager.java?view=diff&r1=155929&r2=155930
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/SimpleAccessManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/security/SimpleAccessManager.java Wed Mar  2 09:18:13 2005
@@ -35,42 +35,72 @@
     /**
      * Subject whose access rights this AccessManager should reflect
      */
-    protected final Subject subject;
+    protected Subject subject;
 
     /**
      * hierarchy manager used for ACL-based access control model
      */
-    protected final HierarchyManager hierMgr;
+    protected HierarchyManager hierMgr;
 
-    protected final boolean system;
-    protected final boolean anonymous;
+    private boolean initialized;
 
+    protected boolean system;
+    protected boolean anonymous;
+
+    /**
+     * Empty constructor
+     */
+    public SimpleAccessManager() {
+        initialized = false;
+        anonymous = false;
+        system = false;
+    }
+
+    //--------------------------------------------------------< AccessManager >
     /**
-     * Constructor
-     *
-     * @param subject
-     * @param hierMgr
+     * @see AccessManager#init(AMContext)
      */
-    public SimpleAccessManager(Subject subject, HierarchyManager hierMgr) {
-        this.subject = subject;
-        this.hierMgr = hierMgr;
+    public void init(AMContext context) throws Exception {
+        if (initialized) {
+            throw new IllegalStateException("already initialized");
+        }
+
+        subject = context.getSubject();
+        hierMgr = context.getHierarchyManager();
         anonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
         system = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
+
+        initialized = true;
+    }
+
+    /**
+     * @see AccessManager#close
+     */
+    public synchronized void close() throws Exception {
+        if (!initialized) {
+            throw new IllegalStateException("not initialized");
+        }
+
+        initialized = false;
     }
 
-    //--------------------------------------------------------< AccessManager >
     /**
      * @see AccessManager#checkPermission(ItemId, int)
      */
     public void checkPermission(ItemId id, int permissions)
             throws AccessDeniedException, ItemNotFoundException,
             RepositoryException {
+        if (!initialized) {
+            throw new IllegalStateException("not initialized");
+        }
+
         if (system) {
             // system has always all permissions
             return;
         } else if (anonymous) {
-            // anonymous is always denied WRITE premission
-            if ((permissions & WRITE) == WRITE) {
+            // anonymous is always denied WRITE & REMOVE premissions
+            if ((permissions & WRITE) == WRITE ||
+                    (permissions & REMOVE) == REMOVE) {
                 throw new AccessDeniedException();
             }
         }
@@ -82,12 +112,17 @@
      */
     public boolean isGranted(ItemId id, int permissions)
             throws ItemNotFoundException, RepositoryException {
+        if (!initialized) {
+            throw new IllegalStateException("not initialized");
+        }
+
         if (system) {
             // system has always all permissions
             return true;
         } else if (anonymous) {
-            // anonymous is always denied WRITE premission
-            if ((permissions & WRITE) == WRITE) {
+            // anonymous is always denied WRITE & REMOVE premissions
+            if ((permissions & WRITE) == WRITE ||
+                    (permissions & REMOVE) == REMOVE) {
                 return false;
             }
         }



Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi marcel

Marcel Reutegger wrote:
> Hi Edgar,
> 
> Edgar Poce wrote:
> 
>> I'm planning to make a ChainedPersistence and a ChainedFileSystem 
>> manager, both implementing the chain of responsibility pattern.
> 
> 
> that's an interesting idea. I was recently thinking about a stacked 
> persistence manager (PM) that uses a persistent PM and has an in memory 
> PM on top of it. the use case behind that is to run jackrabbit off a 
> read-only filesystem but still being able to perform write operations.
> 
>> The general idea is to wrap the PersistenceManager in a persistence 
>> handler which delegates the call if a certain condition is satisfied. 
>> Initially, I would need a UriPersistenceHandler and a 
>> NodeTypePersistenceHandler.
>>
>> Is there any plan to include this feature in the short term? Is it a 
>> good approach?
> 
> 
> We didn't discuss such a feature specifically, but I think it would make 
> an interesting contribution, that we might move to the core sometime.
> 

I meant to ask if a similar work was in progress just to don't start 
something that will be available in a short term. It was not my 
intention to ask whether my implementation would be eligible. I read my 
mail again and I realized I wasn't clear.

> cheers
>  marcel
> 

regards
edgar

Re: Chained Persistence and Filesystem

Posted by Marcel Reutegger <ma...@gmx.net>.
Hi Edgar,

Edgar Poce wrote:
> I'm planning to make a ChainedPersistence and a ChainedFileSystem 
> manager, both implementing the chain of responsibility pattern.

that's an interesting idea. I was recently thinking about a stacked 
persistence manager (PM) that uses a persistent PM and has an in memory 
PM on top of it. the use case behind that is to run jackrabbit off a 
read-only filesystem but still being able to perform write operations.

> The general idea is to wrap the PersistenceManager in a persistence 
> handler which delegates the call if a certain condition is satisfied. 
> Initially, I would need a UriPersistenceHandler and a 
> NodeTypePersistenceHandler.
> 
> Is there any plan to include this feature in the short term? Is it a 
> good approach?

We didn't discuss such a feature specifically, but I think it would make 
an interesting contribution, that we might move to the core sometime.

cheers
  marcel

Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi

  If anyone wants to give it a try, I uploaded a the 
ChainedPersistenceManager to jira. 
http://issues.apache.org/jira/browse/JCR-65
Any feedback is welcome.

regards
edgar

Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
hi david

  I'm sorry I wasn't clear. I'm bussy right now but I'll send you a 
descriptive doc to your personal address in couple of days. It's out of 
topic and I guess many have no interest.

David Nuescheler wrote:
> hi edgar,
> 
> unfortunately, your diagram didnt make it all the way 
> through to me. did anyone else get it? do you
> have an uri?

Sorry, but no uri yet.

> 
> regards,
> david
> 

regards
Edgar


Re: Chained Persistence and Filesystem

Posted by David Nuescheler <da...@gmail.com>.
hi edgar,

unfortunately, your diagram didnt make it all the way 
through to me. did anyone else get it? do you
have an uri?

regards,
david


On Sun, 06 Mar 2005 14:42:55 -0300, Edgar Poce <ed...@gmail.com> wrote:
> Hi david
> 
> David Nuescheler wrote:
> > since i am very interested in making performance
> > improvements to jackrabbits query engine where
> > necessary, i would really be interested in the nature
> > and frequency of your queries, so we have something
> > to base optimization on. do you think you can
> > share details?
> 
> I attach a small diagram (8.5 k).
> 
> Now the only source provider implementation I've got is using jcr to
> cache the query results. It uses JDBC to execute the queries but I'm
> open to jcr if it has a minimal set of tools for running descriptive
> statistics.
> 
> I'm also using JCR in the web app.
> 
> regards
> edgar
> 
> 


-- 
----------------------------------------------------------------------
standardize your content-repository !
                               http://www.jcp.org/en/jsr/detail?id=170
---------------------------------------< david.nuescheler@day.com >---

This message is a private communication. If you are not the intended
recipient, please do not read, copy, or use it, and do not disclose it
to others. Please notify the sender of the delivery error by replying
to this message, and then delete it from your system. Thank you.

The sender does not assume any liability for timely, trouble free,
complete, virus free, secure, error free or uninterrupted arrival of
this e-mail. For verification please request a hard copy version.


mailto:david.nuescheler@day.com
http://www.day.com

David Nuescheler
Chief Technology Officer
Day Software AG
Barfuesserplatz 6 / Postfach
4001 Basel
Switzerland

T  41 61 226 98 98
F  41 61 226 98 97

Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi david

David Nuescheler wrote:
> since i am very interested in making performance
> improvements to jackrabbits query engine where
> necessary, i would really be interested in the nature
> and frequency of your queries, so we have something
> to base optimization on. do you think you can 
> share details?

I attach a small diagram (8.5 k).

Now the only source provider implementation I’ve got is using jcr to 
cache the query results. It uses JDBC to execute the queries but I’m 
open to jcr if it has a minimal set of tools for running descriptive 
statistics.

I’m also using JCR in the web app.

regards
edgar

Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi david

David Nuescheler wrote:
> hi edgar,
> 
> 
>>I'm far (really far) from being a db expert, and I still don't get the
>>big picture of jackrabbit internals, but I think jackrabbit is unable,
>>and probably will allways be, to perform aggregated queries as fast as
>>any of the os or commercial dbs.
> 
> why would that be? the querymanager could be extended
> with an additional query language that does a direct 
> pass-through (i would not necessarily suggest that. in 
> agreement with jukkas statement about trying to avoid 
> relying on the structure of the persistance layer).
> also, i would argue that depending on the nature of the 
> query jackrabbit may have a more adequate index and 
> therefore may easily outperform a classical rdbms.
> 
I didn't see any of these options. It's a little more clear now :). thanks.
I took a look to the jcr searching chapter and I didn't find any 
reference to aggregated functions. A minimal set of functions (avg, 
mean, std, count, min and max among others) would be enough for 
descriptive statistics. And a pluggable mechanism for user defined 
functions would be very useful for more complex calculations. Something 
like udf in mysql. See http://dev.mysql.com/doc/mysql/en/adding-udf.html.
Is this in the scope of jcr?. and, how do I achieve this functionality 
through the jcr api in its current state?.

> you mentioned reporting, in reporting in general 
> performance usually is not so much an issue, since
> in many cases reporting is not done very frequently.
> 
I agree, even in some cases where it's done frecuently. In my project 
I'm using a query handler which is responsible of executing queries. 
Depending on the estimated time it uses synchronous or asynchronous 
strategies, with a single or multiple threads. Query results are 
persisted (here I use jackrabbit too) and will be available for sync 
reporting the next time.

> since i am very interested in making performance
> improvements to jackrabbits query engine where
> necessary, i would really be interested in the nature
> and frequency of your queries, so we have something
> to base optimization on. do you think you can 
> share details?
> 
There are two kind of queries. One for microdata processing (mostly 
async reporting), that's where I need aggregated functions, and another 
for sync reporting. I still don't know the frequency of the queries 
because it's not yet in production and will not be until a few months.
Aggregated queries will include cases ranging from 0 to the entire 
population size by the number of waves. Now I'm handling only one 
household survey with 100k per wave, aproximatly 6 million cases total.
I made a pluggable mechanism for adding source providers and I plan to 
add many more sources, censuses and mainly household surveys.

> jsr-170 specifies persistent queries, which allows
> for substancial optimizations. do you think an 
> extension of the persisent queries could help you
> with respect to performance?
> 
I still don't know, but I will take a look to the jcr doc and the 
jackrabbit implementation and see if it fits my needs. Thanks for the hint.

> regards,
> david
> 

Thank you very much
edgar

Re: Chained Persistence and Filesystem

Posted by David Nuescheler <da...@gmail.com>.
hi edgar,

> I'm far (really far) from being a db expert, and I still don't get the
> big picture of jackrabbit internals, but I think jackrabbit is unable,
> and probably will allways be, to perform aggregated queries as fast as
> any of the os or commercial dbs.
why would that be? the querymanager could be extended
with an additional query language that does a direct 
pass-through (i would not necessarily suggest that. in 
agreement with jukkas statement about trying to avoid 
relying on the structure of the persistance layer).
also, i would argue that depending on the nature of the 
query jackrabbit may have a more adequate index and 
therefore may easily outperform a classical rdbms.

you mentioned reporting, in reporting in general 
performance usually is not so much an issue, since
in many cases reporting is not done very frequently.

since i am very interested in making performance
improvements to jackrabbits query engine where
necessary, i would really be interested in the nature
and frequency of your queries, so we have something
to base optimization on. do you think you can 
share details?

jsr-170 specifies persistent queries, which allows
for substancial optimizations. do you think an 
extension of the persisent queries could help you
with respect to performance?

regards,
david

Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi

Jukka Zitting wrote:
> Hi,
> 
> Edgard Poce wrote:
> 
>>I comment my use case. I'm working with a big amount of data, censuses 
>>and other household surveys. I'd like to store each survey with 
>>jackrabbit, but I'd like/need jackrabbit could share the data with any 
>>statistical processing engine because I don't feel like implementing 
>>statistical algorithms. That's why I need a custom orm pm for 
>>myapp:mysurvey nodetype. What's the best practice?
> 
> 
> There are few best practices yet, but in my opinion you'd better focus
> on doing the integration on top of the JCR API, not below it. Is it
> possible to implement a JCR storage adapter for the statistical
> processing engine you are using? Or alternatively implement an export
> feature that extracts the required data from a JCR content repository.
> 
i think that exporting a 1gb database database is not an option. Besides 
I should write the code to perform the conversion from jcr api to a 
readable db format, I guess it's not so hard but there's no need to do it.

> You can think of the Jackrabbit persistence manager layer as the storage
> layer of an RDBMS implementation. The JCR API is to Jackrabbit what JDBC
> is to an RDBMS. You can use a database to store your data and integrate
> it with your applications using the public API, but you certainly
> wouldn't want to try making your externally stored data visible inside
> the database by writing a custom storage layer implementation... ;-)
> 
I don't fully understand what you said. :(
I want to store, edit, browse, data through the jcr api, and make the 
statistical processing directly from the persistence storage. It would 
be just a read only task, so it shouldn't affect the jackrabbit normal 
behaviour.

I'm far (really far) from being a db expert, and I still don't get the 
big picture of jackrabbit internals, but I think jackrabbit is unable, 
and probably will allways be, to perform aggregated queries as fast as 
any of the os or commercial dbs.

> BR,
> 
> Jukka Zitting
> 
> 
> 
regards
edgar

Re: Chained Persistence and Filesystem

Posted by Jukka Zitting <jz...@yukatan.fi>.
Hi,

Edgard Poce wrote:
> I comment my use case. I'm working with a big amount of data, censuses 
> and other household surveys. I'd like to store each survey with 
> jackrabbit, but I'd like/need jackrabbit could share the data with any 
> statistical processing engine because I don't feel like implementing 
> statistical algorithms. That's why I need a custom orm pm for 
> myapp:mysurvey nodetype. What's the best practice?

There are few best practices yet, but in my opinion you'd better focus
on doing the integration on top of the JCR API, not below it. Is it
possible to implement a JCR storage adapter for the statistical
processing engine you are using? Or alternatively implement an export
feature that extracts the required data from a JCR content repository.

You can think of the Jackrabbit persistence manager layer as the storage
layer of an RDBMS implementation. The JCR API is to Jackrabbit what JDBC
is to an RDBMS. You can use a database to store your data and integrate
it with your applications using the public API, but you certainly
wouldn't want to try making your externally stored data visible inside
the database by writing a custom storage layer implementation... ;-)

BR,

Jukka Zitting



Re: Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi

Stefan Guggisberg wrote:
> hi edgar,
> 
> On Wed, 02 Mar 2005 14:40:12 -0300, Edgar Poce <ed...@gmail.com> wrote:
> 
>>Hi to all
>>
>>I need to store data with many persistence managers, ORMPersistence for
>>some custom node types, XMLPersistence in mem for temp data and
>>XMlPersistence on disk for the rest.
>>
>>I'm planning to make a ChainedPersistence and a ChainedFileSystem
>>manager, both implementing the chain of responsibility pattern.
>>
>>The general idea is to wrap the PersistenceManager in a persistence
>>handler which delegates the call if a certain condition is satisfied.
>>Initially, I would need a UriPersistenceHandler and a
>>NodeTypePersistenceHandler.
> 
> 
> sounds interesting. do you mind sharing your design with us in a 
> few sentences?
> 
see 
http://www.javaworld.com/javaworld/jw-08-2003/jw-0829-designpatterns.html 
figure 2.
Each concrete handler is a PersistenceManager wrapper and delegates the 
call only if certain condition is satisfied. Initially I thought of 
handlers that performs the evaluation based on the uri 
(UriPersistenceHandler), on the node type (NodeTypePersistenceHandler) 
and a DefaultPersistenceHandler which always delegates it.

> 
>>Is there any plan to include this feature in the short term? Is it a
>>good approach?
> 
> 
> i am bit worried about doing fancy stuff in PersistenceManagers 
> in general. let me explain...
> 
> the PersistenceManager interface was never intended as being
> a general SPI that you could implement in order to integrate 
> external datasources with proprietary formats (e.g. a customers 
> database).
> 
> the reason why we abstracted the PersistenceManager interface
> was to leave room for future performance optimizations that 
> would not affect the rest of the implementation (e.g. by storing 
> the raw data in a b-tree based database instead of individual file).
> 
> the PersistenceManager sits at the very bottom layer in
> jackrabbits (not yet existing... :(  system architecture diagram.
> reliability, integrity and performance of the PersistenceManager
> are *crucial* to the overall stability & performance of the repository.
> if e.g. the data that a PersistenceManager is based upon is 
> allowed to change through external means the integrity
> of the repository would be at risk (think of referential integrity/
> node references e.g.).
> 
> therefore, imo, a PersistenceManager  should not be 'intelligent', 
> it should not 'interpret' the data. the only thing it should care about 
> is to efficiently, consistently and reliably store and read the data 
> encapsulated in the passed NodeState & PropertyState objects.
> 
> though it might be feasible to write a custom persistence manager
> to represent existing legacy data in a level-1 (read-only) repository,
> i don't think the same is possible for a level-2 repository and i 
> certainly would not recommend it.
> 
I'm really confused now. Why level 1 and 2 are mutually excluded? I 
thought a level 2 repo should have at least all the features of the 
level 1.

If, as you said, I shouldn't chain persistence managers, if I had a few 
legacy systems I would need a jcr instance for each one?

And if I had a level 2 repo, it would be *only* a level 2 and I 
shouldn't integrate any other source?

I comment my use case. I'm working with a big amount of data, censuses 
and other household surveys. I'd like to store each survey with 
jackrabbit, but I'd like/need jackrabbit could share the data with any 
statistical processing engine because I don't feel like implementing 
statistical algorithms. That's why I need a custom orm pm for 
myapp:mysurvey nodetype. What's the best practice?

> i hope i didn't scare you off, i just wanted to make sure that you are
> fully aware of all potential risk & implications when writing 
> custom persistence managers.
> 
> cheers
> stefan
> 
> 
>>Any feedback is welcome.
>>
>>thanks for your support
>>edgar
>>
>>
> 
> 

thanks
edgar

Re: Chained Persistence and Filesystem

Posted by Stefan Guggisberg <st...@gmail.com>.
hi edgar,

On Wed, 02 Mar 2005 14:40:12 -0300, Edgar Poce <ed...@gmail.com> wrote:
> Hi to all
> 
> I need to store data with many persistence managers, ORMPersistence for
> some custom node types, XMLPersistence in mem for temp data and
> XMlPersistence on disk for the rest.
> 
> I'm planning to make a ChainedPersistence and a ChainedFileSystem
> manager, both implementing the chain of responsibility pattern.
> 
> The general idea is to wrap the PersistenceManager in a persistence
> handler which delegates the call if a certain condition is satisfied.
> Initially, I would need a UriPersistenceHandler and a
> NodeTypePersistenceHandler.

sounds interesting. do you mind sharing your design with us in a 
few sentences?

> 
> Is there any plan to include this feature in the short term? Is it a
> good approach?

i am bit worried about doing fancy stuff in PersistenceManagers 
in general. let me explain...

the PersistenceManager interface was never intended as being
a general SPI that you could implement in order to integrate 
external datasources with proprietary formats (e.g. a customers 
database).

the reason why we abstracted the PersistenceManager interface
was to leave room for future performance optimizations that 
would not affect the rest of the implementation (e.g. by storing 
the raw data in a b-tree based database instead of individual file).

the PersistenceManager sits at the very bottom layer in
jackrabbits (not yet existing... :(  system architecture diagram.
reliability, integrity and performance of the PersistenceManager
are *crucial* to the overall stability & performance of the repository.
if e.g. the data that a PersistenceManager is based upon is 
allowed to change through external means the integrity
of the repository would be at risk (think of referential integrity/
node references e.g.).

therefore, imo, a PersistenceManager  should not be 'intelligent', 
it should not 'interpret' the data. the only thing it should care about 
is to efficiently, consistently and reliably store and read the data 
encapsulated in the passed NodeState & PropertyState objects.

though it might be feasible to write a custom persistence manager
to represent existing legacy data in a level-1 (read-only) repository,
i don't think the same is possible for a level-2 repository and i 
certainly would not recommend it.

i hope i didn't scare you off, i just wanted to make sure that you are
fully aware of all potential risk & implications when writing 
custom persistence managers.

cheers
stefan

> 
> Any feedback is welcome.
> 
> thanks for your support
> edgar
> 
>

Chained Persistence and Filesystem

Posted by Edgar Poce <ed...@gmail.com>.
Hi to all

I need to store data with many persistence managers, ORMPersistence for 
some custom node types, XMLPersistence in mem for temp data and 
XMlPersistence on disk for the rest.

I'm planning to make a ChainedPersistence and a ChainedFileSystem 
manager, both implementing the chain of responsibility pattern.

The general idea is to wrap the PersistenceManager in a persistence 
handler which delegates the call if a certain condition is satisfied. 
Initially, I would need a UriPersistenceHandler and a 
NodeTypePersistenceHandler.

Is there any plan to include this feature in the short term? Is it a 
good approach?

Any feedback is welcome.

thanks for your support
edgar