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 */ 25 26 package com.sun.tools.internal.xjc.model; 27 28 import java.util.AbstractList; 29 import java.util.ArrayList; 30 import java.util.List; 31 import java.util.Map; 32 33 import javax.activation.MimeType; 34 import javax.xml.namespace.QName; 35 36 import com.sun.tools.internal.xjc.model.nav.NClass; 37 import com.sun.tools.internal.xjc.model.nav.NType; 38 import com.sun.tools.internal.xjc.reader.RawTypeSet; 39 import com.sun.xml.internal.bind.v2.model.core.ElementPropertyInfo; 40 import com.sun.xml.internal.bind.v2.model.core.ID; 41 import com.sun.xml.internal.bind.v2.model.core.PropertyKind; 42 import com.sun.xml.internal.xsom.XSComponent; 43 44 import org.xml.sax.Locator; 45 46 /** 47 * {@link ElementPropertyInfo} for the compiler. 48 * 49 * @author Kohsuke Kawaguchi 50 */ 51 public final class CElementPropertyInfo extends CPropertyInfo implements ElementPropertyInfo<NType,NClass> { 52 53 /** 54 * True if this property can never be absent legally. 55 */ 56 private final boolean required; 57 58 private final MimeType expectedMimeType; 59 /** 60 * 61 * <p> 62 * Currently, this is set inside {@link RawTypeSet} in a very ugly way. 63 */ 64 private CAdapter adapter; 65 66 private final boolean isValueList; 67 68 private ID id; 69 70 71 /** 72 * List of referenced types. 73 */ 74 private final List<CTypeRef> types = new ArrayList<CTypeRef>(); 75 76 private final List<CNonElement> ref = new AbstractList<CNonElement>() { 77 public CNonElement get(int index) { 78 return getTypes().get(index).getTarget(); 79 } 80 public int size() { 81 return getTypes().size(); 82 } 83 }; 84 85 // TODO: shouldn't they get id and expectedMimeType from TypeUses of CTypeRef? 86 public CElementPropertyInfo(String name, CollectionMode collection, ID id, MimeType expectedMimeType, XSComponent source, 87 CCustomizations customizations, Locator locator, boolean required) { 88 super(name, collection.col, source, customizations, locator); 89 this.required = required; 90 this.id = id; 91 this.expectedMimeType = expectedMimeType; 92 this.isValueList = collection.val; 93 } 94 95 public ID id() { 96 return id; 97 } 98 99 public List<CTypeRef> getTypes() { 100 return types; 101 } 102 103 public List<CNonElement> ref() { 104 return ref; 105 } 106 107 public QName getSchemaType() { 108 if(types.size()!=1) 109 // if more than one kind is here, can't produce @XmlSchemaType. 110 // TODO: is it allowed to have one generated if types 111 return null; 112 113 CTypeRef t = types.get(0); 114 if(needsExplicitTypeName(t.getTarget(),t.typeName)) 115 return t.typeName; 116 else 117 return null; 118 } 119 120 /** 121 * XJC never uses the wrapper element. Always return null. 122 */ 123 @Deprecated 124 public QName getXmlName() { 125 return null; 126 } 127 128 public boolean isCollectionRequired() { 129 // in XJC, we never recognize a nillable collection pattern, so this is always false. 130 return false; 131 } 132 133 public boolean isCollectionNillable() { 134 // in XJC, we never recognize a nillable collection pattern, so this is always false. 135 return false; 136 } 137 138 public boolean isRequired() { 139 return required; 140 } 141 142 public boolean isValueList() { 143 return isValueList; 144 } 145 146 public boolean isUnboxable() { 147 if(!isCollection() && !required) 148 // if the property can be legally absent, it's not unboxable 149 return false; 150 // we need to have null to represent the absence of value. not unboxable. 151 for (CTypeRef t : getTypes()) { 152 if(t.isNillable()) 153 return false; 154 } 155 return super.isUnboxable(); 156 } 157 158 @Override 159 public boolean isOptionalPrimitive() { 160 // we need to have null to represent the absence of value. not unboxable. 161 for (CTypeRef t : getTypes()) { 162 if(t.isNillable()) 163 return false; 164 } 165 return !isCollection() && !required && super.isUnboxable(); 166 } 167 168 public <V> V accept(CPropertyVisitor<V> visitor) { 169 return visitor.onElement(this); 170 } 171 172 public CAdapter getAdapter() { 173 return adapter; 174 } 175 176 public void setAdapter(CAdapter a) { 177 assert adapter==null; 178 adapter = a; 179 } 180 181 public final PropertyKind kind() { 182 return PropertyKind.ELEMENT; 183 } 184 185 public MimeType getExpectedMimeType() { 186 return expectedMimeType; 187 } 188 189 public static enum CollectionMode { 190 NOT_REPEATED(false,false), 191 REPEATED_ELEMENT(true,false), 192 REPEATED_VALUE(true,true); 193 194 private final boolean col,val; 195 196 CollectionMode(boolean col,boolean val) { 197 this.col = col; 198 this.val = val; 199 } 200 201 public boolean isRepeated() { return col; } 202 } 203 204 @Override 205 public QName collectElementNames(Map<QName, CPropertyInfo> table) { 206 for (CTypeRef t : types) { 207 QName n = t.getTagName(); 208 if(table.containsKey(n)) return n; 209 table.put(n, this); 210 } 211 return null; 212 } 213 }