All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.modelmapper.internal.PropertyInfoSetResolver Maven / Gradle / Ivy
/*
* Copyright 2011 the original author or 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 org.modelmapper.internal;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.Map;
import org.modelmapper.config.Configuration;
import org.modelmapper.config.Configuration.AccessLevel;
import org.modelmapper.spi.NameTransformer;
import org.modelmapper.spi.NameableType;
import org.modelmapper.spi.NamingConvention;
import org.modelmapper.spi.PropertyInfo;
import org.modelmapper.spi.PropertyType;
import org.modelmapper.spi.ValueReader;
import org.modelmapper.spi.ValueWriter;
/**
* Resolves sets of PropertyInfo for a type's accessors or mutators.
*
* @author Jonathan Halterman
*/
final class PropertyInfoSetResolver {
private PropertyInfoSetResolver() {
}
private static class ResolveRequest {
PropertyInfoResolver propertyResolver;
PropertyType propertyType;
Configuration config;
AccessLevel accessLevel;
NamingConvention namingConvention;
NameTransformer nameTransformer;
}
static boolean canAccessMember(Member member, AccessLevel accessLevel) {
int mod = member.getModifiers();
switch (accessLevel) {
default:
case PUBLIC:
return Modifier.isPublic(mod);
case PROTECTED:
return Modifier.isPublic(mod) || Modifier.isProtected(mod);
case PACKAGE_PRIVATE:
return Modifier.isPublic(mod) || Modifier.isProtected(mod) || !Modifier.isPrivate(mod);
case PRIVATE:
return true;
}
}
static Map resolveAccessors(T source, Class type,
InheritingConfiguration configuration) {
ValueReader valueReader = configuration.valueAccessStore.getFirstSupportedReader(type);
if (source != null && valueReader != null)
return resolveAccessorsFromValueReader(source, configuration, valueReader);
else
return resolveProperties(type, true, configuration);
}
static Map resolveAccessorsFromValueReader(T source,
InheritingConfiguration configuration, ValueReader valueReader) {
Map accessors = new LinkedHashMap();
NameTransformer nameTransformer = configuration.getSourceNameTransformer();
for (String memberName : valueReader.memberNames(source)) {
ValueReader.Member> member = valueReader.getMember(source, memberName);
if (member != null)
accessors.put(nameTransformer.transform(memberName, NameableType.GENERIC),
PropertyInfoImpl.ValueReaderPropertyInfo.fromMember(member, memberName));
}
return accessors;
}
static Map resolveMutators(Class type, InheritingConfiguration configuration) {
ValueWriter valueWriter = configuration.valueMutateStore.getFirstSupportedWriter(type);
if (valueWriter != null && valueWriter.isResolveMembersSupport())
return resolveMutatorsFromValueWriter(type, configuration, valueWriter);
return resolveProperties(type, false, configuration);
}
static Map resolveMutatorsFromValueWriter(Class type,
InheritingConfiguration configuration, ValueWriter valueWriter) {
Map mutators = new LinkedHashMap();
NameTransformer nameTransformer = configuration.getSourceNameTransformer();
for (String memberName : valueWriter.memberNames(type)) {
ValueWriter.Member> member = valueWriter.getMember(type, memberName);
if (member != null)
mutators.put(nameTransformer.transform(memberName, NameableType.GENERIC),
PropertyInfoImpl.ValueWriterPropertyInfo.fromMember(member, memberName));
}
return mutators;
}
@SuppressWarnings({ "unchecked" })
private static Map resolveProperties(
Class> type, boolean access, Configuration configuration) {
Map properties = new LinkedHashMap();
if (configuration.isFieldMatchingEnabled()) {
properties.putAll(resolveProperties(type, type, PropertyInfoSetResolver.resolveRequest(configuration, access, true)));
}
properties.putAll(resolveProperties(type, type, PropertyInfoSetResolver.resolveRequest(configuration, access, false)));
return properties;
}
/**
* Populates the {@code resolveRequest.propertyInfo} with {@code resolveRequest.propertyResolver}
* resolved property info for properties that are accessible by the
* {@code resolveRequest.accessLevel} and satisfy the {@code resolveRequest.namingConvention}.
* Uses a depth-first search so that child properties of the same name override parents.
*/
private static Map resolveProperties(
Class> initialType, Class> type, ResolveRequest resolveRequest) {
Map properties = new LinkedHashMap();
Class> superType = type.getSuperclass();
if (superType != null && superType != Object.class && superType != Enum.class)
properties.putAll(resolveProperties(initialType, superType, resolveRequest));
for (M member : resolveRequest.propertyResolver.membersFor(type)) {
if (canAccessMember(member, resolveRequest.accessLevel)
&& resolveRequest.propertyResolver.isValid(member)
&& resolveRequest.namingConvention.applies(member.getName(), resolveRequest.propertyType)) {
String name = resolveRequest.nameTransformer.transform(member.getName(),
PropertyType.FIELD.equals(resolveRequest.propertyType) ? NameableType.FIELD
: NameableType.METHOD);
PI info = resolveRequest.propertyResolver.propertyInfoFor(initialType, member,
resolveRequest.config, name);
properties.put(name, info);
if (!Modifier.isPublic(member.getModifiers())
|| !Modifier.isPublic(member.getDeclaringClass().getModifiers()))
try {
member.setAccessible(true);
} catch (SecurityException e) {
throw new AssertionError(e);
}
}
}
return properties;
}
@SuppressWarnings("unchecked")
private static ResolveRequest resolveRequest(
Configuration configuration, boolean access, boolean field) {
ResolveRequest resolveRequest = new ResolveRequest();
resolveRequest.config = configuration;
if (access) {
resolveRequest.namingConvention = configuration.getSourceNamingConvention();
resolveRequest.nameTransformer = configuration.getSourceNameTransformer();
} else {
resolveRequest.namingConvention = configuration.getDestinationNamingConvention();
resolveRequest.nameTransformer = configuration.getDestinationNameTransformer();
}
if (field) {
resolveRequest.propertyType = PropertyType.FIELD;
resolveRequest.accessLevel = configuration.getFieldAccessLevel();
resolveRequest.propertyResolver = (PropertyInfoResolver) PropertyInfoResolver.FIELDS;
} else {
resolveRequest.propertyType = PropertyType.METHOD;
resolveRequest.accessLevel = configuration.getMethodAccessLevel();
resolveRequest.propertyResolver = (PropertyInfoResolver) (access ? PropertyInfoResolver.ACCESSORS
: PropertyInfoResolver.MUTATORS);
}
return resolveRequest;
}
}