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);
}
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;
}
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;
}
Aggregations