blob: 64c3839271e4214181e4c351ee89f6aea6bb826d [file] [log] [blame]
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.internal.txw2.model;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JMod;
import com.sun.tools.internal.txw2.NameUtil;
import com.sun.tools.internal.txw2.TxwOptions;
import com.sun.xml.internal.txw2.annotation.XmlNamespace;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Root of the model.
*
* @author Kohsuke Kawaguchi
*/
public class NodeSet extends LinkedHashSet<WriterNode> {
/*package*/ final TxwOptions opts;
/*package*/ final JCodeModel codeModel;
/**
* Set of all the {@link Element}s that can be root.
*/
private final Set<Element> rootElements = new HashSet<Element>();
/** The namespace URI declared in {@link XmlNamespace}. */
/*package*/ final String defaultNamespace;
public NodeSet(TxwOptions opts, Leaf entry) {
this.opts = opts;
this.codeModel = opts.codeModel;
addAll(entry.siblings());
markRoot(entry.siblings(),rootElements);
// decide what to put in @XmlNamespace
Set<String> ns = new HashSet<String>();
for( Element e : rootElements )
ns.add(e.name.getNamespaceURI());
if(ns.size()!=1 || opts.noPackageNamespace || opts._package.isUnnamed())
defaultNamespace = null;
else {
defaultNamespace = ns.iterator().next();
opts._package.annotate(XmlNamespace.class)
.param("value",defaultNamespace);
}
}
/**
* Marks all the element children as root.
*/
private void markRoot(Iterable<Leaf> c, Set<Element> rootElements) {
for( Leaf l : c ) {
if( l instanceof Element ) {
Element e = (Element)l;
rootElements.add(e);
e.isRoot = true;
}
if( l instanceof Ref ) {
markRoot(((Ref)l).def,rootElements);
}
}
}
private void addAll(Iterable<Leaf> c) {
for( Leaf l : c ) {
if(l instanceof Element)
if(add((Element)l))
addAll((Element)l);
if(l instanceof Grammar) {
Grammar g = (Grammar)l;
for( Define d : g.getDefinitions() )
add(d);
}
if(l instanceof Ref) {
Ref r = (Ref)l;
Define def = r.def;
// if(def instanceof Grammar) {
// for( Define d : ((Grammar)def).getDefinitions() )
// if(add(d))
// addAll(d);
// }
add(def);
}
}
}
private boolean add(Define def) {
boolean b = super.add(def);
if(b)
addAll(def);
return b;
}
public <T extends WriterNode> Collection<T> subset(Class<T> t) {
ArrayList<T> r = new ArrayList<T>(size());
for( WriterNode n : this )
if(t.isInstance(n))
r.add((T)n);
return r;
}
/**
* Generate code
*/
public void write(TxwOptions opts) {
for( WriterNode n : this )
n.prepare(this);
for( WriterNode n : this )
n.declare(this);
for( WriterNode n : this )
n.generate(this);
}
/*package*/ final JDefinedClass createClass(String name) {
try {
return opts._package._class(
JMod.PUBLIC, NameUtil.toClassName(name), ClassType.INTERFACE );
} catch (JClassAlreadyExistsException e) {
for( int i=2; true; i++ ) {
try {
return opts._package._class(
JMod.PUBLIC, NameUtil.toClassName(name+String.valueOf(i)), ClassType.INTERFACE );
} catch (JClassAlreadyExistsException e1) {
; // continue
}
}
}
}
}