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.util.Iterator;
019: import java.util.LinkedList;
020: import java.util.List;
021:
022: import org.geotools.xml.XSIElementHandler;
023: import org.geotools.xml.schema.Facet;
024: import org.geotools.xml.schema.SimpleType;
025: import org.geotools.xml.schema.impl.FacetGT;
026: import org.geotools.xml.schema.impl.SimpleTypeGT;
027: import org.xml.sax.Attributes;
028: import org.xml.sax.SAXException;
029: import org.xml.sax.SAXNotRecognizedException;
030:
031: /**
032: * SimpleTypeHandler purpose.
033: *
034: * <p>
035: * represents a simpleType element
036: * </p>
037: *
038: * @author dzwiers, Refractions Research, Inc. http://www.refractions.net
039: * @author $Author:$ (last modification)
040: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/xml/src/main/java/org/geotools/xml/handlers/xsi/SimpleTypeHandler.java $
041: * @version $Id: SimpleTypeHandler.java 22266 2006-10-19 11:30:55Z acuster $
042: */
043: public class SimpleTypeHandler extends XSIElementHandler {
044: /** NONE */
045: public static final int NONE = 0;
046:
047: /** ALL */
048: public static final int ALL = 7;
049:
050: /** 'simpleType' */
051: public final static String LOCALNAME = "simpleType";
052: private static int offset = 0;
053: private String id;
054: private String name;
055: private int finaL;
056: private XSIElementHandler child; // one of List, Restriction or Union
057: private int hashCodeOffset = getOffset();
058: private SimpleType cache;
059:
060: /*
061: * helper for hashCode()
062: */
063: private static int getOffset() {
064: return offset++;
065: }
066:
067: /**
068: * @see java.lang.Object#hashCode()
069: */
070: public int hashCode() {
071: return (LOCALNAME.hashCode()
072: * ((id == null) ? 1 : id.hashCode())
073: * ((finaL == 0) ? 1 : finaL) * ((name == null) ? 1
074: : name.hashCode()))
075: + hashCodeOffset;
076: }
077:
078: /**
079: * @see org.geotools.xml.XSIElementHandler#getHandler(java.lang.String,
080: * java.lang.String)
081: */
082: public XSIElementHandler getHandler(String namespaceURI,
083: String localName) throws SAXException {
084: if (SchemaHandler.namespaceURI.equalsIgnoreCase(namespaceURI)) {
085: // child types
086: //
087: // list
088: if (ListHandler.LOCALNAME.equalsIgnoreCase(localName)) {
089: ListHandler lh = new ListHandler();
090:
091: if (child == null) {
092: child = lh;
093: } else {
094: throw new SAXNotRecognizedException(getLocalName()
095: + " may only have one '"
096: + ListHandler.LOCALNAME + "' declaration.");
097: }
098:
099: return lh;
100: }
101:
102: // restriction
103: if (RestrictionHandler.LOCALNAME
104: .equalsIgnoreCase(localName)) {
105: RestrictionHandler lh = new RestrictionHandler();
106:
107: if (child == null) {
108: child = lh;
109: } else {
110: throw new SAXNotRecognizedException(getLocalName()
111: + " may only have one '"
112: + RestrictionHandler.LOCALNAME
113: + "' declaration.");
114: }
115:
116: return lh;
117: }
118:
119: // union
120: if (UnionHandler.LOCALNAME.equalsIgnoreCase(localName)) {
121: UnionHandler lh = new UnionHandler();
122:
123: if (child == null) {
124: child = lh;
125: } else {
126: throw new SAXNotRecognizedException(getLocalName()
127: + " may only have one '"
128: + UnionHandler.LOCALNAME + "' declaration.");
129: }
130:
131: return lh;
132: }
133: }
134:
135: return null;
136: }
137:
138: /**
139: * @see org.geotools.xml.XSIElementHandler#startElement(java.lang.String,
140: * java.lang.String, org.xml.sax.Attributes)
141: */
142: public void startElement(String namespaceURI, String localName,
143: Attributes atts) {
144: id = atts.getValue("", "id");
145:
146: if (id == null) {
147: id = atts.getValue(namespaceURI, "id");
148: }
149:
150: String finaL1 = atts.getValue("", "final");
151:
152: if (finaL1 == null) {
153: finaL1 = atts.getValue(namespaceURI, "final");
154: }
155:
156: this .finaL = findFinal(finaL1);
157:
158: name = atts.getValue("", "name");
159:
160: if (name == null) {
161: name = atts.getValue(namespaceURI, "name");
162: }
163: }
164:
165: /**
166: * <p>
167: * translates the final attribute to an integer mask
168: * </p>
169: *
170: * @param finaL
171: *
172: */
173: public static int findFinal(String finaL) {
174: if ((finaL == null) || "".equalsIgnoreCase(finaL)) {
175: return NONE;
176: }
177:
178: String[] tokens = finaL.split("\\s");
179: int r = 0;
180:
181: for (int i = 0; i < tokens.length; i++) {
182: if ("#all".equalsIgnoreCase(tokens[i])) {
183: r = ALL;
184: i = tokens.length;
185: } else {
186: if ("union".equalsIgnoreCase(tokens[i])) {
187: r += UNION;
188: } else {
189: if ("list".equalsIgnoreCase(tokens[i])) {
190: r += LIST;
191: } else {
192: if ("restriction".equalsIgnoreCase(tokens[i])) {
193: r += RESTRICTION;
194: }
195: }
196: }
197: }
198: }
199:
200: return r;
201: }
202:
203: /**
204: * @see org.geotools.xml.XSIElementHandler#getLocalName()
205: */
206: public String getLocalName() {
207: return LOCALNAME;
208: }
209:
210: /**
211: * <p>
212: * returns the simpletype's name
213: * </p>
214: *
215: */
216: public String getName() {
217: return name;
218: }
219:
220: /**
221: * <p>
222: * compacts the data resolving references.
223: * </p>
224: *
225: * @param parent
226: *
227: */
228: protected SimpleType compress(SchemaHandler parent) {
229: logger.info("Start compressing SimpleType " + getName());
230:
231: if (cache != null) {
232: return cache;
233: }
234:
235: Facet[] facets = null;
236:
237: if (child.getHandlerType() == SimpleType.RESTRICTION) {
238: facets = getFacets((RestrictionHandler) child);
239: }
240:
241: SimpleType[] simpleTypes = getSimpleTypes(child, parent);
242:
243: cache = new SimpleTypeGT(id, name, parent.getTargetNamespace(),
244: child.getHandlerType(), simpleTypes, facets, finaL);
245:
246: logger.info("End compressing SimpleType " + getName());
247: id = null;
248: child = null;
249:
250: return cache;
251: }
252:
253: static SimpleType[] getSimpleTypes(XSIElementHandler child,
254: SchemaHandler parent) {
255: switch (child.getHandlerType()) {
256: case RESTRICTION:
257: return getSimpleTypes((RestrictionHandler) child, parent);
258:
259: case LIST:
260: return getSimpleTypes((ListHandler) child, parent);
261:
262: case UNION:
263: return getSimpleTypes((UnionHandler) child, parent);
264:
265: default:
266: throw new RuntimeException(
267: "Should not be here ... child is one of the other three types.");
268: }
269: }
270:
271: static SimpleType[] getSimpleTypes(RestrictionHandler rest,
272: SchemaHandler parent) {
273: SimpleType[] children = new SimpleType[1];
274:
275: if (rest.getChild() != null) {
276: children[0] = ((SimpleTypeHandler) rest.getChild())
277: .compress(parent);
278: } else {
279: children[0] = parent.lookUpSimpleType(rest.getBase());
280: }
281:
282: return children;
283: }
284:
285: static SimpleType[] getSimpleTypes(ListHandler rest,
286: SchemaHandler parent) {
287: SimpleType[] children = new SimpleType[1];
288:
289: if (rest.getSimpleType() != null) {
290: children[0] = (rest.getSimpleType()).compress(parent);
291: } else {
292: children[0] = parent.lookUpSimpleType(rest.getItemType());
293: }
294:
295: return children;
296: }
297:
298: static SimpleType[] getSimpleTypes(UnionHandler union,
299: SchemaHandler parent) {
300: List l = new LinkedList();
301:
302: if (union.getMemberTypes() != null) {
303: String[] qNames = union.getMemberTypes().split("\\s");
304:
305: for (int i = 0; i < qNames.length; i++)
306: l.add(parent.lookUpSimpleType(qNames[i]));
307: }
308:
309: if (union.getSimpleTypes() != null) {
310: Iterator i = union.getSimpleTypes().iterator();
311:
312: while (i.hasNext()) {
313: l.add(((SimpleTypeHandler) i.next()).compress(parent));
314: }
315: }
316:
317: return (SimpleType[]) l.toArray(new SimpleType[l.size()]);
318: }
319:
320: static Facet[] getFacets(RestrictionHandler rh) {
321: List contraints = rh.getConstraints();
322:
323: if ((contraints == null) || (contraints.size() == 0)) {
324: return null;
325: }
326:
327: Facet[] facets = new Facet[contraints.size()];
328: Iterator i = contraints.iterator();
329: int index = 0;
330:
331: while (i.hasNext()) {
332: FacetHandler fh = (FacetHandler) i.next();
333: facets[index] = new FacetGT(fh.getType(), fh.getValue());
334: index++;
335: }
336:
337: return facets;
338: }
339:
340: /**
341: * @see org.geotools.xml.XSIElementHandler#getHandlerType()
342: */
343: public int getHandlerType() {
344: return SIMPLETYPE;
345: }
346:
347: /**
348: * @see org.geotools.xml.XSIElementHandler#endElement(java.lang.String,
349: * java.lang.String)
350: */
351: public void endElement(String namespaceURI, String localName) {
352: // do nothing
353: }
354: }
|