diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutable.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutable.java index 8996d7925..24b5a3cd8 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutable.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutable.java @@ -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; + } + + } + } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutableResponse.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutableResponse.java index 883a6a33b..ba0eac2fe 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutableResponse.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/CheckImmutableResponse.java @@ -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; + } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMeta.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMeta.java index 8e5d07167..d0a7fe60c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMeta.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMeta.java @@ -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; + } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMetaFactory.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMetaFactory.java index ca7985861..c40004348 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMetaFactory.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ImmutableMetaFactory.java @@ -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 errors = new ArrayList(); - - // 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 errors = new ArrayList(); - 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 list = new ArrayList(); - 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 list = new ArrayList(); + 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 { + + final int score; + final Constructor constructor; + + private ScoreConstructor(int score, Constructor constructor) { + this.score = score; + this.constructor = constructor; } - private static class ScoreConstructor implements Comparable{ - - 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[] parameterTypes = constructor.getParameterTypes(); - if (parameterTypes.length < 2){ - return false; - } - HashSet> set = new HashSet>(); - 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> set = new HashSet>(); + for (int i = 0; i < parameterTypes.length; i++) { + if (!set.add(parameterTypes[i])) { + return true; + } + } + return false; + } + + } + } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundType.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundType.java index a5840e7c0..5815e850d 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundType.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundType.java @@ -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(); + } + } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundTypeProperty.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundTypeProperty.java index 2f92297ab..57b81ecd6 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundTypeProperty.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedCompoundTypeProperty.java @@ -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; + } + + } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedScalarTypeConverter.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedScalarTypeConverter.java index add338267..27074f9b2 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedScalarTypeConverter.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedScalarTypeConverter.java @@ -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); - } - } - } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedTypeBuilder.java b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedTypeBuilder.java index e3874ae85..de9c7c203 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedTypeBuilder.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/reflect/ReflectionBasedTypeBuilder.java @@ -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); + } }