
com.sun.tools.xjc.addon.xew.CommonUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaxb-xew-plugin Show documentation
Show all versions of jaxb-xew-plugin Show documentation
This JAXB plugin utilizes the power of @XmlElementWrapper annotation. Originally xjc trends to create wrapper classes which are the containers for collections. This plugin goes through all properties to find ones which can be represented in the model in more optimal way.
package com.sun.tools.xjc.addon.xew;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
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.JExpr;
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;
import org.apache.commons.lang3.reflect.FieldUtils;
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 true
of the given type
is {@link JClass} and contains classToCheck
* 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 memberValues = 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
* @XmlElementRef(name = "last-name", namespace = "http://mycompany.org/exchange", type = JAXBElement.class)
* for member name
the value last-name
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
try {
// In most cases the value is some expression...
return (JExpression) getPrivateField(annotationValue, "value");
}
catch (IllegalArgumentException e) {
// ... and in some cases (like enum) do the conversion from JGenerable to JExpression
// (a bit unoptimal, since this expression is going to be converted back to string)
return JExpr.lit(generableToString(annotationValue));
}
}
/**
* Append the given annotation to list of annotations.
*/
public static void addAnnotation(JVar field, JAnnotationUse annotation) {
List annotations = getPrivateField(field, "annotations");
annotations.add(annotation);
}
/**
* Remove the given annotation from the list of annotations.
*/
public static void removeAnnotation(JVar field, JAnnotationUse annotation) {
List annotations = getPrivateField(field, "annotations");
annotations.remove(annotation);
}
/**
* Check that given field property has name customization ({@code }).
*
* @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.
//
/**
* Set the {@code newValue} to private field {@code fieldName} of given object {@code obj}.
*
* @throws NoSuchFieldException
* if given field was not found
*/
public static void setPrivateField(Object obj, String fieldName, Object newValue) {
try {
FieldUtils.writeField(obj, fieldName, newValue, true);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* Get the value of private field {@code fieldName} of given object {@code obj}.
*
* @throws IllegalArgumentException
* if given field was not found
*/
@SuppressWarnings("unchecked")
public static T getPrivateField(Object obj, String fieldName) {
try {
return (T) FieldUtils.readField(obj, fieldName, true);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* Perform the copying of all fields from {@code src} to {@code dest}. The code was copied from
* {@link org.springframework.util.ReflectionUtils#shallowCopyFieldState(Object, Object)}.
*/
public static void copyFields(final S src, D dest) throws IllegalArgumentException {
Class> targetClass = src.getClass();
do {
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
// Skip static fields:
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
try {
if ((!Modifier.isPublic(field.getModifiers())
|| !Modifier.isPublic(field.getDeclaringClass().getModifiers())
|| Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {
field.setAccessible(true);
}
Object srcValue = field.get(src);
field.set(dest, srcValue);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException(
"Shouldn't be illegal to access field '" + field.getName() + "': " + ex);
}
}
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
/**
* 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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy