neilg       2003/07/03 08:19:31

  Modified:    java/src/org/apache/xerces/impl/xs XSAnnotationImpl.java
                        SchemaGrammar.java
               java/src/org/apache/xerces/impl/xs/traversers
                        XSDAbstractTraverser.java
  Log:
  expose annotations in the PSVI.  Now the XSAnnotation implementation is complete 
(though probably not yet bug-free)
  
  Revision  Changes    Path
  1.2       +76 -2     
xml-xerces/java/src/org/apache/xerces/impl/xs/XSAnnotationImpl.java
  
  Index: XSAnnotationImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSAnnotationImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSAnnotationImpl.java     18 Jun 2003 03:05:07 -0000      1.1
  +++ XSAnnotationImpl.java     3 Jul 2003 15:19:30 -0000       1.2
  @@ -59,12 +59,39 @@
   import org.apache.xerces.impl.xs.psvi.XSAnnotation;
   import org.apache.xerces.impl.xs.psvi.XSConstants;
   import org.apache.xerces.impl.xs.psvi.XSNamespaceItem;
  +import org.apache.xerces.parsers.SAXParser;
  +import org.apache.xerces.parsers.DOMParser;
  +
  +import org.xml.sax.ContentHandler;
  +import org.xml.sax.SAXException;
  +import org.xml.sax.InputSource;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.Element;
  +import org.w3c.dom.Document;
  +import java.io.StringReader;
  +import java.io.IOException;
   
   /**
    * This is an implementation of the XSAnnotation schema component.
    */
   public class XSAnnotationImpl implements XSAnnotation {
   
  +    // Data
  +
  +    // the content of the annotation node, including all children, along
  +    // with any non-schema attributes from its parent
  +    private String fData = null;
  +
  +    // the grammar which owns this annotation; we get parsers
  +    // from here when we need them
  +    private SchemaGrammar fGrammar = null;
  +
  +    // constructors
  +    public XSAnnotationImpl(String contents, SchemaGrammar grammar) {
  +        fData = contents;
  +        fGrammar = grammar;
  +    }
  +
       /**
        *  Write contents of the annotation to the specified DOM object. If the 
        * specified <code>target</code> object is a DOM in-scope namespace 
  @@ -81,6 +108,13 @@
        */
       public boolean writeAnnotation(Object target, 
                                      short targetType) {
  +        if(targetType == XSAnnotation.W3C_DOM_ELEMENT || targetType == 
XSAnnotation.W3C_DOM_DOCUMENT) {
  +            writeToDOM((Node)target, targetType);
  +            return true;
  +        } else if (targetType == SAX_CONTENTHANDLER) {
  +            writeToSAX((ContentHandler)target);
  +            return true;
  +        }
           return false;
       }
   
  @@ -88,7 +122,7 @@
        * A text representation of annotation.
        */
       public String getAnnotationString() {
  -        return null;
  +        return fData;
       }
   
       // XSObject methods
  @@ -118,12 +152,52 @@
       }
   
       /**
  -     * A namespace schema information itemcorresponding to the target 
  +     * A namespace schema information item corresponding to the target 
        * namespace of the component, if it's globally declared; or null 
        * otherwise.
        */
       public XSNamespaceItem getNamespaceItem() {
           return null;
  +    }
  +
  +    // private methods
  +    private synchronized void writeToSAX(ContentHandler handler) {
  +        // nothing must go wrong with this parse...
  +        SAXParser parser = fGrammar.getSAXParser();
  +        StringReader aReader = new StringReader(fData);
  +        InputSource aSource = new InputSource(aReader);
  +        parser.setContentHandler(handler);
  +        try {
  +            parser.parse(aSource);
  +        } catch (SAXException e) {
  +            // this should never happen!
  +            // REVISIT:  what to do with this?; should really not
  +            // eat it...
  +        } catch (IOException i) {
  +            // ditto with above
  +        }
  +    }
  +
  +    // this creates the new Annotation element as the first child
  +    // of the Node
  +    private synchronized void writeToDOM(Node target, short type){
  +        Document futureOwner = (type == 
XSAnnotation.W3C_DOM_ELEMENT)?target.getOwnerDocument():(Document)target;
  +        DOMParser parser = fGrammar.getDOMParser();
  +        StringReader aReader = new StringReader(fData);
  +        InputSource aSource = new InputSource(aReader);
  +        try {
  +            parser.parse(aSource);
  +        } catch (SAXException e) {
  +            // this should never happen!
  +            // REVISIT:  what to do with this?; should really not
  +            // eat it...
  +        } catch (IOException i) {
  +            // ditto with above
  +        }
  +        Document aDocument = parser.getDocument();
  +        Element annotation = aDocument.getDocumentElement();
  +        Node newElem = futureOwner.importNode(annotation, true);
  +        target.insertBefore(newElem, target.getFirstChild());
       }
   
   }
  
  
  
  1.31      +53 -2     xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaGrammar.java
  
  Index: SchemaGrammar.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaGrammar.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- SchemaGrammar.java        23 Jun 2003 16:35:21 -0000      1.30
  +++ SchemaGrammar.java        3 Jul 2003 15:19:30 -0000       1.31
  @@ -83,7 +83,12 @@
   import org.apache.xerces.impl.xs.util.XSNamedMap4Types;
   import org.apache.xerces.impl.xs.util.XSNamedMapImpl;
   import org.apache.xerces.impl.xs.util.XSObjectListImpl;
  +import org.apache.xerces.impl.Constants;
  +import org.apache.xerces.parsers.DOMParser;
  +import org.apache.xerces.parsers.SAXParser;
  +import org.apache.xerces.parsers.IntegratedParserConfiguration;
   import org.apache.xerces.util.SymbolHash;
  +import org.apache.xerces.util.SymbolTable;
   import org.apache.xerces.xni.grammars.XMLGrammarDescription;
   import org.apache.xerces.xni.grammars.XSGrammar;
   
  @@ -125,6 +130,12 @@
       // number of annotations declared
       int fNumAnnotations;
   
  +    // symbol table for constructing parsers (annotation support)
  +    private SymbolTable fSymbolTable = null;
  +    // parsers for annotation support
  +    private SAXParser fSAXParser = null;
  +    private DOMParser fDOMParser = null;
  +
       //
       // Constructors
       //
  @@ -138,10 +149,13 @@
        * @param targetNamespace
        * @param grammarDesc the XMLGrammarDescription corresponding to this objec
        *               at the least a systemId should always be known.
  +     * @param symbolTable   needed for annotation support
        */
  -    public SchemaGrammar(String targetNamespace, XSDDescription grammarDesc) {
  +    public SchemaGrammar(String targetNamespace, XSDDescription grammarDesc,
  +                SymbolTable symbolTable) {
           fTargetNamespace = targetNamespace;
           fGrammarDescription = grammarDesc;
  +        fSymbolTable = symbolTable;
   
           // REVISIT: do we know the numbers of the following global decls
           // when creating this grammar? If so, we can pass the numbers in,
  @@ -292,6 +306,14 @@
           public synchronized void addDocument(Object document, String location) {
               // ignore
           }
  +
  +        // annotation support
  +        synchronized DOMParser getDOMParser() {
  +            return null;
  +        }
  +        synchronized SAXParser getSAXParser() {
  +            return null;
  +        }
       }
   
       // Grammar methods
  @@ -735,6 +757,35 @@
        */
       public String getSchemaNamespace() {
           return fTargetNamespace;
  +    }
  +
  +    // annotation support
  +    synchronized DOMParser getDOMParser() {
  +        if (fDOMParser != null) return fDOMParser;
  +        // REVISIT:  when schema handles XML 1.1, will need to 
  +        // revisit this (and the practice of not prepending an XML decl to the 
annotation string
  +        IntegratedParserConfiguration config = new 
IntegratedParserConfiguration(fSymbolTable);
  +        // note that this should never produce errors or require
  +        // entity resolution, so just a barebones configuration with
  +        // a couple of feature  set will do fine
  +        config.setFeature(Constants.SAX_FEATURE_PREFIX + 
Constants.NAMESPACES_FEATURE, true);
  +        config.setFeature(Constants.SAX_FEATURE_PREFIX + 
Constants.VALIDATION_FEATURE, false);
  +        fDOMParser = new DOMParser(config);
  +        return fDOMParser;
  +    }
  +
  +    synchronized SAXParser getSAXParser() {
  +        if (fSAXParser != null) return fSAXParser;
  +        // REVISIT:  when schema handles XML 1.1, will need to 
  +        // revisit this (and the practice of not prepending an XML decl to the 
annotation string
  +        IntegratedParserConfiguration config = new 
IntegratedParserConfiguration(fSymbolTable);
  +        // note that this should never produce errors or require
  +        // entity resolution, so just a barebones configuration with
  +        // a couple of feature  set will do fine
  +        config.setFeature(Constants.SAX_FEATURE_PREFIX + 
Constants.NAMESPACES_FEATURE, true);
  +        config.setFeature(Constants.SAX_FEATURE_PREFIX + 
Constants.VALIDATION_FEATURE, false);
  +        fSAXParser = new SAXParser(config);
  +        return fSAXParser;
       }
   
       /**
  
  
  
  1.28      +67 -2     
xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.java
  
  Index: XSDAbstractTraverser.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- XSDAbstractTraverser.java 23 Jun 2003 16:35:22 -0000      1.27
  +++ XSDAbstractTraverser.java 3 Jul 2003 15:19:31 -0000       1.28
  @@ -80,6 +80,8 @@
   import org.apache.xerces.util.SymbolTable;
   import org.apache.xerces.xni.QName;
   import org.w3c.dom.Element;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.Text;
   
   /**
    * Class <code>XSDAbstractTraverser</code> serves as the base class for all
  @@ -141,6 +143,7 @@
           Object[] attrValues = fAttrChecker.checkAttributes(annotationDecl, 
isGlobal, schemaDoc);
           fAttrChecker.returnAttrArray(attrValues, schemaDoc);
   
  +        String contents = null;
           for (Element child = DOMUtil.getFirstChildElement(annotationDecl);
               child != null;
               child = DOMUtil.getNextSiblingElement(child)) {
  @@ -151,6 +154,11 @@
               if (!((name.equals(SchemaSymbols.ELT_APPINFO)) ||
                     (name.equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
                   reportSchemaError("src-annotation", new Object[]{name}, child);
  +            } else { // the annotation, as we currently know it, is a Text child
  +                Node textContent = child.getFirstChild();
  +                if(textContent != null && textContent.getNodeType() == 
Node.TEXT_NODE) {
  +                    contents = ((Text)textContent).getData();
  +                }
               }
   
               // General Attribute Checking
  @@ -159,8 +167,46 @@
               attrValues = fAttrChecker.checkAttributes(child, true, schemaDoc);
               fAttrChecker.returnAttrArray(attrValues, schemaDoc);
           }
  +        // if contents was null, must have been some kind of error;
  +        // nothing to contribute to PSVI
  +        if (contents == null) return null;
  +
  +        // find the grammar; fSchemaHandler must be known!
  +        SchemaGrammar grammar = 
fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
  +        // fish out local attributes passed from parent
  +        Vector annotationLocalAttrs = 
(Vector)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
  +        // optimize for case where there are no local attributes
  +        if(annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
  +            StringBuffer localStrBuffer = new StringBuffer(64);
  +            localStrBuffer.append(" ");
  +            // Vector should contain rawname value pairs
  +            int i=0;
  +            while(i<annotationLocalAttrs.size()) {
  +                localStrBuffer.append((String)annotationLocalAttrs.elementAt(i++))
  +                    .append("=\"");
  +                String value = (String)annotationLocalAttrs.elementAt(i++);
  +                // search for pesky "s and >s within attr value:
  +                value = processAttValue(value);
  +                localStrBuffer.append(value)
  +                    .append("\"");
  +            }
  +            localStrBuffer.append(" ");
  +            // and now splice it into place; immediately after the annotation 
token, for simplicity's sake
  +            StringBuffer contentBuffer = new StringBuffer(contents.length() + 
localStrBuffer.length());
  +            int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
  +            // annotation must occur somewhere or we're in big trouble...
  +            if(annotationTokenEnd == -1) return null;
  +            annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
  +            contentBuffer.append(contents.substring(0,annotationTokenEnd));
  +            contentBuffer.append(localStrBuffer.toString());
  +            contentBuffer.append(contents.substring(annotationTokenEnd, 
contents.length()));
  +            System.err.println("annotation is\n"+contentBuffer);
  +            return new XSAnnotationImpl(contentBuffer.toString(), grammar);
  +        } else {
  +            System.err.println("annotation is\n"+contents);
  +            return new XSAnnotationImpl(contents, grammar);
  +        } 
   
  -        return null;
       }
   
       // the QName simple type used to resolve qnames
  @@ -586,5 +632,24 @@
           particle.fMaxOccurs = max;
   
           return particle;
  +    }
  +
  +    // this is not terribly performant!
  +    private static String processAttValue(String original) {
  +        // normally, nothing will happen
  +        StringBuffer newVal = new StringBuffer(original.length());
  +        for(int i=0; i<original.length(); i++) {
  +            char currChar = original.charAt(i);
  +            if(currChar == '"') {
  +                newVal.append("&quot;");
  +            } else if (currChar == '>') {
  +                newVal.append("&gt;");
  +            } else if (currChar == '&') {
  +                newVal.append("&amp;");
  +            } else {
  +                newVal.append(currChar);
  +            }
  +        }
  +        return newVal.toString();
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to