Package com.adaptiweb.utils.xmlbind

Source Code of com.adaptiweb.utils.xmlbind.Marshaller

package com.adaptiweb.utils.xmlbind;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.adaptiweb.utils.xmlbind.annotation.BindAttribute;
import com.adaptiweb.utils.xmlbind.annotation.BindClass;
import com.adaptiweb.utils.xmlbind.annotation.BindElement;
import com.adaptiweb.utils.xmlbind.annotation.DefaultBindElement;
import com.adaptiweb.utils.xmlbind.annotation.NoBind;

public class Marshaller {

  public void marshal(Object src, OutputStream outputStream) throws ParserException {
    marshal(src, new OutputStremConstructor(outputStream));
  }
 
  private void marshal(Object src, MarshallerOutput output) throws ParserException {
    try {
      Class<? extends Object> reflect = src.getClass();
      output.startElement(extractTagName(reflect));
      examineSource(src, reflect, output);
      output.stopElement();
      output.flush();
    } catch (IOException e) {
      throw new ParserException(e);
    } catch (IllegalArgumentException e) {
      throw new ParserException(e);
    } catch (IllegalAccessException e) {
      throw new ParserException(e);
    } catch (InvocationTargetException e) {
      throw new ParserException(e);
    } catch (SecurityException e) {
      throw new ParserException(e);
    } catch (NoSuchMethodException e) {
      throw new ParserException(e);
    }
  }

  private static String extractTagName(Class<?> reflect) {
    return BindUtils.toXmlName(reflect.isArray() ?
        (reflect = reflect.getComponentType()).isArray() ? "arrays" : reflect.getSimpleName() + "s" :
        reflect.getSimpleName());
  }
 
  private void examineSource(Object obj, Class<?> reflect, MarshallerOutput output) throws IOException, ParserException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
    if(obj == null) return;
   
    if(obj instanceof Map<?,?>) {
      for(Entry<?,?> entry : ((Map<?,?>) obj).entrySet()) {
        output.startElement(BindUtils.toXmlName(entry.getKey().toString()));
        if(entry.getValue() != null)
          examineSource(entry.getValue(), entry.getValue().getClass(), output);
        output.stopElement();
      }
      return;
    }
    if(isBasicType(obj)) {
      output.addText(toString(obj, reflect, output.getCurentTagName()));
      return;
    }
    if(reflect.isArray()) {
      int length = Array.getLength(obj);
      for(int i = 0; i < length; i++) {
        Object item = Array.get(obj, i);
        if(item == null) continue;
        Class<? extends Object> type = item.getClass();
        output.startElement(extractTagName(type));
        examineSource(item, type, output);
        output.stopElement();
      }
      return;
    }

    //---roztriedenie metod
    List<Method> attributes = new LinkedList<Method>();
    List<Method> subelemetns = new LinkedList<Method>();
   
    if(reflect.isAnnotationPresent(BindClass.class)) {
      BindClass annotation = reflect.getAnnotation(BindClass.class);
      (annotation.asElement() ? subelemetns : attributes)
        .add(reflect.getMethod("getClass"));
    }
   
    for(Method method : reflect.getMethods()) {
      if(!method.getName().startsWith("get") && !method.getName().startsWith("is")
        || method.getParameterTypes().length != 0
        || method.isAnnotationPresent(NoBind.class)
        || Object.class.equals(method.getDeclaringClass())) continue;
     
      (method.isAnnotationPresent(BindAttribute.class) ?
        attributes : subelemetns).add(method);
    }

    appendAttributes(obj, attributes, output);
    appendElements(obj, subelemetns, output);

