You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jaxme-dev@ws.apache.org by jo...@apache.org on 2004/09/24 00:23:35 UTC
cvs commit: ws-jaxme/src/xs/org/apache/ws/jaxme/xs/junit DTDParserTest.java
jochen 2004/09/23 15:23:35
Modified: src/xs/org/apache/ws/jaxme/xs/xml XsQName.java XsNCName.java
src/xs/org/apache/ws/jaxme/xs/util DTDParser.java
Added: src/xs/org/apache/ws/jaxme/xs/junit DTDParserTest.java
Log:
More work on the DTDParser, including a unit test.
Revision Changes Path
1.5 +5 -0 ws-jaxme/src/xs/org/apache/ws/jaxme/xs/xml/XsQName.java
Index: XsQName.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/xs/org/apache/ws/jaxme/xs/xml/XsQName.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XsQName.java 27 Aug 2004 01:02:41 -0000 1.4
+++ XsQName.java 23 Sep 2004 22:23:35 -0000 1.5
@@ -43,6 +43,11 @@
if (pLocalName == null) {
throw new NullPointerException("The localName must not be null.");
}
+ int offset = pLocalName.indexOf(':');
+ if (offset >= 0) {
+ throw new IllegalArgumentException("The localName " + pLocalName +
+ " is invalid, because it contains a namespace prefix.");
+ }
localName = pLocalName;
prefix = pPrefix;
}
1.3 +3 -0 ws-jaxme/src/xs/org/apache/ws/jaxme/xs/xml/XsNCName.java
Index: XsNCName.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/xs/org/apache/ws/jaxme/xs/xml/XsNCName.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- XsNCName.java 16 Feb 2004 23:39:46 -0000 1.2
+++ XsNCName.java 23 Sep 2004 22:23:35 -0000 1.3
@@ -27,6 +27,9 @@
if (pValue == null || pValue.length() == 0) {
throw new NullPointerException("An NCName cannot be null or empty.");
}
+ if (pValue.indexOf(':') >= 0) {
+ throw new IllegalArgumentException("NCName " + pValue + " is invalid, because it contains a namespace prefix");
+ }
value = pValue;
}
1.2 +104 -37 ws-jaxme/src/xs/org/apache/ws/jaxme/xs/util/DTDParser.java
Index: DTDParser.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/xs/org/apache/ws/jaxme/xs/util/DTDParser.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DTDParser.java 22 Sep 2004 10:08:01 -0000 1.1
+++ DTDParser.java 23 Sep 2004 22:23:35 -0000 1.2
@@ -13,6 +13,9 @@
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
+import org.apache.ws.jaxme.xs.XSSchema;
+import org.apache.ws.jaxme.xs.impl.XSLogicalParser;
+import org.apache.ws.jaxme.xs.parser.XSContext;
import org.apache.ws.jaxme.xs.parser.impl.XSContextImpl;
import org.apache.ws.jaxme.xs.types.XSAnyType;
import org.apache.ws.jaxme.xs.types.XSEntities;
@@ -27,21 +30,25 @@
import org.apache.ws.jaxme.xs.xml.XsAGOccurs;
import org.apache.ws.jaxme.xs.xml.XsAnyURI;
import org.apache.ws.jaxme.xs.xml.XsEChoice;
+import org.apache.ws.jaxme.xs.xml.XsEComplexContent;
import org.apache.ws.jaxme.xs.xml.XsEEnumeration;
import org.apache.ws.jaxme.xs.xml.XsERestriction;
import org.apache.ws.jaxme.xs.xml.XsESchema;
import org.apache.ws.jaxme.xs.xml.XsESimpleContent;
+import org.apache.ws.jaxme.xs.xml.XsGAttrDecls;
import org.apache.ws.jaxme.xs.xml.XsNCName;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.apache.ws.jaxme.xs.xml.XsTAttribute;
import org.apache.ws.jaxme.xs.xml.XsTComplexType;
import org.apache.ws.jaxme.xs.xml.XsTExplicitGroup;
+import org.apache.ws.jaxme.xs.xml.XsTExtensionType;
import org.apache.ws.jaxme.xs.xml.XsTLocalComplexType;
import org.apache.ws.jaxme.xs.xml.XsTLocalElement;
import org.apache.ws.jaxme.xs.xml.XsTLocalSimpleType;
import org.apache.ws.jaxme.xs.xml.XsTSimpleExtensionType;
import org.apache.ws.jaxme.xs.xml.XsTTopLevelElement;
import org.apache.ws.jaxme.xs.xml.impl.XsESchemaImpl;
+import org.apache.ws.jaxme.xs.xml.impl.XsObjectFactoryImpl;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
@@ -55,7 +62,7 @@
/** A SAX parser converting a DTD into an instance of XML Schema.
*/
-public class DTDParser {
+public class DTDParser extends XSLogicalParser {
/** This class is used to collect the attributes in the
* DTD temporarily.
*/
@@ -69,10 +76,11 @@
type = pType;
mode = pMode;
value = pValue;
- if (locator == null) {
+ Locator l = DTDParser.this.getLocator();
+ if (l == null) {
loc = null;
} else {
- loc = new LocatorImpl(locator);
+ loc = new LocatorImpl(l);
}
}
/** Returns the attributes name.
@@ -118,10 +126,11 @@
/** Sets the elements content model.
*/
public void setModel(String pModel) {
- if (locator == null) {
+ Locator l = DTDParser.this.getLocator();
+ if (l == null) {
loc = null;
} else {
- loc = new LocatorImpl(locator);
+ loc = new LocatorImpl(l);
}
model = pModel;
}
@@ -249,7 +258,7 @@
*/
public class DtdDeclHandler extends DefaultHandler implements DeclHandler {
public void setDocumentLocator(Locator pLocator) {
- locator = pLocator;
+ setLocator(pLocator);
}
public void elementDecl(String pName, String pModel) throws SAXException {
@@ -260,7 +269,7 @@
} else {
if (element.getModel() != null) {
throw new SAXParseException("Element " + pName
- + " declared twice", locator);
+ + " declared twice", getLocator());
}
}
element.setModel(pModel);
@@ -278,7 +287,7 @@
}
public void internalEntityDecl(String pName, String pValue) throws SAXException {
- }
+ }
public void externalEntityDecl(String pName, String publicId, String pSystemId) throws SAXException {
}
@@ -288,6 +297,27 @@
private final Map elements = new HashMap();
private String dummyElementName;
private XsAnyURI targetNamespace;
+ private XSContext context;
+
+ public XSContext getData() {
+ return context;
+ }
+
+ /** Returns the document locator.
+ */
+ public Locator getLocator() {
+ return locator;
+ }
+
+ /** Sets the document locator.
+ */
+ public void setLocator(Locator pLocator) {
+ locator = pLocator;
+ XSContext context = getData();
+ if (context != null) {
+ context.setLocator(pLocator);
+ }
+ }
protected String getDummyElementName() {
if (dummyElementName == null) {
@@ -305,7 +335,7 @@
/** Parses the given DTD, filling the parsers
* temporary map of elements.
*/
- protected void parse(final InputSource pSource)
+ protected void runXMLReader(final InputSource pSource)
throws ParserConfigurationException, IOException, SAXException {
/* We cannot parse the DTD directly. Instead, we create
* a dummy XML document, which references the DTD as
@@ -322,6 +352,9 @@
return "uri:dtd".equals(pSystemId) ? pSource : null;
}
});
+ DtdDeclHandler handler = new DtdDeclHandler();
+ xr.setContentHandler(handler);
+ xr.setProperty("http://xml.org/sax/properties/declaration-handler", handler);
xr.parse(isource);
}
@@ -395,13 +428,13 @@
ct = addToChildToken(ct, t, multiplicity,
(c == '|' ? ChildToken.CHOICE : ChildToken.SEQUENCE),
pLocator);
+ offset = i+1;
}
-
}
}
String t = model.substring(offset).trim();
return addToChildToken(ct, t, multiplicity,
- ct == null ? ct.getType() : ChildToken.SEQUENCE,
+ ct == null ? ChildToken.SEQUENCE : ct.getType(),
pLocator);
}
@@ -440,7 +473,7 @@
pLocator);
}
XsTLocalElement e = pGroup.createElement();
- e.setRef(new XsQName(getTargetNamespace(), name));
+ e.setRef(new XsQName(getTargetNamespace(), getLocalPart(name)));
setMultiplicity(e, multiplicity);
} else if (o instanceof ChildToken) {
ChildToken ct = (ChildToken) o;
@@ -466,7 +499,7 @@
* seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
* </pre>
*/
- protected void parseChildren(XsTTopLevelElement pElement, String pModel,
+ protected XsGAttrDecls parseChildren(XsTTopLevelElement pElement, String pModel,
Locator pLocator) throws SAXException {
ChildToken ct = parseChildren(pModel, pLocator);
XsTLocalComplexType complexType = pElement.createComplexType();
@@ -477,6 +510,7 @@
group = complexType.createChoice();
}
addChildren(pElement, group, ct, pLocator);
+ return complexType;
}
/** Parses a mixed content model. The mixed content model
@@ -486,8 +520,8 @@
* | '(' S? '#PCDATA' S? ')'
* </pre>
*/
- protected void parseMixed(XsTTopLevelElement pElement, String pModel,
- Locator pLocator, boolean pHasAttributes)
+ protected XsGAttrDecls parseMixed(XsTTopLevelElement pElement, String pModel,
+ Locator pLocator, boolean pHasAttributes)
throws SAXException {
if (!pModel.startsWith("(")) {
throw new SAXParseException("Mixed content model must start with '(#PCDATA'",
@@ -519,8 +553,10 @@
XsESimpleContent simpleContent = complexType.createSimpleContent();
XsTSimpleExtensionType ext = simpleContent.createExtension();
ext.setBase(qName);
+ return ext;
} else {
pElement.setType(qName);
+ return null;
}
} else if (!unbounded) {
throw new SAXParseException("Mixed content must be either #PCDATA or have multiplicity '*'",
@@ -548,7 +584,7 @@
}
if (elements.containsKey(name)) {
XsTLocalElement e = choice.createElement();
- e.setRef(new XsQName(getTargetNamespace(), name));
+ e.setRef(new XsQName(getTargetNamespace(), getLocalPart(name)));
} else {
throw new SAXParseException("Element " + pElement.getName()
+ " references element " + name
@@ -556,16 +592,16 @@
pLocator);
}
}
+ return complexType;
}
}
/** Creates a new attribute.
*/
- protected void createAttribute(XsTTopLevelElement pElement, DTDAttribute pAttribute)
+ protected void createAttribute(XsGAttrDecls pAttrDecls, DTDAttribute pAttribute)
throws SAXException {
- XsTComplexType complexType = pElement.getComplexType();
- XsTAttribute attr = complexType.createAttribute();
- attr.setName(new XsNCName(pAttribute.getName()));
+ XsTAttribute attr = pAttrDecls.createAttribute();
+ attr.setName(new XsNCName(getLocalPart(pAttribute.getName())));
String type = pAttribute.getType();
XsQName qName;
if ("CDATA".equals(type)) {
@@ -635,6 +671,15 @@
}
}
+ private String getLocalPart(String pName) {
+ int offset = pName.indexOf(':');
+ if (offset >= 0) {
+ return pName.substring(offset+1);
+ } else {
+ return pName;
+ }
+ }
+
/** Creates an element named <code>pName</code> with the
* content model <code>pModel</code> and the attribute
* list <code>pAttrs</code> in the schema <code>pSchema</code>.
@@ -645,18 +690,29 @@
Locator pLocator)
throws SAXException {
XsTTopLevelElement result = pSchema.createElement();
- result.setName(new XsNCName(pName));
+ result.setName(new XsNCName(getLocalPart(pName)));
+ XsGAttrDecls attrDecls;
if ("EMPTY".equals(pModel)) {
- result.createComplexType();
+ attrDecls = result.createComplexType();
} else if ("ANY".equals(pModel)) {
XsQName qName = XSAnyType.getInstance().getName();
- result.setType(new XsQName(qName.getNamespaceURI(), qName.getLocalName(), "xs"));
+ qName = new XsQName(qName.getNamespaceURI(), qName.getLocalName(), "xs");
+ if (pAttributes.length == 0) {
+ result.setType(qName);
+ attrDecls = null;
+ } else {
+ XsTComplexType complexType = result.createComplexType();
+ XsEComplexContent complexContent = complexType.createComplexContent();
+ XsTExtensionType extensionType = complexContent.createExtension();
+ extensionType.setBase(qName);
+ attrDecls = extensionType;
+ }
} else if (pModel.startsWith("(")) {
String pcData = pModel.substring(1).trim();
if (pcData.startsWith("#PCDATA")) {
- parseMixed(result, pModel, pLocator, pAttributes.length == 0);
+ attrDecls = parseMixed(result, pModel, pLocator, pAttributes.length == 0);
} else {
- parseChildren(result, pModel, pLocator);
+ attrDecls = parseChildren(result, pModel, pLocator);
}
} else {
throw new SAXParseException("Invalid content model in element " + pName
@@ -664,7 +720,7 @@
pLocator);
}
for (int i = 0; i < pAttributes.length; i++) {
- createAttribute(result, pAttributes[i]);
+ createAttribute(attrDecls, pAttributes[i]);
}
return result;
}
@@ -673,11 +729,9 @@
* converts it into an instance of
* {@link org.apache.ws.jaxme.xs.xml.XsESchema}.
*/
- public XsESchema getSchema(InputSource pSource)
+ protected void parse(XsESchema pSchema, InputSource pSource)
throws ParserConfigurationException, IOException, SAXException {
- parse(pSource);
- XsESchema schema = new XsESchemaImpl(new XSContextImpl()){
- };
+ runXMLReader(pSource);
for (Iterator iter = elements.values().iterator(); iter.hasNext(); ) {
DTDElement element = (DTDElement) iter.next();
String name = element.getName();
@@ -690,9 +744,28 @@
+ ", but never declared.",
attrs[0].getLocator());
}
- createElement(schema, name, model, element.getAttributes(),
+ createElement(pSchema, name, model, element.getAttributes(),
element.getLocator());
}
+ }
+
+ public XSSchema parse(InputSource pInputSource)
+ throws ParserConfigurationException, IOException, SAXException {
+ XsObjectFactoryImpl xsObjectFactory = new XsObjectFactoryImpl(){
+ public XSContext getContext() {
+ return getData();
+ }
+ };
+ context = new XSContextImpl();
+ context.setXSLogicalParser(this);
+ context.setXsObjectFactory(xsObjectFactory);
+ clearSyntaxSchemas();
+ XsESchema syntaxSchema = new XsESchemaImpl(context){
+ };
+ parse(syntaxSchema, pInputSource);
+ XSSchema schema = context.getXSObjectFactory().newXSSchema(context, syntaxSchema);
+ setSchema(schema);
+ addSyntaxSchema(syntaxSchema);
return schema;
}
@@ -706,11 +779,5 @@
*/
public XsAnyURI getTargetNamespace() {
return targetNamespace;
- }
-
- public static void main(String[] pArgs) throws Exception {
- String s = "<!ELEMENT a (#PCDATA)>";
- InputSource dtd = new InputSource(new StringReader(s));
- new DTDParser().getSchema(dtd);
}
}
1.1 ws-jaxme/src/xs/org/apache/ws/jaxme/xs/junit/DTDParserTest.java
Index: DTDParserTest.java
===================================================================
package org.apache.ws.jaxme.xs.junit;
import java.io.File;
import java.io.FileReader;
import org.apache.ws.jaxme.xs.util.DTDParser;
import org.xml.sax.InputSource;
import junit.framework.TestCase;
/** A unit test for the
* {@link org.apache.ws.jaxme.xs.util.DTDParser}.
*/
public class DTDParserTest extends TestCase {
/** Creates a new test case with the given name.
*/
public DTDParserTest(String pName) { super(pName); }
/** Parses the file XMLSchema.dtd.
*/
public void testXMLSchemaDtd() throws Exception {
String path = System.getProperty("path.xmlSchema.dtd", "examples/xs/XMLSchema.dtd");
File f = new File(path);
InputSource isource = new InputSource(new FileReader(f));
isource.setSystemId(f.toURL().toString());
new DTDParser().parse(isource);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: jaxme-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: jaxme-dev-help@ws.apache.org