No effective change - reformat code

This commit is contained in:
Robin Bygrave
2016-07-08 15:37:26 +12:00
parent 92069c0319
commit 2c3c23725a
8 changed files with 495 additions and 497 deletions
@@ -11,118 +11,118 @@ import java.lang.reflect.Modifier;
public class CheckImmutable {
private static final Logger logger = LoggerFactory.getLogger(CheckImmutable.class);
private final KnownImmutable knownImmutable;
private static final Logger logger = LoggerFactory.getLogger(CheckImmutable.class);
public CheckImmutable(KnownImmutable knownImmutable) {
this.knownImmutable = knownImmutable;
}
public CheckImmutableResponse checkImmutable(Class<?> cls) {
private final KnownImmutable knownImmutable;
CheckImmutableResponse res = new CheckImmutableResponse();
isImmutable(cls, res);
if (res.isImmutable()){
res.setCompoundType(isCompoundType(cls));
}
return res;
public CheckImmutable(KnownImmutable knownImmutable) {
this.knownImmutable = knownImmutable;
}
public CheckImmutableResponse checkImmutable(Class<?> cls) {
CheckImmutableResponse res = new CheckImmutableResponse();
isImmutable(cls, res);
if (res.isImmutable()) {
res.setCompoundType(isCompoundType(cls));
}
private boolean isCompoundType(Class<?> cls) {
int maxLength = 0;
Constructor<?> chosen = null;
// find the constructor with the most number of parameters
Constructor<?>[] constructors = cls.getConstructors();
for (int i = 0; i < constructors.length; i++) {
Class<?>[] parameterTypes = constructors[i].getParameterTypes();
if (parameterTypes.length > maxLength){
maxLength = parameterTypes.length;
chosen = constructors[i];
}
}
logger.debug("checkImmutable "+cls+" constructor "+chosen);
return maxLength > 1;
}
private boolean isImmutable(Class<?> cls, CheckImmutableResponse res) {
return res;
}
if (knownImmutable.isKnownImmutable(cls)) {
return true;
}
if (cls.isArray()) {
return false;
}
if (hasDefaultConstructor(cls)){
// must not have a default constructor to be considered immutable
res.setReasonNotImmutable(cls+" has a default constructor");
return false;
}
private boolean isCompoundType(Class<?> cls) {
// check super class
Class<?> superClass = cls.getSuperclass();
int maxLength = 0;
Constructor<?> chosen = null;
if (!isImmutable(superClass, res)) {
res.setReasonNotImmutable("Super not Immutable " + superClass);
return false;
}
if (!hasAllFinalFields(cls, res)){
return false;
}
// Lets hope we didn't forget something
return true;
// find the constructor with the most number of parameters
Constructor<?>[] constructors = cls.getConstructors();
for (int i = 0; i < constructors.length; i++) {
Class<?>[] parameterTypes = constructors[i].getParameterTypes();
if (parameterTypes.length > maxLength) {
maxLength = parameterTypes.length;
chosen = constructors[i];
}
}
private boolean hasAllFinalFields(Class<?> cls, CheckImmutableResponse res){
logger.debug("checkImmutable " + cls + " constructor " + chosen);
// Check all fields defined in the class for type and if they are final
Field[] objFields = cls.getDeclaredFields();
for (int i = 0; i < objFields.length; i++) {
if (!Modifier.isStatic(objFields[i].getModifiers())) {
if (!Modifier.isFinal(objFields[i].getModifiers())) {
res.setReasonNotImmutable("Non final field " + cls + "." + objFields[i].getName());
return false;
}
if (!isImmutable(objFields[i].getType(), res)) {
res.setReasonNotImmutable("Non Immutable field type " + objFields[i].getType());
return false;
}
}
}
return maxLength > 1;
}
return true;
private boolean isImmutable(Class<?> cls, CheckImmutableResponse res) {
if (knownImmutable.isKnownImmutable(cls)) {
return true;
}
private boolean hasDefaultConstructor(Class<?> cls) {
Class<?>[] noParams = new Class<?>[0];
try {
cls.getDeclaredConstructor(noParams);
return true;
} catch (SecurityException e) {
// this is ok
return false;
} catch (NoSuchMethodException e) {
// this is expected for our IVO's
return false;
}
if (cls.isArray()) {
return false;
}
if (hasDefaultConstructor(cls)) {
// must not have a default constructor to be considered immutable
res.setReasonNotImmutable(cls + " has a default constructor");
return false;
}
// check super class
Class<?> superClass = cls.getSuperclass();
if (!isImmutable(superClass, res)) {
res.setReasonNotImmutable("Super not Immutable " + superClass);
return false;
}
if (!hasAllFinalFields(cls, res)) {
return false;
}
// Lets hope we didn't forget something
return true;
}
private boolean hasAllFinalFields(Class<?> cls, CheckImmutableResponse res) {
// Check all fields defined in the class for type and if they are final
Field[] objFields = cls.getDeclaredFields();
for (int i = 0; i < objFields.length; i++) {
if (!Modifier.isStatic(objFields[i].getModifiers())) {
if (!Modifier.isFinal(objFields[i].getModifiers())) {
res.setReasonNotImmutable("Non final field " + cls + "." + objFields[i].getName());
return false;
}
if (!isImmutable(objFields[i].getType(), res)) {
res.setReasonNotImmutable("Non Immutable field type " + objFields[i].getType());
return false;
}
}
}
return true;
}
private boolean hasDefaultConstructor(Class<?> cls) {
Class<?>[] noParams = new Class<?>[0];
try {
cls.getDeclaredConstructor(noParams);
return true;
} catch (SecurityException e) {
// this is ok
return false;
} catch (NoSuchMethodException e) {
// this is expected for our IVO's
return false;
}
}
}
@@ -1,37 +1,36 @@
package com.avaje.ebeaninternal.server.type.reflect;
public class CheckImmutableResponse {
private boolean immutable = true;
private String reasonNotImmutable;
private boolean immutable = true;
private boolean compoundType;
public String toString(){
if(immutable){
return "immutable";
} else {
return "not immutable due to:"+reasonNotImmutable;
}
}
private String reasonNotImmutable;
public boolean isCompoundType() {
return compoundType;
}
private boolean compoundType;
public void setCompoundType(boolean compoundType) {
this.compoundType = compoundType;
public String toString() {
if (immutable) {
return "immutable";
} else {
return "not immutable due to:" + reasonNotImmutable;
}
}
public void setReasonNotImmutable(String error) {
this.immutable = false;
this.reasonNotImmutable = error;
}
public boolean isCompoundType() {
return compoundType;
}
public boolean isImmutable() {
return immutable;
}
public void setCompoundType(boolean compoundType) {
this.compoundType = compoundType;
}
public void setReasonNotImmutable(String error) {
this.immutable = false;
this.reasonNotImmutable = error;
}
public boolean isImmutable() {
return immutable;
}
}
@@ -6,25 +6,25 @@ import java.lang.reflect.Method;
public class ImmutableMeta {
private final Constructor<?> constructor;
private final Method[] readers;
public ImmutableMeta(Constructor<?> constructor, Method[] readers) {
this.constructor = constructor;
this.readers = readers;
}
public Constructor<?> getConstructor() {
return constructor;
}
private final Constructor<?> constructor;
public Method[] getReaders() {
return readers;
}
public boolean isCompoundType() {
return readers.length > 1;
}
private final Method[] readers;
public ImmutableMeta(Constructor<?> constructor, Method[] readers) {
this.constructor = constructor;
this.readers = readers;
}
public Constructor<?> getConstructor() {
return constructor;
}
public Method[] getReaders() {
return readers;
}
public boolean isCompoundType() {
return readers.length > 1;
}
}
@@ -14,213 +14,212 @@ import java.util.HashSet;
public class ImmutableMetaFactory {
private static final Logger logger = LoggerFactory.getLogger(ImmutableMetaFactory.class);
public ImmutableMeta createImmutableMeta(Class<?> cls) {
ScoreConstructor[] scoreConstructors = scoreConstructors(cls);
ArrayList<RuntimeException> errors = new ArrayList<RuntimeException>();
// search the constructors in score order ...
// ... we need to find a set of readers for each
// ... type in the constructor
for (int i = 0; i < scoreConstructors.length; i++) {
Constructor<?> constructor = scoreConstructors[i].constructor;
private static final Logger logger = LoggerFactory.getLogger(ImmutableMetaFactory.class);
try {
Method[] getters = findGetters(cls, constructor);
public ImmutableMeta createImmutableMeta(Class<?> cls) {
return new ImmutableMeta(constructor, getters);
} catch (NoSuchMethodException e){
String msg = "Error finding getter method on "+cls+" with constructor "+constructor;
errors.add(new RuntimeException(msg, e));
}
}
String msg = "Was unable to use reflection to find a constructor and appropriate getters for" +
"immutable type "+cls+". The errors while looking for the getter methods follow:";
logger.error(msg);
for (RuntimeException runtimeException : errors) {
logger.error("Error with " + cls, runtimeException);
}
ScoreConstructor[] scoreConstructors = scoreConstructors(cls);
msg = "Unable to use reflection to build ImmutableMeta for " + cls
+ ". Associated Errors trying to find a constructor and getter methods have been logged";
ArrayList<RuntimeException> errors = new ArrayList<RuntimeException>();
throw new RuntimeException(msg);
// search the constructors in score order ...
// ... we need to find a set of readers for each
// ... type in the constructor
for (int i = 0; i < scoreConstructors.length; i++) {
Constructor<?> constructor = scoreConstructors[i].constructor;
try {
Method[] getters = findGetters(cls, constructor);
return new ImmutableMeta(constructor, getters);
} catch (NoSuchMethodException e) {
String msg = "Error finding getter method on " + cls + " with constructor " + constructor;
errors.add(new RuntimeException(msg, e));
}
}
private ScoreConstructor getScore(Constructor<?> c) {
Class<?>[] parameterTypes = c.getParameterTypes();
int score = -1000 * parameterTypes.length;
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].equals(String.class)){
// string is very generic and we would prefer
// a more specific type if that was available
score = score + 1;
} else if (parameterTypes[i].equals(BigDecimal.class)) {
score = score - 10;
} else if (parameterTypes[i].equals(Timestamp.class)) {
score = score - 10;
} else if (parameterTypes[i].equals(double.class)) {
score = score - 9;
} else if (parameterTypes[i].equals(Double.class)) {
score = score - 8;
} else if (parameterTypes[i].equals(float.class)) {
score = score - 7;
} else if (parameterTypes[i].equals(Float.class)) {
score = score - 6;
} else if (parameterTypes[i].equals(long.class)) {
score = score - 5;
} else if (parameterTypes[i].equals(Long.class)) {
score = score - 4;
} else if (parameterTypes[i].equals(int.class)) {
score = score - 3;
} else if (parameterTypes[i].equals(Integer.class)) {
score = score - 2;
}
}
return new ScoreConstructor(score, c);
String msg = "Was unable to use reflection to find a constructor and appropriate getters for" +
"immutable type " + cls + ". The errors while looking for the getter methods follow:";
logger.error(msg);
for (RuntimeException runtimeException : errors) {
logger.error("Error with " + cls, runtimeException);
}
private ScoreConstructor[] scoreConstructors(Class<?> cls) {
// find the constructor with the most number of parameters
int maxParamCount = 0;
Constructor<?>[] constructors = cls.getConstructors();
ScoreConstructor[] score = new ScoreConstructor[constructors.length];
for (int i = 0; i < constructors.length; i++) {
score[i] = getScore(constructors[i]);
if (score[i].hasDuplicateParamTypes()){
String msg = "Duplicate parameter types in "+score[i].constructor;
throw new IllegalStateException(msg);
}
if (score[i].getParamCount() > maxParamCount){
maxParamCount = score[i].getParamCount();
}
}
// filter out any constructors with less parameters than the max
ArrayList<ScoreConstructor> list = new ArrayList<ScoreConstructor>();
for (int i = 0; i < score.length; i++) {
if (score[i].getParamCount() == maxParamCount){
list.add(score[i]);
}
}
score = list.toArray(new ScoreConstructor[list.size()]);
// sort into score ascending order
Arrays.sort(score);
msg = "Unable to use reflection to build ImmutableMeta for " + cls
+ ". Associated Errors trying to find a constructor and getter methods have been logged";
return score;
throw new RuntimeException(msg);
}
private ScoreConstructor getScore(Constructor<?> c) {
Class<?>[] parameterTypes = c.getParameterTypes();
int score = -1000 * parameterTypes.length;
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].equals(String.class)) {
// string is very generic and we would prefer
// a more specific type if that was available
score = score + 1;
} else if (parameterTypes[i].equals(BigDecimal.class)) {
score = score - 10;
} else if (parameterTypes[i].equals(Timestamp.class)) {
score = score - 10;
} else if (parameterTypes[i].equals(double.class)) {
score = score - 9;
} else if (parameterTypes[i].equals(Double.class)) {
score = score - 8;
} else if (parameterTypes[i].equals(float.class)) {
score = score - 7;
} else if (parameterTypes[i].equals(Float.class)) {
score = score - 6;
} else if (parameterTypes[i].equals(long.class)) {
score = score - 5;
} else if (parameterTypes[i].equals(Long.class)) {
score = score - 4;
} else if (parameterTypes[i].equals(int.class)) {
score = score - 3;
} else if (parameterTypes[i].equals(Integer.class)) {
score = score - 2;
}
}
private Method[] findGetters(Class<?> cls, Constructor<?> c) throws NoSuchMethodException {
Method[] methods = cls.getMethods();
return new ScoreConstructor(score, c);
}
Class<?>[] paramTypes = c.getParameterTypes();
Method[] readers = new Method[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
Method getter = findGetter(paramTypes[i], methods);
if (getter == null && paramTypes.length == 1 && paramTypes[i].equals(String.class)){
getter = findToString(cls);
}
if (getter == null) {
throw new NoSuchMethodException("Get Method not found for "+paramTypes[i]+" in "+cls);
}
readers[i] = getter;
}
return readers;
private ScoreConstructor[] scoreConstructors(Class<?> cls) {
// find the constructor with the most number of parameters
int maxParamCount = 0;
Constructor<?>[] constructors = cls.getConstructors();
ScoreConstructor[] score = new ScoreConstructor[constructors.length];
for (int i = 0; i < constructors.length; i++) {
score[i] = getScore(constructors[i]);
if (score[i].hasDuplicateParamTypes()) {
String msg = "Duplicate parameter types in " + score[i].constructor;
throw new IllegalStateException(msg);
}
if (score[i].getParamCount() > maxParamCount) {
maxParamCount = score[i].getParamCount();
}
}
private Method findToString(Class<?> cls) throws NoSuchMethodException {
try {
return cls.getDeclaredMethod("toString", new Class<?>[0]);
} catch (SecurityException e) {
throw new NoSuchMethodException("SecurityException "+e+" trying to find toString method on "+cls);
}
// filter out any constructors with less parameters than the max
ArrayList<ScoreConstructor> list = new ArrayList<ScoreConstructor>();
for (int i = 0; i < score.length; i++) {
if (score[i].getParamCount() == maxParamCount) {
list.add(score[i]);
}
}
private Method findGetter(Class<?> paramType, Method[] methods) {
for (int i = 0; i < methods.length; i++) {
if (!Modifier.isStatic(methods[i].getModifiers())) {
if (methods[i].getParameterTypes().length == 0) {
// could be a getter
String methName = methods[i].getName();
if (methName.equals("hashCode")){
} else if (methName.equals("toString")) {
score = list.toArray(new ScoreConstructor[list.size()]);
} else {
Class<?> returnType = methods[i].getReturnType();
if (paramType.equals(returnType)){
return methods[i];
}
}
}
// sort into score ascending order
Arrays.sort(score);
return score;
}
private Method[] findGetters(Class<?> cls, Constructor<?> c) throws NoSuchMethodException {
Method[] methods = cls.getMethods();
Class<?>[] paramTypes = c.getParameterTypes();
Method[] readers = new Method[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
Method getter = findGetter(paramTypes[i], methods);
if (getter == null && paramTypes.length == 1 && paramTypes[i].equals(String.class)) {
getter = findToString(cls);
}
if (getter == null) {
throw new NoSuchMethodException("Get Method not found for " + paramTypes[i] + " in " + cls);
}
readers[i] = getter;
}
return readers;
}
private Method findToString(Class<?> cls) throws NoSuchMethodException {
try {
return cls.getDeclaredMethod("toString", new Class<?>[0]);
} catch (SecurityException e) {
throw new NoSuchMethodException("SecurityException " + e + " trying to find toString method on " + cls);
}
}
private Method findGetter(Class<?> paramType, Method[] methods) {
for (int i = 0; i < methods.length; i++) {
if (!Modifier.isStatic(methods[i].getModifiers())) {
if (methods[i].getParameterTypes().length == 0) {
// could be a getter
String methName = methods[i].getName();
if (methName.equals("hashCode")) {
} else if (methName.equals("toString")) {
} else {
Class<?> returnType = methods[i].getReturnType();
if (paramType.equals(returnType)) {
return methods[i];
}
}
}
return null;
}
}
return null;
}
private static class ScoreConstructor implements Comparable<ScoreConstructor> {
final int score;
final Constructor<?> constructor;
private ScoreConstructor(int score, Constructor<?> constructor) {
this.score = score;
this.constructor = constructor;
}
private static class ScoreConstructor implements Comparable<ScoreConstructor>{
final int score;
final Constructor<?> constructor;
private ScoreConstructor(int score, Constructor<?> constructor) {
this.score = score;
this.constructor = constructor;
}
@Override
public boolean equals(Object obj) {
// remove FindBugs warning
return obj == this;
}
public int compareTo(ScoreConstructor o) {
return (score<o.score ? -1 : (score==o.score ? 0 : 1));
}
public int getParamCount() {
return constructor.getParameterTypes().length;
}
public boolean hasDuplicateParamTypes() {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length < 2){
return false;
}
HashSet<Class<?>> set = new HashSet<Class<?>>();
for (int i = 0; i < parameterTypes.length; i++) {
if (!set.add(parameterTypes[i])) {
return true;
}
}
return false;
}
@Override
public boolean equals(Object obj) {
// remove FindBugs warning
return obj == this;
}
public int compareTo(ScoreConstructor o) {
return (score < o.score ? -1 : (score == o.score ? 0 : 1));
}
public int getParamCount() {
return constructor.getParameterTypes().length;
}
public boolean hasDuplicateParamTypes() {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length < 2) {
return false;
}
HashSet<Class<?>> set = new HashSet<Class<?>>();
for (int i = 0; i < parameterTypes.length; i++) {
if (!set.add(parameterTypes[i])) {
return true;
}
}
return false;
}
}
}
@@ -6,41 +6,41 @@ import java.util.Arrays;
import com.avaje.ebean.config.CompoundType;
import com.avaje.ebean.config.CompoundTypeProperty;
@SuppressWarnings({ "rawtypes" })
@SuppressWarnings({"rawtypes"})
public class ReflectionBasedCompoundType implements CompoundType {
private final Constructor<?> constructor;
private final ReflectionBasedCompoundTypeProperty[] props;
public ReflectionBasedCompoundType(Constructor<?> constructor, ReflectionBasedCompoundTypeProperty[] props) {
this.constructor = constructor;
this.props = props;
}
public String toString() {
return "ReflectionBasedCompoundType "+constructor+" "+Arrays.toString(props);
}
public Object create(Object[] propertyValues) {
try {
return constructor.newInstance(propertyValues);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final Constructor<?> constructor;
public CompoundTypeProperty[] getProperties() {
return props;
}
private final ReflectionBasedCompoundTypeProperty[] props;
public Class<?> getPropertyType(int i){
return props[i].getPropertyType();
public ReflectionBasedCompoundType(Constructor<?> constructor, ReflectionBasedCompoundTypeProperty[] props) {
this.constructor = constructor;
this.props = props;
}
public String toString() {
return "ReflectionBasedCompoundType " + constructor + " " + Arrays.toString(props);
}
public Object create(Object[] propertyValues) {
try {
return constructor.newInstance(propertyValues);
} catch (Exception e) {
throw new RuntimeException(e);
}
public Class<?> getCompoundType() {
return constructor.getDeclaringClass();
}
}
public CompoundTypeProperty[] getProperties() {
return props;
}
public Class<?> getPropertyType(int i) {
return props[i].getPropertyType();
}
public Class<?> getCompoundType() {
return constructor.getDeclaringClass();
}
}
@@ -4,47 +4,47 @@ import java.lang.reflect.Method;
import com.avaje.ebean.config.CompoundTypeProperty;
@SuppressWarnings({ "rawtypes" })
@SuppressWarnings({"rawtypes"})
public class ReflectionBasedCompoundTypeProperty implements CompoundTypeProperty {
private static final Object[] NO_ARGS = new Object[0];
private final Method reader;
private final String name;
private final Class<?> propertyType;
public ReflectionBasedCompoundTypeProperty(String name, Method reader, Class<?> propertyType) {
this.name = name;
this.reader = reader;
this.propertyType = propertyType;
}
public String toString() {
return name;
}
public int getDbType() {
return 0;
}
private static final Object[] NO_ARGS = new Object[0];
public String getName() {
return name;
}
private final Method reader;
public Object getValue(Object valueObject) {
try {
return reader.invoke(valueObject, NO_ARGS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final String name;
public Class<?> getPropertyType(){
return propertyType;
private final Class<?> propertyType;
public ReflectionBasedCompoundTypeProperty(String name, Method reader, Class<?> propertyType) {
this.name = name;
this.reader = reader;
this.propertyType = propertyType;
}
public String toString() {
return name;
}
public int getDbType() {
return 0;
}
public String getName() {
return name;
}
public Object getValue(Object valueObject) {
try {
return reader.invoke(valueObject, NO_ARGS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Class<?> getPropertyType() {
return propertyType;
}
}
@@ -5,45 +5,45 @@ import java.lang.reflect.Method;
import com.avaje.ebean.config.ScalarTypeConverter;
@SuppressWarnings({ "rawtypes" })
@SuppressWarnings({"rawtypes"})
public class ReflectionBasedScalarTypeConverter implements ScalarTypeConverter {
private static final Object[] NO_ARGS = new Object[0];
private final Constructor<?> constructor;
private final Method reader;
public ReflectionBasedScalarTypeConverter(Constructor<?> constructor, Method reader) {
this.constructor = constructor;
this.reader = reader;
}
public Object getNullValue() {
return null;
}
private static final Object[] NO_ARGS = new Object[0];
public Object unwrapValue(Object beanType) {
if (beanType == null){
return null;
}
try {
return reader.invoke(beanType, NO_ARGS);
} catch (Exception e) {
String msg = "Error invoking read method "+reader.getName()
+" on "+beanType.getClass().getName();
throw new RuntimeException(msg);
}
private final Constructor<?> constructor;
private final Method reader;
public ReflectionBasedScalarTypeConverter(Constructor<?> constructor, Method reader) {
this.constructor = constructor;
this.reader = reader;
}
public Object getNullValue() {
return null;
}
public Object unwrapValue(Object beanType) {
if (beanType == null) {
return null;
}
try {
return reader.invoke(beanType, NO_ARGS);
} catch (Exception e) {
String msg = "Error invoking read method " + reader.getName()
+ " on " + beanType.getClass().getName();
throw new RuntimeException(msg);
}
}
public Object wrapValue(Object scalarType) {
try {
return constructor.newInstance(scalarType);
} catch (Exception e) {
String msg = "Error invoking constructor " + constructor + " with " + scalarType;
throw new RuntimeException(msg);
}
}
public Object wrapValue(Object scalarType) {
try {
return constructor.newInstance(scalarType);
} catch (Exception e) {
String msg = "Error invoking constructor "+constructor+" with "+scalarType;
throw new RuntimeException(msg);
}
}
}
@@ -9,70 +9,70 @@ import com.avaje.ebeaninternal.server.type.TypeManager;
public class ReflectionBasedTypeBuilder {
private final TypeManager typeManager;
public ReflectionBasedTypeBuilder(TypeManager typeManager) {
this.typeManager = typeManager;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public ScalarType<?> buildScalarType(ImmutableMeta meta) {
if (meta.isCompoundType()){
throw new RuntimeException("Must be scalar");
}
Constructor<?> constructor = meta.getConstructor();
Class<?> logicalType = constructor.getDeclaringClass();
Method[] readers = meta.getReaders();
Class<?> returnType = readers[0].getReturnType();
ScalarType<?> scalarType = typeManager.recursiveCreateScalarTypes(returnType);
ReflectionBasedScalarTypeConverter r = new ReflectionBasedScalarTypeConverter(constructor, readers[0]);
return new ScalarTypeWrapper(logicalType, scalarType, r);
}
public ReflectionBasedCompoundType buildCompound(ImmutableMeta meta) {
Constructor<?> constructor = meta.getConstructor();
private final TypeManager typeManager;
Method[] readers = meta.getReaders();
public ReflectionBasedTypeBuilder(TypeManager typeManager) {
this.typeManager = typeManager;
}
ReflectionBasedCompoundTypeProperty[] props = new ReflectionBasedCompoundTypeProperty[readers.length];
for (int i = 0; i < readers.length; i++) {
Class<?> returnType = readers[i].getReturnType();
// ensure that return type is also a ScalarDataReader
typeManager.recursiveCreateScalarDataReader(returnType);
String name = getPropertyName(readers[i]);
props[i] = new ReflectionBasedCompoundTypeProperty(name, readers[i], returnType);
}
return new ReflectionBasedCompoundType(constructor, props);
@SuppressWarnings({"unchecked", "rawtypes"})
public ScalarType<?> buildScalarType(ImmutableMeta meta) {
if (meta.isCompoundType()) {
throw new RuntimeException("Must be scalar");
}
private String getPropertyName(Method method){
String name = method.getName();
if (name.startsWith("is")){
return lowerFirstChar(name.substring(2));
} else if (name.startsWith("get")){
return lowerFirstChar(name.substring(3));
}
String msg = "Expecting method "+name+" to start with is or get "
+" so as to follow bean specification?";
throw new RuntimeException(msg);
Constructor<?> constructor = meta.getConstructor();
Class<?> logicalType = constructor.getDeclaringClass();
Method[] readers = meta.getReaders();
Class<?> returnType = readers[0].getReturnType();
ScalarType<?> scalarType = typeManager.recursiveCreateScalarTypes(returnType);
ReflectionBasedScalarTypeConverter r = new ReflectionBasedScalarTypeConverter(constructor, readers[0]);
return new ScalarTypeWrapper(logicalType, scalarType, r);
}
public ReflectionBasedCompoundType buildCompound(ImmutableMeta meta) {
Constructor<?> constructor = meta.getConstructor();
Method[] readers = meta.getReaders();
ReflectionBasedCompoundTypeProperty[] props = new ReflectionBasedCompoundTypeProperty[readers.length];
for (int i = 0; i < readers.length; i++) {
Class<?> returnType = readers[i].getReturnType();
// ensure that return type is also a ScalarDataReader
typeManager.recursiveCreateScalarDataReader(returnType);
String name = getPropertyName(readers[i]);
props[i] = new ReflectionBasedCompoundTypeProperty(name, readers[i], returnType);
}
private String lowerFirstChar(String name) {
return Character.toLowerCase(name.charAt(0))+name.substring(1);
return new ReflectionBasedCompoundType(constructor, props);
}
private String getPropertyName(Method method) {
String name = method.getName();
if (name.startsWith("is")) {
return lowerFirstChar(name.substring(2));
} else if (name.startsWith("get")) {
return lowerFirstChar(name.substring(3));
}
String msg = "Expecting method " + name + " to start with is or get "
+ " so as to follow bean specification?";
throw new RuntimeException(msg);
}
private String lowerFirstChar(String name) {
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
}
}