📄 defaultxmlbeandefinitionparser.java
字号:
else {
if (StringUtils.hasLength(typeAttr)) {
cargs.addGenericArgumentValue(val, typeAttr);
}
else {
cargs.addGenericArgumentValue(val);
}
}
}
/**
* Parse a property element.
*/
protected void parsePropertyElement(Element ele, String beanName, MutablePropertyValues pvs)
throws BeanDefinitionStoreException {
String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
if (!StringUtils.hasLength(propertyName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Tag 'property' must have a 'name' attribute");
}
if (pvs.contains(propertyName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Multiple 'property' definitions for property '" + propertyName + "'");
}
Object val = parsePropertyValue(ele, beanName, propertyName);
pvs.addPropertyValue(propertyName, val);
}
/**
* Get the value of a property element. May be a list etc.
* Also used for constructor arguments, "propertyName" being null in this case.
*/
protected Object parsePropertyValue(Element ele, String beanName, String propertyName)
throws BeanDefinitionStoreException {
String elementName = (propertyName != null) ?
"<property> element for property '" + propertyName + "'" :
"<constructor-arg> element";
// Should only have one child element: ref, value, list, etc.
NodeList nl = ele.getChildNodes();
Element subElement = null;
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i) instanceof Element) {
Element candidateEle = (Element) nl.item(i);
if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) {
// Keep going: we don't use this value for now.
}
else {
// Child element is what we're looking for.
if (subElement != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, elementName + " must not contain more than one sub-element");
}
subElement = candidateEle;
}
}
}
boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
if ((hasRefAttribute && hasValueAttribute) ||
((hasRefAttribute || hasValueAttribute)) && subElement != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, elementName +
" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element");
}
if (hasRefAttribute) {
String refName = ele.getAttribute(REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, elementName + " contains empty 'ref' attribute");
}
return new RuntimeBeanReference(refName);
}
else if (hasValueAttribute) {
return ele.getAttribute(VALUE_ATTRIBUTE);
}
if (subElement == null) {
// Neither child element nor "ref" or "value" attribute found.
throw new BeanDefinitionStoreException(
getResource(), beanName, elementName + " must specify a ref or value");
}
return parsePropertySubElement(subElement, beanName);
}
/**
* Parse a value, ref or collection sub-element of a property or
* constructor-arg element.
* @param ele subelement of property element; we don't know which yet
*/
protected Object parsePropertySubElement(Element ele, String beanName) throws BeanDefinitionStoreException {
if (ele.getTagName().equals(BEAN_ELEMENT)) {
try {
return parseBeanDefinitionElement(ele, true);
}
catch (BeanDefinitionStoreException ex) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Could not parse inner bean definition", ex);
}
}
else if (ele.getTagName().equals(REF_ELEMENT)) {
// A generic reference to any name of any bean.
String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
boolean toParent = false;
if (!StringUtils.hasLength(refName)) {
// A reference to the id of another bean in the same XML file.
refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
if (!StringUtils.hasLength(refName)) {
// A reference to the id of another bean in a parent context.
refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
toParent = true;
if (!StringUtils.hasLength(refName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "'bean', 'local' or 'parent' is required for <ref> element");
}
}
}
if (!StringUtils.hasText(refName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<ref> element contains empty target attribute");
}
return new RuntimeBeanReference(refName, toParent);
}
else if (ele.getTagName().equals(IDREF_ELEMENT)) {
// A generic reference to any name of any bean.
String beanRef = ele.getAttribute(BEAN_REF_ATTRIBUTE);
if (!StringUtils.hasLength(beanRef)) {
// A reference to the id of another bean in the same XML file.
beanRef = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
if (!StringUtils.hasLength(beanRef)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Either 'bean' or 'local' is required for <idref> element");
}
}
return beanRef;
}
else if (ele.getTagName().equals(VALUE_ELEMENT)) {
// It's a literal value.
String value = DomUtils.getTextValue(ele);
if (ele.hasAttribute(TYPE_ATTRIBUTE)) {
String typeClassName = ele.getAttribute(TYPE_ATTRIBUTE);
try {
Class typeClass = ClassUtils.forName(typeClassName, this.beanDefinitionReader.getBeanClassLoader());
return new TypedStringValue(value, typeClass);
}
catch (ClassNotFoundException ex) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Type class [" + typeClassName + "] not found for <value> element", ex);
}
}
return value;
}
else if (ele.getTagName().equals(NULL_ELEMENT)) {
// It's a distinguished null value.
return null;
}
else if (ele.getTagName().equals(LIST_ELEMENT)) {
return parseListElement(ele, beanName);
}
else if (ele.getTagName().equals(SET_ELEMENT)) {
return parseSetElement(ele, beanName);
}
else if (ele.getTagName().equals(MAP_ELEMENT)) {
return parseMapElement(ele, beanName);
}
else if (ele.getTagName().equals(PROPS_ELEMENT)) {
return parsePropsElement(ele, beanName);
}
throw new BeanDefinitionStoreException(
getResource(), beanName, "Unknown property sub-element: <" + ele.getTagName() + ">");
}
/**
* Parse a list element.
*/
protected List parseListElement(Element collectionEle, String beanName) throws BeanDefinitionStoreException {
NodeList nl = collectionEle.getChildNodes();
ManagedList list = new ManagedList(nl.getLength());
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i) instanceof Element) {
Element ele = (Element) nl.item(i);
list.add(parsePropertySubElement(ele, beanName));
}
}
return list;
}
/**
* Parse a set element.
*/
protected Set parseSetElement(Element collectionEle, String beanName) throws BeanDefinitionStoreException {
NodeList nl = collectionEle.getChildNodes();
ManagedSet set = new ManagedSet(nl.getLength());
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i) instanceof Element) {
Element ele = (Element) nl.item(i);
set.add(parsePropertySubElement(ele, beanName));
}
}
return set;
}
/**
* Parse a map element.
*/
protected Map parseMapElement(Element mapEle, String beanName) throws BeanDefinitionStoreException {
List entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT);
ManagedMap map = new ManagedMap(entryEles.size());
for (Iterator it = entryEles.iterator(); it.hasNext();) {
Element entryEle = (Element) it.next();
// Should only have one value child element: ref, value, list, etc.
// Optionally, there might be a key child element.
NodeList entrySubNodes = entryEle.getChildNodes();
Element keyEle = null;
Element valueEle = null;
for (int j = 0; j < entrySubNodes.getLength(); j++) {
if (entrySubNodes.item(j) instanceof Element) {
Element candidateEle = (Element) entrySubNodes.item(j);
if (candidateEle.getTagName().equals(KEY_ELEMENT)) {
if (keyEle != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element is only allowed to contain one <key> sub-element");
}
keyEle = candidateEle;
}
else {
// Child element is what we're looking for.
if (valueEle != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element must not contain more than one value sub-element");
}
valueEle = candidateEle;
}
}
}
// Extract key from attribute or sub-element.
Object key = null;
boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE);
boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE);
if ((hasKeyAttribute && hasKeyRefAttribute) ||
((hasKeyAttribute || hasKeyRefAttribute)) && keyEle != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element is only allowed to contain either " +
"a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element");
}
if (hasKeyAttribute) {
key = entryEle.getAttribute(KEY_ATTRIBUTE);
}
else if (hasKeyRefAttribute) {
String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element contains empty 'key-ref' attribute");
}
key = new RuntimeBeanReference(refName);
}
else if (keyEle != null) {
key = parseKeyElement(keyEle, beanName);
}
else {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element must specify a key");
}
// Extract value from attribute or sub-element.
Object value = null;
boolean hasValueAttribute = entryEle.hasAttribute(VALUE_ATTRIBUTE);
boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE);
if ((hasValueAttribute && hasValueRefAttribute) ||
((hasValueAttribute || hasValueRefAttribute)) && valueEle != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element is only allowed to contain either " +
"'value' attribute OR 'value-ref' attribute OR <value> sub-element");
}
if (hasValueAttribute) {
value = entryEle.getAttribute(VALUE_ATTRIBUTE);
}
else if (hasValueRefAttribute) {
String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element contains empty 'value-ref' attribute");
}
value = new RuntimeBeanReference(refName);
}
else if (valueEle != null) {
value = parsePropertySubElement(valueEle, beanName);
}
else {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<entry> element must specify a value");
}
// Add final key and value to the Map.
map.put(key, value);
}
return map;
}
/**
* Parse a key sub-element of a map element.
*/
protected Object parseKeyElement(Element keyEle, String beanName) throws BeanDefinitionStoreException {
NodeList nl = keyEle.getChildNodes();
Element subElement = null;
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i) instanceof Element) {
Element candidateEle = (Element) nl.item(i);
// Child element is what we're looking for.
if (subElement != null) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "<key> element must not contain more than one value sub-element");
}
subElement = candidateEle;
}
}
return parsePropertySubElement(subElement, beanName);
}
/**
* Parse a props element.
*/
protected Properties parsePropsElement(Element propsEle, String beanName) throws BeanDefinitionStoreException {
Properties props = new Properties();
List propEles = DomUtils.getChildElementsByTagName(propsEle, PROP_ELEMENT);
for (Iterator it = propEles.iterator(); it.hasNext();) {
Element propEle = (Element) it.next();
String key = propEle.getAttribute(KEY_ATTRIBUTE);
// Trim the text value to avoid unwanted whitespace
// caused by typical XML formatting.
String value = DomUtils.getTextValue(propEle).trim();
props.setProperty(key, value);
}
return props;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -