1 16 17 package org.springframework.beans.factory.xml; 18 19 import java.io.IOException ; 20 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 import org.w3c.dom.Document ; 24 import org.w3c.dom.Element ; 25 import org.w3c.dom.Node ; 26 import org.w3c.dom.NodeList ; 27 28 import org.springframework.beans.factory.BeanDefinitionStoreException; 29 import org.springframework.beans.factory.config.BeanDefinitionHolder; 30 import org.springframework.beans.factory.parsing.BeanComponentDefinition; 31 import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; 32 import org.springframework.core.io.Resource; 33 import org.springframework.core.io.support.ResourcePatternUtils; 34 import org.springframework.util.StringUtils; 35 import org.springframework.util.SystemPropertyUtils; 36 import org.springframework.util.xml.DomUtils; 37 38 55 public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { 56 57 public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT; 58 59 public static final String ALIAS_ELEMENT = "alias"; 60 61 public static final String NAME_ATTRIBUTE = "name"; 62 63 public static final String ALIAS_ATTRIBUTE = "alias"; 64 65 public static final String IMPORT_ELEMENT = "import"; 66 67 public static final String RESOURCE_ATTRIBUTE = "resource"; 68 69 70 protected final Log logger = LogFactory.getLog(getClass()); 71 72 private XmlReaderContext readerContext; 73 74 75 81 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { 82 this.readerContext = readerContext; 83 84 logger.debug("Loading bean definitions"); 85 Element root = doc.getDocumentElement(); 86 87 BeanDefinitionParserDelegate delegate = createHelper(readerContext, root); 88 89 preProcessXml(root); 90 parseBeanDefinitions(root, delegate); 91 postProcessXml(root); 92 } 93 94 protected BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root) { 95 BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); 96 delegate.initDefaults(root); 97 return delegate; 98 } 99 100 103 protected final XmlReaderContext getReaderContext() { 104 return this.readerContext; 105 } 106 107 111 protected Object extractSource(Element ele) { 112 return this.readerContext.extractSource(ele); 113 } 114 115 116 121 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { 122 if (delegate.isDefaultNamespace(root.getNamespaceURI())) { 123 NodeList nl = root.getChildNodes(); 124 for (int i = 0; i < nl.getLength(); i++) { 125 Node node = nl.item(i); 126 if (node instanceof Element ) { 127 Element ele = (Element ) node; 128 String namespaceUri = ele.getNamespaceURI(); 129 if (delegate.isDefaultNamespace(namespaceUri)) { 130 parseDefaultElement(ele, delegate); 131 } 132 else { 133 delegate.parseCustomElement(ele); 134 } 135 } 136 } 137 } 138 else { 139 delegate.parseCustomElement(root); 140 } 141 } 142 143 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { 144 if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT)) { 145 importBeanDefinitionResource(ele); 146 } 147 else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT)) { 148 processAliasRegistration(ele); 149 } 150 else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT)) { 151 processBeanDefinition(ele, delegate); 152 } 153 } 154 155 159 protected void importBeanDefinitionResource(Element ele) { 160 String location = ele.getAttribute(RESOURCE_ATTRIBUTE); 161 if (!StringUtils.hasText(location)) { 162 getReaderContext().error("Resource location must not be empty", ele); 163 return; 164 } 165 166 location = SystemPropertyUtils.resolvePlaceholders(location); 168 169 if (ResourcePatternUtils.isUrl(location)) { 170 try { 171 int importCount = getReaderContext().getReader().loadBeanDefinitions(location); 172 if (logger.isDebugEnabled()) { 173 logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]"); 174 } 175 } 176 catch (BeanDefinitionStoreException ex) { 177 getReaderContext().error( 178 "Failed to import bean definitions from URL location [" + location + "]", ele, ex); 179 } 180 } 181 else { 182 try { 184 Resource relativeResource = getReaderContext().getResource().createRelative(location); 185 int importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); 186 if (logger.isDebugEnabled()) { 187 logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]"); 188 } 189 } 190 catch (IOException ex) { 191 getReaderContext().error( 192 "Invalid relative resource location [" + location + "] to import bean definitions from", ele, ex); 193 } 194 catch (BeanDefinitionStoreException ex) { 195 getReaderContext().error( 196 "Failed to import bean definitions from relative location [" + location + "]", ele, ex); 197 } 198 } 199 200 getReaderContext().fireImportProcessed(location, extractSource(ele)); 201 } 202 203 206 protected void processAliasRegistration(Element ele) { 207 String name = ele.getAttribute(NAME_ATTRIBUTE); 208 String alias = ele.getAttribute(ALIAS_ATTRIBUTE); 209 boolean valid = true; 210 if (!StringUtils.hasText(name)) { 211 getReaderContext().error("Name must not be empty", ele); 212 valid = false; 213 } 214 if (!StringUtils.hasText(alias)) { 215 getReaderContext().error("Alias must not be empty", ele); 216 valid = false; 217 } 218 if (valid) { 219 try { 220 getReaderContext().getRegistry().registerAlias(name, alias); 221 } 222 catch (BeanDefinitionStoreException ex) { 223 getReaderContext().error("Failed to register alias '" + alias + 224 "' for bean with name '" + name + "'", ele, ex); 225 } 226 getReaderContext().fireAliasRegistered(name, alias, extractSource(ele)); 227 } 228 } 229 230 234 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { 235 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); 236 if (bdHolder != null) { 237 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); 238 try { 239 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); 241 } 242 catch (BeanDefinitionStoreException ex) { 243 getReaderContext().error("Failed to register bean definition with name '" + 244 bdHolder.getBeanName() + "'", ele, ex); 245 } 246 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); 248 } 249 } 250 251 252 262 protected void preProcessXml(Element root) { 263 } 264 265 275 protected void postProcessXml(Element root) { 276 } 277 278 } 279 | Popular Tags |