Package com.skaringa.javaxml.serializers

Source Code of com.skaringa.javaxml.serializers.AbstractSerializer

package com.skaringa.javaxml.serializers;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import com.skaringa.javaxml.PropertyKeys;
import com.skaringa.javaxml.SerializerException;
import com.skaringa.javaxml.handler.AttrImpl;
import com.skaringa.javaxml.handler.DocumentOutputHandlerInterface;
import com.skaringa.javaxml.impl.NSConstants;
import com.skaringa.javaxml.impl.PropertyHelper;
import com.skaringa.util.Log;

/**
* Abstract class that provides methods common for all serializers.
*/
public abstract class AbstractSerializer
  implements com.skaringa.javaxml.serializers.ComponentSerializer {

  /**
   * This is used down in getFieldsToSerialize as a template for toArray().
   */
  protected static final Field[] FIELD_TEMPLATE = new Field[0];

  /**
   * Write an element start tag to the output.
   * It includes test for null and setting the type attribute.
   * @param obj The object to write.
   * @param type The type of the object.
   * @param name The name of the object.
   * @param propertyMap The output properties.
   * @param output The handler used to write the output.
   * @throws SerializerException If the element can't be written.
   */
  protected final void startElement(
    Object obj,
    String type,
    String name,
    Map propertyMap,
    DocumentOutputHandlerInterface output)
    throws SerializerException {

    boolean omitXsi =
      PropertyHelper.parseBoolean(propertyMap, PropertyKeys.OMIT_XSI_TYPE);
    boolean omitNil =
      PropertyHelper.parseBoolean(propertyMap, PropertyKeys.OMIT_XSI_NIL);

    AttrImpl attrs = new AttrImpl();
    if (!omitXsi) {
      attrs.addAttribute(
        NSConstants.SCHEMA_INSTANCE_NS_NAME,
        NSConstants.SCHEMA_INSTANCE_NS_PREFIX,
        "type",
        type);
    }
    if (obj == null && !omitNil) {
      attrs.addAttribute(
        NSConstants.SCHEMA_INSTANCE_NS_NAME,
        NSConstants.SCHEMA_INSTANCE_NS_PREFIX,
        "nil",
        "true");
    }
    output.startElement(name, attrs);
  }

  /**
   * Get the type of a field of an object.
   * @param obj The object.
   * @param fieldName Then field name.
   * @return The type of the field or null if the field doesn't exist.
   */
  public static Class getFieldType(Object obj, String fieldName) {
    try {
      Log.debug("getFieldType", fieldName);
      Field field = getField(obj, fieldName);
      return field.getType();
    }
    catch (NoSuchFieldException e) {
      return null; // field not found
    }
  }

  /**
   * Get a field of an object. The field is identified by its name.
   * @param obj The object.
   * @param fieldName Then field name.
   * @return The field.
   * @exception NoSuchFieldException If the object doesn't have a field
   * with the specified name.
   */
  public static Field getField(Object obj, String fieldName)
    throws NoSuchFieldException {
    // get class of obj
    Class c = obj.getClass();

    while (!c.equals(java.lang.Object.class)) {
      try {
        // get field
        return c.getDeclaredField(fieldName);
        // BREAK
      }
      catch (NoSuchFieldException e) {
        // examine the super class of this
        c = c.getSuperclass();
      }
      // until the super class is java.lang.Object
    }

    throw new NoSuchFieldException(fieldName); // field not found
  }

  /**
   * Get all fields to serialize for a type.
   * These are all fields that are not internal, static, nor transient.
   * @param type The type.
   * @param fieldComparator The comparator used to order the fields.
   * @return Array of fields to serialize.
   */
  public static Field[] getFieldsToSerialize(
    Class type,
    Comparator fieldComparator) {

    List result = new ArrayList();
    Field[] fields = type.getDeclaredFields();

    for (int i = 0; i < fields.length; ++i) {
      String fieldName = fields[i].getName();
      int modifiers = fields[i].getModifiers();
      if (fieldName.indexOf('$') < 0
        && !Modifier.isTransient(modifiers)
        && !Modifier.isStatic(modifiers)) {
        // surpress internal, static and transient fields

        result.add(fields[i]);
      }
    }

    if (fieldComparator != null) {
      Collections.sort(result, fieldComparator);
    }
    return (Field[]) result.toArray(FIELD_TEMPLATE);
  }

  /**
   * Write the XML schema definition for a collection.
   * @param componentElementName The name of the elements of the collection.
   * @param componentElementType The type of the elements of the collection.
   * @param output The handler used to write the output.
   * @throws SerializerException If the definition can't be written.
   */
  protected final void writeXMLCollectionDef(
    String componentElementName,
    Class componentElementType,
    DocumentOutputHandlerInterface output)
    throws SerializerException {

    AttrImpl attrs = new AttrImpl();
    attrs.addAttribute("name", getXMLTypeName());
    output.startElement("xsd:complexType", attrs);

    output.startElement("xsd:sequence");

    attrs = new AttrImpl();
    attrs.addAttribute("name", componentElementName);
    attrs.addAttribute("minOccurs", "0");
    attrs.addAttribute("maxOccurs", "unbounded");

    if (componentElementType == null) {
      attrs.addAttribute("type", "xsd:anyType");
    }
    else {
      ComponentSerializer ser =
        SerializerRegistry.getInstance().getSerializer(componentElementType);
      attrs.addAttribute("type", ser.getXMLTypeName());
    }

    attrs.addAttribute("nillable", "true");

    output.startElement("xsd:element", attrs);
    output.endElement("xsd:element");

    output.endElement("xsd:sequence");

    output.endElement("xsd:complexType");
  }

  /**
   * Write the XML schema definition for a type that only extends a base type.
   * @param output The handler used to write the output.
   * @param baseType The XML type name of the base type.
   * @throws SerializerException If the definition can't be written.
   */
  protected final void writeXMLExtensionDef(
    DocumentOutputHandlerInterface output,
    String baseType)
    throws SerializerException {
    AttrImpl attr = new AttrImpl();
    attr.addAttribute("name", getXMLTypeName());
    output.startElement("xsd:complexType", attr);

    output.startElement("xsd:complexContent");

    attr = new AttrImpl();
    attr.addAttribute("base", baseType);
    output.startElement("xsd:extension", attr);

    output.endElement("xsd:extension");

    output.endElement("xsd:complexContent");

    output.endElement("xsd:complexType");
  }

  protected void printEncodedStr(String text, PrintStream output) {
    char[] ctext = text.toCharArray();
    for (int i = 0; i < ctext.length; ++i) {
      char c = ctext[i];
      if (Character.isISOControl(c)) {
        switch (c) {
        case '\b':
          output.print("\\b");
          break;
        case '\f':
          output.print("\\f");
          break;
        case '\n':
          output.print("\\n");
          break;
        case '\r':
          output.print("\\r");
          break;
        case '\t':
          output.print("\\t");
          break;
        default:
          String us = Integer.toHexString(c);
          output.print("\\u0000".substring(0, 6 - us.length()) + us);
          break;
        }
      } else if (c == '"') {
        output.print("\\\"");
      } else if (c == '\\') {
        output.print("\\\\");
      } else {
        output.print(c);
      }
    }
  }

  /**
   * Substitute all occurences of oldString in target by newString.
   * @param target The target of the substitution.
   * @param oldString The old string to be replaced.
   * @param newString The new string.
   * @return The target with all occurences of oldString replaced by newString.
   */
  protected static String subst(
    String target,
    String oldString,
    String newString) {
    StringBuffer res = new StringBuffer();
    int pos = 0;
    int rpos = target.indexOf(oldString, pos);
    while (rpos >= 0) {
      res.append(target.substring(pos, rpos));
      res.append(newString);
      pos = rpos + oldString.length();
      rpos = target.indexOf(oldString, pos);
    }
    res.append(target.substring(pos));

    return res.toString();
  }
}
TOP

Related Classes of com.skaringa.javaxml.serializers.AbstractSerializer

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.