1 /* 2 * Copyright (c) 1997, 2015, 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.Collection; 29 30 import javax.activation.MimeType; 31 import javax.xml.namespace.QName; 32 33 import com.sun.codemodel.internal.JClass; 34 import com.sun.codemodel.internal.JExpression; 35 import com.sun.tools.internal.xjc.model.nav.NClass; 36 import com.sun.tools.internal.xjc.model.nav.NType; 37 import com.sun.tools.internal.xjc.outline.Aspect; 38 import com.sun.tools.internal.xjc.outline.Outline; 39 import com.sun.xml.internal.bind.v2.model.annotation.Locatable; 40 import com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo; 41 import com.sun.xml.internal.bind.v2.model.core.ID; 42 import com.sun.xml.internal.bind.v2.model.core.NonElement; 43 import com.sun.xml.internal.bind.v2.model.core.Element; 44 import com.sun.xml.internal.bind.v2.runtime.Location; 45 import com.sun.xml.internal.xsom.XSComponent; 46 import com.sun.xml.internal.xsom.XmlString; 47 48 import org.xml.sax.Locator; 49 50 /** 51 * Transducer that converts a string into an "enumeration class." 52 * 53 * The structure of the generated class needs to precisely 54 * follow the JAXB spec. 55 * 56 * @author Kohsuke KAWAGUCHI 57 */ 58 public final class CEnumLeafInfo implements EnumLeafInfo<NType,NClass>, NClass, CNonElement 59 { 60 /** 61 * The {@link Model} object to which this bean belongs. 62 */ 63 public final Model model; 64 65 /** 66 * The parent into which the enum class should be generated. 67 */ 68 public final CClassInfoParent parent; 69 70 /** 71 * Short name of the generated type-safe enum. 72 */ 73 public final String shortName; 74 75 private final QName typeName; 76 77 private final XSComponent source; 78 79 /** 80 * Represents the underlying type of this enumeration 81 * and its conversion. 82 * 83 * <p> 84 * To parse XML into a constant, we use the base type 85 * to do {@code lexical -> value}, then use a map to pick up the right one. 86 * 87 * <p> 88 * Hence this also represents the type of the Java value. 89 * For example, if this is an enumeration of xs:int, 90 * then this field will be Java int. 91 */ 92 public final CNonElement base; 93 94 95 /** 96 * List of enum members. 97 */ 98 public final Collection<CEnumConstant> members; 99 100 private final CCustomizations customizations; 101 102 /** 103 * @see #getLocator() 104 */ 105 private final Locator sourceLocator; 106 107 public String javadoc; 108 109 public CEnumLeafInfo(Model model, 110 QName typeName, 111 CClassInfoParent container, 112 String shortName, 113 CNonElement base, 114 Collection<CEnumConstant> _members, 115 XSComponent source, 116 CCustomizations customizations, 117 Locator _sourceLocator) { 118 this.model = model; 119 this.parent = container; 120 this.shortName = model.allocator.assignClassName(parent,shortName); 121 this.base = base; 122 this.members = _members; 123 this.source = source; 124 if(customizations==null) 125 customizations = CCustomizations.EMPTY; 126 this.customizations = customizations; 127 this.sourceLocator = _sourceLocator; 128 this.typeName = typeName; 129 130 for( CEnumConstant mem : members ) 131 mem.setParent(this); 132 133 model.add(this); 134 135 // TODO: can we take advantage of the fact that enum can be XmlRootElement? 136 } 137 138 /** 139 * Source line information that points to the place 140 * where this type-safe enum is defined. 141 * Used to report error messages. 142 */ 143 public Locator getLocator() { 144 return sourceLocator; 145 } 146 147 public QName getTypeName() { 148 return typeName; 149 } 150 151 public NType getType() { 152 return this; 153 } 154 155 /** 156 * @deprecated 157 * why are you calling the method whose return value is known? 158 */ 159 public boolean canBeReferencedByIDREF() { 160 return false; 161 } 162 163 public boolean isElement() { 164 return false; 165 } 166 167 public QName getElementName() { 168 return null; 169 } 170 171 public Element<NType,NClass> asElement() { 172 return null; 173 } 174 175 public NClass getClazz() { 176 return this; 177 } 178 179 public XSComponent getSchemaComponent() { 180 return source; 181 } 182 183 public JClass toType(Outline o, Aspect aspect) { 184 return o.getEnum(this).clazz; 185 } 186 187 public boolean isAbstract() { 188 return false; 189 } 190 191 public boolean isBoxedType() { 192 return false; 193 } 194 195 public String fullName() { 196 return parent.fullName()+'.'+shortName; 197 } 198 199 public boolean isPrimitive() { 200 return false; 201 } 202 203 public boolean isSimpleType() { 204 return true; 205 } 206 207 208 /** 209 * The spec says the value field in the enum class will be generated 210 * only under certain circumstances. 211 * 212 * @return 213 * true if the generated enum class should have the value field. 214 */ 215 public boolean needsValueField() { 216 for (CEnumConstant cec : members) { 217 if(!cec.getName().equals(cec.getLexicalValue())) 218 return true; 219 } 220 return false; 221 } 222 223 public JExpression createConstant(Outline outline, XmlString literal) { 224 // correctly identifying which constant it maps to is hard, so 225 // here I'm cheating 226 JClass type = toType(outline,Aspect.EXPOSED); 227 for (CEnumConstant mem : members) { 228 if(mem.getLexicalValue().equals(literal.value)) 229 return type.staticRef(mem.getName()); 230 } 231 return null; 232 } 233 234 @Deprecated 235 public boolean isCollection() { 236 return false; 237 } 238 239 @Deprecated 240 public CAdapter getAdapterUse() { 241 return null; 242 } 243 244 @Deprecated 245 public CNonElement getInfo() { 246 return this; 247 } 248 249 public ID idUse() { 250 return ID.NONE; 251 } 252 253 public MimeType getExpectedMimeType() { 254 return null; 255 } 256 257 public Collection<CEnumConstant> getConstants() { 258 return members; 259 } 260 261 public NonElement<NType,NClass> getBaseType() { 262 return base; 263 } 264 265 public CCustomizations getCustomizations() { 266 return customizations; 267 } 268 269 public Locatable getUpstream() { 270 throw new UnsupportedOperationException(); 271 } 272 273 public Location getLocation() { 274 throw new UnsupportedOperationException(); 275 } 276 }