Source Code Cross Referenced for SpringNamespaceHelper.java in  » Web-Framework » Caramba » org » caramba » spring » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » Caramba » org.caramba.spring 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.caramba.spring;
0002:
0003:        import org.springframework.beans.factory.xml.XmlBeanDefinitionParser;
0004:        import org.springframework.beans.factory.xml.NamespaceHandlerResolver;
0005:        import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver;
0006:        import org.springframework.beans.factory.xml.NamespaceHandler;
0007:        import org.springframework.beans.factory.xml.BeanDefinitionParser;
0008:        import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
0009:        import org.springframework.beans.factory.support.BeanDefinitionReader;
0010:        import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
0011:        import org.springframework.beans.factory.support.AbstractBeanDefinition;
0012:        import org.springframework.beans.factory.support.MethodOverrides;
0013:        import org.springframework.beans.factory.support.LookupOverride;
0014:        import org.springframework.beans.factory.support.ReplaceOverride;
0015:        import org.springframework.beans.factory.support.ManagedList;
0016:        import org.springframework.beans.factory.support.ManagedSet;
0017:        import org.springframework.beans.factory.support.ManagedMap;
0018:        import org.springframework.beans.factory.support.ReaderContext;
0019:        import org.springframework.beans.factory.BeanDefinitionStoreException;
0020:        import org.springframework.beans.factory.config.BeanDefinitionHolder;
0021:        import org.springframework.beans.factory.config.BeanDefinition;
0022:        import org.springframework.beans.factory.config.ConstructorArgumentValues;
0023:        import org.springframework.beans.factory.config.RuntimeBeanReference;
0024:        import org.springframework.beans.factory.config.TypedStringValue;
0025:        import org.springframework.beans.MutablePropertyValues;
0026:        import org.springframework.core.io.Resource;
0027:        import org.springframework.core.io.support.ResourcePatternUtils;
0028:        import org.springframework.util.SystemPropertyUtils;
0029:        import org.springframework.util.StringUtils;
0030:        import org.springframework.util.ClassUtils;
0031:        import org.springframework.util.xml.DomUtils;
0032:        import org.apache.commons.logging.Log;
0033:        import org.apache.commons.logging.LogFactory;
0034:        import org.w3c.dom.Document;
0035:        import org.w3c.dom.Element;
0036:        import org.w3c.dom.NodeList;
0037:        import org.w3c.dom.Node;
0038:
0039:        import java.io.IOException;
0040:        import java.util.List;
0041:        import java.util.ArrayList;
0042:        import java.util.Arrays;
0043:        import java.util.Iterator;
0044:        import java.util.Set;
0045:        import java.util.Map;
0046:        import java.util.Properties;
0047:
0048:        /*
0049:         * Copyright 2002-2005 the original author or authors.
0050:         *
0051:         * Licensed under the Apache License, Version 2.0 (the "License");
0052:         * you may not use this file except in compliance with the License.
0053:         * You may obtain a copy of the License at
0054:         *
0055:         *      http://www.apache.org/licenses/LICENSE-2.0
0056:         *
0057:         * Unless required by applicable law or agreed to in writing, software
0058:         * distributed under the License is distributed on an "AS IS" BASIS,
0059:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0060:         * See the License for the specific language governing permissions and
0061:         * limitations under the License.
0062:         */
0063:
0064:        /**
0065:         * Default implementation of the XmlBeanDefinitionParser interface.
0066:         * Parses bean definitions according to the "spring-beans" DTD,
0067:         * that is, Spring's default XML bean definition format.
0068:         * <p/>
0069:         * <p>The structure, elements and attribute names of the required XML document
0070:         * are hard-coded in this class. (Of course a transform could be run if necessary
0071:         * to produce this format). <code>&lt;beans&gt;</code> doesn't need to be the root
0072:         * element of the XML document: This class will parse all bean definition elements
0073:         * in the XML file, not regarding the actual root element.
0074:         *
0075:         * @author Rod Johnson
0076:         * @author Juergen Hoeller
0077:         * @author Rob Harrop
0078:         * @author Erik Wiersma
0079:         * @since 18.12.2003
0080:         */
0081:        public class SpringNamespaceHelper implements  XmlBeanDefinitionParser {
0082:
0083:            public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
0084:
0085:            public static final String BEAN_NAME_DELIMITERS = ",; ";
0086:
0087:            /**
0088:             * Value of a T/F attribute that represents true.
0089:             * Anything else represents false. Case seNsItive.
0090:             */
0091:            public static final String TRUE_VALUE = "true";
0092:            public static final String DEFAULT_VALUE = "default";
0093:            public static final String DESCRIPTION_ELEMENT = "description";
0094:
0095:            public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
0096:            public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
0097:            public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor";
0098:            public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";
0099:
0100:            public static final String DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE = "all";
0101:            public static final String DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE = "simple";
0102:            public static final String DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE = "objects";
0103:
0104:            public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
0105:            public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
0106:            public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
0107:            public static final String DEFAULT_INIT_METHOD_ATTRIBUTE = "default-init-method";
0108:            public static final String DEFAULT_DESTROY_METHOD_ATTRIBUTE = "default-destroy-method";
0109:
0110:            public static final String IMPORT_ELEMENT = "import";
0111:            public static final String RESOURCE_ATTRIBUTE = "resource";
0112:
0113:            public static final String ALIAS_ELEMENT = "alias";
0114:            public static final String NAME_ATTRIBUTE = "name";
0115:            public static final String ALIAS_ATTRIBUTE = "alias";
0116:
0117:            public static final String BEAN_ELEMENT = "bean";
0118:            public static final String ID_ATTRIBUTE = "id";
0119:            public static final String PARENT_ATTRIBUTE = "parent";
0120:
0121:            public static final String CLASS_ATTRIBUTE = "class";
0122:            public static final String ABSTRACT_ATTRIBUTE = "abstract";
0123:            public static final String SINGLETON_ATTRIBUTE = "singleton";
0124:            public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
0125:            public static final String AUTOWIRE_ATTRIBUTE = "autowire";
0126:            public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check";
0127:            public static final String DEPENDS_ON_ATTRIBUTE = "depends-on";
0128:            public static final String INIT_METHOD_ATTRIBUTE = "init-method";
0129:            public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
0130:            public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method";
0131:            public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean";
0132:
0133:            public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg";
0134:            public static final String INDEX_ATTRIBUTE = "index";
0135:            public static final String TYPE_ATTRIBUTE = "type";
0136:            public static final String PROPERTY_ELEMENT = "property";
0137:            public static final String REF_ATTRIBUTE = "ref";
0138:            public static final String VALUE_ATTRIBUTE = "value";
0139:            public static final String LOOKUP_METHOD_ELEMENT = "lookup-method";
0140:
0141:            public static final String REPLACED_METHOD_ELEMENT = "replaced-method";
0142:            public static final String REPLACER_ATTRIBUTE = "replacer";
0143:            public static final String ARG_TYPE_ELEMENT = "arg-type";
0144:            public static final String ARG_TYPE_MATCH_ATTRIBUTE = "match";
0145:
0146:            public static final String REF_ELEMENT = "ref";
0147:            public static final String IDREF_ELEMENT = "idref";
0148:            public static final String BEAN_REF_ATTRIBUTE = "bean";
0149:            public static final String LOCAL_REF_ATTRIBUTE = "local";
0150:            public static final String PARENT_REF_ATTRIBUTE = "parent";
0151:
0152:            public static final String VALUE_ELEMENT = "value";
0153:            public static final String NULL_ELEMENT = "null";
0154:            public static final String LIST_ELEMENT = "list";
0155:            public static final String SET_ELEMENT = "set";
0156:            public static final String MAP_ELEMENT = "map";
0157:            public static final String ENTRY_ELEMENT = "entry";
0158:            public static final String KEY_ELEMENT = "key";
0159:            public static final String KEY_ATTRIBUTE = "key";
0160:            public static final String KEY_REF_ATTRIBUTE = "key-ref";
0161:            public static final String VALUE_REF_ATTRIBUTE = "value-ref";
0162:            public static final String PROPS_ELEMENT = "props";
0163:            public static final String PROP_ELEMENT = "prop";
0164:
0165:            protected final Log logger = LogFactory.getLog(getClass());
0166:
0167:            private BeanDefinitionReader beanDefinitionReader;
0168:
0169:            private NamespaceHandlerResolver namespaceHandlerResolver;
0170:
0171:            private Resource resource;
0172:
0173:            private String defaultLazyInit;
0174:
0175:            private String defaultAutowire;
0176:
0177:            private String defaultDependencyCheck;
0178:
0179:            private String defaultInitMethod;
0180:
0181:            private String defaultDestroyMethod;
0182:
0183:            /**
0184:             * Parses bean definitions according to the "spring-beans" DTD.
0185:             * <p>Opens a DOM Document; then initializes the default settings
0186:             * specified at <code>&lt;beans&gt;</code> level; then parses
0187:             * the contained bean definitions.
0188:             */
0189:            public int registerBeanDefinitions(BeanDefinitionReader reader,
0190:                    Document doc, Resource resource)
0191:                    throws BeanDefinitionStoreException {
0192:
0193:                this .beanDefinitionReader = reader;
0194:                this .resource = resource;
0195:
0196:                logger.debug("Loading bean definitions");
0197:                Element root = doc.getDocumentElement();
0198:
0199:                initDefaults(root);
0200:                if (logger.isDebugEnabled()) {
0201:                    logger.debug("Default lazy init '" + getDefaultLazyInit()
0202:                            + "'");
0203:                    logger.debug("Default autowire '" + getDefaultAutowire()
0204:                            + "'");
0205:                    logger.debug("Default dependency check '"
0206:                            + getDefaultDependencyCheck() + "'");
0207:                }
0208:
0209:                preProcessXml(root);
0210:                int beanDefinitionCount = parseBeanDefinitions(root);
0211:                if (logger.isDebugEnabled()) {
0212:                    logger.debug("Found " + beanDefinitionCount
0213:                            + " <bean> elements in " + resource);
0214:                }
0215:                postProcessXml(root);
0216:
0217:                return beanDefinitionCount;
0218:            }
0219:
0220:            /**
0221:             * Return the BeanDefinitionReader that this parser has been called from.
0222:             */
0223:            protected final BeanDefinitionReader getBeanDefinitionReader() {
0224:                return beanDefinitionReader;
0225:            }
0226:
0227:            /**
0228:             * Return the descriptor for the XML resource that this parser works on.
0229:             */
0230:            protected final Resource getResource() {
0231:                return resource;
0232:            }
0233:
0234:            /**
0235:             * Initialize the default lazy-init, autowire and dependency check settings.
0236:             *
0237:             * @see #setDefaultLazyInit
0238:             * @see #setDefaultAutowire
0239:             * @see #setDefaultDependencyCheck
0240:             */
0241:            protected void initDefaults(Element root) {
0242:                setDefaultLazyInit(root
0243:                        .getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE));
0244:                setDefaultAutowire(root
0245:                        .getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE));
0246:                setDefaultDependencyCheck(root
0247:                        .getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
0248:                if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
0249:                    setDefaultInitMethod(root
0250:                            .getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
0251:                }
0252:                if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
0253:                    setDefaultDestroyMethod(root
0254:                            .getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
0255:                }
0256:            }
0257:
0258:            /**
0259:             * Set the default lazy-init flag for the document that's currently parsed.
0260:             */
0261:            protected final void setDefaultLazyInit(String defaultLazyInit) {
0262:                this .defaultLazyInit = defaultLazyInit;
0263:            }
0264:
0265:            /**
0266:             * Return the default lazy-init flag for the document that's currently parsed.
0267:             */
0268:            protected final String getDefaultLazyInit() {
0269:                return defaultLazyInit;
0270:            }
0271:
0272:            /**
0273:             * Set the default autowire setting for the document that's currently parsed.
0274:             */
0275:            protected final void setDefaultAutowire(String defaultAutowire) {
0276:                this .defaultAutowire = defaultAutowire;
0277:            }
0278:
0279:            /**
0280:             * Return the default autowire setting for the document that's currently parsed.
0281:             */
0282:            protected final String getDefaultAutowire() {
0283:                return defaultAutowire;
0284:            }
0285:
0286:            /**
0287:             * Set the default dependency-check setting for the document that's currently parsed.
0288:             */
0289:            protected final void setDefaultDependencyCheck(
0290:                    String defaultDependencyCheck) {
0291:                this .defaultDependencyCheck = defaultDependencyCheck;
0292:            }
0293:
0294:            /**
0295:             * Return the default dependency-check setting for the document that's currently parsed.
0296:             */
0297:            protected final String getDefaultDependencyCheck() {
0298:                return defaultDependencyCheck;
0299:            }
0300:
0301:            /**
0302:             * Set the default dependency-init-method setting for the document that's currently parsed.
0303:             */
0304:            protected final void setDefaultInitMethod(String defaultInitMethod) {
0305:                this .defaultInitMethod = defaultInitMethod;
0306:            }
0307:
0308:            /**
0309:             * Return the default dependency-init-method setting for the document that's currently parsed.
0310:             */
0311:            protected final String getDefaultInitMethod() {
0312:                return defaultInitMethod;
0313:            }
0314:
0315:            /**
0316:             * Set the default dependency-destroy-method setting for the document that's currently parsed.
0317:             */
0318:            protected final void setDefaultDestroyMethod(
0319:                    String defaultDestroyMethod) {
0320:                this .defaultDestroyMethod = defaultDestroyMethod;
0321:            }
0322:
0323:            /**
0324:             * Return the default dependency-destroy-method setting for the document that's currently parsed.
0325:             */
0326:            protected final String getDefaultDestroyMethod() {
0327:                return defaultDestroyMethod;
0328:            }
0329:
0330:            /**
0331:             * Allow the XML to be extensible by processing any custom element types first,
0332:             * before we start to process the bean definitions. This method is a natural
0333:             * extension point for any other custom pre-processing of the XML.
0334:             * <p>Default implementation is empty. Subclasses can override this method to
0335:             * convert custom elements into standard Spring bean definitions, for example.
0336:             * Implementors have access to the parser's bean definition reader and the
0337:             * underlying XML resource, through the corresponding accessors.
0338:             *
0339:             * @see #getBeanDefinitionReader()
0340:             * @see #getResource()
0341:             */
0342:            protected void preProcessXml(Element root)
0343:                    throws BeanDefinitionStoreException {
0344:            }
0345:
0346:            protected NamespaceHandlerResolver createNamespaceHandlerResolver() {
0347:                ClassLoader classLoader = this .beanDefinitionReader
0348:                        .getBeanClassLoader();
0349:                if (classLoader == null) {
0350:                    classLoader = Thread.currentThread()
0351:                            .getContextClassLoader();
0352:                }
0353:                return new DefaultNamespaceHandlerResolver(classLoader);
0354:            }
0355:
0356:            /**
0357:             * Parse the elements at the root level in the document:
0358:             * "import", "alias", "bean".
0359:             *
0360:             * @param root the DOM root element of the document
0361:             * @return the number of bean definitions found
0362:             */
0363:            protected int parseBeanDefinitions(Element root)
0364:                    throws BeanDefinitionStoreException {
0365:                NodeList nl = root.getChildNodes();
0366:                int beanDefinitionCount = 0;
0367:                for (int i = 0; i < nl.getLength(); i++) {
0368:                    Node node = nl.item(i);
0369:                    if (node instanceof  Element) {
0370:                        Element ele = (Element) node;
0371:                        String namespaceUri = ele.getNamespaceURI();
0372:
0373:                        if (isDefaultNamespace(namespaceUri)) {
0374:                            beanDefinitionCount += parseDefaultElement(ele);
0375:                        } else {
0376:                            beanDefinitionCount += parseCustomElement(ele);
0377:                        }
0378:                    }
0379:                }
0380:                return beanDefinitionCount;
0381:            }
0382:
0383:            private boolean isDefaultNamespace(String namespaceUri) {
0384:                return namespaceUri == null
0385:                        || BEANS_NAMESPACE_URI.equals(namespaceUri);
0386:            }
0387:
0388:            private int parseDefaultElement(Element ele) {
0389:                if (IMPORT_ELEMENT.equals(ele.getNodeName())) {
0390:                    importBeanDefinitionResource(ele);
0391:                    return 0;
0392:                } else if (ALIAS_ELEMENT.equals(ele.getNodeName())) {
0393:                    String name = ele.getAttribute(NAME_ATTRIBUTE);
0394:                    String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
0395:                    this .beanDefinitionReader.getBeanFactory().registerAlias(
0396:                            name, alias);
0397:                    return 0;
0398:                } else if (BEAN_ELEMENT.equals(ele.getNodeName())) {
0399:                    BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(
0400:                            ele, false);
0401:                    return decorateAndRegisterBeanDefinition(ele, bdHolder);
0402:                } else {
0403:                    // non-important element
0404:                    return 0;
0405:                }
0406:            }
0407:
0408:            protected int parseCustomElement(Element ele) {
0409:                String namespaceUri = ele.getNamespaceURI();
0410:                NamespaceHandler handler = getNamespaceHandlerResolver()
0411:                        .resolve(namespaceUri);
0412:
0413:                if (handler == null) {
0414:                    throw new BeanDefinitionStoreException(
0415:                            "Unable to locate NamespaceHandler for namespace ["
0416:                                    + namespaceUri + "].");
0417:                }
0418:                int countBefore = getBeanDefinitionCount();
0419:                BeanDefinitionParser parser = handler.findParserForElement(ele);
0420:                //            PDG parser.parse(ele, this.beanDefinitionReader.getBeanFactory());
0421:                return (getBeanDefinitionCount() - countBefore);
0422:            }
0423:
0424:            private NamespaceHandlerResolver getNamespaceHandlerResolver() {
0425:                if (this .namespaceHandlerResolver == null) {
0426:                    this .namespaceHandlerResolver = createNamespaceHandlerResolver();
0427:                }
0428:                return this .namespaceHandlerResolver;
0429:            }
0430:
0431:            private int decorateAndRegisterBeanDefinition(Element element,
0432:                    BeanDefinitionHolder definitionHolder) {
0433:                int registeredCount = 1;
0434:                BeanDefinitionHolder rootDefinition = definitionHolder;
0435:
0436:                NodeList children = element.getChildNodes();
0437:                for (int i = 0; i < children.getLength(); i++) {
0438:                    Node node = children.item(i);
0439:                    String uri = node.getNamespaceURI();
0440:                    if (node.getNodeType() == Node.ELEMENT_NODE
0441:                            && !isDefaultNamespace(uri)) {
0442:                        Element childElement = (Element) node;
0443:                        // a node from a namespace outside of the standard - should map to a decorator
0444:                        NamespaceHandler handler = getNamespaceHandlerResolver()
0445:                                .resolve(uri);
0446:                        BeanDefinitionDecorator decorator = handler
0447:                                .findDecoratorForElement(childElement);
0448:                        int countBefore = getBeanDefinitionCount();
0449:                        // PDG                rootDefinition = decorator.decorate(childElement, rootDefinition, this.beanDefinitionReader.getBeanFactory());
0450:                        registeredCount += (getBeanDefinitionCount() - countBefore);
0451:                    }
0452:                }
0453:                // register the final decorated instance
0454:                BeanDefinitionReaderUtils.registerBeanDefinition(
0455:                        rootDefinition, this .beanDefinitionReader
0456:                                .getBeanFactory());
0457:                return registeredCount;
0458:            }
0459:
0460:            private int getBeanDefinitionCount() {
0461:                return this .beanDefinitionReader.getBeanFactory()
0462:                        .getBeanDefinitionCount();
0463:            }
0464:
0465:            /**
0466:             * Parse an "import" element and load the bean definitions
0467:             * from the given resource into the bean factory.
0468:             */
0469:            protected void importBeanDefinitionResource(Element ele)
0470:                    throws BeanDefinitionStoreException {
0471:                String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
0472:                // Resolve system properties: e.g. "${user.dir}"
0473:                location = SystemPropertyUtils.resolvePlaceholders(location);
0474:
0475:                if (ResourcePatternUtils.isUrl(location)) {
0476:                    int importCount = getBeanDefinitionReader()
0477:                            .loadBeanDefinitions(location);
0478:                    if (logger.isDebugEnabled()) {
0479:                        logger.debug("Imported " + importCount
0480:                                + " bean definitions from URL location ["
0481:                                + location + "]");
0482:                    }
0483:                } else {
0484:                    // No URL -> considering resource location as relative to the current file.
0485:                    try {
0486:                        Resource relativeResource = getResource()
0487:                                .createRelative(location);
0488:                        int importCount = getBeanDefinitionReader()
0489:                                .loadBeanDefinitions(relativeResource);
0490:                        if (logger.isDebugEnabled()) {
0491:                            logger
0492:                                    .debug("Imported "
0493:                                            + importCount
0494:                                            + " bean definitions from relative location ["
0495:                                            + location + "]");
0496:                        }
0497:                    } catch (IOException ex) {
0498:                        throw new BeanDefinitionStoreException(
0499:                                "Invalid relative resource location ["
0500:                                        + location
0501:                                        + "] to import bean definitions from",
0502:                                ex);
0503:                    }
0504:                }
0505:            }
0506:
0507:            /**
0508:             * Allow the XML to be extensible by processing any custom element types last,
0509:             * after we finished processing the bean definitions. This method is a natural
0510:             * extension point for any other custom post-processing of the XML.
0511:             * <p>Default implementation is empty. Subclasses can override this method to
0512:             * convert custom elements into standard Spring bean definitions, for example.
0513:             * Implementors have access to the parser's bean definition reader and the
0514:             * underlying XML resource, through the corresponding accessors.
0515:             *
0516:             * @see #getBeanDefinitionReader()
0517:             * @see #getResource()
0518:             */
0519:            protected void postProcessXml(Element root)
0520:                    throws BeanDefinitionStoreException {
0521:            }
0522:
0523:            /**
0524:             * Parse a standard bean definition into a BeanDefinitionHolder,
0525:             * including bean name and aliases.
0526:             * <p>Bean elements specify their canonical name as "id" attribute
0527:             * and their aliases as a delimited "name" attribute.
0528:             * <p>If no "id" specified, uses the first name in the "name" attribute
0529:             * as canonical name, registering all others as aliases.
0530:             * <p>Callers should specify whether this element represents an inner bean
0531:             * definition or not by setting the <code>isInnerBean</code> argument appropriately
0532:             */
0533:            protected BeanDefinitionHolder parseBeanDefinitionElement(
0534:                    Element ele, boolean isInnerBean)
0535:                    throws BeanDefinitionStoreException {
0536:
0537:                String id = ele.getAttribute(ID_ATTRIBUTE);
0538:                String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
0539:
0540:                List aliases = new ArrayList();
0541:                if (StringUtils.hasLength(nameAttr)) {
0542:                    String[] nameArr = StringUtils.tokenizeToStringArray(
0543:                            nameAttr, BEAN_NAME_DELIMITERS);
0544:                    aliases.addAll(Arrays.asList(nameArr));
0545:                }
0546:
0547:                String beanName = id;
0548:                if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
0549:                    beanName = (String) aliases.remove(0);
0550:                    if (logger.isDebugEnabled()) {
0551:                        logger.debug("No XML 'id' specified - using '"
0552:                                + beanName + "' as bean name and " + aliases
0553:                                + " as aliases");
0554:                    }
0555:                }
0556:
0557:                BeanDefinition beanDefinition = parseBeanDefinitionElement(ele,
0558:                        beanName);
0559:
0560:                if (!StringUtils.hasText(beanName)
0561:                        && beanDefinition instanceof  AbstractBeanDefinition) {
0562:                    beanName = BeanDefinitionReaderUtils.generateBeanName(
0563:                            (AbstractBeanDefinition) beanDefinition,
0564:                            this .beanDefinitionReader.getBeanFactory(),
0565:                            isInnerBean);
0566:                    if (logger.isDebugEnabled()) {
0567:                        logger.debug("Neither XML 'id' nor 'name' specified - "
0568:                                + "using generated bean name [" + beanName
0569:                                + "]");
0570:                    }
0571:                }
0572:
0573:                String[] aliasesArray = (String[]) aliases
0574:                        .toArray(new String[aliases.size()]);
0575:                return new BeanDefinitionHolder(beanDefinition, beanName,
0576:                        aliasesArray);
0577:            }
0578:
0579:            /**
0580:             * Parse the BeanDefinition itself, without regard to name or aliases.
0581:             */
0582:            protected BeanDefinition parseBeanDefinitionElement(Element ele,
0583:                    String beanName) throws BeanDefinitionStoreException {
0584:
0585:                String className = null;
0586:                if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
0587:                    className = ele.getAttribute(CLASS_ATTRIBUTE);
0588:                }
0589:                String parent = null;
0590:                if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
0591:                    parent = ele.getAttribute(PARENT_ATTRIBUTE);
0592:                }
0593:
0594:                try {
0595:                    ConstructorArgumentValues cargs = parseConstructorArgElements(
0596:                            ele, beanName);
0597:                    MutablePropertyValues pvs = parsePropertyElements(ele,
0598:                            beanName);
0599:
0600:                    AbstractBeanDefinition bd = BeanDefinitionReaderUtils
0601:                            .createBeanDefinition(className, parent, cargs,
0602:                                    pvs, getBeanDefinitionReader()
0603:                                            .getBeanClassLoader());
0604:
0605:                    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
0606:                        String dependsOn = ele
0607:                                .getAttribute(DEPENDS_ON_ATTRIBUTE);
0608:                        bd.setDependsOn(StringUtils.tokenizeToStringArray(
0609:                                dependsOn, BEAN_NAME_DELIMITERS));
0610:                    }
0611:
0612:                    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
0613:                        bd.setFactoryMethodName(ele
0614:                                .getAttribute(FACTORY_METHOD_ATTRIBUTE));
0615:                    }
0616:                    if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
0617:                        bd.setFactoryBeanName(ele
0618:                                .getAttribute(FACTORY_BEAN_ATTRIBUTE));
0619:                    }
0620:
0621:                    String dependencyCheck = ele
0622:                            .getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
0623:                    if (DEFAULT_VALUE.equals(dependencyCheck)) {
0624:                        dependencyCheck = getDefaultDependencyCheck();
0625:                    }
0626:                    bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
0627:
0628:                    String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
0629:                    if (DEFAULT_VALUE.equals(autowire)) {
0630:                        autowire = getDefaultAutowire();
0631:                    }
0632:                    bd.setAutowireMode(getAutowireMode(autowire));
0633:
0634:                    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
0635:                        String initMethodName = ele
0636:                                .getAttribute(INIT_METHOD_ATTRIBUTE);
0637:                        if (!"".equals(initMethodName)) {
0638:                            bd.setInitMethodName(initMethodName);
0639:                        }
0640:                    } else {
0641:                        if (getDefaultInitMethod() != null) {
0642:                            bd.setInitMethodName(getDefaultInitMethod());
0643:                            bd.setEnforceInitMethod(false);
0644:                        }
0645:                    }
0646:
0647:                    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
0648:                        String destroyMethodName = ele
0649:                                .getAttribute(DESTROY_METHOD_ATTRIBUTE);
0650:                        if (!"".equals(destroyMethodName)) {
0651:                            bd.setDestroyMethodName(destroyMethodName);
0652:                        }
0653:                    } else {
0654:                        if (getDefaultDestroyMethod() != null) {
0655:                            bd.setDestroyMethodName(getDefaultDestroyMethod());
0656:                            bd.setEnforceDestroyMethod(false);
0657:                        }
0658:                    }
0659:
0660:                    parseLookupOverrideSubElements(ele, beanName, bd
0661:                            .getMethodOverrides());
0662:                    parseReplacedMethodSubElements(ele, beanName, bd
0663:                            .getMethodOverrides());
0664:
0665:                    bd.setResourceDescription(getResource().getDescription());
0666:
0667:                    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
0668:                        bd.setAbstract(TRUE_VALUE.equals(ele
0669:                                .getAttribute(ABSTRACT_ATTRIBUTE)));
0670:                    }
0671:
0672:                    if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
0673:                        bd.setSingleton(TRUE_VALUE.equals(ele
0674:                                .getAttribute(SINGLETON_ATTRIBUTE)));
0675:                    }
0676:
0677:                    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
0678:                    if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
0679:                        // Just apply default to singletons, as lazy-init has no meaning for prototypes.
0680:                        lazyInit = getDefaultLazyInit();
0681:                    }
0682:                    bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
0683:
0684:                    return bd;
0685:                } catch (ClassNotFoundException ex) {
0686:                    throw new BeanDefinitionStoreException(getResource(),
0687:                            beanName, "Bean class [" + className
0688:                                    + "] not found", ex);
0689:                } catch (NoClassDefFoundError err) {
0690:                    throw new BeanDefinitionStoreException(getResource(),
0691:                            beanName, "Class that bean class [" + className
0692:                                    + "] depends on not found", err);
0693:                }
0694:            }
0695:
0696:            protected int getDependencyCheck(String att) {
0697:                int dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
0698:                if (DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE.equals(att)) {
0699:                    dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_ALL;
0700:                } else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) {
0701:                    dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE;
0702:                } else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) {
0703:                    dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS;
0704:                }
0705:                // Else leave default value.
0706:                return dependencyCheckCode;
0707:            }
0708:
0709:            protected int getAutowireMode(String att) {
0710:                int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
0711:                if (AUTOWIRE_BY_NAME_VALUE.equals(att)) {
0712:                    autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME;
0713:                } else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) {
0714:                    autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
0715:                } else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) {
0716:                    autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR;
0717:                } else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) {
0718:                    autowire = AbstractBeanDefinition.AUTOWIRE_AUTODETECT;
0719:                }
0720:                // Else leave default value.
0721:                return autowire;
0722:            }
0723:
0724:            /**
0725:             * Parse constructor-arg sub-elements of the given bean element.
0726:             */
0727:            protected ConstructorArgumentValues parseConstructorArgElements(
0728:                    Element beanEle, String beanName)
0729:                    throws BeanDefinitionStoreException {
0730:
0731:                NodeList nl = beanEle.getChildNodes();
0732:                ConstructorArgumentValues cargs = new ConstructorArgumentValues();
0733:                for (int i = 0; i < nl.getLength(); i++) {
0734:                    Node node = nl.item(i);
0735:                    if (node instanceof  Element
0736:                            && CONSTRUCTOR_ARG_ELEMENT.equals(node
0737:                                    .getNodeName())) {
0738:                        parseConstructorArgElement((Element) node, beanName,
0739:                                cargs);
0740:                    }
0741:                }
0742:                return cargs;
0743:            }
0744:
0745:            /**
0746:             * Parse property sub-elements of the given bean element.
0747:             */
0748:            public MutablePropertyValues parsePropertyElements(Element beanEle,
0749:                    String beanName) throws BeanDefinitionStoreException {
0750:
0751:                NodeList nl = beanEle.getChildNodes();
0752:                MutablePropertyValues pvs = new MutablePropertyValues();
0753:                for (int i = 0; i < nl.getLength(); i++) {
0754:                    Node node = nl.item(i);
0755:                    if (node instanceof  Element
0756:                            && PROPERTY_ELEMENT.equals(node.getNodeName())) {
0757:                        parsePropertyElement((Element) node, beanName, pvs);
0758:                    }
0759:                }
0760:                return pvs;
0761:            }
0762:
0763:            /**
0764:             * Parse lookup-override sub-elements of the given bean element.
0765:             */
0766:            protected void parseLookupOverrideSubElements(Element beanEle,
0767:                    String beanName, MethodOverrides overrides)
0768:                    throws BeanDefinitionStoreException {
0769:
0770:                NodeList nl = beanEle.getChildNodes();
0771:                for (int i = 0; i < nl.getLength(); i++) {
0772:                    Node node = nl.item(i);
0773:                    if (node instanceof  Element
0774:                            && LOOKUP_METHOD_ELEMENT.equals(node.getNodeName())) {
0775:                        Element ele = (Element) node;
0776:                        String methodName = ele.getAttribute(NAME_ATTRIBUTE);
0777:                        String beanRef = ele.getAttribute(BEAN_ELEMENT);
0778:                        overrides.addOverride(new LookupOverride(methodName,
0779:                                beanRef));
0780:                    }
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Parse replaced-method sub-elements of the given bean element.
0786:             */
0787:            protected void parseReplacedMethodSubElements(Element beanEle,
0788:                    String beanName, MethodOverrides overrides)
0789:                    throws BeanDefinitionStoreException {
0790:
0791:                NodeList nl = beanEle.getChildNodes();
0792:                for (int i = 0; i < nl.getLength(); i++) {
0793:                    Node node = nl.item(i);
0794:                    if (node instanceof  Element
0795:                            && REPLACED_METHOD_ELEMENT.equals(node
0796:                                    .getNodeName())) {
0797:                        Element replacedMethodEle = (Element) node;
0798:                        String name = replacedMethodEle
0799:                                .getAttribute(NAME_ATTRIBUTE);
0800:                        String callback = replacedMethodEle
0801:                                .getAttribute(REPLACER_ATTRIBUTE);
0802:                        ReplaceOverride replaceOverride = new ReplaceOverride(
0803:                                name, callback);
0804:                        // Look for arg-type match elements.
0805:                        List argTypeEles = DomUtils.getChildElementsByTagName(
0806:                                replacedMethodEle, ARG_TYPE_ELEMENT);
0807:                        for (Iterator it = argTypeEles.iterator(); it.hasNext();) {
0808:                            Element argTypeEle = (Element) it.next();
0809:                            replaceOverride.addTypeIdentifier(argTypeEle
0810:                                    .getAttribute(ARG_TYPE_MATCH_ATTRIBUTE));
0811:                        }
0812:                        overrides.addOverride(replaceOverride);
0813:                    }
0814:                }
0815:            }
0816:
0817:            /**
0818:             * Parse a constructor-arg element.
0819:             */
0820:            protected void parseConstructorArgElement(Element ele,
0821:                    String beanName, ConstructorArgumentValues cargs)
0822:                    throws BeanDefinitionStoreException {
0823:
0824:                Object val = parsePropertyValue(ele, beanName, null);
0825:                String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
0826:                String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
0827:                if (StringUtils.hasLength(indexAttr)) {
0828:                    try {
0829:                        int index = Integer.parseInt(indexAttr);
0830:                        if (index < 0) {
0831:                            throw new BeanDefinitionStoreException(
0832:                                    getResource(), beanName,
0833:                                    "'index' cannot be lower than 0");
0834:                        }
0835:                        if (StringUtils.hasLength(typeAttr)) {
0836:                            cargs.addIndexedArgumentValue(index, val, typeAttr);
0837:                        } else {
0838:                            cargs.addIndexedArgumentValue(index, val);
0839:                        }
0840:                    } catch (NumberFormatException ex) {
0841:                        throw new BeanDefinitionStoreException(getResource(),
0842:                                beanName,
0843:                                "Attribute 'index' of tag 'constructor-arg' must be an integer");
0844:                    }
0845:                } else {
0846:                    if (StringUtils.hasLength(typeAttr)) {
0847:                        cargs.addGenericArgumentValue(val, typeAttr);
0848:                    } else {
0849:                        cargs.addGenericArgumentValue(val);
0850:                    }
0851:                }
0852:            }
0853:
0854:            /**
0855:             * Parse a property element.
0856:             */
0857:            protected void parsePropertyElement(Element ele, String beanName,
0858:                    MutablePropertyValues pvs)
0859:                    throws BeanDefinitionStoreException {
0860:
0861:                String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
0862:                if (!StringUtils.hasLength(propertyName)) {
0863:                    throw new BeanDefinitionStoreException(getResource(),
0864:                            beanName,
0865:                            "Tag 'property' must have a 'name' attribute");
0866:                }
0867:                if (pvs.contains(propertyName)) {
0868:                    throw new BeanDefinitionStoreException(getResource(),
0869:                            beanName,
0870:                            "Multiple 'property' definitions for property '"
0871:                                    + propertyName + "'");
0872:                }
0873:                Object val = parsePropertyValue(ele, beanName, propertyName);
0874:                pvs.addPropertyValue(propertyName, val);
0875:            }
0876:
0877:            /**
0878:             * Get the value of a property element. May be a list etc.
0879:             * Also used for constructor arguments, "propertyName" being null in this case.
0880:             */
0881:            protected Object parsePropertyValue(Element ele, String beanName,
0882:                    String propertyName) throws BeanDefinitionStoreException {
0883:
0884:                String elementName = (propertyName != null) ? "<property> element for property '"
0885:                        + propertyName + "'"
0886:                        : "<constructor-arg> element";
0887:
0888:                // Should only have one child element: ref, value, list, etc.
0889:                NodeList nl = ele.getChildNodes();
0890:                Element subElement = null;
0891:                for (int i = 0; i < nl.getLength(); i++) {
0892:                    if (nl.item(i) instanceof  Element) {
0893:                        Element candidateEle = (Element) nl.item(i);
0894:                        if (DESCRIPTION_ELEMENT.equals(candidateEle
0895:                                .getTagName())) {
0896:                            // Keep going: we don't use this value for now.
0897:                        } else {
0898:                            // Child element is what we're looking for.
0899:                            if (subElement != null) {
0900:                                throw new BeanDefinitionStoreException(
0901:                                        getResource(),
0902:                                        beanName,
0903:                                        elementName
0904:                                                + " must not contain more than one sub-element");
0905:                            }
0906:                            subElement = candidateEle;
0907:                        }
0908:                    }
0909:                }
0910:
0911:                boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
0912:                boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
0913:                if ((hasRefAttribute && hasValueAttribute)
0914:                        || ((hasRefAttribute || hasValueAttribute))
0915:                        && subElement != null) {
0916:                    throw new BeanDefinitionStoreException(
0917:                            getResource(),
0918:                            beanName,
0919:                            elementName
0920:                                    + " is only allowed to contain either a 'ref' attribute OR a 'value' attribute OR a sub-element");
0921:                }
0922:                if (hasRefAttribute) {
0923:                    return new RuntimeBeanReference(ele
0924:                            .getAttribute(REF_ATTRIBUTE));
0925:                } else if (hasValueAttribute) {
0926:                    return ele.getAttribute(VALUE_ATTRIBUTE);
0927:                }
0928:
0929:                if (subElement == null) {
0930:                    // Neither child element nor "ref" or "value" attribute found.
0931:                    throw new BeanDefinitionStoreException(getResource(),
0932:                            beanName, elementName
0933:                                    + " must specify a ref or value");
0934:                }
0935:
0936:                return parsePropertySubElement(subElement, beanName);
0937:            }
0938:
0939:            /**
0940:             * Parse a value, ref or collection sub-element of a property or
0941:             * constructor-arg element.
0942:             *
0943:             * @param ele subelement of property element; we don't know which yet
0944:             */
0945:            public Object parsePropertySubElement(Element ele, String beanName)
0946:                    throws BeanDefinitionStoreException {
0947:                if (ele.getTagName().equals(BEAN_ELEMENT)) {
0948:                    return parseBeanDefinitionElement(ele, true);
0949:                } else if (ele.getTagName().equals(REF_ELEMENT)) {
0950:                    // A generic reference to any name of any bean.
0951:                    String beanRef = ele.getAttribute(BEAN_REF_ATTRIBUTE);
0952:                    if (!StringUtils.hasLength(beanRef)) {
0953:                        // A reference to the id of another bean in the same XML file.
0954:                        beanRef = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
0955:                        if (!StringUtils.hasLength(beanRef)) {
0956:                            // A reference to the id of another bean in a parent context.
0957:                            beanRef = ele.getAttribute(PARENT_REF_ATTRIBUTE);
0958:                            if (!StringUtils.hasLength(beanRef)) {
0959:                                throw new BeanDefinitionStoreException(
0960:                                        getResource(), beanName,
0961:                                        "'bean', 'local' or 'parent' is required for a reference");
0962:                            }
0963:                            return new RuntimeBeanReference(beanRef, true);
0964:                        }
0965:                    }
0966:                    return new RuntimeBeanReference(beanRef);
0967:                } else if (ele.getTagName().equals(IDREF_ELEMENT)) {
0968:                    // A generic reference to any name of any bean.
0969:                    String beanRef = ele.getAttribute(BEAN_REF_ATTRIBUTE);
0970:                    if (!StringUtils.hasLength(beanRef)) {
0971:                        // A reference to the id of another bean in the same XML file.
0972:                        beanRef = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
0973:                        if (!StringUtils.hasLength(beanRef)) {
0974:                            throw new BeanDefinitionStoreException(
0975:                                    getResource(), beanName,
0976:                                    "Either 'bean' or 'local' is required for an idref");
0977:                        }
0978:                    }
0979:                    return beanRef;
0980:                } else if (ele.getTagName().equals(VALUE_ELEMENT)) {
0981:                    // It's a literal value.
0982:                    String value = DomUtils.getTextValue(ele);
0983:                    if (ele.hasAttribute(TYPE_ATTRIBUTE)) {
0984:                        String typeClassName = ele.getAttribute(TYPE_ATTRIBUTE);
0985:                        try {
0986:                            Class typeClass = ClassUtils.forName(typeClassName,
0987:                                    this .beanDefinitionReader
0988:                                            .getBeanClassLoader());
0989:                            return new TypedStringValue(value, typeClass);
0990:                        } catch (ClassNotFoundException ex) {
0991:                            throw new BeanDefinitionStoreException(
0992:                                    getResource(), beanName,
0993:                                    "Value type class [" + typeClassName
0994:                                            + "] not found", ex);
0995:                        }
0996:                    }
0997:                    return value;
0998:                } else if (ele.getTagName().equals(NULL_ELEMENT)) {
0999:                    // It's a distinguished null value.
1000:                    return null;
1001:                } else if (ele.getTagName().equals(LIST_ELEMENT)) {
1002:                    return parseListElement(ele, beanName);
1003:                } else if (ele.getTagName().equals(SET_ELEMENT)) {
1004:                    return parseSetElement(ele, beanName);
1005:                } else if (ele.getTagName().equals(MAP_ELEMENT)) {
1006:                    return parseMapElement(ele, beanName);
1007:                } else if (ele.getTagName().equals(PROPS_ELEMENT)) {
1008:                    return parsePropsElement(ele, beanName);
1009:                }
1010:                throw new BeanDefinitionStoreException(getResource(), beanName,
1011:                        "Unknown property sub-element: <" + ele.getTagName()
1012:                                + ">");
1013:            }
1014:
1015:            /**
1016:             * Parse a list element.
1017:             */
1018:            protected List parseListElement(Element collectionEle,
1019:                    String beanName) throws BeanDefinitionStoreException {
1020:                NodeList nl = collectionEle.getChildNodes();
1021:                ManagedList list = new ManagedList(nl.getLength());
1022:                for (int i = 0; i < nl.getLength(); i++) {
1023:                    if (nl.item(i) instanceof  Element) {
1024:                        Element ele = (Element) nl.item(i);
1025:                        list.add(parsePropertySubElement(ele, beanName));
1026:                    }
1027:                }
1028:                return list;
1029:            }
1030:
1031:            /**
1032:             * Parse a set element.
1033:             */
1034:            protected Set parseSetElement(Element collectionEle, String beanName)
1035:                    throws BeanDefinitionStoreException {
1036:                NodeList nl = collectionEle.getChildNodes();
1037:                ManagedSet set = new ManagedSet(nl.getLength());
1038:                for (int i = 0; i < nl.getLength(); i++) {
1039:                    if (nl.item(i) instanceof  Element) {
1040:                        Element ele = (Element) nl.item(i);
1041:                        set.add(parsePropertySubElement(ele, beanName));
1042:                    }
1043:                }
1044:                return set;
1045:            }
1046:
1047:            /**
1048:             * Parse a map element.
1049:             */
1050:            protected Map parseMapElement(Element mapEle, String beanName)
1051:                    throws BeanDefinitionStoreException {
1052:                List entryEles = DomUtils.getChildElementsByTagName(mapEle,
1053:                        ENTRY_ELEMENT);
1054:                Map map = new ManagedMap(entryEles.size());
1055:
1056:                for (Iterator it = entryEles.iterator(); it.hasNext();) {
1057:                    Element entryEle = (Element) it.next();
1058:                    // Should only have one value child element: ref, value, list, etc.
1059:                    // Optionally, there might be a key child element.
1060:                    NodeList entrySubNodes = entryEle.getChildNodes();
1061:
1062:                    Element keyEle = null;
1063:                    Element valueEle = null;
1064:                    for (int j = 0; j < entrySubNodes.getLength(); j++) {
1065:                        if (entrySubNodes.item(j) instanceof  Element) {
1066:                            Element candidateEle = (Element) entrySubNodes
1067:                                    .item(j);
1068:                            if (candidateEle.getTagName().equals(KEY_ELEMENT)) {
1069:                                if (keyEle != null) {
1070:                                    throw new BeanDefinitionStoreException(
1071:                                            getResource(), beanName,
1072:                                            "<entry> is only allowed to contain one <key> sub-element");
1073:                                }
1074:                                keyEle = candidateEle;
1075:                            } else {
1076:                                // Child element is what we're looking for.
1077:                                if (valueEle != null) {
1078:                                    throw new BeanDefinitionStoreException(
1079:                                            getResource(), beanName,
1080:                                            "<entry> must not contain more than one value sub-element");
1081:                                }
1082:                                valueEle = candidateEle;
1083:                            }
1084:                        }
1085:                    }
1086:
1087:                    // Extract key from attribute or sub-element.
1088:                    Object key = null;
1089:                    boolean hasKeyAttribute = entryEle
1090:                            .hasAttribute(KEY_ATTRIBUTE);
1091:                    boolean hasKeyRefAttribute = entryEle
1092:                            .hasAttribute(KEY_REF_ATTRIBUTE);
1093:                    if ((hasKeyAttribute && hasKeyRefAttribute)
1094:                            || ((hasKeyAttribute || hasKeyRefAttribute))
1095:                            && keyEle != null) {
1096:                        throw new BeanDefinitionStoreException(
1097:                                getResource(),
1098:                                beanName,
1099:                                "<entry> is only allowed to contain either "
1100:                                        + "a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element");
1101:                    }
1102:                    if (hasKeyAttribute) {
1103:                        key = entryEle.getAttribute(KEY_ATTRIBUTE);
1104:                    } else if (hasKeyRefAttribute) {
1105:                        key = new RuntimeBeanReference(entryEle
1106:                                .getAttribute(KEY_REF_ATTRIBUTE));
1107:                    } else if (keyEle != null) {
1108:                        key = parseKeyElement(keyEle, beanName);
1109:                    } else {
1110:                        throw new BeanDefinitionStoreException(getResource(),
1111:                                beanName, "<entry> must specify a key");
1112:                    }
1113:
1114:                    // Extract value from attribute or sub-element.
1115:                    Object value = null;
1116:                    boolean hasValueAttribute = entryEle
1117:                            .hasAttribute(VALUE_ATTRIBUTE);
1118:                    boolean hasValueRefAttribute = entryEle
1119:                            .hasAttribute(VALUE_REF_ATTRIBUTE);
1120:                    if ((hasValueAttribute && hasValueRefAttribute)
1121:                            || ((hasValueAttribute || hasValueRefAttribute))
1122:                            && valueEle != null) {
1123:                        throw new BeanDefinitionStoreException(
1124:                                getResource(),
1125:                                beanName,
1126:                                "<entry> is only allowed to contain either "
1127:                                        + "a 'value' attribute OR a 'value-ref' attribute OR a value sub-element");
1128:                    }
1129:                    if (hasValueAttribute) {
1130:                        value = entryEle.getAttribute(VALUE_ATTRIBUTE);
1131:                    } else if (hasValueRefAttribute) {
1132:                        value = new RuntimeBeanReference(entryEle
1133:                                .getAttribute(VALUE_REF_ATTRIBUTE));
1134:                    } else if (valueEle != null) {
1135:                        value = parsePropertySubElement(valueEle, beanName);
1136:                    } else {
1137:                        throw new BeanDefinitionStoreException(getResource(),
1138:                                beanName, "<entry> must specify a value");
1139:                    }
1140:
1141:                    // Add final key and value to the Map.
1142:                    map.put(key, value);
1143:                }
1144:
1145:                return map;
1146:            }
1147:
1148:            /**
1149:             * Parse a key sub-element of a map element.
1150:             */
1151:            protected Object parseKeyElement(Element keyEle, String beanName)
1152:                    throws BeanDefinitionStoreException {
1153:                NodeList nl = keyEle.getChildNodes();
1154:                Element subElement = null;
1155:                for (int i = 0; i < nl.getLength(); i++) {
1156:                    if (nl.item(i) instanceof  Element) {
1157:                        Element candidateEle = (Element) nl.item(i);
1158:                        // Child element is what we're looking for.
1159:                        if (subElement != null) {
1160:                            throw new BeanDefinitionStoreException(
1161:                                    getResource(), beanName,
1162:                                    "<key> must not contain more than one value sub-element");
1163:                        }
1164:                        subElement = candidateEle;
1165:                    }
1166:                }
1167:                return parsePropertySubElement(subElement, beanName);
1168:            }
1169:
1170:            /**
1171:             * Parse a props element.
1172:             */
1173:            protected Properties parsePropsElement(Element propsEle,
1174:                    String beanName) throws BeanDefinitionStoreException {
1175:                Properties props = new Properties();
1176:                List propEles = DomUtils.getChildElementsByTagName(propsEle,
1177:                        PROP_ELEMENT);
1178:                for (Iterator it = propEles.iterator(); it.hasNext();) {
1179:                    Element propEle = (Element) it.next();
1180:                    String key = propEle.getAttribute(KEY_ATTRIBUTE);
1181:                    // Trim the text value to avoid unwanted whitespace
1182:                    // caused by typical XML formatting.
1183:                    String value = DomUtils.getTextValue(propEle).trim();
1184:                    props.setProperty(key, value);
1185:                }
1186:                return props;
1187:            }
1188:
1189:            public void registerBeanDefinitions(Document pDocument,
1190:                    ReaderContext pReaderContext)
1191:                    throws BeanDefinitionStoreException {
1192:            }
1193:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.