001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free SoftwareFoundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.relaxng.program;
031:
032: import com.caucho.log.Log;
033: import com.caucho.relaxng.RelaxException;
034: import com.caucho.util.CharBuffer;
035: import com.caucho.util.L10N;
036: import com.caucho.xml.QName;
037:
038: import java.util.HashSet;
039: import java.util.Iterator;
040: import java.util.NoSuchElementException;
041: import java.util.logging.Logger;
042:
043: /**
044: * Generates programs from patterns.
045: */
046: abstract public class Item {
047: protected final static L10N L = new L10N(Item.class);
048: protected final static Logger log = Log.open(Item.class);
049:
050: private static final Iterator<Item> EMPTY_ITEM_ITERATOR;
051:
052: /**
053: * Adds to the first set the set of element names possible.
054: */
055: public void firstSet(HashSet<QName> set) {
056: }
057:
058: /**
059: * Adds to the first set the set of element names required.
060: */
061: public void requiredFirstSet(HashSet<QName> set) {
062: if (!allowEmpty())
063: firstSet(set);
064: }
065:
066: /**
067: * Returns true if the item can match empty.
068: */
069: public boolean allowEmpty() {
070: return false;
071: }
072:
073: /**
074: * Return all possible child items
075: */
076: public Iterator<Item> getItemsIterator() {
077: return emptyItemIterator();
078: }
079:
080: protected Iterator<Item> emptyItemIterator() {
081: return EMPTY_ITEM_ITERATOR;
082: }
083:
084: protected Iterator<Item> itemIterator(final Item item) {
085: if (item == null)
086: return emptyItemIterator();
087:
088: return new Iterator<Item>() {
089: private boolean _done;
090:
091: public boolean hasNext() {
092: return !_done;
093: }
094:
095: public Item next() {
096: if (!hasNext())
097: throw new NoSuchElementException();
098:
099: _done = true;
100:
101: return item;
102: }
103:
104: public void remove() {
105: throw new UnsupportedOperationException();
106: }
107: };
108: }
109:
110: /**
111: * Returns the next item when an element of the given name is returned
112: *
113: * @param name the name of the element
114: *
115: * @return the program for handling the element
116: */
117: public Item startElement(QName name) throws RelaxException {
118: return null;
119: }
120:
121: /**
122: * Returns true if the element is allowed somewhere in the item.
123: * allowsElement is used for error messages to give more information
124: * in cases of order dependency.
125: *
126: * @param name the name of the element
127: *
128: * @return true if the element is allowed somewhere
129: */
130: public boolean allowsElement(QName name) {
131: return false;
132: }
133:
134: /**
135: * Adds to the first set, the set of attribute names possible.
136: */
137: public void attributeSet(HashSet<QName> set) {
138: }
139:
140: /**
141: * Sets an attribute.
142: *
143: * @param name the name of the attribute
144: * @param value the value of the attribute
145: *
146: * @return the program for handling the element
147: */
148: public boolean allowAttribute(QName name, String value)
149: throws RelaxException {
150: return false;
151: }
152:
153: /**
154: * Sets an attribute.
155: *
156: * @param name the name of the attribute
157: * @param value the value of the attribute
158: *
159: * @return the program for handling the element
160: */
161: public Item setAttribute(QName name, String value)
162: throws RelaxException {
163: return this ;
164: }
165:
166: /**
167: * Returns true if the item can match empty.
168: */
169: public Item attributeEnd() {
170: return this ;
171: }
172:
173: /**
174: * Adds text.
175: */
176: public Item text(CharSequence text) throws RelaxException {
177: return null;
178: }
179:
180: /**
181: * Returns the next item when the element closes
182: */
183: public Item endElement() throws RelaxException {
184: if (allowEmpty())
185: return EmptyItem.create();
186: else
187: return null;
188: }
189:
190: /**
191: * Interleaves a continuation.
192: */
193: public Item interleaveContinuation(Item cont) {
194: throw new IllegalStateException(String.valueOf(getClass()
195: .getName()));
196: }
197:
198: /**
199: * Interleaves a continuation.
200: */
201: public Item inElementContinuation(Item cont) {
202: throw new IllegalStateException(String.valueOf(getClass()
203: .getName()));
204: }
205:
206: /**
207: * Appends a group to a continuation.
208: */
209: public Item groupContinuation(Item cont) {
210: throw new IllegalStateException(String.valueOf(getClass()
211: .getName()));
212: }
213:
214: /**
215: * Returns the pretty printed syntax.
216: */
217: public String toSyntaxDescription(int depth) {
218: return toString();
219: }
220:
221: /**
222: * Returns true for an element with simple syntax.
223: */
224: protected boolean isSimpleSyntax() {
225: return false;
226: }
227:
228: /**
229: * Adds a syntax newline.
230: */
231: protected void addSyntaxNewline(CharBuffer cb, int depth) {
232: cb.append('\n');
233: for (int i = 0; i < depth; i++)
234: cb.append(' ');
235: }
236:
237: /**
238: * Throws an error.
239: */
240: protected RelaxException error(String msg) {
241: return new RelaxException(msg);
242: }
243:
244: static {
245: EMPTY_ITEM_ITERATOR = new Iterator<Item>() {
246: public boolean hasNext() {
247: return false;
248: }
249:
250: public Item next() {
251: throw new NoSuchElementException();
252: }
253:
254: public void remove() {
255: throw new UnsupportedOperationException();
256: }
257: };
258: }
259: }
|