/**
* 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