Search in sources :

Example 6 with Accessor

use of org.mapstruct.ap.internal.util.accessor.Accessor in project mapstruct by mapstruct.

the class Executables method addFields.

private static void addFields(List<Accessor> alreadyCollected, List<VariableElement> variablesToAdd) {
    List<Accessor> safeToAdd = new ArrayList<Accessor>(variablesToAdd.size());
    for (VariableElement toAdd : variablesToAdd) {
        safeToAdd.add(new VariableElementAccessor(toAdd));
    }
    alreadyCollected.addAll(0, safeToAdd);
}
Also used : VariableElementAccessor(org.mapstruct.ap.internal.util.accessor.VariableElementAccessor) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) Accessor(org.mapstruct.ap.internal.util.accessor.Accessor) VariableElementAccessor(org.mapstruct.ap.internal.util.accessor.VariableElementAccessor) ExecutableElementAccessor(org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor)

Example 7 with Accessor

use of org.mapstruct.ap.internal.util.accessor.Accessor in project mapstruct by mapstruct.

the class Type method getPropertyWriteAccessors.

/**
 * getPropertyWriteAccessors returns a map of the write accessors according to the CollectionMappingStrategy. These
 * accessors include:
 * <ul>
 * <li>setters, the obvious candidate :-), {@link #getSetters() }</li>
 * <li>readAccessors, for collections that do not have a setter, e.g. for JAXB generated collection attributes
 * {@link #getPropertyReadAccessors() }</li>
 * <li>adders, typically for from table generated entities, {@link #getAdders() }</li>
 * </ul>
 *
 * @param cmStrategy collection mapping strategy
 * @return an unmodifiable map of all write accessors indexed by property name
 */
public Map<String, Accessor> getPropertyWriteAccessors(CollectionMappingStrategyGem cmStrategy) {
    // collect all candidate target accessors
    List<Accessor> candidates = new ArrayList<>(getSetters());
    candidates.addAll(getAlternativeTargetAccessors());
    Map<String, Accessor> result = new LinkedHashMap<>();
    for (Accessor candidate : candidates) {
        String targetPropertyName = getPropertyName(candidate);
        Accessor readAccessor = getPropertyReadAccessors().get(targetPropertyName);
        Type preferredType = determinePreferredType(readAccessor);
        Type targetType = determineTargetType(candidate);
        // The following if block, checks if the target accessor should be overruled by an add method.
        if (cmStrategy == CollectionMappingStrategyGem.SETTER_PREFERRED || cmStrategy == CollectionMappingStrategyGem.ADDER_PREFERRED || cmStrategy == CollectionMappingStrategyGem.TARGET_IMMUTABLE) {
            // first check if there's a setter method.
            Accessor adderMethod = null;
            if (candidate.getAccessorType() == AccessorType.SETTER && // ok, the current accessor is a setter. So now the strategy determines what to use
            cmStrategy == CollectionMappingStrategyGem.ADDER_PREFERRED) {
                adderMethod = getAdderForType(targetType, targetPropertyName);
            } else if (candidate.getAccessorType() == AccessorType.GETTER) {
                // the current accessor is a getter (no setter available). But still, an add method is according
                // to the above strategy (SETTER_PREFERRED || ADDER_PREFERRED) preferred over the getter.
                adderMethod = getAdderForType(targetType, targetPropertyName);
            }
            if (adderMethod != null) {
                // an adder has been found (according strategy) so overrule current choice.
                candidate = adderMethod;
            }
        } else if (candidate.getAccessorType() == AccessorType.FIELD && (Executables.isFinal(candidate) || result.containsKey(targetPropertyName))) {
            // if the candidate is a field and a mapping already exists, then use that one, skip it.
            continue;
        }
        Accessor previousCandidate = result.get(targetPropertyName);
        if (previousCandidate == null || preferredType == null || (targetType != null && typeUtils.isAssignable(preferredType.getTypeMirror(), targetType.getTypeMirror()))) {
            result.put(targetPropertyName, candidate);
        }
    }
    return result;
}
Also used : AccessorType(org.mapstruct.ap.internal.util.accessor.AccessorType) DeclaredType(javax.lang.model.type.DeclaredType) WildcardType(javax.lang.model.type.WildcardType) ArrayType(javax.lang.model.type.ArrayType) PrimitiveType(javax.lang.model.type.PrimitiveType) ArrayList(java.util.ArrayList) Accessor(org.mapstruct.ap.internal.util.accessor.Accessor) PresenceCheckAccessor(org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor) FieldElementAccessor(org.mapstruct.ap.internal.util.accessor.FieldElementAccessor) ReadAccessor(org.mapstruct.ap.internal.util.accessor.ReadAccessor) MapValueAccessor(org.mapstruct.ap.internal.util.accessor.MapValueAccessor) LinkedHashMap(java.util.LinkedHashMap)

