Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;
//License from project: Open Source License 

import java.io.File;

import java.io.InvalidObjectException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;

import com.fasterxml.jackson.annotation.JsonGetter;

public class Main {
    /**
     * List of classes that are wrapped directly. This information is need when
     * traversing object trees for reference matching
     */
    private static final Set<Class> WRAPPER_TYPES = new HashSet(
            Arrays.asList(Boolean.class, Character.class, Byte.class, Short.class, String.class, Integer.class,
                    Long.class, Float.class, Double.class, Void.class, File.class));

    /**
     * Appends the given set of parameters to the given query string
     * @param   queryBuilder   The query url string to append the parameters
     * @param   parameters   The parameters to append
     */
    public static void appendUrlWithQueryParameters(StringBuilder queryBuilder, Map<String, Object> parameters) {
        //perform parameter validation
        if (null == queryBuilder)
            throw new IllegalArgumentException("Given value for parameter \"queryBuilder\" is invalid.");

        if (null == parameters)
            return;

        //does the query string already has parameters
        boolean hasParams = (queryBuilder.indexOf("?") > 0) || (queryBuilder.indexOf("http") != 0);
        if (!hasParams)
            queryBuilder.append('?');

        encodeObjectAsQueryString("", parameters, queryBuilder);
    }

    /**
     * Encodes a given object to url encoded string
     * @param name
     * @param obj
     * @param objBuilder
     */
    private static void encodeObjectAsQueryString(String name, Object obj, StringBuilder objBuilder) {
        try {
            if (obj == null)
                return;

            Map<String, Object> objectMap = new LinkedHashMap<String, Object>();
            objectToMap(name, obj, objectMap, new HashSet<Integer>());
            boolean hasParam = false;

            for (Map.Entry<String, Object> pair : objectMap.entrySet()) {
                String paramKeyValPair;

                //ignore nulls
                Object value = pair.getValue();
                if (value == null)
                    continue;

                hasParam = true;
                //load element value as string
                paramKeyValPair = String.format("%s=%s&", pair.getKey(), tryUrlEncode(value.toString()));
                objBuilder.append(paramKeyValPair);
            }

            //remove the last &
            if (hasParam) {
                objBuilder.setLength(objBuilder.length() - 1);
            }
        } catch (Exception ex) {
        }
    }

    /**
     * Converts a given object to a form encoded map
     * @param objName Name of the object
     * @param obj The object to convert into a map
     * @param objectMap The object map to populate
     * @param processed List of objects hashCodes that are already parsed
     * @throws InvalidObjectException
     */
    private static void objectToMap(String objName, Object obj, Map<String, Object> objectMap,
            HashSet<Integer> processed) throws InvalidObjectException {
        //null values need not to be processed
        if (obj == null)
            return;

        //wrapper types are autoboxed, so reference checking is not needed
        if (!isWrapperType(obj.getClass())) {
            //avoid infinite recursion
            if (processed.contains(obj.hashCode()))
                return;
            processed.add(obj.hashCode());
        }

        //process arrays
        if (obj instanceof Collection<?>) {
            //process array
            if ((objName == null) || (objName.isEmpty()))
                throw new InvalidObjectException("Object name cannot be empty");

            Collection<?> array = (Collection<?>) obj;
            //append all elements in the array into a string
            int index = 0;
            for (Object element : array) {
                //load key value pair
                String key = String.format("%s[%d]", objName, index++);
                loadKeyValuePairForEncoding(key, element, objectMap, processed);
            }
        } else if (obj instanceof Map) {
            //process map
            Map<?, ?> map = (Map<?, ?>) obj;
            //append all elements in the array into a string            
            for (Map.Entry<?, ?> pair : map.entrySet()) {
                String attribName = pair.getKey().toString();
                String key = attribName;
                if ((objName != null) && (!objName.isEmpty())) {
                    key = String.format("%s[%s]", objName, attribName);
                }
                loadKeyValuePairForEncoding(key, pair.getValue(), objectMap, processed);
            }
        } else {
            //process objects
            // invoke getter methods
            Method[] methods = obj.getClass().getMethods();
            for (Method method : methods) {
                //is a getter?
                if ((method.getParameterTypes().length != 0) || (!method.getName().startsWith("get")))
                    continue;

                //get json attribute name
                Annotation getterAnnotation = method.getAnnotation(JsonGetter.class);
                if (getterAnnotation == null)
                    continue;

                //load key name
                String attribName = ((JsonGetter) getterAnnotation).value();
                String key = attribName;
                if ((objName != null) && (!objName.isEmpty())) {
                    key = String.format("%s[%s]", objName, attribName);
                }

                try {
                    //load key value pair
                    Object value = method.invoke(obj);
                    loadKeyValuePairForEncoding(key, value, objectMap, processed);
                } catch (Exception ex) {
                }
            }
            // load fields
            Field[] fields = obj.getClass().getFields();
            for (Field field : fields) {
                //load key name
                String attribName = field.getName();
                String key = attribName;
                if ((objName != null) && (!objName.isEmpty())) {
                    key = String.format("%s[%s]", objName, attribName);
                }

                try {
                    //load key value pair
                    Object value = field.get(obj);
                    loadKeyValuePairForEncoding(key, value, objectMap, processed);
                } catch (Exception ex) {
                }
            }
        }
    }

    /**
     * Tries Url encode using UTF-8
     * @param value The value to url encode
     * @return
     */
    private static String tryUrlEncode(String value) {
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (Exception ex) {
            return value;
        }
    }

    /**
     * Checks if the given class can be wrapped directly
     * @param clazz The given class
     * @return true if the given class is an autoboxed class e.g., Integer
     */
    private static boolean isWrapperType(Class clazz) {
        return WRAPPER_TYPES.contains(clazz) || clazz.isPrimitive() || clazz.isEnum();
    }

    /**
     * While processing objects to map, decides whether to perform recursion or load value
     * @param key The key to used for creating key value pair
     * @param value The value to process against the given key
     * @param objectMap The object map to process with key value pair
     * @param processed List of processed objects hashCodes
     * @throws InvalidObjectException
     */
    private static void loadKeyValuePairForEncoding(String key, Object value, Map<String, Object> objectMap,
            HashSet<Integer> processed) throws InvalidObjectException {
        if (value == null)
            return;
        if (isWrapperType(value.getClass()))
            objectMap.put(key, value);
        else
            objectToMap(key, value, objectMap, processed);
    }
}