Package net.sourceforge.javautil.common.jaxb

Source Code of net.sourceforge.javautil.common.jaxb.StandardJAXBMapper

package net.sourceforge.javautil.common.jaxb;

import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlValue;

import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassField;
import net.sourceforge.javautil.common.reflection.cache.ClassProperty;
import net.sourceforge.javautil.common.reflection.cache.IClassMemberWritableValue;

/**
* This will map standard JAXB annotations to {@link JavaXMLBean} templates.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class StandardJAXBMapper implements IJavaXMLBeanMapper {

  @Override public JavaXMLBean createElement(Class<?> bean) throws JAXBException {
    String name = null;
    String namespace = "";
    boolean rootElement = false;
   
    XmlRootElement root = bean.getAnnotation(XmlRootElement.class);
   
    if (root != null) {
      name = root.name();
      namespace = !root.namespace().equals("##default") ? root.namespace() : "";
      rootElement = true;
    } else {
      XmlElement element = bean.getAnnotation(XmlElement.class);
      if (element != null) {
        name = element.name();
        namespace = !element.namespace().equals("##default") ? element.namespace() : "";
      }
    }
   
    return new JavaXMLBean(bean, name, namespace, rootElement);
  }

  @Override public Map<String, IJavaXMLAttribute> getAttributes(ClassDescriptor<?> bean, JavaXMLBeanInitializationContext context) throws JAXBException {
    Map<String, IJavaXMLAttribute> attributes = new HashMap<String, IJavaXMLAttribute>();
 
    ClassField[] fields = bean.getFields(XmlAttribute.class);
    ClassProperty[] properties = bean.getProperties(XmlAttribute.class);
   
    List<IClassMemberWritableValue> members = new ArrayList<IClassMemberWritableValue>();
   
    members.addAll(Arrays.asList(properties));
    members.addAll(Arrays.asList(fields));
   
    for (IClassMemberWritableValue member : members) {
      XmlAttribute attribute = member.getAnnotation(XmlAttribute.class);
     
      String namespace = attribute != null && !attribute.namespace().equals("##default") ? attribute.namespace() : "";
      String xmlName = attribute != null && !"".equals( attribute.name() ) ? attribute.name() : member.getName();
     
      attributes.put("".equals(namespace) ? xmlName : (namespace + ":" + xmlName), new JavaXMLAttribute(member));
    }
   
    return attributes;
  }

  @Override public Map<String, IJavaXMLElement> getElements(ClassDescriptor<?> bean, JavaXMLBeanInitializationContext context) throws JAXBException {
    Map<String, IJavaXMLElement> elements = new HashMap<String, IJavaXMLElement>();
   
    XmlAccessorType xatDecl = bean.getAnnotation(XmlAccessorType.class);
    XmlAccessType xat = xatDecl == null ? XmlAccessType.PUBLIC_MEMBER : xatDecl.value();
   
    List<IClassMemberWritableValue> members = this.filter( this.getMembers(bean, context), XmlElement.class, xat );
   
    for (IClassMemberWritableValue member : members) {
      if (member.getAnnotation(XmlAttribute.class) != null) continue;
      if (member.getAnnotation(XmlAnyElement.class) != null) continue;
     
      XmlElement element = member.getAnnotation(XmlElement.class);
     
      String namespace = element != null && !element.namespace().equals("##default") ? element.namespace() : "";
      String xmlName = element != null && !"".equals( element.name() ) ? element.name() : member.getName();
     
      if (this.isSimple(member)) {
        elements.put("".equals(namespace) ? xmlName : (namespace + ":" + xmlName), new JavaXMLSimpleElement(member, namespace, xmlName));
      } else {
        elements.put("".equals(namespace) ? xmlName : (namespace + ":" + xmlName), this.createRealType(member, context));
      }
    }
   
    return elements;
  }
 
  @Override public IJavaXMLElement getAnyElementHandler(ClassDescriptor<?> bean, JavaXMLBeanInitializationContext context) throws JAXBException {
    XmlAccessorType xatDecl = bean.getAnnotation(XmlAccessorType.class);
    XmlAccessType xat = xatDecl == null ? XmlAccessType.PUBLIC_MEMBER : xatDecl.value();
   
    List<IClassMemberWritableValue> members = this.filter( this.getMembers(bean, context), XmlAnyElement.class, xat );
   
    Iterator<IClassMemberWritableValue> it = members.iterator();
    while (it.hasNext()) {
      IClassMemberWritableValue member = it.next();
      if (member.getAnnotation(XmlAnyElement.class) == null) {
        it.remove();
      }
    }

    if (members.size() > 1)
      throw new JAXBException("More than one member declared with XmlValue on" + bean);
   
    return members.size() == 1 ? this.createRealType(members.get(0), context) : null;
  }

  @Override public IJavaXMLContent getContentHandler(ClassDescriptor<?> bean, JavaXMLBeanInitializationContext context) throws JAXBException {
    XmlAccessorType xatDecl = bean.getAnnotation(XmlAccessorType.class);
    XmlAccessType xat = xatDecl == null ? XmlAccessType.PUBLIC_MEMBER : xatDecl.value();
   
    List<IClassMemberWritableValue> members = this.filter( this.getMembers(bean, context), XmlValue.class, xat );
   
    Iterator<IClassMemberWritableValue> it = members.iterator();
    while (it.hasNext()) {
      IClassMemberWritableValue member = it.next();
      if (member.getAnnotation(XmlValue.class) == null) {
        it.remove();
      }
    }

    if (members.size() > 1)
      throw new JAXBException("More than one member declared with XmlValue on" + bean);
   
    return members.size() == 1 ? new JavaXMLContent(members.get(0)) : null;
  }
 
  protected IJavaXMLElement createRealType (IClassMemberWritableValue member, JavaXMLBeanInitializationContext context) throws JAXBException {
    if (Collection.class.isAssignableFrom(member.getBaseType())) {
      Class<?> realType = ReflectionUtil.getConcreteGeneric(member.getGenericType(), 0);
     
      if (realType == null) {
        throw new JAXBException("Could not determine real collection type for: " + member);
      }
     
      XmlElementWrapper wrapper = member.getAnnotation(XmlElementWrapper.class);
      String wname = wrapper != null ? ("".equals(wrapper.name()) ? member.getName() : wrapper.name()) : null;
     
      return wname == null ?
          new JavaXMLCummulativeCollection(member, context.resolve(realType)) :
          new JavaXMLWrappedCollection(member, context.resolve(member.getBaseType()), context.resolve(realType));
    } else if (member.getBaseType().isArray()) {
      return null;
    } else {
      return new JavaXMLComplexElement(member, context.resolve(member.getBaseType()));
    }
  }

  protected List<IClassMemberWritableValue> getMembers (ClassDescriptor<?> bean, JavaXMLBeanInitializationContext context) {
    List<IClassMemberWritableValue> members = new ArrayList<IClassMemberWritableValue>();
   
    Map<String, List<ClassField>> fields = bean.getFields();
   
    for (String name : fields.keySet()) {
      members.addAll(fields.get(name));
    }
   
    members.addAll(bean.getProperties().values());
   
    return members;
  }
 
  protected List<IClassMemberWritableValue> filter (List<IClassMemberWritableValue> members, Class<? extends Annotation> atype, XmlAccessType xat) {
    for (Iterator<IClassMemberWritableValue> it = members.iterator(); it.hasNext(); ) {
      IClassMemberWritableValue member = it.next();
     
      if (member.isStatic() || Modifier.isTransient(member.getJavaMember().getModifiers()) ||
          member instanceof ClassProperty && !((ClassProperty)member).isWritable() ||
          member.getAnnotation(XmlTransient.class) != null) {
        it.remove();
        continue;
      }
     
      Annotation attribute = member.getAnnotation(atype);
     
      switch (xat) {
        case PUBLIC_MEMBER:
          if (!Modifier.isPublic( member.getJavaMember().getModifiers() )) it.remove();
          break;
         
        case NONE:
          if (attribute == null) it.remove();
          break;
         
        case PROPERTY:
          if (member instanceof ClassField && attribute == null) it.remove();
          break;
         
        case FIELD:
          if (member instanceof ClassProperty && attribute == null) it.remove();
      }
    }
   
    return members;
  }
 
  protected boolean isSimple (IClassMemberWritableValue member) {
    if (member.getBaseType().isPrimitive() || ReflectionUtil.isBoxedType(member.getBaseType())) return true;
   
    if (member.getBaseType() == String.class) return true;
   
    return false;
  }

}
TOP

Related Classes of net.sourceforge.javautil.common.jaxb.StandardJAXBMapper

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.