Package ma.glasnost.orika.metadata

Source Code of ma.glasnost.orika.metadata.ClassMapBuilder$Factory

/*
* Orika - simpler, better and faster Java bean mapping
*
* Copyright (C) 2011 Orika authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ma.glasnost.orika.metadata;

import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import ma.glasnost.orika.DefaultFieldMapper;
import ma.glasnost.orika.MappedTypePair;
import ma.glasnost.orika.Mapper;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingException;
import ma.glasnost.orika.impl.UtilityResolver;
import ma.glasnost.orika.property.PropertyResolver;
import ma.glasnost.orika.property.PropertyResolverStrategy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* ClassMapBuilder provides a fluent API which can be used to define
* a mapping from one class to another.
*
* @param <A>
* @param <B>
*/
public class ClassMapBuilder<A, B> implements MappedTypePair<A, B> {
   
 
  public static class Factory extends ClassMapBuilderFactory {

    /* (non-Javadoc)
     * @see ma.glasnost.orika.metadata.ClassMapBuilderFactory#newClassMapBuilder(ma.glasnost.orika.metadata.Type, ma.glasnost.orika.metadata.Type, ma.glasnost.orika.property.PropertyResolverStrategy, ma.glasnost.orika.DefaultFieldMapper[])
     */
    @Override
    protected <A, B> ClassMapBuilder<A, B> newClassMapBuilder(
        Type<A> aType, Type<B> bType,
        MapperFactory mapperFactory,
        PropertyResolverStrategy propertyResolver,
        DefaultFieldMapper[] defaults) {
     
      return new ClassMapBuilder<A,B>(aType, bType, mapperFactory, propertyResolver, defaults);
    }
  }
 
    private final Map<String, Property> aProperties;
    private final Map<String, Property> bProperties;
    private final Set<String> propertiesCacheA;
    private final Set<String> propertiesCacheB;
    final private Type<A> aType;
    final private Type<B> bType;
    final private Set<FieldMap> fieldsMapping;
   
    final private Set<MapperKey> usedMappers;
    private Mapper<A, B> customizedMapper;
    private String[] constructorA;
    private String[] constructorB;
    private final PropertyResolverStrategy propertyResolver;
    private final MapperFactory mapperFactory;
    private final DefaultFieldMapper[] defaults;
    private Boolean sourcesMappedOnNull;
    private Boolean destinationsMappedOnNull;
   
    private static final Logger LOGGER = LoggerFactory.getLogger(ClassMapBuilder.class);
   
    /**
     * Note: this static member variable exists to support the deprecated static map methods;
     * it can be removed as soon as they are removed
     */
    private static volatile WeakReference<PropertyResolverStrategy> defaultPropertyResolver;
   
   
    /**
     * @param aType
     * @param bType
     * @param propertyResolver
     * @param defaults
     */
    protected ClassMapBuilder(Type<A> aType, Type<B> bType, MapperFactory mapperFactory, PropertyResolverStrategy propertyResolver, DefaultFieldMapper... defaults) {
     
      if (aType == null) {
          throw new MappingException("[aType] is required");
      }
     
      if (bType == null) {
          throw new MappingException("[bType] is required");
      }
     
      this.mapperFactory = mapperFactory;
      this.propertyResolver = propertyResolver;
      this.defaults = defaults;
     
      aProperties = propertyResolver.getProperties(aType);
      bProperties = propertyResolver.getProperties(bType);
      propertiesCacheA = new LinkedHashSet<String>();
      propertiesCacheB = new LinkedHashSet<String>();
     
      this.aType = aType;
      this.bType = bType;
      this.fieldsMapping = new LinkedHashSet<FieldMap>();
      this.usedMappers = new LinkedHashSet<MapperKey>();
     
  }
    
    /**
     * @param aType
     * @param bType
     * @deprecated Use of this method instantiates a new PropertyResolverStrategy instance
     * each time; instead, {@link ma.glasnost.orika.MapperFactory#classMap(Type, Type)} should
     * be used which will leverage the PropertyResolverStrategy instance associated with the factory.
     */
    @Deprecated
  private ClassMapBuilder(Type<A> aType, Type<B> bType) {
       
      this(aType, bType, null, getDefaultPropertyResolver());
    }
   
