001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.txw2.model;
027:
028: import com.sun.codemodel.ClassType;
029: import com.sun.codemodel.JClassAlreadyExistsException;
030: import com.sun.codemodel.JCodeModel;
031: import com.sun.codemodel.JDefinedClass;
032: import com.sun.codemodel.JMod;
033: import com.sun.tools.internal.txw2.NameUtil;
034: import com.sun.tools.internal.txw2.TxwOptions;
035: import com.sun.xml.internal.txw2.annotation.XmlNamespace;
036:
037: import java.util.ArrayList;
038: import java.util.Collection;
039: import java.util.HashSet;
040: import java.util.LinkedHashSet;
041: import java.util.Set;
042:
043: /**
044: * Root of the model.
045: *
046: * @author Kohsuke Kawaguchi
047: */
048: public class NodeSet extends LinkedHashSet<WriterNode> {
049:
050: /*package*/final TxwOptions opts;
051: /*package*/final JCodeModel codeModel;
052:
053: /**
054: * Set of all the {@link Element}s that can be root.
055: */
056: private final Set<Element> rootElements = new HashSet<Element>();
057:
058: /** The namespace URI declared in {@link XmlNamespace}. */
059: /*package*/final String defaultNamespace;
060:
061: public NodeSet(TxwOptions opts, Leaf entry) {
062: this .opts = opts;
063: this .codeModel = opts.codeModel;
064: addAll(entry.siblings());
065: markRoot(entry.siblings(), rootElements);
066:
067: // decide what to put in @XmlNamespace
068: Set<String> ns = new HashSet<String>();
069: for (Element e : rootElements)
070: ns.add(e.name.getNamespaceURI());
071:
072: if (ns.size() != 1 || opts.noPackageNamespace
073: || opts._package.isUnnamed())
074: defaultNamespace = null;
075: else {
076: defaultNamespace = ns.iterator().next();
077:
078: opts._package.annotate(XmlNamespace.class).param("value",
079: defaultNamespace);
080: }
081: }
082:
083: /**
084: * Marks all the element children as root.
085: */
086: private void markRoot(Iterable<Leaf> c, Set<Element> rootElements) {
087: for (Leaf l : c) {
088: if (l instanceof Element) {
089: Element e = (Element) l;
090: rootElements.add(e);
091: e.isRoot = true;
092: }
093: if (l instanceof Ref) {
094: markRoot(((Ref) l).def, rootElements);
095: }
096: }
097: }
098:
099: private void addAll(Iterable<Leaf> c) {
100: for (Leaf l : c) {
101: if (l instanceof Element)
102: if (add((Element) l))
103: addAll((Element) l);
104: if (l instanceof Grammar) {
105: Grammar g = (Grammar) l;
106: for (Define d : g.getDefinitions())
107: add(d);
108: }
109: if (l instanceof Ref) {
110: Ref r = (Ref) l;
111: Define def = r.def;
112: // if(def instanceof Grammar) {
113: // for( Define d : ((Grammar)def).getDefinitions() )
114: // if(add(d))
115: // addAll(d);
116: // }
117: add(def);
118: }
119: }
120: }
121:
122: private boolean add(Define def) {
123: boolean b = super .add(def);
124: if (b)
125: addAll(def);
126: return b;
127: }
128:
129: public <T extends WriterNode> Collection<T> subset(Class<T> t) {
130: ArrayList<T> r = new ArrayList<T>(size());
131: for (WriterNode n : this )
132: if (t.isInstance(n))
133: r.add((T) n);
134: return r;
135: }
136:
137: /**
138: * Generate code
139: */
140: public void write(TxwOptions opts) {
141: for (WriterNode n : this )
142: n.prepare(this );
143: for (WriterNode n : this )
144: n.declare(this );
145: for (WriterNode n : this )
146: n.generate(this );
147: }
148:
149: /*package*/final JDefinedClass createClass(String name) {
150: try {
151: return opts._package._class(JMod.PUBLIC, NameUtil
152: .toClassName(name), ClassType.INTERFACE);
153: } catch (JClassAlreadyExistsException e) {
154: for (int i = 2; true; i++) {
155: try {
156: return opts._package._class(JMod.PUBLIC, NameUtil
157: .toClassName(name + String.valueOf(i)),
158: ClassType.INTERFACE);
159: } catch (JClassAlreadyExistsException e1) {
160: ; // continue
161: }
162: }
163: }
164: }
165: }
|