1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.beans.factory.xml;
  17. import java.util.ArrayList;
  18. import java.util.Arrays;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Properties;
  22. import java.util.Set;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.w3c.dom.DOMException;
  26. import org.w3c.dom.Document;
  27. import org.w3c.dom.Element;
  28. import org.w3c.dom.Node;
  29. import org.w3c.dom.NodeList;
  30. import org.w3c.dom.Text;
  31. import org.springframework.beans.MutablePropertyValues;
  32. import org.springframework.beans.PropertyValue;
  33. import org.springframework.beans.factory.BeanDefinitionStoreException;
  34. import org.springframework.beans.factory.config.BeanDefinition;
  35. import org.springframework.beans.factory.config.ConstructorArgumentValues;
  36. import org.springframework.beans.factory.config.RuntimeBeanReference;
  37. import org.springframework.beans.factory.support.AbstractBeanDefinition;
  38. import org.springframework.beans.factory.support.BeanDefinitionHolder;
  39. import org.springframework.beans.factory.support.BeanDefinitionRegistry;
  40. import org.springframework.beans.factory.support.ChildBeanDefinition;
  41. import org.springframework.beans.factory.support.ManagedLinkedMap;
  42. import org.springframework.beans.factory.support.ManagedList;
  43. import org.springframework.beans.factory.support.ManagedMap;
  44. import org.springframework.beans.factory.support.ManagedSet;
  45. import org.springframework.beans.factory.support.RootBeanDefinition;
  46. import org.springframework.core.JdkVersion;
  47. import org.springframework.core.io.Resource;
  48. import org.springframework.util.StringUtils;
  49. /**
  50. * Default implementation of the XmlBeanDefinitionParser interface.
  51. * Parses bean definitions according to the "spring-beans" DTD.
  52. * @author Rod Johnson
  53. * @author Juergen Hoeller
  54. * @since 18.12.2003
  55. */
  56. public class DefaultXmlBeanDefinitionParser implements XmlBeanDefinitionParser {
  57. public static final String BEAN_NAME_DELIMITERS = ",; ";
  58. /**
  59. * Value of a T/F attribute that represents true.
  60. * Anything else represents false. Case seNsItive.
  61. */
  62. public static final String TRUE_VALUE = "true";
  63. public static final String DEFAULT_VALUE = "default";
  64. public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
  65. public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
  66. public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
  67. public static final String BEAN_ELEMENT = "bean";
  68. public static final String DESCRIPTION_ELEMENT = "description";
  69. public static final String CLASS_ATTRIBUTE = "class";
  70. public static final String PARENT_ATTRIBUTE = "parent";
  71. public static final String ID_ATTRIBUTE = "id";
  72. public static final String NAME_ATTRIBUTE = "name";
  73. public static final String SINGLETON_ATTRIBUTE = "singleton";
  74. public static final String DEPENDS_ON_ATTRIBUTE = "depends-on";
  75. public static final String INIT_METHOD_ATTRIBUTE = "init-method";
  76. public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
  77. public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg";
  78. public static final String INDEX_ATTRIBUTE = "index";
  79. public static final String TYPE_ATTRIBUTE = "type";
  80. public static final String PROPERTY_ELEMENT = "property";
  81. public static final String REF_ELEMENT = "ref";
  82. public static final String IDREF_ELEMENT = "idref";
  83. public static final String BEAN_REF_ATTRIBUTE = "bean";
  84. public static final String LOCAL_REF_ATTRIBUTE = "local";
  85. public static final String LIST_ELEMENT = "list";
  86. public static final String SET_ELEMENT = "set";
  87. public static final String MAP_ELEMENT = "map";
  88. public static final String KEY_ATTRIBUTE = "key";
  89. public static final String ENTRY_ELEMENT = "entry";
  90. public static final String VALUE_ELEMENT = "value";
  91. public static final String NULL_ELEMENT = "null";
  92. public static final String PROPS_ELEMENT = "props";
  93. public static final String PROP_ELEMENT = "prop";
  94. public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
  95. public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check";
  96. public static final String DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE = "all";
  97. public static final String DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE = "simple";
  98. public static final String DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE = "objects";
  99. public static final String AUTOWIRE_ATTRIBUTE = "autowire";
  100. public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
  101. public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
  102. public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor";
  103. public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";
  104. protected final Log logger = LogFactory.getLog(getClass());
  105. private BeanDefinitionRegistry beanFactory;
  106. private ClassLoader beanClassLoader;
  107. private Resource resource;
  108. private String defaultLazyInit;
  109. private String defaultDependencyCheck;
  110. private String defaultAutowire;
  111. public void registerBeanDefinitions(BeanDefinitionRegistry beanFactory, ClassLoader beanClassLoader,
  112. Document doc, Resource resource) {
  113. this.beanFactory = beanFactory;
  114. this.beanClassLoader = beanClassLoader;
  115. this.resource = resource;
  116. logger.debug("Loading bean definitions");
  117. Element root = doc.getDocumentElement();
  118. this.defaultLazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
  119. logger.debug("Default lazy init '" + this.defaultLazyInit + "'");
  120. this.defaultDependencyCheck = root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE);
  121. logger.debug("Default dependency check '" + this.defaultDependencyCheck + "'");
  122. this.defaultAutowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
  123. logger.debug("Default autowire '" + this.defaultAutowire + "'");
  124. NodeList nl = root.getChildNodes();
  125. int beanDefinitionCounter = 0;
  126. for (int i = 0; i < nl.getLength(); i++) {
  127. Node node = nl.item(i);
  128. if (node instanceof Element && BEAN_ELEMENT.equals(node.getNodeName())) {
  129. beanDefinitionCounter++;
  130. registerBeanDefinition((Element) node);
  131. }
  132. }
  133. logger.debug("Found " + beanDefinitionCounter + " <" + BEAN_ELEMENT + "> elements defining beans");
  134. }
  135. protected BeanDefinitionRegistry getBeanFactory() {
  136. return beanFactory;
  137. }
  138. protected ClassLoader getBeanClassLoader() {
  139. return beanClassLoader;
  140. }
  141. protected String getDefaultLazyInit() {
  142. return defaultLazyInit;
  143. }
  144. protected String getDefaultDependencyCheck() {
  145. return defaultDependencyCheck;
  146. }
  147. protected String getDefaultAutowire() {
  148. return defaultAutowire;
  149. }
  150. /**
  151. * Parse a "bean" element and register it with the bean factory.
  152. */
  153. protected void registerBeanDefinition(Element ele) {
  154. BeanDefinitionHolder bdHolder = parseBeanDefinition(ele);
  155. logger.debug("Registering bean definition with id '" + bdHolder.getBeanName() + "'");
  156. this.beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition());
  157. if (bdHolder.getAliases() != null) {
  158. for (int i = 0; i < bdHolder.getAliases().length; i++) {
  159. this.beanFactory.registerAlias(bdHolder.getBeanName(), bdHolder.getAliases()[i]);
  160. }
  161. }
  162. }
  163. /**
  164. * Parse a standard bean definition into a BeanDefinitionHolder,
  165. * including bean name and aliases.
  166. * <p>Bean elements specify their canonical name as "id" attribute
  167. * and their aliases as a delimited "name" attribute.
  168. * <p>If no "id" specified, uses the first name in the "name" attribute
  169. * as canonical name, registering all others as aliases.
  170. */
  171. protected BeanDefinitionHolder parseBeanDefinition(Element ele) {
  172. String id = ele.getAttribute(ID_ATTRIBUTE);
  173. String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
  174. List aliases = new ArrayList();
  175. if (nameAttr != null && !"".equals(nameAttr)) {
  176. String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS, true, true);
  177. aliases.addAll(Arrays.asList(nameArr));
  178. }
  179. if (id == null || "".equals(id) && !aliases.isEmpty()) {
  180. id = (String) aliases.remove(0);
  181. logger.debug("No XML 'id' specified - using '" + id + "' as ID and " + aliases + " as aliases");
  182. }
  183. BeanDefinition beanDefinition = parseBeanDefinition(ele, id);
  184. if (id == null || "".equals(id)) {
  185. if (beanDefinition instanceof RootBeanDefinition) {
  186. id = ((RootBeanDefinition) beanDefinition).getBeanClassName();
  187. logger.debug("Neither XML 'id' nor 'name' specified - using bean class name [" + id + "] as ID");
  188. }
  189. else if (beanDefinition instanceof ChildBeanDefinition) {
  190. throw new BeanDefinitionStoreException(this.resource, "",
  191. "Child bean definition has neither 'id' nor 'name'");
  192. }
  193. }
  194. String[] aliasesArray = (String[]) aliases.toArray(new String[aliases.size()]);
  195. return new BeanDefinitionHolder(beanDefinition, id, aliasesArray);
  196. }
  197. /**
  198. * Parse the BeanDefinition itself, without regard to name or aliases.
  199. */
  200. protected BeanDefinition parseBeanDefinition(Element ele, String beanName) {
  201. String className = null;
  202. try {
  203. if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
  204. className = ele.getAttribute(CLASS_ATTRIBUTE);
  205. }
  206. String parent = null;
  207. if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
  208. parent = ele.getAttribute(PARENT_ATTRIBUTE);
  209. }
  210. if (className == null && parent == null) {
  211. throw new BeanDefinitionStoreException(this.resource, beanName, "Either 'class' or 'parent' is required");
  212. }
  213. AbstractBeanDefinition bd = null;
  214. MutablePropertyValues pvs = getPropertyValueSubElements(beanName, ele);
  215. if (className != null) {
  216. ConstructorArgumentValues cargs = getConstructorArgSubElements(beanName, ele);
  217. RootBeanDefinition rbd = null;
  218. if (this.beanClassLoader != null) {
  219. Class clazz = Class.forName(className, true, this.beanClassLoader);
  220. rbd = new RootBeanDefinition(clazz, cargs, pvs);
  221. }
  222. else {
  223. rbd = new RootBeanDefinition(className, cargs, pvs);
  224. }
  225. if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
  226. String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
  227. rbd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS, true, true));
  228. }
  229. String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
  230. if (DEFAULT_VALUE.equals(dependencyCheck)) {
  231. dependencyCheck = this.defaultDependencyCheck;
  232. }
  233. rbd.setDependencyCheck(getDependencyCheck(dependencyCheck));
  234. String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
  235. if (DEFAULT_VALUE.equals(autowire)) {
  236. autowire = this.defaultAutowire;
  237. }
  238. rbd.setAutowireMode(getAutowireMode(autowire));
  239. String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
  240. if (!initMethodName.equals("")) {
  241. rbd.setInitMethodName(initMethodName);
  242. }
  243. String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
  244. if (!destroyMethodName.equals("")) {
  245. rbd.setDestroyMethodName(destroyMethodName);
  246. }
  247. bd = rbd;
  248. }
  249. else {
  250. bd = new ChildBeanDefinition(parent, pvs);
  251. }
  252. if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
  253. bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
  254. }
  255. String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
  256. if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
  257. // just apply default to singletons, as lazy-init has no meaning for prototypes
  258. lazyInit = this.defaultLazyInit;
  259. }
  260. bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
  261. bd.setResourceDescription(this.resource.getDescription());
  262. return bd;
  263. }
  264. catch (ClassNotFoundException ex) {
  265. throw new BeanDefinitionStoreException(this.resource, beanName,
  266. "Bean class [" + className + "] not found", ex);
  267. }
  268. catch (NoClassDefFoundError err) {
  269. throw new BeanDefinitionStoreException(this.resource, beanName,
  270. "Class that bean class [" + className + "] depends on not found", err);
  271. }
  272. }
  273. /**
  274. * Parse constructor argument subelements of the given bean element.
  275. */
  276. protected ConstructorArgumentValues getConstructorArgSubElements(String beanName, Element beanEle)
  277. throws ClassNotFoundException {
  278. NodeList nl = beanEle.getChildNodes();
  279. ConstructorArgumentValues cargs = new ConstructorArgumentValues();
  280. for (int i = 0; i < nl.getLength(); i++) {
  281. Node node = nl.item(i);
  282. if (node instanceof Element && CONSTRUCTOR_ARG_ELEMENT.equals(node.getNodeName())) {
  283. parseConstructorArgElement(beanName, cargs, (Element) node);
  284. }
  285. }
  286. return cargs;
  287. }
  288. /**
  289. * Parse property value subelements of the given bean element.
  290. */
  291. protected MutablePropertyValues getPropertyValueSubElements(String beanName, Element beanEle) {
  292. NodeList nl = beanEle.getChildNodes();
  293. MutablePropertyValues pvs = new MutablePropertyValues();
  294. for (int i = 0; i < nl.getLength(); i++) {
  295. Node node = nl.item(i);
  296. if (node instanceof Element && PROPERTY_ELEMENT.equals(node.getNodeName())) {
  297. parsePropertyElement(beanName, pvs, (Element) node);
  298. }
  299. }
  300. return pvs;
  301. }
  302. /**
  303. * Parse a constructor-arg element.
  304. */
  305. protected void parseConstructorArgElement(String beanName, ConstructorArgumentValues cargs, Element ele)
  306. throws DOMException, ClassNotFoundException {
  307. Object val = getPropertyValue(ele, beanName);
  308. String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
  309. String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
  310. if (!"".equals(indexAttr)) {
  311. try {
  312. int index = Integer.parseInt(indexAttr);
  313. if (index < 0) {
  314. throw new BeanDefinitionStoreException(this.resource, beanName, "'index' cannot be lower than 0");
  315. }
  316. if (!"".equals(typeAttr)) {
  317. cargs.addIndexedArgumentValue(index, val, typeAttr);
  318. }
  319. else {
  320. cargs.addIndexedArgumentValue(index, val);
  321. }
  322. }
  323. catch (NumberFormatException ex) {
  324. throw new BeanDefinitionStoreException(this.resource, beanName,
  325. "Attribute 'index' of tag 'constructor-arg' must be an integer");
  326. }
  327. }
  328. else {
  329. if (!"".equals(typeAttr)) {
  330. cargs.addGenericArgumentValue(val, typeAttr);
  331. }
  332. else {
  333. cargs.addGenericArgumentValue(val);
  334. }
  335. }
  336. }
  337. /**
  338. * Parse a property element.
  339. */
  340. protected void parsePropertyElement(String beanName, MutablePropertyValues pvs, Element ele)
  341. throws DOMException {
  342. String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
  343. if ("".equals(propertyName)) {
  344. throw new BeanDefinitionStoreException(this.resource, beanName,
  345. "Tag 'property' must have a 'name' attribute");
  346. }
  347. Object val = getPropertyValue(ele, beanName);
  348. pvs.addPropertyValue(new PropertyValue(propertyName, val));
  349. }
  350. /**
  351. * Get the value of a property element. May be a list.
  352. * @param ele property element
  353. */
  354. protected Object getPropertyValue(Element ele, String beanName) {
  355. // should only have one element child: value, ref, collection
  356. NodeList nl = ele.getChildNodes();
  357. Element valueRefOrCollectionElement = null;
  358. for (int i = 0; i < nl.getLength(); i++) {
  359. if (nl.item(i) instanceof Element) {
  360. Element candidateEle = (Element) nl.item(i);
  361. if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) {
  362. // keep going: we don't use this value for now
  363. }
  364. else {
  365. // child element is what we're looking for
  366. valueRefOrCollectionElement = candidateEle;
  367. }
  368. }
  369. }
  370. if (valueRefOrCollectionElement == null) {
  371. throw new BeanDefinitionStoreException(this.resource, beanName,
  372. "<property> element must have a subelement like 'value' or 'ref'");
  373. }
  374. return parsePropertySubelement(valueRefOrCollectionElement, beanName);
  375. }
  376. /**
  377. * Parse a value, ref or collection subelement of a property element
  378. * @param ele subelement of property element; we don't know which yet
  379. */
  380. protected Object parsePropertySubelement(Element ele, String beanName) {
  381. if (ele.getTagName().equals(BEAN_ELEMENT)) {
  382. return parseBeanDefinition(ele);
  383. }
  384. else if (ele.getTagName().equals(REF_ELEMENT)) {
  385. // a generic reference to any name of any bean
  386. String beanRef = ele.getAttribute(BEAN_REF_ATTRIBUTE);
  387. if ("".equals(beanRef)) {
  388. // a reference to the id of another bean in the same XML file
  389. beanRef = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
  390. if ("".equals(beanRef)) {
  391. throw new BeanDefinitionStoreException(this.resource, beanName,
  392. "Either 'bean' or 'local' is required for a reference");
  393. }
  394. }
  395. return new RuntimeBeanReference(beanRef);
  396. }
  397. else if (ele.getTagName().equals(IDREF_ELEMENT)) {
  398. // a generic reference to any name of any bean
  399. String beanRef = ele.getAttribute(BEAN_REF_ATTRIBUTE);
  400. if ("".equals(beanRef)) {
  401. // a reference to the id of another bean in the same XML file
  402. beanRef = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
  403. if ("".equals(beanRef)) {
  404. throw new BeanDefinitionStoreException(this.resource, beanName,
  405. "Either 'bean' or 'local' is required for an idref");
  406. }
  407. }
  408. return beanRef;
  409. }
  410. else if (ele.getTagName().equals(LIST_ELEMENT)) {
  411. return getList(ele, beanName);
  412. }
  413. else if (ele.getTagName().equals(SET_ELEMENT)) {
  414. return getSet(ele, beanName);
  415. }
  416. else if (ele.getTagName().equals(MAP_ELEMENT)) {
  417. return getMap(ele, beanName);
  418. }
  419. else if (ele.getTagName().equals(PROPS_ELEMENT)) {
  420. return getProps(ele, beanName);
  421. }
  422. else if (ele.getTagName().equals(VALUE_ELEMENT)) {
  423. // it's a literal value
  424. return getTextValue(ele, beanName);
  425. }
  426. else if (ele.getTagName().equals(NULL_ELEMENT)) {
  427. // it's a distinguished null value
  428. return null;
  429. }
  430. throw new BeanDefinitionStoreException(this.resource, beanName,
  431. "Unknown subelement of <property>: <" + ele.getTagName() + ">");
  432. }
  433. protected List getList(Element collectionEle, String beanName) {
  434. NodeList nl = collectionEle.getChildNodes();
  435. ManagedList list = new ManagedList(nl.getLength());
  436. for (int i = 0; i < nl.getLength(); i++) {
  437. if (nl.item(i) instanceof Element) {
  438. Element ele = (Element) nl.item(i);
  439. list.add(parsePropertySubelement(ele, beanName));
  440. }
  441. }
  442. return list;
  443. }
  444. protected Set getSet(Element collectionEle, String beanName) {
  445. NodeList nl = collectionEle.getChildNodes();
  446. ManagedSet set = new ManagedSet(nl.getLength());
  447. for (int i = 0; i < nl.getLength(); i++) {
  448. if (nl.item(i) instanceof Element) {
  449. Element ele = (Element) nl.item(i);
  450. set.add(parsePropertySubelement(ele, beanName));
  451. }
  452. }
  453. return set;
  454. }
  455. protected Map getMap(Element mapEle, String beanName) {
  456. List list = getChildElementsByTagName(mapEle, ENTRY_ELEMENT);
  457. Map map = null;
  458. // A LinkedHashMap will preserve insertion order, but is not available pre-1.4.
  459. if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_14) {
  460. map = ManagedLinkedMapCreator.createManagedLinkedMap(list.size());
  461. // ManagedLinkedMap = a tag subclass of java.util.LinkedHashMap
  462. }
  463. else {
  464. map = new ManagedMap(list.size()); // a tag subclass of java.util.HashMap
  465. }
  466. for (int i = 0; i < list.size(); i++) {
  467. Element entryEle = (Element) list.get(i);
  468. String key = entryEle.getAttribute(KEY_ATTRIBUTE);
  469. // TODO hack: make more robust
  470. NodeList subEles = entryEle.getElementsByTagName("*");
  471. map.put(key, parsePropertySubelement((Element) subEles.item(0), beanName));
  472. }
  473. return map;
  474. }
  475. /**
  476. * Don't use the horrible DOM API to get child elements:
  477. * Get an element's children with a given element name
  478. */
  479. protected List getChildElementsByTagName(Element mapEle, String elementName) {
  480. NodeList nl = mapEle.getChildNodes();
  481. List nodes = new ArrayList();
  482. for (int i = 0; i < nl.getLength(); i++) {
  483. Node n = nl.item(i);
  484. if (n instanceof Element && elementName.equals(n.getNodeName())) {
  485. nodes.add(n);
  486. }
  487. }
  488. return nodes;
  489. }
  490. protected Properties getProps(Element propsEle, String beanName) {
  491. Properties props = new Properties();
  492. NodeList nl = propsEle.getElementsByTagName(PROP_ELEMENT);
  493. for (int i = 0; i < nl.getLength(); i++) {
  494. Element propEle = (Element) nl.item(i);
  495. String key = propEle.getAttribute(KEY_ATTRIBUTE);
  496. // trim the text value to avoid unwanted whitespace
  497. // caused by typical XML formatting
  498. String value = getTextValue(propEle, beanName).trim();
  499. props.setProperty(key, value);
  500. }
  501. return props;
  502. }
  503. /**
  504. * Make the horrible DOM API slightly more bearable:
  505. * get the text value we know this element contains
  506. */
  507. protected String getTextValue(Element ele, String beanName) {
  508. NodeList nl = ele.getChildNodes();
  509. if (nl.item(0) == null) {
  510. // treat empty value as empty String
  511. return "";
  512. }
  513. if (nl.getLength() != 1 || !(nl.item(0) instanceof Text)) {
  514. throw new BeanDefinitionStoreException(this.resource, beanName,
  515. "Unexpected element or type mismatch: expected single node of " +
  516. nl.item(0).getClass() + " to be of type Text: " + "found " + ele, null);
  517. }
  518. Text t = (Text) nl.item(0);
  519. // This will be a String
  520. return t.getData();
  521. }
  522. protected int getDependencyCheck(String att) {
  523. int dependencyCheckCode = RootBeanDefinition.DEPENDENCY_CHECK_NONE;
  524. if (DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE.equals(att)) {
  525. dependencyCheckCode = RootBeanDefinition.DEPENDENCY_CHECK_ALL;
  526. }
  527. else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) {
  528. dependencyCheckCode = RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE;
  529. }
  530. else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) {
  531. dependencyCheckCode = RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS;
  532. }
  533. // else leave default value
  534. return dependencyCheckCode;
  535. }
  536. protected int getAutowireMode(String att) {
  537. int autowire = RootBeanDefinition.AUTOWIRE_NO;
  538. if (AUTOWIRE_BY_NAME_VALUE.equals(att)) {
  539. autowire = RootBeanDefinition.AUTOWIRE_BY_NAME;
  540. }
  541. else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) {
  542. autowire = RootBeanDefinition.AUTOWIRE_BY_TYPE;
  543. }
  544. else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) {
  545. autowire = RootBeanDefinition.AUTOWIRE_CONSTRUCTOR;
  546. }
  547. else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) {
  548. autowire = RootBeanDefinition.AUTOWIRE_AUTODETECT;
  549. }
  550. // else leave default value
  551. return autowire;
  552. }
  553. /**
  554. * Actual creation of a ManagedLinkedMap.
  555. * In separate inner class to avoid runtime dependency on JDK 1.4.
  556. */
  557. private static abstract class ManagedLinkedMapCreator {
  558. private static Map createManagedLinkedMap(int capacity) {
  559. return new ManagedLinkedMap(capacity);
  560. }
  561. }
  562. }