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
26package com.sun.tools.internal.xjc.reader.dtd.bindinfo;
27
28import java.util.ArrayList;
29
30import com.sun.codemodel.internal.JClass;
31import com.sun.tools.internal.xjc.Options;
32import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
33
34import org.w3c.dom.Element;
35
36/**
37 * Particles in the {@code <content>} declaration in the binding file.
38 *
39 */
40public class BIContent
41{
42    /**
43     * Wraps a given particle.
44     *
45     * <p>
46     * This object should be created through
47     * the {@link #create(Element, BIElement)} method.
48     */
49    private BIContent( Element e, BIElement _parent ) {
50        this.element = e;
51        this.parent = _parent;
52        this.opts = parent.parent.model.options;
53    }
54
55    /** The particle element which this object is wrapping. */
56    protected final Element element;
57
58    /** The parent object.*/
59    protected final BIElement parent;
60
61    private final Options opts;
62
63    /**
64     * Gets the realization of this particle, if any.
65     *
66     * @return
67     *      null if the "collection" attribute was not specified.
68     */
69    public final FieldRenderer getRealization() {
70        String v = DOMUtil.getAttribute(element,"collection");
71        if(v==null)     return null;
72
73        v = v.trim();
74        if(v.equals("array"))   return opts.getFieldRendererFactory().getArray();
75        if(v.equals("list"))
76            return opts.getFieldRendererFactory().getList(
77                parent.parent.codeModel.ref(ArrayList.class));
78
79        // the correctness of the attribute value must be
80        // checked by the validator.
81        throw new InternalError("unexpected collection value: "+v);
82    }
83
84    /**
85     * Gets the property name of this particle.
86     *
87     * @return
88     *      always a non-null, valid string.
89     */
90    public final String getPropertyName() {
91        String r = DOMUtil.getAttribute(element,"property");
92
93        // in case of <element-ref>, @property is optional and
94        // defaults to @name.
95        // in all other cases, @property is mandatory.
96        if(r!=null)     return r;
97        return DOMUtil.getAttribute(element,"name");
98    }
99
100    /**
101     * Gets the type of this property, if any.
102     * <p>
103     * {@code <element-ref>} particle doesn't have the type.
104     *
105     * @return
106     *      null if none is specified.
107     */
108    public final JClass getType() {
109        try {
110            String type = DOMUtil.getAttribute(element,"supertype");
111            if(type==null)     return null;
112
113            // TODO: does this attribute defaults to the current package?
114            int idx = type.lastIndexOf('.');
115            if(idx<0)   return parent.parent.codeModel.ref(type);
116            else        return parent.parent.getTargetPackage().ref(type);
117        } catch( ClassNotFoundException e ) {
118            // TODO: better error handling
119            throw new NoClassDefFoundError(e.getMessage());
120        }
121    }
122
123
124
125
126
127    /**
128     * Creates an appropriate subclass of BIContent
129     * by sniffing the tag name.
130     * <p>
131     * This method should be only called by the BIElement class.
132     */
133    static BIContent create( Element e, BIElement _parent ) {
134        return new BIContent(e,_parent);
135    }
136
137
138}
139