Package com.sun.xml.bind.v2.model.impl

Source Code of com.sun.xml.bind.v2.model.impl.ClassInfoImpl

/*      */ package com.sun.xml.bind.v2.model.impl;
/*      */
/*      */ import com.sun.istack.FinalArrayList;
/*      */ import com.sun.xml.bind.v2.model.annotation.AnnotationReader;
/*      */ import com.sun.xml.bind.v2.model.annotation.Locatable;
/*      */ import com.sun.xml.bind.v2.model.annotation.MethodLocatable;
/*      */ import com.sun.xml.bind.v2.model.core.ClassInfo;
/*      */ import com.sun.xml.bind.v2.model.core.Element;
/*      */ import com.sun.xml.bind.v2.model.core.ID;
/*      */ import com.sun.xml.bind.v2.model.core.NonElement;
/*      */ import com.sun.xml.bind.v2.model.core.PropertyInfo;
/*      */ import com.sun.xml.bind.v2.model.core.PropertyKind;
/*      */ import com.sun.xml.bind.v2.model.core.ValuePropertyInfo;
/*      */ import com.sun.xml.bind.v2.model.nav.Navigator;
/*      */ import com.sun.xml.bind.v2.runtime.IllegalAnnotationException;
/*      */ import com.sun.xml.bind.v2.runtime.Location;
/*      */ import com.sun.xml.bind.v2.util.EditDistance;
/*      */ import java.lang.annotation.Annotation;
/*      */ import java.lang.reflect.Method;
/*      */ import java.util.AbstractList;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Collection;
/*      */ import java.util.Collections;
/*      */ import java.util.Comparator;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.LinkedHashMap;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ import java.util.TreeSet;
/*      */ import javax.xml.bind.annotation.XmlAccessOrder;
/*      */ import javax.xml.bind.annotation.XmlAccessType;
/*      */ import javax.xml.bind.annotation.XmlAccessorOrder;
/*      */ import javax.xml.bind.annotation.XmlAccessorType;
/*      */ import javax.xml.bind.annotation.XmlAnyAttribute;
/*      */ import javax.xml.bind.annotation.XmlAnyElement;
/*      */ import javax.xml.bind.annotation.XmlAttachmentRef;
/*      */ import javax.xml.bind.annotation.XmlAttribute;
/*      */ import javax.xml.bind.annotation.XmlElement;
/*      */ import javax.xml.bind.annotation.XmlElementRef;
/*      */ import javax.xml.bind.annotation.XmlElementRefs;
/*      */ import javax.xml.bind.annotation.XmlElementWrapper;
/*      */ import javax.xml.bind.annotation.XmlElements;
/*      */ import javax.xml.bind.annotation.XmlID;
/*      */ import javax.xml.bind.annotation.XmlIDREF;
/*      */ import javax.xml.bind.annotation.XmlInlineBinaryData;
/*      */ import javax.xml.bind.annotation.XmlList;
/*      */ import javax.xml.bind.annotation.XmlMimeType;
/*      */ import javax.xml.bind.annotation.XmlMixed;
/*      */ import javax.xml.bind.annotation.XmlSchemaType;
/*      */ import javax.xml.bind.annotation.XmlTransient;
/*      */ import javax.xml.bind.annotation.XmlType;
/*      */ import javax.xml.bind.annotation.XmlType.DEFAULT;
/*      */ import javax.xml.bind.annotation.XmlValue;
/*      */ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/*      */ import javax.xml.namespace.QName;
/*      */
/*      */ class ClassInfoImpl<T, C, F, M> extends TypeInfoImpl<T, C, F, M>
/*      */   implements ClassInfo<T, C>, Element<T, C>
/*      */ {
/*      */   protected final C clazz;
/*      */   private final QName elementName;
/*      */   private final QName typeName;
/*      */   private FinalArrayList<PropertyInfoImpl<T, C, F, M>> properties;
/*      */   private final String[] propOrder;
/*      */   private ClassInfoImpl<T, C, F, M> baseClass;
/*  142 */   private boolean baseClassComputed = false;
/*      */
/*  144 */   private boolean hasSubClasses = false;
/*      */   protected PropertySeed<T, C, F, M> attributeWildcard;
/*  158 */   private M factoryMethod = null;
/*      */   private static final SecondaryAnnotation[] SECONDARY_ANNOTATIONS;
/*      */   private static final Annotation[] EMPTY_ANNOTATIONS;
/*      */   private static final HashMap<Class, Integer> ANNOTATION_NUMBER_MAP;
/*      */   private static final String[] DEFAULT_ORDER;
/*      */
/*      */   ClassInfoImpl(ModelBuilder<T, C, F, M> builder, Locatable upstream, C clazz)
/*      */   {
/*  161 */     super(builder, upstream);
/*  162 */     this.clazz = clazz;
/*  163 */     assert (clazz != null);
/*      */
/*  166 */     this.elementName = parseElementName(clazz);
/*      */
/*  169 */     XmlType t = (XmlType)reader().getClassAnnotation(XmlType.class, clazz, this);
/*  170 */     this.typeName = parseTypeName(clazz, t);
/*      */
/*  172 */     if (t != null) {
/*  173 */       String[] propOrder = t.propOrder();
/*  174 */       if (propOrder.length == 0) {
/*  175 */         this.propOrder = null;
/*      */       }
/*  177 */       else if (propOrder[0].length() == 0)
/*  178 */         this.propOrder = DEFAULT_ORDER;
/*      */       else
/*  180 */         this.propOrder = propOrder;
/*      */     }
/*      */     else {
/*  183 */       this.propOrder = DEFAULT_ORDER;
/*      */     }
/*      */
/*  186 */     if (nav().isInterface(clazz)) {
/*  187 */       builder.reportError(new IllegalAnnotationException(Messages.CANT_HANDLE_INTERFACE.format(new Object[] { nav().getClassName(clazz) }), this));
/*      */     }
/*      */
/*  192 */     if ((!hasFactoryConstructor(t)) &&
/*  193 */       (!nav().hasDefaultConstructor(clazz)))
/*      */     {
/*      */       Messages msg;
/*      */       Messages msg;
/*  195 */       if (nav().isInnerClass(clazz))
/*  196 */         msg = Messages.CANT_HANDLE_INNER_CLASS;
/*      */       else {
/*  198 */         msg = Messages.NO_DEFAULT_CONSTRUCTOR;
/*      */       }
/*  200 */       builder.reportError(new IllegalAnnotationException(msg.format(new Object[] { nav().getClassName(clazz) }), this));
/*      */     }
/*      */   }
/*      */
/*      */   public ClassInfoImpl<T, C, F, M> getBaseClass()
/*      */   {
/*  207 */     if (!this.baseClassComputed) {
/*  208 */       this.baseClassComputed = true;
/*      */
/*  210 */       Object s = nav().getSuperClass(this.clazz);
/*  211 */       if ((s == null) || (s == nav().asDecl(Object.class))) {
/*  212 */         this.baseClass = null;
/*      */       } else {
/*  214 */         NonElement b = this.builder.getClassInfo(s, true, this);
/*  215 */         if ((b instanceof ClassInfoImpl)) {
/*  216 */           this.baseClass = ((ClassInfoImpl)b);
/*  217 */           this.baseClass.hasSubClasses = true;
/*      */         } else {
/*  219 */           this.baseClass = null;
/*      */         }
/*      */       }
/*      */     }
/*  223 */     return this.baseClass;
/*      */   }
/*      */
/*      */   public final Element<T, C> getSubstitutionHead()
/*      */   {
/*  232 */     ClassInfoImpl c = getBaseClass();
/*  233 */     while ((c != null) && (!c.isElement()))
/*  234 */       c = c.getBaseClass();
/*  235 */     return c;
/*      */   }
/*      */
/*      */   public final C getClazz() {
/*  239 */     return this.clazz;
/*      */   }
/*      */
/*      */   /** @deprecated */
/*      */   public ClassInfoImpl<T, C, F, M> getScope()
/*      */   {
/*  250 */     return null;
/*      */   }
/*      */
/*      */   public final T getType() {
/*  254 */     return nav().use(this.clazz);
/*      */   }
/*      */
/*      */   public boolean canBeReferencedByIDREF()
/*      */   {
/*  262 */     for (PropertyInfo p : getProperties()) {
/*  263 */       if (p.id() == ID.ID)
/*  264 */         return true;
/*      */     }
/*  266 */     ClassInfoImpl base = getBaseClass();
/*  267 */     if (base != null) {
/*  268 */       return base.canBeReferencedByIDREF();
/*      */     }
/*  270 */     return false;
/*      */   }
/*      */
/*      */   public final String getName() {
/*  274 */     return nav().getClassName(this.clazz);
/*      */   }
/*      */
/*      */   public <A extends Annotation> A readAnnotation(Class<A> a) {
/*  278 */     return reader().getClassAnnotation(a, this.clazz, this);
/*      */   }
/*      */
/*      */   public Element<T, C> asElement() {
/*  282 */     if (isElement()) {
/*  283 */       return this;
/*      */     }
/*  285 */     return null;
/*      */   }
/*      */
/*      */   public List<? extends PropertyInfo<T, C>> getProperties() {
/*  289 */     if (this.properties != null) return this.properties;
/*      */
/*  292 */     XmlAccessType at = getAccessType();
/*      */
/*  294 */     this.properties = new FinalArrayList();
/*      */
/*  296 */     findFieldProperties(this.clazz, at);
/*      */
/*  298 */     findGetterSetterProperties(at);
/*      */
/*  300 */     if ((this.propOrder == DEFAULT_ORDER) || (this.propOrder == null)) {
/*  301 */       XmlAccessOrder ao = getAccessorOrder();
/*  302 */       if (ao == XmlAccessOrder.ALPHABETICAL)
/*  303 */         Collections.sort(this.properties);
/*      */     }
/*      */     else {
/*  306 */       PropertySorter sorter = new PropertySorter();
/*  307 */       for (PropertyInfoImpl p : this.properties)
/*  308 */         sorter.checkedGet(p);
/*  309 */       Collections.sort(this.properties, sorter);
/*  310 */       sorter.checkUnusedProperties();
/*      */     }
/*      */
/*  314 */     PropertyInfoImpl vp = null;
/*  315 */     PropertyInfoImpl ep = null;
/*      */
/*  317 */     for (PropertyInfoImpl p : this.properties) {
/*  318 */       switch (1.$SwitchMap$com$sun$xml$bind$v2$model$core$PropertyKind[p.kind().ordinal()]) {
/*      */       case 1:
/*      */       case 2:
/*      */       case 3:
/*  322 */         ep = p;
/*  323 */         break;
/*      */       case 4:
/*  325 */         if (vp != null)
/*      */         {
/*  327 */           this.builder.reportError(new IllegalAnnotationException(Messages.MULTIPLE_VALUE_PROPERTY.format(new Object[0]), vp, p));
/*      */         }
/*      */
/*  331 */         if (getBaseClass() != null) {
/*  332 */           this.builder.reportError(new IllegalAnnotationException(Messages.XMLVALUE_IN_DERIVED_TYPE.format(new Object[0]), p));
/*      */         }
/*      */
/*  335 */         vp = p;
/*  336 */         break;
/*      */       case 5:
/*  338 */         break;
/*      */       default:
/*  340 */         if ($assertionsDisabled) break; throw new AssertionError();
/*      */       }
/*      */     }
/*      */
/*  344 */     if ((ep != null) && (vp != null))
/*      */     {
/*  346 */       this.builder.reportError(new IllegalAnnotationException(Messages.ELEMENT_AND_VALUE_PROPERTY.format(new Object[0]), vp, ep));
/*      */     }
/*      */
/*  353 */     return this.properties;
/*      */   }
/*      */
/*      */   private void findFieldProperties(C c, XmlAccessType at)
/*      */   {
/*  358 */     Object sc = nav().getSuperClass(c);
/*  359 */     if (shouldRecurseSuperClass(sc)) {
/*  360 */       findFieldProperties(sc, at);
/*      */     }
/*  362 */     for (Iterator i$ = nav().getDeclaredFields(c).iterator(); i$.hasNext(); ) { Object f = i$.next();
/*  363 */       Annotation[] annotations = reader().getAllFieldAnnotations(f, this);
/*  364 */       if (nav().isTransient(f))
/*      */       {
/*  366 */         if (hasJAXBAnnotation(annotations)) {
/*  367 */           this.builder.reportError(new IllegalAnnotationException(Messages.TRANSIENT_FIELD_NOT_BINDABLE.format(new Object[] { nav().getFieldName(f) }), getSomeJAXBAnnotation(annotations)));
/*      */         }
/*      */
/*      */       }
/*  371 */       else if (nav().isStaticField(f))
/*      */       {
/*  373 */         if (hasJAXBAnnotation(annotations))
/*  374 */           addProperty(createFieldSeed(f), annotations);
/*      */       } else {
/*  376 */         if ((at == XmlAccessType.FIELD) || ((at == XmlAccessType.PUBLIC_MEMBER) && (nav().isPublicField(f))) || (hasJAXBAnnotation(annotations)))
/*      */         {
/*  379 */           addProperty(createFieldSeed(f), annotations);
/*  380 */         }checkFieldXmlLocation(f);
/*      */       } }
/*      */   }
/*      */
/*      */   public final boolean hasValueProperty()
/*      */   {
/*  386 */     ClassInfoImpl bc = getBaseClass();
/*  387 */     if ((bc != null) && (bc.hasValueProperty())) {
/*  388 */       return true;
/*      */     }
/*  390 */     for (PropertyInfo p : getProperties()) {
/*  391 */       if ((p instanceof ValuePropertyInfo)) return true;
/*      */     }
/*      */
/*  394 */     return false;
/*      */   }
/*      */
/*      */   public PropertyInfo<T, C> getProperty(String name) {
/*  398 */     for (PropertyInfo p : getProperties()) {
/*  399 */       if (p.getName().equals(name))
/*  400 */         return p;
/*      */     }
/*  402 */     return null;
/*      */   }
/*      */
/*      */   protected void checkFieldXmlLocation(F f)
/*      */   {
/*      */   }
/*      */
/*      */   private <T extends Annotation> T getClassOrPackageAnnotation(Class<T> type)
/*      */   {
/*  415 */     Annotation t = reader().getClassAnnotation(type, this.clazz, this);
/*  416 */     if (t != null) {
/*  417 */       return t;
/*      */     }
/*  419 */     return reader().getPackageAnnotation(type, this.clazz, this);
/*      */   }
/*      */
/*      */   private XmlAccessType getAccessType()
/*      */   {
/*  427 */     XmlAccessorType xat = (XmlAccessorType)getClassOrPackageAnnotation(XmlAccessorType.class);
/*  428 */     if (xat != null) {
/*  429 */       return xat.value();
/*      */     }
/*  431 */     return XmlAccessType.PUBLIC_MEMBER;
/*      */   }
/*      */
/*      */   private XmlAccessOrder getAccessorOrder()
/*      */   {
/*  438 */     XmlAccessorOrder xao = (XmlAccessorOrder)getClassOrPackageAnnotation(XmlAccessorOrder.class);
/*  439 */     if (xao != null) {
/*  440 */       return xao.value();
/*      */     }
/*  442 */     return XmlAccessOrder.UNDEFINED;
/*      */   }
/*      */
/*      */   public boolean hasProperties()
/*      */   {
/*  533 */     return !this.properties.isEmpty();
/*      */   }
/*      */
/*      */   private static <T> T pickOne(T[] args)
/*      */   {
/*  541 */     for (Object arg : args)
/*  542 */       if (arg != null)
/*  543 */         return arg;
/*  544 */     return null;
/*      */   }
/*      */
/*      */   private static <T> List<T> makeSet(T[] args) {
/*  548 */     List l = new FinalArrayList();
/*  549 */     for (Object arg : args) {
/*  550 */       if (arg == null) continue; l.add(arg);
/*  551 */     }return l;
/*      */   }
/*      */
/*      */   private void checkConflict(Annotation a, Annotation b)
/*      */     throws ClassInfoImpl.DupliateException
/*      */   {
/*  672 */     assert (b != null);
/*  673 */     if (a != null)
/*  674 */       throw new DupliateException(a, b);
/*      */   }
/*      */
/*      */   private void addProperty(PropertySeed<T, C, F, M> seed, Annotation[] annotations)
/*      */   {
/*  697 */     XmlTransient t = null;
/*  698 */     XmlAnyAttribute aa = null;
/*  699 */     XmlAttribute a = null;
/*  700 */     XmlValue v = null;
/*  701 */     XmlElement e1 = null;
/*  702 */     XmlElements e2 = null;
/*  703 */     XmlElementRef r1 = null;
/*  704 */     XmlElementRefs r2 = null;
/*  705 */     XmlAnyElement xae = null;
/*  706 */     XmlMixed mx = null;
/*      */
/*  709 */     int secondaryAnnotations = 0;
/*      */     try
/*      */     {
/*  712 */       for (Annotation ann : annotations) {
/*  713 */         Integer index = (Integer)ANNOTATION_NUMBER_MAP.get(ann.annotationType());
/*  714 */         if (index != null) {
/*  715 */           switch (index.intValue()) { case 0:
/*  716 */             checkConflict(t, ann); t = (XmlTransient)ann; break;
/*      */           case 1:
/*  717 */             checkConflict(aa, ann); aa = (XmlAnyAttribute)ann; break;
/*      */           case 2:
/*  718 */             checkConflict(a, ann); a = (XmlAttribute)ann; break;
/*      */           case 3:
/*  719 */             checkConflict(v, ann); v = (XmlValue)ann; break;
/*      */           case 4:
/*  720 */             checkConflict(e1, ann); e1 = (XmlElement)ann; break;
/*      */           case 5:
/*  721 */             checkConflict(e2, ann); e2 = (XmlElements)ann; break;
/*      */           case 6:
/*  722 */             checkConflict(r1, ann); r1 = (XmlElementRef)ann; break;
/*      */           case 7:
/*  723 */             checkConflict(r2, ann); r2 = (XmlElementRefs)ann; break;
/*      */           case 8:
/*  724 */             checkConflict(xae, ann); xae = (XmlAnyElement)ann; break;
/*      */           case 9:
/*  725 */             checkConflict(mx, ann); mx = (XmlMixed)ann; break;
/*      */           default:
/*  728 */             secondaryAnnotations |= 1 << index.intValue() - 20;
/*      */           }
/*      */
/*      */         }
/*      */
/*      */       }
/*      */
/*  735 */       PropertyGroup group = null;
/*  736 */       int groupCount = 0;
/*      */
/*  738 */       if (t != null) {
/*  739 */         group = PropertyGroup.TRANSIENT;
/*  740 */         groupCount++;
/*      */       }
/*  742 */       if (aa != null) {
/*  743 */         group = PropertyGroup.ANY_ATTRIBUTE;
/*  744 */         groupCount++;
/*      */       }
/*  746 */       if (a != null) {
/*  747 */         group = PropertyGroup.ATTRIBUTE;
/*  748 */         groupCount++;
/*      */       }
/*  750 */       if (v != null) {
/*  751 */         group = PropertyGroup.VALUE;
/*  752 */         groupCount++;
/*      */       }
/*  754 */       if ((e1 != null) || (e2 != null)) {
/*  755 */         group = PropertyGroup.ELEMENT;
/*  756 */         groupCount++;
/*      */       }
/*  758 */       if ((r1 != null) || (r2 != null) || (xae != null) || (mx != null)) {
/*  759 */         group = PropertyGroup.ELEMENT_REF;
/*  760 */         groupCount++;
/*      */       }
/*      */
/*  763 */       if (groupCount > 1)
/*      */       {
/*  765 */         List err = makeSet(new Annotation[] { t, aa, a, v, (Annotation)pickOne(new Annotation[] { e1, e2 }), (Annotation)pickOne(new Annotation[] { r1, r2, xae }) });
/*  766 */         throw new ConflictException(err);
/*      */       }
/*      */
/*  769 */       if (group == null)
/*      */       {
/*  772 */         assert (groupCount == 0);
/*      */
/*  775 */         if ((nav().isSubClassOf(seed.getRawType(), nav().ref(Map.class))) && (!seed.hasAnnotation(XmlJavaTypeAdapter.class)))
/*      */         {
/*  777 */           group = PropertyGroup.MAP;
/*      */         }
/*  779 */         else group = PropertyGroup.ELEMENT;
/*      */
/*      */       }
/*      */
/*  784 */       if ((secondaryAnnotations & group.allowedsecondaryAnnotations) != 0)
/*      */       {
/*  786 */         for (SecondaryAnnotation sa : SECONDARY_ANNOTATIONS) {
/*  787 */           if (group.allows(sa))
/*      */             continue;
/*  789 */           for (Class m : sa.members) {
/*  790 */             Annotation offender = seed.readAnnotation(m);
/*  791 */             if (offender == null)
/*      */               continue;
/*  793 */             this.builder.reportError(new IllegalAnnotationException(Messages.ANNOTATION_NOT_ALLOWED.format(new Object[] { m.getSimpleName() }), offender));
/*      */
/*  795 */             return;
/*      */           }
/*      */
/*      */         }
/*      */
/*  800 */         if (!$assertionsDisabled) throw new AssertionError();
/*      */
/*      */       }
/*      */
/*  804 */       switch (1.$SwitchMap$com$sun$xml$bind$v2$model$impl$ClassInfoImpl$PropertyGroup[group.ordinal()]) {
/*      */       case 1:
/*  806 */         return;
/*      */       case 2:
/*  809 */         if (this.attributeWildcard != null) {
/*  810 */           this.builder.reportError(new IllegalAnnotationException(Messages.TWO_ATTRIBUTE_WILDCARDS.format(new Object[] { nav().getClassName(getClazz()) }), aa, this.attributeWildcard));
/*      */
/*  813 */           return;
/*      */         }
/*  815 */         this.attributeWildcard = seed;
/*      */
/*  817 */         if (inheritsAttributeWildcard()) {
/*  818 */           this.builder.reportError(new IllegalAnnotationException(Messages.SUPER_CLASS_HAS_WILDCARD.format(new Object[0]), aa, getInheritedAttributeWildcard()));
/*      */
/*  821 */           return;
/*      */         }
/*      */
/*  825 */         if (!nav().isSubClassOf(seed.getRawType(), nav().ref(Map.class))) {
/*  826 */           this.builder.reportError(new IllegalAnnotationException(Messages.INVALID_ATTRIBUTE_WILDCARD_TYPE.format(new Object[] { nav().getTypeName(seed.getRawType()) }), aa, getInheritedAttributeWildcard()));
/*      */
/*  829 */           return;
/*      */         }
/*      */
/*  833 */         return;
/*      */       case 3:
/*  835 */         this.properties.add(createAttributeProperty(seed));
/*  836 */         return;
/*      */       case 4:
/*  838 */         this.properties.add(createValueProperty(seed));
/*  839 */         return;
/*      */       case 5:
/*  841 */         this.properties.add(createElementProperty(seed));
/*  842 */         return;
/*      */       case 6:
/*  844 */         this.properties.add(createReferenceProperty(seed));
/*  845 */         return;
/*      */       case 7:
/*  847 */         this.properties.add(createMapProperty(seed));
/*  848 */         return;
/*      */       }
/*  850 */       if (!$assertionsDisabled) throw new AssertionError();
/*      */     }
/*      */     catch (ConflictException x)
/*      */     {
/*  854 */       List err = x.annotations;
/*      */
/*  856 */       this.builder.reportError(new IllegalAnnotationException(Messages.MUTUALLY_EXCLUSIVE_ANNOTATIONS.format(new Object[] { nav().getClassName(getClazz()) + '#' + seed.getName(), ((Annotation)err.get(0)).annotationType().getName(), ((Annotation)err.get(1)).annotationType().getName() }), (Annotation)err.get(0), (Annotation)err.get(1)));
/*      */     }
/*      */     catch (DupliateException e)
/*      */     {
/*  865 */       this.builder.reportError(new IllegalAnnotationException(Messages.DUPLICATE_ANNOTATIONS.format(new Object[] { e.a1.annotationType().getName() }), e.a1, e.a2));
/*      */     }
/*      */   }
/*      */
/*      */   protected ReferencePropertyInfoImpl<T, C, F, M> createReferenceProperty(PropertySeed<T, C, F, M> seed)
/*      */   {
/*  874 */     return new ReferencePropertyInfoImpl(this, seed);
/*      */   }
/*      */
/*      */   protected AttributePropertyInfoImpl<T, C, F, M> createAttributeProperty(PropertySeed<T, C, F, M> seed) {
/*  878 */     return new AttributePropertyInfoImpl(this, seed);
/*      */   }
/*      */
/*      */   protected ValuePropertyInfoImpl<T, C, F, M> createValueProperty(PropertySeed<T, C, F, M> seed) {
/*  882 */     return new ValuePropertyInfoImpl(this, seed);
/*      */   }
/*      */
/*      */   protected ElementPropertyInfoImpl<T, C, F, M> createElementProperty(PropertySeed<T, C, F, M> seed) {
/*  886 */     return new ElementPropertyInfoImpl(this, seed);
/*      */   }
/*      */
/*      */   protected MapPropertyInfoImpl<T, C, F, M> createMapProperty(PropertySeed<T, C, F, M> seed) {
/*  890 */     return new MapPropertyInfoImpl(this, seed);
/*      */   }
/*      */
/*      */   private void findGetterSetterProperties(XmlAccessType at)
/*      */   {
/*  900 */     Map getters = new LinkedHashMap();
/*  901 */     Map setters = new LinkedHashMap();
/*      */
/*  903 */     Object c = this.clazz;
/*      */     do {
/*  905 */       collectGetterSetters(this.clazz, getters, setters);
/*      */
/*  908 */       c = nav().getSuperClass(c);
/*  909 */     }while (shouldRecurseSuperClass(c));
/*      */
/*  913 */     Set complete = new TreeSet(getters.keySet());
/*  914 */     complete.retainAll(setters.keySet());
/*      */
/*  916 */     resurrect(getters, complete);
/*  917 */     resurrect(setters, complete);
/*      */
/*  920 */     for (String name : complete) {
/*  921 */       Object getter = getters.get(name);
/*  922 */       Object setter = setters.get(name);
/*      */
/*  924 */       Annotation[] ga = getter != null ? reader().getAllMethodAnnotations(getter, new MethodLocatable(this, getter, nav())) : EMPTY_ANNOTATIONS;
/*  925 */       Annotation[] sa = setter != null ? reader().getAllMethodAnnotations(setter, new MethodLocatable(this, setter, nav())) : EMPTY_ANNOTATIONS;
/*      */
/*  927 */       boolean hasAnnotation = (hasJAXBAnnotation(ga)) || (hasJAXBAnnotation(sa));
/*  928 */       boolean isOverriding = false;
/*  929 */       if (!hasAnnotation)
/*      */       {
/*  932 */         isOverriding = ((getter != null) && (nav().isOverriding(getter, c))) || ((setter != null) && (nav().isOverriding(setter, c)));
/*      */       }
/*      */
/*  936 */       if (((at == XmlAccessType.PROPERTY) && (!isOverriding)) || ((at == XmlAccessType.PUBLIC_MEMBER) && (isConsideredPublic(getter)) && (isConsideredPublic(setter)) && (!isOverriding)) || (hasAnnotation))
/*      */       {
/*  940 */         if ((getter != null) && (setter != null) && (!nav().getReturnType(getter).equals(nav().getMethodParameters(setter)[0])))
/*      */         {
/*  943 */           this.builder.reportError(new IllegalAnnotationException(Messages.GETTER_SETTER_INCOMPATIBLE_TYPE.format(new Object[] { nav().getTypeName(nav().getReturnType(getter)), nav().getTypeName(nav().getMethodParameters(setter)[0]) }), new MethodLocatable(this, getter, nav()), new MethodLocatable(this, setter, nav())));
/*      */
/*  950 */           continue;
/*      */         }
/*      */         Annotation[] r;
/*      */         Annotation[] r;
/*  955 */         if (ga.length == 0) {
/*  956 */           r = sa;
/*      */         }
/*      */         else
/*      */         {
/*      */           Annotation[] r;
/*  958 */           if (sa.length == 0) {
/*  959 */             r = ga;
/*      */           } else {
/*  961 */             r = new Annotation[ga.length + sa.length];
/*  962 */             System.arraycopy(ga, 0, r, 0, ga.length);
/*  963 */             System.arraycopy(sa, 0, r, ga.length, sa.length);
/*      */           }
/*      */         }
/*  966 */         addProperty(createAccessorSeed(getter, setter), r);
/*      */       }
/*      */     }
/*      */
/*  970 */     getters.keySet().removeAll(complete);
/*  971 */     setters.keySet().removeAll(complete);
/*      */   }
/*      */
/*      */   private void collectGetterSetters(C c, Map<String, M> getters, Map<String, M> setters)
/*      */   {
/*  988 */     Object sc = nav().getSuperClass(c);
/*  989 */     if (shouldRecurseSuperClass(sc)) {
/*  990 */       collectGetterSetters(sc, getters, setters);
/*      */     }
/*      */
/*  993 */     Collection methods = nav().getDeclaredMethods(c);
/*  994 */     Map allSetters = new LinkedHashMap();
/*  995 */     for (Iterator i$ = methods.iterator(); i$.hasNext(); ) { Object method = i$.next();
/*  996 */       boolean used = false;
/*      */
/*  998 */       if (nav().isBridgeMethod(method)) {
/*      */         continue;
/*      */       }
/* 1001 */       String name = nav().getMethodName(method);
/* 1002 */       int arity = nav().getMethodParameters(method).length;
/*      */
/* 1004 */       if (nav().isStaticMethod(method)) {
/* 1005 */         ensureNoAnnotation(method);
/* 1006 */         continue;
/*      */       }
/*      */
/* 1012 */       String propName = getPropertyNameFromGetMethod(name);
/* 1013 */       if ((propName != null) && (arity == 0)) {
/* 1014 */         getters.put(propName, method);
/* 1015 */         used = true;
/*      */       }
/*      */
/* 1019 */       propName = getPropertyNameFromSetMethod(name);
/* 1020 */       if ((propName != null) && (arity == 1)) {
/* 1021 */         List propSetters = (List)allSetters.get(propName);
/* 1022 */         if (null == propSetters) {
/* 1023 */           propSetters = new ArrayList();
/* 1024 */           allSetters.put(propName, propSetters);
/*      */         }
/* 1026 */         propSetters.add(method);
/* 1027 */         used = true;
/*      */       }
/*      */
/* 1030 */       if (!used) {
/* 1031 */         ensureNoAnnotation(method);
/*      */       }
/*      */     }
/*      */
/* 1035 */     for (Map.Entry entry : getters.entrySet()) {
/* 1036 */       propName = (String)entry.getKey();
/* 1037 */       Object getter = entry.getValue();
/* 1038 */       List propSetters = (List)allSetters.remove(propName);
/* 1039 */       if (null == propSetters)
/*      */       {
/*      */         continue;
/*      */       }
/* 1043 */       getterType = nav().getReturnType(getter);
/* 1044 */       for (i$ = propSetters.iterator(); i$.hasNext(); ) { Object setter = i$.next();
/* 1045 */         Object setterType = nav().getMethodParameters(setter)[0];
/* 1046 */         if (setterType.equals(getterType)) {
/* 1047 */           setters.put(propName, setter);
/* 1048 */           break;
/*      */         }
/*      */       }
/*      */     }
/*      */     String propName;
/*      */     Object getterType;
/*      */     Iterator i$;
/* 1054 */     for (Map.Entry e : allSetters.entrySet())
/* 1055 */       setters.put(e.getKey(), ((List)e.getValue()).get(0));
/*      */   }
/*      */
/*      */   private boolean shouldRecurseSuperClass(C sc)
/*      */   {
/* 1063 */     return (sc != null) && ((this.builder.isReplaced(sc)) || (reader().hasClassAnnotation(sc, XmlTransient.class)));
/*      */   }
/*      */
/*      */   private boolean isConsideredPublic(M m)
/*      */   {
/* 1071 */     return (m == null) || (nav().isPublicMethod(m));
/*      */   }
/*      */
/*      */   private void resurrect(Map<String, M> methods, Set<String> complete)
/*      */   {
/* 1079 */     for (Map.Entry e : methods.entrySet()) {
/* 1080 */       if (complete.contains(e.getKey()))
/*      */         continue;
/* 1082 */       if (hasJAXBAnnotation(reader().getAllMethodAnnotations(e.getValue(), this)))
/* 1083 */         complete.add(e.getKey());
/*      */     }
/*      */   }
/*      */
/*      */   private void ensureNoAnnotation(M method)
/*      */   {
/* 1092 */     Annotation[] annotations = reader().getAllMethodAnnotations(method, this);
/* 1093 */     for (Annotation a : annotations)
/* 1094 */       if (isJAXBAnnotation(a)) {
/* 1095 */         this.builder.reportError(new IllegalAnnotationException(Messages.ANNOTATION_ON_WRONG_METHOD.format(new Object[0]), a));
/*      */
/* 1098 */         return;
/*      */       }
/*      */   }
/*      */
/*      */   private static boolean isJAXBAnnotation(Annotation a)
/*      */   {
/* 1107 */     return ANNOTATION_NUMBER_MAP.containsKey(a.annotationType());
/*      */   }
/*      */
/*      */   private static boolean hasJAXBAnnotation(Annotation[] annotations)
/*      */   {
/* 1114 */     return getSomeJAXBAnnotation(annotations) != null;
/*      */   }
/*      */
/*      */   private static Annotation getSomeJAXBAnnotation(Annotation[] annotations) {
/* 1118 */     for (Annotation a : annotations)
/* 1119 */       if (isJAXBAnnotation(a))
/* 1120 */         return a;
/* 1121 */     return null;
/*      */   }
/*      */
/*      */   private static String getPropertyNameFromGetMethod(String name)
/*      */   {
/* 1132 */     if ((name.startsWith("get")) && (name.length() > 3))
/* 1133 */       return name.substring(3);
/* 1134 */     if ((name.startsWith("is")) && (name.length() > 2))
/* 1135 */       return name.substring(2);
/* 1136 */     return null;
/*      */   }
/*      */
/*      */   private static String getPropertyNameFromSetMethod(String name)
/*      */   {
/* 1146 */     if ((name.startsWith("set")) && (name.length() > 3))
/* 1147 */       return name.substring(3);
/* 1148 */     return null;
/*      */   }
/*      */
/*      */   protected PropertySeed<T, C, F, M> createFieldSeed(F f)
/*      */   {
/* 1158 */     return new FieldPropertySeed(this, f);
/*      */   }
/*      */
/*      */   protected PropertySeed<T, C, F, M> createAccessorSeed(M getter, M setter)
/*      */   {
/* 1165 */     return new GetterSetterPropertySeed(this, getter, setter);
/*      */   }
/*      */
/*      */   public final boolean isElement() {
/* 1169 */     return this.elementName != null;
/*      */   }
/*      */
/*      */   public boolean isAbstract() {
/* 1173 */     return nav().isAbstract(this.clazz);
/*      */   }
/*      */
/*      */   public boolean isOrdered() {
/* 1177 */     return this.propOrder != null;
/*      */   }
/*      */
/*      */   public final boolean isFinal() {
/* 1181 */     return nav().isFinal(this.clazz);
/*      */   }
/*      */
/*      */   public final boolean hasSubClasses() {
/* 1185 */     return this.hasSubClasses;
/*      */   }
/*      */
/*      */   public final boolean hasAttributeWildcard() {
/* 1189 */     return (declaresAttributeWildcard()) || (inheritsAttributeWildcard());
/*      */   }
/*      */
/*      */   public final boolean inheritsAttributeWildcard() {
/* 1193 */     return getInheritedAttributeWildcard() != null;
/*      */   }
/*      */
/*      */   public final boolean declaresAttributeWildcard() {
/* 1197 */     return this.attributeWildcard != null;
/*      */   }
/*      */
/*      */   private PropertySeed<T, C, F, M> getInheritedAttributeWildcard()
/*      */   {
/* 1204 */     for (ClassInfoImpl c = getBaseClass(); c != null; c = c.getBaseClass())
/* 1205 */       if (c.attributeWildcard != null)
/* 1206 */         return c.attributeWildcard;
/* 1207 */     return null;
/*      */   }
/*      */
/*      */   public final QName getElementName() {
/* 1211 */     return this.elementName;
/*      */   }
/*      */
/*      */   public final QName getTypeName() {
/* 1215 */     return this.typeName;
/*      */   }
/*      */
/*      */   public final boolean isSimpleType() {
/* 1219 */     List props = getProperties();
/* 1220 */     if (props.size() != 1) return false;
/* 1221 */     return ((PropertyInfo)props.get(0)).kind() == PropertyKind.VALUE;
/*      */   }
/*      */
/*      */   void link()
/*      */   {
/* 1229 */     getProperties();
/*      */
/* 1232 */     Map names = new HashMap();
/* 1233 */     for (PropertyInfoImpl p : this.properties) {
/* 1234 */       p.link();
/* 1235 */       PropertyInfoImpl old = (PropertyInfoImpl)names.put(p.getName(), p);
/* 1236 */       if (old != null) {
/* 1237 */         this.builder.reportError(new IllegalAnnotationException(Messages.PROPERTY_COLLISION.format(new Object[] { p.getName() }), p, old));
/*      */       }
/*      */
/*      */     }
/*      */
/* 1242 */     super.link();
/*      */   }
/*      */
/*      */   public Location getLocation() {
/* 1246 */     return nav().getClassLocation(this.clazz);
/*      */   }
/*      */
/*      */   private boolean hasFactoryConstructor(XmlType t)
/*      */   {
/* 1258 */     if (t == null) return false;
/*      */
/* 1260 */     String method = t.factoryMethod();
/* 1261 */     Object fClass = reader().getClassValue(t, "factoryClass");
/* 1262 */     if (method.length() > 0) {
/* 1263 */       if (fClass.equals(nav().ref(XmlType.DEFAULT.class))) {
/* 1264 */         fClass = nav().use(this.clazz);
/*      */       }
/* 1266 */       for (Iterator i$ = nav().getDeclaredMethods(nav().asDecl(fClass)).iterator(); i$.hasNext(); ) { Object m = i$.next();
/*      */
/* 1268 */         if ((nav().getMethodName(m).equals(method)) && (nav().getReturnType(m).equals(nav().use(this.clazz))) && (nav().getMethodParameters(m).length == 0) && (nav().isStaticMethod(m)))
/*      */         {
/* 1272 */           this.factoryMethod = m;
/* 1273 */           break;
/*      */         }
/*      */       }
/* 1276 */       if (this.factoryMethod == null) {
/* 1277 */         this.builder.reportError(new IllegalAnnotationException(Messages.NO_FACTORY_METHOD.format(new Object[] { nav().getClassName(nav().asDecl(fClass)), method }), this));
/*      */       }
/*      */     }
/* 1280 */     else if (!fClass.equals(nav().ref(XmlType.DEFAULT.class))) {
/* 1281 */       this.builder.reportError(new IllegalAnnotationException(Messages.FACTORY_CLASS_NEEDS_FACTORY_METHOD.format(new Object[] { nav().getClassName(nav().asDecl(fClass)) }), this));
/*      */     }
/*      */
/* 1284 */     return this.factoryMethod != null;
/*      */   }
/*      */
/*      */   public Method getFactoryMethod() {
/* 1288 */     return (Method)this.factoryMethod;
/*      */   }
/*      */
/*      */   public String toString() {
/* 1292 */     return "ClassInfo(" + this.clazz + ')';
/*      */   }
/*      */
/*      */   static
/*      */   {
/*  597 */     SECONDARY_ANNOTATIONS = SecondaryAnnotation.values();
/*      */
/*  636 */     EMPTY_ANNOTATIONS = new Annotation[0];
/*      */
/*  641 */     ANNOTATION_NUMBER_MAP = new HashMap();
/*      */
/*  643 */     Class[] annotations = { XmlTransient.class, XmlAnyAttribute.class, XmlAttribute.class, XmlValue.class, XmlElement.class, XmlElements.class, XmlElementRef.class, XmlElementRefs.class, XmlAnyElement.class, XmlMixed.class };
/*      */
/*  656 */     HashMap m = ANNOTATION_NUMBER_MAP;
/*      */
/*  659 */     for (Class c : annotations) {
/*  660 */       m.put(c, Integer.valueOf(m.size()));
/*      */     }
/*      */
/*  663 */     int index = 20;
/*  664 */     for (SecondaryAnnotation sa : SECONDARY_ANNOTATIONS) {
/*  665 */       for (Class member : sa.members)
/*  666 */         m.put(member, Integer.valueOf(index));
/*  667 */       index++;
/*      */     }
/*      */
/* 1295 */     DEFAULT_ORDER = new String[0];
/*      */   }
/*      */
/*      */   private static enum PropertyGroup
/*      */   {
/*      */     final int allowedsecondaryAnnotations;
/*      */
/*      */     private PropertyGroup(boolean[] bits)
/*      */     {
/*  622 */       int mask = 0;
/*  623 */       assert (bits.length == ClassInfoImpl.SECONDARY_ANNOTATIONS.length);
/*  624 */       for (int i = 0; i < bits.length; i++) {
/*  625 */         if (bits[i] != 0)
/*  626 */           mask |= ClassInfoImpl.SECONDARY_ANNOTATIONS[i].bitMask;
/*      */       }
/*  628 */       this.allowedsecondaryAnnotations = (mask ^ 0xFFFFFFFF);
/*      */     }
/*      */
/*      */     boolean allows(ClassInfoImpl.SecondaryAnnotation a) {
/*  632 */       return (this.allowedsecondaryAnnotations & a.bitMask) == 0;
/*      */     }
/*      */
/*      */     static
/*      */     {
/*  606 */       TRANSIENT = new PropertyGroup("TRANSIENT", 0, new boolean[] { false, false, false, false, false, false });
/*  607 */       ANY_ATTRIBUTE = new PropertyGroup("ANY_ATTRIBUTE", 1, new boolean[] { true, false, false, false, false, false });
/*  608 */       ATTRIBUTE = new PropertyGroup("ATTRIBUTE", 2, new boolean[] { true, true, true, false, true, true });
/*  609 */       VALUE = new PropertyGroup("VALUE", 3, new boolean[] { true, true, true, false, true, true });
/*  610 */       ELEMENT = new PropertyGroup("ELEMENT", 4, new boolean[] { true, true, true, true, true, true });
/*  611 */       ELEMENT_REF = new PropertyGroup("ELEMENT_REF", 5, new boolean[] { true, false, false, true, false, false });
/*  612 */       MAP = new PropertyGroup("MAP", 6, new boolean[] { false, false, false, true, false, false });
/*      */
/*  605 */       $VALUES = new PropertyGroup[] { TRANSIENT, ANY_ATTRIBUTE, ATTRIBUTE, VALUE, ELEMENT, ELEMENT_REF, MAP };
/*      */     }
/*      */   }
/*      */
/*      */   private static enum SecondaryAnnotation
/*      */   {
/*  574 */     JAVA_TYPE(1, new Class[] { XmlJavaTypeAdapter.class }),
/*  575 */     ID_IDREF(2, new Class[] { XmlID.class, XmlIDREF.class }),
/*  576 */     BINARY(4, new Class[] { XmlInlineBinaryData.class, XmlMimeType.class, XmlAttachmentRef.class }),
/*  577 */     ELEMENT_WRAPPER(8, new Class[] { XmlElementWrapper.class }),
/*  578 */     LIST(16, new Class[] { XmlList.class }),
/*  579 */     SCHEMA_TYPE(32, new Class[] { XmlSchemaType.class });
/*      */
/*      */     final int bitMask;
/*      */     final Class<? extends Annotation>[] members;
/*      */
/*      */     private SecondaryAnnotation(int bitMask, Class<? extends Annotation>[] members)
/*      */     {
/*  592 */       this.bitMask = bitMask;
/*  593 */       this.members = members;
/*      */     }
/*      */   }
/*      */
/*      */   private static final class DupliateException extends Exception
/*      */   {
/*      */     final Annotation a1;
/*      */     final Annotation a2;
/*      */
/*      */     public DupliateException(Annotation a1, Annotation a2)
/*      */     {
/*  565 */       this.a1 = a1;
/*  566 */       this.a2 = a2;
/*      */     }
/*      */   }
/*      */
/*      */   private static final class ConflictException extends Exception
/*      */   {
/*      */     final List<Annotation> annotations;
/*      */
/*      */     public ConflictException(List<Annotation> one)
/*      */     {
/*  558 */       this.annotations = one;
/*      */     }
/*      */   }
/*      */
/*      */   private final class PropertySorter extends HashMap<String, Integer>
/*      */     implements Comparator<PropertyInfoImpl>
/*      */   {
/*  455 */     PropertyInfoImpl[] used = new PropertyInfoImpl[ClassInfoImpl.this.propOrder.length];
/*      */     private Set<String> collidedNames;
/*      */
/*      */     PropertySorter()
/*      */     {
/*  464 */       super();
/*  465 */       for (String name : ClassInfoImpl.this.propOrder) {
/*  466 */         if (put(name, Integer.valueOf(size())) == null)
/*      */           continue;
/*  468 */         ClassInfoImpl.this.builder.reportError(new IllegalAnnotationException(Messages.DUPLICATE_ENTRY_IN_PROP_ORDER.format(new Object[] { name }), ClassInfoImpl.this));
/*      */       }
/*      */     }
/*      */
/*      */     public int compare(PropertyInfoImpl o1, PropertyInfoImpl o2)
/*      */     {
/*  474 */       int lhs = checkedGet(o1);
/*  475 */       int rhs = checkedGet(o2);
/*      */
/*  477 */       return lhs - rhs;
/*      */     }
/*      */
/*      */     private int checkedGet(PropertyInfoImpl p) {
/*  481 */       Integer i = (Integer)get(p.getName());
/*  482 */       if (i == null)
/*      */       {
/*  484 */         if (p.kind().isOrdered) {
/*  485 */           ClassInfoImpl.this.builder.reportError(new IllegalAnnotationException(Messages.PROPERTY_MISSING_FROM_ORDER.format(new Object[] { p.getName() }), p));
/*      */         }
/*      */
/*  489 */         i = Integer.valueOf(size());
/*  490 */         put(p.getName(), i);
/*      */       }
/*      */
/*  494 */       int ii = i.intValue();
/*  495 */       if (ii < this.used.length) {
/*  496 */         if ((this.used[ii] != null) && (this.used[ii] != p)) {
/*  497 */           if (this.collidedNames == null) this.collidedNames = new HashSet();
/*      */
/*  499 */           if (this.collidedNames.add(p.getName()))
/*      */           {
/*  501 */             ClassInfoImpl.this.builder.reportError(new IllegalAnnotationException(Messages.DUPLICATE_PROPERTIES.format(new Object[] { p.getName() }), p, this.used[ii]));
/*      */           }
/*      */         }
/*  504 */         this.used[ii] = p;
/*      */       }
/*      */
/*  507 */       return i.intValue();
/*      */     }
/*      */
/*      */     public void checkUnusedProperties()
/*      */     {
/*  514 */       for (int i = 0; i < this.used.length; i++)
/*  515 */         if (this.used[i] == null) {
/*  516 */           String unusedName = ClassInfoImpl.this.propOrder[i];
/*  517 */           String nearest = EditDistance.findNearest(unusedName, new AbstractList() {
/*      */             public String get(int index) {
/*  519 */               return ((PropertyInfoImpl)ClassInfoImpl.this.properties.get(index)).getName();
/*      */             }
/*      */
/*      */             public int size() {
/*  523 */               return ClassInfoImpl.this.properties.size();
/*      */             }
/*      */           });
/*  526 */           ClassInfoImpl.this.builder.reportError(new IllegalAnnotationException(Messages.PROPERTY_ORDER_CONTAINS_UNUSED_ENTRY.format(new Object[] { unusedName, nearest }), ClassInfoImpl.this));
/*      */         }
/*      */     }
/*      */   }
/*      */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/thirdparty-all.jar
* Qualified Name:     com.sun.xml.bind.v2.model.impl.ClassInfoImpl
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of com.sun.xml.bind.v2.model.impl.ClassInfoImpl

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.