View Javadoc

1   package org.springframework.security.config;
2   
3   import org.springframework.beans.factory.xml.BeanDefinitionParser;
4   import org.springframework.beans.factory.xml.ParserContext;
5   import org.springframework.beans.factory.config.BeanDefinition;
6   import org.springframework.beans.factory.config.RuntimeBeanReference;
7   import org.springframework.beans.factory.support.AbstractBeanDefinition;
8   import org.springframework.beans.factory.support.BeanDefinitionBuilder;
9   import org.springframework.beans.factory.support.RootBeanDefinition;
10  import org.springframework.beans.factory.BeanDefinitionStoreException;
11  import org.springframework.util.StringUtils;
12  
13  import org.w3c.dom.Element;
14  
15  /**
16   * @author Luke Taylor
17   * @version $Id: AbstractUserDetailsServiceBeanDefinitionParser.java 3086 2008-05-23 21:30:57Z luke_t $
18   */
19  public abstract class AbstractUserDetailsServiceBeanDefinitionParser implements BeanDefinitionParser {
20      private static final String CACHE_REF = "cache-ref";
21      public static final String CACHING_SUFFIX = ".caching";
22      
23      /**  UserDetailsService bean Id. For use in a stateful context (i.e. in AuthenticationProviderBDP) */
24      private String id;
25      
26      protected abstract String getBeanClassName(Element element);
27      
28      protected abstract void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);    
29      
30      public BeanDefinition parse(Element element, ParserContext parserContext) {
31          BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClassName(element)); 
32          
33          doParse(element, parserContext, builder);
34          
35          RootBeanDefinition userService = (RootBeanDefinition) builder.getBeanDefinition();
36          String beanId = resolveId(element, userService, parserContext);
37          
38          parserContext.getRegistry().registerBeanDefinition(beanId, userService);
39          
40          String cacheRef = element.getAttribute(CACHE_REF);
41          
42          // Register a caching version of the user service if there's a cache-ref
43          if (StringUtils.hasText(cacheRef)) {
44              BeanDefinitionBuilder cachingUSBuilder = BeanDefinitionBuilder.rootBeanDefinition(CachingUserDetailsService.class);
45              cachingUSBuilder.addConstructorArgReference(beanId);
46              
47              cachingUSBuilder.addPropertyValue("userCache", new RuntimeBeanReference(cacheRef));
48              BeanDefinition cachingUserService = cachingUSBuilder.getBeanDefinition();
49              parserContext.getRegistry().registerBeanDefinition(beanId + CACHING_SUFFIX, cachingUserService);            
50          }
51  
52          id = beanId;
53          
54          return null;
55      }
56  
57      private String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) 
58              throws BeanDefinitionStoreException {
59  
60          String id = element.getAttribute("id");
61  
62          if (StringUtils.hasText(id)) {
63              return id;
64          }
65  
66          if(Elements.AUTHENTICATION_PROVIDER.equals(element.getParentNode().getNodeName())) {
67              return parserContext.getReaderContext().generateBeanName(definition);
68          }
69  
70          // If top level, use the default name or throw an exception if already used
71          if (parserContext.getRegistry().containsBeanDefinition(BeanIds.USER_DETAILS_SERVICE)) {
72              throw new BeanDefinitionStoreException("No id supplied and another " +
73                      "bean is already registered as " + BeanIds.USER_DETAILS_SERVICE);
74          }
75  
76          return BeanIds.USER_DETAILS_SERVICE;
77      }
78  
79      String getId() {
80          return id;
81      }
82  }