You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by un...@apache.org on 2004/09/17 17:02:02 UTC

cvs commit: jakarta-slide/src/share/org/apache/slide/security ActionsCache.java SecurityImpl.java

unico       2004/09/17 08:02:02

  Modified:    src/share/org/apache/slide/security SecurityImpl.java
  Added:       src/share/org/apache/slide/security ActionsCache.java
  Log:
  share common actions cache between Security helper instances
  (thanks to Johan Stuyts j.stuyts <at> hippo <dot> nl)
  
  Revision  Changes    Path
  1.54      +90 -91    jakarta-slide/src/share/org/apache/slide/security/SecurityImpl.java
  
  Index: SecurityImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/security/SecurityImpl.java,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- SecurityImpl.java	9 Aug 2004 12:05:29 -0000	1.53
  +++ SecurityImpl.java	17 Sep 2004 15:02:02 -0000	1.54
  @@ -121,21 +121,6 @@
       protected int aclInheritanceType;
       
       /**
  -     * Cached all actions exsiting at namespace initialization
  -     * and their aggregated actions
  -     */
  -    private Map actionAggregation;        // actionNode -> Set-of-aggregated-nodes (direct aggregates)
  -    private Map actionAggregationClosure; // actionNode -> Set-of-aggregated-nodes (transitive closure)
  -    
  -    /**
  -     * If during the loading of the actions cache an error occurs, the cache
  -     * state will remain 'not loaded'. To prevent that a new attempt is made to
  -     * load the actions cache (which will probably fail too) each time the
  -     * actions cache is accessed, this flag will be set.
  -     */
  -    private boolean hasActionsCacheLoadingFailed;
  -
  -    /**
        * The actions that can modify objects in the repository. These are used
        * to determine actions cache invalidation.
        */
  @@ -462,13 +447,12 @@
                                   ActionNode action)
           throws ServiceAccessException, AccessDeniedException,
           ObjectNotFoundException {
  -        determineActionsCacheInvalidation(object, action);
  -        
           if (!hasPermission(object, subject, action)) {
               throw new AccessDeniedException(object.getUri(), subject.getUri(),
                                               action.getUri());
           }
  -        
  +
  +        determineActionsCacheInvalidation(object, action);
       }
       
       /**
  @@ -484,12 +468,12 @@
        * @throws   ObjectNotFoundException
        */
       public void checkPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, AccessDeniedException, ObjectNotFoundException {
  -        determineActionsCacheInvalidation(object, action);
  -        
           if (!hasPermission(token, object, action)) {
               throw new AccessDeniedException(object.getUri(), getPrincipal(token).getUri(),
                                               action.getUri());
           }
  +
  +        determineActionsCacheInvalidation(object, action);
       }
       
       
  @@ -1073,9 +1057,9 @@
        * @throws   SlideException
        * @throws   JDOMException
        */
  -    private Set getActionAggregates(ActionNode aNode) throws SlideException, JDOMException {
  +    private static synchronized Set getActionAggregates(SecurityImpl security, ActionNode aNode) throws SlideException, JDOMException {
           Set result = new HashSet();
  -        Uri aNodeUri = namespace.getUri(aNode.getUri());
  +        Uri aNodeUri = security.namespace.getUri(aNode.getUri());
           NodeRevisionDescriptor aNrd = aNodeUri.getStore().retrieveRevisionDescriptor(aNodeUri, new NodeRevisionNumber());
           NodeProperty membersProp = aNrd.getProperty(PRIVILEGE_MEMBER_SET);
           if (membersProp != null && membersProp.getValue() != null) {
  @@ -1086,20 +1070,22 @@
               else {
                   membersVal = new XMLValue((String)membersProp.getValue());
               }
  -            logger.log(membersVal.getHrefStrings(), LOG_CHANNEL, Logger.DEBUG);
  +            security.logger.log(membersVal.getHrefStrings(), LOG_CHANNEL, Logger.DEBUG);
               Iterator mUris = membersVal.getHrefStrings().iterator();
               while (mUris.hasNext()) {
                   String uriAsString = (String)mUris.next();
  -                Uri uri = new Uri(namespace, uriAsString);
  +                Uri uri = new Uri(security.namespace, uriAsString);
                   NodeRevisionNumber latestRevisionNumber = aNodeUri.getStore().retrieveRevisionDescriptors(uri).getLatestRevision();
  -                NodeProperty privilegeNamespace = aNodeUri.getStore().retrieveRevisionDescriptor(uri, latestRevisionNumber).getProperty(PRIVILEGE_NAMESPACE, "DAV:");
  -                org.jdom.Namespace namespace = null;
  -                if (privilegeNamespace != null && privilegeNamespace.getValue() instanceof String) {
  -                    namespace = org.jdom.Namespace.getNamespace((String) privilegeNamespace.getValue());
  -                } else {
  -                    namespace = org.jdom.Namespace.getNamespace("DAV:");
  +                if (latestRevisionNumber != null) {
  +                    NodeProperty privilegeNamespace = aNodeUri.getStore().retrieveRevisionDescriptor(uri, latestRevisionNumber).getProperty(PRIVILEGE_NAMESPACE, "DAV:");
  +                    org.jdom.Namespace namespace = null;
  +                    if (privilegeNamespace != null && privilegeNamespace.getValue() instanceof String) {
  +                        namespace = org.jdom.Namespace.getNamespace((String) privilegeNamespace.getValue());
  +                    } else {
  +                        namespace = org.jdom.Namespace.getNamespace("DAV:");
  +                    }
  +                    result.add(ActionNode.getActionNode(uriAsString, namespace));
                   }
  -                result.add(ActionNode.getActionNode(uriAsString, namespace));
               }
           }
           return result;
  @@ -1119,7 +1105,7 @@
           if (permAction.equals(ActionNode.ALL)) {
               return true;
           }
  -        Map actionAggregationClosure = getActionAggregationClosureImpl(token, checkAction.getUri());
  +        Map actionAggregationClosure = getActionAggregationClosureImpl(this, token, checkAction.getUri());
           Set permActionSet = (Set)actionAggregationClosure.get(permAction);
           if (permActionSet == null) {
               logger.log("Unknown action " + permAction.getUri() , LOG_CHANNEL, Logger.WARNING);
  @@ -1223,7 +1209,7 @@
        */
       public Map getActionAggregation() {
           logger.log("Action aggregation being retrieved", LOG_CHANNEL, Logger.DEBUG);
  -        return Collections.unmodifiableMap(getActionAggregationImpl());
  +        return Collections.unmodifiableMap(getActionAggregationImpl(this));
       }
   
       /**
  @@ -1279,7 +1265,7 @@
                       logger.log("Actions cache invalidated for operation " + action.getUri()
                               + " on action " + object.getUri(), LOG_CHANNEL, Logger.DEBUG);
                   }
  -                invalidateActionsCache();
  +                invalidateActionsCache(this);
               }
           }
       }
  @@ -1288,11 +1274,23 @@
        * Invalidates the actions cache causing it to be reloaded the next time it
        * is needed.
        */
  -    private synchronized void invalidateActionsCache() {
  -        hasActionsCacheLoadingFailed = false;
  -        actionAggregation = null;
  -        actionAggregationClosure = null;
  +    private static synchronized void invalidateActionsCache(SecurityImpl security) {
  +        ActionsCache cache = getActionsCache(security);
  +        cache.invalidate();
       }
  +    
  +    private static synchronized ActionsCache getActionsCache(SecurityImpl security) {
  +        String namespaceName = security.namespace.getName();
  +        ActionsCache result = (ActionsCache)caches.get(namespaceName);
  +        if (result == null)
  +        {
  +            result = new ActionsCache();
  +            caches.put(namespaceName, result);
  +        }
  +        return result;
  +    }
  +    
  +    private static final Map caches = new HashMap();
   
       /**
        * Populate the actions cache.
  @@ -1300,44 +1298,43 @@
        * @param namespace
        * @param namespaceConfig
        */
  -    private synchronized void loadActionsCache(Namespace namespace, NamespaceConfig namespaceConfig) {
  +    private static synchronized void loadActionsCache(SecurityImpl security) {
  +        ActionsCache cache = getActionsCache(security);
           try {
  -            actionAggregation = new HashMap();
  -            actionAggregationClosure = new HashMap();
  -            String actionsPath = namespaceConfig.getActionsPath();
  -            Uri actionsPathUri = namespace.getUri(actionsPath);
  +            cache.aggregation = new HashMap();
  +            cache.aggregationClosure = new HashMap();
  +            String actionsPath = security.namespaceConfig.getActionsPath();
  +            Uri actionsPathUri = security.namespace.getUri(actionsPath);
               ObjectNode actionsPathNode = actionsPathUri.getStore().retrieveObject(actionsPathUri);
               Enumeration actions = actionsPathNode.enumerateChildren();
  -            addActionLeafsToActionAggregation(actions);
  +            addActionLeafsToActionAggregation(security, cache, actions);
   
  -            Iterator keys = actionAggregationClosure.keySet().iterator();
  +            Iterator keys = cache.aggregationClosure.keySet().iterator();
               while (keys.hasNext()) {
                   ActionNode aNode = (ActionNode)keys.next();
  -                Set aClosure = (Set)actionAggregationClosure.get(aNode);
  -                actionAggregationClosure.put(aNode, buildClosure(aClosure));
  +                Set aClosure = (Set)cache.aggregationClosure.get(aNode);
  +                cache.aggregationClosure.put(aNode, buildClosure(cache, aClosure));
               }
               // log success
  -            if (logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) {
  -                logger.log("Action aggregations loaded successfully", LOG_CHANNEL, Logger.DEBUG);
  +            if (security.logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) {
  +                security.logger.log("Action aggregations loaded successfully", LOG_CHANNEL, Logger.DEBUG);
               }
  -            if (logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) {
  -                logger.log("\n@@@ Actions aggregations", LOG_CHANNEL, Logger.DEBUG);
  -                Iterator i = actionAggregation.entrySet().iterator();
  +            if (security.logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) {
  +                security.logger.log("\n@@@ Actions aggregations", LOG_CHANNEL, Logger.DEBUG);
  +                Iterator i = cache.aggregation.entrySet().iterator();
                   while (i.hasNext()) {
  -                    logger.log("  "+i.next(), LOG_CHANNEL, Logger.DEBUG);
  +                    security.logger.log("  "+i.next(), LOG_CHANNEL, Logger.DEBUG);
                   }
  -                logger.log("\n@@@ Action aggregations (transitive closure)", LOG_CHANNEL, Logger.DEBUG);
  -                i = actionAggregationClosure.entrySet().iterator();
  +                security.logger.log("\n@@@ Action aggregations (transitive closure)", LOG_CHANNEL, Logger.DEBUG);
  +                i = cache.aggregationClosure.entrySet().iterator();
                   while (i.hasNext()) {
  -                    logger.log("  "+i.next(), LOG_CHANNEL, Logger.DEBUG);
  +                    security.logger.log("  "+i.next(), LOG_CHANNEL, Logger.DEBUG);
                   }
               }
           }
           catch (Throwable e) {
  -            logger.log(e, LOG_CHANNEL, Logger.DEBUG);
  -            actionAggregation = null;
  -            actionAggregationClosure = null;
  -            hasActionsCacheLoadingFailed = true;
  +            security.logger.log(e, LOG_CHANNEL, Logger.ERROR);
  +            cache.fail();
           }
       }
       
  @@ -1350,21 +1347,21 @@
        * @throws SlideException
        * @throws JDOMException
        */
  -    private synchronized void addActionLeafsToActionAggregation(Enumeration actions) throws SlideException, JDOMException {
  +    private static synchronized void addActionLeafsToActionAggregation(SecurityImpl security, ActionsCache cache, Enumeration actions) throws SlideException, JDOMException {
           while (actions.hasMoreElements()) {
  -            Uri aNodeUri = namespace.getUri((String)actions.nextElement());
  -            ObjectNode oNode = namespace.getStore(aNodeUri.getScope()).retrieveObject(aNodeUri);
  +            Uri aNodeUri = security.namespace.getUri((String)actions.nextElement());
  +            ObjectNode oNode = security.namespace.getStore(aNodeUri.getScope()).retrieveObject(aNodeUri);
               if (oNode.hasChildren()) {
  -                if (logger.isEnabled(Logger.DEBUG)) {
  -                    logger.log("Adding children of action " + oNode.getUri() + " to action aggregation", LOG_CHANNEL, Logger.DEBUG);
  +                if (security.logger.isEnabled(Logger.DEBUG)) {
  +                    security.logger.log("Adding children of action " + oNode.getUri() + " to action aggregation", LOG_CHANNEL, Logger.DEBUG);
                   }
  -                addActionLeafsToActionAggregation(oNode.enumerateChildren());
  +                addActionLeafsToActionAggregation(security, cache, oNode.enumerateChildren());
               } else {
  -                if (logger.isEnabled(Logger.DEBUG)) {
  -                    logger.log("Adding action " + oNode.getUri() + " to action aggregation", LOG_CHANNEL, Logger.DEBUG);
  +                if (security.logger.isEnabled(Logger.DEBUG)) {
  +                    security.logger.log("Adding action " + oNode.getUri() + " to action aggregation", LOG_CHANNEL, Logger.DEBUG);
                   }
  -                NodeRevisionNumber latestRevisionNumber = namespace.getStore(aNodeUri.getScope()).retrieveRevisionDescriptors(aNodeUri).getLatestRevision();
  -                NodeProperty privilegeNamespace = namespace.getStore(aNodeUri.getScope()).retrieveRevisionDescriptor(aNodeUri, latestRevisionNumber).getProperty(PRIVILEGE_NAMESPACE, "DAV:");
  +                NodeRevisionNumber latestRevisionNumber = security.namespace.getStore(aNodeUri.getScope()).retrieveRevisionDescriptors(aNodeUri).getLatestRevision();
  +                NodeProperty privilegeNamespace = security.namespace.getStore(aNodeUri.getScope()).retrieveRevisionDescriptor(aNodeUri, latestRevisionNumber).getProperty(PRIVILEGE_NAMESPACE, "DAV:");
                   ActionNode aNode;
                   org.jdom.Namespace actionNamespace;
                   if (privilegeNamespace != null && privilegeNamespace.getValue() instanceof String) {
  @@ -1373,12 +1370,12 @@
                       actionNamespace = org.jdom.Namespace.getNamespace("DAV:");
                   }
                   aNode = ActionNode.getActionNode(oNode.getUri(), actionNamespace);
  -                Set directAggregates = getActionAggregates(aNode);
  -                actionAggregation.put(aNode, directAggregates);
  +                Set directAggregates = getActionAggregates(security, aNode);
  +                cache.aggregation.put(aNode, directAggregates);
                   Set aClosure = new HashSet();
                   aClosure.add(aNode);
                   aClosure.addAll(directAggregates);
  -                actionAggregationClosure.put(aNode, aClosure);
  +                cache.aggregationClosure.put(aNode, aClosure);
               }
           }
       }
  @@ -1393,7 +1390,7 @@
        * @return A collection containing the action, its known and additionally
        *         found children and grandchildren.
        */
  -    private synchronized Set buildClosure(Set aClosure) {
  +    private static synchronized Set buildClosure(ActionsCache cache, Set aClosure) {
           Set result = new HashSet(aClosure);
           int size = 0;
           while (result.size() > size) {
  @@ -1402,7 +1399,7 @@
               Iterator i = result.iterator();
               while (i.hasNext()) {
                   Object member = i.next();
  -                Set membersOfMember = (Set)actionAggregationClosure.get(member);
  +                Set membersOfMember = (Set)cache.aggregationClosure.get(member);
                   if (membersOfMember != null) {
                       newResult.addAll(membersOfMember);
                   }
  @@ -1421,15 +1418,16 @@
        * @return A map from actions to their aggregated actions, or and empty map
        *         if loading of the actions cache failed.
        */
  -    private synchronized Map getActionAggregationImpl() {
  -        if (this.actionAggregation == null && !this.hasActionsCacheLoadingFailed) {
  -            loadActionsCache(this.namespace, this.namespaceConfig);
  +    private static synchronized Map getActionAggregationImpl(SecurityImpl security) {
  +        ActionsCache cache = getActionsCache(security);
  +        if (!cache.hasBeenLoaded()) {
  +            loadActionsCache(security);
           }
  -        if (this.hasActionsCacheLoadingFailed) {
  -            logger.log("actionAggregation retrieved but cache didn't load successfully" , LOG_CHANNEL, Logger.WARNING);
  +        if (cache.hasLoadingFailed) {
  +            security.logger.log("actionAggregation retrieved but cache didn't load successfully" , LOG_CHANNEL, Logger.WARNING);
               return new HashMap();
           }
  -        return this.actionAggregation;
  +        return cache.aggregation;
       }
       
       /**
  @@ -1442,15 +1440,16 @@
        * @throws ServiceAccessException Indicates the loading of the actions
        *                                cache failed.
        */
  -    private synchronized Map getActionAggregationClosureImpl(SlideToken token, String uri) throws ServiceAccessException {
  -        if (this.actionAggregationClosure == null && !this.hasActionsCacheLoadingFailed) {
  -            loadActionsCache(this.namespace, this.namespaceConfig);
  +    private static synchronized Map getActionAggregationClosureImpl(SecurityImpl security, SlideToken token, String uri) throws ServiceAccessException {
  +        ActionsCache cache = getActionsCache(security);
  +        if (!cache.hasBeenLoaded()) {
  +            loadActionsCache(security);
           }
  -        if (this.hasActionsCacheLoadingFailed) {
  -            Uri u = this.namespace.getUri(token, uri);
  +        if (cache.hasLoadingFailed()) {
  +            Uri u = security.namespace.getUri(token, uri);
               Store s = u.getStore();
               throw new ServiceAccessException(s, "Actions cache not loaded");
           }
  -        return this.actionAggregationClosure;
  +        return cache.aggregationClosure;
       }
   }
  
  
  
  1.1                  jakarta-slide/src/share/org/apache/slide/security/ActionsCache.java
  
  Index: ActionsCache.java
  ===================================================================
  package org.apache.slide.security;
  
  import java.util.Map;
  
  class ActionsCache {
  
      Map aggregation; // actionNode -> Set-of-aggregated-nodes (direct aggregates)
  
      Map aggregationClosure; // actionNode -> Set-of-aggregated-nodes (transitive closure)
      
      boolean hasLoadingFailed;
  
      ActionsCache() {
          super();
      }
  
      void invalidate() {
          hasLoadingFailed = false;
          aggregation = null;
          aggregationClosure = null;
      }
      
      void fail() {
          aggregation = null;
          aggregationClosure = null;
          hasLoadingFailed = true;
      }
  
      boolean hasBeenLoaded() {
          return aggregation != null || hasLoadingFailed;
      }
  
      public boolean hasLoadingFailed() {
          return hasLoadingFailed;
      }
  
  }
  
  
  

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