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
17
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
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
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
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 }