jaxp/src/com/sun/org/apache/xml/internal/serializer/ElemContext.java
author lana
Tue, 18 Mar 2014 17:49:48 -0700
changeset 23377 2af1ddf102a4
parent 12457 c348e06f0e82
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
 * Copyright 2003-2004 The Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * Licensed under the Apache License, Version 2.0 (the "License");
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 * you may not use this file except in compliance with the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * You may obtain a copy of the License at
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *     http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 * $Id: ElemContext.java,v 1.2.4.1 2005/09/15 08:15:15 suresh_emailid Exp $
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
package com.sun.org.apache.xml.internal.serializer;
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
 * This class is a stack frame that consists of
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
 * information about the element currently being processed
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
 * by a serializer. Consider this example:
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
 * <pre>
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 *   <A>
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 *     <B1>
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 *     </B1>
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 *     <B2>
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 *     </B2>
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 *   <A>
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 * </pre>
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 * A stack frame will be pushed for "A" at depth 1,
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 * then another one for "B1" at depth 2.
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 * Then "B1" stackframe is popped.  When the stack frame for "B2" is
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * pushed, this implementation re-uses the old stack fram object used
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * by "B1" to be efficient at not creating too many of these object.
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * This is by no means a public class, and neither are its fields or methods,
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * they are all helper fields for a serializer.
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * The purpose of this class is to be more consistent with pushing information
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 * when a new element is being serialized and more quickly restoring the old
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
 * information about the parent element with a simple pop() when the
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
 * child element is done.  Previously there was some redundant and error-prone
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
 * calculations going on to retore information.
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
 * @xsl.usage internal
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
final class ElemContext
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
{
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
    // Fields that form the context of the element
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
     * The nesting depth of the element inside other elements.
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
    final int m_currentElemDepth;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    /** HTML field, the element description of the HTML element */
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
    ElemDesc m_elementDesc = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
     * The local name of the element.
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    String m_elementLocalName = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
     * The fully qualified name of the element (with prefix, if any).
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
    String m_elementName = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
     * The URI of the element.
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
    String m_elementURI = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
    /** If the element is in the cdata-section-names list
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
     * then the value is true. If it is true the text children of the element
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
     * should be output in CDATA section blocks.
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
    boolean m_isCdataSection;
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
    /** True if the current element has output escaping disabled.
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
     * This is true for SCRIPT and STYLE elements.
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
    boolean m_isRaw = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
    /** The next element "stack frame". This value will only be
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
     * set once as deeper stack frames are not deleted when popped off,
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
     * but are rather re-used when a push is required.
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
     * This makes for very fast pushing and popping of stack frames
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
     * because very few stack frame objects are ever created, they are
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
     * mostly re-used.  This re-use saves object creation but it also means
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
     * that connections between the frames via m_next and m_prev
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
     * never changes either. Just the contents of the frames change
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
     * as they are re-used. Only the reference to the current stack frame, which
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
     * is held by the serializer is changed via a quick pop() or push().
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
    private ElemContext m_next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
    /** The previous element "stack frame". */
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
    final ElemContext m_prev;
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
     * Set to true when a start tag is started, or open, but not all the
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
     * attributes or namespace information is yet collected.
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
    boolean m_startTagOpen = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
     * Constructor to create the root of the element contexts.
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
    ElemContext()
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
        // this assignment means can never pop this context off
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
        m_prev = this;
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
        // depth 0 because it doesn't correspond to any element
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
        m_currentElemDepth = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
     * Constructor to create the "stack frame" for a given element depth.
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
     * This implementation will re-use the context at each depth. If
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
     * a documents deepest element depth is N then there will be (N+1)
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
     * such objects created, no more than that.
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
     * @param previous The "stack frame" corresponding to the new
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
     * elements parent element.
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
    private ElemContext(final ElemContext previous)
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        m_prev = previous;
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
        m_currentElemDepth = previous.m_currentElemDepth + 1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
     * Pop the current "stack frame".
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
     * @return Returns the parent "stack frame" of the one popped.
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
    final ElemContext pop()
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
        /* a very simple pop.  No clean up is done of the deeper
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
         * stack frame.  All deeper stack frames are still attached
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
         * but dormant, just waiting to be re-used.
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
         */
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
        return this.m_prev;
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
     * This method pushes an element "stack frame"
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
     * but with no initialization of values in that frame.
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
     * This method is used for optimization purposes, like when pushing
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
     * a stack frame for an HTML "IMG" tag which has no children and
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
     * the stack frame will almost immediately be popped.
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
    final ElemContext push()
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
        ElemContext frame = this.m_next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
        if (frame == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
            /* We have never been at this depth yet, and there is no
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
             * stack frame to re-use, so we now make a new one.
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
             */
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
            frame = new ElemContext(this);
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
            this.m_next = frame;
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
        /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
         * We shouldn't need to set this true because we should just
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
         * be pushing a dummy stack frame that will be instantly popped.
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
         * Yet we need to be ready in case this element does have
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
         * unexpected children.
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
         */
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
        frame.m_startTagOpen = true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
        return frame;
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
     * Push an element context on the stack. This context keeps track of
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
     * information gathered about the element.
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
     * @param uri The URI for the namespace for the element name,
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
     * can be null if it is not yet known.
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
     * @param localName The local name of the element (no prefix),
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
     * can be null.
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
     * @param qName The qualified name (with prefix, if any)
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
     * of the element, this parameter is required.
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
    final ElemContext push(
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
        final String uri,
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
        final String localName,
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
        final String qName)
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
        ElemContext frame = this.m_next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
        if (frame == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
            /* We have never been at this depth yet, and there is no
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
             * stack frame to re-use, so we now make a new one.
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
             */
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
            frame = new ElemContext(this);
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
            this.m_next = frame;
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
        // Initialize, or reset values in the new or re-used stack frame.
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
        frame.m_elementName = qName;
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
        frame.m_elementLocalName = localName;
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
        frame.m_elementURI = uri;
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
        frame.m_isCdataSection = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
        frame.m_startTagOpen = true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
        // is_Raw is already set in the HTML startElement() method
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
        // frame.m_isRaw = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
        return frame;
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
}