You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2004/08/13 03:59:59 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/xinclude XIncludeHandler.java

mrglavas    2004/08/12 18:59:59

  Modified:    java/src/org/apache/xerces/xinclude XIncludeHandler.java
  Log:
  Adding an implementation for language fixup as specified in
  the XInclude 1.0 CR (April, 2004). Also, renaming some
  fields to conform to the project's naming conventions.
  
  [1] http://www.w3.org/TR/2004/CR-xinclude-20040413/#language
  
  Revision  Changes    Path
  1.30      +171 -39   xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java
  
  Index: XIncludeHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- XIncludeHandler.java	20 Jul 2004 04:07:17 -0000	1.29
  +++ XIncludeHandler.java	13 Aug 2004 01:59:59 -0000	1.30
  @@ -99,6 +99,7 @@
    * </p>
    *
    * @author Peter McCracken, IBM
  + * @author Michael Glavassevich, IBM
    *
    * @version $Id$
    *
  @@ -141,6 +142,15 @@
               XINCLUDE_BASE,
               XMLSymbols.PREFIX_XML + ":" + XINCLUDE_BASE,
               NamespaceContext.XML_URI);
  +    
  +    // used for adding [language] attributes
  +    public final static String XINCLUDE_LANG = "lang";
  +    public final static QName XML_LANG_QNAME = 
  +        new QName(
  +                XMLSymbols.PREFIX_XML,
  +                XINCLUDE_LANG,
  +                XMLSymbols.PREFIX_XML + ":" + XINCLUDE_LANG,
  +                NamespaceContext.XML_URI);
   
       public final static QName NEW_NS_ATTR_QNAME =
           new QName(
  @@ -244,10 +254,15 @@
   
       // these are needed for XML Base processing
       protected XMLResourceIdentifier fCurrentBaseURI;
  -    protected IntStack baseURIScope;
  -    protected Stack baseURI;
  -    protected Stack literalSystemID;
  -    protected Stack expandedSystemID;
  +    protected IntStack fBaseURIScope;
  +    protected Stack fBaseURI;
  +    protected Stack fLiteralSystemID;
  +    protected Stack fExpandedSystemID;
  +    
  +    // these are needed for Language Fixup
  +    protected IntStack fLanguageScope;
  +    protected Stack fLanguageStack;
  +    protected String fCurrentLanguage;
   
       // used for passing features on to child XIncludeHandler objects
       protected ParserConfigurationSettings fSettings;
  @@ -298,11 +313,15 @@
           fNotations = new Vector();
           fUnparsedEntities = new Vector();
   
  -        baseURIScope = new IntStack();
  -        baseURI = new Stack();
  -        literalSystemID = new Stack();
  -        expandedSystemID = new Stack();
  +        fBaseURIScope = new IntStack();
  +        fBaseURI = new Stack();
  +        fLiteralSystemID = new Stack();
  +        fExpandedSystemID = new Stack();
           fCurrentBaseURI = new XMLResourceIdentifierImpl();
  +        
  +        fLanguageScope = new IntStack();
  +        fLanguageStack = new Stack();
  +        fCurrentLanguage = null;
       }
   
       // XMLComponent methods
  @@ -317,10 +336,10 @@
           fIsXML11 = false;
           fInDTD = false;
   
  -        baseURIScope.clear();
  -        baseURI.clear();
  -        literalSystemID.clear();
  -        expandedSystemID.clear();
  +        fBaseURIScope.clear();
  +        fBaseURI.clear();
  +        fLiteralSystemID.clear();
  +        fExpandedSystemID.clear();
   
           // REVISIT: Find a better method for maintaining
           // the state of the XInclude processor. These arrays
  @@ -630,6 +649,10 @@
               augs = new AugmentationsImpl();
           }
           augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
  +        
  +        // initialize the current language
  +        fCurrentLanguage = XMLSymbols.EMPTY_STRING;
  +        saveLanguage(fCurrentLanguage);
   
           if (isRootDocument() && fDocumentHandler != null) {
               fDocumentHandler.startDocument(
  @@ -707,8 +730,10 @@
           fDepth++;
           setState(getState(fDepth - 1));
   
  -        // we process the xml:base attributes regardless of what type of element it is
  +        // we process the xml:base and xml:lang attributes regardless
  +        // of what type of element it is.
           processXMLBaseAttributes(attributes);
  +        processXMLLangAttributes(attributes);
   
           if (isIncludeElement(element)) {
               boolean success = this.handleIncludeElement(attributes);
  @@ -757,8 +782,10 @@
           fDepth++;
           setState(getState(fDepth - 1));
   
  -        // we process the xml:base attributes regardless of what type of element it is
  +        // we process the xml:base and xml:lang attributes regardless
  +        // of what type of element it is.
           processXMLBaseAttributes(attributes);
  +        processXMLLangAttributes(attributes);
   
           if (isIncludeElement(element)) {
               boolean success = this.handleIncludeElement(attributes);
  @@ -802,7 +829,7 @@
           setSawInclude(fDepth + 1, false);
   
           // check if an xml:base has gone out of scope
  -        if (baseURIScope.size() > 0 && fDepth == baseURIScope.peek()) {
  +        if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
               // pop the values from the stack
               restoreBaseURI();
           }
  @@ -838,10 +865,17 @@
           setSawInclude(fDepth + 1, false);
   
           // check if an xml:base has gone out of scope
  -        if (baseURIScope.size() > 0 && fDepth == baseURIScope.peek()) {
  +        if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
               // pop the values from the stack
               restoreBaseURI();
           }
  +        
  +        // check if an xml:lang has gone out of scope
  +        if (fLanguageScope.size() > 0 && fDepth == fLanguageScope.peek()) {
  +            // pop the language from the stack
  +            fCurrentLanguage = restoreLanguage();
  +        }
  +        
           fDepth--;
       }
   
  @@ -1485,6 +1519,23 @@
           //       The decision also affects whether we output the file name of the URI, or just the path.
           return parentBaseURI != null && parentBaseURI.equals(baseURI);
       }
  +    
  +    /**
  +     * Returns true if the current [language] is equivalent to the [language] that
  +     * was in effect on the include parent, taking case-insensitivity into account
  +     * as per [RFC 3066].  This method should <em>only</em> be called when the
  +     * current element is a top level included element, i.e. the direct child
  +     * of a fallback element, or the root elements in an included document.
  +     * The "include parent" is the element which, in the result infoset, will be the
  +     * direct parent of the current element.
  +     * 
  +     * @return true if the [language] properties have the same value
  +     * taking case-insensitivity into account as per [RFC 3066].
  +     */
  +    protected boolean sameLanguageAsIncludeParent() {
  +        String parentLanguage = getIncludeParentLanguage();
  +        return parentLanguage != null && parentLanguage.equalsIgnoreCase(fCurrentLanguage);
  +    }
   
       /**
        * Checks if the file indicated by the given XMLLocator has already been included
  @@ -1585,6 +1636,21 @@
                           uri);
                   attributes.setSpecified(index, true);
               }
  +            
  +            // Modify attributes to perform language-fixup (spec 4.5.6).
  +            // We only do it to top level included elements, which have a different
  +            // [language] than their include parent.
  +            if (!sameLanguageAsIncludeParent()) {
  +                if (attributes == null) {
  +                    attributes = new XMLAttributesImpl();
  +                }
  +                int index =
  +                    attributes.addAttribute(
  +                        XML_LANG_QNAME,
  +                        XMLSymbols.fCDATASymbol,
  +                        fCurrentLanguage);
  +                attributes.setSpecified(index, true);
  +            }
   
               // Modify attributes of included items to do namespace-fixup. (spec 4.5.4)
               Enumeration inscopeNS = fNamespaceContext.getAllPrefixes();
  @@ -1712,6 +1778,21 @@
               return this.getBaseURI(depth);
           }
       }
  +    
  +    /**
  +     * Returns the [language] of the include parent.
  +     * 
  +     * @return the language property of the include parent.
  +     */
  +    private String getIncludeParentLanguage() {
  +        int depth = getIncludeParentDepth();
  +        if (!isRootDocument() && depth == 0) {
  +            return fParentXIncludeHandler.getIncludeParentLanguage();
  +        }
  +        else {
  +            return getLanguage(depth);
  +        }
  +    }
   
       /**
        * Returns the depth of the include parent.  Here, the include parent is
  @@ -2200,23 +2281,44 @@
        * Saves the current base URI to the top of the stack.
        */
       protected void saveBaseURI() {
  -        baseURIScope.push(fDepth);
  -        baseURI.push(fCurrentBaseURI.getBaseSystemId());
  -        literalSystemID.push(fCurrentBaseURI.getLiteralSystemId());
  -        expandedSystemID.push(fCurrentBaseURI.getExpandedSystemId());
  +        fBaseURIScope.push(fDepth);
  +        fBaseURI.push(fCurrentBaseURI.getBaseSystemId());
  +        fLiteralSystemID.push(fCurrentBaseURI.getLiteralSystemId());
  +        fExpandedSystemID.push(fCurrentBaseURI.getExpandedSystemId());
       }
   
       /**
        * Discards the URIs at the top of the stack, and restores the ones beneath it.
        */
       protected void restoreBaseURI() {
  -        baseURI.pop();
  -        literalSystemID.pop();
  -        expandedSystemID.pop();
  -        baseURIScope.pop();
  -        fCurrentBaseURI.setBaseSystemId((String)baseURI.peek());
  -        fCurrentBaseURI.setLiteralSystemId((String)literalSystemID.peek());
  -        fCurrentBaseURI.setExpandedSystemId((String)expandedSystemID.peek());
  +        fBaseURI.pop();
  +        fLiteralSystemID.pop();
  +        fExpandedSystemID.pop();
  +        fBaseURIScope.pop();
  +        fCurrentBaseURI.setBaseSystemId((String)fBaseURI.peek());
  +        fCurrentBaseURI.setLiteralSystemId((String)fLiteralSystemID.peek());
  +        fCurrentBaseURI.setExpandedSystemId((String)fExpandedSystemID.peek());
  +    }
  +    
  +    // The following methods are used for language processing
  +    
  +    /**
  +     * Saves the given language on the top of the stack.
  +     * 
  +     * @param lanaguage the language to push onto the stack.
  +     */
  +    protected void saveLanguage(String language) {
  +        fLanguageScope.push(fDepth);
  +        fLanguageStack.push(language);
  +    }
  +    
  +    /**
  +     * Discards the language at the top of the stack, and returns the one beneath it.
  +     */
  +    public String restoreLanguage() {
  +        fLanguageStack.pop();
  +        fLanguageScope.pop();
  +        return (String) fLanguageStack.peek();
       }
   
       /**
  @@ -2225,8 +2327,18 @@
        * @return the base URI
        */
       public String getBaseURI(int depth) {
  -        int scope = scopeOf(depth);
  -        return (String)expandedSystemID.elementAt(scope);
  +        int scope = scopeOfBaseURI(depth);
  +        return (String)fExpandedSystemID.elementAt(scope);
  +    }
  +    
  +    /**
  +     * Gets the language that was in use at that depth.
  +     * @param depth
  +     * @return the language
  +     */
  +    public String getLanguage(int depth) {
  +        int scope = scopeOfLanguage(depth);
  +        return (String)fLanguageStack.elementAt(scope);
       }
   
       /**
  @@ -2241,14 +2353,14 @@
           // The literal system id at the location given by "start" is *in focus* at
           // the given depth. So we need to adjust it to the next scope, so that we
           // only process out of focus literal system ids
  -        int start = scopeOf(depth) + 1;
  -        if (start == baseURIScope.size()) {
  +        int start = scopeOfBaseURI(depth) + 1;
  +        if (start == fBaseURIScope.size()) {
               // If that is the last system id, then we don't need a relative URI
               return "";
           }
  -        URI uri = new URI("file", (String)literalSystemID.elementAt(start));
  -        for (int i = start + 1; i < baseURIScope.size(); i++) {
  -            uri = new URI(uri, (String)literalSystemID.elementAt(i));
  +        URI uri = new URI("file", (String)fLiteralSystemID.elementAt(start));
  +        for (int i = start + 1; i < fBaseURIScope.size(); i++) {
  +            uri = new URI(uri, (String)fLiteralSystemID.elementAt(i));
           }
           return uri.getPath();
       }
  @@ -2256,12 +2368,20 @@
       // We need to find two consecutive elements in the scope stack,
       // such that the first is lower than 'depth' (or equal), and the
       // second is higher.
  -    private int scopeOf(int depth) {
  -        for (int i = baseURIScope.size() - 1; i >= 0; i--) {
  -            if (baseURIScope.elementAt(i) <= depth)
  +    private int scopeOfBaseURI(int depth) {
  +        for (int i = fBaseURIScope.size() - 1; i >= 0; i--) {
  +            if (fBaseURIScope.elementAt(i) <= depth)
  +                return i;
  +        }
  +        // we should never get here, because 0 was put on the stack in startDocument()
  +        return -1;
  +    }
  +    
  +    private int scopeOfLanguage(int depth) {
  +        for (int i = fLanguageScope.size() - 1; i >= 0; i--) {
  +            if (fLanguageScope.elementAt(i) <= depth)
                   return i;
           }
  -
           // we should never get here, because 0 was put on the stack in startDocument()
           return -1;
       }
  @@ -2291,6 +2411,18 @@
               catch (MalformedURIException e) {
                   // REVISIT: throw error here
               }
  +        }
  +    }
  +    
  +    /**
  +     * Search for a xml:lang attribute, and if one is found, put the new 
  +     * [language] into effect.
  +     */
  +    protected void processXMLLangAttributes(XMLAttributes attributes) {
  +        String language = attributes.getValue(NamespaceContext.XML_URI, "lang");
  +        if (language != null) {
  +            fCurrentLanguage = language;
  +            saveLanguage(fCurrentLanguage);
           }
       }
       
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org