jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r792142 [12/35] - in /jackrabbit/sandbox/JCR-1456: ./ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-core/ jackrabbit-core/src/main/java/org/apache/jackrab...
Date Wed, 08 Jul 2009 13:57:46 GMT
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java Wed Jul  8 13:57:13 2009
@@ -18,16 +18,12 @@
 
 import org.apache.jackrabbit.core.security.authorization.AbstractAccessControlProvider;
 import org.apache.jackrabbit.core.security.authorization.AccessControlConstants;
-import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.security.authorization.AccessControlEditor;
 import org.apache.jackrabbit.core.security.authorization.CompiledPermissions;
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.security.authorization.AbstractCompiledPermissions;
-import org.apache.jackrabbit.core.security.authorization.AccessControlUtils;
-import org.apache.jackrabbit.core.security.authorization.UnmodifiableAccessControlList;
 import org.apache.jackrabbit.core.security.SecurityConstants;
-import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.ItemImpl;
@@ -39,6 +35,8 @@
 import javax.jcr.security.AccessControlEntry;
 import javax.jcr.security.Privilege;
 import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlException;
+
 import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,7 +48,6 @@
 import javax.jcr.PropertyType;
 import javax.jcr.ValueFactory;
 import javax.jcr.observation.Event;
-import javax.jcr.observation.EventListener;
 import javax.jcr.observation.EventIterator;
 import java.util.Map;
 import java.util.Set;
@@ -70,13 +67,14 @@
     private static Logger log = LoggerFactory.getLogger(ACLProvider.class);
 
     // TODO: add means to show effective-policy to a user.
+    private static final AccessControlPolicy effectivePolicy = EffectivePrincipalBasedPolicy.getInstance();
 
     private ACLEditor editor;
     private NodeImpl acRoot;
 
     //-------------------------------------------------< AccessControlUtils >---
     /**
-     * @see AccessControlUtils#isAcItem(Path)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(Path)
      */
     public boolean isAcItem(Path absPath) throws RepositoryException {
         Path.Element[] elems = absPath.getElements();
@@ -89,7 +87,7 @@
     }
 
     /**
-     * @see AccessControlUtils#isAcItem(ItemImpl)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(ItemImpl)
      */
     public boolean isAcItem(ItemImpl item) throws RepositoryException {
         NodeImpl n = ((item.isNode()) ? (NodeImpl) item : (NodeImpl) item.getParent());
@@ -98,7 +96,7 @@
 
     //----------------------------------------------< AccessControlProvider >---
     /**
-     * @see AccessControlProvider#init(javax.jcr.Session, java.util.Map)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#init(javax.jcr.Session, java.util.Map)
      */
     public void init(Session systemSession, Map configuration) throws RepositoryException {
         super.init(systemSession, configuration);
@@ -125,38 +123,23 @@
 
                 PrincipalManager pMgr = session.getPrincipalManager();
                 AccessControlManager acMgr = session.getAccessControlManager();
+
+                // initial default permissions for the administrators group                
                 Principal administrators;
                 String pName = SecurityConstants.ADMINISTRATORS_NAME;
                 if (pMgr.hasPrincipal(pName)) {
                     administrators = pMgr.getPrincipal(pName);
+                    installDefaultPermissions(administrators,
+                        new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_ALL)},
+                        restrictions, editor);
                 } else {
-                    log.warn("Administrators principal group is missing.");
-                    administrators = new PrincipalImpl(pName);
-                }
-                AccessControlPolicy[] acls = editor.editAccessControlPolicies(administrators);
-                ACLTemplate acl = (ACLTemplate) acls[0];
-                if (acl.isEmpty()) {
-                    log.debug("... Privilege.ALL for administrators principal.");
-                    acl.addEntry(administrators,
-                            new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_ALL)},
-                            true, restrictions);
-                    editor.setPolicy(acl.getPath(), acl);
-                } else {
-                    log.debug("... policy for administrators principal already present.");
+                    log.warn("Administrators principal group is missing -> Not adding default permissions.");
                 }
 
-                Principal everyone = pMgr.getEveryone();
-                acls = editor.editAccessControlPolicies(everyone);
-                acl = (ACLTemplate) acls[0];
-                if (acl.isEmpty()) {
-                    log.debug("... Privilege.READ for everyone principal.");
-                    acl.addEntry(everyone,
-                            new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_READ)},
-                            true, restrictions);
-                    editor.setPolicy(acl.getPath(), acl);
-                } else {
-                    log.debug("... policy for everyone principal already present.");
-                }
+                // initialize default permissions for the everyone group
+                installDefaultPermissions(pMgr.getEveryone(),
+                        new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_READ)},
+                        restrictions, editor);
 
                 session.save();
             } catch (RepositoryException e) {
@@ -166,30 +149,40 @@
         }
     }
 
