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.builder.relaxng;
027:
028: import com.sun.codemodel.JClass;
029: import com.sun.codemodel.JCodeModel;
030: import com.sun.codemodel.JType;
031: import com.sun.tools.internal.txw2.model.Attribute;
032: import com.sun.tools.internal.txw2.model.Data;
033: import com.sun.tools.internal.txw2.model.Element;
034: import com.sun.tools.internal.txw2.model.Empty;
035: import com.sun.tools.internal.txw2.model.Leaf;
036: import com.sun.tools.internal.txw2.model.List;
037: import com.sun.tools.internal.txw2.model.Value;
038: import org.kohsuke.rngom.ast.builder.BuildException;
039: import org.kohsuke.rngom.ast.builder.DataPatternBuilder;
040: import org.kohsuke.rngom.ast.builder.ElementAnnotationBuilder;
041: import org.kohsuke.rngom.ast.builder.Grammar;
042: import org.kohsuke.rngom.ast.builder.NameClassBuilder;
043: import org.kohsuke.rngom.ast.builder.SchemaBuilder;
044: import org.kohsuke.rngom.ast.builder.Scope;
045: import org.kohsuke.rngom.ast.om.ParsedElementAnnotation;
046: import org.kohsuke.rngom.ast.util.LocatorImpl;
047: import org.kohsuke.rngom.nc.NameClass;
048: import org.kohsuke.rngom.nc.NameClassBuilderImpl;
049: import org.kohsuke.rngom.parse.Context;
050: import org.kohsuke.rngom.parse.IllegalSchemaException;
051: import org.kohsuke.rngom.parse.Parseable;
052:
053: import javax.xml.namespace.QName;
054:
055: /**
056: * Builds a model from a RELAX NG grammar.
057: *
058: * @author Kohsuke Kawaguchi
059: */
060: public final class SchemaBuilderImpl
061: implements
062: SchemaBuilder<NameClass, Leaf, ParsedElementAnnotation, LocatorImpl, AnnotationsImpl, CommentListImpl> {
063: private final NameClassBuilderImpl ncb = new NameClassBuilderImpl();
064: private final JClass string;
065: private final DatatypeFactory dtf;
066:
067: public SchemaBuilderImpl(JCodeModel codeModel) {
068: string = codeModel.ref(String.class);
069: dtf = new DatatypeFactory(codeModel);
070: }
071:
072: public Leaf expandPattern(Leaf leaf) throws BuildException {
073: return leaf;
074: }
075:
076: public NameClassBuilder getNameClassBuilder() throws BuildException {
077: return ncb;
078: }
079:
080: private Leaf merge(java.util.List<Leaf> leaves) {
081: for (int i = 1; i < leaves.size(); i++)
082: leaves.get(0).merge(leaves.get(i));
083: return leaves.get(0);
084: }
085:
086: public Leaf makeChoice(java.util.List<Leaf> leaves,
087: LocatorImpl locator, AnnotationsImpl annotations)
088: throws BuildException {
089: return merge(leaves);
090: }
091:
092: public Leaf makeInterleave(java.util.List<Leaf> leaves,
093: LocatorImpl locator, AnnotationsImpl annotations)
094: throws BuildException {
095: return merge(leaves);
096: }
097:
098: public Leaf makeGroup(java.util.List<Leaf> leaves,
099: LocatorImpl locator, AnnotationsImpl annotations)
100: throws BuildException {
101: return merge(leaves);
102: }
103:
104: public Leaf makeOneOrMore(Leaf leaf, LocatorImpl locator,
105: AnnotationsImpl annotations) throws BuildException {
106: return leaf;
107: }
108:
109: public Leaf makeZeroOrMore(Leaf leaf, LocatorImpl locator,
110: AnnotationsImpl annotations) throws BuildException {
111: return leaf.merge(new Empty(locator));
112: }
113:
114: public Leaf makeOptional(Leaf leaf, LocatorImpl locator,
115: AnnotationsImpl annotations) throws BuildException {
116: return leaf.merge(new Empty(locator));
117: }
118:
119: public Leaf makeList(Leaf leaf, LocatorImpl locator,
120: AnnotationsImpl annotations) throws BuildException {
121: return new List(locator, leaf);
122: }
123:
124: public Leaf makeMixed(Leaf leaf, LocatorImpl locator,
125: AnnotationsImpl annotations) throws BuildException {
126: return leaf.merge(new Data(locator, string));
127: }
128:
129: public Leaf makeEmpty(LocatorImpl locator,
130: AnnotationsImpl annotations) {
131: return new Empty(locator);
132: }
133:
134: public Leaf makeNotAllowed(LocatorImpl locator,
135: AnnotationsImpl annotations) {
136: // technically this is incorrect, but we won't be
137: // able to handle <notAllowed/> correctly anyway.
138: return new Empty(locator);
139: }
140:
141: public Leaf makeText(LocatorImpl locator,
142: AnnotationsImpl annotations) {
143: return new Data(locator, string);
144: }
145:
146: public Leaf makeAttribute(NameClass nameClass, Leaf leaf,
147: LocatorImpl locator, AnnotationsImpl annotations)
148: throws BuildException {
149: Leaf r = null;
150: for (QName n : nameClass.listNames()) {
151: Leaf l = new Attribute(locator, n, leaf);
152: if (r != null)
153: r = r.merge(l);
154: else
155: r = l;
156: }
157: if (r == null)
158: return new Empty(locator);
159: return r;
160: }
161:
162: public Leaf makeElement(NameClass nameClass, Leaf leaf,
163: LocatorImpl locator, AnnotationsImpl annotations)
164: throws BuildException {
165: Leaf r = null;
166: for (QName n : nameClass.listNames()) {
167: Leaf l = new Element(locator, n, leaf);
168: if (r != null)
169: r = r.merge(l);
170: else
171: r = l;
172: }
173: if (r == null)
174: return new Empty(locator);
175: return r;
176: }
177:
178: public DataPatternBuilder makeDataPatternBuilder(
179: String datatypeLibrary, String type, LocatorImpl locator)
180: throws BuildException {
181: return new DataPatternBuilderImpl(
182: getType(datatypeLibrary, type));
183: }
184:
185: private JType getType(String datatypeLibrary, String type) {
186: JType t = dtf.getType(datatypeLibrary, type);
187: if (t == null)
188: t = string;
189: return t;
190: }
191:
192: public Leaf makeValue(String datatypeLibrary, String type,
193: String value, Context c, String ns, LocatorImpl locator,
194: AnnotationsImpl annotations) throws BuildException {
195: return new Value(locator, getType(datatypeLibrary, type), value);
196: }
197:
198: public Grammar<Leaf, ParsedElementAnnotation, LocatorImpl, AnnotationsImpl, CommentListImpl> makeGrammar(
199: Scope<Leaf, ParsedElementAnnotation, LocatorImpl, AnnotationsImpl, CommentListImpl> scope) {
200: return new GrammarImpl(scope);
201: }
202:
203: public Leaf annotate(Leaf leaf, AnnotationsImpl annotations)
204: throws BuildException {
205: return leaf;
206: }
207:
208: public Leaf annotateAfter(Leaf leaf,
209: ParsedElementAnnotation parsedElementAnnotation)
210: throws BuildException {
211: return leaf;
212: }
213:
214: public Leaf makeErrorPattern() {
215: return new Empty(null);
216: }
217:
218: public boolean usesComments() {
219: return false;
220: }
221:
222: public Leaf makeExternalRef(
223: Parseable current,
224: String uri,
225: String ns,
226: Scope<Leaf, ParsedElementAnnotation, LocatorImpl, AnnotationsImpl, CommentListImpl> scope,
227: LocatorImpl locator, AnnotationsImpl annotations)
228: throws BuildException, IllegalSchemaException {
229: // I'm not too sure if this is correct
230: return current.parseExternal(uri, this , scope, ns);
231: }
232:
233: public LocatorImpl makeLocation(String systemId, int lineNumber,
234: int columnNumber) {
235: return new LocatorImpl(systemId, lineNumber, columnNumber);
236: }
237:
238: public AnnotationsImpl makeAnnotations(CommentListImpl commentList,
239: Context context) {
240: return new AnnotationsImpl();
241: }
242:
243: public ElementAnnotationBuilder<Leaf, ParsedElementAnnotation, LocatorImpl, AnnotationsImpl, CommentListImpl> makeElementAnnotationBuilder(
244: String ns, String localName, String prefix,
245: LocatorImpl locator, CommentListImpl commentList,
246: Context context) {
247: return new ElementAnnotationBuilderImpl();
248: }
249:
250: public CommentListImpl makeCommentList() {
251: return null;
252: }
253:
254: public Leaf commentAfter(Leaf leaf, CommentListImpl commentList)
255: throws BuildException {
256: return leaf;
257: }
258: }
|