Fri, 24 Oct 2014 15:02:28 +0200
8054367: More references for endpoints
Summary: fix also reviewed by Iaroslav.Savytskyi@oracle.com, Alexander.Fomin@oracle.com
Reviewed-by: mullan, skoivu
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.bind.v2.model.impl;
28 import java.util.AbstractList;
29 import java.util.Collections;
30 import java.util.List;
32 import javax.xml.bind.annotation.XmlElement;
33 import javax.xml.bind.annotation.XmlElements;
34 import javax.xml.bind.annotation.XmlList;
35 import javax.xml.namespace.QName;
37 import com.sun.istack.internal.FinalArrayList;
38 import com.sun.xml.internal.bind.v2.model.core.ElementPropertyInfo;
39 import com.sun.xml.internal.bind.v2.model.core.ID;
40 import com.sun.xml.internal.bind.v2.model.core.PropertyKind;
41 import com.sun.xml.internal.bind.v2.model.core.TypeInfo;
42 import com.sun.xml.internal.bind.v2.model.core.TypeRef;
43 import com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationException;
45 /**
46 * Common {@link ElementPropertyInfo} implementation used for both
47 * Annotation Processing and runtime.
48 *
49 * @author Kohsuke Kawaguchi
50 */
51 class ElementPropertyInfoImpl<TypeT,ClassDeclT,FieldT,MethodT>
52 extends ERPropertyInfoImpl<TypeT,ClassDeclT,FieldT,MethodT>
53 implements ElementPropertyInfo<TypeT,ClassDeclT>
54 {
55 /**
56 * Lazily computed.
57 * @see #getTypes()
58 */
59 private List<TypeRefImpl<TypeT,ClassDeclT>> types;
61 private final List<TypeInfo<TypeT,ClassDeclT>> ref = new AbstractList<TypeInfo<TypeT,ClassDeclT>>() {
62 public TypeInfo<TypeT,ClassDeclT> get(int index) {
63 return getTypes().get(index).getTarget();
64 }
66 public int size() {
67 return getTypes().size();
68 }
69 };
71 /**
72 * Lazily computed.
73 * @see #isRequired()
74 */
75 private Boolean isRequired;
77 /**
78 * @see #isValueList()
79 */
80 private final boolean isValueList;
82 ElementPropertyInfoImpl(
83 ClassInfoImpl<TypeT,ClassDeclT,FieldT,MethodT> parent,
84 PropertySeed<TypeT,ClassDeclT,FieldT,MethodT> propertySeed) {
85 super(parent, propertySeed);
87 isValueList = seed.hasAnnotation(XmlList.class);
89 }
91 public List<? extends TypeRefImpl<TypeT,ClassDeclT>> getTypes() {
92 if(types==null) {
93 types = new FinalArrayList<TypeRefImpl<TypeT,ClassDeclT>>();
94 XmlElement[] ann=null;
96 XmlElement xe = seed.readAnnotation(XmlElement.class);
97 XmlElements xes = seed.readAnnotation(XmlElements.class);
99 if(xe!=null && xes!=null) {
100 parent.builder.reportError(new IllegalAnnotationException(
101 Messages.MUTUALLY_EXCLUSIVE_ANNOTATIONS.format(
102 nav().getClassName(parent.getClazz())+'#'+seed.getName(),
103 xe.annotationType().getName(), xes.annotationType().getName()),
104 xe, xes ));
105 }
107 isRequired = true;
109 if(xe!=null)
110 ann = new XmlElement[]{xe};
111 else
112 if(xes!=null)
113 ann = xes.value();
115 if(ann==null) {
116 // default
117 TypeT t = getIndividualType();
118 if(!nav().isPrimitive(t) || isCollection())
119 isRequired = false;
120 // nillableness defaults to true if it's collection
121 types.add(createTypeRef(calcXmlName((XmlElement)null),t,isCollection(),null));
122 } else {
123 for( XmlElement item : ann ) {
124 // TODO: handle defaulting in names.
125 QName name = calcXmlName(item);
126 TypeT type = reader().getClassValue(item, "type");
127 if (nav().isSameType(type, nav().ref(XmlElement.DEFAULT.class)))
128 type = getIndividualType();
129 if((!nav().isPrimitive(type) || isCollection()) && !item.required())
130 isRequired = false;
131 types.add(createTypeRef(name, type, item.nillable(), getDefaultValue(item.defaultValue()) ));
132 }
133 }
134 types = Collections.unmodifiableList(types);
135 assert !types.contains(null);
136 }
137 return types;
138 }
140 private String getDefaultValue(String value) {
141 if(value.equals("\u0000"))
142 return null;
143 else
144 return value;
145 }
147 /**
148 * Used by {@link PropertyInfoImpl} to create new instances of {@link TypeRef}
149 */
150 protected TypeRefImpl<TypeT,ClassDeclT> createTypeRef(QName name,TypeT type,boolean isNillable,String defaultValue) {
151 return new TypeRefImpl<TypeT,ClassDeclT>(this,name,type,isNillable,defaultValue);
152 }
154 public boolean isValueList() {
155 return isValueList;
156 }
158 public boolean isRequired() {
159 if(isRequired==null)
160 getTypes(); // compute the value
161 return isRequired;
162 }
164 public List<? extends TypeInfo<TypeT,ClassDeclT>> ref() {
165 return ref;
166 }
168 public final PropertyKind kind() {
169 return PropertyKind.ELEMENT;
170 }
172 protected void link() {
173 super.link();
174 for (TypeRefImpl<TypeT, ClassDeclT> ref : getTypes() ) {
175 ref.link();
176 }
178 if(isValueList()) {
179 // ugly test, because IDREF's are represented as text on the wire,
180 // it's OK to be a value list in that case.
181 if(id()!= ID.IDREF) {
182 // check if all the item types are simple types
183 // this can't be done when we compute types because
184 // not all TypeInfos are available yet
185 for (TypeRefImpl<TypeT,ClassDeclT> ref : types) {
186 if(!ref.getTarget().isSimpleType()) {
187 parent.builder.reportError(new IllegalAnnotationException(
188 Messages.XMLLIST_NEEDS_SIMPLETYPE.format(
189 nav().getTypeName(ref.getTarget().getType())), this ));
190 break;
191 }
192 }
193 }
195 if(!isCollection())
196 parent.builder.reportError(new IllegalAnnotationException(
197 Messages.XMLLIST_ON_SINGLE_PROPERTY.format(), this
198 ));
199 }
200 }
201 }