Package com.sun.tools.xjc.addon.xew

Source Code of com.sun.tools.xjc.addon.xew.CommonUtils

package com.sun.tools.xjc.addon.xew;

import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import com.sun.codemodel.JAnnotatable;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JAnnotationValue;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JFormatter;
import com.sun.codemodel.JGenerable;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIDeclaration;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIProperty;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo;
import com.sun.xml.xsom.XSAnnotation;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSDeclaration;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSTerm;

public final class CommonUtils {

  /**
   * Returns {@code true} if given class is hidden, that is not generated & saved by XJC. These are for example
   * instances of {@link JCodeModel.JReferencedClass} (JVM-wide classes) or instances of {@link JDefinedClass} with
   * hidden flag (customized super-class or super-interface).
   */
  public static boolean isHiddenClass(JClass clazz) {
    // See also https://java.net/jira/browse/JAXB-958
    return !(clazz instanceof JDefinedClass) || ((JDefinedClass) clazz).isHidden();
  }

  /**
   * Returns <code>true</code> of the given <code>type</code> is {@link JClass} and contains <code>classToCheck</code>
   * in the list of parametrisations.
   */
  public static boolean isListedAsParametrisation(JClass classToCheck, JType type) {
    return type instanceof JClass && ((JClass) type).getTypeParameters().contains(classToCheck);
  }

  //
  // Annotation helpers.
  //

  /**
   * Returns the annotation for the given field.
   */
  public static JAnnotationUse getAnnotation(JAnnotatable annotatable, JClass annotationClass) {
    for (JAnnotationUse annotation : annotatable.annotations()) {
      if (annotation.getAnnotationClass().equals(annotationClass)) {
        return annotation;
      }
    }

    return null;
  }

  /**
   * Returns the annotation element as {@href JAnnotationValue}.
   */
  public static JAnnotationValue getAnnotationMember(JAnnotationUse annotation, String annotationMember) {
    if (annotation == null) {
      return null;
    }

    // FIXME: Workaround for https://java.net/jira/browse/JAXB-1040:
    Map<String, JAnnotationValue> memberValues = (Map<String, JAnnotationValue>) getPrivateField(annotation,
                "memberValues");

    if (memberValues == null) {
      return null;
    }

    return memberValues.get(annotationMember);
  }

  /**
   * Returns the value of annotation element as {@href JExpression}. For example, for annotation
   * <code>@XmlElementRef(name = "last-name", namespace = "http://mycompany.org/exchange", type = JAXBElement.class)</code>
   * for member <code>name</code> the value <code>last-name</code> will be returned.
   */
  public static JExpression getAnnotationMemberExpression(JAnnotationUse annotation, String annotationMember) {
    JAnnotationValue annotationValue = getAnnotationMember(annotation, annotationMember);

    if (annotationValue == null) {
      return null;
    }

    // FIXME: Pending for https://java.net/jira/browse/JAXB-878
    return (JExpression) getPrivateField(annotationValue, "value");
  }

  /**
   * Append the given annotation to list of annotations.
   */
  @SuppressWarnings("unchecked")
  public static void addAnnotation(JVar field, JAnnotationUse annotation) {
    ((List<JAnnotationUse>) getPrivateField(field, JVar.class, "annotations")).add(annotation);
  }

  /**
   * Remove the given annotation from the list of annotations.
   */
  @SuppressWarnings("unchecked")
  public static void removeAnnotation(JVar field, JAnnotationUse annotation) {
    ((List<JAnnotationUse>) getPrivateField(field, JVar.class, "annotations")).remove(annotation);
  }

  /**
   * Check that given field property has name customization ({@code <jaxb:property name="..." />}).
   *
   * @see com.sun.xml.bind.api.impl.NameUtil
   * @see com.sun.codemodel.JJavaName
   * @see com.sun.tools.xjc.reader.xmlschema.bindinfo.BIProperty#getCustomization(XSComponent)
   */
  public static boolean hasPropertyNameCustomization(CPropertyInfo fieldPropertyInfo) {
    XSAnnotation annotation = fieldPropertyInfo.getSchemaComponent().getAnnotation();

    if (annotation == null) {
      annotation = getXsdDeclaration(fieldPropertyInfo).getAnnotation();
    }

    if (annotation == null || !(annotation.getAnnotation() instanceof BindInfo)) {
      return false;
    }

    for (BIDeclaration declaration : (BindInfo) annotation.getAnnotation()) {
      if (declaration instanceof BIProperty) {
        return true;
      }
    }

    return false;
  }

  /**
   * Returns the string value of passed argument.
   */
  public static final String generableToString(JGenerable generable) {
    // There is hardly any clean universal way to get the value from e.g. JExpression except of serializing it.
    // Compare JStringLiteral and JExp#dotclass().
    Writer w = new StringWriter();

    generable.generate(new JFormatter(w));

    // FIXME: Hopefully nobody will put quotes into annotation member value.
    return w.toString().replace("\"", "");
  }

  //
  // Reflection helpers.
  //

  public static void setPrivateField(Object obj, String fieldName, Object newValue) {
    setPrivateField(obj, obj.getClass(), fieldName, newValue);
  }

  /**
   * Set the {@code newValue} to private field {@code fieldName} of given object {@code obj}.
   */
  private static void setPrivateField(Object obj, Class<?> clazz, String fieldName, Object newValue) {
    try {
      Field field = clazz.getDeclaredField(fieldName);
      field.setAccessible(true);
      field.set(obj, newValue);
    }
    catch (NoSuchFieldException e) {
      if (clazz.getSuperclass() == Object.class) {
        // Field is really not found:
        throw new RuntimeException(e);
      }

      // Try super class:
      setPrivateField(obj, clazz.getSuperclass(), fieldName, newValue);
    }
    catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Get the value of private field {@code fieldName} of given object {@code obj}.
   */
  public static Object getPrivateField(Object obj, String fieldName) {
    return getPrivateField(obj, obj.getClass(), fieldName);
  }

  /**
   * Get the value of private field {@code fieldName} of given object {@code obj} which is treated as class
   * {@code clazz}.
   */
  private static Object getPrivateField(Object obj, Class<?> clazz, String fieldName) {
    try {
      Field field = clazz.getDeclaredField(fieldName);
      field.setAccessible(true);
      return field.get(obj);
    }
    catch (NoSuchFieldException e) {
      if (clazz.getSuperclass() == Object.class) {
        // Field is really not found:
        throw new RuntimeException(e);
      }

      // Try super class:
      return getPrivateField(obj, clazz.getSuperclass(), fieldName);
    }
    catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns XSD declaration of given property.
   */
  public static XSDeclaration getXsdDeclaration(CPropertyInfo propertyInfo) {
    XSComponent schemaComponent = propertyInfo.getSchemaComponent();

    if (!(schemaComponent instanceof XSParticle)) {
      // XSComplexType for example:
      return null;
    }

    XSTerm term = ((XSParticle) schemaComponent).getTerm();

    if (!(term instanceof XSDeclaration)) {
      // XSModelGroup for example:
      return null;
    }

    return (XSDeclaration) term;
  }
}
TOP

Related Classes of com.sun.tools.xjc.addon.xew.CommonUtils

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.