1 /*
   2  * Copyright (c) 1997, 2016, 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     public QName getTypeName() {
  74         return typeName;
  75     }
  76 
  77     public static QName getSimpleTypeName(XSElementDecl decl) {
  78         if(decl==null || !decl.getType().isSimpleType())
  79             return null; // null if not simple type
  80         return resolveSimpleTypeName(decl.getType());
  81     }
  82 
  83     /**
  84      * Recursively search for type name.
  85      *
  86      * This is needed to find correct type for refs like:
  87      *
  88      *<xs:simpleType name="parent">
  89      *  <xs:restriction base="xs:date"/>
  90      *</xs:simpleType>
  91      *<xs:simpleType name="child">
  92      *  <xs:restriction base="parent"/>
  93      *</xs:simpleType>
  94      *
  95      *<xs:element name="testField" type="child"/>
  96      *
  97      * @param declType given type
  98      * @return simpleTypeName or null
  99      */
 100     private static QName resolveSimpleTypeName(XSType declType) {
 101         QName name = BGMBuilder.getName(declType);
 102         QName result = null;
 103         if (name != null && !XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(name.getNamespaceURI())) {
 104             result = resolveSimpleTypeName(declType.getBaseType());
 105         } else {
 106             if ( !"anySimpleType".equals(declType.getName()) ) {
 107                 result = name;
 108             }
 109         }
 110         return result;
 111     }
 112 
 113     public CTypeRef(CNonElement type, QName elementName, QName typeName, boolean nillable, XmlString defaultValue) {
 114         assert type!=null;
 115         assert elementName!=null;
 116 
 117         this.type = type;
 118         this.elementName = elementName;
 119         this.typeName = typeName;
 120         this.nillable = nillable;
 121         this.defaultValue = defaultValue;
 122     }
 123 
 124     public CNonElement getTarget() {
 125         return type;
 126     }
 127 
 128     public QName getTagName() {
 129         return elementName;
 130     }
 131 
 132     public boolean isNillable() {
 133         return nillable;
 134     }
 135 
 136     /**
 137      * Inside XJC, use {@link #defaultValue} that has context information.
 138      * This method is to override the one defined in the runtime model.
 139      *
 140      * @see #defaultValue
 141      */
 142     public String getDefaultValue() {
 143         if(defaultValue!=null)
 144             return defaultValue.value;
 145         else
 146             return null;
 147     }
 148 
 149     public boolean isLeaf() {
 150         // TODO: implement this method later
 151         throw new UnsupportedOperationException();
 152     }
 153 
 154     public PropertyInfo<NType, NClass> getSource() {
 155         // TODO: implement this method later
 156         throw new UnsupportedOperationException();
 157     }
 158 }