    if(Iterable.class.isAssignableFrom(reflect)) {
      for(Object item : (Iterable<?>) obj) {
        if(item == null) continue;
        Class<? extends Object> type = item.getClass();
        output.startElement(extractTagName(type));
        examineSource(item, type, output);
        output.stopElement();
      }
    }
  }

  private boolean isBasicType(Object obj) {
    return obj instanceof Enum<?> || obj instanceof BigDecimal
        || obj instanceof String || obj instanceof Integer
        || obj instanceof Long || obj instanceof Character
        || obj instanceof Boolean || obj instanceof Date
        || obj instanceof Calendar;
  }
 
  public static String toString(Object obj, Class<?> type, String currentTag) {
    if(obj instanceof Enum<?>) {
      if(currentTag.endsWith("_text"))
        return ((Enum<?>) obj).toString();
      else if(currentTag.endsWith("_num"))
        return Integer.toString(((Enum<?>) obj).ordinal());
      else
        return ((Enum<?>) obj).name();
    }
    if(obj instanceof BigDecimal) {
      return ((BigDecimal) obj).toPlainString();
    }
    if(obj instanceof String || obj instanceof Integer || obj instanceof Long || obj instanceof Character || obj instanceof Boolean) {
      return obj.toString();
    }
    if(obj instanceof Date || obj instanceof Calendar) {
      Date dateTime = obj instanceof Calendar?
          ((Calendar) obj).getTime() : (Date) obj;
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").format(dateTime);
//      if(currentTag.endsWith("_time"))
//        return Dates.formatTime(dateTime);
//      else if(currentTag.endsWith("_date"))
//        return Dates.formatDate(dateTime);
//      else if(currentTag.endsWith("_sdate"))
//        return Dates.formatDate(dateTime, Dates.SYSTEM_DATE_FORMAT);
//      else
//        return Dates.formatDateTime(dateTime);
    }
    throw new IllegalArgumentException("Unknown type " + type.getName());
  }
 
  private void appendElements(Object obj, List<Method> subelemetns, MarshallerOutput output) throws IllegalArgumentException, IllegalAccessException, IOException, SecurityException, ParserException, NoSuchMethodException, ArrayIndexOutOfBoundsException, InvocationTargetException {
    for(Method method : subelemetns) {
      BindElement annotation = method.getAnnotation(BindElement.class);
      if(annotation == null) annotation = DefaultBindElement.defaultInstance;

      Class<?> type = method.getReturnType();
      Object result = null;
      try {
        result = method.invoke(obj);
      } catch (InvocationTargetException ignore) {}

      String tag = annotation.tagName().length() != 0 ? annotation.tagName() :
        BindUtils.toXmlName(method.getName().substring(method.getName().startsWith("is") ? 2 : 3));
           
      if(Iterable.class.isAssignableFrom(type) || type.isArray()) {
        if(result == null) continue;
       
        if(annotation.itemTag().length() != 0) {
          output.startElement(tag);
          tag = annotation.itemTag();
        }
       
        if(type.isArray())
          for(int i = 0, length = Array.getLength(result); i < length; i++)
            determineElement(tag, Array.get(result, i), annotation, output);
        else
          for(Object o : (Iterable<?>) result)
            determineElement(tag, o, annotation, output);
       
        if(annotation.itemTag().length() != 0)
          output.stopElement();
      }
      else determineElement(tag, result, annotation, output);
    }
  }

  private void determineElement(String tag, Object object, BindElement annotation, MarshallerOutput output) throws IOException, IllegalArgumentException, SecurityException, ParserException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    output.startElement(tag);
   
    if(object != null) {
     
      if(annotation.recursive().is(object.getClass()))
        examineSource(object, object.getClass(), output);
      else
        output.addText(extractValue(object, annotation.evalProvider(), ""));
    }
   
    output.stopElement();
  }

  private void appendAttributes(Object obj, List<Method> attributes, MarshallerOutput output) throws ParserException, IOException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    for(Method method : attributes) {
      Class<?> type = method.getReturnType();
      BindAttribute annotation = method.getAnnotation(BindAttribute.class);

      String name = annotation.name().length() != 0 ? annotation.name() :
        BindUtils.toXmlName(method.getName().substring(method.getName().startsWith("is") ? 2 : 3));
       
      String value = null;
     
      if(Iterable.class.isAssignableFrom(type) || type.isArray()) {
        String separator = annotation.separator();
        StringBuffer result = new StringBuffer();
       
        if(type.isArray())
          for(Object o : (Object[]) method.invoke(obj))
            result.append(separator).append(extractValue(o, annotation.evalProvider(), name));
        else
          for(Object o : (Iterable<?>) method.invoke(obj))
            result.append(separator).append(extractValue(o, annotation.evalProvider(), name));
       
        value = result.substring(separator.length());
      }
      else value = extractValue(method.invoke(obj), annotation.evalProvider(), name);
     
      output.addAttribute(name, value);
    }
  }
 
  private String extractValue(Object o, Class<? extends BindValueProvider> evalProvider, String attributeName) {
    if(o == null) return "";
    if(o instanceof BindValue) return ((BindValue) o).getBindValue();
    if(!BindValueProvider.class.equals(evalProvider)) {
      try {
        return evalProvider.newInstance().getBindValue(o);
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
    if(o instanceof Class<?>) return ((Class<?>) o).getName();
    if(o instanceof BigDecimal) return ((BigDecimal) o).toPlainString();
    if(o instanceof Date || o instanceof Calendar) {
      Date dateTime = o instanceof Calendar?
          ((Calendar) o).getTime() : (Date) o;
     
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").format(dateTime);
//      if(attributeName.endsWith("_time"))
//        return Dates.formatTime(dateTime);
//      else if(attributeName.endsWith("_date"))
//        return Dates.formatDate(dateTime);
//      else if(attributeName.endsWith("_sdate"))
//        return Dates.formatDate(dateTime, Dates.SYSTEM_DATE_FORMAT);
//      else
//        return Dates.formatDateTime(dateTime);
    }
    return o.toString();
  }
}
TOP

Related Classes of com.adaptiweb.utils.xmlbind.Marshaller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.