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 javax.xml.XMLConstants;
  29 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  30 import javax.xml.namespace.QName;
  31 
  32 import com.sun.tools.internal.xjc.model.nav.NClass;
  33 import com.sun.tools.internal.xjc.model.nav.NType;
  34 import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
  35 import com.sun.xml.internal.bind.v2.model.core.PropertyInfo;
  36 import com.sun.xml.internal.bind.v2.model.core.TypeRef;
  37 import com.sun.xml.internal.bind.v2.runtime.RuntimeUtil;
  38 import com.sun.xml.internal.xsom.XSType;
  39 import com.sun.xml.internal.xsom.XmlString;
  40 import com.sun.xml.internal.xsom.XSElementDecl;
  41 import com.sun.istack.internal.Nullable;
  42 
  43 /**
  44  * {@link TypeRef} for XJC.
  45  *
  46  * TODO: do we need the source schema component support here?
  47  *
  48  * @author Kohsuke Kawaguchi
  49  */
  50 public final class CTypeRef implements TypeRef<NType,NClass> {
  51     /**
  52      * In-memory type.
  53      *
  54      * This is the type used when
  55      */
  56     @XmlJavaTypeAdapter(RuntimeUtil.ToStringAdapter.class)
  57     private final CNonElement type;
  58 
  59     private final QName elementName;
  60 
  61     /**
  62      * XML Schema type name of {@link #type}, if available.
  63      */
  64     /*package*/ final @Nullable QName typeName;
  65 
  66     private final boolean nillable;
  67     public final XmlString defaultValue;
  68 
  69     public CTypeRef(CNonElement type, XSElementDecl decl) {
  70         this(type, BGMBuilder.getName(decl),getSimpleTypeName(decl), decl.isNillable(), decl.getDefaultValue() );
  71 
  72     }
  73 
  74     public QName getTypeName() {
  75         return typeName;
  76     }
  77 
  78     public static QName getSimpleTypeName(XSElementDecl decl) {
  79         if(decl==null || !decl.getType().isSimpleType())
  80             return null; // null if not simple type
  81         return resolveSimpleTypeName(decl.getType());
  82     }
  83 
  84     /**
  85      * Recursively search for type name.
  86      *
  87      * This is needed to find correct type for refs like:
  88      *
  89      *<xs:simpleType name="parent">
  90      *  <xs:restriction base="xs:date"/>
  91      *</xs:simpleType>
  92      *<xs:simpleType name="child">
  93      *  <xs:restriction base="parent"/>
  94      *</xs:simpleType>
  95      *
  96      *<xs:element name="testField" type="child"/>
  97      *
  98      * @param declType given type
  99      * @return simpleTypeName or null
 100      */
 101     private static QName resolveSimpleTypeName(XSType declType) {
 102         QName name = BGMBuilder.getName(declType);
 103         if (name != null && !XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(name.getNamespaceURI()))
 104             return resolveSimpleTypeName(declType.getBaseType());
 105         else
 106             return name;
 107     }
 108 
 109     public CTypeRef(CNonElement type, QName elementName, QName typeName, boolean nillable, XmlString defaultValue) {
 110         assert type!=null;
 111         assert elementName!=null;
 112 
 113         this.type = type;
 114         this.elementName = elementName;
 115         this.typeName = typeName;
 116         this.nillable = nillable;
 117         this.defaultValue = defaultValue;
 118     }
 119 
 120     public CNonElement getTarget() {
 121         return type;
 122     }
 123 
 124     public QName getTagName() {
 125         return elementName;
 126     }
 127 
 128     public boolean isNillable() {
 129         return nillable;
 130     }
 131 
 132     /**
 133      * Inside XJC, use {@link #defaultValue} that has context information.
 134      * This method is to override the one defined in the runtime model.
 135      *
 136      * @see #defaultValue
 137      */
 138     public String getDefaultValue() {
 139         if(defaultValue!=null)
 140             return defaultValue.value;
 141         else
 142             return null;
 143     }
 144 
 145     public boolean isLeaf() {
 146         // TODO: implement this method later
 147         throw new UnsupportedOperationException();
 148     }
 149 
 150     public PropertyInfo<NType, NClass> getSource() {
 151         // TODO: implement this method later
 152         throw new UnsupportedOperationException();
 153     }
 154 }