001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.xml.handlers.xsi;
017:
018: import java.net.URI;
019: import java.util.LinkedList;
020: import java.util.List;
021:
022: import org.geotools.xml.XSIElementHandler;
023: import org.geotools.xml.schema.Choice;
024: import org.geotools.xml.schema.Element;
025: import org.geotools.xml.schema.ElementGrouping;
026: import org.xml.sax.Attributes;
027: import org.xml.sax.SAXException;
028:
029: /**
030: * ChoiceHandler purpose.
031: *
032: * <p>
033: * represtents a 'choice' element
034: * </p>
035: *
036: * @author dzwiers, Refractions Research, Inc. http://www.refractions.net
037: * @author $Author:$ (last modification)
038: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/xml/src/main/java/org/geotools/xml/handlers/xsi/ChoiceHandler.java $
039: * @version $Id: ChoiceHandler.java 20747 2006-07-29 01:12:15Z jeichar $
040: */
041: public class ChoiceHandler extends ElementGroupingHandler {
042: /** 'choice' */
043: public final static String LOCALNAME = "choice";
044: private String id;
045: private int minOccurs;
046: private int maxOccurs;
047: private List children; // element, group, choice, sequence, any
048: private DefaultChoice cache = null;
049:
050: /**
051: * @see java.lang.Object#hashCode()
052: */
053: public int hashCode() {
054: return (LOCALNAME.hashCode() * ((id == null) ? 1 : id
055: .hashCode()))
056: + (minOccurs * maxOccurs);
057: }
058:
059: /**
060: * @see org.geotools.xml.XSIElementHandler#getHandler(java.lang.String,
061: * java.lang.String)
062: */
063: public XSIElementHandler getHandler(String namespaceURI,
064: String localName) {
065: if (SchemaHandler.namespaceURI.equalsIgnoreCase(namespaceURI)) {
066: // child types
067: //
068: // group
069: if (GroupHandler.LOCALNAME.equalsIgnoreCase(localName)) {
070: if (children == null) {
071: children = new LinkedList();
072: }
073:
074: GroupHandler gh = new GroupHandler();
075: children.add(gh);
076:
077: return gh;
078: }
079:
080: // choice
081: if (LOCALNAME.equalsIgnoreCase(localName)) {
082: if (children == null) {
083: children = new LinkedList();
084: }
085:
086: GroupHandler gh = new GroupHandler();
087: children.add(gh);
088:
089: return gh;
090: }
091:
092: // sequence
093: if (SequenceHandler.LOCALNAME.equalsIgnoreCase(localName)) {
094: if (children == null) {
095: children = new LinkedList();
096: }
097:
098: SequenceHandler gh = new SequenceHandler();
099: children.add(gh);
100:
101: return gh;
102: }
103:
104: // any
105: if (AnyHandler.LOCALNAME.equalsIgnoreCase(localName)) {
106: if (children == null) {
107: children = new LinkedList();
108: }
109:
110: AnyHandler gh = new AnyHandler();
111: children.add(gh);
112:
113: return gh;
114: }
115:
116: // element
117: if (ElementTypeHandler.LOCALNAME
118: .equalsIgnoreCase(localName)) {
119: if (children == null) {
120: children = new LinkedList();
121: }
122:
123: ElementTypeHandler gh = new ElementTypeHandler();
124: children.add(gh);
125:
126: return gh;
127: }
128: }
129:
130: return null;
131: }
132:
133: /**
134: * @see org.geotools.xml.XSIElementHandler#startElement(java.lang.String,
135: * java.lang.String, org.xml.sax.Attributes)
136: */
137: public void startElement(String namespaceURI, String localName,
138: Attributes atts) {
139: id = atts.getValue("", "id");
140:
141: if (id == null) {
142: id = atts.getValue(namespaceURI, "id");
143: }
144:
145: String min = atts.getValue("", "minOccurs");
146:
147: if (min == null) {
148: min = atts.getValue(namespaceURI, "minOccurs");
149: }
150:
151: String max = atts.getValue("", "maxOccurs");
152:
153: if (max == null) {
154: max = atts.getValue(namespaceURI, "maxOccurs");
155: }
156:
157: minOccurs = ((min == null) || "".equalsIgnoreCase(min)) ? 1
158: : Integer.parseInt(min);
159: maxOccurs = ((max == null) || "".equalsIgnoreCase(max)) ? 1
160: : ("unbounded".equalsIgnoreCase(max) ? ElementGrouping.UNBOUNDED
161: : Integer.parseInt(max));
162: }
163:
164: /**
165: * @see org.geotools.xml.XSIElementHandler#getLocalName()
166: */
167: public String getLocalName() {
168: return LOCALNAME;
169: }
170:
171: /**
172: * @see org.geotools.xml.XSIHandlers.ElementGroupingHandler#compress(org.geotools.xml.XSIHandlers.SchemaHandler)
173: */
174: protected ElementGrouping compress(SchemaHandler parent)
175: throws SAXException {
176:
177: synchronized (this ) {
178: if (cache != null)
179: return cache;
180: cache = new DefaultChoice();
181: }
182:
183: cache.id = id;
184: cache.maxOccurs = maxOccurs;
185: cache.minOccurs = minOccurs;
186:
187: if (children != null) {
188: cache.children = new ElementGrouping[children.size()];
189:
190: // TODO compress choices here
191: // remove child choices and make the options as peers
192: for (int i = 0; i < cache.children.length; i++)
193: cache.children[i] = ((ElementGroupingHandler) children
194: .get(i)).compress(parent);
195: }
196:
197: id = null;
198: children = null;
199:
200: return cache;
201: }
202:
203: /**
204: * @see org.geotools.xml.XSIElementHandler#getHandlerType()
205: */
206: public int getHandlerType() {
207: return DEFAULT;
208: }
209:
210: /**
211: * @see org.geotools.xml.XSIElementHandler#endElement(java.lang.String,
212: * java.lang.String)
213: */
214: public void endElement(String namespaceURI, String localName) {
215: // does nothing
216: }
217:
218: /**
219: * <p>
220: * Implementation of a Choice
221: * </p>
222: *
223: * @author dzwiers
224: *
225: * @see Choice
226: */
227: private static class DefaultChoice implements Choice {
228: // file visible to avoid set* methods
229: ElementGrouping[] children;
230: String id;
231: int maxOccurs;
232: int minOccurs;
233:
234: /**
235: * @see org.geotools.xml.xsi.ElementGrouping#findChildElement(java.lang.String)
236: */
237: public Element findChildElement(String name) {
238: if (children == null) {
239: return null;
240: }
241:
242: for (int i = 0; i < children.length; i++) {
243: Element t = children[i].findChildElement(name);
244:
245: if (t != null) { // found it
246:
247: return t;
248: }
249: }
250:
251: return null;
252: }
253:
254: /**
255: * @see org.geotools.xml.xsi.Choice#getChildren()
256: */
257: public ElementGrouping[] getChildren() {
258: return children;
259: }
260:
261: /**
262: * @see org.geotools.xml.xsi.Choice#getId()
263: */
264: public String getId() {
265: return id;
266: }
267:
268: /**
269: * @see org.geotools.xml.xsi.ElementGrouping#getMaxOccurs()
270: */
271: public int getMaxOccurs() {
272: return maxOccurs;
273: }
274:
275: /**
276: * @see org.geotools.xml.xsi.ElementGrouping#getMinOccurs()
277: */
278: public int getMinOccurs() {
279: return minOccurs;
280: }
281:
282: /**
283: * @see org.geotools.xml.xsi.ElementGrouping#getGrouping()
284: */
285: public int getGrouping() {
286: return CHOICE;
287: }
288:
289: public Element findChildElement(String localName,
290: URI namespaceURI) {
291: if (children == null) {
292: return null;
293: }
294:
295: for (int i = 0; i < children.length; i++) {
296: Element t = children[i].findChildElement(localName,
297: namespaceURI);
298:
299: if (t != null) { // found it
300:
301: return t;
302: }
303: }
304:
305: return null;
306: }
307: }
308: }
|