use of org.mapstruct.ap.internal.util.accessor.ReadAccessor in project mapstruct by mapstruct.
the class Filters method recordAccessorsIn.
public Map<String, ReadAccessor> recordAccessorsIn(Collection<Element> recordComponents) {
if (RECORD_COMPONENT_ACCESSOR_METHOD == null) {
return java.util.Collections.emptyMap();
}
try {
Map<String, ReadAccessor> recordAccessors = new LinkedHashMap<>();
for (Element recordComponent : recordComponents) {
ExecutableElement recordExecutableElement = (ExecutableElement) RECORD_COMPONENT_ACCESSOR_METHOD.invoke(recordComponent);
recordAccessors.put(recordComponent.getSimpleName().toString(), ReadAccessor.fromGetter(recordExecutableElement, getReturnType(recordExecutableElement)));
}
return recordAccessors;
} catch (IllegalAccessException | InvocationTargetException e) {
return java.util.Collections.emptyMap();
}
}
use of org.mapstruct.ap.internal.util.accessor.ReadAccessor in project mapstruct by mapstruct.
the class Type method getAlternativeTargetAccessors.
/**
* Alternative accessors could be a getter for a collection. By means of the
* {@link java.util.Collection#addAll(java.util.Collection) } this getter can still
* be used as targetAccessor. JAXB XJC tool generates such constructs.
*
* This method can be extended when new cases come along.
*
* @return an unmodifiable list of alternative target accessors.
*/
private List<Accessor> getAlternativeTargetAccessors() {
if (alternativeTargetAccessors != null) {
return alternativeTargetAccessors;
}
if (isRecord()) {
alternativeTargetAccessors = Collections.emptyList();
}
if (alternativeTargetAccessors == null) {
List<Accessor> result = new ArrayList<>();
List<Accessor> setterMethods = getSetters();
List<Accessor> readAccessors = new ArrayList<>(getPropertyReadAccessors().values());
// All the fields are also alternative accessors
readAccessors.addAll(filters.fieldsIn(getAllFields(), FieldElementAccessor::new));
// (assuming it is initialized)
for (Accessor readAccessor : readAccessors) {
if (isCollectionOrMapOrStream(readAccessor) && !correspondingSetterMethodExists(readAccessor, setterMethods)) {
result.add(readAccessor);
} else if (readAccessor.getAccessorType() == AccessorType.FIELD && !correspondingSetterMethodExists(readAccessor, setterMethods)) {
result.add(readAccessor);
}
}
alternativeTargetAccessors = Collections.unmodifiableList(result);
}
return alternativeTargetAccessors;
}
use of org.mapstruct.ap.internal.util.accessor.ReadAccessor in project mapstruct by mapstruct.
the class Type method getPropertyReadAccessors.
/**
* getPropertyReadAccessors
*
* @return an unmodifiable map of all read accessors (including 'is' for booleans), indexed by property name
*/
public Map<String, ReadAccessor> getPropertyReadAccessors() {
if (readAccessors == null) {
Map<String, ReadAccessor> modifiableGetters = new LinkedHashMap<>();
Map<String, ReadAccessor> recordAccessors = filters.recordAccessorsIn(getRecordComponents());
modifiableGetters.putAll(recordAccessors);
List<ReadAccessor> getterList = filters.getterMethodsIn(getAllMethods());
for (ReadAccessor getter : getterList) {
String simpleName = getter.getSimpleName();
if (recordAccessors.containsKey(simpleName)) {
// but the property name is isActive, since it is a record
continue;
}
String propertyName = getPropertyName(getter);
if (recordAccessors.containsKey(propertyName)) {
// If there is already a record accessor, the property needs to be ignored
continue;
}
if (modifiableGetters.containsKey(propertyName)) {
// getFoo(); The latter is preferred.
if (!simpleName.startsWith("is")) {
modifiableGetters.put(propertyName, getter);
}
} else {
modifiableGetters.put(propertyName, getter);
}
}
List<ReadAccessor> fieldsList = filters.fieldsIn(getAllFields(), ReadAccessor::fromField);
for (ReadAccessor field : fieldsList) {
String propertyName = getPropertyName(field);
// If there was no getter or is method for booleans, then resort to the field.
// If a field was already added do not add it again.
modifiableGetters.putIfAbsent(propertyName, field);
}
readAccessors = Collections.unmodifiableMap(modifiableGetters);
}
return readAccessors;
}
use of org.mapstruct.ap.internal.util.accessor.ReadAccessor in project mapstruct by mapstruct.
the class SourceReference method push.
public List<SourceReference> push(TypeFactory typeFactory, FormattingMessager messager, Method method) {
List<SourceReference> result = new ArrayList<>();
PropertyEntry deepestProperty = getDeepestProperty();
if (deepestProperty != null) {
Type type = deepestProperty.getType();
Map<String, ReadAccessor> newDeepestReadAccessors = type.getPropertyReadAccessors();
String parameterName = getParameter().getName();
String deepestPropertyFullName = deepestProperty.getFullName();
for (Map.Entry<String, ReadAccessor> newDeepestReadAccessorEntry : newDeepestReadAccessors.entrySet()) {
// Always include the parameter name in the new full name.
// Otherwise multi source parameters might be reported incorrectly
String newFullName = parameterName + "." + deepestPropertyFullName + "." + newDeepestReadAccessorEntry.getKey();
SourceReference sourceReference = new BuilderFromMapping().sourceName(newFullName).method(method).messager(messager).typeFactory(typeFactory).build();
result.add(sourceReference);
}
}
return result;
}
use of org.mapstruct.ap.internal.util.accessor.ReadAccessor 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;
}
Aggregations