--- old/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/model/impl/ElementInfoImpl.java 2018-01-30 20:32:07.000000000 -0500 +++ /dev/null 2018-01-30 20:32:07.000000000 -0500 @@ -1,430 +0,0 @@ -/* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.xml.internal.bind.v2.model.impl; - -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import javax.activation.MimeType; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAttachmentRef; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlID; -import javax.xml.bind.annotation.XmlIDREF; -import javax.xml.bind.annotation.XmlInlineBinaryData; -import javax.xml.bind.annotation.XmlSchema; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.namespace.QName; - -import com.sun.istack.internal.FinalArrayList; -import com.sun.xml.internal.bind.v2.TODO; -import com.sun.xml.internal.bind.v2.model.annotation.AnnotationSource; -import com.sun.xml.internal.bind.v2.model.annotation.Locatable; -import com.sun.xml.internal.bind.v2.model.core.Adapter; -import com.sun.xml.internal.bind.v2.model.core.ClassInfo; -import com.sun.xml.internal.bind.v2.model.core.ElementInfo; -import com.sun.xml.internal.bind.v2.model.core.ElementPropertyInfo; -import com.sun.xml.internal.bind.v2.model.core.ID; -import com.sun.xml.internal.bind.v2.model.core.NonElement; -import com.sun.xml.internal.bind.v2.model.core.PropertyInfo; -import com.sun.xml.internal.bind.v2.model.core.PropertyKind; -import com.sun.xml.internal.bind.v2.model.core.TypeInfo; -import com.sun.xml.internal.bind.v2.model.core.TypeRef; -import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException; -import com.sun.xml.internal.bind.v2.runtime.Location; -import com.sun.xml.internal.bind.v2.runtime.SwaRefAdapter; - -/** - * {@link ElementInfo} implementation. - * - * @author Kohsuke Kawaguchi - */ -class ElementInfoImpl extends TypeInfoImpl implements ElementInfo { - - private final QName tagName; - - private final NonElement contentType; - - private final T tOfJAXBElementT; - - private final T elementType; - - private final ClassInfo scope; - - /** - * Annotation that controls the binding. - */ - private final XmlElementDecl anno; - - /** - * If this element can substitute another element, the element name. - * @see #link() - */ - private ElementInfoImpl substitutionHead; - - /** - * Lazily constructed list of {@link ElementInfo}s that can substitute this element. - * This could be null. - * @see #link() - */ - private FinalArrayList> substitutionMembers; - - /** - * The factory method from which this mapping was created. - */ - private final M method; - - /** - * If the content type is adapter, return that adapter. - */ - private final Adapter adapter; - - private final boolean isCollection; - - private final ID id; - - private final PropertyImpl property; - private final MimeType expectedMimeType; - private final boolean inlineBinary; - private final QName schemaType; - - /** - * Singleton instance of {@link ElementPropertyInfo} for this element. - */ - protected class PropertyImpl implements - ElementPropertyInfo, - TypeRef, - AnnotationSource { - // - // TypeRef impl - // - public NonElement getTarget() { - return contentType; - } - public QName getTagName() { - return tagName; - } - - public List> getTypes() { - return Collections.singletonList(this); - } - - public List> ref() { - return Collections.singletonList(contentType); - } - - public QName getXmlName() { - return tagName; - } - - public boolean isCollectionRequired() { - return false; - } - - public boolean isCollectionNillable() { - return true; - } - - public boolean isNillable() { - return true; - } - - public String getDefaultValue() { - String v = anno.defaultValue(); - if(v.equals("\u0000")) - return null; - else - return v; - } - - public ElementInfoImpl parent() { - return ElementInfoImpl.this; - } - - public String getName() { - return "value"; - } - - public String displayName() { - return "JAXBElement#value"; - } - - public boolean isCollection() { - return isCollection; - } - - /** - * For {@link ElementInfo}s, a collection always means a list of values. - */ - public boolean isValueList() { - return isCollection; - } - - public boolean isRequired() { - return true; - } - - public PropertyKind kind() { - return PropertyKind.ELEMENT; - } - - public Adapter getAdapter() { - return adapter; - } - - public ID id() { - return id; - } - - public MimeType getExpectedMimeType() { - return expectedMimeType; - } - - public QName getSchemaType() { - return schemaType; - } - - public boolean inlineBinaryData() { - return inlineBinary; - } - - public PropertyInfo getSource() { - return this; - } - - // - // - // AnnotationSource impl - // - // - public A readAnnotation(Class annotationType) { - return reader().getMethodAnnotation(annotationType,method,ElementInfoImpl.this); - } - - public boolean hasAnnotation(Class annotationType) { - return reader().hasMethodAnnotation(annotationType,method); - } - } - - /** - * @param m - * The factory method on ObjectFactory that comes with {@link XmlElementDecl}. - */ - public ElementInfoImpl(ModelBuilder builder, - RegistryInfoImpl registry, M m ) throws IllegalAnnotationException { - super(builder,registry); - - this.method = m; - anno = reader().getMethodAnnotation( XmlElementDecl.class, m, this ); - assert anno!=null; // the caller should check this - assert anno instanceof Locatable; - - elementType = nav().getReturnType(m); - T baseClass = nav().getBaseClass(elementType,nav().asDecl(JAXBElement.class)); - if(baseClass==null) - throw new IllegalAnnotationException( - Messages.XML_ELEMENT_MAPPING_ON_NON_IXMLELEMENT_METHOD.format(nav().getMethodName(m)), - anno ); - - tagName = parseElementName(anno); - T[] methodParams = nav().getMethodParameters(m); - - // adapter - Adapter a = null; - if(methodParams.length>0) { - XmlJavaTypeAdapter adapter = reader().getMethodAnnotation(XmlJavaTypeAdapter.class,m,this); - if(adapter!=null) - a = new Adapter(adapter,reader(),nav()); - else { - XmlAttachmentRef xsa = reader().getMethodAnnotation(XmlAttachmentRef.class,m,this); - if(xsa!=null) { - TODO.prototype("in Annotation Processing swaRefAdapter isn't avaialble, so this returns null"); - a = new Adapter(owner.nav.asDecl(SwaRefAdapter.class),owner.nav); - } - } - } - this.adapter = a; - - // T of JAXBElement - tOfJAXBElementT = - methodParams.length>0 ? methodParams[0] // this is more reliable, as it works even for ObjectFactory that sometimes have to return public types - : nav().getTypeArgument(baseClass,0); // fall back to infer from the return type if no parameter. - - if(adapter==null) { - T list = nav().getBaseClass(tOfJAXBElementT,nav().asDecl(List.class)); - if(list==null) { - isCollection = false; - contentType = builder.getTypeInfo(tOfJAXBElementT,this); // suck this type into the current set. - } else { - isCollection = true; - contentType = builder.getTypeInfo(nav().getTypeArgument(list,0),this); - } - } else { - // but if adapted, use the adapted type - contentType = builder.getTypeInfo(this.adapter.defaultType,this); - isCollection = false; - } - - // scope - T s = reader().getClassValue(anno,"scope"); - if(nav().isSameType(s, nav().ref(XmlElementDecl.GLOBAL.class))) - scope = null; - else { - // TODO: what happens if there's an error? - NonElement scp = builder.getClassInfo(nav().asDecl(s),this); - if(!(scp instanceof ClassInfo)) { - throw new IllegalAnnotationException( - Messages.SCOPE_IS_NOT_COMPLEXTYPE.format(nav().getTypeName(s)), - anno ); - } - scope = (ClassInfo)scp; - } - - id = calcId(); - - property = createPropertyImpl(); - - this.expectedMimeType = Util.calcExpectedMediaType(property,builder); - this.inlineBinary = reader().hasMethodAnnotation(XmlInlineBinaryData.class,method); - this.schemaType = Util.calcSchemaType(reader(),property,registry.registryClass, - getContentInMemoryType(),this); - } - - final QName parseElementName(XmlElementDecl e) { - String local = e.name(); - String nsUri = e.namespace(); - if(nsUri.equals("##default")) { - // if defaulted ... - XmlSchema xs = reader().getPackageAnnotation(XmlSchema.class, - nav().getDeclaringClassForMethod(method),this); - if(xs!=null) - nsUri = xs.namespace(); - else { - nsUri = builder.defaultNsUri; - } - } - - return new QName(nsUri.intern(),local.intern()); - } - - protected PropertyImpl createPropertyImpl() { - return new PropertyImpl(); - } - - public ElementPropertyInfo getProperty() { - return property; - } - - public NonElement getContentType() { - return contentType; - } - - public T getContentInMemoryType() { - if(adapter==null) { - return tOfJAXBElementT; - } else { - return adapter.customType; - } - } - - public QName getElementName() { - return tagName; - } - - public T getType() { - return elementType; - } - - /** - * Leaf-type cannot be referenced from IDREF. - * - * @deprecated - * why are you calling a method whose return value is always known? - */ - public final boolean canBeReferencedByIDREF() { - return false; - } - - private ID calcId() { - // TODO: share code with PropertyInfoImpl - if(reader().hasMethodAnnotation(XmlID.class,method)) { - return ID.ID; - } else - if(reader().hasMethodAnnotation(XmlIDREF.class,method)) { - return ID.IDREF; - } else { - return ID.NONE; - } - } - - public ClassInfo getScope() { - return scope; - } - - public ElementInfo getSubstitutionHead() { - return substitutionHead; - } - - public Collection> getSubstitutionMembers() { - if(substitutionMembers==null) - return Collections.emptyList(); - else - return substitutionMembers; - } - - /** - * Called after all the {@link TypeInfo}s are collected into the {@link #owner}. - */ - /*package*/ void link() { - // substitution head - if(anno.substitutionHeadName().length()!=0) { - QName name = new QName( - anno.substitutionHeadNamespace(), anno.substitutionHeadName() ); - substitutionHead = owner.getElementInfo(null,name); - if(substitutionHead==null) { - builder.reportError( - new IllegalAnnotationException(Messages.NON_EXISTENT_ELEMENT_MAPPING.format( - name.getNamespaceURI(),name.getLocalPart()), anno)); - // recover by ignoring this substitution declaration - } else - substitutionHead.addSubstitutionMember(this); - } else - substitutionHead = null; - super.link(); - } - - private void addSubstitutionMember(ElementInfoImpl child) { - if(substitutionMembers==null) - substitutionMembers = new FinalArrayList>(); - substitutionMembers.add(child); - } - - public Location getLocation() { - return nav().getMethodLocation(method); - } -}