private String generateFieldMapCode( SourceCodeContext code, FieldMap fieldMap, ClassMap<?, ?> classMap, VariableRef destination, StringBuilder logDetails) throws Exception { final VariableRef sourceProperty = new VariableRef(fieldMap.getSource(), "source"); final VariableRef destinationProperty = new VariableRef(fieldMap.getDestination(), "destination"); destinationProperty.setOwner(destination); if (!sourceProperty.isReadable() || ((!destinationProperty.isAssignable()) && destinationProperty.type().isImmutable())) { if (logDetails != null) { code.debugField(fieldMap, "excluding because "); if (!sourceProperty.isReadable()) { Type<?> sourceType = classMap.getAType().equals(destination.type()) ? classMap.getBType() : classMap.getAType(); logDetails.append( sourceType + "." + fieldMap.getSource().getName() + "(" + fieldMap.getSource().getType() + ") is not readable"); } else { logDetails.append( destination.type() + "." + fieldMap.getDestination().getName() + "(" + fieldMap.getDestination().getType() + ") is not assignable and cannot be mapped in-place"); } } return ""; } // Make sure the source and destination types are accessible to the // builder compilerStrategy.assureTypeIsAccessible(sourceProperty.rawType()); compilerStrategy.assureTypeIsAccessible(destinationProperty.rawType()); return code.mapFields(fieldMap, sourceProperty, destinationProperty); }
public GeneratedMapperBase build(ClassMap<?, ?> classMap, MappingContext context) { StringBuilder logDetails = null; try { compilerStrategy.assureTypeIsAccessible(classMap.getAType().getRawType()); compilerStrategy.assureTypeIsAccessible(classMap.getBType().getRawType()); if (LOGGER.isDebugEnabled()) { logDetails = new StringBuilder(); String srcName = TypeFactory.nameOf(classMap.getAType(), classMap.getBType()); String dstName = TypeFactory.nameOf(classMap.getBType(), classMap.getAType()); logDetails.append("Generating new mapper for (" + srcName + ", " + dstName + ")"); } final SourceCodeContext mapperCode = new SourceCodeContext( classMap.getMapperClassName(), GeneratedMapperBase.class, context, logDetails); Set<FieldMap> mappedFields = new LinkedHashSet<FieldMap>(); mappedFields.addAll(addMapMethod(mapperCode, true, classMap, logDetails)); mappedFields.addAll(addMapMethod(mapperCode, false, classMap, logDetails)); GeneratedMapperBase instance = mapperCode.getInstance(); instance.setAType(classMap.getAType()); instance.setBType(classMap.getBType()); instance.setFavorsExtension(classMap.favorsExtension()); if (logDetails != null) { LOGGER.debug(logDetails.toString()); logDetails = null; } /* * Add a copy of the ClassMap to the current mapping context, which * only contains the field maps that were processed by this mapper * generation; this can later be used by ObjectFactory generation * when selecting a constructor -- since we only need a constructor * which handles the fields not mapped by the generated mapper */ classMap = classMap.copy(mappedFields); context.registerMapperGeneration(classMap); return instance; } catch (final Exception e) { if (logDetails != null) { /* * Print out the partial progress of the code generation, as it * can help to pinpoint the location of the internal error */ logDetails.append("\n<---- ERROR occurred here"); LOGGER.debug(logDetails.toString()); } throw new MappingException(e); } }