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