1/*
2 * Copyright (c) 1997, 2012, 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
26package com.sun.xml.internal.bind.v2.model.impl;
27
28import javax.xml.bind.annotation.XmlRootElement;
29import javax.xml.bind.annotation.XmlSchema;
30import javax.xml.bind.annotation.XmlType;
31import javax.xml.namespace.QName;
32
33import com.sun.xml.internal.bind.api.impl.NameConverter;
34import com.sun.xml.internal.bind.v2.model.annotation.AnnotationReader;
35import com.sun.xml.internal.bind.v2.model.annotation.Locatable;
36import com.sun.xml.internal.bind.v2.model.core.TypeInfo;
37import com.sun.xml.internal.bind.v2.model.core.TypeInfoSet;
38import com.sun.xml.internal.bind.v2.model.nav.Navigator;
39
40/**
41 * Common implementation between {@link ClassInfoImpl} and {@link ElementInfoImpl}.
42 *
43 * @author Kohsuke Kawaguchi
44 */
45abstract class TypeInfoImpl<TypeT,ClassDeclT,FieldT,MethodT>
46        implements TypeInfo<TypeT,ClassDeclT>, Locatable {
47
48    /**
49     * The Java class that caused this Java class to be a part of the JAXB processing.
50     *
51     * null if it's specified explicitly by the user.
52     */
53    private final Locatable upstream;
54
55    /**
56     * {@link TypeInfoSet} to which this class belongs.
57     */
58    protected final TypeInfoSetImpl<TypeT,ClassDeclT,FieldT,MethodT> owner;
59
60    /**
61     * Reference to the {@link ModelBuilder}, only until we link {@link TypeInfo}s all together,
62     * because we don't want to keep {@link ModelBuilder} too long.
63     */
64    protected ModelBuilder<TypeT,ClassDeclT,FieldT,MethodT> builder;
65
66    protected TypeInfoImpl(
67        ModelBuilder<TypeT,ClassDeclT,FieldT,MethodT> builder,
68        Locatable upstream) {
69
70        this.builder = builder;
71        this.owner = builder.typeInfoSet;
72        this.upstream = upstream;
73    }
74
75    public Locatable getUpstream() {
76        return upstream;
77    }
78
79    /*package*/ void link() {
80        builder = null;
81    }
82
83    protected final Navigator<TypeT,ClassDeclT,FieldT,MethodT> nav() {
84        return owner.nav;
85    }
86
87    protected final AnnotationReader<TypeT,ClassDeclT,FieldT,MethodT> reader() {
88        return owner.reader;
89    }
90
91    /**
92     * Parses an {@link XmlRootElement} annotation on a class
93     * and determine the element name.
94     *
95     * @return null
96     *      if none was found.
97     */
98    protected final QName parseElementName(ClassDeclT clazz) {
99        XmlRootElement e = reader().getClassAnnotation(XmlRootElement.class,clazz,this);
100        if(e==null)
101            return null;
102
103        String local = e.name();
104        if(local.equals("##default")) {
105            // if defaulted...
106            local = NameConverter.standard.toVariableName(nav().getClassShortName(clazz));
107        }
108        String nsUri = e.namespace();
109        if(nsUri.equals("##default")) {
110            // if defaulted ...
111            XmlSchema xs = reader().getPackageAnnotation(XmlSchema.class,clazz,this);
112            if(xs!=null)
113                nsUri = xs.namespace();
114            else {
115                nsUri = builder.defaultNsUri;
116            }
117        }
118
119        return new QName(nsUri.intern(),local.intern());
120    }
121
122    protected final QName parseTypeName(ClassDeclT clazz) {
123        return parseTypeName( clazz, reader().getClassAnnotation(XmlType.class,clazz,this) );
124    }
125
126    /**
127     * Parses a (potentially-null) {@link XmlType} annotation on a class
128     * and determine the actual value.
129     *
130     * @param clazz
131     *      The class on which the XmlType annotation is checked.
132     * @param t
133     *      The {@link XmlType} annotation on the clazz. This value
134     *      is taken as a parameter to improve the performance for the case where
135     *      't' is pre-computed.
136     */
137    protected final QName parseTypeName(ClassDeclT clazz, XmlType t) {
138        String nsUri="##default";
139        String local="##default";
140        if(t!=null) {
141            nsUri = t.namespace();
142            local = t.name();
143        }
144
145        if(local.length()==0)
146            return null; // anonymous
147
148
149        if(local.equals("##default"))
150            // if defaulted ...
151            local = NameConverter.standard.toVariableName(nav().getClassShortName(clazz));
152
153        if(nsUri.equals("##default")) {
154            // if defaulted ...
155            XmlSchema xs = reader().getPackageAnnotation(XmlSchema.class,clazz,this);
156            if(xs!=null)
157                nsUri = xs.namespace();
158            else {
159                nsUri = builder.defaultNsUri;
160            }
161        }
162
163        return new QName(nsUri.intern(),local.intern());
164    }
165}
166