001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.tools.xjc.reader.dtd.bindinfo;
037:
038: import java.util.ArrayList;
039: import java.util.HashMap;
040: import java.util.List;
041: import java.util.Map;
042:
043: import javax.xml.namespace.QName;
044:
045: import com.sun.tools.xjc.model.CClassInfo;
046: import com.sun.xml.bind.api.impl.NameConverter;
047:
048: import org.w3c.dom.Element;
049: import org.xml.sax.Locator;
050:
051: /**
052: * <element> declaration in the binding file.
053: */
054: public final class BIElement {
055: /**
056: * Wraps a given <element> element in the binding file.
057: *
058: * <p>
059: * Should be created only from {@link BindInfo}.
060: */
061: BIElement(BindInfo bi, Element _e) {
062: this .parent = bi;
063: this .e = _e;
064:
065: {
066: Element c = DOMUtil.getElement(e, "content");
067: if (c != null) {
068: if (DOMUtil.getAttribute(c, "property") != null) {
069: // if @property is there, this is a general declaration
070: this .rest = BIContent.create(c, this );
071: } else {
072: // this must be a model-based declaration
073: for (Element p : DOMUtil.getChildElements(c)) {
074: if (p.getLocalName().equals("rest"))
075: this .rest = BIContent.create(p, this );
076: else
077: this .contents
078: .add(BIContent.create(p, this ));
079: }
080: }
081: }
082: }
083:
084: // parse <attribute>s
085: for (Element atr : DOMUtil.getChildElements(e, "attribute")) {
086: BIAttribute a = new BIAttribute(this , atr);
087: attributes.put(a.name(), a);
088: }
089:
090: if (isClass()) {
091: // if this is a class-declaration, create JClass object now
092: String className = DOMUtil.getAttribute(e, "class");
093: if (className == null)
094: // none was specified. infer the name.
095: className = NameConverter.standard.toClassName(name());
096: this .className = className;
097: } else {
098: // this is not an element-class declaration
099: className = null;
100: }
101:
102: // process conversion declarations
103: for (Element conv : DOMUtil.getChildElements(e, "conversion")) {
104: BIConversion c = new BIUserConversion(bi, conv);
105: conversions.put(c.name(), c);
106: }
107: for (Element en : DOMUtil.getChildElements(e, "enumeration")) {
108: BIConversion c = BIEnumeration.create(en, this );
109: conversions.put(c.name(), c);
110: }
111:
112: // parse <constructor>s
113: for (Element c : DOMUtil.getChildElements(e, "constructor")) {
114: constructors.add(new BIConstructor(c));
115: }
116:
117: String name = name();
118: QName tagName = new QName("", name);
119:
120: this .clazz = new CClassInfo(parent.model, parent
121: .getTargetPackage(), className, getLocation(), null,
122: tagName, null, null/*TODO*/);
123: }
124:
125: /**
126: * Gets the source location where this element is declared.
127: */
128: public Locator getLocation() {
129: return DOMLocator.getLocationInfo(e);
130: }
131:
132: /** The parent {@link BindInfo} object to which this object belongs. */
133: final BindInfo parent;
134:
135: /** <element> element which this object is wrapping. */
136: private final Element e;
137:
138: /**
139: * The bean representation for this element.
140: */
141: public final CClassInfo clazz;
142:
143: /**
144: * Content-property declarations.
145: * <p>
146: * This vector will be empty if no content-property declaration is made.
147: */
148: private final List<BIContent> contents = new ArrayList<BIContent>();
149:
150: /** Conversion declarations. */
151: private final Map<String, BIConversion> conversions = new HashMap<String, BIConversion>();
152:
153: /**
154: * The "rest" content-property declaration.
155: * <p>
156: * This field is null when there was no "rest" declaration.
157: */
158: private BIContent rest;
159:
160: /** Attribute-property declarations. */
161: private final Map<String, BIAttribute> attributes = new HashMap<String, BIAttribute>();
162:
163: /** Constructor declarations. */
164: private final List<BIConstructor> constructors = new ArrayList<BIConstructor>();
165:
166: /**
167: * the class which is generated by this declaration.
168: * This field will be null if this declaration is an element-property
169: * declaration.
170: */
171: private final String className;
172:
173: /** Gets the element name. */
174: public String name() {
175: return DOMUtil.getAttribute(e, "name");
176: }
177:
178: /**
179: * Checks if the element type is "class".
180: * If false, that means this element will be a value.
181: */
182: public boolean isClass() {
183: return "class".equals(e.getAttribute("type"));
184: }
185:
186: /**
187: * Checks if this element is designated as a root element.
188: */
189: public boolean isRoot() {
190: return "true".equals(e.getAttribute("root"));
191: }
192:
193: /**
194: * Gets the JClass object that represents this declaration.
195: *
196: * <p>
197: * This method returns null if this declaration
198: * is an element-property declaration.
199: */
200: public String getClassName() {
201: return className;
202: }
203:
204: /**
205: * Creates constructor declarations for this element.
206: *
207: * <p>
208: * This method should only be called by DTDReader <b>after</b>
209: * the normalization has completed.
210: *
211: * @param src
212: * The ClassItem object that corresponds to this declaration
213: */
214: public void declareConstructors(CClassInfo src) {
215: for (BIConstructor c : constructors)
216: c.createDeclaration(src);
217: }
218:
219: /**
220: * Gets the conversion method for this element.
221: *
222: * <p>
223: * This method can be called only when this element
224: * declaration is designated as element-value.
225: *
226: * @return
227: * If the convert attribute is not specified, this
228: * method returns null.
229: */
230: public BIConversion getConversion() {
231: String cnv = DOMUtil.getAttribute(e, "convert");
232: if (cnv == null)
233: return null;
234:
235: return conversion(cnv);
236: }
237:
238: /**
239: * Resolves the conversion name to the conversion declaration.
240: *
241: * <p>
242: * Element-local declarations are checked first.
243: *
244: * @return
245: * A non-null valid BIConversion object.
246: */
247: public BIConversion conversion(String name) {
248: BIConversion r = conversions.get(name);
249: if (r != null)
250: return r;
251:
252: // check the global conversion declarations
253: return parent.conversion(name);
254: }
255:
256: /**
257: * Iterates all content-property declarations (except 'rest').
258: */
259: public List<BIContent> getContents() {
260: return contents;
261: }
262:
263: /**
264: * Gets the attribute-property declaration, if any.
265: *
266: * @return
267: * null if attribute declaration was not given by that name.
268: */
269: public BIAttribute attribute(String name) {
270: return attributes.get(name);
271: }
272:
273: /**
274: * Gets the 'rest' content-property declaration, if any.
275: * @return
276: * if there is no 'rest' declaration, return null.
277: */
278: public BIContent getRest() {
279: return this .rest;
280: }
281:
282: /** Gets the location where this declaration is declared. */
283: public Locator getSourceLocation() {
284: return DOMLocator.getLocationInfo(e);
285: }
286: }
|