All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.firefly.utils.json.compiler.DecodeCompiler Maven / Gradle / Ivy

There is a newer version: 4.0.3.2
Show newest version
package com.firefly.utils.json.compiler;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.firefly.utils.json.annotation.DateFormat;
import com.firefly.utils.json.annotation.Transient;
import com.firefly.utils.json.exception.JsonException;
import com.firefly.utils.json.parser.CollectionParser;
import com.firefly.utils.json.parser.ComplexTypeParser;
import com.firefly.utils.json.parser.MapParser;
import com.firefly.utils.json.parser.ParserStateMachine;
import com.firefly.utils.json.support.FieldInvoke;
import com.firefly.utils.json.support.MethodInvoke;
import com.firefly.utils.json.support.ParserMetaInfo;

public class DecodeCompiler {
	private static final ParserMetaInfo[] EMPTY_ARRAY = new ParserMetaInfo[0];
	
	public static ParserMetaInfo[] compile(Class clazz) {
		ParserMetaInfo[] parserMetaInfos = null;
		Set fieldSet = new TreeSet();
		for (Method method : clazz.getMethods()) {
			method.setAccessible(true);
			String methodName = method.getName();
			
			if (method.getDeclaringClass().equals(Object.class)) continue;
			if (method.getName().length() < 4) continue;
            if (!method.getName().startsWith("set")) continue;
            if (method.getParameterTypes().length != 1) continue;
            if (Modifier.isStatic(method.getModifiers())) continue;
            if (Modifier.isAbstract(method.getModifiers())) continue;
            if (method.isAnnotationPresent(Transient.class)) continue;
            if (methodName.length() < 4) continue;
            
            String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
//            System.out.println(propertyName);
            Field field = null;
			try {
				field = clazz.getDeclaredField(propertyName);
			} catch (Throwable t) {
//				t.printStackTrace();
			}

			if (field != null
					&& (Modifier.isTransient(field.getModifiers())
					|| field.isAnnotationPresent(Transient.class)))
				continue;
            
            ParserMetaInfo parserMetaInfo = new ParserMetaInfo();
            parserMetaInfo.setPropertyNameString(propertyName);
            parserMetaInfo.setPropertyInvoke(new MethodInvoke(method));
            Class type =  method.getParameterTypes()[0];
            
            if (Collection.class.isAssignableFrom(type)) {
            	Type[] types = method.getGenericParameterTypes();
            	if(types.length != 1 || !(types[0] instanceof ParameterizedType))
            		throw new JsonException("not support the " + method);
            	
            	ParameterizedType paramType = (ParameterizedType) types[0];
            	Type[] types2 = paramType.getActualTypeArguments();
            	if(types2.length != 1)
            		throw new JsonException("not support the " + method);
            	
            	Type elementType = types2[0];
            	parserMetaInfo.setType(ComplexTypeParser.getImplClass(type));
            	parserMetaInfo.setParser(new CollectionParser(elementType));
            } else if (Map.class.isAssignableFrom(type)) { // construct map meta information
            	Type[] types = method.getGenericParameterTypes();
            	if(types.length != 1 || !(types[0] instanceof ParameterizedType))
            		throw new JsonException("not support the " + method);
            	
            	ParameterizedType paramType = (ParameterizedType) types[0];
            	Type[] types2 = paramType.getActualTypeArguments();
            	if(types2.length != 2)
            		throw new JsonException("not support the " + method);
            	
            	Type key = types2[0];
            	if (!((key instanceof Class) && key == String.class))
            		throw new JsonException("not support the " + method);
            	
            	Type elementType = types2[1];
            	parserMetaInfo.setType(ComplexTypeParser.getImplClass(type));
            	parserMetaInfo.setParser(new MapParser(elementType));
            } else { // get array, object or enumeration parser
            	DateFormat d = null;
    			if(field != null) {
    				d = field.getAnnotation(DateFormat.class);
    			}
    			if(d == null) {
    				d = method.getAnnotation(DateFormat.class);
    			}
            	
            	parserMetaInfo.setType(type);
            	parserMetaInfo.setParser(ParserStateMachine.getParser(type, d)); 
            }
            fieldSet.add(parserMetaInfo);
		}
		
		for(Field field : clazz.getFields()) { // construct public field parser
			if(Modifier.isTransient(field.getModifiers()) || field.isAnnotationPresent(Transient.class) || Modifier.isStatic(field.getModifiers()))
				continue;
			
			field.setAccessible(true);
			
			ParserMetaInfo parserMetaInfo = new ParserMetaInfo();
            parserMetaInfo.setPropertyNameString(field.getName());
            parserMetaInfo.setPropertyInvoke(new FieldInvoke(field));
            
            Class type = field.getType();
            if (Collection.class.isAssignableFrom(type)) {
            	Type fieldType = field.getGenericType();
            	if(!(fieldType instanceof ParameterizedType))
            		throw new JsonException("not support the " + field);
            	
            	ParameterizedType paramType = (ParameterizedType)fieldType;
            	Type[] types2 = paramType.getActualTypeArguments();
            	if(types2.length != 1)
            		throw new JsonException("not support the " + field);
            	
            	Type elementType = types2[0];
            	parserMetaInfo.setType(ComplexTypeParser.getImplClass(type));
            	parserMetaInfo.setParser(new CollectionParser(elementType));
            } else if (Map.class.isAssignableFrom(type)) { // construct map meta information
            	Type fieldType = field.getGenericType();
            	if(!(fieldType instanceof ParameterizedType))
            		throw new JsonException("not support the " + field);
            	
            	ParameterizedType paramType = (ParameterizedType) fieldType;
            	Type[] types2 = paramType.getActualTypeArguments();
            	if(types2.length != 2)
            		throw new JsonException("not support the " + field);
            	
            	Type key = types2[0];
            	if (!((key instanceof Class) && key == String.class))
            		throw new JsonException("not support the " + field);
            	
            	Type elementType = types2[1];
            	parserMetaInfo.setType(ComplexTypeParser.getImplClass(type));
            	parserMetaInfo.setParser(new MapParser(elementType));
            } else { // get array, object or enumeration parser
            	parserMetaInfo.setType(type);
            	parserMetaInfo.setParser(ParserStateMachine.getParser(type, field.getAnnotation(DateFormat.class)));
            }
            fieldSet.add(parserMetaInfo);
		}
		
		parserMetaInfos = fieldSet.toArray(EMPTY_ARRAY);
		if(parserMetaInfos.length <= 0)
			throw new JsonException("not support the " + clazz.getName());
		return parserMetaInfos;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy