jaxp/src/com/sun/org/apache/xml/internal/serializer/dom3/NamespaceSupport.java
changeset 25834 aba3efbf4ec5
equal deleted inserted replaced
25833:054a597b18f8 25834:aba3efbf4ec5
       
     1 /*
       
     2  * Licensed to the Apache Software Foundation (ASF) under one
       
     3  * or more contributor license agreements. See the NOTICE file
       
     4  * distributed with this work for additional information
       
     5  * regarding copyright ownership. The ASF licenses this file
       
     6  * to you under the Apache License, Version 2.0 (the  "License");
       
     7  * you may not use this file except in compliance with the License.
       
     8  * You may obtain a copy of the License at
       
     9  *
       
    10  *     http://www.apache.org/licenses/LICENSE-2.0
       
    11  *
       
    12  * Unless required by applicable law or agreed to in writing, software
       
    13  * distributed under the License is distributed on an "AS IS" BASIS,
       
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    15  * See the License for the specific language governing permissions and
       
    16  * limitations under the License.
       
    17  */
       
    18 /*
       
    19  * $Id:  $
       
    20  */
       
    21 
       
    22 package com.sun.org.apache.xml.internal.serializer.dom3;
       
    23 
       
    24 import java.util.Enumeration;
       
    25 import java.util.NoSuchElementException;
       
    26 
       
    27 /**
       
    28  * Namespace support for XML document handlers. This class doesn't
       
    29  * perform any error checking and assumes that all strings passed
       
    30  * as arguments to methods are unique symbols. The SymbolTable class
       
    31  * can be used for this purpose.
       
    32  *
       
    33  * Derived from org.apache.xerces.util.NamespaceSupport
       
    34  *
       
    35  * @author Andy Clark, IBM
       
    36  *
       
    37  * @version $Id: Exp $
       
    38  */
       
    39 public class NamespaceSupport {
       
    40 
       
    41         static final String PREFIX_XML = "xml".intern();
       
    42 
       
    43         static final String PREFIX_XMLNS = "xmlns".intern();
       
    44 
       
    45     /**
       
    46      * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is
       
    47      * the Namespace URI that is automatically mapped to the "xml" prefix.
       
    48      */
       
    49     public final static String XML_URI = "http://www.w3.org/XML/1998/namespace".intern();
       
    50 
       
    51     /**
       
    52      * XML Information Set REC
       
    53      * all namespace attributes (including those named xmlns,
       
    54      * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/
       
    55      */
       
    56     public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern();
       
    57 
       
    58         //
       
    59     // Data
       
    60     //
       
    61 
       
    62     /**
       
    63      * Namespace binding information. This array is composed of a
       
    64      * series of tuples containing the namespace binding information:
       
    65      * <prefix, uri>. The default size can be set to anything
       
    66      * as long as it is a power of 2 greater than 1.
       
    67      *
       
    68      * @see #fNamespaceSize
       
    69      * @see #fContext
       
    70      */
       
    71     protected String[] fNamespace = new String[16 * 2];
       
    72 
       
    73     /** The top of the namespace information array. */
       
    74     protected int fNamespaceSize;
       
    75 
       
    76     // NOTE: The constructor depends on the initial context size
       
    77     //       being at least 1. -Ac
       
    78 
       
    79     /**
       
    80      * Context indexes. This array contains indexes into the namespace
       
    81      * information array. The index at the current context is the start
       
    82      * index of declared namespace bindings and runs to the size of the
       
    83      * namespace information array.
       
    84      *
       
    85      * @see #fNamespaceSize
       
    86      */
       
    87     protected int[] fContext = new int[8];
       
    88 
       
    89     /** The current context. */
       
    90     protected int fCurrentContext;
       
    91 
       
    92     protected String[] fPrefixes = new String[16];
       
    93 
       
    94     //
       
    95     // Constructors
       
    96     //
       
    97 
       
    98     /** Default constructor. */
       
    99     public NamespaceSupport() {
       
   100     } // <init>()
       
   101 
       
   102     //
       
   103     // Public methods
       
   104     //
       
   105 
       
   106         /**
       
   107          * @see org.apache.xerces.xni.NamespaceContext#reset()
       
   108          */
       
   109     public void reset() {
       
   110 
       
   111         // reset namespace and context info
       
   112         fNamespaceSize = 0;
       
   113         fCurrentContext = 0;
       
   114         fContext[fCurrentContext] = fNamespaceSize;
       
   115 
       
   116         // bind "xml" prefix to the XML uri
       
   117         fNamespace[fNamespaceSize++] = PREFIX_XML;
       
   118         fNamespace[fNamespaceSize++] = XML_URI;
       
   119         // bind "xmlns" prefix to the XMLNS uri
       
   120         fNamespace[fNamespaceSize++] = PREFIX_XMLNS;
       
   121         fNamespace[fNamespaceSize++] = XMLNS_URI;
       
   122         ++fCurrentContext;
       
   123 
       
   124     } // reset(SymbolTable)
       
   125 
       
   126 
       
   127         /**
       
   128          * @see org.apache.xerces.xni.NamespaceContext#pushContext()
       
   129          */
       
   130     public void pushContext() {
       
   131 
       
   132         // extend the array, if necessary
       
   133         if (fCurrentContext + 1 == fContext.length) {
       
   134             int[] contextarray = new int[fContext.length * 2];
       
   135             System.arraycopy(fContext, 0, contextarray, 0, fContext.length);
       
   136             fContext = contextarray;
       
   137         }
       
   138 
       
   139         // push context
       
   140         fContext[++fCurrentContext] = fNamespaceSize;
       
   141 
       
   142     } // pushContext()
       
   143 
       
   144 
       
   145         /**
       
   146          * @see org.apache.xerces.xni.NamespaceContext#popContext()
       
   147          */
       
   148     public void popContext() {
       
   149         fNamespaceSize = fContext[fCurrentContext--];
       
   150     } // popContext()
       
   151 
       
   152         /**
       
   153          * @see org.apache.xerces.xni.NamespaceContext#declarePrefix(String, String)
       
   154          */
       
   155     public boolean declarePrefix(String prefix, String uri) {
       
   156         // ignore "xml" and "xmlns" prefixes
       
   157         if (prefix == PREFIX_XML || prefix == PREFIX_XMLNS) {
       
   158             return false;
       
   159         }
       
   160 
       
   161         // see if prefix already exists in current context
       
   162         for (int i = fNamespaceSize; i > fContext[fCurrentContext]; i -= 2) {
       
   163             //if (fNamespace[i - 2] == prefix) {
       
   164                 if (fNamespace[i - 2].equals(prefix) )  {
       
   165                 // REVISIT: [Q] Should the new binding override the
       
   166                 //          previously declared binding or should it
       
   167                 //          it be ignored? -Ac
       
   168                 // NOTE:    The SAX2 "NamespaceSupport" helper allows
       
   169                 //          re-bindings with the new binding overwriting
       
   170                 //          the previous binding. -Ac
       
   171                 fNamespace[i - 1] = uri;
       
   172                 return true;
       
   173             }
       
   174         }
       
   175 
       
   176         // resize array, if needed
       
   177         if (fNamespaceSize == fNamespace.length) {
       
   178             String[] namespacearray = new String[fNamespaceSize * 2];
       
   179             System.arraycopy(fNamespace, 0, namespacearray, 0, fNamespaceSize);
       
   180             fNamespace = namespacearray;
       
   181         }
       
   182 
       
   183         // bind prefix to uri in current context
       
   184         fNamespace[fNamespaceSize++] = prefix;
       
   185         fNamespace[fNamespaceSize++] = uri;
       
   186 
       
   187         return true;
       
   188 
       
   189     } // declarePrefix(String,String):boolean
       
   190 
       
   191         /**
       
   192          * @see org.apache.xerces.xni.NamespaceContext#getURI(String)
       
   193          */
       
   194     public String getURI(String prefix) {
       
   195 
       
   196         // find prefix in current context
       
   197         for (int i = fNamespaceSize; i > 0; i -= 2) {
       
   198             //if (fNamespace[i - 2] == prefix) {
       
   199                 if (fNamespace[i - 2].equals(prefix) ) {
       
   200                 return fNamespace[i - 1];
       
   201             }
       
   202         }
       
   203 
       
   204         // prefix not found
       
   205         return null;
       
   206 
       
   207     } // getURI(String):String
       
   208 
       
   209 
       
   210         /**
       
   211          * @see org.apache.xerces.xni.NamespaceContext#getPrefix(String)
       
   212          */
       
   213     public String getPrefix(String uri) {
       
   214 
       
   215         // find uri in current context
       
   216         for (int i = fNamespaceSize; i > 0; i -= 2) {
       
   217             //if (fNamespace[i - 1] == uri) {
       
   218                 if (fNamespace[i - 1].equals(uri) ) {
       
   219                 //if (getURI(fNamespace[i - 2]) == uri)
       
   220                         if (getURI(fNamespace[i - 2]).equals(uri) )
       
   221                     return fNamespace[i - 2];
       
   222             }
       
   223         }
       
   224 
       
   225         // uri not found
       
   226         return null;
       
   227 
       
   228     } // getPrefix(String):String
       
   229 
       
   230 
       
   231         /**
       
   232          * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixCount()
       
   233          */
       
   234     public int getDeclaredPrefixCount() {
       
   235         return (fNamespaceSize - fContext[fCurrentContext]) / 2;
       
   236     } // getDeclaredPrefixCount():int
       
   237 
       
   238         /**
       
   239          * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixAt(int)
       
   240          */
       
   241     public String getDeclaredPrefixAt(int index) {
       
   242         return fNamespace[fContext[fCurrentContext] + index * 2];
       
   243     } // getDeclaredPrefixAt(int):String
       
   244 
       
   245         /**
       
   246          * @see org.apache.xerces.xni.NamespaceContext#getAllPrefixes()
       
   247          */
       
   248         public Enumeration getAllPrefixes() {
       
   249         int count = 0;
       
   250         if (fPrefixes.length < (fNamespace.length/2)) {
       
   251             // resize prefix array
       
   252             String[] prefixes = new String[fNamespaceSize];
       
   253             fPrefixes = prefixes;
       
   254         }
       
   255         String prefix = null;
       
   256         boolean unique = true;
       
   257         for (int i = 2; i < (fNamespaceSize-2); i += 2) {
       
   258             prefix = fNamespace[i + 2];
       
   259             for (int k=0;k<count;k++){
       
   260                 if (fPrefixes[k]==prefix){
       
   261                     unique = false;
       
   262                     break;
       
   263                 }
       
   264             }
       
   265             if (unique){
       
   266                 fPrefixes[count++] = prefix;
       
   267             }
       
   268             unique = true;
       
   269         }
       
   270                 return new Prefixes(fPrefixes, count);
       
   271         }
       
   272 
       
   273     protected final class Prefixes implements Enumeration {
       
   274         private String[] prefixes;
       
   275         private int counter = 0;
       
   276         private int size = 0;
       
   277 
       
   278                 /**
       
   279                  * Constructor for Prefixes.
       
   280                  */
       
   281                 public Prefixes(String [] prefixes, int size) {
       
   282                         this.prefixes = prefixes;
       
   283             this.size = size;
       
   284                 }
       
   285 
       
   286        /**
       
   287                  * @see java.util.Enumeration#hasMoreElements()
       
   288                  */
       
   289                 public boolean hasMoreElements() {
       
   290                         return (counter< size);
       
   291                 }
       
   292 
       
   293                 /**
       
   294                  * @see java.util.Enumeration#nextElement()
       
   295                  */
       
   296                 public Object nextElement() {
       
   297             if (counter< size){
       
   298                 return fPrefixes[counter++];
       
   299             }
       
   300                         throw new NoSuchElementException("Illegal access to Namespace prefixes enumeration.");
       
   301                 }
       
   302 
       
   303         public String toString(){
       
   304             StringBuffer buf = new StringBuffer();
       
   305             for (int i=0;i<size;i++){
       
   306                 buf.append(prefixes[i]);
       
   307                 buf.append(" ");
       
   308             }
       
   309 
       
   310             return buf.toString();
       
   311         }
       
   312 
       
   313 }
       
   314 
       
   315 } // class NamespaceSupport