+    private static void installDefaultPermissions(Principal principal, Privilege[] privs, Map restrictions, AccessControlEditor editor) throws RepositoryException, AccessControlException {
+        AccessControlPolicy[] acls = editor.editAccessControlPolicies(principal);
+        if (acls.length > 0) {
+            ACLTemplate acl = (ACLTemplate) acls[0];
+            if (acl.isEmpty()) {
+                acl.addEntry(principal, privs, true, restrictions);
+                editor.setPolicy(acl.getPath(), acl);
+            } else {
+                log.debug("... policy for principal '"+principal.getName()+"' already present.");
+            }
+        } else {
+            log.debug("... policy for principal  '"+principal.getName()+"'  already present.");
+        }
+    }
+
     /**
-     * @see AccessControlProvider#getEffectivePolicies(Path)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#getEffectivePolicies(Path)
      */
     public AccessControlPolicy[] getEffectivePolicies(Path absPath)
             throws ItemNotFoundException, RepositoryException {
-        /* 
-           TODO review
+        /*
            since the per-node effect of the policies is defined by the
-           rep:nodePath restriction, returning the principal-based
-           policy at 'absPath' probably doesn't reveal what the caller expects.
-           Maybe it would be better not to return an empty array as
-           {@link AccessControlManager#getEffectivePolicies(String)
-           is defined to express a best-effor estimate only.
+           rep:nodePath restriction present with the individual access control
+           entries, returning the principal-based policy at 'absPath' (which for
+           most nodes in the repository isn't available anyway) doesn't
+           provide the desired information.
+           As tmp. solution some default policy is returned indicating.
+           TODO: add proper evalution and return a set of ACLs that take effect on the node at abspath
         */
-        AccessControlPolicy[] tmpls = editor.getPolicies(session.getJCRPath(absPath));
-        AccessControlPolicy[] effectives = new AccessControlPolicy[tmpls.length];
-        for (int i = 0; i < tmpls.length; i++) {
-            effectives[i] = new UnmodifiableAccessControlList((ACLTemplate) tmpls[i]);
-        }
-        return effectives;
+        return new AccessControlPolicy[] {effectivePolicy};
     }
 
     /**
-     * @see AccessControlProvider#getEditor(Session)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#getEditor(Session)
      */
     public AccessControlEditor getEditor(Session editingSession) {
         checkInitialized();
@@ -207,7 +200,7 @@
     }
 
     /**
-     * @see AccessControlProvider#compilePermissions(Set)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#compilePermissions(Set)
      */
     public CompiledPermissions compilePermissions(Set principals) throws RepositoryException {
         checkInitialized();
@@ -221,7 +214,7 @@
     }
 
     /**
-     * @see AccessControlProvider#canAccessRoot(Set)
+     * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#canAccessRoot(Set)
      */
     public boolean canAccessRoot(Set principals) throws RepositoryException {
         checkInitialized();
@@ -311,7 +304,7 @@
 
         //--------------------------------------------------< EventListener >---
         /**
-         * @see EventListener#onEvent(EventIterator)
+         * @see javax.jcr.observation.EventListener#onEvent(EventIterator)
          */
         public synchronized void onEvent(EventIterator events) {
             try {
@@ -324,6 +317,7 @@
                     switch (ev.getType()) {
                         case Event.NODE_ADDED:
                         case Event.NODE_REMOVED:
+                        case Event.NODE_MOVED:
                             reload = acPaths.contains(Text.getRelativeParent(path, 2));
                             break;
                         case Event.PROPERTY_ADDED:
@@ -331,6 +325,7 @@
                         case Event.PROPERTY_REMOVED:
                             reload = acPaths.contains(Text.getRelativeParent(path, 3));
                             break;
+
                         default:
                             // illegal event-type: should never occur. ignore
                             break;
@@ -448,4 +443,18 @@
             return new AbstractCompiledPermissions.Result(allows, denies, allowPrivileges, denyPrivileges);
         }
     }
+
+    /**
+     * Dummy effective policy 
+     */
+    private static final class EffectivePrincipalBasedPolicy implements AccessControlPolicy {
+
+        private static EffectivePrincipalBasedPolicy INSTANCE = new EffectivePrincipalBasedPolicy();
+        private EffectivePrincipalBasedPolicy() {
+        }
+
+        private static EffectivePrincipalBasedPolicy getInstance() {
+            return INSTANCE;
+        }
+    }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java Wed Jul  8 13:57:13 2009
@@ -16,16 +16,11 @@
  */
 package org.apache.jackrabbit.core.security.authorization.principalbased;
 
-import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.AccessControlList;
-import javax.jcr.security.Privilege;
-import javax.jcr.security.AccessControlManager;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.authorization.AccessControlConstants;
 import org.apache.jackrabbit.core.security.authorization.AccessControlEntryImpl;
-import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.slf4j.Logger;
@@ -38,6 +33,10 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
 import java.security.Principal;
 import java.security.acl.Group;
 import java.util.ArrayList;
@@ -48,7 +47,7 @@
 import java.util.Set;
 
 /**
- * Implementation of the {@link JackrabbitAccessControlList} interface that
+ * Implementation of the {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList} interface that
  * is detached from the effective access control content. Consequently, any
  * modifications applied to this ACL only take effect, if the policy gets
  * {@link javax.jcr.security.AccessControlManager#setPolicy(String, javax.jcr.security.AccessControlPolicy) reapplied}
@@ -100,7 +99,7 @@
         if (acNode != null && acNode.hasNode(N_POLICY)) {
             // build the list of policy entries;
             NodeImpl aclNode = acNode.getNode(N_POLICY);
-            AccessControlManager acMgr = ((SessionImpl) aclNode.getSession()).getAccessControlManager();
+            AccessControlManager acMgr = aclNode.getSession().getAccessControlManager();
 
             // loop over all entries in the aclNode for the princ-Principal
             for (NodeIterator aceNodes = aclNode.getNodes(); aceNodes.hasNext();) {
@@ -133,7 +132,8 @@
         } // else: no-node at all or no acl-node present.
     }
 
-    AccessControlEntry createEntry(Principal princ, Privilege[] privileges, boolean allow, Map restrictions) throws RepositoryException {
+    AccessControlEntry createEntry(Principal princ, Privilege[] privileges,
+                                   boolean allow, Map<String, Value> restrictions) throws RepositoryException {
         if (!principal.equals(princ)) {
             throw new AccessControlException("Invalid principal. Expected: " + principal);
         }
@@ -147,13 +147,13 @@
         }
 
         // make sure the nodePath restriction is of type PATH
-        Value v = (Value) restrictions.get(jcrNodePathName);
+        Value v = restrictions.get(jcrNodePathName);
         if (v.getType() != PropertyType.PATH) {
             v = valueFactory.createValue(v.getString(), PropertyType.PATH);
             restrictions.put(jcrNodePathName, v);
         }
         // ... and glob is of type STRING.
-        v = (Value) restrictions.get(jcrGlobName);
+        v = restrictions.get(jcrGlobName);
         if (v != null && v.getType() != PropertyType.STRING) {
             v = valueFactory.createValue(v.getString(), PropertyType.STRING);
             restrictions.put(jcrGlobName, v);
@@ -197,7 +197,7 @@
     }
 
     /**
-     * @see JackrabbitAccessControlList#size()
+     * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlList#size()
      */
     public int size() {
         return entries.size();
@@ -218,7 +218,7 @@
      *   rep:glob      (optional)  value-type: STRING
      * </pre>
      *
-     * @see JackrabbitAccessControlList#addEntry(Principal, Privilege[], boolean, Map)
+     * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlList#addEntry(Principal, Privilege[], boolean, Map)
      */
     public boolean addEntry(Principal principal, Privilege[] privileges,
                             boolean isAllow, Map restrictions)
@@ -242,7 +242,7 @@
 
     //--------------------------------------------------< AccessControlList >---
     /**
-     * @see AccessControlList#getAccessControlEntries()
+     * @see javax.jcr.security.AccessControlList#getAccessControlEntries()
      */
     public AccessControlEntry[] getAccessControlEntries()
             throws RepositoryException {
@@ -250,7 +250,7 @@
     }
 
     /**
-     * @see AccessControlList#addAccessControlEntry(Principal, Privilege[])
+     * @see javax.jcr.security.AccessControlList#addAccessControlEntry(Principal, Privilege[])
      */
     public boolean addAccessControlEntry(Principal principal,
                                          Privilege[] privileges)
@@ -259,7 +259,7 @@
     }
 
     /**
-     * @see AccessControlList#removeAccessControlEntry(AccessControlEntry)
+     * @see javax.jcr.security.AccessControlList#removeAccessControlEntry(AccessControlEntry)
      */
     public void removeAccessControlEntry(AccessControlEntry ace)
             throws AccessControlException, RepositoryException {
@@ -305,12 +305,12 @@
 
     //--------------------------------------------------------------------------
     /**
-     *
+     * The access control entry of a principalbased ACL.
      */
     class Entry extends AccessControlEntryImpl {
 
         /**
-         *
+         * The path of the Node this entry applies to.
          */
         private final String nodePath;
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/EveryonePrincipal.java Wed Jul  8 13:57:13 2009
@@ -27,12 +27,12 @@
     private static final String NAME = "everyone";
     private static final EveryonePrincipal INSTANCE = new EveryonePrincipal();
 
-    private EveryonePrincipal() {}
+    private EveryonePrincipal() { }
 
     public static EveryonePrincipal getInstance() {
         return INSTANCE;
     }
-    
+
     //----------------------------------------------------------< Principal >---
     public String getName() {
         return NAME;

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ItemBasedPrincipal.java Wed Jul  8 13:57:13 2009
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.core.security.principal;
 
 import javax.jcr.RepositoryException;
-import java.security.Principal;
 
 /**
  * <code>ItemBasedPrincipal</code> is a <code>Principal</code> that is

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/PrincipalProvider.java Wed Jul  8 13:57:13 2009
@@ -17,11 +17,9 @@
 package org.apache.jackrabbit.core.security.principal;
 
 import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
-import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 
 import javax.jcr.Session;
 import java.security.Principal;
-import java.security.acl.Group;
 import java.util.Properties;
 
 /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java Wed Jul  8 13:57:13 2009
@@ -59,7 +59,7 @@
     public PrincipalProvider registerProvider(Properties config) throws RepositoryException {
         PrincipalProvider provider = createProvider(config);
         if (provider != null) {
-            synchronized(providers) {
+            synchronized (providers) {
                 providers.put(provider.getClass().getName(), provider);
             }
         } else {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleLoginModule.java Wed Jul  8 13:57:13 2009
@@ -18,7 +18,6 @@
 
 import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
 import org.apache.jackrabbit.core.security.authentication.Authentication;
-import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -85,7 +84,7 @@
      * @return principal or <code>null</code> if the principal provider does
      * not contain a user-principal with the given userID/principal name.
      *
-     * @see AbstractLoginModule#getPrincipal(Credentials) 
+     * @see AbstractLoginModule#getPrincipal(Credentials)
      */
     protected Principal getPrincipal(Credentials credentials) {
         String userId = getUserID(credentials);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleSecurityManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleSecurityManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleSecurityManager.java Wed Jul  8 13:57:13 2009
@@ -110,10 +110,10 @@
         // read the LoginModule configuration
         LoginModuleConfig loginModConf = config.getLoginModuleConfig();
         authCtxProvider = new AuthContextProvider(config.getAppName(), loginModConf);
-        if (authCtxProvider.isJAAS()) {
-            log.info("init: using JAAS LoginModule configuration for " + config.getAppName());
-        } else if (authCtxProvider.isLocal()) {
+        if (authCtxProvider.isLocal()) {
             log.info("init: using Repository LoginModule configuration for " + config.getAppName());
+        } else if (authCtxProvider.isJAAS()) {
+            log.info("init: using JAAS LoginModule configuration for " + config.getAppName());
         } else {
             String msg = "No valid LoginModule configuriation for " + config.getAppName();
             log.error(msg);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java Wed Jul  8 13:57:13 2009
@@ -39,6 +39,7 @@
 import javax.jcr.PropertyIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.PropertyDefinition;
 import java.security.Principal;
@@ -304,8 +305,7 @@
     boolean addToGroup(GroupImpl group) throws RepositoryException {
         try {
             Value[] values;
-            // TODO: replace by weak-refs
-            Value added = getSession().getValueFactory().createValue(group.getNode());
+            Value added = getSession().getValueFactory().createValue(group.getNode(), true);
             NodeImpl node = getNode();
             if (node.hasProperty(P_GROUPS)) {
                 Value[] old = node.getProperty(P_GROUPS).getValues();
@@ -333,7 +333,7 @@
             return false;
         }
 
-        Value toRemove = getSession().getValueFactory().createValue(group.getNode());
+        Value toRemove = getSession().getValueFactory().createValue(group.getNode(), true);
         PropertyImpl property = node.getProperty(P_GROUPS);
         List valList = new ArrayList(Arrays.asList(property.getValues()));
         if (valList.remove(toRemove)) {
@@ -364,10 +364,16 @@
         }
         Value[] refs = node.getProperty(P_GROUPS).getValues();
         for (int i = 0; i < refs.length; i++) {
-            NodeImpl groupNode = (NodeImpl) getSession().getNodeByUUID(refs[i].getString());
-            Group group = GroupImpl.create(groupNode, userManager);
-            if (groups.add(group) && includedIndirect) {
-                ((AuthorizableImpl) group).collectMembership(groups, true);
+            try {
+                NodeImpl groupNode = (NodeImpl) getSession().getNodeByUUID(refs[i].getString());
+                Group group = GroupImpl.create(groupNode, userManager);
+                if (groups.add(group) && includedIndirect) {
+                    ((AuthorizableImpl) group).collectMembership(groups, true);
+                }
+            } catch (ItemNotFoundException e) {
+                // groupNode doesn't exist any more
+                log.warn("Group node referenced by " + getID() + " doesn't exist -> Ignored from membership list.");
+                // TODO: ev. clean up list of group memberships
             }
         }
     }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/GroupImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/GroupImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/GroupImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/GroupImpl.java Wed Jul  8 13:57:13 2009
@@ -45,7 +45,7 @@
 
     private static final Logger log = LoggerFactory.getLogger(GroupImpl.class);
 
-    private Principal principal = null;
+    private Principal principal;
 
     private GroupImpl(NodeImpl node, UserManagerImpl userManager) throws RepositoryException {
         super(node, userManager);
@@ -55,7 +55,7 @@
         if (node == null || !node.isNodeType(NT_REP_GROUP)) {
             throw new IllegalArgumentException();
         }
-        if(!Text.isDescendant(GROUPS_PATH, node.getPath())) {
+        if (!Text.isDescendant(GROUPS_PATH, node.getPath())) {
             throw new IllegalArgumentException("Group has to be within the Group Path");
         }
         return new GroupImpl(node, userManager);
@@ -168,8 +168,7 @@
      * @throws RepositoryException If an error occurs while collecting the members.
      */
     private Collection getMembers(boolean includeIndirect) throws RepositoryException {
-        // TODO: replace by weak-refs
-        PropertyIterator itr = getNode().getReferences();
+        PropertyIterator itr = getNode().getWeakReferences(getSession().getJCRName(P_GROUPS));
         Collection members = new HashSet((int) itr.getSize());
         while (itr.hasNext()) {
             NodeImpl n = (NodeImpl) itr.nextProperty().getParent();
@@ -183,6 +182,10 @@
             } else if (n.isNodeType(NT_REP_USER)) {
                 User user = userManager.createUser(n);
                 members.add(user);
+            } else {
+                // weak-ref property 'rep:groups' that doesn't reside under an
+                // authorizable node -> doesn't represent a member of this group.
+                log.debug("Undefined reference to group '" + getID() + "' -> Not included in member set.");
             }
         }
         return members;

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/IndexNodeResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/IndexNodeResolver.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/IndexNodeResolver.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/IndexNodeResolver.java Wed Jul  8 13:57:13 2009
@@ -118,7 +118,6 @@
     private Query buildQuery(String value, Set props, Name ntName,
                              boolean exact, long maxSize)
             throws RepositoryException {
-        // TODO: include maxSize in query statement.
         StringBuffer stmt = new StringBuffer("/jcr:root");
         stmt.append(getSearchRoot(ntName));
         stmt.append("//element(*,");
@@ -143,6 +142,8 @@
             }
             stmt.append("]");
         }
-        return queryManager.createQuery(stmt.toString(), Query.XPATH);
+        Query q = queryManager.createQuery(stmt.toString(), Query.XPATH);
+        q.setLimit(maxSize);
+        return q;
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/TraversingNodeResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/TraversingNodeResolver.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/TraversingNodeResolver.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/TraversingNodeResolver.java Wed Jul  8 13:57:13 2009
@@ -19,7 +19,6 @@
 
 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
 import org.apache.jackrabbit.core.NodeImpl;
-import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.slf4j.Logger;
@@ -64,11 +63,9 @@
      */
     public Node findNode(Name nodeName, Name ntName) throws RepositoryException {
         String sr = getSearchRoot(ntName);
-        // TODO: remove cast once 283 is released
-        SessionImpl sImpl = (SessionImpl) getSession();
-        if (sImpl.nodeExists(sr)) {
+        if (getSession().nodeExists(sr)) {
             try {
-                Node root = sImpl.getNode(sr);
+                Node root = getSession().getNode(sr);
                 return collectNode(nodeName, ntName, root.getNodes());
             } catch (PathNotFoundException e) {
                 // should not get here
@@ -83,11 +80,9 @@
      */
     public Node findNode(Name propertyName, String value, Name ntName) throws RepositoryException {
         String sr = getSearchRoot(ntName);
-        // TODO: remove cast once 283 is released
-        SessionImpl sImpl = (SessionImpl) getSession();
-        if (sImpl.nodeExists(sr)) {
+        if (getSession().nodeExists(sr)) {
             try {
-                Node root = sImpl.getNode(sr);
+                Node root = getSession().getNode(sr);
                 NodeIterator nodes = collectNodes(value,
                         Collections.singleton(propertyName), ntName,
                         root.getNodes(), true, 1);
@@ -108,11 +103,9 @@
     public NodeIterator findNodes(Set propertyNames, String value, Name ntName,
                                   boolean exact, long maxSize) throws RepositoryException {
         String sr = getSearchRoot(ntName);
-        // TODO: remove cast once 283 is released
-        SessionImpl sImpl = (SessionImpl) getSession();
-        if (sImpl.nodeExists(sr)) {
+        if (getSession().nodeExists(sr)) {
             try {
-                Node root = sImpl.getNode(sr);
+                Node root = getSession().getNode(sr);
                 return collectNodes(value, propertyNames, ntName, root.getNodes(), exact, maxSize);
             } catch (PathNotFoundException e) {
                 // should not get here

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java Wed Jul  8 13:57:13 2009
@@ -27,7 +27,6 @@
 import org.apache.jackrabbit.core.security.authorization.AbstractAccessControlProvider;
 import org.apache.jackrabbit.core.security.authorization.AbstractCompiledPermissions;
 import org.apache.jackrabbit.core.security.authorization.AccessControlEditor;
-import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
 import org.apache.jackrabbit.core.security.authorization.CompiledPermissions;
 import org.apache.jackrabbit.core.security.authorization.NamedAccessControlPolicyImpl;
 import org.apache.jackrabbit.core.security.authorization.Permission;
@@ -109,7 +108,7 @@
     /**
      * Always returns false, since this ac provider does not use content stored
      * in items to evaluate AC information.
-     * 
+     *
      * @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(Path)
      */
     public boolean isAcItem(Path absPath) throws RepositoryException {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java Wed Jul  8 13:57:13 2009
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.core.security.user;
 
-import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Impersonation;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.core.NodeImpl;
@@ -39,8 +38,8 @@
 
     private final String id;
 
-    private Principal principal = null;
-    private Impersonation impersonation = null;
+    private Principal principal;
+    private Impersonation impersonation;
 
     private UserImpl(NodeImpl node, UserManagerImpl userManager) throws RepositoryException {
         super(node, userManager);
@@ -59,14 +58,14 @@
         if (node == null || !node.isNodeType(NT_REP_USER)) {
             throw new IllegalArgumentException();
         }
-        if(!Text.isDescendant(USERS_PATH, node.getPath())) {
+        if (!Text.isDescendant(USERS_PATH, node.getPath())) {
             throw new IllegalArgumentException("User has to be within the User Path");
         }
         return new UserImpl(node, userManager);
     }
 
     /**
-     * 
+     *
      * @param password
      * @return
      * @throws RepositoryException

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java Wed Jul  8 13:57:13 2009
@@ -121,9 +121,8 @@
                     n = (NodeImpl) authItem;
                 }
             }
-        }
-        // another Principal -> search
-        if (n == null) {
+        } else {
+            // another Principal -> search
             String name = principal.getName();
             n = (NodeImpl) authResolver.findNode(P_PRINCIPAL_NAME, name, NT_REP_AUTHORIZABLE);
         }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java Wed Jul  8 13:57:13 2009
@@ -160,6 +160,18 @@
     }
 
     /**
+     * Returns a flag indicating whether a given item state is marked as
+     * modified in this log.
+     *
+     * @param id the id of the item.
+     * @return <code>true</code> if the item state is marked as modified in this
+     *         log; <code>false</code> otherwise.
+     */
+    public boolean isModified(ItemId id) {
+        return modifiedStates.containsKey(id);
+    }
+
+    /**
      * Return a node references object given its id. Returns
      * <code>null</code> if the node reference is not in the modified
      * section.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChildNodeEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChildNodeEntries.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChildNodeEntries.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChildNodeEntries.java Wed Jul  8 13:57:13 2009
@@ -314,7 +314,7 @@
         return result;
     }
 
-    //-------------------------------------------< unmodifiable List view >
+    //-----------------------------------------------< unmodifiable List view >
     public boolean contains(Object o) {
         if (o instanceof ChildNodeEntry) {
             return entries.containsKey(((ChildNodeEntry) o).getId());
@@ -447,7 +447,32 @@
         throw new UnsupportedOperationException();
     }
 
-    //------------------------------------------------< Cloneable support >
+    //-------------------------------------------< java.lang.Object overrides >
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ChildNodeEntries) {
+            ChildNodeEntries other = (ChildNodeEntries) obj;
+            return (nameMap.equals(other.nameMap)
+                    && entries.equals(other.entries)
+                    && shared == other.shared);
+        }
+        return false;
+    }
+
+    /**
+     * Returns zero to satisfy the Object equals/hashCode contract.
+     * This class is mutable and not meant to be used as a hash key.
+     *
+     * @return always zero
+     * @see Object#hashCode()
+     */
+    public int hashCode() {
+        return 0;
+    }
+
+    //----------------------------------------------------< Cloneable support >
 
     /**
      * Returns a shallow copy of this <code>ChildNodeEntries</code> instance;
@@ -502,7 +527,7 @@
         }
     }
 
-    //----------------------------------------------------< inner classes >
+    //--------------------------------------------------------< inner classes >
     class EntriesIterator implements ListIterator {
 
         private final OrderedMapIterator mapIter;

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java Wed Jul  8 13:57:13 2009
@@ -67,13 +67,27 @@
      * @param sharedStateMgr shared state manager
      * @param factory event state collection factory
      */
-    public LocalItemStateManager(SharedItemStateManager sharedStateMgr,
+    protected LocalItemStateManager(SharedItemStateManager sharedStateMgr,
                                  EventStateCollectionFactory factory, ItemStateCacheFactory cacheFactory) {
         cache = new ItemStateReferenceCache(cacheFactory);
         this.sharedStateMgr = sharedStateMgr;
         this.factory = factory;
+    }
 
-        sharedStateMgr.addListener(this);
+    /**
+     * Creates a new {@code LocalItemStateManager} instance and registers it as an {@link ItemStateListener}
+     * with the given {@link SharedItemStateManager}. 
+     * 
+     * @param sharedStateMgr the {@link SharedItemStateManager}
+     * @param factory the {@link EventStateCollectionFactory}
+     * @param cacheFactory the {@link ItemStateCacheFactory}
+     * @return a new {@code LocalItemStateManager} instance
+     */
+    public static LocalItemStateManager createInstance(SharedItemStateManager sharedStateMgr,
+            EventStateCollectionFactory factory, ItemStateCacheFactory cacheFactory) {
+        LocalItemStateManager mgr = new LocalItemStateManager(sharedStateMgr, factory, cacheFactory);
+        sharedStateMgr.addListener(mgr);
+        return mgr;
     }
 
     /**
@@ -411,9 +425,7 @@
                 cache.cache(local);
             }
         }
-        if (local != null) {
-            dispatcher.notifyStateCreated(created);
-        }
+        dispatcher.notifyStateCreated(created);
     }
 
     /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java Wed Jul  8 13:57:13 2009
@@ -23,7 +23,6 @@
 
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Iterator;
 
 /**
  * Internal utility class used for merging concurrent changes that occurred
@@ -98,15 +97,12 @@
                 // child node entries
                 if (!state.getChildNodeEntries().equals(
                         overlayedState.getChildNodeEntries())) {
-                    ArrayList added = new ArrayList();
-                    ArrayList removed = new ArrayList();
+                    ArrayList<ChildNodeEntry> added = new ArrayList<ChildNodeEntry>();
+                    ArrayList<ChildNodeEntry> removed = new ArrayList<ChildNodeEntry>();
 
-                    for (Iterator iter = state.getAddedChildNodeEntries().iterator();
-                         iter.hasNext();) {
-                        ChildNodeEntry cne =
-                                (ChildNodeEntry) iter.next();
+                    for (ChildNodeEntry cne : state.getAddedChildNodeEntries()) {
 
-                        if (context.isAdded(cne.getId())) {
+                        if (context.isAdded(cne.getId()) || context.isModified(cne.getId())) {
                             // a new child node entry has been added to this state;
                             // check for name collisions with other state
                             if (overlayedState.hasChildNodeEntry(cne.getName())) {
@@ -121,30 +117,27 @@
                             }
 
                             added.add(cne);
+                        } else {
+                            // externally added
                         }
                     }
 
-                    for (Iterator iter = state.getRemovedChildNodeEntries().iterator();
-                         iter.hasNext();) {
-                        ChildNodeEntry cne =
-                                (ChildNodeEntry) iter.next();
-                        if (context.isDeleted(cne.getId())) {
+                    for (ChildNodeEntry cne : state.getRemovedChildNodeEntries()) {
+                        if (context.isDeleted(cne.getId()) || context.isModified(cne.getId())) {
                             // a child node entry has been removed from this node state
                             removed.add(cne);
+                        } else {
+                            // externally removed
                         }
                     }
 
                     // copy child node antries from other state and
                     // re-apply changes made on this state
                     state.setChildNodeEntries(overlayedState.getChildNodeEntries());
-                    for (Iterator iter = added.iterator(); iter.hasNext();) {
-                        ChildNodeEntry cne =
-                                (ChildNodeEntry) iter.next();
+                    for (ChildNodeEntry cne : added) {
                         state.addChildNodeEntry(cne.getName(), cne.getId());
                     }
-                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
-                        ChildNodeEntry cne =
-                                (ChildNodeEntry) iter.next();
+                    for (ChildNodeEntry cne : removed) {
                         state.removeChildNodeEntry(cne.getId());
                     }
                 }
@@ -152,29 +145,17 @@
                 // property names
                 if (!state.getPropertyNames().equals(
                         overlayedState.getPropertyNames())) {
-                    HashSet added = new HashSet();
-                    HashSet removed = new HashSet();
+                    HashSet<Name> added = new HashSet<Name>();
+                    HashSet<Name> removed = new HashSet<Name>();
 
-                    for (Iterator iter = state.getAddedPropertyNames().iterator();
-                         iter.hasNext();) {
-                        Name name = (Name) iter.next();
+                    for (Name name : state.getAddedPropertyNames()) {
                         PropertyId propId =
                                 new PropertyId(state.getNodeId(), name);
                         if (context.isAdded(propId)) {
-                            // a new property name has been added to this state;
-                            // check for name collisions
-                            if (overlayedState.hasPropertyName(name)
-                                    || overlayedState.hasChildNodeEntry(name)) {
-                                // conflicting names
-                                return false;
-                            }
-
                             added.add(name);
                         }
                     }
-                    for (Iterator iter = state.getRemovedPropertyNames().iterator();
-                         iter.hasNext();) {
-                        Name name = (Name) iter.next();
+                    for (Name name : state.getRemovedPropertyNames()) {
                         PropertyId propId =
                                 new PropertyId(state.getNodeId(), name);
                         if (context.isDeleted(propId)) {
@@ -186,12 +167,10 @@
                     // copy property names from other and
                     // re-apply changes made on this state
                     state.setPropertyNames(overlayedState.getPropertyNames());
-                    for (Iterator iter = added.iterator(); iter.hasNext();) {
-                        Name name = (Name) iter.next();
+                    for (Name name : added) {
                         state.addPropertyName(name);
                     }
-                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
-                        Name name = (Name) iter.next();
+                    for (Name name : removed) {
                         state.removePropertyName(name);
                     }
                 }
@@ -206,9 +185,13 @@
 
     //-----------------------------------------------------< inner interfaces >
 
+    /**
+     * The context of a modification.
+     */
     static interface MergeContext {
         boolean isAdded(ItemId id);
         boolean isDeleted(ItemId id);
+        boolean isModified(ItemId id);
         boolean allowsSameNameSiblings(NodeId id);
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java Wed Jul  8 13:57:13 2009
@@ -177,12 +177,7 @@
             return getTransientItemState(id);
         }
 
-        // check if there's persistent state for the specified item
-        if (stateMgr.hasItemState(id)) {
-            return stateMgr.getItemState(id);
-        }
-
-        throw new NoSuchItemStateException(id.toString());
+        return stateMgr.getItemState(id);
     }
 
     /**
@@ -383,10 +378,11 @@
      *                                   deleted externally
      * @throws RepositoryException       if another error occurs
      */
-    public Iterator getDescendantTransientItemStates(NodeId parentId)
+    public Iterator<ItemState> getDescendantTransientItemStates(NodeId parentId)
             throws InvalidItemStateException, RepositoryException {
         if (transientStore.isEmpty()) {
-            return Collections.EMPTY_LIST.iterator();
+            List<ItemState> empty = Collections.emptyList();
+            return empty.iterator();
         }
 
         // build ordered collection of descendant transient states
@@ -460,7 +456,8 @@
          * situation
          */
         if (resultIter.getIterators().isEmpty()) {
-            return Collections.EMPTY_LIST.iterator();
+            List<ItemState> empty = Collections.emptyList();
+            return empty.iterator();
         }
         return resultIter;
     }
@@ -473,9 +470,10 @@
      *                 instances to be returned.
      * @return an iterator over descendant transient item state instances in the attic
      */
-    public Iterator getDescendantTransientItemStatesInAttic(NodeId parentId) {
+    public Iterator<ItemState> getDescendantTransientItemStatesInAttic(NodeId parentId) {
         if (atticStore.isEmpty()) {
-            return Collections.EMPTY_LIST.iterator();
+            List<ItemState> empty = Collections.emptyList();
+            return empty.iterator();
         }
 
         // build ordered collection of descendant transient states in attic
@@ -489,9 +487,7 @@
         // the depth is used as array index
         List[] la = new List[10];
         try {
-            Iterator iter = atticStore.values().iterator();
-            while (iter.hasNext()) {
-                ItemState state = (ItemState) iter.next();
+            for (ItemState state : atticStore.values()) {
                 // determine relative depth: > 0 means it's a descendant
                 //int depth = zombieHierMgr.getRelativeDepth(parentId, state.getId());
                 int depth = zombieHierMgr.getShareRelativeDepth(parentId, state.getId());
@@ -534,7 +530,8 @@
          * situation
          */
         if (resultIter.getIterators().isEmpty()) {
-            return Collections.EMPTY_LIST.iterator();
+            List<ItemState> empty = Collections.emptyList();
+            return empty.iterator();
         }
         return resultIter;
     }
@@ -729,16 +726,12 @@
     public void disposeAllTransientItemStates() {
         // dispose item states in transient map & attic
         // (use temp collection to avoid ConcurrentModificationException)
-        Collection tmp = new ArrayList(transientStore.values());
-        Iterator iter = tmp.iterator();
-        while (iter.hasNext()) {
-            ItemState state = (ItemState) iter.next();
+        Collection<ItemState> tmp = new ArrayList<ItemState>(transientStore.values());
+        for (ItemState state : tmp) {
             disposeTransientItemState(state);
         }
-        tmp = new ArrayList(atticStore.values());
-        iter = tmp.iterator();
-        while (iter.hasNext()) {
-            ItemState state = (ItemState) iter.next();
+        tmp = new ArrayList<ItemState>(atticStore.values());
+        for (ItemState state : tmp) {
             disposeTransientItemStateInAttic(state);
         }
     }
@@ -789,9 +782,23 @@
             // local state was created
             ItemState transientState = transientStore.get(created.getId());
             if (transientState != null) {
-                // underlying state has been permanently created
-                transientState.pull();
-                transientState.setStatus(ItemState.STATUS_EXISTING);
+                if (transientState.hasOverlayedState()) {
+                    // underlying state has been permanently created
+                    transientState.pull();
+                    transientState.setStatus(ItemState.STATUS_EXISTING);
+                } else {
+                    // this is a notification from another session
+                    try {
+                        ItemState local = stateMgr.getItemState(created.getId());
+                        transientState.connect(local);
+                        // update mod count
+                        transientState.setModCount(local.getModCount());
+                        transientState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                    } catch (ItemStateException e) {
+                        // something went wrong, mark as stale
+                        transientState.setStatus(ItemState.STATUS_STALE_MODIFIED);
+                    }
+                }
                 visibleState = transientState;
             }
         }
@@ -825,6 +832,12 @@
                                     return atticStore.contains(id);
                                 }
 
+                                public boolean isModified(ItemId id) {
+                                    ItemState is = transientStore.get(id);
+                                    return is != null
+                                            && is.getStatus() == ItemState.STATUS_EXISTING_MODIFIED;
+                                }
+
                                 public boolean allowsSameNameSiblings(NodeId id) {
                                     NodeState ns;
                                     try {
@@ -869,6 +882,13 @@
             if (transientState != null) {
                 transientState.setStatus(ItemState.STATUS_STALE_DESTROYED);
                 visibleState = transientState;
+            } else {
+                // check attic
+                transientState = atticStore.get(destroyed.getId());
+                if (transientState != null) {
+                    atticStore.remove(destroyed.getId());
+                    transientState.onDisposed();
+                }
             }
         }
         dispatcher.notifyStateDestroyed(visibleState);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Wed Jul  8 13:57:13 2009
@@ -39,6 +39,7 @@
 import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.observation.EventState;
 import org.apache.jackrabbit.core.observation.EventStateCollection;
 import org.apache.jackrabbit.core.observation.EventStateCollectionFactory;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
@@ -520,7 +521,7 @@
         /**
          * Map of attributes stored for this update operation.
          */
-        private HashMap attributes;
+        private HashMap<String, Object> attributes;
 
         /**
          * Timestamp when this update was created.
@@ -595,8 +596,8 @@
                  * respective shared item and add the shared items to a
                  * new change log.
                  */
-                for (Iterator iter = local.modifiedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = local.modifiedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     state.connect(getItemState(state.getId()));
                     if (state.isStale()) {
                         boolean merged = false;
@@ -617,6 +618,10 @@
                                             return local.deleted(id);
                                         }
 
+                                        public boolean isModified(ItemId id) {
+                                            return local.isModified(id);
+                                        }
+
                                         public boolean allowsSameNameSiblings(NodeId id) {
                                             NodeState ns;
                                             try {
@@ -648,8 +653,8 @@
 
                     shared.modified(state.getOverlayedState());
                 }
-                for (Iterator iter = local.deletedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = local.deletedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     state.connect(getItemState(state.getId()));
                     if (state.isStale()) {
                         String msg = state.getId() + " has been modified externally";
@@ -658,16 +663,16 @@
                     }
                     shared.deleted(state.getOverlayedState());
                 }
-                for (Iterator iter = local.addedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = local.addedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     state.connect(createInstance(state));
                     shared.added(state.getOverlayedState());
                 }
 
                 // filter out virtual node references for later processing
                 // (see comment above)
-                for (Iterator iter = local.modifiedRefs(); iter.hasNext();) {
-                    NodeReferences refs = (NodeReferences) iter.next();
+                for (Iterator<NodeReferences> iter = local.modifiedRefs(); iter.hasNext();) {
+                    NodeReferences refs = iter.next();
                     boolean virtual = false;
                     NodeId id = refs.getId().getTargetId();
                     for (int i = 0; i < virtualProviders.length; i++) {
@@ -786,24 +791,24 @@
 
                 local.disconnect();
 
-                for (Iterator iter = shared.modifiedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = shared.modifiedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     try {
                         state.copy(loadItemState(state.getId()), false);
                     } catch (ItemStateException e) {
                         state.discard();
                     }
                 }
-                for (Iterator iter = shared.deletedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = shared.deletedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     try {
                         state.copy(loadItemState(state.getId()), false);
                     } catch (ItemStateException e) {
                         state.discard();
                     }
                 }
-                for (Iterator iter = shared.addedStates(); iter.hasNext();) {
-                    ItemState state = (ItemState) iter.next();
+                for (Iterator<ItemState> iter = shared.addedStates(); iter.hasNext();) {
+                    ItemState state = iter.next();
                     state.discard();
                 }
             } finally {
@@ -819,7 +824,7 @@
          */
         public void setAttribute(String name, Object value) {
             if (attributes == null) {
-                attributes = new HashMap();
+                attributes = new HashMap<String, Object>();
             }
             attributes.put(name, value);
         }
@@ -844,7 +849,7 @@
         /**
          * {@inheritDoc}
          */
-        public List getEvents() {
+        public List<EventState> getEvents() {
             return events.getEvents();
         }
 
@@ -872,37 +877,41 @@
          */
         private void updateReferences() throws ItemStateException {
             // process added REFERENCE properties
-            for (Iterator i = local.addedStates(); i.hasNext();) {
-                addReferences((ItemState) i.next());
+            for (Iterator<ItemState> i = local.addedStates(); i.hasNext();) {
+                ItemState state = i.next();
+                if (!state.isNode()) {
+                    // remove refs from the target which have been added externally (JCR-2138)
+                    if (hasItemState(state.getId())) {
+                        removeReferences(getItemState(state.getId()));
+                    }
+                    // add new references to the target
+                    addReferences((PropertyState) state);
+                }
             }
 
             // process modified REFERENCE properties
-            for (Iterator i = local.modifiedStates(); i.hasNext();) {
-                ItemState state = (ItemState) i.next();
+            for (Iterator<ItemState> i = local.modifiedStates(); i.hasNext();) {
+                ItemState state = i.next();
                 if (!state.isNode()) {
                     // remove old references from the target
                     removeReferences(getItemState(state.getId()));
                     // add new references to the target
-                    addReferences(state);
+                    addReferences((PropertyState) state);
                 }
             }
 
             // process removed REFERENCE properties
-            for (Iterator i = local.deletedStates(); i.hasNext();) {
-                removeReferences((ItemState) i.next());
+            for (Iterator<ItemState> i = local.deletedStates(); i.hasNext();) {
+                removeReferences(i.next());
             }
         }
 
-        private void addReferences(ItemState state)
-                throws NoSuchItemStateException, ItemStateException {
-            if (!state.isNode()) {
-                PropertyState property = (PropertyState) state;
-                if (property.getType() == PropertyType.REFERENCE) {
-                    InternalValue[] values = property.getValues();
-                    for (int i = 0; values != null && i < values.length; i++) {
-                        addReference(
-                                property.getPropertyId(), values[i].getUUID());
-                    }
+        private void addReferences(PropertyState property) throws NoSuchItemStateException,
+                ItemStateException {
+            if (property.getType() == PropertyType.REFERENCE) {
+                InternalValue[] values = property.getValues();
+                for (int i = 0; values != null && i < values.length; i++) {
+                    addReference(property.getPropertyId(), values[i].getUUID());
                 }
             }
         }
@@ -979,8 +988,8 @@
                 throws ReferentialIntegrityException, ItemStateException {
 
             // check whether removed referenceable nodes are still being referenced
-            for (Iterator iter = local.deletedStates(); iter.hasNext();) {
-                ItemState state = (ItemState) iter.next();
+            for (Iterator<ItemState> iter = local.deletedStates(); iter.hasNext();) {
+                ItemState state = iter.next();
                 if (state.isNode()) {
                     NodeState node = (NodeState) state;
                     if (isReferenceable(node)) {
@@ -1008,8 +1017,8 @@
             }
 
             // check whether targets of modified node references exist
-            for (Iterator iter = local.modifiedRefs(); iter.hasNext();) {
-                NodeReferences refs = (NodeReferences) iter.next();
+            for (Iterator<NodeReferences> iter = local.modifiedRefs(); iter.hasNext();) {
+                NodeReferences refs = iter.next();
                 NodeId id = refs.getTargetId();
                 // no need to check existence of target if there are no references
                 if (refs.hasReferences()) {
@@ -1037,7 +1046,7 @@
         private boolean isReferenceable(NodeState state) throws ItemStateException {
             // shortcut: check some well known built-in types first
             Name primary = state.getNodeTypeName();
-            Set mixins = state.getMixinTypeNames();
+            Set<Name> mixins = state.getMixinTypeNames();
             if (mixins.contains(NameConstants.MIX_REFERENCEABLE)
                     || mixins.contains(NameConstants.MIX_VERSIONABLE)
                     || primary.equals(NameConstants.NT_RESOURCE)) {
@@ -1167,9 +1176,9 @@
         // Build a copy of the external change log, consisting of shared
         // states we have in our cache. Inform listeners about this
         // change.
-        Iterator modifiedStates = external.modifiedStates();
+        Iterator<ItemState> modifiedStates = external.modifiedStates();
         while (modifiedStates.hasNext()) {
-            ItemState state = (ItemState) modifiedStates.next();
+            ItemState state = modifiedStates.next();
             state = cache.retrieve(state.getId());
             if (state != null) {
                 try {
@@ -1189,9 +1198,9 @@
                 }
             }
         }
-        Iterator deletedStates = external.deletedStates();
+        Iterator<ItemState> deletedStates = external.deletedStates();
         while (deletedStates.hasNext()) {
-            ItemState state = (ItemState) deletedStates.next();
+            ItemState state = deletedStates.next();
             state = cache.retrieve(state.getId());
             if (state != null) {
                 shared.deleted(state);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java Wed Jul  8 13:57:13 2009
@@ -23,7 +23,6 @@
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.util.Collection;
-import java.util.Iterator;
 
 /**
  * Component that holds references to listeners interested in changes to item
@@ -35,13 +34,13 @@
      * Simple item state listeners.
      * A copy on write array list is used so that no synchronization is required.
      */
-    private final Collection listeners = new CopyOnWriteArrayList();
+    private final Collection<WeakReference<ItemStateListener>> listeners = new CopyOnWriteArrayList();
 
     /**
      * Node state listeners
      * A copy on write array list is used so that no synchronization is required.
      */
-    private final transient Collection nsListeners = new CopyOnWriteArrayList();
+    private final transient Collection<WeakReference<NodeStateListener>> nsListeners = new CopyOnWriteArrayList();
 
     /**
      * Add an <code>ItemStateListener</code>.
@@ -49,18 +48,17 @@
      */
     public void addListener(ItemStateListener listener) {
         assert getReference(listeners, listener) == null;
-        listeners.add(new WeakReference(listener));
+        listeners.add(new WeakReference<ItemStateListener>(listener));
 
         if (listener instanceof NodeStateListener) {
-            assert getReference(nsListeners, listener) == null;
-            nsListeners.add(new WeakReference(listener));
+            NodeStateListener nsListener = (NodeStateListener) listener;
+            assert getReference(nsListeners, nsListener) == null;
+            nsListeners.add(new WeakReference<NodeStateListener>(nsListener));
         }
     }
-    
-    private Reference getReference(Collection coll, ItemStateListener listener) {
-        Iterator iter = coll.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
+
+    private <T> Reference<T> getReference(Collection< ? extends Reference<T>> coll, ItemStateListener listener) {
+        for (Reference<T> ref : coll) {
             Object o = ref.get();
             if (o == listener) {
                 return ref;
@@ -88,10 +86,8 @@
      * @param created created state.
      */
     public void notifyStateCreated(ItemState created) {
-        Iterator iter = listeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            ItemStateListener l = (ItemStateListener) ref.get();
+        for (Reference<ItemStateListener> ref : listeners) {
+            ItemStateListener l = ref.get();
             if (l != null) {
                 l.stateCreated(created);
             }
@@ -103,10 +99,8 @@
      * @param modified modified state.
      */
     public void notifyStateModified(ItemState modified) {
-        Iterator iter = listeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            ItemStateListener l = (ItemStateListener) ref.get();
+        for (Reference<ItemStateListener> ref : listeners) {
+            ItemStateListener l = ref.get();
             if (l != null) {
                 l.stateModified(modified);
             }
@@ -118,13 +112,11 @@
      * @param destroyed destroyed state.
      */
     public void notifyStateDestroyed(ItemState destroyed) {
-        Iterator iter = listeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            ItemStateListener l = (ItemStateListener) ref.get();
+        for (Reference<ItemStateListener> ref : listeners) {
+            ItemStateListener l = ref.get();
             if (l != null) {
                 l.stateDestroyed(destroyed);
-            }            
+            }
         }
     }
 
@@ -133,13 +125,11 @@
      * @param discarded discarded state.
      */
     public void notifyStateDiscarded(ItemState discarded) {
-        Iterator iter = listeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            ItemStateListener l = (ItemStateListener) ref.get();
+        for (Reference<ItemStateListener> ref : listeners) {
+            ItemStateListener l = ref.get();
             if (l != null) {
                 l.stateDiscarded(discarded);
-            }               
+            }
         }
     }
 
@@ -151,13 +141,11 @@
      * @param id    id of new node
      */
     public void notifyNodeAdded(NodeState state, Name name, int index, NodeId id) {
-        Iterator iter = nsListeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            NodeStateListener n = (NodeStateListener) ref.get();
+        for (Reference<NodeStateListener> ref : nsListeners) {
+            NodeStateListener n = ref.get();
             if (n != null) {
                 n.nodeAdded(state, name, index, id);
-            }                 
+            }
         }
     }
 
@@ -166,13 +154,11 @@
      * @param state node state that changed
      */
     public void notifyNodesReplaced(NodeState state) {
-        Iterator iter = nsListeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            NodeStateListener n = (NodeStateListener) ref.get();
+        for (Reference<NodeStateListener> ref : nsListeners) {
+            NodeStateListener n = ref.get();
             if (n != null) {
                 n.nodesReplaced(state);
-            }              
+            }
         }
     }
 
@@ -181,13 +167,11 @@
      * @param state node state that changed
      */
     public void notifyNodeModified(NodeState state) {
-        Iterator iter = nsListeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            NodeStateListener n = (NodeStateListener) ref.get();
+        for (Reference<NodeStateListener> ref : nsListeners) {
+            NodeStateListener n = ref.get();
             if (n != null) {
                 n.nodeModified(state);
-            }               
+            }
         }
     }
 
@@ -199,13 +183,11 @@
      * @param id    id of new node
      */
     public void notifyNodeRemoved(NodeState state, Name name, int index, NodeId id) {
-        Iterator iter = nsListeners.iterator();
-        while (iter.hasNext()) {
-            Reference ref = (Reference) iter.next();
-            NodeStateListener n = (NodeStateListener) ref.get();
+        for (Reference<NodeStateListener> ref : nsListeners) {
+            NodeStateListener n = ref.get();
             if (n != null) {
                 n.nodeRemoved(state, name, index, id);
-            }               
+            }
         }
     }
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java Wed Jul  8 13:57:13 2009
@@ -53,7 +53,7 @@
      * on the returned object to make it persistent.
      *
      * @param id           the id of the node
-     * @param nodeTypeName qualified node type name
+     * @param nodeTypeName The node type name
      * @param parentId     parent node's id
      * @return a node state
      * @throws IllegalStateException if the manager is not in edit mode.
@@ -66,7 +66,7 @@
      * i.e. not yet existing state. Call {@link #store}
      * on the returned object to make it persistent.
      *
-     * @param propName   qualified property name
+     * @param propName   property name
      * @param parentId   parent node Id
      * @return a property state
      * @throws IllegalStateException if the manager is not in edit mode.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java Wed Jul  8 13:57:13 2009
@@ -83,30 +83,39 @@
     private VirtualItemStateProvider virtualProvider;
 
     /**
-     * Creates a new instance of this class.
-     *
-     * @param sharedStateMgr shared state manager
-     * @param factory        event state collection factory
-     */
-    public XAItemStateManager(SharedItemStateManager sharedStateMgr,
-                              EventStateCollectionFactory factory, ItemStateCacheFactory cacheFactory) {
-        this(sharedStateMgr, factory, DEFAULT_ATTRIBUTE_NAME, cacheFactory);
-    }
-
-    /**
      * Creates a new instance of this class with a custom attribute name.
      *
      * @param sharedStateMgr shared state manager
      * @param factory        event state collection factory
-     * @param attributeName  attribute name
+     * @param attributeName  the attribute name, if {@code null} then a default name is used
      */
-    public XAItemStateManager(SharedItemStateManager sharedStateMgr,
+    private XAItemStateManager(SharedItemStateManager sharedStateMgr,
                               EventStateCollectionFactory factory,
                               String attributeName,
                               ItemStateCacheFactory cacheFactory) {
         super(sharedStateMgr, factory, cacheFactory);
+        if (attributeName != null) {
+            this.attributeName = attributeName;
+        } else {
+            this.attributeName = DEFAULT_ATTRIBUTE_NAME;
+        }
+    }
 
-        this.attributeName = attributeName;
+    /**
+     * Creates a new {@code XAItemStateManager} instance and registers it as an {@link ItemStateListener}
+     * with the given {@link SharedItemStateManager}. 
+     * 
+     * @param sharedStateMgr the {@link SharedItemStateManager}
+     * @param factory the {@link EventStateCollectionFactory}
+     * @param attributeName the attribute name, if {@code null} then a default name is used
+     * @param cacheFactory the {@link ItemStateCacheFactory}
+     * @return a new {@code XAItemStateManager} instance
+     */
+    public static XAItemStateManager createInstance(SharedItemStateManager sharedStateMgr,
+            EventStateCollectionFactory factory, String attributeName, ItemStateCacheFactory cacheFactory) {
+        XAItemStateManager mgr = new XAItemStateManager(sharedStateMgr, factory, attributeName, cacheFactory);
+        sharedStateMgr.addListener(mgr);
+        return mgr;
     }
 
     /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java Wed Jul  8 13:57:13 2009
@@ -18,13 +18,12 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 
 import javax.jcr.RepositoryException;
+import javax.jcr.Binary;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.data.DataIdentifier;
 
 /**
@@ -37,14 +36,7 @@
  * This interface is for Jackrabbit-internal use only. Applications should
  * use <code>javax.jcr.ValueFactory</code> to create binary values.
  */
-public abstract class BLOBFileValue {
-
-    /**
-     * Returns an InputStream representation of this value.
-     *
-     * @return An InputStream representation of this value.
-     */
-    public abstract InputStream getStream() throws RepositoryException;
+abstract class BLOBFileValue implements Binary {
 
     /**
      * Returns a String representation of this value.
@@ -52,7 +44,7 @@
      * @return String representation of this value.
      * @throws RepositoryException
      */
-    public String getString() throws RepositoryException {
+    String getString() throws RepositoryException {
         // TODO: review again. currently the getString method of the JCR Value is delegated to the QValue.
         InputStream stream = getStream();
         try {
@@ -80,22 +72,13 @@
     }
 
     /**
-     * Returns the length of this <code>BLOBFileValue</code>.
-     *
-     * @return The length, in bytes, of this <code>BLOBFileValue</code>,
-     *         or -1L if the length can't be determined.
-     * @throws IOException
-     */
-    public abstract long getLength();
-
-    /**
      * Frees temporarily allocated resources such as temporary file, buffer, etc.
      * If this <code>BLOBFileValue</code> is backed by a persistent resource
      * calling this method will have no effect.
      *
      * @see #delete(boolean)
      */
-    public abstract void discard();
+    abstract void discard();
 
     /**
      * Deletes the persistent resource backing this <code>BLOBFileValue</code>.
@@ -103,7 +86,7 @@
      * @param pruneEmptyParentDirs if <code>true</code>, empty parent directories
      *                             will automatically be deleted
      */
-    public abstract void delete(boolean pruneEmptyParentDirs);
+    abstract void delete(boolean pruneEmptyParentDirs);
 
     /**
      * Checks if this object is immutable.
@@ -111,56 +94,40 @@
      *
      * @return true if the object is immutable
      */
-    public abstract boolean isImmutable();
+    abstract boolean isImmutable();
 
-    /**
-     * {@inheritDoc}
-     */
     public abstract boolean equals(Object obj);
 
-    /**
-     * {@inheritDoc}
-     */
     public abstract String toString();
 
-    /*
-     * Spools the contents of this <code>BLOBFileValue</code> to the given
-     * output stream.
+    public abstract int hashCode();
+
+    /**
+     * Get the data identifier if one is available.
      *
-     * @param out output stream
-     * @throws RepositoryException if the input stream for this
-     *                             <code>BLOBFileValue</code> could not be obtained
-     * @throws IOException         if an error occurs while while spooling
+     * @return the data identifier or null
      */
-    public void spool(OutputStream out) throws RepositoryException, IOException {
+    DataIdentifier getDataIdentifier() {
+        return null;
+    }
+
+    //-----------------------------------------------------< javax.jcr.Binary >
+    public abstract long getSize();
+
+    public abstract InputStream getStream() throws RepositoryException;
+
+    public int read(byte[] b, long position) throws IOException, RepositoryException {
         InputStream in = getStream();
         try {
-            IOUtils.copy(in, out);
+            in.skip(position);
+            return in.read(b);
         } finally {
-            IOUtils.closeQuietly(in);
+            in.close();
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public abstract int hashCode();
-
-    /**
-     * Check if the value is small (contains a low number of bytes) and should
-     * be stored inline.
-     *
-     * @return true if the value is small
-     */
-    public abstract boolean isSmall();
-    
-    /**
-     * Get the data identifier if one is available.
-     * 
-     * @return the data identifier or null
-     */
-    public DataIdentifier getDataIdentifier() {
-        return null;
+    public void dispose() {
+        discard();
     }
 
 }



Mime
View raw message