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.xjc.reader.dtd;
027:
028: import java.util.ArrayList;
029: import java.util.List;
030:
031: import com.sun.xml.internal.dtdparser.DTDEventListener;
032:
033: /**
034: * @author Kohsuke Kawaguchi
035: */
036: final class ModelGroup extends Term {
037: enum Kind {
038: CHOICE, SEQUENCE
039: }
040:
041: Kind kind;
042:
043: private final List<Term> terms = new ArrayList<Term>();
044:
045: void normalize(List<Block> r, boolean optional) {
046: switch (kind) {
047: case SEQUENCE:
048: for (Term t : terms)
049: t.normalize(r, optional);
050: return;
051: case CHOICE:
052: Block b = new Block(isOptional() || optional, isRepeated());
053: addAllElements(b);
054: r.add(b);
055: return;
056: }
057: }
058:
059: void addAllElements(Block b) {
060: for (Term t : terms)
061: t.addAllElements(b);
062: }
063:
064: boolean isOptional() {
065: switch (kind) {
066: case SEQUENCE:
067: for (Term t : terms)
068: if (!t.isOptional())
069: return false;
070: return true;
071: case CHOICE:
072: for (Term t : terms)
073: if (t.isOptional())
074: return true;
075: return false;
076: default:
077: throw new IllegalArgumentException();
078: }
079: }
080:
081: boolean isRepeated() {
082: switch (kind) {
083: case SEQUENCE:
084: return true;
085: case CHOICE:
086: for (Term t : terms)
087: if (t.isRepeated())
088: return true;
089: return false;
090: default:
091: throw new IllegalArgumentException();
092: }
093: }
094:
095: void setKind(short connectorType) {
096: Kind k;
097: switch (connectorType) {
098: case DTDEventListener.SEQUENCE:
099: k = Kind.SEQUENCE;
100: break;
101: case DTDEventListener.CHOICE:
102: k = Kind.CHOICE;
103: break;
104: default:
105: throw new IllegalArgumentException();
106: }
107:
108: assert kind == null || k == kind;
109: kind = k;
110: }
111:
112: void addTerm(Term t) {
113: if (t instanceof ModelGroup) {
114: ModelGroup mg = (ModelGroup) t;
115: if (mg.kind == this .kind) {
116: terms.addAll(mg.terms);
117: return;
118: }
119: }
120: terms.add(t);
121: }
122:
123: Term wrapUp() {
124: switch (terms.size()) {
125: case 0:
126: return EMPTY;
127: case 1:
128: assert kind == null;
129: return terms.get(0);
130: default:
131: assert kind != null;
132: return this;
133: }
134: }
135:
136: }
|