0001: /*
0002: * GeoTools - OpenSource mapping toolkit
0003: * http://geotools.org
0004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation;
0009: * version 2.1 of the License.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: */
0016: package org.geotools.xml.handlers.xsi;
0017:
0018: import java.net.URI;
0019: import java.net.URISyntaxException;
0020: import java.util.Arrays;
0021: import java.util.Collections;
0022: import java.util.Comparator;
0023: import java.util.HashMap;
0024: import java.util.HashSet;
0025: import java.util.Iterator;
0026: import java.util.LinkedList;
0027: import java.util.List;
0028: import java.util.Map;
0029: import java.util.TreeSet;
0030:
0031: import org.geotools.xml.SchemaFactory;
0032: import org.geotools.xml.XSIElementHandler;
0033: import org.geotools.xml.schema.All;
0034: import org.geotools.xml.schema.Attribute;
0035: import org.geotools.xml.schema.AttributeGroup;
0036: import org.geotools.xml.schema.Choice;
0037: import org.geotools.xml.schema.ComplexType;
0038: import org.geotools.xml.schema.Element;
0039: import org.geotools.xml.schema.ElementGrouping;
0040: import org.geotools.xml.schema.Facet;
0041: import org.geotools.xml.schema.Group;
0042: import org.geotools.xml.schema.Schema;
0043: import org.geotools.xml.schema.Sequence;
0044: import org.geotools.xml.schema.SimpleType;
0045: import org.geotools.xml.schema.Type;
0046: import org.geotools.xml.xsi.XSISimpleTypes;
0047: import org.xml.sax.Attributes;
0048: import org.xml.sax.SAXException;
0049:
0050: /**
0051: * SchemaHandler purpose.
0052: * <p>
0053: * represents a Schema element
0054: * </p>
0055: *
0056: * @author dzwiers, Refractions Research, Inc. http://www.refractions.net
0057: * @author $Author:$ (last modification)
0058: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/xml/src/main/java/org/geotools/xml/handlers/xsi/SchemaHandler.java $
0059: * @version $Id: SchemaHandler.java 22266 2006-10-19 11:30:55Z acuster $
0060: */
0061: public class SchemaHandler extends XSIElementHandler {
0062: /** "http://www.w3.org/2001/XMLSchema" */
0063: public static final String namespaceURI = "http://www.w3.org/2001/XMLSchema";
0064:
0065: /** 'schema' */
0066: public final static String LOCALNAME = "schema";
0067: private String id;
0068: private String prefix;
0069: private URI targetNamespace;
0070: private String version;
0071: private boolean elementFormDefault;
0072: private boolean attributeFormDefault;
0073: private int finalDefault;
0074: private int blockDefault;
0075: private List includes;
0076: private List imports;
0077: private List redefines;
0078: private List attributes;
0079: private List attributeGroups;
0080: private List complexTypes;
0081: private List elements;
0082: private List groups;
0083: private List simpleTypes;
0084: private URI uri;
0085: private Schema schema = null;
0086: private HashMap prefixCache;
0087:
0088: /**
0089: * @see java.lang.Object#hashCode()
0090: */
0091: public int hashCode() {
0092: return LOCALNAME.hashCode()
0093: * ((id == null) ? 1 : id.hashCode())
0094: * ((version == null) ? 1 : version.hashCode())
0095: * ((targetNamespace == null) ? 1 : targetNamespace
0096: .hashCode());
0097: }
0098:
0099: /**
0100: * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
0101: */
0102: public void startPrefixMapping(String pref, String uri1) {
0103: if (targetNamespace == null) {
0104: if (prefixCache == null) {
0105: prefixCache = new HashMap();
0106: }
0107:
0108: if (!pref.trim().equals("")
0109: || !prefixCache.containsKey(uri1))
0110: prefixCache.put(uri1, pref);
0111:
0112: if (this .uri == null && (pref == null || "".equals(pref)))
0113: try {
0114: this .uri = new URI(uri1);
0115: } catch (URISyntaxException e) {
0116: logger.warning(e.getMessage());
0117: }
0118: } else {
0119: // we have already started
0120: if (targetNamespace.equals(uri1.toString())) {
0121: prefix = pref;
0122: }
0123: }
0124: }
0125:
0126: /**
0127: * @see org.geotools.xml.XSIElementHandler#startElement(java.lang.String, java.lang.String, org.xml.sax.Attributes)
0128: */
0129: public void startElement(String namespaceURI1, String localName,
0130: Attributes atts) throws SAXException {
0131: // targetNamespace
0132: String targetNamespace1 = atts.getValue("", "targetNamespace");
0133:
0134: if (targetNamespace1 == null) {
0135: targetNamespace1 = atts.getValue(namespaceURI1,
0136: "targetNamespace");
0137: }
0138:
0139: try {
0140: this .targetNamespace = new URI(targetNamespace1);
0141: } catch (URISyntaxException e) {
0142: logger.warning(e.toString());
0143: throw new SAXException(e);
0144: }
0145:
0146: if ((prefixCache != null) && (targetNamespace1 != null)
0147: && (!targetNamespace1.equals(""))) {
0148: Iterator i = prefixCache.keySet().iterator();
0149:
0150: while ((i != null) && i.hasNext()) {
0151: String uriT = (String) i.next();
0152:
0153: if (targetNamespace1.equals(uriT)) {
0154: prefix = (String) prefixCache.get(uriT);
0155: i = null;
0156: }
0157: }
0158: }
0159:
0160: // prefixCache = null;
0161:
0162: // attributeFormDefault
0163: String attributeFormDefault1 = atts.getValue("",
0164: "attributeFormDefault");
0165:
0166: if (attributeFormDefault1 == null) {
0167: attributeFormDefault1 = atts.getValue(namespaceURI1,
0168: "attributeFormDefault");
0169: }
0170:
0171: this .attributeFormDefault = "qualified"
0172: .equalsIgnoreCase(attributeFormDefault1);
0173:
0174: // blockDefault
0175: String blockDefault1 = atts.getValue("", "blockDefault");
0176:
0177: if (blockDefault1 == null) {
0178: blockDefault1 = atts
0179: .getValue(namespaceURI1, "blockDefault");
0180: }
0181:
0182: this .blockDefault = ComplexTypeHandler.findBlock(blockDefault1);
0183:
0184: // elementFormDefault
0185: String elementFormDefault1 = atts.getValue("",
0186: "elementFormDefault");
0187:
0188: if (elementFormDefault1 == null) {
0189: elementFormDefault1 = atts.getValue(namespaceURI1,
0190: "elementFormDefault");
0191: }
0192:
0193: this .elementFormDefault = "qualified"
0194: .equalsIgnoreCase(elementFormDefault1);
0195:
0196: // finalDefault
0197: String finalDefault1 = atts.getValue("", "finalDefault");
0198:
0199: if (finalDefault1 == null) {
0200: finalDefault1 = atts
0201: .getValue(namespaceURI1, "finalDefault");
0202: }
0203:
0204: this .finalDefault = SimpleTypeHandler.findFinal(finalDefault1);
0205:
0206: // id
0207: id = atts.getValue("", "id");
0208:
0209: if (id == null) {
0210: id = atts.getValue(namespaceURI1, "id");
0211: }
0212:
0213: // version
0214: version = atts.getValue("", "version");
0215:
0216: if (version == null) {
0217: version = atts.getValue(namespaceURI1, "version");
0218: }
0219: }
0220:
0221: /**
0222: * @see org.geotools.xml.XSIElementHandler#getHandler(java.lang.String, java.lang.String)
0223: */
0224: public XSIElementHandler getHandler(String namespaceURI1,
0225: String localName) {
0226: // check that we are working with a known namespace
0227: if (SchemaHandler.namespaceURI.equalsIgnoreCase(namespaceURI1)) {
0228: // child elements:
0229: //
0230: // This list order has been picked in an adhock manner
0231: // attempting to improve performance. Re-order the
0232: // child elements if this order does not appear optimal.
0233: // complexType
0234: if (ComplexTypeHandler.LOCALNAME
0235: .equalsIgnoreCase(localName)) {
0236: if (complexTypes == null) {
0237: complexTypes = new LinkedList();
0238: }
0239:
0240: ComplexTypeHandler cth = new ComplexTypeHandler();
0241: complexTypes.add(cth);
0242:
0243: return cth;
0244: }
0245:
0246: // simpleType
0247: if (SimpleTypeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0248: if (simpleTypes == null) {
0249: simpleTypes = new LinkedList();
0250: }
0251:
0252: SimpleTypeHandler sth = new SimpleTypeHandler();
0253: simpleTypes.add(sth);
0254:
0255: return sth;
0256: }
0257:
0258: // element
0259: if (ElementTypeHandler.LOCALNAME
0260: .equalsIgnoreCase(localName)) {
0261: if (elements == null) {
0262: elements = new LinkedList();
0263: }
0264:
0265: ElementTypeHandler eth = new ElementTypeHandler();
0266: elements.add(eth);
0267:
0268: return eth;
0269: }
0270:
0271: // attribute
0272: if (AttributeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0273: if (attributes == null) {
0274: attributes = new LinkedList();
0275: }
0276:
0277: AttributeHandler ah = new AttributeHandler();
0278: attributes.add(ah);
0279:
0280: return ah;
0281: }
0282:
0283: // include
0284: if (IncludeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0285: if (includes == null) {
0286: includes = new LinkedList();
0287: }
0288:
0289: IncludeHandler ih = new IncludeHandler();
0290: includes.add(ih);
0291:
0292: return ih;
0293: }
0294:
0295: // import
0296: if (ImportHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0297: if (imports == null) {
0298: imports = new LinkedList();
0299: }
0300:
0301: ImportHandler ih = new ImportHandler();
0302: imports.add(ih);
0303:
0304: return ih;
0305: }
0306:
0307: // group
0308: if (GroupHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0309: if (groups == null) {
0310: groups = new LinkedList();
0311: }
0312:
0313: GroupHandler gh = new GroupHandler();
0314: groups.add(gh);
0315:
0316: return gh;
0317: }
0318:
0319: // redefine
0320: if (RedefineHandler.LOCALNAME.equalsIgnoreCase(localName)) {
0321: if (redefines == null) {
0322: redefines = new LinkedList();
0323: }
0324:
0325: RedefineHandler rh = new RedefineHandler();
0326: redefines.add(rh);
0327:
0328: return rh;
0329: }
0330:
0331: // attributeGroup
0332: if (AttributeGroupHandler.LOCALNAME
0333: .equalsIgnoreCase(localName)) {
0334: if (attributeGroups == null) {
0335: attributeGroups = new LinkedList();
0336: }
0337:
0338: AttributeGroupHandler agh = new AttributeGroupHandler();
0339: attributeGroups.add(agh);
0340:
0341: return agh;
0342: }
0343: }
0344:
0345: return null;
0346: }
0347:
0348: /**
0349: * @see org.geotools.xml.XSIElementHandler#getLocalName()
0350: */
0351: public String getLocalName() {
0352: return LOCALNAME;
0353: }
0354:
0355: /**
0356: * <p>
0357: * creates a smaller, more compact version of the schema
0358: * </p>
0359: *
0360: * @param thisURI
0361: * @throws SAXException
0362: */
0363: protected Schema compress(URI this URI) throws SAXException {
0364: if (schema != null) {
0365: return schema; // already compressed.
0366: }
0367:
0368: if (uri == null) {
0369: uri = this URI;
0370: } else {
0371: if (this URI != null) {
0372: uri = this URI.resolve(uri);
0373: }
0374: }
0375:
0376: if (prefix == null && prefixCache != null) {
0377: prefix = (String) prefixCache.get(targetNamespace);
0378: }
0379:
0380: Iterator it = null;
0381:
0382: if (includes != null) {
0383: // do these first
0384: it = includes.iterator();
0385:
0386: while (it.hasNext()) {
0387: IncludeHandler inc = (IncludeHandler) it.next();
0388: logger.finest("compressing include "
0389: + inc.getSchemaLocation());
0390:
0391: if (inc != null && inc.getSchemaLocation() != null) {
0392: Schema cs;
0393: URI incURI = null;
0394: if (this URI == null) {
0395: try {
0396: incURI = new URI(inc.getSchemaLocation());
0397: } catch (URISyntaxException e) {
0398: logger.warning(e.getMessage());
0399: }
0400: } else {
0401: incURI = this URI.normalize().resolve(
0402: inc.getSchemaLocation());
0403: }
0404: cs = SchemaFactory.getInstance(targetNamespace,
0405: incURI, logger.getLevel());
0406:
0407: if (uri != null) {
0408: uri = incURI.resolve(uri);
0409: } else {
0410: uri = incURI;
0411: }
0412:
0413: // already compressed
0414: addSchema(cs);
0415: }
0416: }
0417: }
0418:
0419: includes = null;
0420:
0421: // imports may be schema or schemaHandler
0422: if (this .imports != null) {
0423: // have now loaded the included stuff.
0424: LinkedList imports1 = new LinkedList();
0425: it = this .imports.iterator();
0426:
0427: while (it.hasNext()) {
0428: Object obj = it.next();
0429:
0430: if (obj instanceof ImportHandler) {
0431: ImportHandler imp = (ImportHandler) obj;
0432: URI incURI = null;
0433:
0434: // if ((imp.getSchemaLocation() != null) && (thisURI != null)) {
0435: // incURI = thisURI.normalize().resolve(imp
0436: // .getSchemaLocation());
0437: // }
0438: // fix from chris dillard
0439: if (imp.getSchemaLocation() != null) {
0440: if (this URI != null) {
0441: // For resolving relative URIs
0442: incURI = this URI.normalize().resolve(
0443: imp.getSchemaLocation());
0444: } else {
0445: // If thisURI is null, we have to assume the
0446: // URI is absolute.
0447: incURI = imp.getSchemaLocation();
0448: }
0449: }
0450:
0451: Schema cs = SchemaFactory.getInstance(imp
0452: .getNamespace(), incURI, logger.getLevel());
0453:
0454: imports1.add(cs);
0455: } else {
0456: imports1.add(obj);
0457: }
0458: }
0459:
0460: this .imports = imports1;
0461: }
0462:
0463: // TODO redefines?
0464: // should do over-writing here
0465: // build schema object ... be thrown out
0466: DefaultSchema schema1 = new DefaultSchema();
0467: schema1.attributeFormDefault = attributeFormDefault;
0468: schema1.elementFormDefault = elementFormDefault;
0469: schema1.finalDefault = finalDefault;
0470: schema1.blockDefault = blockDefault;
0471: schema1.id = id;
0472: schema1.prefix = prefix;
0473: schema1.targetNamespace = targetNamespace;
0474: schema1.version = version;
0475: schema1.uri = uri;
0476:
0477: if (imports != null) {
0478: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0479: tmp.addAll(imports);
0480: schema1.imports = (Schema[]) tmp.toArray(new Schema[tmp
0481: .size()]);
0482: }
0483:
0484: // these need to be retyped
0485:
0486: if (simpleTypes != null) {
0487: it = simpleTypes.iterator();
0488: HashSet cache = new HashSet();
0489: while (it.hasNext()) {
0490: Object t = it.next();
0491: if (t instanceof SimpleTypeHandler) {
0492: SimpleTypeHandler tt = (SimpleTypeHandler) t;
0493: cache.add(tt.compress(this ));
0494: it.remove();
0495: }
0496: }
0497: it = cache.iterator();
0498: while (it.hasNext())
0499: simpleTypes.add(it.next());
0500:
0501: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0502: tmp.addAll(simpleTypes);
0503: schema1.simpleTypes = (SimpleType[]) tmp
0504: .toArray(new SimpleType[tmp.size()]);
0505: }
0506:
0507: if (attributeGroups != null) {
0508: it = attributeGroups.iterator();
0509: HashSet cache = new HashSet();
0510: while (it.hasNext()) {
0511: Object t = it.next();
0512: if (t instanceof AttributeGroupHandler) {
0513: AttributeGroupHandler tt = (AttributeGroupHandler) t;
0514: cache.add(tt.compress(this ));
0515: it.remove();
0516: }
0517: }
0518: it = cache.iterator();
0519: while (it.hasNext())
0520: attributeGroups.add(it.next());
0521:
0522: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0523: tmp.addAll(attributeGroups);
0524: schema1.attributeGroups = (AttributeGroup[]) tmp
0525: .toArray(new AttributeGroup[tmp.size()]);
0526: }
0527:
0528: if (attributes != null) {
0529: it = attributes.iterator();
0530: HashSet cache = new HashSet();
0531: while (it.hasNext()) {
0532: Object t = it.next();
0533: if (t instanceof AttributeHandler) {
0534: AttributeHandler tt = (AttributeHandler) t;
0535: cache.add(tt.compress(this ));
0536: it.remove();
0537: }
0538: }
0539: it = cache.iterator();
0540: while (it.hasNext())
0541: attributes.add(it.next());
0542:
0543: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0544: tmp.addAll(attributes);
0545: schema1.attributes = (Attribute[]) tmp
0546: .toArray(new Attribute[tmp.size()]);
0547: }
0548:
0549: if (complexTypes != null) {
0550: it = complexTypes.iterator();
0551: HashSet cache = new HashSet();
0552: while (it.hasNext()) {
0553: Object t = it.next();
0554: if (t instanceof ComplexTypeHandler) {
0555: ComplexTypeHandler tt = (ComplexTypeHandler) t;
0556: cache.add(tt.compress(this ));
0557: }
0558: }
0559: complexTypes.clear();
0560: it = cache.iterator();
0561: while (it.hasNext())
0562: complexTypes.add(it.next());
0563:
0564: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0565: tmp.addAll(complexTypes);
0566: schema1.complexTypes = (ComplexType[]) tmp
0567: .toArray(new ComplexType[tmp.size()]);
0568: }
0569:
0570: if (elements != null) {
0571: it = elements.iterator();
0572: HashSet cache = new HashSet();
0573: while (it.hasNext()) {
0574: Object t = it.next();
0575: if (t instanceof ElementTypeHandler) {
0576: ElementTypeHandler tt = (ElementTypeHandler) t;
0577: cache.add(tt.compress(this ));
0578: it.remove();
0579: }
0580: }
0581: it = cache.iterator();
0582: while (it.hasNext())
0583: elements.add(it.next());
0584:
0585: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0586: tmp.addAll(elements);
0587: schema1.elements = (Element[]) tmp.toArray(new Element[tmp
0588: .size()]);
0589: }
0590:
0591: if (groups != null) {
0592: it = groups.iterator();
0593: HashSet cache = new HashSet();
0594: while (it.hasNext()) {
0595: Object t = it.next();
0596: if (t instanceof GroupHandler) {
0597: GroupHandler tt = (GroupHandler) t;
0598: cache.add(tt.compress(this ));
0599: it.remove();
0600: }
0601: }
0602: it = cache.iterator();
0603: while (it.hasNext())
0604: groups.add(it.next());
0605:
0606: TreeSet tmp = new TreeSet(SchemaComparator.getInstance());
0607: tmp.addAll(groups);
0608: schema1.groups = (Group[]) tmp
0609: .toArray(new Group[tmp.size()]);
0610: }
0611:
0612: attributeGroups = attributes = complexTypes = simpleTypes = elements = groups = imports = includes = redefines = null;
0613:
0614: return schema1;
0615: }
0616:
0617: /*
0618: * Helper method for lookUpSimpleType(String)
0619: */
0620: private SimpleType lookUpSimpleType(String localName, Schema s,
0621: TreeSet targets) {
0622: if (s == null) {
0623: return null;
0624: }
0625:
0626: targets.add(s.getTargetNamespace());
0627:
0628: if (s.getSimpleTypes() != null) {
0629: SimpleType[] sts = s.getSimpleTypes();
0630:
0631: for (int i = 0; (sts != null) && (i < sts.length); i++) {
0632: if (localName.equalsIgnoreCase(sts[i].getName())) {
0633: return sts[i];
0634: }
0635: }
0636: }
0637:
0638: if (s.getImports() != null) {
0639: Schema[] ss = s.getImports();
0640:
0641: for (int i = 0; (ss != null) && (i < ss.length); i++) {
0642: if (!targets.contains(ss[i].getTargetNamespace())) {
0643: SimpleType st = lookUpSimpleType(localName, ss[i],
0644: targets);
0645:
0646: if (st != null) {
0647: return st;
0648: }
0649: }
0650: }
0651: }
0652:
0653: return null;
0654: }
0655:
0656: /**
0657: * <p>
0658: * convinience method for package classes
0659: * </p>
0660: *
0661: * @param qname
0662: */
0663: protected SimpleType lookUpSimpleType(String qname) {
0664: int index = qname.indexOf(":");
0665: String localName, prefix1;
0666: localName = prefix1 = null;
0667: if (index >= 0) {
0668: localName = qname.substring(index + 1);
0669: prefix1 = qname.substring(0, index);
0670: } else {
0671: prefix1 = "";
0672: localName = qname;
0673: }
0674: logger.finest("prefix is " + prefix1);
0675: logger.finest("localName is " + localName);
0676: Iterator it;
0677: if ((this .prefix == null && prefix1 == null)
0678: || (this .prefix != null && this .prefix.equals(prefix1))) {
0679: if (schema != null)
0680: return lookUpSimpleType(localName, schema,
0681: new TreeSet());
0682: } else {
0683: if (imports != null) {
0684: it = imports.iterator();
0685: while (it.hasNext()) {
0686: Schema s = (Schema) it.next();
0687: String ns = s.getTargetNamespace().toString();
0688:
0689: String prefixLookup = prefixCache != null ? (String) prefixCache
0690: .get(ns)
0691: : null;
0692: if (prefix1 == null || prefixLookup == null
0693: || prefix1.equals(prefixLookup)) {
0694: SimpleType st = lookUpSimpleType(localName, s,
0695: new TreeSet());
0696: if (st != null) {
0697: return st;
0698: }
0699: }
0700: }
0701: }
0702: }
0703:
0704: if (simpleTypes != null) {
0705: it = simpleTypes.iterator();
0706:
0707: while (it.hasNext()) {
0708: Object o = it.next();
0709:
0710: if (o instanceof SimpleTypeHandler) {
0711: SimpleTypeHandler sst = (SimpleTypeHandler) o;
0712:
0713: if (localName.equalsIgnoreCase(sst.getName())) {
0714: return sst.compress(this );
0715: }
0716: } else {
0717: SimpleType sst = (SimpleType) o;
0718:
0719: if (localName.equalsIgnoreCase(sst.getName())) {
0720: return sst;
0721: }
0722: }
0723: }
0724: }
0725:
0726: SimpleType sti = XSISimpleTypes.find(localName);
0727:
0728: if (sti != null) {
0729: return sti;
0730: }
0731:
0732: return null;
0733: }
0734:
0735: /*
0736: * helper for lookUpComplexType(String)
0737: */
0738: private ComplexType lookUpComplexType(String localName, Schema s,
0739: TreeSet targets) {
0740: if (s == null) {
0741: return null;
0742: }
0743:
0744: targets.add(s.getTargetNamespace());
0745:
0746: if (s.getComplexTypes() != null) {
0747: ComplexType[] sts = s.getComplexTypes();
0748:
0749: for (int i = 0; (sts != null) && (i < sts.length); i++) {
0750: String name = sts[i].getName();
0751: if (localName.equalsIgnoreCase(name)) {
0752: return sts[i];
0753: }
0754: }
0755: }
0756:
0757: if (s.getImports() != null) {
0758: Schema[] ss = s.getImports();
0759:
0760: for (int i = 0; (ss != null) && (i < ss.length); i++) {
0761: if (!targets.contains(ss[i].getTargetNamespace())) {
0762: ComplexType st = lookUpComplexType(localName,
0763: ss[i], targets);
0764:
0765: if (st != null) {
0766: return st;
0767: }
0768: }
0769: }
0770: }
0771:
0772: return null;
0773: }
0774:
0775: /**
0776: * <p>
0777: * convinience method for package
0778: * </p>
0779: *
0780: * @param qname
0781: * @throws SAXException
0782: */
0783: protected ComplexType lookUpComplexType(String qname)
0784: throws SAXException {
0785: int index = qname.indexOf(":");
0786: String localName, prefix1;
0787: localName = prefix1 = null;
0788: if (index >= 0) {
0789: localName = qname.substring(index + 1);
0790: prefix1 = qname.substring(0, index);
0791: } else {
0792: prefix1 = "";
0793: localName = qname;
0794: }
0795: logger.finest("prefix is " + prefix1);
0796: logger.finest("localName is " + localName);
0797:
0798: Iterator it;
0799: if ((this .prefix == null && prefix1 == null)
0800: || (this .prefix != null && this .prefix.equals(prefix1))) {
0801: if (schema != null)
0802: return lookUpComplexType(localName, schema,
0803: new TreeSet());
0804: } else {
0805: if (imports != null) {
0806: it = imports.iterator();
0807: while (it.hasNext()) {
0808: Schema s = (Schema) it.next();
0809: String ns = s.getTargetNamespace().toString();
0810: String prefixLookup = prefixCache != null ? (String) prefixCache
0811: .get(ns)
0812: : null;
0813: if (prefix1 == null || prefixLookup == null
0814: || prefix1.equals(prefixLookup)) {
0815: ComplexType ct = lookUpComplexType(localName,
0816: s, new TreeSet());
0817: if (ct != null) {
0818: return ct;
0819: }
0820: }
0821: }
0822: }
0823: }
0824:
0825: if (complexTypes != null) {
0826: it = complexTypes.iterator();
0827:
0828: while (it.hasNext()) {
0829: Object o = it.next();
0830:
0831: if (o instanceof ComplexTypeHandler) {
0832: ComplexTypeHandler sst = (ComplexTypeHandler) o;
0833:
0834: if (localName.equalsIgnoreCase(sst.getName())) {
0835: return sst.compress(this );
0836: }
0837: } else {
0838: ComplexType sst = (ComplexType) o;
0839:
0840: if (localName.equalsIgnoreCase(sst.getName())) {
0841: return sst;
0842: }
0843: }
0844: }
0845: }
0846:
0847: return null;
0848: }
0849:
0850: /*
0851: * helper method for lookupElement(String)
0852: */
0853: private Element lookupElement(String localName, Schema s,
0854: TreeSet targets) {
0855: if (s == null) {
0856: return null;
0857: }
0858:
0859: logger.finest("looking for element in "
0860: + s.getTargetNamespace());
0861: targets.add(s.getTargetNamespace());
0862:
0863: if (s.getElements() != null) {
0864: Element[] sts = s.getElements();
0865:
0866: for (int i = 0; (sts != null) && (i < sts.length); i++) {
0867: String name = sts[i].getName();
0868: logger.finest("checking element " + name);
0869:
0870: if (localName.equalsIgnoreCase(name)) {
0871: return sts[i];
0872: }
0873: }
0874: }
0875:
0876: if (s.getImports() != null) {
0877: Schema[] ss = s.getImports();
0878:
0879: for (int i = 0; (ss != null) && (i < ss.length); i++) {
0880: if (!targets.contains(ss[i].getTargetNamespace())) {
0881: Element st = lookupElement(localName, ss[i],
0882: targets);
0883:
0884: if (st != null) {
0885: return st;
0886: }
0887: }
0888: }
0889: }
0890:
0891: return null;
0892: }
0893:
0894: /**
0895: * <p>
0896: * convinience method for package
0897: * </p>
0898: *
0899: * @param qname
0900: * @throws SAXException
0901: */
0902: protected Element lookUpElement(String qname) throws SAXException {
0903: int index = qname.indexOf(":");
0904: String localName, prefix1;
0905: localName = prefix1 = null;
0906: if (index >= 0) {
0907: localName = qname.substring(index + 1);
0908: prefix1 = qname.substring(0, index);
0909: } else {
0910: prefix1 = "";
0911: localName = qname;
0912: }
0913: logger.finest("prefix is " + prefix1);
0914: logger.finest("localName is " + localName);
0915:
0916: Iterator it;
0917: if ((this .prefix == null && prefix1 == null)
0918: || (this .prefix != null && this .prefix.equals(prefix1))) {
0919: if (schema != null)
0920: return lookupElement(localName, schema, new TreeSet());
0921: } else {
0922: if (imports != null) {
0923: it = imports.iterator();
0924: while (it.hasNext()) {
0925: Schema s = (Schema) it.next();
0926: String ns = s.getTargetNamespace().toString();
0927: String prefixLookup = prefixCache != null ? (String) prefixCache
0928: .get(ns)
0929: : null;
0930: if (prefix1 == null || prefixLookup == null
0931: || prefix1.equals(prefixLookup)) {
0932: Element ct = lookupElement(localName, s,
0933: new TreeSet());
0934: if (ct != null) {
0935: return ct;
0936: }
0937: }
0938: }
0939: }
0940: if (includes != null) {
0941: it = includes.iterator();
0942: while (it.hasNext()) {
0943: Schema s = (Schema) it.next();
0944: String ns = s.getTargetNamespace().toString();
0945: String prefixLookup = prefixCache != null ? (String) prefixCache
0946: .get(ns)
0947: : null;
0948: if (prefix1 == null || prefixLookup == null
0949: || prefix1.equals(prefixLookup)) {
0950: Element ct = lookupElement(localName, s,
0951: new TreeSet());
0952: if (ct != null) {
0953: return ct;
0954: }
0955: }
0956: }
0957: }
0958: }
0959:
0960: it = elements.iterator();
0961:
0962: while (it.hasNext()) {
0963: Object o = it.next();
0964:
0965: if (o instanceof ElementTypeHandler) {
0966: ElementTypeHandler sst = (ElementTypeHandler) o;
0967:
0968: if (localName.equalsIgnoreCase(sst.getName())) {
0969: return (Element) sst.compress(this );
0970: }
0971: } else {
0972: Element sst = (Element) o;
0973:
0974: if (localName.equalsIgnoreCase(sst.getName())) {
0975: return sst;
0976: }
0977: }
0978: }
0979: return null;
0980: }
0981:
0982: /*
0983: * helper for lookUpGroup
0984: */
0985: private Group lookUpGroup(String localName, Schema s,
0986: TreeSet targets) {
0987: if (s == null) {
0988: return null;
0989: }
0990:
0991: targets.add(s.getTargetNamespace());
0992:
0993: if (s.getGroups() != null) {
0994: Group[] sts = s.getGroups();
0995:
0996: for (int i = 0; (sts != null) && (i < sts.length); i++) {
0997: if (localName.equalsIgnoreCase(sts[i].getName())) {
0998: return sts[i];
0999: }
1000: }
1001: }
1002:
1003: if (s.getImports() != null) {
1004: Schema[] ss = s.getImports();
1005:
1006: for (int i = 0; (ss != null) && (i < ss.length); i++) {
1007: if (!targets.contains(ss[i].getTargetNamespace())) {
1008: Group st = lookUpGroup(localName, ss[i], targets);
1009:
1010: if (st != null) {
1011: return st;
1012: }
1013: }
1014: }
1015: }
1016:
1017: return null;
1018: }
1019:
1020: /**
1021: * <p>
1022: * convinience method for package
1023: * </p>
1024: *
1025: * @param qname
1026: * @throws SAXException
1027: */
1028: protected Group lookUpGroup(String qname) throws SAXException {
1029: int index = qname.indexOf(":");
1030: String localName, prefix1;
1031: localName = prefix1 = null;
1032: if (index >= 0) {
1033: localName = qname.substring(index + 1);
1034: prefix1 = qname.substring(0, index);
1035: } else {
1036: prefix1 = "";
1037: localName = qname;
1038: }
1039: logger.finest("prefix is " + prefix1);
1040: logger.finest("localName is " + localName);
1041:
1042: Iterator it;
1043: if ((this .prefix == null && prefix1 == null)
1044: || (this .prefix != null && this .prefix.equals(prefix1))) {
1045: if (schema != null)
1046: return lookUpGroup(localName, schema, new TreeSet());
1047: } else {
1048: if (imports != null) {
1049: it = imports.iterator();
1050: while (it.hasNext()) {
1051: Schema s = (Schema) it.next();
1052: String ns = s.getTargetNamespace().toString();
1053: String prefixLookup = prefixCache != null ? (String) prefixCache
1054: .get(ns)
1055: : null;
1056: if (prefix1 == null || prefixLookup == null
1057: || prefix1.equals(prefixLookup)) {
1058: Group ct = lookUpGroup(localName, s,
1059: new TreeSet());
1060: if (ct != null) {
1061: return ct;
1062: }
1063: }
1064: }
1065: }
1066: }
1067:
1068: if (groups != null) {
1069: it = groups.iterator();
1070:
1071: while (it.hasNext()) {
1072: Object o = it.next();
1073:
1074: if (o instanceof GroupHandler) {
1075: GroupHandler sst = (GroupHandler) o;
1076:
1077: if (localName.equalsIgnoreCase(sst.getName())) {
1078: return (Group) sst.compress(this );
1079: }
1080: } else {
1081: Group sst = (Group) o;
1082:
1083: if (localName.equalsIgnoreCase(sst.getName())) {
1084: return sst;
1085: }
1086: }
1087: }
1088: }
1089:
1090: return null;
1091: }
1092:
1093: /*
1094: * helper method for lookUpAttributeGroup
1095: */
1096: private AttributeGroup lookUpAttributeGroup(String localName,
1097: Schema s, TreeSet targets) {
1098: if (s == null) {
1099: return null;
1100: }
1101:
1102: targets.add(s.getTargetNamespace());
1103:
1104: if (s.getAttributeGroups() != null) {
1105: AttributeGroup[] sts = s.getAttributeGroups();
1106:
1107: for (int i = 0; (sts != null) && (i < sts.length); i++) {
1108: if (localName.equalsIgnoreCase(sts[i].getName())) {
1109: return sts[i];
1110: }
1111: }
1112: }
1113:
1114: if (s.getImports() != null) {
1115: Schema[] ss = s.getImports();
1116:
1117: for (int i = 0; (ss != null) && (i < ss.length); i++) {
1118: if (!targets.contains(ss[i].getTargetNamespace())) {
1119: AttributeGroup st = lookUpAttributeGroup(localName,
1120: ss[i], targets);
1121:
1122: if (st != null) {
1123: return st;
1124: }
1125: }
1126: }
1127: }
1128:
1129: return null;
1130: }
1131:
1132: /**
1133: * <p>
1134: * convinience method for the package
1135: * </p>
1136: *
1137: * @param qname
1138: * @throws SAXException
1139: */
1140: protected AttributeGroup lookUpAttributeGroup(String qname)
1141: throws SAXException {
1142: int index = qname.indexOf(":");
1143: String localName, prefix1;
1144: localName = prefix1 = null;
1145: if (index >= 0) {
1146: localName = qname.substring(index + 1);
1147: prefix1 = qname.substring(0, index);
1148: } else {
1149: prefix1 = "";
1150: localName = qname;
1151: }
1152: logger.finest("prefix is " + prefix1);
1153: logger.finest("localName is " + localName);
1154:
1155: Iterator it;
1156: if ((this .prefix == null && prefix1 == null)
1157: || (this .prefix != null && this .prefix.equals(prefix1))) {
1158: if (schema != null)
1159: return lookUpAttributeGroup(localName, schema,
1160: new TreeSet());
1161: } else {
1162: if (imports != null) {
1163: it = imports.iterator();
1164: while (it.hasNext()) {
1165: Schema s = (Schema) it.next();
1166: String ns = s.getTargetNamespace().toString();
1167: String prefixLookup = prefixCache != null ? (String) prefixCache
1168: .get(ns)
1169: : null;
1170: if (prefix1 == null || prefixLookup == null
1171: || prefix1.equals(prefixLookup)) {
1172: AttributeGroup ct = lookUpAttributeGroup(
1173: localName, s, new TreeSet());
1174: if (ct != null) {
1175: return ct;
1176: }
1177: }
1178: }
1179: }
1180: }
1181:
1182: if (attributeGroups != null) {
1183: it = attributeGroups.iterator();
1184:
1185: while (it.hasNext()) {
1186: Object o = it.next();
1187:
1188: if (o instanceof AttributeGroupHandler) {
1189: AttributeGroupHandler sst = (AttributeGroupHandler) o;
1190:
1191: if (localName.equalsIgnoreCase(sst.getName())) {
1192: return sst.compress(this );
1193: }
1194: } else {
1195: AttributeGroup sst = (AttributeGroup) o;
1196:
1197: if (localName.equalsIgnoreCase(sst.getName())) {
1198: return sst;
1199: }
1200: }
1201: }
1202: }
1203:
1204: return null;
1205: }
1206:
1207: /*
1208: * helper method for lookUpAttribute
1209: */
1210: private Attribute lookUpAttribute(String localName, Schema s,
1211: TreeSet targets) {
1212: if (s == null) {
1213: return null;
1214: }
1215:
1216: targets.add(s.getTargetNamespace());
1217:
1218: if (s.getAttributes() != null) {
1219: Attribute[] sts = s.getAttributes();
1220:
1221: for (int i = 0; (sts != null) && (i < sts.length); i++) {
1222: if (sts[i] != null && sts[i].getName() != null) {
1223: if (localName.equalsIgnoreCase(sts[i].getName())) {
1224: return sts[i];
1225: }
1226: }
1227: }
1228: }
1229:
1230: if (s.getImports() != null) {
1231: Schema[] ss = s.getImports();
1232:
1233: for (int i = 0; (ss != null) && (i < ss.length); i++) {
1234: if (!targets.contains(ss[i].getTargetNamespace())) {
1235: Attribute st = lookUpAttribute(localName, ss[i],
1236: targets);
1237:
1238: if (st != null) {
1239: return st;
1240: }
1241: }
1242: }
1243: }
1244:
1245: return null;
1246: }
1247:
1248: /**
1249: * <p>
1250: * convinience method for package
1251: * </p>
1252: *
1253: * @param qname
1254: * @throws SAXException
1255: */
1256: protected Attribute lookUpAttribute(String qname)
1257: throws SAXException {
1258: int index = qname.indexOf(":");
1259: String localName, prefix1;
1260: localName = prefix1 = null;
1261: if (index >= 0) {
1262: localName = qname.substring(index + 1);
1263: prefix1 = qname.substring(0, index);
1264: } else {
1265: prefix1 = "";
1266: localName = qname;
1267: }
1268: logger.finest("prefix is " + prefix1);
1269: logger.finest("localName is " + localName);
1270:
1271: Iterator it;
1272: if ((this .prefix == null && prefix1 == null)
1273: || (this .prefix != null && this .prefix.equals(prefix1))) {
1274: if (schema != null)
1275: return lookUpAttribute(localName, schema, new TreeSet());
1276: } else {
1277: if (imports != null) {
1278: it = imports.iterator();
1279: while (it.hasNext()) {
1280: Schema s = (Schema) it.next();
1281: String ns = s.getTargetNamespace().toString();
1282: String prefixLookup = prefixCache != null ? (String) prefixCache
1283: .get(ns)
1284: : null;
1285: if (prefix1 == null || prefixLookup == null
1286: || prefix1.equals(prefixLookup)) {
1287: Attribute ct = lookUpAttribute(localName, s,
1288: new TreeSet());
1289: if (ct != null) {
1290: return ct;
1291: }
1292: }
1293: }
1294: }
1295: }
1296:
1297: if (attributes != null) {
1298: it = attributes.iterator();
1299:
1300: while (it.hasNext()) {
1301: Object o = it.next();
1302:
1303: if (o instanceof AttributeHandler) {
1304: AttributeHandler sst = (AttributeHandler) o;
1305:
1306: if (localName.equalsIgnoreCase(sst.getName())) {
1307: return sst.compress(this );
1308: }
1309: } else {
1310: Attribute sst = (Attribute) o;
1311:
1312: if (localName.equalsIgnoreCase(sst.getName())) {
1313: return sst;
1314: }
1315: }
1316: }
1317: }
1318:
1319: return null;
1320: }
1321:
1322: /**
1323: * <p>
1324: * convinience method for package
1325: * </p>
1326: *
1327: * @param qname
1328: * @throws SAXException
1329: */
1330: protected Type lookUpType(String qname) throws SAXException {
1331: if (qname == null)
1332: return null;
1333: Type t = null;
1334: t = lookUpComplexType(qname);
1335: t = t == null ? lookUpSimpleType(qname) : t;
1336: return t;
1337: }
1338:
1339: /*
1340: * helper method that merges the provided Schema into this Schema
1341: */
1342: private void addSchema(Schema s) {
1343: Object[] objs = null;
1344:
1345: objs = s.getAttributes();
1346:
1347: if (objs != null) {
1348: if ((attributes == null) && (objs.length > 0)) {
1349: attributes = new LinkedList();
1350: }
1351:
1352: for (int i = 0; i < objs.length; i++)
1353: attributes.add(objs[i]);
1354: }
1355:
1356: objs = s.getAttributeGroups();
1357:
1358: if (objs != null) {
1359: if ((attributeGroups == null) && (objs.length > 0)) {
1360: attributeGroups = new LinkedList();
1361: }
1362:
1363: for (int i = 0; i < objs.length; i++)
1364: attributeGroups.add(objs[i]);
1365: }
1366:
1367: objs = s.getComplexTypes();
1368:
1369: if (objs != null) {
1370: if ((complexTypes == null) && (objs.length > 0)) {
1371: complexTypes = new LinkedList();
1372: }
1373:
1374: for (int i = 0; i < objs.length; i++)
1375: complexTypes.add(objs[i]);
1376: }
1377:
1378: objs = s.getElements();
1379:
1380: if (objs != null) {
1381: if ((elements == null) && (objs.length > 0)) {
1382: elements = new LinkedList();
1383: }
1384:
1385: for (int i = 0; i < objs.length; i++)
1386: elements.add(objs[i]);
1387: }
1388:
1389: objs = s.getGroups();
1390:
1391: if (objs != null) {
1392: if ((groups == null) && (objs.length > 0)) {
1393: groups = new LinkedList();
1394: }
1395:
1396: for (int i = 0; i < objs.length; i++)
1397: groups.add(objs[i]);
1398: }
1399:
1400: objs = s.getImports();
1401:
1402: if (objs != null) {
1403: if ((imports == null) && (objs.length > 0)) {
1404: imports = new LinkedList();
1405: }
1406:
1407: for (int i = 0; i < objs.length; i++)
1408: imports.add(objs[i]);
1409: }
1410:
1411: objs = s.getSimpleTypes();
1412:
1413: if (objs != null) {
1414: if ((simpleTypes == null) && (objs.length > 0)) {
1415: simpleTypes = new LinkedList();
1416: }
1417:
1418: for (int i = 0; i < objs.length; i++)
1419: simpleTypes.add(objs[i]);
1420: }
1421:
1422: URI tempuri = s.getURI();
1423:
1424: if (uri == null) {
1425: uri = tempuri;
1426: } else {
1427: if (tempuri != null) {
1428: uri = tempuri.resolve(uri);
1429: }
1430: }
1431: }
1432:
1433: /**
1434: * DOCUMENT ME!
1435: *
1436: * @return Returns the targetNamespace.
1437: */
1438: public URI getTargetNamespace() {
1439: return targetNamespace;
1440: }
1441:
1442: /**
1443: * @see org.geotools.xml.XSIElementHandler#getHandlerType()
1444: */
1445: public int getHandlerType() {
1446: return DEFAULT;
1447: }
1448:
1449: /**
1450: * @see org.geotools.xml.XSIElementHandler#endElement(java.lang.String,
1451: * java.lang.String)
1452: */
1453: public void endElement(String namespaceURI1, String localName) {
1454: // do nothing
1455: }
1456:
1457: /**
1458: * <p>
1459: * Default implementation of a Schema for a parsed schema.
1460: * </p>
1461: *
1462: * @author dzwiers
1463: *
1464: * @see Schema
1465: */
1466: private static class DefaultSchema implements Schema {
1467: // file visible to avoid set* methods
1468: boolean attributeFormDefault;
1469: boolean elementFormDefault;
1470: String id;
1471: URI targetNamespace;
1472: String version;
1473: int finalDefault;
1474: int blockDefault;
1475: URI uri;
1476: Schema[] imports;
1477: SimpleType[] simpleTypes;
1478: ComplexType[] complexTypes;
1479: AttributeGroup[] attributeGroups;
1480: Attribute[] attributes;
1481: Element[] elements;
1482: Group[] groups;
1483: String prefix;
1484:
1485: /**
1486: * @see org.geotools.xml.xsi.Schema#isAttributeFormDefault()
1487: */
1488: public boolean isAttributeFormDefault() {
1489: return attributeFormDefault;
1490: }
1491:
1492: /**
1493: * @see org.geotools.xml.xsi.Schema#getAttributeGroups()
1494: */
1495: public AttributeGroup[] getAttributeGroups() {
1496: return attributeGroups;
1497: }
1498:
1499: /**
1500: * @see org.geotools.xml.xsi.Schema#getAttributes()
1501: */
1502: public Attribute[] getAttributes() {
1503: return attributes;
1504: }
1505:
1506: /**
1507: * @see org.geotools.xml.xsi.Schema#getBlockDefault()
1508: */
1509: public int getBlockDefault() {
1510: return blockDefault;
1511: }
1512:
1513: /**
1514: * @see org.geotools.xml.xsi.Schema#getComplexTypes()
1515: */
1516: public ComplexType[] getComplexTypes() {
1517: return complexTypes;
1518: }
1519:
1520: /**
1521: * @see org.geotools.xml.xsi.Schema#isElementFormDefault()
1522: */
1523: public boolean isElementFormDefault() {
1524: return elementFormDefault;
1525: }
1526:
1527: /**
1528: * @see org.geotools.xml.xsi.Schema#getElements()
1529: */
1530: public Element[] getElements() {
1531: return elements;
1532: }
1533:
1534: /**
1535: * @see org.geotools.xml.xsi.Schema#getFinalDefault()
1536: */
1537: public int getFinalDefault() {
1538: return finalDefault;
1539: }
1540:
1541: /**
1542: * @see org.geotools.xml.xsi.Schema#getId()
1543: */
1544: public String getId() {
1545: return id;
1546: }
1547:
1548: /**
1549: * @see org.geotools.xml.xsi.Schema#getImports()
1550: */
1551: public Schema[] getImports() {
1552: return imports;
1553: }
1554:
1555: /**
1556: * @see org.geotools.xml.xsi.Schema#getSimpleTypes()
1557: */
1558: public SimpleType[] getSimpleTypes() {
1559: return simpleTypes;
1560: }
1561:
1562: /**
1563: * @see org.geotools.xml.xsi.Schema#getTargetNamespace()
1564: */
1565: public URI getTargetNamespace() {
1566: return targetNamespace;
1567: }
1568:
1569: /**
1570: * @see org.geotools.xml.xsi.Schema#getURI()
1571: */
1572: public URI getURI() {
1573: return uri;
1574: }
1575:
1576: /**
1577: * @see org.geotools.xml.xsi.Schema#getVersion()
1578: */
1579: public String getVersion() {
1580: return version;
1581: }
1582:
1583: /**
1584: * @see org.geotools.xml.xsi.Schema#getGroups()
1585: */
1586: public Group[] getGroups() {
1587: return groups;
1588: }
1589:
1590: /**
1591: * @see org.geotools.xml.xsi.Schema#includesURI(java.net.URI)
1592: */
1593: public boolean includesURI(URI uri1) {
1594: if (this .uri == null) {
1595: return false;
1596: }
1597: return this .uri.equals(uri1);
1598: }
1599:
1600: /**
1601: * @see org.geotools.xml.schema.Schema#getPrefix()
1602: */
1603: public String getPrefix() {
1604: return prefix;
1605: }
1606:
1607: /**
1608: * Returns the implementation hints. The default implementation returns en empty map.
1609: */
1610: public Map getImplementationHints() {
1611: return Collections.EMPTY_MAP;
1612: }
1613: }
1614:
1615: /**
1616: *
1617: * This class breaks both the collections api and the comparable api.
1618: * When an object is a temp ... thus we don't care ... it's always less
1619: than.
1620: * Please do not use this unless you fully understand it. It is intended to
1621: * be used for compressing two schemas and to remove duplicates resulting
1622: values (not placeholders).
1623: * Making this evaluate place holders would cause the parser to fail !!!
1624: *
1625: * @author dzwiers
1626: *
1627: */
1628: private static class SchemaComparator implements Comparator {
1629: private static SchemaComparator instance = new SchemaComparator();
1630:
1631: public static SchemaComparator getInstance() {
1632: return instance;
1633: }
1634:
1635: /* (non-Javadoc)
1636: * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
1637: */
1638: public int compare(Object arg0, Object arg1) {
1639: // attribute
1640: if (arg0 instanceof Attribute && arg1 instanceof Attribute)
1641: return compareAttribute((Attribute) arg0,
1642: (Attribute) arg1);
1643: // attrbute group
1644: if (arg0 instanceof AttributeGroup
1645: && arg1 instanceof AttributeGroup)
1646: return compareAttributeGroup((AttributeGroup) arg0,
1647: (AttributeGroup) arg1);
1648: // complex type
1649: if (arg0 instanceof ComplexType
1650: && arg1 instanceof ComplexType)
1651: return compareComplexType((ComplexType) arg0,
1652: (ComplexType) arg1);
1653: // simpletype
1654: if (arg0 instanceof SimpleType
1655: && arg1 instanceof SimpleType)
1656: return compareSimpleType((SimpleType) arg0,
1657: (SimpleType) arg1);
1658: // group
1659: if (arg0 instanceof Group && arg1 instanceof Group)
1660: return compareGroup((Group) arg0, (Group) arg1);
1661: // element
1662: if (arg0 instanceof Element && arg1 instanceof Element)
1663: return compareElement((Element) arg0, (Element) arg1);
1664: // imports
1665: if (arg0 instanceof Schema && arg1 instanceof Schema)
1666: return compareImport((Schema) arg0, (Schema) arg1);
1667:
1668: return -1; // hack for unresolved portions
1669: // throw new ClassCastException("Unknown type "+arg0.getClass().getName());
1670: }
1671:
1672: private int compareAttribute(Attribute arg0, Attribute arg1) {
1673: if (arg0 == arg1)
1674: return 0;
1675: if (arg0 == null)
1676: return 1;
1677: if (arg1 == null)
1678: return -1;
1679: int i = arg0.getName() == null ? arg1.getName() == null ? 0
1680: : 1 : arg0.getName().compareTo(arg1.getName());
1681: if (i != 0)
1682: return i;
1683: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
1684: : 1
1685: : arg0.getNamespace()
1686: .compareTo(arg1.getNamespace());
1687: if (i != 0)
1688: return i;
1689: i = arg0.getUse() - arg1.getUse();
1690: if (i != 0)
1691: return i;
1692: return compareSimpleType(arg0.getSimpleType(), arg1
1693: .getSimpleType());
1694: }
1695:
1696: private int compareAttributeGroup(AttributeGroup arg0,
1697: AttributeGroup arg1) {
1698: if (arg0 == arg1)
1699: return 0;
1700: if (arg0 == null)
1701: return 1;
1702: if (arg1 == null)
1703: return -1;
1704: int i = arg0.getName() == null ? arg1.getName() == null ? 0
1705: : 1 : arg0.getName().compareTo(arg1.getName());
1706: if (i != 0)
1707: return i;
1708: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
1709: : 1
1710: : arg0.getNamespace()
1711: .compareTo(arg1.getNamespace());
1712: if (i != 0)
1713: return i;
1714: i = arg0.getAnyAttributeNameSpace() == null ? arg1
1715: .getAnyAttributeNameSpace() == null ? 0 : 1 : arg0
1716: .getAnyAttributeNameSpace().compareTo(
1717: arg1.getAnyAttributeNameSpace());
1718: if (i != 0)
1719: return i;
1720:
1721: Attribute[] a0 = arg0.getAttributes();
1722: Arrays.sort(a0, this );
1723: Attribute[] a1 = arg1.getAttributes();
1724: Arrays.sort(a1, this );
1725:
1726: if (a0 == a1)
1727: return 0;
1728: if (a0 == null)
1729: return 1;
1730: if (a1 == null)
1731: return -1;
1732:
1733: if (a0.length < a1.length)
1734: return -1;
1735: if (a0.length > a1.length)
1736: return 1;
1737:
1738: for (int j = 0; j < a0.length && i == 0; j++)
1739: i = compareAttribute(a0[j], a1[j]);
1740:
1741: return i;
1742: }
1743:
1744: private int compareGroup(Group arg0, Group arg1) {
1745: if (arg0 == arg1)
1746: return 0;
1747: if (arg0 == null)
1748: return 1;
1749: if (arg1 == null)
1750: return -1;
1751: int i = arg0.getName() == null ? arg1.getName() == null ? 0
1752: : 1 : arg0.getName().compareTo(arg1.getName());
1753: if (i != 0)
1754: return i;
1755: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
1756: : 1
1757: : arg0.getNamespace()
1758: .compareTo(arg1.getNamespace());
1759: if (i != 0)
1760: return i;
1761:
1762: i = arg0.getMaxOccurs() - arg1.getMaxOccurs();
1763: if (i != 0)
1764: return i;
1765:
1766: i = arg0.getMinOccurs() - arg1.getMinOccurs();
1767: if (i != 0)
1768: return i;
1769:
1770: ElementGrouping a0 = arg0.getChild();
1771: ElementGrouping a1 = arg1.getChild();
1772:
1773: if (a0 == a1)
1774: return 0;
1775: if (a0 == null)
1776: return 1;
1777: if (a1 == null)
1778: return -1;
1779:
1780: return compareElementGrouping(a0, a1);
1781: }
1782:
1783: private int compareElement(Element arg0, Element arg1) {
1784: if (arg0 == arg1)
1785: return 0;
1786: if (arg0 == null)
1787: return 1;
1788: if (arg1 == null)
1789: return -1;
1790: int i = arg0.getName() == null ? arg1.getName() == null ? 0
1791: : 1 : arg0.getName().compareTo(arg1.getName());
1792: if (i != 0)
1793: return i;
1794: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
1795: : 1
1796: : arg0.getNamespace()
1797: .compareTo(arg1.getNamespace());
1798: if (i != 0)
1799: return i;
1800:
1801: i = arg0.getMaxOccurs() - arg1.getMaxOccurs();
1802: if (i != 0)
1803: return i;
1804:
1805: i = arg0.getMinOccurs() - arg1.getMinOccurs();
1806: if (i != 0)
1807: return i;
1808:
1809: i = compareElement(arg0.getSubstitutionGroup(), arg1
1810: .getSubstitutionGroup());
1811: if (i != 0)
1812: return i;
1813:
1814: // ignore a few things here ... might need them back
1815:
1816: return compare(arg0.getType(), arg1.getType());
1817: }
1818:
1819: private int compareElementGrouping(ElementGrouping arg0,
1820: ElementGrouping arg1) {
1821: if (arg0 == arg1)
1822: return 0;
1823: if (arg0 == null)
1824: return 1;
1825: if (arg1 == null)
1826: return -1;
1827:
1828: int i = 0;
1829: i = arg0.getGrouping() - arg1.getGrouping();
1830: if (i != 0)
1831: return i;
1832:
1833: i = arg0.getMaxOccurs() - arg1.getMaxOccurs();
1834: if (i != 0)
1835: return i;
1836:
1837: i = arg0.getMinOccurs() - arg1.getMinOccurs();
1838: if (i != 0)
1839: return i;
1840:
1841: ElementGrouping[] eg0 = null;
1842: ElementGrouping[] eg1 = null;
1843:
1844: switch (arg0.getGrouping()) {
1845: case ElementGrouping.ELEMENT:
1846: return compareElement((Element) arg0, (Element) arg1);
1847: case ElementGrouping.GROUP:
1848: return compareGroup((Group) arg0, (Group) arg1);
1849: case ElementGrouping.CHOICE:
1850: Choice c0 = (Choice) arg0;
1851: Choice c1 = (Choice) arg1;
1852: eg0 = c0.getChildren();
1853: eg1 = c1.getChildren();
1854: case ElementGrouping.SEQUENCE:
1855: Sequence s0 = (Sequence) arg0;
1856: Sequence s1 = (Sequence) arg1;
1857: eg0 = s0.getChildren();
1858: eg1 = s1.getChildren();
1859: case ElementGrouping.ALL:
1860: All a0 = (All) arg0;
1861: All a1 = (All) arg1;
1862: eg0 = a0.getElements();
1863: eg1 = a1.getElements();
1864: }
1865:
1866: if (eg0.length < eg1.length)
1867: return -1;
1868: if (eg0.length > eg1.length)
1869: return 1;
1870:
1871: for (int j = 0; j < eg0.length && i != 0; j++)
1872: i = compareElementGrouping(eg0[j], eg1[j]);
1873: return 0;
1874: }
1875:
1876: private int compareImport(Schema arg0, Schema arg1) {
1877: if (arg0 == arg1)
1878: return 0;
1879: if (arg0 == null)
1880: return 1;
1881: if (arg1 == null)
1882: return -1;
1883: int i = arg0.getTargetNamespace() == null ? arg1
1884: .getTargetNamespace() == null ? 0 : 1 : arg0
1885: .getTargetNamespace().compareTo(
1886: arg1.getTargetNamespace());
1887: if (i != 0)
1888: return i;
1889: i = arg0.getURI() == null ? arg1.getURI() == null ? 0 : 1
1890: : arg0.getURI().compareTo(arg1.getURI());
1891: if (i != 0)
1892: return i;
1893:
1894: i = arg0.getElements().length - arg1.getElements().length;
1895: if (i != 0)
1896: return i;
1897:
1898: i = arg0.getComplexTypes().length
1899: - arg1.getComplexTypes().length;
1900: if (i != 0)
1901: return i;
1902:
1903: i = arg0.getSimpleTypes().length
1904: - arg1.getSimpleTypes().length;
1905: if (i != 0)
1906: return i;
1907:
1908: i = arg0.getAttributes().length
1909: - arg1.getAttributes().length;
1910: if (i != 0)
1911: return i;
1912:
1913: i = arg0.getAttributeGroups().length
1914: - arg1.getAttributeGroups().length;
1915: if (i != 0)
1916: return i;
1917:
1918: i = arg0.getGroups().length - arg1.getGroups().length;
1919: if (i != 0)
1920: return i;
1921:
1922: // Yes we are making a huge assumption here.
1923:
1924: return 0;
1925: }
1926:
1927: private int compareSimpleType(SimpleType arg0, SimpleType arg1) {
1928: if (arg0 == arg1)
1929: return 0;
1930: if (arg0 == null)
1931: return 1;
1932: if (arg1 == null)
1933: return -1;
1934: int i = arg0.getName() == null ? arg1.getName() == null ? 0
1935: : 1 : arg0.getName().compareTo(arg1.getName());
1936: if (i != 0)
1937: return i;
1938: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
1939: : 1
1940: : arg0.getNamespace()
1941: .compareTo(arg1.getNamespace());
1942: if (i != 0)
1943: return i;
1944:
1945: SimpleType[] a0 = arg0.getParents();
1946: Arrays.sort(a0, this );
1947: SimpleType[] a1 = arg1.getParents();
1948: Arrays.sort(a1, this );
1949:
1950: if (a0 == a1)
1951: return 0;
1952: if (a0 == null)
1953: return 1;
1954: if (a1 == null)
1955: return -1;
1956:
1957: if (a0.length < a1.length)
1958: return -1;
1959: if (a0.length > a1.length)
1960: return 1;
1961:
1962: for (int j = 0; j < a0.length && i == 0; j++)
1963: i = compareSimpleType(a0[j], a1[j]);
1964:
1965: Facet[] a01 = arg0.getFacets();
1966: Arrays.sort(a0, this );
1967: Facet[] a11 = arg1.getFacets();
1968: Arrays.sort(a1, this );
1969:
1970: if (a01 == a11)
1971: return 0;
1972: if (a01 == null)
1973: return 1;
1974: if (a11 == null)
1975: return -1;
1976:
1977: if (a01.length < a11.length)
1978: return -1;
1979: if (a01.length > a11.length)
1980: return 1;
1981:
1982: for (int j = 0; j < a01.length && i == 0; j++)
1983: i = compareFacet(a01[j], a11[j]);
1984:
1985: return i;
1986: }
1987:
1988: private int compareFacet(Facet arg0, Facet arg1) {
1989: if (arg0 == arg1)
1990: return 0;
1991: if (arg0 == null)
1992: return 1;
1993: if (arg1 == null)
1994: return -1;
1995:
1996: int i = 0;
1997: i = arg0.getFacetType() - arg1.getFacetType();
1998: if (i != 0)
1999: return i;
2000:
2001: i = arg0.getValue() == null ? arg1.getValue() == null ? 0
2002: : 1 : arg0.getValue().compareTo(arg1.getValue());
2003: return i;
2004: }
2005:
2006: private int compareComplexType(ComplexType arg0,
2007: ComplexType arg1) {
2008: if (arg0 == arg1)
2009: return 0;
2010: if (arg0 == null)
2011: return 1;
2012: if (arg1 == null)
2013: return -1;
2014: int i = arg0.getName() == null ? arg1.getName() == null ? 0
2015: : 1 : arg0.getName().compareTo(arg1.getName());
2016: if (i != 0)
2017: return i;
2018: i = arg0.getNamespace() == null ? arg1.getNamespace() == null ? 0
2019: : 1
2020: : arg0.getNamespace()
2021: .compareTo(arg1.getNamespace());
2022: if (i != 0)
2023: return i;
2024:
2025: Type a00 = arg0.getParent();
2026: Type a01 = arg1.getParent();
2027:
2028: if (a00 == a01)
2029: return 0;
2030: if (a00 == null)
2031: return 1;
2032: if (a01 == null)
2033: return -1;
2034:
2035: i = compare(a00, a01);
2036: if (i != 0)
2037: return i;
2038:
2039: i = arg0.getAnyAttributeNameSpace() == null ? arg1
2040: .getAnyAttributeNameSpace() == null ? 0 : 1 : arg0
2041: .getAnyAttributeNameSpace().compareTo(
2042: arg1.getAnyAttributeNameSpace());
2043: if (i != 0)
2044: return i;
2045:
2046: Attribute[] a10 = arg0.getAttributes();
2047: Arrays.sort(a10, this );
2048: Attribute[] a11 = arg1.getAttributes();
2049: Arrays.sort(a11, this );
2050:
2051: if (a10 == a11)
2052: return 0;
2053: if (a10 == null)
2054: return 1;
2055: if (a11 == null)
2056: return -1;
2057:
2058: if (a10.length < a11.length)
2059: return -1;
2060: if (a10.length > a11.length)
2061: return 1;
2062:
2063: for (int j = 0; j < a10.length && i == 0; j++)
2064: i = compareAttribute(a10[j], a11[j]);
2065: if (i != 0)
2066: return i;
2067:
2068: Element[] a0 = arg0.getChildElements();
2069: Arrays.sort(a0, this );
2070: Element[] a1 = arg1.getChildElements();
2071: Arrays.sort(a1, this );
2072:
2073: if (a0 == a1)
2074: return 0;
2075: if (a0 == null)
2076: return 1;
2077: if (a1 == null)
2078: return -1;
2079:
2080: if (a0.length < a1.length)
2081: return -1;
2082: if (a0.length > a1.length)
2083: return 1;
2084:
2085: for (int j = 0; j < a0.length && i == 0; j++)
2086: i = compareElement(a0[j], a1[j]);
2087:
2088: return i;
2089: }
2090: }
2091: }
|