Coverage Report - org.dozer.fieldmap.MapFieldMap
 
Classes in this File Line Coverage Branch Coverage Complexity
MapFieldMap
98%
62/63
94%
49/52
4.714
MapFieldMap$PrepareTargetObjectResult
100%
5/5
N/A
4.714
 
 1  
 /**
 2  
  * Copyright 2005-2013 Dozer Project
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.dozer.fieldmap;
 17  
 
 18  
 import org.dozer.classmap.ClassMap;
 19  
 import org.dozer.factory.DestBeanCreator;
 20  
 import org.dozer.propertydescriptor.DozerPropertyDescriptor;
 21  
 import org.dozer.propertydescriptor.FieldPropertyDescriptor;
 22  
 import org.dozer.propertydescriptor.JavaBeanPropertyDescriptor;
 23  
 import org.dozer.propertydescriptor.MapPropertyDescriptor;
 24  
 import org.dozer.util.DozerConstants;
 25  
 import org.dozer.util.MappingUtils;
 26  
 
 27  
 /**
 28  
  * Only intended for internal use. Handles field mapping involving Map Backed properties. Map backed property support
 29  
  * includes top level class Map data type, field level Map data type, and custom Map backed objects that provide custom
 30  
  * map-get/set methods.
 31  
  * 
 32  
  * @author garsombke.franz
 33  
  * @author sullins.ben
 34  
  * @author tierney.matt
 35  
  * 
 36  
  */
 37  
 public class MapFieldMap extends FieldMap {
 38  
 
 39  
   public MapFieldMap(ClassMap classMap) {
 40  9840
     super(classMap);
 41  9840
   }
 42  
 
 43  
   public MapFieldMap(FieldMap fieldMap) {
 44  
     //Create from existing field map
 45  1279
     super(fieldMap.getClassMap());
 46  1279
     setCopyByReference(fieldMap.isCopyByReference());
 47  1279
     setCustomConverter(fieldMap.getCustomConverter());
 48  1279
     setCustomConverterId(fieldMap.getCustomConverterId());
 49  1279
     setCustomConverterParam(fieldMap.getCustomConverterParam());
 50  1279
     setDestField(fieldMap.getDestField());
 51  1279
     setDestHintContainer(fieldMap.getDestHintContainer());
 52  1279
     setDestDeepIndexHintContainer(fieldMap.getDestDeepIndexHintContainer());
 53  1279
     setMapId(fieldMap.getMapId());
 54  1279
     setRelationshipType(fieldMap.getRelationshipType());
 55  1279
     setRemoveOrphans(fieldMap.isRemoveOrphans());
 56  1279
     setSrcField(fieldMap.getSrcField());
 57  1279
     setSrcHintContainer(fieldMap.getSrcHintContainer());
 58  1279
     setSrcDeepIndexHintContainer(fieldMap.getSrcDeepIndexHintContainer());
 59  1279
     setType(fieldMap.getType());
 60  1279
   }
 61  
 
 62  
   @Override
 63  
   public void writeDestValue(Object destObj, Object destFieldValue) {
 64  
     DozerPropertyDescriptor propDescriptor;
 65  773
     Object targetObject = destObj;
 66  
 
 67  773
     if (getDestFieldName().equals(DozerConstants.SELF_KEYWORD)
 68  
         || (destFieldValue != null && MappingUtils.isSupportedMap(destFieldValue.getClass()))) {
 69  
       // Destination value is already a Map, so just use normal
 70  277
       propDescriptor = super.getDestPropertyDescriptor(destObj.getClass());
 71  
     } else {
 72  496
       if (getDestFieldMapGetMethod() != null
 73  
           || MappingUtils.isSupportedMap(determineActualPropertyType(getDestFieldName(), isDestFieldIndexed(), getDestFieldIndex(),
 74  
               destObj, true))) {
 75  
         // Need to dig out actual destination Map object and use map property descriptor to set the value on that target object....
 76  74
         PrepareTargetObjectResult result = prepareTargetObject(destObj);
 77  74
         targetObject = result.targetObject;
 78  74
         propDescriptor = result.propDescriptor;
 79  74
       } else {
 80  422
         propDescriptor = super.getDestPropertyDescriptor(destObj.getClass());
 81  
       }
 82  
     }
 83  
 
 84  773
     propDescriptor.setPropertyValue(targetObject, destFieldValue, this);
 85  773
   }
 86  
 
 87  
   @Override
 88  
   public Object getSrcFieldValue(Object srcObj) {
 89  
     DozerPropertyDescriptor propDescriptor;
 90  775
     Object targetObject = srcObj;
 91  
 
 92  775
     if (getSrcFieldName().equals(DozerConstants.SELF_KEYWORD)) {
 93  396
       propDescriptor = super.getSrcPropertyDescriptor(srcObj.getClass());
 94  
     } else {
 95  379
       Class<?> actualType = determineActualPropertyType(getSrcFieldName(), isSrcFieldIndexed(), getSrcFieldIndex(), srcObj, false);
 96  379
       if ((getSrcFieldMapGetMethod() != null)
 97  
           || (this.getMapId() == null && MappingUtils.isSupportedMap(actualType) && getSrcHintContainer() == null)) {
 98  
         // Need to dig out actual map object by using getter on the field. Use actual map object to get the field value
 99  58
         targetObject = super.getSrcFieldValue(srcObj);
 100  
 
 101  58
         String setMethod = MappingUtils.isSupportedMap(actualType) ? "put" : getSrcFieldMapSetMethod();
 102  58
         String getMethod = MappingUtils.isSupportedMap(actualType) ? "get" : getSrcFieldMapGetMethod();
 103  58
         String key = getSrcFieldKey() != null ? getSrcFieldKey() : getDestFieldName();
 104  
 
 105  58
         propDescriptor = new MapPropertyDescriptor(actualType, getSrcFieldName(), isSrcFieldIndexed(), getDestFieldIndex(),
 106  
                 setMethod, getMethod, key, getSrcDeepIndexHintContainer(), getDestDeepIndexHintContainer());
 107  58
       } else {
 108  321
         propDescriptor = super.getSrcPropertyDescriptor(srcObj.getClass());
 109  
       }
 110  
     }
 111  
 
 112  775
     Object result = null;
 113  775
     if (targetObject != null) {
 114  757
       result = propDescriptor.getPropertyValue(targetObject);
 115  
     }
 116  
 
 117  775
     return result;
 118  
 
 119  
   }
 120  
 
 121  
   private PrepareTargetObjectResult prepareTargetObject(Object destObj) {
 122  
     //  Need to dig out actual destination Map object and use map property descriptor to set the value on that target object....
 123  
     DozerPropertyDescriptor pd;
 124  74
     if (isDestFieldAccessible()) {
 125  0
       pd = new FieldPropertyDescriptor(destObj.getClass(), getDestFieldName(), isDestFieldIndexed(), getDestFieldIndex(),
 126  
           getSrcDeepIndexHintContainer(), getDestDeepIndexHintContainer());
 127  
     } else {
 128  74
       pd = new JavaBeanPropertyDescriptor(destObj.getClass(), getDestFieldName(), isDestFieldIndexed(), getDestFieldIndex(),
 129  
           getSrcDeepIndexHintContainer(), getDestDeepIndexHintContainer());
 130  
     }
 131  
 
 132  74
     Class<?> c = pd.getPropertyType();
 133  74
     Object targetObject = pd.getPropertyValue(destObj);
 134  74
     if (targetObject == null) {
 135  
       // Create new instance of target object that will be populated.
 136  42
       if (getDestHintContainer() != null) {
 137  12
         if (MappingUtils.isSupportedMap(c)) {
 138  6
           if (MappingUtils.isSupportedMap(getDestHintContainer().getHint())) {
 139  6
             c = getDestHintContainer().getHint();
 140  
           }
 141  
         } else {
 142  6
           c = getDestHintContainer().getHint();
 143  
         }
 144  
 
 145  
       }
 146  
 
 147  
       //TODO: add support for custom factory/create method in conjunction with Map backed properties
 148  42
       targetObject = DestBeanCreator.create(c, destObj.getClass());
 149  42
       pd.setPropertyValue(destObj, targetObject, this);
 150  
     }
 151  
 
 152  74
     return new PrepareTargetObjectResult(targetObject, new MapPropertyDescriptor(c, getDestFieldName(), isDestFieldIndexed(),
 153  
         getDestFieldIndex(), MappingUtils.isSupportedMap(c) ? "put" : getDestFieldMapSetMethod(),
 154  
         MappingUtils.isSupportedMap(c) ? "get" : getDestFieldMapGetMethod(), getDestFieldKey() != null ? getDestFieldKey()
 155  
             : getSrcFieldName(), getSrcDeepIndexHintContainer(), getDestDeepIndexHintContainer()));
 156  
 
 157  
   }
 158  
 
 159  
   private Class<?> determineActualPropertyType(String fieldName, boolean isIndexed, int index, Object targetObj, boolean isDestObj) {
 160  
     // Dig out actual Map object by calling getter on top level object    
 161  
     DozerPropertyDescriptor pd;
 162  857
     if ((isDestObj && isDestFieldAccessible()) || (!isDestObj && isSrcFieldAccessible())) {
 163  1
       pd = new FieldPropertyDescriptor(targetObj.getClass(), fieldName, isIndexed, index, getSrcDeepIndexHintContainer(),
 164  
           getDestDeepIndexHintContainer());
 165  
     } else {
 166  856
       pd = new JavaBeanPropertyDescriptor(targetObj.getClass(), fieldName, isIndexed, index, getSrcDeepIndexHintContainer(),
 167  
           getDestDeepIndexHintContainer());
 168  
     }
 169  
 
 170  857
     return pd.getPropertyType();
 171  
   }
 172  
 
 173  148
   private static class PrepareTargetObjectResult {
 174  
     private Object targetObject;
 175  
     private MapPropertyDescriptor propDescriptor;
 176  74
     public PrepareTargetObjectResult(Object targetObject, MapPropertyDescriptor propDescriptor) {
 177  74
       this.targetObject = targetObject;
 178  74
       this.propDescriptor = propDescriptor;
 179  74
     }
 180  
   }
 181  
 
 182  
 }