portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r695783 - /portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java
Date Tue, 16 Sep 2008 09:27:58 GMT
Author: ddam
Date: Tue Sep 16 02:27:57 2008
New Revision: 695783

URL: http://svn.apache.org/viewvc?rev=695783&view=rev
Log:
default synchronizer changes
- don't check for required or read only
- use generic methods for handling associations, for both to->from and from->to relations
- add detection of assocation deletes in external store

Modified:
    portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java

Modified: portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java?rev=695783&r1=695782&r2=695783&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java
(original)
+++ portals/jetspeed-2/portal/branches/security-refactoring/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedPrincipalSynchronizer.java
Tue Sep 16 02:27:57 2008
@@ -17,10 +17,12 @@
 package org.apache.jetspeed.security.spi.impl;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -31,10 +33,16 @@
 import org.apache.jetspeed.security.AttributeRequiredException;
 import org.apache.jetspeed.security.AttributeTypeNotFoundException;
 import org.apache.jetspeed.security.AttributesReadOnlyException;
+import org.apache.jetspeed.security.DependentPrincipalException;
 import org.apache.jetspeed.security.JetspeedPrincipal;
 import org.apache.jetspeed.security.JetspeedPrincipalManager;
 import org.apache.jetspeed.security.JetspeedPrincipalManagerProvider;
 import org.apache.jetspeed.security.JetspeedPrincipalType;
+import org.apache.jetspeed.security.PrincipalAssociationNotAllowedException;
+import org.apache.jetspeed.security.PrincipalAssociationRequiredException;
+import org.apache.jetspeed.security.PrincipalAssociationUnsupportedException;
+import org.apache.jetspeed.security.PrincipalNotFoundException;
+import org.apache.jetspeed.security.PrincipalNotRemovableException;
 import org.apache.jetspeed.security.PrincipalUpdateException;
 import org.apache.jetspeed.security.SecurityAttribute;
 import org.apache.jetspeed.security.SecurityAttributeType;
@@ -47,25 +55,23 @@
 
 /**
  * @author <a href="mailto:ddam@apache.org">Dennis Dam</a>
- * @version $Id$
+ * @version $Id: DefaultJetspeedPrincipalSynchronizer.java 694772 2008-09-12
+ *          18:39:51Z ddam $
  */
