/** * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Intalio, Inc. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Intalio, Inc. Exolab is a registered * trademark of Intalio, Inc. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2000 (C) Intalio Inc. All Rights Reserved. * * $Id$ */ package org.exolab.castor.xml.dtd; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.Writer; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.exolab.castor.xml.dtd.parser.DTDInitialParser; import org.exolab.castor.xml.dtd.parser.DTDParser; import org.exolab.castor.xml.dtd.parser.InputCharStream; import org.exolab.castor.xml.dtd.parser.ParseException; import org.exolab.castor.xml.dtd.parser.TokenMgrError; import org.exolab.castor.xml.schema.Annotation; import org.exolab.castor.xml.schema.AttributeDecl; import org.exolab.castor.xml.schema.ComplexType; import org.exolab.castor.xml.schema.ContentType; import org.exolab.castor.xml.schema.Documentation; import org.exolab.castor.xml.schema.ElementDecl; import org.exolab.castor.xml.schema.Facet; import org.exolab.castor.xml.schema.FacetFactory; import org.exolab.castor.xml.schema.Group; import org.exolab.castor.xml.schema.Order; import org.exolab.castor.xml.schema.Particle; import org.exolab.castor.xml.schema.Schema; import org.exolab.castor.xml.schema.SchemaException; import org.exolab.castor.xml.schema.SimpleType; import org.exolab.castor.xml.schema.SimpleTypesFactory; import org.exolab.castor.xml.schema.Wildcard; import org.exolab.castor.xml.schema.writer.SchemaWriter; import org.xml.sax.SAXException; /** * Class containing methods to parse and convert XML DTD * documents to corresponding XML Schema documents. Also contains simple command * line interface to read an XML DTD file and create corresponding XML Schema * object. * * @author <a href="mailto:totok@intalio.com">Alexander Totok</a> * @version $Revision$ $Date: 2006-04-14 04:14:43 -0600 (Fri, 14 Apr * 2006) $ */ public class Converter { private static final Log log = LogFactory.getLog(Converter.class); public static final String NAME_SPACE_PREFIX_KEY = "nameSpacePrefixKey"; public static final String NAME_SPACE_KEY = "nameSpaceKey"; public static final String DEFAULT_NAME_SPACE_PREFIX = "tns"; public static final String DEFAULT_NAME_SPACE = "generated.castor.org"; /** * Simple command line interface to read an XML DTD file and create * corresponding XML Schema file. Usage: * * <pre> * java org.exolab.castor.xml.dtd.Converter dtd_file xsd_file [character_encoding] * [-tns=[TNS_PREFIX:]NAMESPACE_URI] * [-xmlns=[TNS_PREFIX:]NAMESPACE_URI]* * * dtd_file: name of the input DTD file * xsd_file: name of the output Schema file * character_encoding: name of the character encoding, * if not specified, ASCII is chosen * </pre> * * Help message is provided. * * @throws DTDException * if the input DTD document is malformed. * @throws SchemaException * if Schema object can not be created. * @throws SAXException * if an error occured during marshalling of schema object * constructed from the DTD document. */ public static void main(String args[]) throws IOException, DTDException, SchemaException, SAXException { StringBuffer header = new StringBuffer(); header.append("\n"); header.append("Converts a DTD to an XML schema.\n\n"); header.append(" <DTD>: Name of the input DTD file.\n"); header.append(" <XSD>: Name of the output XML schema file.\n"); header.append("\n"); header.append("Options:"); Options options = new Options(); Option targetNamespace = OptionBuilder .withDescription("target namespace of the XML schema generated") .isRequired(false) .withLongOpt("targetNamespace") .hasArg() .withArgName("[prefix:]uri") .create("tns"); Option xmlns = OptionBuilder .withDescription("xml namespace declarations") .isRequired(false) .hasArgs() .withValueSeparator(',') .withArgName("[[prefix:]uri]*") .create("xmlns"); options.addOption(targetNamespace); options.addOption(xmlns); options.addOption("h", "help", false, "prints usage information"); options.addOption("e", "encoding", false, "character encoding"); CommandLineParser parser = new GnuParser(); CommandLine line = null; try { line = parser.parse(options, args); } catch (org.apache.commons.cli.ParseException e) { System.err.println( "Parsing failed. Reason: " + e.getMessage() ); } if (args.length < 2 || line.hasOption("help")) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("org.exolab.castor.xml.dtd.Converter <DTD> <XSD>", header.toString(), options, ""); return; } String encoding = "US-ASCII"; String targetNameSpace = DEFAULT_NAME_SPACE; Map<String, String> nameSpaceMap = new HashMap<String, String>(); if (line.hasOption("tns")) { log.info("Found option -tns ..."); Map<String, String> nameSpaceMapTemp = parseNamespace(line.getOptionValue("tns")); targetNameSpace = nameSpaceMapTemp.get(NAME_SPACE_KEY); nameSpaceMap.put(nameSpaceMapTemp.get(NAME_SPACE_PREFIX_KEY), targetNameSpace); } if (line.hasOption("xmlns")) { log.info("Found option -xmlns ..."); Map<String, String> nameSpaceMapTemp = parseNamespace(line.getOptionValue("xmlns")); nameSpaceMap.put(nameSpaceMapTemp.get(NAME_SPACE_PREFIX_KEY), nameSpaceMapTemp.get(NAME_SPACE_KEY)); } if (line.hasOption("encoding")) { log.info("Found option -encoding ..."); String encodingValue = line.getOptionValue("encoding"); if (encodingValue.equalsIgnoreCase("ascii") || args[2].equalsIgnoreCase("us-ascii")) { encoding = "US-ASCII"; } else if (encodingValue.equalsIgnoreCase("utf-8")) { encoding = "UTF-8"; } else if (encodingValue.equalsIgnoreCase("utf-16")) { encoding = "UTF-16"; } else { encoding = encodingValue.toUpperCase(); } } String inFile = args[0]; String outFile = args[1]; Converter convertor = new Converter(); convertor.process(inFile, outFile, encoding, targetNameSpace, nameSpaceMap); } /** * @param dtdFile Location of the DTD file. * @param schemaFile Location of the XML schema file. * @param encoding (Optional) encoding. * @param targetNamespace (Optional) target name space. * @param namespaces (Optional) XML name spaces. * @throws SchemaException * @throws DTDException * @throws IOException * @throws SAXException */ public void process(final String dtdFile, final String schemaFile, final String encoding, final String targetNamespace, final Map<String, String> namespaces) throws SchemaException, DTDException, IOException, SAXException { // instantiate input byte stream, associated with the input file FileInputStream inputStream = new FileInputStream(dtdFile); // instantiate char reader from input file byte stream InputStreamReader reader = new InputStreamReader(inputStream, encoding); // instantiate output byte stream, associated with the output file FileOutputStream outputStream = new FileOutputStream(schemaFile); // instantiate char writer from output file byte stream OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding); process (reader, writer, encoding, targetNamespace, namespaces); } /** * @param in Location of the DTD file. * @param out Location of the XML schema file. * @param encoding (Optional) encoding. * @param targetNamespace (Optional) target name space. * @param namespaces (Optional) XML name spaces. * @throws SchemaException * @throws DTDException * @throws IOException * @throws SAXException */ public void process(final Reader in, final Writer out, final String encoding, final String targetNamespace, final Map<String, String> namespaces) throws SchemaException, DTDException, IOException, SAXException { // -- convert DTD to Schema convertDTDtoSchema(in, out, targetNamespace, namespaces); in.close(); out.close(); } protected static Map<String, String> parseNamespace(final String nameSpaceArg) { Map<String, String> nameSpaceMap = new HashMap<String, String>(); if ("".equals(nameSpaceArg.substring("-tns=".length()))) { throw new RuntimeException("name space argument is emty, Spaces after '='? "); } String[] tnsToken = nameSpaceArg.substring("-tns=".length()).split(":", 2); if (isNameSpacePrefix(tnsToken[0])) { nameSpaceMap.put(NAME_SPACE_PREFIX_KEY, tnsToken[0]); nameSpaceMap.put(NAME_SPACE_KEY, tnsToken[1]); } else { nameSpaceMap.put(NAME_SPACE_KEY, nameSpaceArg.substring("-tns=".length())); nameSpaceMap.put(NAME_SPACE_PREFIX_KEY, "tns"); } // -- namespace return nameSpaceMap; } protected static boolean isNameSpacePrefix(String nameSpacePrefix2test) { if (!nameSpacePrefix2test.matches("[a-z]*")) { return false; } if (nameSpacePrefix2test.matches("https?")) { return false; } return true; } /** * Convert DTD document to corresponding XML Schema document. * * @param reader * reader of the input DTD document. * @param writer * writer to the output Schema document. * @param targetNameSpaceMap * (Optional) XML target name space for the XML schema. * @param nameSpaceMap * (Optional) XML name space declarations for the XML schema. * @throws DTDException * if the DTD document is syntactically or semantically not * correct. * @throws SchemaException * if Schema object can not be created. * @throws IOException * if there is an I/O problem with the <tt>reader</tt> or * <tt>writer</tt>. * @throws SAXException * if an error occured during schema object marshalling. */ public void convertDTDtoSchema(Reader reader, Writer writer, String targetNameSpace, Map<String, String> nameSpaceMap) throws DTDException, SchemaException, IOException, SAXException { // -- parse text of DTD document DTDdocument dtd = parseDTD(reader); // -- convert DTD document object into its corresponding Schema object Schema schema = convertDTDObjectToSchemaObject(dtd, targetNameSpace, nameSpaceMap); // -- marshal Schema object into its corresponding XML document marshalSchema(schema, writer); } // -- convertDTDtoSchema /** * Convert DTD document to corresponding XML Schema document. * * @param reader * reader of the input DTD document. * @param writer * writer to the output Schema document. * * @throws DTDException * if the DTD document is syntactically or semanticly not * correct. * @throws SchemaException * if Schema object can not be created. * @throws IOException * if there is an I/O problem with the <tt>reader</tt> or * <tt>writer</tt>. * @throws SAXException * if an error occured during schema object marshalling. */ public void convertDTDtoSchema(Reader reader, Writer writer) throws DTDException, SchemaException, IOException, SAXException { String targetNameSpace = DEFAULT_NAME_SPACE; Map<String, String> nameSpaceMap = new HashMap<String, String>(); convertDTDtoSchema(reader, writer, targetNameSpace, nameSpaceMap); } /** * Parses text of a DTD document and returns corresponding DTD document * object. It is left to constructor of the <tt>reader</tt> to set up * character encoding correctly. This means that method <u><font * color="blue">read</font></u> of the <tt>reader</tt> is used to get next * character, assuming it returns appropriate values. * * @param reader * input char stream reader. It is recommended to use class * {@link java.io.InputStreamReader java.io.InputStreamReader} as * a <tt>reader</tt>, which allows to set desired character * encoding. * @return DTD document object corresponding to the input text of a DTD * document. * @throws DTDException * if the DTD document is syntactically or semanticly not * correct. */ public DTDdocument parseDTD(Reader reader) throws DTDException { try { InputCharStream charStream; // -- instantiate char stream for initial parser from the input // reader charStream = new InputCharStream(reader); // -- instantiate initial parser DTDInitialParser initialParser = new DTDInitialParser(charStream); // -- get result of initial parsing - DTD document with parameter // -- entity references expanded String intermedResult = initialParser.Input(); // -- construct StringReader from the intermediate result of parsing StringReader strReader = new StringReader(intermedResult); // -- instantiate char stream for main parser charStream = new InputCharStream(strReader); // -- instantiate main parser DTDParser parser = new DTDParser(charStream); // -- parse intermediate result by the main parser // -- and get corresponding DTD document oblect DTDdocument dtd = parser.Input(); strReader.close(); // -- return DTD document object return dtd; } catch (TokenMgrError tme) { String msg = tme.getMessage(); throw new DTDException("TokenMgrError" + (msg == null ? "" : ": " + msg)); } catch (ParseException pe) { String msg = pe.getMessage(); throw new DTDException("ParseException" + (msg == null ? "" : ": " + msg)); } } // -- parseDTD /** * Convert DTD document object to corresponding Schema object. * * @param dtd * input XML DTD document object. * @param nameSpacePrefix * * @param nameSpace * * @return corresponding XML Schema object. * @throws DTDException * if the input DTD document is malformed. * @throws SchemaException * if Schema object can not be created. */ public Schema convertDTDObjectToSchemaObject(DTDdocument dtd, String targetNamespace, Map nameSpaceMap) throws DTDException, SchemaException { Schema schema = new Schema(); String name = dtd.getName(); if (name != null && !name.equals("")) { schema.setId(name); } schema.setTargetNamespace(targetNamespace); for (Iterator<String> namespaces = nameSpaceMap.keySet().iterator(); namespaces .hasNext();) { String xmlns = namespaces.next(); schema.addNamespace(xmlns, (String) nameSpaceMap.get(xmlns)); } // convert Notation declarations Enumeration dtdNotations = dtd.getNotations(); while (dtdNotations.hasMoreElements()) { dtdNotations.nextElement(); // do nothing for now as the Castor Schema object model does not // support Notation declarations } // -- convert Notations declarations // convert General Entity declarations. // XML Schema does not provide facilities analogous to General Entity // declarations in XML DTD, so we convert each General Entity // declaration // to Documentation subelement of XML Schema document annotaion. Enumeration dtdGeneralEntities = dtd.getGeneralEntities(); if (dtdGeneralEntities.hasMoreElements()) { GeneralEntity ge; Annotation annotation = new Annotation(); Documentation documentation; String text; while (dtdGeneralEntities.hasMoreElements()) { ge = (GeneralEntity) dtdGeneralEntities.nextElement(); documentation = new Documentation(); text = "General Entity Declaration"; documentation.add(text); documentation.add(ge); annotation.addDocumentation(documentation); } schema.addAnnotation(annotation); } // -- convert General Entity declarations // convert Element declarations Enumeration<Element> dtdElements = dtd.getElements(); Element dtdElement; // DTD Element declaration ElementDecl schemaElement; // Schema Element declaration while (dtdElements.hasMoreElements()) { dtdElement = dtdElements.nextElement(); schemaElement = convertDTDElementToSchemaElement(dtdElement, schema); schema.addElementDecl(schemaElement); } // -- convert Element declarations return schema; } // -- convertDTDObjectToSchemaObject /** * Convert DTD Element declaration to Schema Element Declaration. * * @param dtdElement * DTD Element declaration. * @param schema * Schema owning Element declaration. * @throws DTDException * if the input DTD Element Declaration is malformed. * @throws SchemaException * if unable to construct return * {@link org.exolab.castor.xml.schema.ElementDecl ElementDecl} * object from the input DTD * {@link org.exolab.castor.xml.dtd.Element Element} object. * @return corresponding Schema Element declaration. */ public ElementDecl convertDTDElementToSchemaElement( Element dtdElement, Schema schema) throws DTDException, SchemaException { String name = dtdElement.getName(); if (name == null || name.equals("")) { String err = "DTD to Schema converter: a DTD element has no name."; throw new DTDException(err); } ElementDecl schemaElement = new ElementDecl(schema, name); // start converting content of the element ComplexType complexType = schema.createComplexType(); ContentType contentType = null; Group group = null; // auxiliary Iterator mixedChildrenIterator = null; // auxiliary String elementRef = null; // auxiliary ElementDecl elem = null; // auxiliary if (dtdElement.isEmptyContent()) { // mixed="false" contentType = ContentType.elemOnly; // -- mixed="false" } else if (dtdElement.isAnyContent()) { // mixed="true" contentType = ContentType.mixed; // -- mixed="true" group = new Group(); group.setOrder(Order.sequence); group.setMinOccurs(0); group.setMaxOccurs(-1); Wildcard any = new Wildcard(group); group.addWildcard(any); complexType.addGroup(group); } else if (dtdElement.isElemOnlyContent()) { // mixed="false" contentType = ContentType.elemOnly; // -- mixed="false" ContentParticle dtdContent = dtdElement.getContent(); if (dtdContent == null) { // content is not specified String err = "DTD to Schema converter: element \"" + dtdElement.getName(); err += "\" has no content."; throw new DTDException(err); } Particle content = null; try { content = convertContentParticle(dtdContent, schema); } catch (DTDException e) { String err = "DTD to Schema converter: content of DTD element \"" + dtdElement.getName(); err += "\", represented by a Content Particle, is malformed."; throw new DTDException(err); } if (content instanceof ElementDecl) { group = new Group(); group.setOrder(Order.sequence); group.addElementDecl((ElementDecl) content); complexType.addGroup(group); } else { complexType.addGroup((Group) content); } } else if (dtdElement.isMixedContent()) { // mixed="true" contentType = ContentType.mixed; // -- mixed="true" mixedChildrenIterator = dtdElement.getMixedContentChildren(); if ((mixedChildrenIterator != null) && (mixedChildrenIterator.hasNext())) { group = new Group(); group.setOrder(Order.choice); group.setMinOccurs(0); group.setMaxOccurs(-1); while (mixedChildrenIterator.hasNext()) { elementRef = (String) mixedChildrenIterator.next(); elem = new ElementDecl(schema); elem.setReferenceName(elementRef); group.addElementDecl(elem); } complexType.addGroup(group); } } else { // the type of the element has not been specified String err = "DTD to Schema converter: content type of DTD element \"" + dtdElement.getName(); err += "\" has not been specified."; throw new DTDException(err); } complexType.setContentType(contentType); // finish converting content of the element // start attributes convertion Enumeration dtdAttributes = dtdElement.getAttributes(); Attribute dtdAttribute; AttributeDecl schemaAttribute; while (dtdAttributes.hasMoreElements()) { dtdAttribute = (Attribute) dtdAttributes.nextElement(); schemaAttribute = convertAttribute(dtdAttribute, schema); complexType.addAttributeDecl(schemaAttribute); } // end attributes convertion schemaElement.setType(complexType); return schemaElement; } // -- convertDTDElementToSchemaElement /** * Method to convert {@link org.exolab.castor.xml.dtd.ContentParticle * ContentParticle} object, used to implement element content in the DTD * object model, to the corresponding object in the Schema object model: * either {@link org.exolab.castor.xml.schema.Group Group} or * {@link org.exolab.castor.xml.schema.ElementDecl ElementDecl}. * * @param dtdContent * input {@link org.exolab.castor.xml.dtd.ContentParticle * ContentParticle} object. * @return object returned is an instance of either * {@link org.exolab.castor.xml.schema.Group Group} class or * {@link org.exolab.castor.xml.schema.ElementDecl ElementDecl} * class. * @throws DTDException * if the input ContentParticle is malformed. * @throws SchemaException * if unable to construct return content object from a given * ContentParticle */ public Particle convertContentParticle(ContentParticle dtdContent, Schema schema) throws DTDException, SchemaException { Particle returnValue; if (dtdContent.isReferenceType()) { ElementDecl elem = new ElementDecl(schema); elem.setReferenceName(dtdContent.getReference()); returnValue = elem; } else if (dtdContent.isSeqType() || dtdContent.isChoiceType()) { Group group = new Group(); if (dtdContent.isSeqType()) group.setOrder(Order.sequence); else group.setOrder(Order.choice); Enumeration<ContentParticle> children = dtdContent.getChildren(); ContentParticle child; Particle contentParticle; while (children.hasMoreElements()) { child = children.nextElement(); contentParticle = convertContentParticle(child, schema); if (contentParticle instanceof ElementDecl) { group.addElementDecl((ElementDecl) contentParticle); } else { group.addGroup((Group) contentParticle); } } returnValue = group; } else { // -- type of input DTD Content Particle is not specified throw new DTDException(); } if (dtdContent.isOneOccurance()) { returnValue.setMinOccurs(1); returnValue.setMaxOccurs(1); } else if (dtdContent.isOneOrMoreOccurances()) { returnValue.setMinOccurs(1); returnValue.setMaxOccurs(-1); } else if (dtdContent.isZeroOrMoreOccurances()) { returnValue.setMinOccurs(0); returnValue.setMaxOccurs(-1); } else if (dtdContent.isZeroOrOneOccurance()) { returnValue.setMinOccurs(0); returnValue.setMaxOccurs(1); } else { // a content particle always has "one occurance" default // occurance specification } return returnValue; } // -- convertContentParticle /** * Convert DTD Attribute declaration to Schema Attribute Declaration. * * @param dtdAttribute * DTD Attribute declaration. * @param schema * Schema owning Element of this Attribute. * @throws DTDException * if the input DTD Attribute Declaration is malformed. * @return corresponding Schema Attribute declaration. */ public AttributeDecl convertAttribute(Attribute dtdAttribute, Schema schema) throws DTDException { AttributeDecl schemaAttribute = new AttributeDecl(schema, dtdAttribute .getName()); SimpleType type = null; if (dtdAttribute.isStringType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.STRING_TYPE)); } else if (dtdAttribute.isIDType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.ID_TYPE)); } else if (dtdAttribute.isIDREFType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.IDREF_TYPE)); } else if (dtdAttribute.isIDREFSType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.IDREFS_TYPE)); } else if (dtdAttribute.isENTITYType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.ENTITY_TYPE)); } else if (dtdAttribute.isENTITIESType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.ENTITIES_TYPE)); } else if (dtdAttribute.isNMTOKENType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.NMTOKEN_TYPE)); } else if (dtdAttribute.isNMTOKENSType()) { type = schema.getSimpleType(schema .getBuiltInTypeName(SimpleTypesFactory.NMTOKENS_TYPE)); } else if (dtdAttribute.isNOTATIONType()) { type = schema.createSimpleType(null, schema .getBuiltInTypeName(SimpleTypesFactory.NOTATION_TYPE), "restriction"); Iterator<String> values = dtdAttribute.getValues(); FacetFactory facetFactory = FacetFactory.getInstance(); while (values.hasNext()) { Facet facet = facetFactory.createFacet(Facet.ENUMERATION, values.next()); facet.setOwningType(type); type.addFacet(facet); } } else if (dtdAttribute.isEnumerationType()) { type = schema.createSimpleType(null, schema .getBuiltInTypeName(SimpleTypesFactory.NMTOKEN_TYPE), "restriction"); Iterator<String> values = dtdAttribute.getValues(); FacetFactory facetFactory = FacetFactory.getInstance(); while (values.hasNext()) { Facet facet = facetFactory.createFacet(Facet.ENUMERATION, values.next()); facet.setOwningType(type); type.addFacet(facet); } } else { String err = "DTD to Schema converter: DTD attribute \"" + dtdAttribute.getName(); err += "\" has unspecified type."; throw new DTDException(err); } schemaAttribute.setSimpleType(type); if (dtdAttribute.isREQUIRED()) { schemaAttribute.setUse(AttributeDecl.USE_REQUIRED); } else if (dtdAttribute.isIMPLIED()) { schemaAttribute.setUse(AttributeDecl.USE_OPTIONAL); } else if (dtdAttribute.isFIXED()) { // } else { // DTD attribute is of "DEFAULT" type schemaAttribute.setDefaultValue(dtdAttribute.getDefaultValue()); } return schemaAttribute; } // -- convertAttribute /** * Marshals XML Schema to output char stream. * * @param schema * XML Schema object to marshal. * @param writer * output char stream to marshal Schema to. * @throws IOException * if there is an I/O problem with the <tt>writer</tt>. * @throws SAXException * if an error occured during <tt>schema</tt> marshalling. */ public void marshalSchema(Schema schema, Writer writer) throws IOException, SAXException { SchemaWriter sw = new SchemaWriter(writer); sw.write(schema); } // -- marshalSchema } // -- Converter