    private static PropertyResolverStrategy getDefaultPropertyResolver() {
      if (defaultPropertyResolver == null || defaultPropertyResolver.get() == null) {
          synchronized(ClassMapBuilder.class) {
            if (defaultPropertyResolver == null || defaultPropertyResolver.get() == null) {
              defaultPropertyResolver = new WeakReference<PropertyResolverStrategy>(
                  UtilityResolver.getDefaultPropertyResolverStrategy());
            }
          }
        }
      return defaultPropertyResolver.get();
    }
   
    /**
     * Map a field in both directions
     *
     * @param fieldNameA
     *            property name in type A
     * @param fieldNameB
     *            property name in type B
     * @return
     */
    public ClassMapBuilder<A, B> field(String fieldNameA, String fieldNameB) {
        return fieldMap(fieldNameA, fieldNameB).add();
    }
   
   
    /**
     * Map a field in one direction only (from fieldNameA to fieldNameB)
     *
     * @param fieldNameA the (source) fieldName from type A
     * @param fieldNameB the (destination) fieldName from type B
     * @return
     */
    public ClassMapBuilder<A, B> fieldAToB(String fieldNameA, String fieldNameB) {
        return fieldMap(fieldNameA, fieldNameB).aToB().add();
    }
   
    /**
     * Map a field in one direction only (from fieldNameB to fieldNameA)
     *
     * @param fieldNameB the (source) fieldName from type B
     * @param fieldNameA the (destination) fieldName from type A
     * @return
     */
    public ClassMapBuilder<A, B> fieldBToA(String fieldNameB, String fieldNameA) {
        return fieldMap(fieldNameA, fieldNameB).bToA().add();
    }
   
    /**
     * Create a fieldMap for the particular field (same property name used in both types)
     *
     * @param a
     * @return
     */
    public FieldMapBuilder<A, B> fieldMap(String a) {
        return fieldMap(a, a);
    }
   
    /**
     * Create a fieldMap for the particular field (same property name used in both types)
     *
     * @param a
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A, B> fieldMap(String a, boolean byDefault) {
        return fieldMap(a, a, byDefault);
    }
   
   
    /**
     * Create a fieldMap for the particular field mapping
     *
     * @param fieldNameA the name of the field in type A
     * @param fieldNameB the name of the field in type B
     * @return
     */
    public FieldMapBuilder<A, B> fieldMap(String fieldNameA, String fieldNameB) {
      return fieldMap(fieldNameA, fieldNameB, false);
    }
   
