1/* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.internal.xjc.reader.dtd; 27 28import java.util.ArrayList; 29import java.util.List; 30 31import com.sun.xml.internal.dtdparser.DTDEventListener; 32 33 34/** 35 * @author Kohsuke Kawaguchi 36 */ 37final class ModelGroup extends Term { 38 enum Kind { 39 CHOICE, SEQUENCE 40 } 41 42 Kind kind; 43 44 private final List<Term> terms = new ArrayList<Term>(); 45 46 void normalize(List<Block> r, boolean optional) { 47 switch(kind) { 48 case SEQUENCE: 49 for( Term t : terms ) 50 t.normalize(r,optional); 51 return; 52 case CHOICE: 53 Block b = new Block(isOptional()||optional,isRepeated()); 54 addAllElements(b); 55 r.add(b); 56 return; 57 } 58 } 59 60 void addAllElements(Block b) { 61 for( Term t : terms ) 62 t.addAllElements(b); 63 } 64 65 boolean isOptional() { 66 switch(kind) { 67 case SEQUENCE: 68 for( Term t : terms ) 69 if(!t.isOptional()) 70 return false; 71 return true; 72 case CHOICE: 73 for( Term t : terms ) 74 if(t.isOptional()) 75 return true; 76 return false; 77 default: 78 throw new IllegalArgumentException(); 79 } 80 } 81 82 boolean isRepeated() { 83 switch(kind) { 84 case SEQUENCE: 85 return true; 86 case CHOICE: 87 for( Term t : terms ) 88 if(t.isRepeated()) 89 return true; 90 return false; 91 default: 92 throw new IllegalArgumentException(); 93 } 94 } 95 96 void setKind(short connectorType) { 97 Kind k; 98 switch(connectorType) { 99 case DTDEventListener.SEQUENCE: 100 k = Kind.SEQUENCE; 101 break; 102 case DTDEventListener.CHOICE: 103 k = Kind.CHOICE; 104 break; 105 default: 106 throw new IllegalArgumentException(); 107 } 108 109 assert kind==null || k==kind; 110 kind = k; 111 } 112 113 void addTerm(Term t) { 114 if (t instanceof ModelGroup) { 115 ModelGroup mg = (ModelGroup) t; 116 if(mg.kind==this.kind) { 117 terms.addAll(mg.terms); 118 return; 119 } 120 } 121 terms.add(t); 122 } 123 124 125 Term wrapUp() { 126 switch(terms.size()) { 127 case 0: 128 return EMPTY; 129 case 1: 130 assert kind==null; 131 return terms.get(0); 132 default: 133 assert kind!=null; 134 return this; 135 } 136 } 137 138} 139