0001: /**
0002: * Redistribution and use of this software and associated documentation
0003: * ("Software"), with or without modification, are permitted provided
0004: * that the following conditions are met:
0005: *
0006: * 1. Redistributions of source code must retain copyright
0007: * statements and notices. Redistributions must also contain a
0008: * copy of this document.
0009: *
0010: * 2. Redistributions in binary form must reproduce the
0011: * above copyright notice, this list of conditions and the
0012: * following disclaimer in the documentation and/or other
0013: * materials provided with the distribution.
0014: *
0015: * 3. The name "Exolab" must not be used to endorse or promote
0016: * products derived from this Software without prior written
0017: * permission of Intalio, Inc. For written permission,
0018: * please contact info@exolab.org.
0019: *
0020: * 4. Products derived from this Software may not be called "Exolab"
0021: * nor may "Exolab" appear in their names without prior written
0022: * permission of Intalio, Inc. Exolab is a registered
0023: * trademark of Intalio, Inc.
0024: *
0025: * 5. Due credit should be given to the Exolab Project
0026: * (http://www.exolab.org/).
0027: *
0028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
0029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
0030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
0031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
0032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
0033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
0035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
0039: * OF THE POSSIBILITY OF SUCH DAMAGE.
0040: *
0041: * Copyright 1999-2003 (C) Intalio, Inc. All Rights Reserved.
0042: *
0043: * $Id: SchemaWriter.java 6908 2007-03-29 08:22:29Z wguttmn $
0044: */package org.exolab.castor.xml.schema.writer;
0045:
0046: import java.io.Writer;
0047: import java.io.IOException;
0048: import java.util.Enumeration;
0049: import org.exolab.castor.types.AnyNode;
0050: import org.exolab.castor.util.LocalConfiguration;
0051: import org.exolab.castor.xml.schema.*;
0052: import org.exolab.castor.xml.schema.simpletypes.ListType;
0053: import org.exolab.castor.xml.util.AnyNode2SAX;
0054: import org.exolab.castor.xml.Namespaces;
0055: import org.exolab.castor.xml.Serializer;
0056:
0057: import org.xml.sax.DocumentHandler;
0058: import org.xml.sax.SAXException;
0059: import org.xml.sax.helpers.AttributeListImpl;
0060:
0061: /**
0062: * A class for serializing Schema models
0063: * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
0064: * @version $Revision: 6908 $ $Date: 2006-04-05 13:16:42 -0600 (Wed, 05 Apr 2006) $
0065: **/
0066: public class SchemaWriter {
0067:
0068: //------------------------/
0069: //- Schema element names -/
0070: //------------------------/
0071:
0072: /**
0073: * Annotation element name.
0074: */
0075: private static final String ANNOTATION = "annotation";
0076:
0077: /**
0078: * AppInfo element name
0079: */
0080: private static final String APPINFO = "appinfo";
0081:
0082: /**
0083: * Attribute element name.
0084: */
0085: private static final String ATTRIBUTE = "attribute";
0086:
0087: /**
0088: * AttributeGroup element name.
0089: */
0090: private static final String ATTRIBUTE_GROUP = "attributeGroup";
0091:
0092: /**
0093: * ComplexType element name.
0094: */
0095: private static final String COMPLEX_TYPE = "complexType";
0096:
0097: /**
0098: * Documentation element name.
0099: */
0100: private static final String DOCUMENTATION = "documentation";
0101:
0102: /**
0103: * Element element name.
0104: */
0105: private static final String ELEMENT = "element";
0106:
0107: /**
0108: * ModelGroup element name.
0109: */
0110: private static final String GROUP = "group";
0111:
0112: /**
0113: * Restriction element name.
0114: */
0115: private static final String RESTRICTION = "restriction";
0116:
0117: /**
0118: * Schema element name.
0119: */
0120: private static final String SCHEMA = "schema";
0121:
0122: /**
0123: * SimpleType element name
0124: */
0125: private static final String SIMPLE_TYPE = "simpleType";
0126:
0127: //-------------------/
0128: //- Attribute names -/
0129: //-------------------/
0130:
0131: private static final String ATTR_NAME = "name";
0132: private static final String ATTR_TYPE = "type";
0133:
0134: private static final String VALUE_TRUE = "true";
0135:
0136: /**
0137: * For use with SAX AttributeList
0138: */
0139: private static final String CDATA = "CDATA";
0140: private static final String XMLNS_PREFIX = "xmlns:";
0141: private static final String XMLNS_DEFAULT = "xmlns";
0142: private static final String DEFAULT_PREFIX = "xsd";
0143:
0144: /**
0145: * The DocumentHandler to send events to
0146: */
0147: private DocumentHandler _handler = null;
0148:
0149: /**
0150: * The AttributeList to send events to
0151: */
0152: private AttributeListImpl _atts = new AttributeListImpl();
0153:
0154: /**
0155: * This field is no longer used and only here for
0156: * backward compatibility.
0157: * @deprecated
0158: **/
0159: public static boolean enable = false;
0160:
0161: /**
0162: * Creates a new SchemaWriter for the given Writer
0163: *
0164: * @param writer the Writer to serialize to
0165: **/
0166: public SchemaWriter(Writer writer) throws IOException {
0167:
0168: Serializer serializer = LocalConfiguration.getInstance()
0169: .getSerializer();
0170:
0171: if (serializer == null)
0172: throw new IOException("Unable to obtain serailizer");
0173:
0174: serializer.setOutputCharStream(writer);
0175:
0176: DocumentHandler handler = serializer.asDocumentHandler();
0177:
0178: if (handler == null) {
0179: String err = "The following serializer is not SAX capable: ";
0180: err += serializer.getClass().getName();
0181: err += "; cannot proceed.";
0182: throw new IOException(err);
0183: }
0184:
0185: _handler = handler;
0186:
0187: } //-- SchemaWriter
0188:
0189: /**
0190: * Creates a new SchemaWriter for the given DocumentHandler
0191: *
0192: * @param handler the DocumentHandler to send events to
0193: **/
0194: public SchemaWriter(DocumentHandler handler) {
0195:
0196: if (handler == null)
0197: throw new IllegalArgumentException(
0198: "DocumentHandler must not be null.");
0199:
0200: _handler = handler;
0201:
0202: } //-- SchemaWriter
0203:
0204: public void write(Schema schema) throws SAXException {
0205: if (schema == null)
0206: throw new IllegalArgumentException(
0207: "Schema must not be null.");
0208:
0209: processSchema(schema);
0210:
0211: } //-- write
0212:
0213: /**
0214: * Processes the given annotated structure into events
0215: *
0216: * @param annotated the annotated structure to process into events
0217: **/
0218: private void processAnnotated(Annotated annotated,
0219: String schemaPrefix) throws SAXException {
0220: Enumeration enumeration = annotated.getAnnotations();
0221: while (enumeration.hasMoreElements())
0222: processAnnotation((Annotation) enumeration.nextElement(),
0223: schemaPrefix);
0224:
0225: } //-- processAnnotated
0226:
0227: /**
0228: * Processes the given annotation into events
0229: *
0230: * @param annotation the annotation to process into events
0231: * @param schemaPrefix the namespace prefix to use for schema elements
0232: **/
0233: private void processAnnotation(Annotation annotation,
0234: String schemaPrefix) throws SAXException {
0235:
0236: _atts.clear();
0237:
0238: String ELEM_ANNOTATION = schemaPrefix + ANNOTATION;
0239:
0240: _handler.startElement(ELEM_ANNOTATION, _atts);
0241:
0242: //--process appinfo elements
0243: Enumeration enumeration = annotation.getAppInfo();
0244: String ELEM_APPINFO = schemaPrefix + APPINFO;
0245: while (enumeration.hasMoreElements()) {
0246: AppInfo app = (AppInfo) enumeration.nextElement();
0247:
0248: String source = app.getSource();
0249: String sourceName = _atts.getName(0);
0250: boolean isSourceIsNull = (sourceName == null);
0251: boolean isSourceExists = false;
0252:
0253: if (!isSourceIsNull) {
0254: isSourceExists = sourceName
0255: .equals(SchemaNames.SOURCE_ATTR);
0256: }
0257: if (source != null && !isSourceExists)
0258: _atts.addAttribute(SchemaNames.SOURCE_ATTR, CDATA,
0259: source);
0260:
0261: _handler.startElement(ELEM_APPINFO, _atts);
0262: Enumeration anyNodes = app.getObjects();
0263: while (anyNodes.hasMoreElements()) {
0264: Object obj = anyNodes.nextElement();
0265: if (obj instanceof AnyNode) {
0266: AnyNode2SAX anyNode2SAX = new AnyNode2SAX(
0267: (AnyNode) obj);
0268: anyNode2SAX.setDocumentHandler(_handler);
0269: anyNode2SAX.start();
0270: } else {
0271: char[] chars = obj.toString().toCharArray();
0272: _handler.characters(chars, 0, chars.length);
0273:
0274: }
0275: }
0276: _handler.endElement(ELEM_APPINFO);
0277: }
0278:
0279: //-- process documentation elements
0280: enumeration = annotation.getDocumentation();
0281: String ELEM_DOCUMENTATION = schemaPrefix + DOCUMENTATION;
0282: while (enumeration.hasMoreElements()) {
0283: _atts.clear();
0284: Documentation doc = (Documentation) enumeration
0285: .nextElement();
0286: String source = doc.getSource();
0287: String sourceName = _atts.getName(0);
0288: boolean isSourceIsNull = (sourceName == null);
0289: boolean isSourceExists = false;
0290:
0291: if (!isSourceIsNull) {
0292: isSourceExists = sourceName
0293: .equals(SchemaNames.SOURCE_ATTR);
0294: }
0295: if (source != null && !isSourceExists) {
0296: _atts.addAttribute(SchemaNames.SOURCE_ATTR, CDATA,
0297: source);
0298: }
0299:
0300: _handler.startElement(ELEM_DOCUMENTATION, _atts);
0301: Enumeration anyNodes = doc.getObjects();
0302: while (anyNodes.hasMoreElements()) {
0303: Object obj = anyNodes.nextElement();
0304: if (obj instanceof AnyNode) {
0305: AnyNode2SAX anyNode2SAX = new AnyNode2SAX(
0306: (AnyNode) obj);
0307: anyNode2SAX.setDocumentHandler(_handler);
0308: anyNode2SAX.start();
0309: } else {
0310: char[] chars = obj.toString().toCharArray();
0311: _handler.characters(chars, 0, chars.length);
0312:
0313: }
0314: }
0315: _handler.endElement(ELEM_DOCUMENTATION);
0316: }
0317:
0318: _handler.endElement(ELEM_ANNOTATION);
0319:
0320: } //-- processAnnotations
0321:
0322: /**
0323: * Processes the given attribute declaration
0324: *
0325: * @param attribute the attribute declaration to process into events
0326: * @param schemaPrefix the namespace prefix to use for schema elements
0327: **/
0328: private void processAttribute(AttributeDecl attribute,
0329: String schemaPrefix) throws SAXException {
0330: String ELEM_ATTRIBUTE = schemaPrefix + ATTRIBUTE;
0331:
0332: _atts.clear();
0333:
0334: boolean isReference = attribute.isReference();
0335:
0336: //-- name
0337: if (!isReference) {
0338: _atts.addAttribute(SchemaNames.NAME_ATTR, CDATA, attribute
0339: .getName());
0340: } else {
0341: _atts.addAttribute(SchemaNames.REF_ATTR, CDATA, attribute
0342: .getReferenceName());
0343: }
0344:
0345: //-- type attribute
0346: boolean hasAnonymousType = false;
0347: SimpleType type = attribute.getSimpleType();
0348: if ((!isReference) && (type != null)) {
0349:
0350: if (type.getName() != null) {
0351:
0352: String typeName = type.getName();
0353:
0354: //-- add prefix if necessary
0355: if (typeName.indexOf(':') < 0) {
0356: if (type.isBuiltInType()) {
0357: typeName = schemaPrefix + typeName; // xsd prefix
0358: } else {
0359: // resolve prefix
0360: String namespace = type.getSchema()
0361: .getTargetNamespace();
0362: if (namespace == null)
0363: namespace = "";
0364: String prefix = getNSPrefix(attribute
0365: .getSchema(), namespace);
0366: if ((prefix != null) && (prefix.length() > 0))
0367: typeName = prefix + ":" + typeName;
0368: }
0369: }
0370: _atts.addAttribute(ATTR_TYPE, CDATA, typeName);
0371: } else
0372: hasAnonymousType = true;
0373: }
0374:
0375: // default or fixed values?
0376: //-- @default
0377: if (attribute.isDefault()) {
0378: _atts.addAttribute(SchemaNames.DEFAULT_ATTR, CDATA,
0379: attribute.getDefaultValue());
0380: }
0381: //-- @fixed
0382: else if (attribute.isFixed()) {
0383: _atts.addAttribute(SchemaNames.FIXED_ATTR, CDATA, attribute
0384: .getFixedValue());
0385: }
0386:
0387: //-- @form
0388: if (attribute.getForm() != null) {
0389: _atts.addAttribute(SchemaNames.FORM, CDATA, attribute
0390: .getForm().toString());
0391: }
0392:
0393: //-- @id (optional)
0394: if (attribute.getId() != null) {
0395: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, attribute
0396: .getId());
0397: }
0398:
0399: //-- use : required
0400: if (attribute.isRequired()) {
0401: _atts.addAttribute(SchemaNames.USE_ATTR, CDATA,
0402: AttributeDecl.USE_REQUIRED);
0403: }
0404: //-- use : prohibited
0405: else if (attribute.isProhibited()) {
0406: _atts.addAttribute(SchemaNames.USE_ATTR, CDATA,
0407: AttributeDecl.USE_PROHIBITED);
0408: }
0409:
0410: _handler.startElement(ELEM_ATTRIBUTE, _atts);
0411:
0412: //-- process annotations
0413: processAnnotated(attribute, schemaPrefix);
0414:
0415: //-- process anonymous type if necessary
0416: if (hasAnonymousType) {
0417: processSimpleType(type, schemaPrefix);
0418: }
0419:
0420: _handler.endElement(ELEM_ATTRIBUTE);
0421:
0422: } //-- processAttribute
0423:
0424: /**
0425: * Processes the given attributeGroup declaration
0426: *
0427: * @param attGroup the attributeGroup declaration to process into events
0428: * @param schemaPrefix the namespace prefix to use for schema elements
0429: **/
0430: private void processAttributeGroup(AttributeGroup attGroup,
0431: String schemaPrefix) throws SAXException {
0432: String ELEM_ATTRIBUTE_GROUP = schemaPrefix + ATTRIBUTE_GROUP;
0433:
0434: _atts.clear();
0435:
0436: boolean isReference = (attGroup instanceof AttributeGroupReference);
0437:
0438: //-- name
0439: if (!isReference) {
0440: _atts.addAttribute(SchemaNames.NAME_ATTR, CDATA,
0441: ((AttributeGroupDecl) attGroup).getName());
0442: } else {
0443: _atts
0444: .addAttribute(SchemaNames.REF_ATTR, CDATA,
0445: ((AttributeGroupReference) attGroup)
0446: .getReference());
0447: }
0448:
0449: //-- @id (optional)
0450: if (attGroup.getId() != null) {
0451: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, attGroup
0452: .getId());
0453: }
0454:
0455: _handler.startElement(ELEM_ATTRIBUTE_GROUP, _atts);
0456:
0457: //-- process annotations
0458: processAnnotated(attGroup, schemaPrefix);
0459:
0460: if (!isReference) {
0461: AttributeGroupDecl group = (AttributeGroupDecl) attGroup;
0462: Enumeration enumeration = group.getLocalAttributes();
0463: while (enumeration.hasMoreElements()) {
0464: processAttribute((AttributeDecl) enumeration
0465: .nextElement(), schemaPrefix);
0466: }
0467: enumeration = group.getLocalAttributeGroupReferences();
0468: while (enumeration.hasMoreElements()) {
0469: processAttributeGroup((AttributeGroup) enumeration
0470: .nextElement(), schemaPrefix);
0471: }
0472:
0473: if (group.getAnyAttribute() != null) {
0474: processWildcard(group.getAnyAttribute(), schemaPrefix);
0475: }
0476: }
0477:
0478: _handler.endElement(ELEM_ATTRIBUTE_GROUP);
0479:
0480: } //-- processAttributeGroup
0481:
0482: /**
0483: * Processes the given complex type definition
0484: *
0485: * @param complexType the complex type definition to process into events
0486: * @param schemaPrefix the namespace prefix to use for schema elements
0487: **/
0488: private void processComplexType(ComplexType complexType,
0489: String schemaPrefix) throws SAXException {
0490: String ELEMENT_NAME = schemaPrefix + COMPLEX_TYPE;
0491:
0492: _atts.clear();
0493:
0494: //-- handle top-level only attributes
0495: if (complexType.isTopLevel()) {
0496:
0497: //-- @name
0498: _atts.addAttribute(SchemaNames.NAME_ATTR, CDATA,
0499: complexType.getName());
0500:
0501: //-- @abstract
0502: if (complexType.isAbstract()) {
0503: _atts.addAttribute(SchemaNames.ABSTRACT, CDATA,
0504: VALUE_TRUE);
0505: }
0506:
0507: //-- @block
0508: if (complexType.getBlock() != null) {
0509: _atts.addAttribute(SchemaNames.BLOCK_ATTR, CDATA,
0510: complexType.getBlock().toString());
0511: }
0512:
0513: //-- @final
0514: if (complexType.getFinal() != null) {
0515: _atts.addAttribute(SchemaNames.FINAL_ATTR, CDATA,
0516: complexType.getFinal().toString());
0517: }
0518: } //-- isTopLevel
0519:
0520: //-- @id
0521: if (complexType.getId() != null) {
0522: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, complexType
0523: .getId());
0524: }
0525:
0526: //-- @mixed
0527: if (complexType.getContentType() == ContentType.mixed) {
0528: _atts.addAttribute(SchemaNames.MIXED, CDATA, VALUE_TRUE);
0529: }
0530:
0531: _handler.startElement(ELEMENT_NAME, _atts);
0532:
0533: //-- process annotations
0534: processAnnotated(complexType, schemaPrefix);
0535:
0536: //-- handle simpleContent/complexContent if we have a baseType.
0537: String ELEM_CONTENT = null;
0538: String ELEM_DERIVATION = null;
0539: XMLType baseType = complexType.getBaseType();
0540: if (baseType != null) {
0541: if (complexType.isSimpleContent())
0542: ELEM_CONTENT = schemaPrefix
0543: + SchemaNames.SIMPLE_CONTENT;
0544: else
0545: ELEM_CONTENT = schemaPrefix
0546: + SchemaNames.COMPLEX_CONTENT;
0547:
0548: _atts.clear();
0549: if (complexType.isComplexContent()) {
0550: if (complexType.getContentType() == ContentType.mixed) {
0551: _atts.addAttribute(SchemaNames.MIXED, CDATA,
0552: VALUE_TRUE);
0553: }
0554:
0555: }
0556: _handler.startElement(ELEM_CONTENT, _atts);
0557:
0558: ELEM_DERIVATION = schemaPrefix
0559: + complexType.getDerivationMethod();
0560:
0561: String baseTypeName = baseType.getName();
0562:
0563: //-- add "xsd" prefix if necessary
0564: if (complexType.isSimpleContent()) {
0565: //the base type can be a complexType in extension
0566: if (baseType.isSimpleType()) {
0567: SimpleType simpleType = (SimpleType) baseType;
0568: if (baseTypeName.indexOf(':') < 0) {
0569: if (simpleType.isBuiltInType()) {
0570: baseTypeName = schemaPrefix + baseTypeName;
0571: } else {
0572: String targetNamespace = simpleType
0573: .getSchema().getTargetNamespace();
0574: String prefix = getNSPrefix(complexType
0575: .getSchema(), targetNamespace);
0576: if ((prefix != null)
0577: && (prefix.length() > 0)) {
0578: baseTypeName = prefix + ":"
0579: + baseTypeName;
0580: }
0581: }
0582: }
0583: }
0584: } else if (complexType.isComplexContent()) {
0585: //--complexType: add 'xsd' only for anyType
0586: if (baseType.isAnyType()) {
0587: if (baseTypeName.indexOf(':') < 0) {
0588: baseTypeName = schemaPrefix + baseTypeName;
0589: }
0590:
0591: }
0592: } //--end of 'xsd' appending
0593: //add the targetNamespace prefix if necessary
0594: if (baseType.isComplexType()) {
0595: String targetNamespace = baseType.getSchema()
0596: .getTargetNamespace();
0597: //-- targetNamespace is null
0598: if (targetNamespace == null) {
0599: if (complexType.isRedefined()) {
0600: targetNamespace = complexType.getSchema()
0601: .getTargetNamespace();
0602: }
0603: }
0604:
0605: else {
0606: String nsPrefix = getNSPrefix(complexType
0607: .getSchema(), targetNamespace);
0608: if ((nsPrefix != null) && (nsPrefix.length() != 0))
0609: baseTypeName = nsPrefix + ':' + baseTypeName;
0610: targetNamespace = null;
0611: nsPrefix = null;
0612: }
0613:
0614: }
0615: _atts.clear();
0616: _atts.addAttribute(SchemaNames.BASE_ATTR, CDATA,
0617: baseTypeName);
0618: _handler.startElement(ELEM_DERIVATION, _atts);
0619: //--Any Facets to process?
0620: //--only relevant for the simpleContent with restriction
0621: if (complexType.isSimpleContent()
0622: && complexType.isRestricted()) {
0623: if (complexType.getContentType().getType() == ContentType.SIMPLE) {
0624: SimpleContent simpleContent = (SimpleContent) complexType
0625: .getContentType();
0626: SimpleType simpleType = simpleContent
0627: .getSimpleType();
0628: //-- process facets
0629: Enumeration enumeration = simpleType
0630: .getLocalFacets();
0631: while (enumeration.hasMoreElements()) {
0632: Facet facet = (Facet) enumeration.nextElement();
0633: _atts.clear();
0634: _atts.addAttribute(SchemaNames.VALUE_ATTR,
0635: CDATA, facet.getValue());
0636: String facetName = schemaPrefix
0637: + facet.getName();
0638: _handler.startElement(facetName, _atts);
0639: Enumeration annotations = facet
0640: .getAnnotations();
0641: while (annotations.hasMoreElements()) {
0642: Annotation annotation = (Annotation) annotations
0643: .nextElement();
0644: processAnnotation(annotation, schemaPrefix);
0645: }
0646: _handler.endElement(facetName);
0647: } //--facets
0648: enumeration = null;
0649: simpleType = null;
0650: }
0651: }//--<simpleContent><restriction>
0652:
0653: }
0654:
0655: //-- process content model group
0656: processContentModelGroup(complexType, schemaPrefix);
0657:
0658: //-- process Attributes, must appear last in a complex type
0659: Enumeration enumeration = complexType.getLocalAttributeDecls();
0660: while (enumeration.hasMoreElements()) {
0661: processAttribute((AttributeDecl) enumeration.nextElement(),
0662: schemaPrefix);
0663: }
0664: enumeration = complexType.getAttributeGroupReferences();
0665: while (enumeration.hasMoreElements()) {
0666: processAttributeGroup((AttributeGroup) enumeration
0667: .nextElement(), schemaPrefix);
0668: }
0669:
0670: if (baseType != null) {
0671: _handler.endElement(ELEM_DERIVATION);
0672: _handler.endElement(ELEM_CONTENT);
0673: }
0674:
0675: if (complexType.getAnyAttribute() != null) {
0676: processWildcard(complexType.getAnyAttribute(), schemaPrefix);
0677: }
0678:
0679: _handler.endElement(ELEMENT_NAME);
0680:
0681: } //-- processComplexType
0682:
0683: /**
0684: * Processes the given ContentModelGroup
0685: *
0686: * @param contentModel the content model group to process into events
0687: * @param schemaPrefix the namespace prefix to use for schema elements
0688: **/
0689: private void processContentModelGroup(
0690: ContentModelGroup contentModel, String schemaPrefix)
0691: throws SAXException {
0692: Enumeration enumeration = contentModel.enumerate();
0693: while (enumeration.hasMoreElements()) {
0694: Structure structure = (Structure) enumeration.nextElement();
0695: switch (structure.getStructureType()) {
0696: case Structure.ELEMENT:
0697: processElement((ElementDecl) structure, schemaPrefix);
0698: break;
0699: case Structure.MODELGROUP:
0700: case Structure.GROUP:
0701: processGroup((Group) structure, schemaPrefix);
0702: break;
0703: case Structure.WILDCARD:
0704: processWildcard((Wildcard) structure, schemaPrefix);
0705: break;
0706: default:
0707: break;
0708: }
0709: }
0710: } //-- contentModel
0711:
0712: /**
0713: * Processes the given element declaration
0714: *
0715: * @param element the element declaration to process into events
0716: **/
0717: private void processElement(ElementDecl element, String schemaPrefix)
0718: throws SAXException {
0719: String ELEMENT_NAME = schemaPrefix + ELEMENT;
0720:
0721: _atts.clear();
0722:
0723: //-- name or reference
0724: String value = element.getName();
0725: if (value != null) {
0726: if (element.isReference()) {
0727: String targetNamespace = element.getReference()
0728: .getSchema().getTargetNamespace();
0729: String nsPrefix = getNSPrefix(element.getSchema(),
0730: targetNamespace);
0731: if ((nsPrefix != null) && (nsPrefix.length() != 0))
0732: value = nsPrefix + ':' + value;
0733: targetNamespace = null;
0734: nsPrefix = null;
0735: _atts.addAttribute(SchemaNames.REF_ATTR, CDATA, value);
0736:
0737: } else
0738: _atts.addAttribute(ATTR_NAME, CDATA, value);
0739: }
0740:
0741: //-- minOccurs/maxOccurs
0742: int max = element.getMaxOccurs();
0743: int min = element.getMinOccurs();
0744:
0745: if (min != 1) {
0746: _atts.addAttribute(SchemaNames.MIN_OCCURS_ATTR, CDATA,
0747: Integer.toString(min));
0748: }
0749:
0750: if (max < 0) {
0751: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
0752: "unbounded");
0753: } else if (max != 1) {
0754: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
0755: Integer.toString(max));
0756: }
0757:
0758: //-- type attribute
0759: boolean hasAnonymousType = false;
0760: if (!element.isReference()) {
0761: XMLType type = element.getType();
0762:
0763: //-- no type?
0764: if (type == null) {
0765: //-- do nothing
0766: }
0767: //-- anonymous (in-lined) type
0768: else if (type.getName() == null) {
0769: hasAnonymousType = true;
0770: }
0771: //-- built-in simpleType
0772: else if (type.isSimpleType()
0773: && ((SimpleType) type).isBuiltInType()) {
0774: _atts.addAttribute(ATTR_TYPE, CDATA, schemaPrefix
0775: + type.getName());
0776: } else if (type.getStructureType() == Structure.ANYTYPE) {
0777: _atts.addAttribute(ATTR_TYPE, CDATA, schemaPrefix
0778: + type.getName());
0779: }
0780: //-- type imported from another schema
0781: else if (isImportedType(type, element)) {
0782: String namespace = type.getSchema()
0783: .getTargetNamespace();
0784: String prefix = getNSPrefix(element.getSchema(),
0785: namespace);
0786: if (prefix == null) {
0787: //-- declare a temporary prefix
0788: prefix = schemaPrefix + '2';
0789: _atts.addAttribute("xmlns:" + prefix, CDATA,
0790: namespace);
0791: }
0792: _atts.addAttribute(ATTR_TYPE, CDATA, prefix + ':'
0793: + type.getName());
0794: //-- otherwise...user defined type.
0795: } else {
0796: String typeName = type.getName();
0797: //add the targetNamespace prefix if necessary
0798: String targetNamespace = element.getSchema()
0799: .getTargetNamespace();
0800: if (targetNamespace != null) {
0801: String nsPrefix = getNSPrefix(element.getSchema(),
0802: targetNamespace);
0803: if ((nsPrefix != null) && (nsPrefix.length() != 0))
0804: typeName = nsPrefix + ':' + typeName;
0805: targetNamespace = null;
0806: nsPrefix = null;
0807: }
0808:
0809: _atts.addAttribute(ATTR_TYPE, CDATA, typeName);
0810: }
0811: }
0812:
0813: // add various attributes if we are looking at a local element definition; iow,
0814: // for an element reference, this values should be specified on the
0815: // referenced (global) element definition only.
0816: if (!element.isReference()) {
0817:
0818: //-- @abstract
0819: if (element.isAbstract()) {
0820: _atts.addAttribute(SchemaNames.ABSTRACT, CDATA,
0821: VALUE_TRUE);
0822: }
0823:
0824: //-- @block
0825: if (element.getBlock() != null) {
0826: _atts.addAttribute(SchemaNames.BLOCK_ATTR, CDATA,
0827: element.getBlock().toString());
0828: }
0829:
0830: //-- @default
0831: String defaultValue = element.getDefaultValue();
0832: if (defaultValue != null) {
0833: _atts.addAttribute(SchemaNames.DEFAULT_ATTR, CDATA,
0834: defaultValue);
0835: }
0836:
0837: //-- @fixed
0838: String fixedValue = element.getFixedValue();
0839: if (fixedValue != null) {
0840: _atts.addAttribute(SchemaNames.FIXED_ATTR, CDATA,
0841: fixedValue);
0842: }
0843:
0844: //-- @final
0845: FinalList finalValue = element.getFinal();
0846: if (finalValue != null) {
0847: _atts.addAttribute(SchemaNames.FINAL_ATTR, CDATA,
0848: finalValue.toString());
0849: }
0850:
0851: //-- @substitutionGroup
0852: String substitutionGroup = element.getSubstitutionGroup();
0853: if (substitutionGroup != null) {
0854: _atts.addAttribute(SchemaNames.SUBSTITUTION_GROUP_ATTR,
0855: CDATA, substitutionGroup);
0856: }
0857: }
0858:
0859: //-- @form
0860: Form form = element.getForm();
0861: if (form != null) {
0862: _atts
0863: .addAttribute(SchemaNames.FORM, CDATA, form
0864: .toString());
0865: }
0866:
0867: //-- @id
0868: String id = element.getId();
0869: if (id != null) {
0870: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, id);
0871: }
0872:
0873: //-- @nillable
0874: if (element.isNillable()) {
0875: _atts.addAttribute(SchemaNames.NILLABLE_ATTR, CDATA,
0876: VALUE_TRUE);
0877: }
0878:
0879: _handler.startElement(ELEMENT_NAME, _atts);
0880:
0881: //-- process annotations
0882: processAnnotated(element, schemaPrefix);
0883:
0884: //-- process anonymous type if necessary
0885: if (hasAnonymousType) {
0886: XMLType type = element.getType();
0887: if (type.isComplexType())
0888: processComplexType((ComplexType) type, schemaPrefix);
0889: else if (type.isSimpleType())
0890: processSimpleType((SimpleType) type, schemaPrefix);
0891: }
0892:
0893: //-- process any identity-constraints
0894: Enumeration enumeration = element.getIdentityConstraints();
0895: while (enumeration.hasMoreElements()) {
0896: processIdentityConstraint((IdentityConstraint) enumeration
0897: .nextElement(), schemaPrefix);
0898: }
0899:
0900: _handler.endElement(ELEMENT_NAME);
0901:
0902: } //-- processElement
0903:
0904: /**
0905: * Processes the given group definition into SAX events
0906: *
0907: * @param group the group definition to process into SAX events
0908: * @param schemaPrefix the namespace prefix to use for schema elements
0909: **/
0910: private void processGroup(Group group, String schemaPrefix)
0911: throws SAXException {
0912: String ELEMENT_NAME = schemaPrefix;
0913:
0914: //-- ModelGroup
0915: String reference = null;
0916: if (group instanceof ModelGroup) {
0917: ELEMENT_NAME += GROUP;
0918: ModelGroup mGroup = (ModelGroup) group;
0919: if (mGroup.hasReference()) {
0920: ModelGroup refGroup = mGroup.getReference();
0921: if (refGroup != null) {
0922: reference = refGroup.getName();
0923: //-- prefix
0924: String namespace = refGroup.getSchema()
0925: .getTargetNamespace();
0926: if (namespace == null)
0927: namespace = "";
0928: String prefix = getNSPrefix(mGroup.getSchema(),
0929: namespace);
0930: if ((prefix != null) && (prefix.length() > 0))
0931: reference = prefix + ':' + reference;
0932:
0933: }
0934: }
0935: }
0936: //-- Group
0937: else {
0938: ELEMENT_NAME += group.getOrder().toString();
0939: }
0940:
0941: _atts.clear();
0942:
0943: //-- @id
0944: if (group.getId() != null) {
0945: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, group
0946: .getId());
0947: }
0948:
0949: //-- reference
0950: if (reference != null) {
0951: _atts.addAttribute("ref", CDATA, reference);
0952: } else if (group.getName() != null) {
0953: _atts.addAttribute(ATTR_NAME, CDATA, group.getName());
0954: }
0955:
0956: //-- minOccurs/maxOccurs
0957: int max = group.getMaxOccurs();
0958: int min = group.getMinOccurs();
0959:
0960: if (min != 1) {
0961: _atts.addAttribute(SchemaNames.MIN_OCCURS_ATTR, CDATA,
0962: Integer.toString(min));
0963: }
0964:
0965: if (max < 0) {
0966: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
0967: "unbounded");
0968: } else if (max != 1) {
0969: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
0970: Integer.toString(max));
0971: }
0972:
0973: _handler.startElement(ELEMENT_NAME, _atts);
0974:
0975: //-- process annotations
0976: processAnnotated(group, schemaPrefix);
0977:
0978: //-- process content model
0979: if (reference == null) {
0980: processContentModelGroup(group, schemaPrefix);
0981: }
0982:
0983: _handler.endElement(ELEMENT_NAME);
0984:
0985: } //-- processGroup
0986:
0987: /**
0988: * Processes the given IdentityConstraint
0989: *
0990: * @param constraint the IdentityConstraint to process
0991: **/
0992: private void processIdentityConstraint(
0993: IdentityConstraint constraint, String schemaPrefix)
0994: throws SAXException {
0995:
0996: if (constraint == null)
0997: return;
0998:
0999: String ELEMENT_NAME = schemaPrefix;
1000:
1001: String id = null;
1002: String refer = null;
1003:
1004: switch (constraint.getStructureType()) {
1005: case Structure.KEYREF:
1006: ELEMENT_NAME += SchemaNames.KEYREF;
1007: refer = ((KeyRef) constraint).getRefer();
1008: break;
1009: case Structure.UNIQUE:
1010: ELEMENT_NAME += SchemaNames.UNIQUE;
1011: break;
1012: default:
1013: ELEMENT_NAME += SchemaNames.KEY;
1014: break;
1015: }
1016:
1017: id = constraint.getId();
1018:
1019: _atts.clear();
1020:
1021: //-- name
1022: _atts.addAttribute(SchemaNames.NAME_ATTR, CDATA, constraint
1023: .getName());
1024:
1025: //-- id
1026: if (id != null) {
1027: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, id);
1028: }
1029:
1030: //-- refer
1031: if (refer != null) {
1032: _atts.addAttribute(SchemaNames.REFER_ATTR, CDATA, refer);
1033: }
1034:
1035: _handler.startElement(ELEMENT_NAME, _atts);
1036:
1037: //-- process annotations
1038: processAnnotated(constraint, schemaPrefix);
1039:
1040: //-- process selector
1041: String ELEM_SELECTOR = schemaPrefix + SchemaNames.SELECTOR;
1042: String xpath = null;
1043:
1044: IdentitySelector selector = constraint.getSelector();
1045: xpath = selector.getXPath();
1046: id = selector.getId();
1047: _atts.clear();
1048: _atts.addAttribute(SchemaNames.XPATH_ATTR, CDATA, xpath);
1049: if (id != null) {
1050: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, id);
1051: }
1052: _handler.startElement(ELEM_SELECTOR, _atts);
1053: processAnnotated(selector, schemaPrefix);
1054: _handler.endElement(ELEM_SELECTOR);
1055:
1056: //-- process field(s)
1057: String ELEM_FIELD = schemaPrefix + SchemaNames.FIELD;
1058: Enumeration enumeration = constraint.getFields();
1059: while (enumeration.hasMoreElements()) {
1060: IdentityField field = (IdentityField) enumeration
1061: .nextElement();
1062: _atts.clear();
1063: id = field.getId();
1064: xpath = field.getXPath();
1065: _atts.addAttribute(SchemaNames.XPATH_ATTR, CDATA, xpath);
1066: if (id != null) {
1067: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, id);
1068: }
1069: _handler.startElement(ELEM_FIELD, _atts);
1070: processAnnotated(field, schemaPrefix);
1071: _handler.endElement(ELEM_FIELD);
1072: }
1073: _handler.endElement(ELEMENT_NAME);
1074:
1075: } //-- processIdentityConstraint
1076:
1077: private void processSchema(Schema schema) throws SAXException {
1078: //-- calculate schema prefix
1079: String schemaPrefix = getNSPrefix(schema, schema
1080: .getSchemaNamespace());
1081: if (schemaPrefix == null) {
1082: schemaPrefix = DEFAULT_PREFIX;
1083: }
1084:
1085: //-- namespace declaration for xsd
1086: _atts.clear();
1087: if (schemaPrefix.length() == 0) {
1088: //-- declared as default namespace
1089: _atts.addAttribute(XMLNS_DEFAULT, CDATA, schema
1090: .getSchemaNamespace());
1091: } else {
1092: //-- declare namespace + prefix
1093: _atts.addAttribute(XMLNS_PREFIX + schemaPrefix, CDATA,
1094: schema.getSchemaNamespace());
1095: }
1096:
1097: //-- namespace declarations
1098: Namespaces namespaces = schema.getNamespaces();
1099: Enumeration keys = namespaces.getLocalNamespacePrefixes();
1100: while (keys.hasMoreElements()) {
1101: String nsPrefix = (String) keys.nextElement();
1102: if (!nsPrefix.equals(schemaPrefix)) {
1103: String ns = namespaces.getNamespaceURI(nsPrefix);
1104: if (nsPrefix.length() > 0) {
1105: _atts.addAttribute(XMLNS_PREFIX + nsPrefix, CDATA,
1106: ns);
1107: } else {
1108: _atts.addAttribute(XMLNS_DEFAULT, CDATA, ns);
1109: }
1110: }
1111: }
1112:
1113: //-- targetNS
1114: String value = schema.getTargetNamespace();
1115: if (value != null)
1116: _atts
1117: .addAttribute(SchemaNames.TARGET_NS_ATTR, CDATA,
1118: value);
1119:
1120: //-- attributeFormDefault
1121: Form form = schema.getAttributeFormDefault();
1122: if (form != null) {
1123: _atts.addAttribute(SchemaNames.ATTR_FORM_DEFAULT_ATTR,
1124: CDATA, form.toString());
1125: }
1126: //-- elementFormDefault
1127: form = schema.getElementFormDefault();
1128: if (form != null) {
1129: _atts.addAttribute(SchemaNames.ELEM_FORM_DEFAULT_ATTR,
1130: CDATA, form.toString());
1131: }
1132:
1133: //-- blockDefault
1134: BlockList blockList = schema.getBlockDefault();
1135: if (blockList != null) {
1136: _atts.addAttribute(SchemaNames.BLOCK_DEFAULT_ATTR, CDATA,
1137: blockList.toString());
1138: }
1139:
1140: //-- finalDefault
1141: FinalList finalList = schema.getFinalDefault();
1142: if (finalList != null) {
1143: _atts.addAttribute(SchemaNames.FINAL_DEFAULT_ATTR, CDATA,
1144: finalList.toString());
1145: }
1146:
1147: //--@version
1148: if (schema.getVersion() != null) {
1149: _atts.addAttribute(SchemaNames.VERSION_ATTR, CDATA, schema
1150: .getVersion());
1151: }
1152:
1153: //-- modify schemaPrefix to include ':'
1154: if (schemaPrefix.length() > 0) {
1155: schemaPrefix += ':';
1156: }
1157:
1158: _handler.startDocument();
1159:
1160: String ELEM_SCHEMA = schemaPrefix + SCHEMA;
1161:
1162: _handler.startElement(ELEM_SCHEMA, _atts);
1163:
1164: //-- process annotations
1165: processAnnotated(schema, schemaPrefix);
1166:
1167: Enumeration enumeration = null;
1168: //-- process all imported schemas
1169: enumeration = schema.getImportedSchema();
1170: while (enumeration.hasMoreElements()) {
1171: processImport((Schema) enumeration.nextElement(),
1172: schemaPrefix);
1173: }
1174:
1175: //-- process all cached included schemas
1176: enumeration = schema.getCachedIncludedSchemas();
1177: while (enumeration.hasMoreElements()) {
1178: processIncludedSchema((Schema) enumeration.nextElement(),
1179: schemaPrefix);
1180: }
1181:
1182: //-- process all redefinitions
1183: enumeration = schema.getRedefineSchema();
1184: while (enumeration.hasMoreElements()) {
1185: processRedefinition((RedefineSchema) enumeration
1186: .nextElement(), schema, schemaPrefix);
1187: }
1188:
1189: //-- process all top level attributeGroup declarations
1190: enumeration = schema.getAttributeGroups();
1191: while (enumeration.hasMoreElements()) {
1192: boolean found = false;
1193: AttributeGroup temp = (AttributeGroup) enumeration
1194: .nextElement();
1195: //-- check if this attributeGroup is not
1196: //-- part of a redefinition
1197: if (temp instanceof AttributeGroupDecl) {
1198: if (((AttributeGroupDecl) temp).isRedefined())
1199: found = true;
1200: }
1201:
1202: //--check if this attributeGroup is not
1203: //-- included
1204: Enumeration includedSchemas = schema
1205: .getCachedIncludedSchemas();
1206: while (includedSchemas.hasMoreElements()) {
1207: Schema tempSchema = (Schema) includedSchemas
1208: .nextElement();
1209: if (temp instanceof AttributeGroupDecl) {
1210: String name = ((AttributeGroupDecl) temp).getName();
1211: found = (tempSchema.getAttributeGroup(name) != null);
1212: }
1213: }
1214:
1215: if (!found)
1216: processAttributeGroup(temp, schemaPrefix);
1217: }
1218:
1219: //-- process all top level attribute declarations
1220: enumeration = schema.getAttributes();
1221: while (enumeration.hasMoreElements()) {
1222: AttributeDecl temp = (AttributeDecl) enumeration
1223: .nextElement();
1224: boolean found = false;
1225: //--check if this attributeGroup is not
1226: //-- included
1227: Enumeration includedSchemas = schema
1228: .getCachedIncludedSchemas();
1229: while (includedSchemas.hasMoreElements()) {
1230: Schema tempSchema = (Schema) includedSchemas
1231: .nextElement();
1232: found = (tempSchema.getAttribute(temp.getName()) != null);
1233: }
1234:
1235: if (!found)
1236: processAttribute(temp, schemaPrefix);
1237: }
1238:
1239: //-- process all top level element declarations
1240: enumeration = schema.getElementDecls();
1241: while (enumeration.hasMoreElements()) {
1242: ElementDecl temp = (ElementDecl) enumeration.nextElement();
1243: boolean found = false;
1244: //--check if this attributeGroup is not
1245: //-- included
1246: Enumeration includedSchemas = schema
1247: .getCachedIncludedSchemas();
1248: while (includedSchemas.hasMoreElements()) {
1249: Schema tempSchema = (Schema) includedSchemas
1250: .nextElement();
1251: found = (tempSchema.getElementDecl(temp.getName()) != null);
1252: }
1253:
1254: if (!found)
1255: processElement(temp, schemaPrefix);
1256: }
1257:
1258: //-- process all top level complex types
1259: enumeration = schema.getComplexTypes();
1260: while (enumeration.hasMoreElements()) {
1261: ComplexType temp = (ComplexType) enumeration.nextElement();
1262: boolean found = false;
1263: //--check if this attributeGroup is not
1264: //-- included
1265: Enumeration includedSchemas = schema
1266: .getCachedIncludedSchemas();
1267: while (includedSchemas.hasMoreElements()) {
1268: Schema tempSchema = (Schema) includedSchemas
1269: .nextElement();
1270: found = (tempSchema.getComplexType(temp.getName()) != null);
1271: }
1272: if (!temp.isRedefined() && !found)
1273: processComplexType(temp, schemaPrefix);
1274: }
1275:
1276: //-- process all top level groups
1277: enumeration = schema.getModelGroups();
1278: while (enumeration.hasMoreElements()) {
1279: ModelGroup temp = (ModelGroup) enumeration.nextElement();
1280: boolean found = false;
1281: //--check if this Group is not
1282: //-- included
1283: Enumeration includedSchemas = schema
1284: .getCachedIncludedSchemas();
1285: while (includedSchemas.hasMoreElements()) {
1286: Schema tempSchema = (Schema) includedSchemas
1287: .nextElement();
1288: found = (tempSchema.getModelGroup(temp.getName()) != null);
1289: }
1290:
1291: if (!temp.isRedefined() && !found)
1292: processGroup(temp, schemaPrefix);
1293: }
1294:
1295: //-- process all top level simple types
1296: enumeration = schema.getSimpleTypes();
1297: while (enumeration.hasMoreElements()) {
1298: SimpleType temp = (SimpleType) enumeration.nextElement();
1299: boolean found = false;
1300: //--check if this attributeGroup is not
1301: //-- included
1302: Enumeration includedSchemas = schema
1303: .getCachedIncludedSchemas();
1304: while (includedSchemas.hasMoreElements()) {
1305: Schema tempSchema = (Schema) includedSchemas
1306: .nextElement();
1307: found = (tempSchema.getSimpleType(temp.getName()) != null);
1308: }
1309: if (!temp.isRedefined() && !found)
1310: processSimpleType(temp, schemaPrefix);
1311: }
1312:
1313: _handler.endElement(ELEM_SCHEMA);
1314:
1315: _handler.endDocument();
1316:
1317: } //-- processSchema
1318:
1319: /**
1320: * Process a Wildcard (xsd:any) component
1321: *
1322: * @param wildcard the Wildcard to process
1323: * @param schemaPrefix the namespace prefix to use for schema elements
1324: */
1325: private void processWildcard(Wildcard wildcard, String schemaPrefix)
1326: throws SAXException {
1327:
1328: String ELEMENT_NAME = null;
1329: if (wildcard.isAttributeWildcard())
1330: ELEMENT_NAME = schemaPrefix + SchemaNames.ANY_ATTRIBUTE;
1331: else
1332: ELEMENT_NAME = schemaPrefix + SchemaNames.ANY;
1333:
1334: _atts.clear();
1335:
1336: //-- @namespace
1337: StringBuffer namespace = new StringBuffer();
1338: Enumeration enumeration = wildcard.getNamespaces();
1339: while (enumeration.hasMoreElements()) {
1340: if (namespace.length() > 0)
1341: namespace.append(' ');
1342: namespace.append(enumeration.nextElement().toString());
1343: }
1344: if (namespace.length() > 0) {
1345: _atts.addAttribute(SchemaNames.NAMESPACE, CDATA, namespace
1346: .toString());
1347: }
1348:
1349: //-- minOccurs/maxOccurs
1350: int max = wildcard.getMaxOccurs();
1351: int min = wildcard.getMinOccurs();
1352:
1353: if (min != 1) {
1354: _atts.addAttribute(SchemaNames.MIN_OCCURS_ATTR, CDATA,
1355: Integer.toString(min));
1356: }
1357:
1358: if (max < 0) {
1359: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
1360: "unbounded");
1361: } else if (max != 1) {
1362: _atts.addAttribute(SchemaNames.MAX_OCCURS_ATTR, CDATA,
1363: Integer.toString(max));
1364: }
1365:
1366: //-- @processContents
1367: String value = wildcard.getProcessContent();
1368: if (value != null) {
1369: _atts.addAttribute(SchemaNames.PROCESS_CONTENTS, CDATA,
1370: value);
1371: }
1372: _handler.startElement(ELEMENT_NAME, _atts);
1373: processAnnotated(wildcard, schemaPrefix);
1374: _handler.endElement(ELEMENT_NAME);
1375:
1376: } //-- processWildcard
1377:
1378: /**
1379: * Process an imported schema
1380: *
1381: * @param schema the imported Schema to process
1382: * @param schemaPrefix the namespace prefix to use for schema elements
1383: **/
1384: private void processImport(Schema schema, String schemaPrefix)
1385: throws SAXException {
1386: String ELEMENT_NAME = schemaPrefix + SchemaNames.IMPORT;
1387: _atts.clear();
1388:
1389: String namespace = schema.getTargetNamespace();
1390: String schemaLoc = schema.getSchemaLocation();
1391:
1392: _atts.addAttribute("namespace", null, namespace);
1393: _atts.addAttribute("schemaLocation", null, schemaLoc);
1394: _handler.startElement(ELEMENT_NAME, _atts);
1395: _handler.endElement(ELEMENT_NAME);
1396: } //-- processImport
1397:
1398: /**
1399: * Process an included schema
1400: *
1401: * @param schema the imported Schema to process
1402: * @param schemaPrefix the namespace prefix to use for schema elements
1403: **/
1404: private void processIncludedSchema(Schema schema,
1405: String schemaPrefix) throws SAXException {
1406: String ELEMENT_NAME = schemaPrefix + SchemaNames.INCLUDE;
1407: _atts.clear();
1408:
1409: String schemaLoc = schema.getSchemaLocation();
1410:
1411: _atts.addAttribute("schemaLocation", null, schemaLoc);
1412: _handler.startElement(ELEMENT_NAME, _atts);
1413: _handler.endElement(ELEMENT_NAME);
1414: } //-- processImport
1415:
1416: /**
1417: * Process a set of redefinitions
1418: *
1419: * @param schema the redefined Schema to process
1420: * @param schemaPrefix the namespace prefix to use for schema elements
1421: **/
1422: private void processRedefinition(RedefineSchema schema,
1423: Schema parentSchema, String schemaPrefix)
1424: throws SAXException {
1425: String ELEMENT_NAME = schemaPrefix + SchemaNames.REDEFINE;
1426: _atts.clear();
1427:
1428: String schemaLoc = schema.getSchemaLocation();
1429: if (schemaLoc != "")
1430: _atts.addAttribute("schemaLocation", null, schemaLoc);
1431:
1432: _handler.startElement(ELEMENT_NAME, _atts);
1433:
1434: //-- process annotations
1435: processAnnotated(schema, schemaPrefix);
1436:
1437: if (schemaLoc != "") {
1438: Enumeration enumeration = null;
1439: //--process complexTypes
1440: enumeration = schema.enumerateComplexTypes();
1441: while (enumeration.hasMoreElements()) {
1442: ComplexType type = (ComplexType) enumeration
1443: .nextElement();
1444: processComplexType(type, schemaPrefix);
1445: }
1446: //--process simpleTypes
1447: enumeration = schema.enumerateSimpleTypes();
1448: while (enumeration.hasMoreElements()) {
1449: SimpleType type = (SimpleType) enumeration
1450: .nextElement();
1451: processSimpleType(type, schemaPrefix);
1452: }
1453: //--process groups
1454: enumeration = schema.enumerateGroups();
1455: while (enumeration.hasMoreElements()) {
1456: ModelGroup group = (ModelGroup) enumeration
1457: .nextElement();
1458: processGroup(group, schemaPrefix);
1459: }
1460: //--process AttributeGroups
1461: enumeration = schema.enumerateAttributeGroups();
1462: while (enumeration.hasMoreElements()) {
1463: AttributeGroupDecl attGroup = (AttributeGroupDecl) enumeration
1464: .nextElement();
1465: processAttributeGroup(attGroup, schemaPrefix);
1466: }
1467: }
1468: _handler.endElement(ELEMENT_NAME);
1469: } //-- processImport
1470:
1471: /**
1472: * Processes the given simple type definition
1473: *
1474: * @param simpleType the simple type definition to process into events
1475: * @param schemaPrefix the namespace prefix to use for schema elements
1476: **/
1477: private void processSimpleType(SimpleType simpleType,
1478: String schemaPrefix) throws SAXException {
1479:
1480: if (simpleType.isBuiltInType())
1481: return;
1482:
1483: String ELEMENT_NAME = schemaPrefix + SIMPLE_TYPE;
1484:
1485: _atts.clear();
1486:
1487: String name = simpleType.getName();
1488:
1489: //-- top-level simple type
1490: if (name != null) {
1491: _atts.addAttribute(SchemaNames.NAME_ATTR, CDATA, name);
1492: }
1493:
1494: //-- @final
1495: if (simpleType.getFinal() != null) {
1496: _atts.addAttribute(SchemaNames.FINAL_ATTR, CDATA,
1497: simpleType.getFinal());
1498: }
1499:
1500: //-- @id
1501: if (simpleType.getId() != null) {
1502: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, simpleType
1503: .getId());
1504: }
1505:
1506: _handler.startElement(ELEMENT_NAME, _atts);
1507:
1508: //-- process annotations
1509: processAnnotated(simpleType, schemaPrefix);
1510:
1511: //-- handle restriction
1512: SimpleType base = (SimpleType) simpleType.getBaseType();
1513: boolean isRestriction = false;
1514: if (base != null) {
1515: if (simpleType instanceof ListType) {
1516: isRestriction = (base instanceof ListType);
1517: } else
1518: isRestriction = true;
1519: }
1520:
1521: if (isRestriction) {
1522:
1523: String ELEM_RESTRICTION = schemaPrefix + RESTRICTION;
1524:
1525: _atts.clear();
1526:
1527: String typeName = base.getName();
1528: //-- add "xsd" prefix if necessary
1529: if (typeName.indexOf(':') < 0) {
1530: if (base.isBuiltInType()) {
1531: typeName = schemaPrefix + typeName;
1532: } else {
1533: String targetNamespace = base.getSchema()
1534: .getTargetNamespace();
1535: String prefix = getNSPrefix(simpleType.getSchema(),
1536: targetNamespace);
1537: if ((prefix != null) && (prefix.length() > 0)) {
1538: typeName = prefix + ":" + typeName;
1539: }
1540: }
1541: }
1542: _atts.addAttribute(SchemaNames.BASE_ATTR, CDATA, typeName);
1543:
1544: _handler.startElement(ELEM_RESTRICTION, _atts);
1545:
1546: //-- process facets
1547: Enumeration enumeration = simpleType.getLocalFacets();
1548: while (enumeration.hasMoreElements()) {
1549: Facet facet = (Facet) enumeration.nextElement();
1550: _atts.clear();
1551: _atts.addAttribute(SchemaNames.VALUE_ATTR, CDATA, facet
1552: .getValue());
1553: String facetName = schemaPrefix + facet.getName();
1554: _handler.startElement(facetName, _atts);
1555: Enumeration annotations = facet.getAnnotations();
1556: while (annotations.hasMoreElements()) {
1557: Annotation annotation = (Annotation) annotations
1558: .nextElement();
1559: processAnnotation(annotation, schemaPrefix);
1560: }
1561: _handler.endElement(facetName);
1562: }
1563:
1564: _handler.endElement(ELEM_RESTRICTION);
1565: } else if (simpleType instanceof Union) {
1566: processUnion((Union) simpleType, schemaPrefix);
1567: }
1568: //-- handle List
1569: else {
1570:
1571: String ELEM_LIST = schemaPrefix + SchemaNames.LIST;
1572:
1573: _atts.clear();
1574:
1575: SimpleType itemType = ((ListType) simpleType).getItemType();
1576:
1577: boolean topLevel = (itemType.getParent() == itemType
1578: .getSchema());
1579: if (itemType.isBuiltInType() || topLevel) {
1580: String typeName = itemType.getName();
1581: //-- add "xsd" prefix if necessary
1582: if ((typeName.indexOf(':') < 0)
1583: && itemType.isBuiltInType()) {
1584: typeName = schemaPrefix + typeName;
1585: }
1586: _atts.addAttribute("itemType", CDATA, typeName);
1587: }
1588: _handler.startElement(ELEM_LIST, _atts);
1589:
1590: //-- processAnnotations
1591: Annotation ann = ((ListType) simpleType)
1592: .getLocalAnnotation();
1593: if (ann != null) {
1594: processAnnotation(ann, schemaPrefix);
1595: }
1596: //-- process simpleType if necessary
1597: if ((!topLevel) && (!itemType.isBuiltInType())) {
1598: processSimpleType(itemType, schemaPrefix);
1599: }
1600: _handler.endElement(ELEM_LIST);
1601: }
1602:
1603: _handler.endElement(ELEMENT_NAME);
1604:
1605: } //-- processSimpleType
1606:
1607: /**
1608: * Processes the given simpleType Union definition
1609: *
1610: * @param union the simpleType Union definition to process into events
1611: * @param schemaPrefix the namespace prefix to use for schema elements
1612: **/
1613: private void processUnion(Union union, String schemaPrefix)
1614: throws SAXException {
1615:
1616: String ELEMENT_NAME = schemaPrefix + SchemaNames.UNION;
1617:
1618: _atts.clear();
1619:
1620: if (union.getId() != null) {
1621: _atts.addAttribute(SchemaNames.ID_ATTR, CDATA, union
1622: .getId());
1623: }
1624:
1625: //-- process local simpleType references
1626: StringBuffer memberTypes = new StringBuffer();
1627: Enumeration enumeration = union.getMemberTypes();
1628: while (enumeration.hasMoreElements()) {
1629: SimpleType simpleType = (SimpleType) enumeration
1630: .nextElement();
1631: //-- ignore local simpleTypes;
1632: if (simpleType.getParent() != union.getSchema()) {
1633: continue;
1634: }
1635: //-- process top-level references
1636: if (memberTypes.length() > 0)
1637: memberTypes.append(' ');
1638: memberTypes.append(simpleType.getName());
1639: }
1640: if (memberTypes.length() > 0) {
1641: _atts.addAttribute(SchemaNames.MEMBER_TYPES_ATTR, CDATA,
1642: memberTypes.toString());
1643: }
1644:
1645: _handler.startElement(ELEMENT_NAME, _atts);
1646:
1647: //-- process local annotation
1648: Annotation annotation = union.getLocalAnnotation();
1649: if (annotation != null) {
1650: processAnnotation(annotation, schemaPrefix);
1651: }
1652:
1653: //-- process local simpleType definitions
1654: enumeration = union.getMemberTypes();
1655: while (enumeration.hasMoreElements()) {
1656: SimpleType simpleType = (SimpleType) enumeration
1657: .nextElement();
1658: //-- ignore top-level simpleTypes;
1659: if (simpleType.getParent() == union.getSchema())
1660: continue;
1661: processSimpleType(simpleType, schemaPrefix);
1662: }
1663: _handler.endElement(ELEMENT_NAME);
1664:
1665: } //-- processUnion
1666:
1667: /**
1668: * Determines if a given XMLType is imported by the
1669: * schema containing the element that refers to it.
1670: *
1671: * @param type the type to be checked to see if it is imported
1672: * @param element the schema element that references the type
1673: **/
1674: private boolean isImportedType(XMLType type, ElementDecl element) {
1675: String targetNS = type.getSchema().getTargetNamespace();
1676: if (targetNS != null)
1677: return (element.getSchema().getImportedSchema(targetNS) != null);
1678: else
1679: return false;
1680: } //-- isImportedType
1681:
1682: /**
1683: * Determines the proper namespace prefix for a namespace
1684: * by scanning all declared namespaces for the schema.
1685: *
1686: * @param schema the schema in which the namespace is declared
1687: * @param namespace the namespace for which a prefix will be returned
1688: **/
1689: private String getNSPrefix(Schema schema, String namespace) {
1690: if (namespace == null)
1691: namespace = "";
1692: return schema.getNamespaces().getNamespacePrefix(namespace);
1693: } //-- getNSPrefix
1694:
1695: } //-- SchemaWriter
|