|  | @@ -10,6 +10,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.config.RuntimeBeanReference;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.parsing.BeanComponentDefinition;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.support.ManagedList;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.support.RootBeanDefinition;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.xml.BeanDefinitionParser;
 | 
	
	
		
			
				|  | @@ -50,102 +51,135 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      public BeanDefinition parse(Element element, ParserContext parserContext) {
 | 
	
		
			
				|  |  | -    	boolean useJsr250 = "enabled".equals(element.getAttribute(ATT_USE_JSR250));
 | 
	
		
			
				|  |  | -        boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // Check the required classes are present
 | 
	
		
			
				|  |  | -        if (useSecured) {
 | 
	
		
			
				|  |  | -        	validatePresent(SECURED_METHOD_DEFINITION_SOURCE_CLASS, element, parserContext);
 | 
	
		
			
				|  |  | -        	validatePresent(SECURED_DEPENDENCY_CLASS, element, parserContext);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        if (useJsr250) {
 | 
	
		
			
				|  |  | -        	validatePresent(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS, element, parserContext);
 | 
	
		
			
				|  |  | -        	validatePresent(JSR_250_VOTER_CLASS, element, parserContext);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        Object source = parserContext.extractSource(element);
 | 
	
		
			
				|  |  | +        // The list of method metadata delegates
 | 
	
		
			
				|  |  | +        ManagedList delegates = new ManagedList();
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        boolean jsr250Enabled = registerAnnotationBasedMethodDefinitionSources(element, parserContext, delegates);
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        // Now create a Map<String, ConfigAttribute> for each <protect-pointcut> sub-element
 | 
	
		
			
				|  |  | -        Map pointcutMap = new LinkedHashMap();
 | 
	
		
			
				|  |  | -        List protect = DomUtils.getChildElementsByTagName(element, Elements.PROTECT_POINTCUT);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        for (Iterator i = protect.iterator(); i.hasNext();) {
 | 
	
		
			
				|  |  | -            Element childElt = (Element) i.next();
 | 
	
		
			
				|  |  | -            String accessConfig = childElt.getAttribute(ATT_ACCESS);
 | 
	
		
			
				|  |  | -            String expression = childElt.getAttribute(ATT_EXPRESSION);
 | 
	
		
			
				|  |  | -            Assert.hasText(accessConfig, "Access configuration required for '" + childElt + "'");
 | 
	
		
			
				|  |  | -            Assert.hasText(expression, "Expression required for '" + childElt + "'");
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -            ConfigAttributeDefinition def = new ConfigAttributeDefinition(StringUtils.commaDelimitedListToStringArray(accessConfig));
 | 
	
		
			
				|  |  | -            pointcutMap.put(expression, def);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          MapBasedMethodDefinitionSource mapBasedMethodDefinitionSource = new MapBasedMethodDefinitionSource();
 | 
	
		
			
				|  |  | +        delegates.add(mapBasedMethodDefinitionSource);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        // Now create a Map<String, ConfigAttribute> for each <protect-pointcut> sub-element        
 | 
	
		
			
				|  |  | +        Map pointcutMap = parseProtectPointcuts(parserContext, 
 | 
	
		
			
				|  |  | +                DomUtils.getChildElementsByTagName(element, Elements.PROTECT_POINTCUT));
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        // Now create and populate our ProtectPointcutBeanPostProcessor, if needed
 | 
	
		
			
				|  |  |          if (pointcutMap.size() > 0) {
 | 
	
		
			
				|  |  | -            RootBeanDefinition ppbp = new RootBeanDefinition(ProtectPointcutPostProcessor.class);
 | 
	
		
			
				|  |  | -            ppbp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
	
		
			
				|  |  | -            ppbp.setSource(parserContext.extractSource(element));
 | 
	
		
			
				|  |  | -            ppbp.getConstructorArgumentValues().addGenericArgumentValue(mapBasedMethodDefinitionSource);
 | 
	
		
			
				|  |  | -            ppbp.getPropertyValues().addPropertyValue("pointcutMap", pointcutMap);
 | 
	
		
			
				|  |  | -            parserContext.getRegistry().registerBeanDefinition(BeanIds.PROTECT_POINTCUT_POST_PROCESSOR, ppbp);
 | 
	
		
			
				|  |  | +            registerProtectPointcutPostProcessor(parserContext, pointcutMap, mapBasedMethodDefinitionSource, source);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        // Create our list of method metadata delegates
 | 
	
		
			
				|  |  | -        ManagedList delegates = new ManagedList();
 | 
	
		
			
				|  |  | -        delegates.add(mapBasedMethodDefinitionSource);
 | 
	
		
			
				|  |  | +        registerDelegatingMethodDefinitionSource(parserContext, delegates, source);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        // Register the applicable AccessDecisionManager, handling the special JSR 250 voter if being used
 | 
	
		
			
				|  |  | +        String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!StringUtils.hasText(accessManagerId)) {
 | 
	
		
			
				|  |  | +            ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (jsr250Enabled) {
 | 
	
		
			
				|  |  | +                ConfigUtils.addVoter(new RootBeanDefinition(JSR_250_VOTER_CLASS, null, null), parserContext);                
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            accessManagerId = BeanIds.ACCESS_MANAGER;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        registerMethodSecurityInterceptor(parserContext, accessManagerId, source);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        registerAdvisor(parserContext, source);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        return null;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * Checks whether JSR-250 and/or Secured annotations are enabled and adds the appropriate 
 | 
	
		
			
				|  |  | +     * MethodDefinitionSource delegates if required. 
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private boolean registerAnnotationBasedMethodDefinitionSources(Element element, ParserContext pc, ManagedList delegates) {
 | 
	
		
			
				|  |  | +        boolean useJsr250 = "enabled".equals(element.getAttribute(ATT_USE_JSR250));
 | 
	
		
			
				|  |  | +        boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED));
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | +        // Check the required classes are present
 | 
	
		
			
				|  |  |          if (useSecured) {
 | 
	
		
			
				|  |  | +            validatePresent(SECURED_METHOD_DEFINITION_SOURCE_CLASS, element, pc);
 | 
	
		
			
				|  |  | +            validatePresent(SECURED_DEPENDENCY_CLASS, element, pc);
 | 
	
		
			
				|  |  |              delegates.add(BeanDefinitionBuilder.rootBeanDefinition(SECURED_METHOD_DEFINITION_SOURCE_CLASS).getBeanDefinition());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if (useJsr250) {
 | 
	
		
			
				|  |  | -            delegates.add(BeanDefinitionBuilder.rootBeanDefinition(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS).getBeanDefinition());            
 | 
	
		
			
				|  |  | +            validatePresent(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS, element, pc);
 | 
	
		
			
				|  |  | +            validatePresent(JSR_250_VOTER_CLASS, element, pc);
 | 
	
		
			
				|  |  | +            delegates.add(BeanDefinitionBuilder.rootBeanDefinition(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS).getBeanDefinition());           
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -    	// Register our DelegatingMethodDefinitionSource
 | 
	
		
			
				|  |  | +        return useJsr250;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    private void registerDelegatingMethodDefinitionSource(ParserContext parserContext, ManagedList delegates, Object source) {
 | 
	
		
			
				|  |  | +        if (parserContext.getRegistry().containsBeanDefinition(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE)) {
 | 
	
		
			
				|  |  | +            parserContext.getReaderContext().error("Duplicate <global-method-security> detected.", source);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          RootBeanDefinition delegatingMethodDefinitionSource = new RootBeanDefinition(DelegatingMethodDefinitionSource.class);
 | 
	
		
			
				|  |  |          delegatingMethodDefinitionSource.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
	
		
			
				|  |  | -        delegatingMethodDefinitionSource.setSource(parserContext.extractSource(element));
 | 
	
		
			
				|  |  | +        delegatingMethodDefinitionSource.setSource(source);
 | 
	
		
			
				|  |  |          delegatingMethodDefinitionSource.getPropertyValues().addPropertyValue("methodDefinitionSources", delegates);
 | 
	
		
			
				|  |  | -        parserContext.getRegistry().registerBeanDefinition(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE, delegatingMethodDefinitionSource);
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        // Register the applicable AccessDecisionManager, handling the special JSR 250 voter if being used
 | 
	
		
			
				|  |  | -        String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
 | 
	
		
			
				|  |  | +        parserContext.getRegistry().registerBeanDefinition(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE, delegatingMethodDefinitionSource);        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    private void registerProtectPointcutPostProcessor(ParserContext parserContext, Map pointcutMap,
 | 
	
		
			
				|  |  | +            MapBasedMethodDefinitionSource mapBasedMethodDefinitionSource, Object source) {
 | 
	
		
			
				|  |  | +        RootBeanDefinition ppbp = new RootBeanDefinition(ProtectPointcutPostProcessor.class);
 | 
	
		
			
				|  |  | +        ppbp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
	
		
			
				|  |  | +        ppbp.setSource(source);
 | 
	
		
			
				|  |  | +        ppbp.getConstructorArgumentValues().addGenericArgumentValue(mapBasedMethodDefinitionSource);
 | 
	
		
			
				|  |  | +        ppbp.getPropertyValues().addPropertyValue("pointcutMap", pointcutMap);
 | 
	
		
			
				|  |  | +        parserContext.getRegistry().registerBeanDefinition(BeanIds.PROTECT_POINTCUT_POST_PROCESSOR, ppbp);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (!StringUtils.hasText(accessManagerId)) {
 | 
	
		
			
				|  |  | -            ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
 | 
	
		
			
				|  |  | +    private Map parseProtectPointcuts(ParserContext parserContext, List protectPointcutElts) {
 | 
	
		
			
				|  |  | +        Map pointcutMap = new LinkedHashMap();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if (useJsr250) {
 | 
	
		
			
				|  |  | -                ConfigUtils.addVoter(new RootBeanDefinition(JSR_250_VOTER_CLASS, null, null), parserContext);                
 | 
	
		
			
				|  |  | +        for (Iterator i = protectPointcutElts.iterator(); i.hasNext();) {
 | 
	
		
			
				|  |  | +            Element childElt = (Element) i.next();
 | 
	
		
			
				|  |  | +            String accessConfig = childElt.getAttribute(ATT_ACCESS);
 | 
	
		
			
				|  |  | +            String expression = childElt.getAttribute(ATT_EXPRESSION);
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            if (!StringUtils.hasText(accessConfig)) {
 | 
	
		
			
				|  |  | +                parserContext.getReaderContext().error("Access configuration required", parserContext.extractSource(childElt));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            accessManagerId = BeanIds.ACCESS_MANAGER;
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            if (!StringUtils.hasText(expression)) {
 | 
	
		
			
				|  |  | +                parserContext.getReaderContext().error("Pointcut expression required", parserContext.extractSource(childElt));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            ConfigAttributeDefinition def = new ConfigAttributeDefinition(StringUtils.commaDelimitedListToStringArray(accessConfig));
 | 
	
		
			
				|  |  | +            pointcutMap.put(expression, def);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // MethodSecurityInterceptor
 | 
	
		
			
				|  |  | +        return pointcutMap;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    private void registerMethodSecurityInterceptor(ParserContext parserContext, String accessManagerId, Object source) {
 | 
	
		
			
				|  |  |          RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
 | 
	
		
			
				|  |  |          interceptor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
	
		
			
				|  |  | -        interceptor.setSource(parserContext.extractSource(element));
 | 
	
		
			
				|  |  | +        interceptor.setSource(source);
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          interceptor.getPropertyValues().addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
 | 
	
		
			
				|  |  |          interceptor.getPropertyValues().addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
 | 
	
		
			
				|  |  |          interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", new RuntimeBeanReference(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE));
 | 
	
		
			
				|  |  |          parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR, interceptor);
 | 
	
		
			
				|  |  | -        parserContext.registerComponent(new BeanComponentDefinition(interceptor, BeanIds.METHOD_SECURITY_INTERCEPTOR));
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        // MethodDefinitionSourceAdvisor
 | 
	
		
			
				|  |  | +        parserContext.registerComponent(new BeanComponentDefinition(interceptor, BeanIds.METHOD_SECURITY_INTERCEPTOR));        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    private void registerAdvisor(ParserContext parserContext, Object source) {
 | 
	
		
			
				|  |  |          RootBeanDefinition advisor = new RootBeanDefinition(MethodDefinitionSourceAdvisor.class);
 | 
	
		
			
				|  |  |          advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 | 
	
		
			
				|  |  | -        advisor.setSource(parserContext.extractSource(element));
 | 
	
		
			
				|  |  | +        advisor.setSource(source);
 | 
	
		
			
				|  |  |          advisor.getConstructorArgumentValues().addGenericArgumentValue(BeanIds.METHOD_SECURITY_INTERCEPTOR);
 | 
	
		
			
				|  |  |          advisor.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        //advisor.getConstructorArgumentValues().addGenericArgumentValue(interceptor);
 | 
	
		
			
				|  |  | -        parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        return null;
 | 
	
		
			
				|  |  | +        parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor);        
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  |  }
 |