-public class DefaultJetspeedPrincipalSynchronizer implements
-        JetspeedPrincipalSynchronizer
+public class DefaultJetspeedPrincipalSynchronizer implements JetspeedPrincipalSynchronizer
 {
 
     private static final Log logger = LogFactory.getLog(DefaultJetspeedPrincipalSynchronizer.class);
-    
+
     JetspeedPrincipalManagerProvider principalManagerProvider;
 
     SecurityEntityManager securityEntityManager;
 
     Collection<String> supportedExternalEntityTypes = Collections.emptyList();
 
-    Collection<SecurityEntityRelationType> supportedExternalEntityRelationTypes = Collections
-            .emptyList();
+    Collection<SecurityEntityRelationType> supportedExternalEntityRelationTypes = Collections.emptyList();
 
-    Map<String, Collection<SecurityEntityRelationType>> entityToRelationTypes
= Collections
-            .emptyMap();
+    Map<String, Collection<SecurityEntityRelationType>> entityToRelationTypes
= Collections.emptyMap();
 
     public void synchronizeAll()
     {
@@ -74,151 +80,246 @@
 
     public void synchronizeUserPrincipal(String name)
     {
-        
-        JetspeedPrincipalManager manager = principalManagerProvider
-                .getManager(principalManagerProvider
-                        .getPrincipalType(JetspeedPrincipalType.USER_TYPE_NAME));
-        if (manager != null)
-        {
-            Collection<String> skipTypes = new ArrayList<String>();
-            skipTypes.add(JetspeedPrincipalType.USER_TYPE_NAME);
-            // TODO do not skip user relations which are required!
-            Collection<SecurityEntityRelationType> userRelations = securityEntityManager.getSupportedEntityRelationTypes(JetspeedPrincipalType.USER_TYPE_NAME);
-            recursiveSynchronizePrincipal(securityEntityManager.getEntity(JetspeedPrincipalType.USER_TYPE_NAME,
name), new SynchronizationState(userRelations));
-        }
+        // don't process relations going towards users to avoid sync'ing huge
+        // amounts of data.
+        // TODO: allow processing of required relations towards users.
+        Collection<String> skipEntities = Arrays.asList(new String[]
+        { JetspeedPrincipalType.USER_TYPE_NAME});
+        recursiveSynchronizePrincipal(securityEntityManager.getEntity(JetspeedPrincipalType.USER_TYPE_NAME,
name), new SynchronizationState(skipEntities));
     }
 
-    public void recursiveSynchronizePrincipal(Entity entity, SynchronizationState syncState)

+    public JetspeedPrincipal recursiveSynchronizePrincipal(Entity entity, SynchronizationState
syncState)
     {
-        JetspeedPrincipal upToDatePrincipal=null;
-        if (entity != null && !syncState.isProcessed(entity)){
+        JetspeedPrincipal updatedPrincipal = null;
+        if (entity != null && !syncState.isProcessed(entity))
+        {
             // mark as processed, to avoid nasty loops
             syncState.setProcessed(entity);
-            
-            Collection<SecurityEntityRelationType> notRequiredRelationTypes=new ArrayList<SecurityEntityRelationType>();
-            for(SecurityEntityRelationType relationTypeForThisPrincipal : entityToRelationTypes.get(entity.getType())){
-                    String fromType = relationTypeForThisPrincipal.getFromEntityType();
-                    String toType = relationTypeForThisPrincipal.getToEntityType();
-                    // check at what side of the relationship this entity represents (from
or to) and check whether
-                    // entities on the other side should be synchronized.Entity entity
-                    if (fromType.equals(entity.getType())){
-                        if (!syncState.isProcessedFrom(relationTypeForThisPrincipal,entity)){
-                            if (isRequiredRelation(relationTypeForThisPrincipal)){
-                                syncState.setProcessedFrom(relationTypeForThisPrincipal,
entity);
-                                Collection<Entity> relatedEntities = securityEntityManager.getRelatedEntitiesTo(entity,
relationTypeForThisPrincipal);
-                                for (Entity relatedEntity : relatedEntities)
-                                {
-                                    // first create/update principal
-                                    recursiveSynchronizePrincipal(relatedEntity, syncState);
-                                    // .. then update associations
-                                    synchronizePrincipalAssocation(relationTypeForThisPrincipal,entity,relatedEntity);
-                                }
-                            } else {
-                                // process relation later: a related principal (related either
indirect or direct) might be 
-                                // dependent on the currently processed entity. So first
update/add the current principal.
-                                notRequiredRelationTypes.add(relationTypeForThisPrincipal);
-                            }
-                        }    
-                        
+
+            // update / create corresponding JetspeedPrincipal first
+            updatedPrincipal = synchronizePrincipalAttributes(entity);
+
+            if (updatedPrincipal != null)
+            {
+                // loop through all relation types for this entity type
+                for (SecurityEntityRelationType relationTypeForThisEntity : entityToRelationTypes.get(entity.getType()))
+                {
+                    // check at what side of the relationship this entity
+                    // represents (from or to) and check whether
+                    // entities on the other side should be synchronized.Entity
+                    // entity
+                    if (relationTypeForThisEntity.getFromEntityType().equals(entity.getType())){
+                        Collection<String> updatedAssociationToNames = synchronizeAddedAssociations(relationTypeForThisEntity,entity,updatedPrincipal,true,syncState);
  
+                        synchronizeRemovedAssociations(updatedAssociationToNames, relationTypeForThisEntity.getRelationType(),
updatedPrincipal, true);
                     }
-                    // the entity can represent *both* sides of the relationship, so synchronize
both ways.
-                    if (toType.equals(entity.getType())){
-                        if (!syncState.isProcessedTo(relationTypeForThisPrincipal,entity)){
-                            Collection<Entity> relatedEntities = securityEntityManager.getRelatedEntitiesTo(entity,
relationTypeForThisPrincipal);
-                            for (Entity relatedEntity : relatedEntities)
-                            {
-                                recursiveSynchronizePrincipal(relatedEntity, syncState);
-                            }
-                        }                            
+                    
+                    // the entity can represent either side or *both* sides of
+                    // the relationship, so synchronize both ways.
+                    if (relationTypeForThisEntity.getToEntityType().equals(entity.getType()))
+                    {
+                        Collection<String> updatedAssociationFromNames = synchronizeAddedAssociations(relationTypeForThisEntity,entity,updatedPrincipal,false,syncState);
  
+                        synchronizeRemovedAssociations(updatedAssociationFromNames, relationTypeForThisEntity.getRelationType(),
updatedPrincipal, false);
                     }
+                }
             }
-                                   
-            synchronizePrincipalAttributes(entity);
-            
-            for(SecurityEntityRelationType relationTypeForThisPrincipal : notRequiredRelationTypes){
-                
+
+        }
+        return updatedPrincipal;
+    }
+
+    protected Collection<String> synchronizeAddedAssociations(SecurityEntityRelationType
relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal, boolean entityIsFromEntity,
SynchronizationState syncState){
+        Collection<String> externalRelatedEntityIds=null;
+        Collection<Entity> relatedEntities = entityIsFromEntity ? 
+                securityEntityManager.getRelatedEntitiesFrom(entity, relationTypeForThisEntity)
:
+                securityEntityManager.getRelatedEntitiesTo(entity, relationTypeForThisEntity);
+        externalRelatedEntityIds = new ArrayList<String>();
+        for (Entity relatedEntity : relatedEntities)
+        {                
+            Entity fromEntity = entityIsFromEntity ? entity : relatedEntity;
+            Entity toEntity = entityIsFromEntity ? relatedEntity : entity ;
+            if (syncState.isRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity))
+            {
+                // first flag the relation as processed to
+                // prevent synchronizing the same relation from
+                // the other side.
+                syncState.setRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity,
entityIsFromEntity);
+                // first create/update principal
+                JetspeedPrincipal relatedPrincipal = recursiveSynchronizePrincipal(relatedEntity,
syncState);
+                // .. then update associations to / from it
+                JetspeedPrincipal fromPrincipal = entityIsFromEntity ? principal : relatedPrincipal;
+                JetspeedPrincipal toPrincipal = entityIsFromEntity ? relatedPrincipal : principal;
+                // does association exist in DB ?
+                if (relatedPrincipal != null && !associationExists(fromPrincipal,
toPrincipal, relationTypeForThisEntity.getRelationType()))
+                {
+                    synchronizeAddedPrincipalAssocation(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType());
+                }
+                externalRelatedEntityIds.add(relatedPrincipal.getName());
             }
         }
+        return externalRelatedEntityIds;
     }
     
-    private boolean isRequiredRelation(SecurityEntityRelationType relationType){
-        return false; // TODO: wait until 
+    protected void synchronizeRemovedAssociations(Collection<String> externalRelatedEntityIds,
String associationName, JetspeedPrincipal principal,
+            boolean isFromPrincipal)
+    {
+        // check whether associations were removed in external store (e.g.
+        // LDAP), but still present in the DB
+        JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(principal.getType());
+        List<? extends JetspeedPrincipal> relatedToPrincipals = null;
+        if (isFromPrincipal)
+        {
+            relatedToPrincipals = principalManager.getAssociatedFrom(principal.getName(),
principal.getType(), associationName);
+        } else
+        {
+            relatedToPrincipals = principalManager.getAssociatedTo(principal.getName(), principal.getType(),
associationName);
+        }
+        for (JetspeedPrincipal relatedPrincipal : relatedToPrincipals)
+        {
+            // check whether principal association still exists
+            if (!externalRelatedEntityIds.contains(relatedPrincipal.getId()))
+            {
+                try
+                {
+                    if (isFromPrincipal)
+                    {
+                        principalManager.removeAssociation(principal, relatedPrincipal, associationName);
+                    } else
+                    {
+                        principalManager.removeAssociation(relatedPrincipal, principal, associationName);
+                    }
+                } catch (PrincipalAssociationRequiredException e)
+                {
+                    if (logger.isErrorEnabled())
+                    {
+                        logger.error("Unexpected PrincipalAssociationRequiredException trying
to remove association during synchronization.", e);
+                    }
+                } catch (PrincipalNotFoundException e)
+                {
+                    if (logger.isErrorEnabled())
+                    {
+                        logger.error("Unexpected PrincipalNotFoundException trying to remove
association during synchronization.", e);
+                    }
+                }
+            }
+        }
     }
-    
-    protected void synchronizePrincipalAssocation(SecurityEntityRelationType relationType,
Entity fromEntity, Entity toEntity){
-        JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(principalManagerProvider.getPrincipalType(fromEntity.getType()));
-        
-        // principalManager.getAssociatedTo(principalToName, to, associationName)
+
+    protected boolean associationExists(JetspeedPrincipal fromPrincipal, JetspeedPrincipal
toPrincipal, String associationName){
+        JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(fromPrincipal.getType());
+        List<String> toPrincipals = principalManager.getAssociatedNamesFrom(fromPrincipal.getName(),
fromPrincipal.getType(), associationName);
+        return toPrincipals.contains(toPrincipal.getName());
     }
     
-    protected void synchronizePrincipalAttributes(Entity entity){ 
-        JetspeedPrincipalManager principalManager = principalManagerProvider
-        .getManager(principalManagerProvider
-                .getPrincipalType(entity.getType()));
-        if (principalManager!=null){
-            JetspeedPrincipal principal = principalManager.getPrincipal(entity.getId());
-            Map<String,Attribute> mappedEntityAttrs = entity.getMappedAttributes();
+    protected void synchronizeAddedPrincipalAssocation(JetspeedPrincipal fromPrincipal, JetspeedPrincipal
toPrincipal, String associationName)
+    {
+        JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(fromPrincipal.getType());
+        try
+        {
+            principalManager.addAssociation(fromPrincipal, toPrincipal, associationName);
+        } catch (PrincipalNotFoundException e)
+        {
+            if (logger.isErrorEnabled())
+            {
+                logger.error("Unexpected PrincipalNotFoundException trying to update principal
association.", e);
+            }
+        } catch (PrincipalAssociationUnsupportedException e)
+        {
+        } catch (PrincipalAssociationNotAllowedException e)
+        {
+            if (logger.isErrorEnabled())
+            {
+                logger.error("Unexpected PrincipalAssociationNotAllowedException trying to
update principal during synchronization.", e);
+            }
+        }
+    }
+
+    protected JetspeedPrincipal synchronizePrincipalAttributes(Entity entity)
+    {
+        JetspeedPrincipal updatedPrincipal = null;
+        JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(principalManagerProvider.getPrincipalType(entity.getType()));
+        if (principalManager != null)
+        {
+            updatedPrincipal = principalManager.getPrincipal(entity.getId());
+            Map<String, Attribute> mappedEntityAttrs = entity.getMappedAttributes();
             Collection<Attribute> attrsToBeUpdated = new ArrayList<Attribute>();
-            if (principal == null){
-                // principal does not exist yet, create it using the Jetspeed principal manager
-                principal = principalManager.newPrincipal(entity.getId(), true);
+            if (updatedPrincipal == null)
+            {
+                // principal does not exist yet, create it using the Jetspeed
+                // principal manager
+                updatedPrincipal = principalManager.newPrincipal(entity.getId(), true);
                 attrsToBeUpdated.addAll(mappedEntityAttrs.values());
-            } else if (!principal.isReadOnly() && principal.isMapped()) {
-                SecurityAttributes principalAttrs = principal.getSecurityAttributes();
-                for (Map.Entry<String,Attribute> entityAttrEntry : mappedEntityAttrs.entrySet()){
+            } else if (updatedPrincipal.isMapped())
+            {
+                SecurityAttributes principalAttrs = updatedPrincipal.getSecurityAttributes();
+                for (Map.Entry<String, Attribute> entityAttrEntry : mappedEntityAttrs.entrySet())
+                {
                     SecurityAttribute principalAttr = principalAttrs.getAttribute(entityAttrEntry.getKey());
                     Attribute entityAttr = entityAttrEntry.getValue();
-                    if (principalAttr!=null){
-                        if (entityAttr.getDefinition().isMultiValue()){
-                            // TODO : multi-valued Principal attrs are not yet supported
-                        } else {
-                            if (!StringUtils.equals(principalAttr.getStringValue(), entityAttr.getValue())){
                               
+                    if (principalAttr != null)
+                    {
+                        if (entityAttr.getDefinition().isMultiValue())
+                        {
+                            // TODO : multi-valued Principal attrs are not yet
+                            // supported
+                        } else
+                        {
+                            if (!StringUtils.equals(principalAttr.getStringValue(), entityAttr.getValue()))
+                            {
                                 attrsToBeUpdated.add(entityAttr);
                             }
                         }
-                    } else {
+                    } else
+                    {
                         attrsToBeUpdated.add(entityAttr);
                     }
                 }
             }
 
-            SecurityAttributes principalAttrs = principal.getSecurityAttributes();
-            Map<String,SecurityAttributeType> securityAttrTypes = principalAttrs.getSecurityAttributeTypes().getAttributeTypeMap();
-            
+            SecurityAttributes principalAttrs = updatedPrincipal.getSecurityAttributes();
+            Map<String, SecurityAttributeType> securityAttrTypes = principalAttrs.getSecurityAttributeTypes().getAttributeTypeMap();
+
             // Step 1. update principal's attributes
-            for (Attribute addedEntityAttr : attrsToBeUpdated ){
-                if (!addedEntityAttr.getDefinition().isMultiValue()){
-                    SecurityAttribute principalAttr = null;                
+            for (Attribute addedEntityAttr : attrsToBeUpdated)
+            {
+                if (!addedEntityAttr.getDefinition().isMultiValue())
+                {
+                    SecurityAttribute principalAttr = null;
                     try
                     {
-                        SecurityAttributeType securityAttrType =  securityAttrTypes.get(addedEntityAttr.getMappedName());
-                        if (securityAttrType!=null && !securityAttrType.isReadOnly()){
-                            principalAttr = principalAttrs.getAttribute(addedEntityAttr.getMappedName(),true);
+                        SecurityAttributeType securityAttrType = securityAttrTypes.get(addedEntityAttr.getMappedName());
+                        if (securityAttrType != null && !securityAttrType.isReadOnly())
+                        {
+                            principalAttr = principalAttrs.getAttribute(addedEntityAttr.getMappedName(),
true);
                         }
                         principalAttr.setStringValue(addedEntityAttr.getValue());
                     } catch (AttributesReadOnlyException e)
                     {
-                        if (logger.isErrorEnabled()){
-                            logger.error("Unexpected read-only exception for attribute "+addedEntityAttr.getMappedName()+".",e);
                       
+                        if (logger.isErrorEnabled())
+                        {
+                            logger.error("Unexpected read-only exception for attribute "
+ addedEntityAttr.getMappedName() + ".", e);
                         }
                     } catch (AttributeTypeNotFoundException e)
                     {
-                        if (logger.isErrorEnabled()){
-                            logger.error("Unexpected missing type exception for attribute
"+addedEntityAttr.getMappedName()+".",e);                        
+                        if (logger.isErrorEnabled())
+                        {
+                            logger.error("Unexpected missing type exception for attribute
" + addedEntityAttr.getMappedName() + ".", e);
                         }
                     }
                 }
             }
-            if (principal.isMapped() && !principal.isReadOnly()){
+            if (updatedPrincipal.isMapped() && !updatedPrincipal.isReadOnly())
+            {
                 boolean updated = (attrsToBeUpdated.size() > 0);
                 // Step 2, check whether attributes should be removed.
-                for (Map.Entry<String,SecurityAttribute> principalAttrEntry : principalAttrs.getAttributeMap().entrySet()
){
+                for (Map.Entry<String, SecurityAttribute> principalAttrEntry : principalAttrs.getAttributeMap().entrySet())
+                {
                     // TODO: check whether this attribute is mapped
-                    if (!mappedEntityAttrs.containsKey(principalAttrEntry.getKey())){
+                    if (!mappedEntityAttrs.containsKey(principalAttrEntry.getKey()))
+                    {
                         try
                         {
                             principalAttrs.removeAttribute(principalAttrEntry.getKey());
-                            updated=true;
+                            updated = true;
                         } catch (AttributesReadOnlyException e)
                         {
                             // TODO Auto-generated catch block
@@ -235,28 +336,33 @@
                     }
                 }
                 // step 3, update synchronized principal
-                if (updated){
+                if (updated)
+                {
                     try
                     {
-                        principalManager.updatePrincipal(principal);
+                        principalManager.updatePrincipal(updatedPrincipal);
                     } catch (PrincipalUpdateException e)
                     {
-                        if (logger.isErrorEnabled()){
-                            logger.error("Could not synchronize principal "+principal.getName()+"
of type "+principal.getType().getName(),e);
+                        if (logger.isErrorEnabled())
+                        {
+                            logger.error("Could not synchronize principal " + updatedPrincipal.getName()
+ " of type " + updatedPrincipal.getType().getName(),
+                                    e);
                         }
                     } catch (Exception e)
                     {
-                        if (logger.isErrorEnabled()){
-                            logger.error("Unexpected exception trying to update principal
during synchronization.",e);
+                        if (logger.isErrorEnabled())
+                        {
+                            logger.error("Unexpected exception trying to update principal
during synchronization.", e);
                         }
-                    } 
+                    }
                 }
             }
 
-        } else {
+        } else
+        {
             // TODO throw proper exception
         }
-        
+        return updatedPrincipal;
     }
 
     public void synchronizePrincipalsByType(String principalTypeName)
@@ -264,88 +370,106 @@
 
     }
 
-    public void setPrincipalManagerProvider(
-            JetspeedPrincipalManagerProvider principalManagerProvider)
+    public void setPrincipalManagerProvider(JetspeedPrincipalManagerProvider principalManagerProvider)
     {
         this.principalManagerProvider = principalManagerProvider;
     }
 
-    public void setSecurityEntityManager(
-            SecurityEntityManager securityEntityManager)
+    public void setSecurityEntityManager(SecurityEntityManager securityEntityManager)
     {
         this.securityEntityManager = securityEntityManager;
-        supportedExternalEntityTypes = securityEntityManager
-                .getSupportedEntityTypes();
-        supportedExternalEntityRelationTypes = securityEntityManager
-                .getSupportedEntityRelationTypes();
+        supportedExternalEntityTypes = securityEntityManager.getSupportedEntityTypes();
+        supportedExternalEntityRelationTypes = securityEntityManager.getSupportedEntityRelationTypes();
         entityToRelationTypes = new HashMap<String, Collection<SecurityEntityRelationType>>();
         for (String entityType : supportedExternalEntityTypes)
         {
-            entityToRelationTypes.put(entityType, securityEntityManager
-                    .getSupportedEntityRelationTypes(entityType));
+            entityToRelationTypes.put(entityType, securityEntityManager.getSupportedEntityRelationTypes(entityType));
         }
     }
-    
-    private class SynchronizationState {
-        
+
+    private class SynchronizationState
+    {
+
         // entity type to processed entity IDs map
-        Map<String, Set<String>> processedEntities=new HashMap<String, Set<String>>();
  
-        // map from relation type to from entity id
-        Map<SecurityEntityRelationType, Collection<String>> processedEntityRelationsFrom
= new HashMap<SecurityEntityRelationType, Collection<String>>();
-        // map from relation type to "to entity id"
-        Map<SecurityEntityRelationType, Collection<String>> processedEntityRelationsTo
= new HashMap<SecurityEntityRelationType, Collection<String>>();
-        // Relations which are not checked: this can be used when updating a user principal
without indirectly updating other users.
-        Collection<SecurityEntityRelationType> skipRelations;
-        
-        SynchronizationState(Collection<SecurityEntityRelationType> skipRelations){
-            this.skipRelations=skipRelations;
+        Map<String, Set<String>> processedEntities = new HashMap<String, Set<String>>();
+
+        // map relation type to a "from entity" -> "to entity" mapping
+        Map<SecurityEntityRelationType, Map<String, Collection<String>>>
processedEntityRelationsFromTo = new HashMap<SecurityEntityRelationType, Map<String,
Collection<String>>>();
+
+        // Entity types which are not processed
+        // This is implemented as not following relations towards entities of
+        // these types. E.g. if skipEntities contains the "user" type, and
+        // isProcessedFromTo(..) is invoked,
+        // where the toEntity is of type "user", then the result of
+        // isProcessedFromTo will be "true", to effectively skip the processing
+        // of entities of type "user".
+        // The same goes for isProcessedToFrom(..) : if the type of fromEntity
+        // is "user", the relation is flagged as processed.
+        Collection<String> skipEntities;
+
+        SynchronizationState(Collection<String> skipEntities)
+        {
+            this.skipEntities = skipEntities;
         }
-        
-        public boolean isProcessed(Entity entity){
+
+        public boolean isProcessed(Entity entity)
+        {
             Set<String> processedEntitiesByType = processedEntities.get(entity.getType());
             return processedEntitiesByType != null && processedEntitiesByType.contains(entity.getId());
         }
 
-        public void setProcessed(Entity entity){
+        public void setProcessed(Entity entity)
+        {
             Set<String> processedEntitiesByType = processedEntities.get(entity.getType());
-            if (processedEntitiesByType==null){
-                processedEntitiesByType=new HashSet<String>();                
+            if (processedEntitiesByType == null)
+            {
+                processedEntitiesByType = new HashSet<String>();
             }
             processedEntitiesByType.add(entity.getId());
         }
-        
-        public boolean isProcessedFrom(SecurityEntityRelationType relationType, Entity fromEntity){
-            if (skipRelations.contains(relationType)){
-                return true; // effectively skip the relation by marking it as processed
+
+        public boolean isRelationProcessed(SecurityEntityRelationType relationType, Entity
startEntity, Entity endEntity, boolean startEntityIsFrom){
+            if (startEntityIsFrom){
+                return isRelationProcessed(relationType, startEntity, endEntity);
+            } else {
+                return isRelationProcessed(relationType, endEntity, startEntity);
             }
-            Collection<String> fromIds = processedEntityRelationsFrom.get(relationType);
-            return fromIds != null && fromIds.contains(fromEntity.getId());
         }
         
-        public boolean isProcessedTo(SecurityEntityRelationType relationType, Entity toEntity){
-            if (skipRelations.contains(relationType)){
-                return true; // effectively skip the relation by marking it as processed
+        public boolean isRelationProcessed(SecurityEntityRelationType relationType, Entity
fromEntity, Entity toEntity)
+        {
+            Map<String, Collection<String>> e2eMap = processedEntityRelationsFromTo.get(relationType);
+            if (e2eMap != null)
+            {
+                Collection<String> endIds = e2eMap.get(fromEntity.getId());
+                return endIds != null && endIds.contains(toEntity.getId());
             }
-            Collection<String> toIds = processedEntityRelationsFrom.get(relationType);
-            return toIds != null && toIds.contains(toEntity.getId());
+            return false;
         }
-        
-        public void setProcessedFrom(SecurityEntityRelationType relationType, Entity fromEntity){
-            Collection<String> fromIds=processedEntityRelationsFrom.get(relationType);
-            if (fromIds==null){
-                fromIds=new ArrayList<String>();
-                processedEntityRelationsFrom.put(relationType,fromIds);
-            }            
-            fromIds.add(fromEntity.getId());
+
+        public void setRelationProcessed(SecurityEntityRelationType relationType, Entity
startEntity, Entity endEntity, boolean startEntityIsFrom){
+            if (startEntityIsFrom){
+                setRelationProcessed(relationType, startEntity, endEntity);
+            } else {
+                setRelationProcessed(relationType, endEntity, startEntity);
+            }
         }
         
-        public void setProcessedTo(SecurityEntityRelationType relationType, Entity toEntity){
-            Collection<String> toIds=processedEntityRelationsTo.get(relationType);
-            if (toIds==null){
-                toIds=new ArrayList<String>();
-                processedEntityRelationsTo.put(relationType,toIds);
-            }            
-            toIds.add(toEntity.getId());
+        public void setRelationProcessed(SecurityEntityRelationType relationType, Entity
fromEntity, Entity toEntity)
+        {
+            Map<String, Collection<String>> e2eMap = processedEntityRelationsFromTo.get(relationType);
+            if (e2eMap == null)
+            {
+                e2eMap = new HashMap<String, Collection<String>>();
+                processedEntityRelationsFromTo.put(relationType, e2eMap);
+            }
+            Collection<String> endIds = e2eMap.get(fromEntity.getId());
+            if (endIds == null)
+            {
+                endIds = new ArrayList<String>();
+                e2eMap.put(fromEntity.getId(), endIds);
+            }
+            endIds.add(toEntity.getId());
         }
 
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message