Example 8 with Accessor

use of org.mapstruct.ap.internal.util.accessor.Accessor in project mapstruct by mapstruct.

the class Type method getAccessorCandidates.

/**
 * Returns all accessor candidates that start with "add" and have exactly one argument
 * whose type matches the collection or stream property's type argument.
 *
 * @param property the collection or stream property
 * @param superclass the superclass to use for type argument lookup
 *
 * @return accessor candidates
 */
private List<Accessor> getAccessorCandidates(Type property, Class<?> superclass) {
    TypeMirror typeArg = first(property.determineTypeArguments(superclass)).getTypeBound().getTypeMirror();
    // now, look for a method that
    // 1) starts with add,
    // 2) and has typeArg as one and only arg
    List<Accessor> adderList = getAdders();
    List<Accessor> candidateList = new ArrayList<>();
    for (Accessor adder : adderList) {
        ExecutableElement executable = (ExecutableElement) adder.getElement();
        VariableElement arg = executable.getParameters().get(0);
        if (typeUtils.isSameType(boxed(arg.asType()), boxed(typeArg))) {
            candidateList.add(adder);
        }
    }
    return candidateList;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) Accessor(org.mapstruct.ap.internal.util.accessor.Accessor) PresenceCheckAccessor(org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor) FieldElementAccessor(org.mapstruct.ap.internal.util.accessor.FieldElementAccessor) ReadAccessor(org.mapstruct.ap.internal.util.accessor.ReadAccessor) MapValueAccessor(org.mapstruct.ap.internal.util.accessor.MapValueAccessor)

Aggregations

Accessor (org.mapstruct.ap.internal.util.accessor.Accessor)8 ArrayList (java.util.ArrayList)7 ExecutableElementAccessor (org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor)4 ExecutableElement (javax.lang.model.element.ExecutableElement)3 VariableElement (javax.lang.model.element.VariableElement)3 FieldElementAccessor (org.mapstruct.ap.internal.util.accessor.FieldElementAccessor)3 MapValueAccessor (org.mapstruct.ap.internal.util.accessor.MapValueAccessor)3 PresenceCheckAccessor (org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor)3 ReadAccessor (org.mapstruct.ap.internal.util.accessor.ReadAccessor)3 LinkedHashMap (java.util.LinkedHashMap)2 DeclaredType (javax.lang.model.type.DeclaredType)2 TypeMirror (javax.lang.model.type.TypeMirror)2 WildcardType (javax.lang.model.type.WildcardType)2 VariableElementAccessor (org.mapstruct.ap.internal.util.accessor.VariableElementAccessor)2 ArrayType (javax.lang.model.type.ArrayType)1 PrimitiveType (javax.lang.model.type.PrimitiveType)1 CollectionMappingStrategyGem (org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem)1 Type (org.mapstruct.ap.internal.model.common.Type)1 AccessorType (org.mapstruct.ap.internal.util.accessor.AccessorType)1