    /**
     * Create a fieldMap for the particular field mapping
     *
     * @param fieldNameA the name of the field in type A
     * @param fieldNameB the name of the field in type B
     * @param byDefault whether the field mapping has been provided by default
     * @return
     */
    public FieldMapBuilder<A, B> fieldMap(String fieldNameA, String fieldNameB, boolean byDefault) {
   
      try {
        final FieldMapBuilder<A, B> fieldMapBuilder = new FieldMapBuilder<A, B>(this, fieldNameA, fieldNameB, byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
         
          return fieldMapBuilder;
      } catch (MappingException e) {
        /*
         * Add more information to the message to help with debugging
         */
        String msg = getClass().getSimpleName() + ".map(" + aType + ", " + bType + ")" +
            ".field('" + fieldNameA + "', '" + fieldNameB + "'): Error: " + e.getLocalizedMessage();
        throw new MappingException(msg, e);
      }
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(Property fieldA, Property fieldB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, fieldA, fieldB, byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(String fieldNameA, Property fieldB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, resolvePropertyForA(fieldNameA), fieldB, byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldNameB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(Property fieldA, String fieldNameB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, fieldA, resolvePropertyForB(fieldNameB), byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(Property.Builder fieldA, Property.Builder fieldB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, fieldA.build((PropertyResolver)propertyResolver), fieldB.build((PropertyResolver)propertyResolver), byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(String fieldNameA, Property.Builder fieldB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, resolvePropertyForA(fieldNameA), fieldB.build((PropertyResolver)propertyResolver), byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldNameB
     * @param byDefault
     * @return
     */
    public FieldMapBuilder<A,B> fieldMap(Property.Builder fieldA, String fieldNameB, boolean byDefault) {
        return new FieldMapBuilder<A,B>(this, fieldA.build((PropertyResolver)propertyResolver), resolvePropertyForB(fieldNameB), byDefault, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(Property fieldA, Property fieldB) {
        return fieldMap(fieldA, fieldB, false).add();
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(String fieldNameA, Property fieldB) {
        return fieldMap(fieldNameA, fieldB, false).add();
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldNameB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(Property fieldA, String fieldNameB) {
        return fieldMap(fieldA, fieldNameB, false).add();
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(Property.Builder fieldA, Property.Builder fieldB) {
        return fieldMap(fieldA, fieldB, false).add();
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(String fieldNameA, Property.Builder fieldB) {
        return fieldMap(fieldNameA, fieldB, false).add();
    }
   
    /**
     *
     *
     * @param fieldA
     * @param fieldNameB
     * @param byDefault
     * @return
     */
    public ClassMapBuilder<A,B> field(Property.Builder fieldA, String fieldNameB) {
        return fieldMap(fieldA, fieldNameB, false).add();
    }
   
   
    /**
     * Exclude the specified field from mapping
     *
     * @param fieldName the name of the field/property to exclude
     * @return
     */
    public ClassMapBuilder<A, B> exclude(String fieldName) {
        return fieldMap(fieldName).exclude().add();
    }
   
    /**
     * Set the custom mapper to use for this mapping.
     *
     * @param legacyCustomizedMapper
     * @return
     * @deprecated use {@link #customize(Mapper)} instead
     */
    @Deprecated
    public final ClassMapBuilder<A, B> customize(ma.glasnost.orika.MapperBase<A, B> legacyCustomizedMapper) {
        customize(new ma.glasnost.orika.MapperBase.MapperBaseAdapter<A, B>(legacyCustomizedMapper));
        return this;
    }
   
    /**
     * Set the custom mapper to use for this mapping.
     *
     * @param customizedMapper
     * @return
     */
    public ClassMapBuilder<A, B> customize(Mapper<A, B> customizedMapper) {
        this.customizedMapper = customizedMapper;
        return this;
    }
   
    /**
     * Configure this ClassMapBuilder to use an existing mapping (for parent classes)
     * defined from <code>aParentClass</code> to <code>bParentClass</code>.
     *
     * @param aParentClass the source class of the parent mapping
     * @param bParentClass the destination class of the parent mapping
     * @return this ClassMapBuilder
     */
    public <X, Y> ClassMapBuilder<A, B> use(Class<?> aParentClass, Class<?> bParentClass) {
       
        @SuppressWarnings("unchecked")
        Type<Object> aParentType = TypeFactory.valueOf((Class<Object>) aParentClass);
        @SuppressWarnings("unchecked")
        Type<Object> bParentType = TypeFactory.valueOf((Class<Object>) bParentClass);
       
        return use(aParentType, bParentType);
    }
   
    /**
     * Configure this ClassMapBuilder to use an existing mapping (for parent classes)
     * defined from <code>aParentClass</code> to <code>bParentClass</code>.
     *
     * @param aParentClass the source type of the parent mapping
     * @param bParentClass the destination type of the parent mapping
     * @return this ClassMapBuilder
     */
    public <X, Y> ClassMapBuilder<A, B> use(Type<?> aParentType, Type<?> bParentType) {
       
        if (!aParentType.isAssignableFrom(aType)) {
            throw new MappingException(aType.getSimpleName() + " is not a subclass of " + aParentType.getSimpleName());
        }
       
        if (!bParentType.isAssignableFrom(bType)) {
            throw new MappingException(bType.getSimpleName() + " is not a subclass of " + bParentType.getSimpleName());
        }
       
        usedMappers.add(new MapperKey(aParentType, bParentType));
       
        return this;
    }
   
    /**
     * Configures this class-map builder to employ the default property mapping
     * behavior to any properties that have not already been mapped or excluded;
     * if any DefaultFieldMapper instances are passed, they will be used (instead of
     * those configured on the builder) to attempt a property name match if a direct
     * match is not found.
     *
     * @param withDefaults zero or more DefaultFieldMapper instances to apply during the default mapping;
     * if none are supplied, the configured DefaultFieldMappers for the builder (if any) should be used.
     * @return this ClassMapBuilder instance
     */
    public ClassMapBuilder<A, B> byDefault(DefaultFieldMapper... withDefaults) {
       
      DefaultFieldMapper[] defaults;
      if (withDefaults.length == 0) {
        defaults = getDefaultFieldMappers();
      } else {
        defaults = withDefaults;
      }
     
        for (final String propertyName : getPropertiesForTypeA()) {
            if (!getMappedPropertiesForTypeA().contains(propertyName)) {
                if (getPropertiesForTypeB().contains(propertyName)) {
                    if (!getMappedPropertiesForTypeB().contains(propertyName)) {
                        /*
                         * Don't include the default mapping of Class to Class; this
                         * property is resolved for all types, but can't be mapped
                         * in either direction.
                         */
                        if (!propertyName.equals("class")) {
                            fieldMap(propertyName, true).add();
                        }
                    }
                } else {
                    Property prop = resolvePropertyForA(propertyName);
                    for (DefaultFieldMapper defaulter : defaults) {
                        String suggestion = defaulter.suggestMappedField(propertyName, prop.getType());
                        if (suggestion != null && getPropertiesForTypeB().contains(suggestion)) {
                            if (!getMappedPropertiesForTypeB().contains(suggestion)) {
                                fieldMap(propertyName, suggestion, true).add();
                            }
                        }
                    }
                }
            }
        }
       
        return this;
    }
   
    /**
     * @deprecated use {@link #byDefault(DefaultFieldMapper...)} instead
     *
     * @param hint0
     *            first hint
     * @param mappingHints
     *            remaining hints
     * @return
     */
    @Deprecated
    public final ClassMapBuilder<A, B> byDefault(ma.glasnost.orika.MappingHint hint0, ma.glasnost.orika.MappingHint... mappingHints) {
        ma.glasnost.orika.MappingHint[] hints = new ma.glasnost.orika.MappingHint[mappingHints.length + 1];
        hints[0] = hint0;
        if (mappingHints.length > 0) {
            System.arraycopy(mappingHints, 0, hints, 1, mappingHints.length);
        }
        return byDefault(hints);
    }
   
    /**
     * @deprecated use {@link #byDefault(DefaultFieldMapper...)} instead
     *
     * @param mappingHints
     * @return
     */
    @Deprecated
    public final ClassMapBuilder<A, B> byDefault(ma.glasnost.orika.MappingHint[] mappingHints) {
       
        for (final String propertyName : aProperties.keySet()) {
            if (!propertiesCacheA.contains(propertyName)) {
                if (bProperties.containsKey(propertyName)) {
                    if (!propertiesCacheB.contains(propertyName)) {
                        /*
                         * Don't include the default mapping of Class to Class; this
                         * property is resolved for all types, but can't be mapped
                         * in either direction.
                         */
                        if (!propertyName.equals("class")) {
                            fieldMap(propertyName).add();
                        }
                    }
                } else {
                    Property prop = aProperties.get(propertyName);
                    for (ma.glasnost.orika.MappingHint hint : mappingHints) {
                        String suggestion = hint.suggestMappedField(propertyName, prop.getType().getRawType());
                        if (suggestion != null && bProperties.containsKey(suggestion)) {
                            if (!propertiesCacheB.contains(suggestion)) {
                                fieldMap(propertyName, suggestion).add();
                            }
                        }
                    }
                }
            }
        }
       
        return this;
    }
   
    /**
     * Produces a ClassMap instance based on the configurations defined on this
     * ClassMapBuilder. A ClassMap is used by Orika as a runtime descriptor for
     * the details of a mapping between one type and another.
     *
     * @return a ClassMap as configured by this ClassMapBuilder
     */
    public ClassMap<A, B> toClassMap() {
     
      if(LOGGER.isDebugEnabled()) {
          LOGGER.debug("ClassMap created:\n\t" + describeClassMap());
        }
     
        return new ClassMap<A, B>(aType, bType, fieldsMapping, customizedMapper, usedMappers, constructorA, constructorB, sourcesMappedOnNull, destinationsMappedOnNull);
    }
   
    /**
     * @param destinationsMappedOnNull true|false to indicate whether the destination
     * properties of this class map's fields should be set to null (when mapping in the forward
     * direction) if the source property's value is null
     *
     * @return this FieldMapBuilder
     */
    public ClassMapBuilder<A, B> mapNulls(boolean destinationsMappedOnNull) {
        this.destinationsMappedOnNull = destinationsMappedOnNull;
       
        return this;
    }
   
    /**
     * @param sourcesMappedOnNull true|false to indicate whether the source properties of
     * this class map's fields should be set to null (when mapping in the reverse direction)
     * if the destination property's value is null
     *
     * @return this FieldMapBuilder
     */
    public ClassMapBuilder<A, B> mapNullsInReverse(boolean sourcesMappedOnNull) {
        this.sourcesMappedOnNull = sourcesMappedOnNull;
       
        return this;
    }
   
    /**
     * Registers the ClassMap defined by this builder with it's initiating MapperFactory
     */
    public void register() {
        if (this.mapperFactory == null) {
            throw new IllegalStateException("register() is not supported from deprecated static ClassMapBuilder.map(..) instances");
        }
        mapperFactory.registerClassMap(this);
    }
   
    /**
     * @return a pseudo-code description of the class map that is created by this builder
     */
    protected String describeClassMap() {
      StringBuilder output = new StringBuilder();
      output.append(getClass().getSimpleName() + ".map(" + aType + ", " + bType + ")");
      for (FieldMap f: fieldsMapping) {
        if (f.isExcluded()) {
          output.append("\n\t .exclude('" + f.getSourceName() + "')");
        } else {
          output.append("\n\t .field( " + f.getSource() + ", " + f.getDestination() + " )");
        }
      } 
      if (constructorA != null) {
        output.append("\n\t .constructorA(" + Arrays.toString(constructorA) + ")");
      }
      if (constructorB != null) {
        output.append("\n\t .constructorB(" + Arrays.toString(constructorB) + ")");
      }
      return output.toString();
    }
   
    /**
     * Creates a new ClassMapBuilder configuration for mapping between <code>aType</code>
     * and <code>bType</code>.
     *
     * @param aType
     * @param bType
     * @return
     * @deprecated use {@link ma.glasnost.orika.MapperFactory#classMap(Class, Class)} instead
     */
    public static final <A, B> ClassMapBuilder<A, B> map(Class<A> aType, Class<B> bType) {
        return new ClassMapBuilder<A, B>(TypeFactory.<A> valueOf(aType), TypeFactory.<B> valueOf(bType));
    }
   
    /**
     * @param aType
     * @param bType
     * @return
     * @deprecated use {@link ma.glasnost.orika.MapperFactory#classMap(Type, Type)} instead
     */
    public static final <A, B> ClassMapBuilder<A, B> map(Type<A> aType, Type<B> bType) {
        return new ClassMapBuilder<A, B>(aType, bType);
    }
   
    /**
     * @param aType
     * @param bType
     * @return
     * @deprecated use {@link ma.glasnost.orika.MapperFactory#classMap(Class, Type)} instead
     */
    public static final <A, B> ClassMapBuilder<A, B> map(Class<A> aType, Type<B> bType) {
        return new ClassMapBuilder<A, B>(TypeFactory.<A> valueOf(aType), bType);
    }
   
    /**
     * @param aType
     * @param bType
     * @return
     * @deprecated use {@link ma.glasnost.orika.MapperFactory#classMap(Type, Class)} instead
     */
    public static final <A, B> ClassMapBuilder<A, B> map(Type<A> aType, Class<B> bType) {
        return new ClassMapBuilder<A, B>(aType, TypeFactory.<B> valueOf(bType));
    }
   
    /**
     * Determines whether the provided string is a valid property expression
     *
     * @param expression the expression to evaluate
     * @return
     */
    protected boolean isNestedPropertyExpression(String expression) {
        return expression.indexOf('.') != -1;
    }
   
    /**
     * Resolves a property for the particular type, based on the provided property expression
     *
     * @param type the type to resolve
     * @param expr the property expression to resolve
     * @return the Property referenced by the provided expression
     */
    protected Property resolveProperty(java.lang.reflect.Type type, String expr) {
        return propertyResolver.getProperty(type, expr);
    }
   
  /**
     * Resolves a property expression for this builder's 'A' type
     *
     * @param expr the property expression
     * @return the Property referenced by the provided expression
     */
    protected Property resolvePropertyForA(String expr) {
        return resolveProperty(aType, expr);
    }
   
    /**
     * Resolves a property expression for this builder's 'B' type
     *
     * @param expr the property expression
     * @return the Property referenced by the provided expression
     */
    protected Property resolvePropertyForB(String expr) {
        return resolveProperty(bType, expr);
    }
   
    /**
     * @return the 'A' type for this builder
     */
    public Type<A> getAType() {
      return aType;
    }
   
    /**
     * @return the 'B' type for this builder
     */
    public Type<B> getBType() {
      return bType;
    }
   
    protected void addFieldMap(FieldMap fieldMap) {
      getMappedFields().add(fieldMap);
        getMappedPropertiesForTypeA().add(fieldMap.getSourceExpression());
        getMappedPropertiesForTypeB().add(fieldMap.getDestinationExpression());
    }
   
    /**
     * @return the mapped properties for type A
     */
    protected Set<String> getMappedPropertiesForTypeA() {
      return propertiesCacheA;
    }
   
    /**
     * @return the mapped properties for type B
     */
    protected Set<String> getMappedPropertiesForTypeB() {
      return propertiesCacheB;
    }
   
    /**
     * @return the mapped fields for this builder
     */
    protected Set<FieldMap> getMappedFields() {
      return fieldsMapping;
    }
   
    /**
     * @return the known properties for type A
     */
    protected Set<String> getPropertiesForTypeA() {
      return aProperties.keySet();
    }
   
    /**
     * @return the known properties for type B
     */
    protected Set<String> getPropertiesForTypeB() {
      return bProperties.keySet();
    }
   
    /**
     * @return the default field mappers (if any) configured for this builder
     */
    protected DefaultFieldMapper[] getDefaultFieldMappers() {
      return defaults;
    }
   
    /**
     * @return the property resolver used by this builder
     */
    protected PropertyResolverStrategy getPropertyResolver() {
      return this.propertyResolver;
    }
   
    /**
     * Declares a constructor to be used for the A type
     * with the specified arguments.
     *
     * @param args the arguments identifying the constructor to be used
     * @return this ClassMapBuilder
     */
    public ClassMapBuilder<A, B> constructorA(String... args) {
        this.constructorA = args.clone();
        return this;
    }
   
    /**
     * Declares a constructor to be used for the B type
     * with the specified arguments.
     *
     * @param args the arguments identifying the constructor to be used
     * @return this ClassMapBuilder
     */
    public ClassMapBuilder<A, B> constructorB(String... args) {
        this.constructorB = args.clone();
        return this;
    }
   
    public String toString() {
        return getClass().getSimpleName() + "[" + getAType() + ", " + getBType() + "]";
    }
   
}
TOP

Related Classes of ma.glasnost.orika.metadata.ClassMapBuilder$Factory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.