MapEntry mapEntry = (MapEntry)parent;
mapEntry.setKey(o);
}
else if(parentElement != null)
{
MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentElement, qName);
String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
if(getKeyMethodName == null)
{
getKeyMethodName = "getKey";
}
String setKeyMethodName = mapEntryMetaData.getSetKeyMethod();
if(setKeyMethodName == null)
{
setKeyMethodName = "setKey";
}
Class parentCls = parent.getClass();
Method setKeyMethod = getSetMethod(parentCls, getKeyMethodName, setKeyMethodName);
invokeSetter(setKeyMethod, parent, o, setKeyMethodName);
}
else
{
throw new JBossXBRuntimeException(
"Element " +
qName +
" bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
);
}
}
else if(element.isMapEntryValue())
{
if(parent instanceof MapEntry)
{
MapEntry mapEntry = (MapEntry)parent;
mapEntry.setValue(o);
}
else if(parentElement != null)
{
MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentElement, qName);
setMapEntryValue(mapEntryMetaData, parent, o);
}
else
{
throw new JBossXBRuntimeException(
"Element " +
qName +
" bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
);
}
}
else
{
Object owner = parent;
if(parent instanceof MapEntry)
{
MapEntry mapEntry = (MapEntry)parent;
owner = mapEntry.getValue();
if(owner == null)
{
if(parentElement == null)
{
throw new JBossXBRuntimeException("Binding metadata needed for lazy map entry value instantiation is not available " +
"for parent element of element " +
qName
);
}
MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentElement, qName);
String valueType = mapEntryMetaData.getValueType();
if(valueType == null)
{
throw new JBossXBRuntimeException("Element " +
qName +
" of type " +
element.getType() +
" is supposed to be bound as map entry value with lazy value instantiation " +
"but value type is not specified in its map entry metadata."
);
}
Class valueCls;
try
{
valueCls = Thread.currentThread().getContextClassLoader().loadClass(valueType);
}
catch(ClassNotFoundException e)
{
throw new JBossXBRuntimeException(
"Failed to load value type specified in the map entry metadata: " + valueType
);
}
try
{
owner = valueCls.newInstance();
}
catch(Exception e)
{
throw new JBossXBRuntimeException(
"Failed to create an instance of value type " + valueType + ": " + e.getMessage()
);
}
setMapEntryValue(mapEntryMetaData, parent, owner);
}
}
if(owner instanceof GenericValueContainer)
{
((GenericValueContainer)owner).addChild(qName, o);
}
else if(owner instanceof Collection)
{
((Collection)owner).add(o);
}
else
{
PutMethodMetaData putMethodMetaData = element.getPutMethodMetaData();
if(owner instanceof Map || putMethodMetaData != null)
{
MapEntryMetaData mapEntryMetaData = element.getMapEntryMetaData();
if(mapEntryMetaData == null)
{
throw new JBossXBRuntimeException((owner instanceof Map ?
"Parent object is an instance of java.util.Map" :
"putMethod is specified for element " + qName
) +
" but mapEntry is specified for neither element " +
qName +
" nor it's type " +
element.getType().getQName()
);
}
Class oClass = o.getClass();
String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
if(getKeyMethodName == null)
{
getKeyMethodName = "getKey";
}
Method keyMethod;
try
{
keyMethod = oClass.getMethod(getKeyMethodName, null);
}
catch(NoSuchMethodException e)
{
throw new JBossXBRuntimeException("setParent failed for " +
qName +
"=" +
o +
": getKeyMethod=" +
getKeyMethodName +
" not found in " + oClass
);
}
Object key;
try
{
key = keyMethod.invoke(o, null);
}
catch(Exception e)
{
throw new JBossXBRuntimeException("setParent failed for " +
qName +
"=" +
o +
": getKeyMethod=" +
getKeyMethodName +
" threw an exception: " + e.getMessage(), e
);
}
Class keyType = Object.class;
Class valueType = Object.class;
String putMethodName = "put";
Class ownerClass = owner.getClass();
if(putMethodMetaData != null)
{
if(putMethodMetaData.getKeyType() != null)
{
try
{
keyType =
Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getKeyType());
}
catch(ClassNotFoundException e)
{
throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
}
}
if(putMethodMetaData.getValueType() != null)
{
try
{
valueType =
Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getValueType());
}
catch(ClassNotFoundException e)
{
throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
}
}
String name = putMethodMetaData.getName();
if(name != null)
{
putMethodName = name;
}
}
Method putMethod;
try
{
putMethod = ownerClass.getMethod(putMethodName, new Class[]{keyType, valueType});
}
catch(NoSuchMethodException e)
{
throw new JBossXBRuntimeException("setParent failed for " +
qName +
"=" +
o +
": putMethod=" +
putMethodName +
"(" + keyType.getName() + " key, " + valueType.getName() + " value) not found in " + ownerClass
);
}
Object value = o;
String valueMethodName = mapEntryMetaData.getGetValueMethod();
if(valueMethodName != null)
{
Method valueMethod;
try
{
valueMethod = oClass.getMethod(valueMethodName, null);
}
catch(NoSuchMethodException e)
{
throw new JBossXBRuntimeException("setParent failed for " +
qName +
"=" +
o +
": getValueMethod=" +
mapEntryMetaData.getGetValueMethod() +
" not found in " + oClass
);
}
try
{
value = valueMethod.invoke(o, null);
}
catch(Exception e)
{
throw new JBossXBRuntimeException("setParent failed for " +
qName +
"=" +
o +
": getValueMethod=" +
mapEntryMetaData.getGetValueMethod() +
" threw an exception: " + e.getMessage(), e
);
}
}
else if(o instanceof MapEntry)