in xbean-blueprint/src/main/java/org/apache/xbean/blueprint/context/impl/XBeanNamespaceHandler.java [494:575]
protected Metadata parseCustomMapElement(MutableBeanMetadata beanMetadata, Element element, String name, ParserContext parserContext) {
MutableMapMetadata map = parserContext.createMetadata(MutableMapMetadata.class);
Element parent = (Element) element.getParentNode();
String entryName = mappingMetaData.getMapEntryName(getLocalName(parent), name);
String keyName = mappingMetaData.getMapKeyName(getLocalName(parent), name);
String dups = mappingMetaData.getMapDupsMode(getLocalName(parent), name);
boolean flat = mappingMetaData.isFlatMap(getLocalName(parent), name);
String defaultKey = mappingMetaData.getMapDefaultKey(getLocalName(parent), name);
if (entryName == null) entryName = "property";
if (keyName == null) keyName = "key";
if (dups == null) dups = "replace";
// TODO : support further customizations
//String valueName = "value";
//boolean keyIsAttr = true;
//boolean valueIsAttr = false;
NodeList nl = element.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element childElement = (Element) node;
String localName = childElement.getLocalName();
String uri = childElement.getNamespaceURI();
if (localName == null || localName.equals("xmlns") || localName.startsWith("xmlns:")) {
continue;
}
// we could use namespaced attributes to differentiate real spring
// attributes from namespace-specific attributes
if (!flat && !isEmpty(uri) && localName.equals(entryName)) {
String key = childElement.getAttributeNS(uri, keyName);
if (key == null || key.length() == 0) {
key = defaultKey;
}
if (key == null) {
throw new RuntimeException("No key defined for map " + entryName);
}
NonNullMetadata keyValue = (NonNullMetadata) getValue(key, mappingMetaData.getPropertyEditor(localName, key), parserContext);
Element valueElement = getFirstChildElement(childElement);
Metadata value;
if (valueElement != null) {
value = parserContext.parseElement(Metadata.class, beanMetadata, valueElement);
// String valueElUri = valueElement.getNamespaceURI();
// String valueElLocalName = valueElement.getLocalName();
// if (valueElUri == null ||
// valueElUri.equals(BLUEPRINT_NAMESPACE)) {
// if ("bean".equals(valueElLocalName)) {
// value = parserContext.parseElement(BeanMetadata.class, beanMetadata, valueElement);
// } else {
// value = parserContext.parseElement(BeanProperty.class, beanMetadata, valueElement).getValue();
// }
// } else {
// value = parserContext.parseElement(ValueMetadata.class, beanMetadata, valueElement);
// }
} else {
value = getValue(getElementText(childElement), mappingMetaData.getPropertyEditor(localName, key), parserContext);
}
addValueToMap(map, keyValue, value, dups, parserContext);
} else if (flat && !isEmpty(uri)) {
String key = childElement.getAttributeNS(uri, keyName);
if (key == null || key.length() == 0) {
key = defaultKey;
}
if (key == null) {
throw new RuntimeException("No key defined for map entry " + entryName);
}
NonNullMetadata keyValue = (NonNullMetadata) getValue(key, mappingMetaData.getPropertyEditor(localName, key), parserContext);
childElement = cloneElement(childElement);
childElement.removeAttributeNS(uri, keyName);
Metadata bdh = parse(childElement, parserContext);
addValueToMap(map, keyValue, bdh, dups, parserContext);
}
}
}
return map;
}