📄 mappingprocessor.java
字号:
if (parentFieldNames.contains(key)) {
return;
} else {
parentFieldNames.add(key);
}
}
if (fieldMapping instanceof GenericFieldMap && ((GenericFieldMap) fieldMapping).isMethodMap()
&& fieldMapping.getDestField().getType().equals(MapperConstants.ITERATE)) {
mapFromIterateMethodFieldMap(sourceObj, destObj, sourceFieldValue, classMap, fieldMapping);
} else {
//either deep field map or generic map. The is the most likely scenario
mapFromFieldMap(sourceObj, destObj, sourceFieldValue, classMap, fieldMapping);
}
statsMgr.increment(StatisticTypeConstants.FIELD_MAPPING_SUCCESS_COUNT);
} catch (Throwable e) {
log.error(logMsgFactory.createFieldMappingErrorMsg(sourceObj, fieldMapping, sourceFieldValue, destObj, e), e);
statsMgr.increment(StatisticTypeConstants.FIELD_MAPPING_FAILURE_COUNT);
// check error handling policy.
if (classMap.getStopOnErrors()) {
mappingUtils.throwMappingException(e);
} else {
statsMgr.increment(StatisticTypeConstants.FIELD_MAPPING_FAILURE_IGNORED_COUNT);
}
}
}
private void mapFromFieldMap(Object sourceObj, Object destObj, Object sourceFieldValue, ClassMap classMap,
FieldMap fieldMapping) throws IllegalAccessException, InvocationTargetException, InvocationTargetException,
InstantiationException, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException, NoSuchFieldException {
Class destFieldType = null;
// methodmap logic should be encapsulated and figured out at the fieldmap level
if (fieldMapping instanceof GenericFieldMap && ((GenericFieldMap) fieldMapping).isMethodMap()) {
destFieldType = fieldMapping.getDestFieldWriteMethod(classMap.getDestClass().getClassToMap()).getParameterTypes()[0];
} else {
destFieldType = fieldMapping.getDestFieldType(classMap.getDestClass().getClassToMap());
}
String destFieldName = fieldMapping.getDestField().getName();
Object destFieldValue = mapOrRecurseObject(sourceFieldValue, destFieldType, classMap, fieldMapping, destObj);
// check for custom converters
// TODO why was this code added?
CustomConverterContainer customConverters = classMap.getConfiguration().getCustomConverters();
Class converterClass = null;
if ((customConverters != null) && (fieldMapping.getDestinationTypeHint() != null) && (destFieldValue != null)
&& fieldMapping.getDestinationTypeHint().getHints().size() == 1) {// we don't support complicated hints
converterClass = customConverters.getConverterByDestinationType(Thread.currentThread().getContextClassLoader()
.loadClass(fieldMapping.getDestinationTypeHint().getHintName()), destFieldValue.getClass(), cacheMgr);
}
if (converterClass != null) {
Object o = converterClass.newInstance();
if (!(o instanceof CustomConverter)) {
throw new InstantiationException("Class is not an instance of the CustomConverter interface");
}
CustomConverter theConverter = (CustomConverter) o;
destFieldValue = theConverter.convert(null, destFieldValue, destFieldValue.getClass(), destFieldType.getClass());
}
// TODO end new code
writeDestinationValue(destObj, destFieldValue, classMap, fieldMapping);
if(log.isDebugEnabled()) {
log.debug(logMsgFactory.createFieldMappingSuccessMsg(sourceObj.getClass(), destObj.getClass(), fieldMapping.getSourceField().getName(),
destFieldName, sourceFieldValue, destFieldValue));
}
}
private void mapFromIterateMethodFieldMap(Object sourceObj, Object destObj, Object sourceFieldValue,
ClassMap classMap, FieldMap fieldMapping) throws IllegalAccessException, InvocationTargetException,
InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException,
NoSuchFieldException {
String destFieldName = fieldMapping.getDestField().getName();
// iterate over the destFieldValue - iterating is fine unless we are
// mapping in the other direction. verify that it is truly a collection
// if it is an iterator object turn it into a List
if (sourceFieldValue instanceof Iterator) {
sourceFieldValue = IteratorUtils.toList((Iterator) sourceFieldValue);
}
if (sourceFieldValue != null) {
for (int i = 0; i < collectionUtils.getLengthOfCollection(sourceFieldValue); i++) {
Object value = collectionUtils.getValueFromCollection(sourceFieldValue, i);
// map this value
if (fieldMapping.getDestinationTypeHint() == null) {
throw new MappingException("<field type=\"iterate\"> must have a source or destination type hint");
}
// check for custom converters
CustomConverterContainer customConverters = classMap.getConfiguration().getCustomConverters();
Class converterClass = null;
if (customConverters != null) {
converterClass = customConverters.getConverterByDestinationType(Thread.currentThread()
.getContextClassLoader().loadClass(fieldMapping.getDestinationTypeHint().getHintName()),
value.getClass(), cacheMgr);
}
if (customConverters != null && converterClass != null) {
value = mapUsingCustomConverter(converterClass, value.getClass(), value, fieldMapping
.getDestinationTypeHint().getHint(), null, fieldMapping, false);
} else {
value = map(value, fieldMapping.getDestinationTypeHint().getHint());
}
if (value != null) {
writeDestinationValue(destObj, value, classMap, fieldMapping);
}
}
}
if (log.isDebugEnabled()) {
log.debug(logMsgFactory.createFieldMappingSuccessMsg(sourceObj.getClass(), destObj.getClass(), fieldMapping.getSourceField().getName(),
destFieldName, sourceFieldValue, null));
}
}
// TODO there has to be a much better way then ignoreClassMap flag
// this is related to testPropertyClassLevelMapBack unit test. transforming String to Integer from HashMap
private Object mapOrRecurseObject(Object sourceFieldValue, Class destFieldType, ClassMap classMap, FieldMap fieldMap,
Object destObj) throws InvocationTargetException, InstantiationException, IllegalAccessException,
NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
return mapOrRecurseObject(sourceFieldValue, destFieldType, classMap, fieldMap, destObj, false);
}
private Object mapOrRecurseObject(Object sourceFieldValue, Class destFieldType, ClassMap classMap, FieldMap fieldMap,
Object destObj, boolean ignoreClassMap) throws InvocationTargetException, InstantiationException,
IllegalAccessException, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
boolean isDestFieldTypeSupportedMap = mappingUtils.isSupportedMap(destFieldType);
if (sourceFieldValue == null && !isDestFieldTypeSupportedMap) {
return null;
}
// this is so we don't null out the entire Map with a null source value
if (sourceFieldValue == null && isDestFieldTypeSupportedMap) {
return mapMapToProperty(sourceFieldValue, null, fieldMap, destObj, destFieldType, classMap);
}
Object rvalue = null;
Class sourceFieldClass = sourceFieldValue.getClass();
boolean isSourceFieldClassSupportedMap = mappingUtils.isSupportedMap(sourceFieldClass);
CustomConverterContainer customConverters = classMap.getConfiguration().getCustomConverters();
Class converterClass = null;
if (customConverters != null) {
converterClass = customConverters.getConverterByDestinationType(destFieldType, sourceFieldClass, cacheMgr);
}
if (customConverters != null && converterClass != null) {
rvalue = mapUsingCustomConverter(converterClass, sourceFieldClass, sourceFieldValue, destFieldType, destObj,
fieldMap, false);
} else if (fieldMap.getCopyByReference()) {
/*
* just get the src and return it, no transformation.
*/
return sourceFieldValue;
// if the mapId is not null then it means we are mapping a Class Level Map Backed Property
// in the future the mapId might be used for other things...
} else if (fieldMap.getMapId() != null && mappingUtils.validateMap(sourceFieldClass, destFieldType, fieldMap)) {
return mapCustomObject(fieldMap, destObj, destFieldType, sourceFieldValue);
} else if (fieldMap instanceof MapFieldMap && !ignoreClassMap) {
// we just take the source and set it on the Map - if we are mapping in reverse we need to get the value off of
// the map
return mapClassLevelMap(fieldMap, sourceFieldValue, sourceFieldClass, classMap, destFieldType, destObj);
} else if (mappingUtils.isSupportedCollection(sourceFieldClass)
&& (mappingUtils.isSupportedCollection(destFieldType))) {
return mapCollection(sourceFieldValue, classMap, fieldMap, destObj);
} else if (isSourceFieldClassSupportedMap && isDestFieldTypeSupportedMap) {
return mapMap(sourceFieldValue, classMap, fieldMap, destObj, destFieldType);
} else if (isSourceFieldClassSupportedMap || isDestFieldTypeSupportedMap) {
return mapMapToProperty(sourceFieldValue, sourceFieldClass, fieldMap, destObj, destFieldType, classMap);
} else if (mappingUtils.isCustomMapMethod(fieldMap)) {
return mapCustomMapToProperty(sourceFieldValue, sourceFieldClass, fieldMap, destObj, destFieldType);
} else if (mappingUtils.isPrimitiveOrWrapper(sourceFieldClass) || mappingUtils.isPrimitiveOrWrapper(destFieldType)) {
//Primitive or Wrapper conversion
if (fieldMap.getDestinationTypeHint() != null) {
destFieldType = fieldMap.getDestinationTypeHint().getHint();
}
if (fieldMap.getSourceField().getIndex() < 0) {
return primitiveOrWrapperConverter.convert(sourceFieldValue, destFieldType, new DateFormatContainer(classMap, fieldMap));
} else {
return primitiveOrWrapperConverter.convertUsingIndex(sourceFieldValue, fieldMap.getSourceField().getIndex(),
destFieldType, new DateFormatContainer(classMap, fieldMap));
}
} else {
//Map from one custom data object to another custom data object
return mapCustomObject(fieldMap, destObj, destFieldType, sourceFieldValue);
}
return rvalue;
}
private Object mapClassLevelMap(FieldMap fieldMap, Object sourceFieldValue, Class sourceFieldClass,
ClassMap classMap, Class destType, Object destObj) throws InvocationTargetException, IllegalAccessException,
NoSuchFieldException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
// TODO This should be encapsulated in MapFieldMap?
if (!mappingUtils.isSupportedMap(sourceFieldClass) && !classMap.getSourceClass().isCustomMap()) {
return sourceFieldValue;
} else {
String key = null;
if (StringUtils.isEmpty(fieldMap.getDestField().getKey())) {
key = fieldMap.getDestField().getName();
} else {
key = fieldMap.getDestField().getKey();
}
Method resultMethod = reflectionUtils.getMethod(sourceFieldValue, fieldMap.getSourceField().getMapGetMethod());
Object result = resultMethod.invoke(sourceFieldValue, new Object[] { key });
return mapOrRecurseObject(result, destType, classMap, fieldMap, destObj, true);
}
}
private Object mapCustomObject(FieldMap fieldMap, Object destObj, Class destFieldType, Object sourceFieldValue)
throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException,
ClassNotFoundException, NoSuchFieldException {
// custom java bean
// Need to make sure that the destination object is not already
// instantiated.
Object field = mappingValidator.validateField(fieldMap, destObj, destFieldType);
ClassMap classMap = null;
// if the field is not null than we don't want a new instance
if (field == null) {
// first check to see if this plain old field map has hints to the actual type.
if (fieldMap.getDestinationTypeHint() != null) {
Class destType = fieldMap.getDestinationTypeHint().getHint();
// if the destType is null this means that there was more than one hint. we must
// have already set the destType then.
if (destType != null) {
destFieldType = destType;
}
}
//Check to see if explicit map-id has been specified for the field mapping
String mapId = null;
if (fieldMap != null) {
mapId = fieldMap.getMapId();
}
classMap = getClassMap(sourceFieldValue, destFieldType, mapId, false);
field = destBeanCreator.create(sourceFieldValue, classMap, fieldMap, null);
}
map(classMap, sourceFieldValue, field, null, fieldMap);
return field;
}
private Object mapCollection(Object sourceCollectionValue, ClassMap classMap, FieldMap fieldMap, Object destObj)
throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
ClassNotFoundException, NoSuchFieldException {
// if it is an iterator object turn it into a List
if (sourceCollectionValue instanceof Iterator) {
sourceCollectionValue = IteratorUtils.toList((Iterator) sourceCollectionValue);
}
Class destCollectionType = fieldMap.getDestFieldType(classMap.getDestClass().getClassToMap());
Class sourceFieldType = sourceCollectionValue.getClass();
Object result = null;
// if they use a standard Collection we have to assume it is a List...better way to do this?
if (destCollectionType.getName().equals(Collection.class.getName())) {
destCollectionType = List.class;
}
// Array to Array
if (collectionUtils.isArray(sourceFieldType) && (collectionUtils.isArray(destCollectionType))) {
result = mapArrayToArray(sourceCollectionValue, classMap, fieldMap, destObj);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -