/**
*
*/
package org.ebayopensource.turmeric.tools.codegen.external;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.List;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;
/**
* @author rkulandaivel
*
*/
public class JClassContentsComparatorProvider {
private static final JMethodsComparator s_jMethodsComparatorInstance = new JMethodsComparator();
private static final JAnnotationUseComparator s_jAnnotationUseComparatorInstance = new JAnnotationUseComparator();
private static final SameNameJMethodsComparator s_sameNameJMethodsComparatorInstance = new SameNameJMethodsComparator();
private static final JFieldVarComparator s_JFieldVarComparatorInstance = new JFieldVarComparator();
private JClassContentsComparatorProvider(){}
public static final Comparator<JMethod> getJMethodComparatorInstance(){
return s_jMethodsComparatorInstance;
}
public static final Comparator<JAnnotationUse> getAnnotationUseComparatorInstance(){
return s_jAnnotationUseComparatorInstance;
}
public static final Comparator<JMethod> getSameNameJMethodsComparatorInstance(){
return s_sameNameJMethodsComparatorInstance;
}
public static final Comparator<JFieldVar> getJFieldVarComparatorInstance(){
return s_JFieldVarComparatorInstance;
}
private static Field getReflectionField( Class<?> clazz, String fieldName){
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
} catch (SecurityException e) {
throw new RuntimeException("Exception while retriveing the field '"+ fieldName +"' of '"+ clazz.getName() +"' through reflection", e);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Exception while retriveing the field '"+ fieldName +"' of '"+ clazz.getName() +"' through reflection", e);
}
return field;
}
private static Object getReflectionValue( Field field, Object instanceObj ){
try {
return field.get(instanceObj);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Exception while retriveing the value for field " + field.getName() + " through reflection", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Exception while retriveing the value for field " + field.getName() + " through reflection", e);
}
}
private static class SameNameJMethodsComparator implements Comparator<JMethod> {
private Field m_paramsField = null;
private SameNameJMethodsComparator(){
m_paramsField = getReflectionField( JMethod.class, "params");
}
@SuppressWarnings("unchecked")
@Override
public int compare(JMethod object1, JMethod object2) {
int returnResult;
List<JVar> params1 = (List<JVar>) getReflectionValue( m_paramsField, object1);
List<JVar> params2 = (List<JVar>) getReflectionValue( m_paramsField, object2);
if( (params1 == null) && (params2 == null) ){
returnResult = 0;
}else if( params1 == null){
returnResult = -1;
}else if( params2 == null){
returnResult = 1;
}else{
returnResult = params1.size() - params2.size() ;
}
return returnResult;
}
}
private static class JMethodsComparator extends SameNameJMethodsComparator implements Comparator<JMethod> {
private JMethodsComparator(){
}
@Override
public int compare(JMethod object1, JMethod object2) {
int nameCompare = object1.name().compareTo(object2.name());
if( nameCompare == 0 ){
nameCompare = super.compare(object1, object2);
}
return nameCompare;
}
}
private static class JAnnotationUseComparator implements Comparator<JAnnotationUse> {
private Field m_jClazzField = null;
private JAnnotationUseComparator(){
m_jClazzField = getReflectionField( JAnnotationUse.class, "clazz");
}
@Override
public int compare(JAnnotationUse object1, JAnnotationUse object2) {
JClass clazz1 = (JClass) getReflectionValue( m_jClazzField, object1);
JClass clazz2 = (JClass) getReflectionValue( m_jClazzField, object2);
return clazz1.compareTo( clazz2);
}
}
private static class JFieldVarComparator implements Comparator<JFieldVar> {
private JFieldVarComparator(){
}
@Override
public int compare(JFieldVar object1, JFieldVar object2) {
return object1.name().compareTo(object2.name());
}
}
}