jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/EntityReferenceImpl.java
author joehw
Thu, 28 Jul 2016 22:58:41 -0700
changeset 39907 db51759e3695
parent 25868 686eef1e7a79
child 44797 8b3b3b911b8a
permissions -rw-r--r--
8158084: Catalog API: JAXP XML Processor Support Reviewed-by: lancea, clanger
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 1999-2002,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
package com.sun.org.apache.xerces.internal.dom;
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
import com.sun.org.apache.xerces.internal.util.URI;
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
import org.w3c.dom.DocumentType;
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
import org.w3c.dom.EntityReference;
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
import org.w3c.dom.NamedNodeMap;
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
import org.w3c.dom.Node;
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 * EntityReference models the XML &entityname; syntax, when used for
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 * entities defined by the DOM. Entities hardcoded into XML, such as
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 * character entities, should instead have been translated into text
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 * by the code which generated the DOM tree.
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 * An XML processor has the alternative of fully expanding Entities
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 * into the normal document tree. If it does so, no EntityReference nodes
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 * will appear.
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 * Similarly, non-validating XML processors are not required to read
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 * or process entity declarations made in the external subset or
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * declared in external parameter entities. Hence, some applications
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * may not make the replacement value available for Parsed Entities
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 * of these types.
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * EntityReference behaves as a read-only node, and the children of
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 * the EntityReference (which reflect those of the Entity, and should
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * also be read-only) give its replacement value, if any. They are
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 * supposed to automagically stay in synch if the DocumentType is
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
 * updated with new values for the Entity.
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
 * The defined behavior makes efficient storage difficult for the DOM
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
 * implementor. We can't just look aside to the Entity's definition
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
 * in the DocumentType since those nodes have the wrong parent (unless
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
 * we can come up with a clever "imaginary parent" mechanism). We
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
 * must at least appear to clone those children... which raises the
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
 * issue of keeping the reference synchronized with its parent.
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
 * This leads me back to the "cached image of centrally defined data"
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
 * solution, much as I dislike it.
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
 * For now I have decided, since REC-DOM-Level-1-19980818 doesn't
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
 * cover this in much detail, that synchronization doesn't have to be
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
 * considered while the user is deep in the tree. That is, if you're
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
 * looking within one of the EntityReferennce's children and the Entity
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
 * changes, you won't be informed; instead, you will continue to access
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
 * the same object -- which may or may not still be part of the tree.
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
 * This is the same behavior that obtains elsewhere in the DOM if the
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
 * subtree you're looking at is deleted from its parent, so it's
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
 * acceptable here. (If it really bothers folks, we could set things
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
 * up so deleted subtrees are walked and marked invalid, but that's
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
 * not part of the DOM's defined behavior.)
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
 * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
 * As a result, only the EntityReference itself has to be aware of
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
 * changes in the Entity. And it can take advantage of the same
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
 * structure-change-monitoring code I implemented to support
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
 * DeepNodeList.
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
 * @xerces.internal
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
 * @author Arnaud  Le Hors, IBM
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
 * @author Joe Kesselman, IBM
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
 * @author Andy Clark, IBM
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
 * @author Ralf Pfeiffer, IBM
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
 * @since  PR-DOM-Level-1-19980818.
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
public class EntityReferenceImpl
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
extends ParentNode
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
implements EntityReference {
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
    // Constants
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
    /** Serialization version. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
    static final long serialVersionUID = -7381452955687102062L;
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
    // Data
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
    /** Name of Entity referenced */
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
    protected String name;
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
    /** Base URI*/
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
    protected String baseURI;
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
    /** Entity changes. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
    //protected int entityChanges = -1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
    /** Enable synchronize. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
    //protected boolean fEnableSynchronize = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
    // Constructors
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
    /** Factory constructor. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
    public EntityReferenceImpl(CoreDocumentImpl ownerDoc, String name) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
        super(ownerDoc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
        this.name = name;
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
        isReadOnly(true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
        needsSyncChildren(true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
    // Node methods
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
     * A short integer indicating what type of node this is. The named
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
     * constants for this value are defined in the org.w3c.dom.Node interface.
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
    public short getNodeType() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
        return Node.ENTITY_REFERENCE_NODE;
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
     * Returns the name of the entity referenced
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
    public String getNodeName() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        if (needsSyncData()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
            synchronizeData();
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
        return name;
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
    /** Clone node. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
    public Node cloneNode(boolean deep) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
        EntityReferenceImpl er = (EntityReferenceImpl)super.cloneNode(deep);
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
        er.setReadOnly(true, deep);
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
        return er;
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
     * Returns the absolute base URI of this node or null if the implementation
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
     * wasn't able to obtain an absolute URI. Note: If the URI is malformed, a
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
     * null is returned.
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
     * @return The absolute base URI of this node or null.
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
     * @since DOM Level 3
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
    public String getBaseURI() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
        if (needsSyncData()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
            synchronizeData();
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
        if (baseURI == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
            DocumentType doctype;
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
            NamedNodeMap entities;
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
            EntityImpl entDef;
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
            if (null != (doctype = getOwnerDocument().getDoctype()) &&
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
                null != (entities = doctype.getEntities())) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
                entDef = (EntityImpl)entities.getNamedItem(getNodeName());
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
                if (entDef !=null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
                    return entDef.getBaseURI();
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
        } else if (baseURI != null && baseURI.length() != 0 ) {// attribute value is always empty string
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
            try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
                return new URI(baseURI).toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
                // REVISIT: what should happen in this case?
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
                return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
        return baseURI;
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
    /** NON-DOM: set base uri*/
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
    public void setBaseURI(String uri){
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
        if (needsSyncData()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
            synchronizeData();
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
        baseURI = uri;
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
        /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
         * NON-DOM: compute string representation of the entity reference.
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
     * This method is used to retrieve a string value for an attribute node that has child nodes.
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
         * @return String representing a value of this entity ref. or
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
     *          null if any node other than EntityReference, Text is encountered
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
     *          during computation
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
         */
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
    protected String getEntityRefValue (){
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
        if (needsSyncChildren()){
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
            synchronizeChildren();
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
        String value = "";
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
        if (firstChild != null){
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
          if (firstChild.getNodeType() == Node.ENTITY_REFERENCE_NODE){
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
              value = ((EntityReferenceImpl)firstChild).getEntityRefValue();
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
          else if (firstChild.getNodeType() == Node.TEXT_NODE){
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
            value = firstChild.getNodeValue();
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
          else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
             // invalid to have other types of nodes in attr value
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
            return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
          if (firstChild.nextSibling == null){
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
            return value;
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
          else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   227
            StringBuffer buff = new StringBuffer(value);
7f561c08de6b Initial load
duke
parents:
diff changeset
   228
            ChildNode next = firstChild.nextSibling;
7f561c08de6b Initial load
duke
parents:
diff changeset
   229
            while (next != null){
7f561c08de6b Initial load
duke
parents:
diff changeset
   230
7f561c08de6b Initial load
duke
parents:
diff changeset
   231
                if (next.getNodeType() == Node.ENTITY_REFERENCE_NODE){
7f561c08de6b Initial load
duke
parents:
diff changeset
   232
                   value = ((EntityReferenceImpl)next).getEntityRefValue();
7f561c08de6b Initial load
duke
parents:
diff changeset
   233
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   234
                else if (next.getNodeType() == Node.TEXT_NODE){
7f561c08de6b Initial load
duke
parents:
diff changeset
   235
                  value = next.getNodeValue();
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
                else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
                    // invalid to have other types of nodes in attr value
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
                    return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   241
                buff.append(value);
7f561c08de6b Initial load
duke
parents:
diff changeset
   242
                next = next.nextSibling;
7f561c08de6b Initial load
duke
parents:
diff changeset
   243
7f561c08de6b Initial load
duke
parents:
diff changeset
   244
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   245
            return buff.toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
   246
          }
7f561c08de6b Initial load
duke
parents:
diff changeset
   247
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   248
        return "";
7f561c08de6b Initial load
duke
parents:
diff changeset
   249
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   250
7f561c08de6b Initial load
duke
parents:
diff changeset
   251
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   252
     * EntityReference's children are a reflection of those defined in the
7f561c08de6b Initial load
duke
parents:
diff changeset
   253
     * named Entity. This method creates them if they haven't been created yet.
7f561c08de6b Initial load
duke
parents:
diff changeset
   254
     * This doesn't support editing the Entity though, since this only called
7f561c08de6b Initial load
duke
parents:
diff changeset
   255
     * once for all.
7f561c08de6b Initial load
duke
parents:
diff changeset
   256
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   257
    protected void synchronizeChildren() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   258
        // no need to synchronize again
7f561c08de6b Initial load
duke
parents:
diff changeset
   259
        needsSyncChildren(false);
7f561c08de6b Initial load
duke
parents:
diff changeset
   260
7f561c08de6b Initial load
duke
parents:
diff changeset
   261
        DocumentType doctype;
7f561c08de6b Initial load
duke
parents:
diff changeset
   262
        NamedNodeMap entities;
7f561c08de6b Initial load
duke
parents:
diff changeset
   263
        EntityImpl entDef;
7f561c08de6b Initial load
duke
parents:
diff changeset
   264
        if (null != (doctype = getOwnerDocument().getDoctype()) &&
7f561c08de6b Initial load
duke
parents:
diff changeset
   265
            null != (entities = doctype.getEntities())) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   266
7f561c08de6b Initial load
duke
parents:
diff changeset
   267
            entDef = (EntityImpl)entities.getNamedItem(getNodeName());
7f561c08de6b Initial load
duke
parents:
diff changeset
   268
7f561c08de6b Initial load
duke
parents:
diff changeset
   269
            // No Entity by this name, stop here.
7f561c08de6b Initial load
duke
parents:
diff changeset
   270
            if (entDef == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   271
                return;
7f561c08de6b Initial load
duke
parents:
diff changeset
   272
7f561c08de6b Initial load
duke
parents:
diff changeset
   273
            // If entity's definition exists, clone its kids
7f561c08de6b Initial load
duke
parents:
diff changeset
   274
            isReadOnly(false);
7f561c08de6b Initial load
duke
parents:
diff changeset
   275
            for (Node defkid = entDef.getFirstChild();
7f561c08de6b Initial load
duke
parents:
diff changeset
   276
                defkid != null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   277
                defkid = defkid.getNextSibling()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   278
                Node newkid = defkid.cloneNode(true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   279
                insertBefore(newkid, null);
7f561c08de6b Initial load
duke
parents:
diff changeset
   280
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   281
            setReadOnly(true, true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   282
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   283
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   284
7f561c08de6b Initial load
duke
parents:
diff changeset
   285
7f561c08de6b Initial load
duke
parents:
diff changeset
   286
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   287
     * NON-DOM: sets the node and its children value.
7f561c08de6b Initial load
duke
parents:
diff changeset
   288
     * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
   289
     * Note: make sure that entity reference and its kids could be set readonly.
7f561c08de6b Initial load
duke
parents:
diff changeset
   290
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   291
    public void setReadOnly(boolean readOnly, boolean deep) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   292
7f561c08de6b Initial load
duke
parents:
diff changeset
   293
        if (needsSyncData()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   294
            synchronizeData();
7f561c08de6b Initial load
duke
parents:
diff changeset
   295
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   296
        if (deep) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   297
7f561c08de6b Initial load
duke
parents:
diff changeset
   298
            if (needsSyncChildren()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   299
                synchronizeChildren();
7f561c08de6b Initial load
duke
parents:
diff changeset
   300
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   301
            // Recursively set kids
7f561c08de6b Initial load
duke
parents:
diff changeset
   302
            for (ChildNode mykid = firstChild;
7f561c08de6b Initial load
duke
parents:
diff changeset
   303
                 mykid != null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   304
                 mykid = mykid.nextSibling) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   305
7f561c08de6b Initial load
duke
parents:
diff changeset
   306
                mykid.setReadOnly(readOnly,true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   307
7f561c08de6b Initial load
duke
parents:
diff changeset
   308
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   309
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   310
        isReadOnly(readOnly);
7f561c08de6b Initial load
duke
parents:
diff changeset
   311
    } // setReadOnly(boolean,boolean)
7f561c08de6b Initial load
duke
parents:
diff changeset
   312
7f561c08de6b Initial load
duke
parents:
diff changeset
   313
7f561c08de6b Initial load
duke
parents:
diff changeset
   314
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   315
     * Enable the synchronize method which may do cloning. This method is enabled
7f561c08de6b Initial load
duke
parents:
diff changeset
   316
     * when the parser is done with an EntityReference.
7f561c08de6b Initial load
duke
parents:
diff changeset
   317
    /***
7f561c08de6b Initial load
duke
parents:
diff changeset
   318
    // revisit: enable editing of Entity
7f561c08de6b Initial load
duke
parents:
diff changeset
   319
    public void enableSynchronize(boolean enableSynchronize) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   320
        fEnableSynchronize= enableSynchronize;
7f561c08de6b Initial load
duke
parents:
diff changeset
   321
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   322
    /***/
7f561c08de6b Initial load
duke
parents:
diff changeset
   323
7f561c08de6b Initial load
duke
parents:
diff changeset
   324
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   325
     * EntityReference's children are a reflection of those defined in the
7f561c08de6b Initial load
duke
parents:
diff changeset
   326
     * named Entity. This method updates them if the Entity is changed.
7f561c08de6b Initial load
duke
parents:
diff changeset
   327
     * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
   328
     * It is unclear what the least-cost resynch mechanism is.
7f561c08de6b Initial load
duke
parents:
diff changeset
   329
     * If we expect the kids to be shallow, and/or expect changes
7f561c08de6b Initial load
duke
parents:
diff changeset
   330
     * to the Entity contents to be rare, wiping them all out
7f561c08de6b Initial load
duke
parents:
diff changeset
   331
     * and recloning is simplest.
7f561c08de6b Initial load
duke
parents:
diff changeset
   332
     * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
   333
     * If we expect them to be deep,
7f561c08de6b Initial load
duke
parents:
diff changeset
   334
     * it might be better to first decide which kids (if any)
7f561c08de6b Initial load
duke
parents:
diff changeset
   335
     * persist, and keep the ones (if any) that are unchanged
7f561c08de6b Initial load
duke
parents:
diff changeset
   336
     * rather than doing all the work of cloning them again.
7f561c08de6b Initial load
duke
parents:
diff changeset
   337
     * But that latter gets into having to convolve the two child lists,
7f561c08de6b Initial load
duke
parents:
diff changeset
   338
     * insert new information in the right order (and possibly reorder
7f561c08de6b Initial load
duke
parents:
diff changeset
   339
     * the existing kids), and a few other complexities that I really
7f561c08de6b Initial load
duke
parents:
diff changeset
   340
     * don't want to deal with in this implementation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   341
     * <P>
7f561c08de6b Initial load
duke
parents:
diff changeset
   342
     * Note that if we decide that we need to update the EntityReference's
7f561c08de6b Initial load
duke
parents:
diff changeset
   343
     * contents, we have to turn off the readOnly flag temporarily to do so.
7f561c08de6b Initial load
duke
parents:
diff changeset
   344
     * When we get around to adding multitasking support, this whole method
7f561c08de6b Initial load
duke
parents:
diff changeset
   345
     * should probably be an atomic operation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   346
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   347
     * @see DocumentTypeImpl
7f561c08de6b Initial load
duke
parents:
diff changeset
   348
     * @see EntityImpl
7f561c08de6b Initial load
duke
parents:
diff changeset
   349
     */
24887
47b6d4800c64 8046443: A few typos in JAXP JavaDoc
joehw
parents: 12457
diff changeset
   350
    // The Xerces parser invokes callbacks for startEntityReference
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   351
    // the parsed value of the entity EACH TIME, so it is actually
7f561c08de6b Initial load
duke
parents:
diff changeset
   352
    // easier to create the nodes through the callbacks rather than
7f561c08de6b Initial load
duke
parents:
diff changeset
   353
    // clone the Entity.
7f561c08de6b Initial load
duke
parents:
diff changeset
   354
    /***
7f561c08de6b Initial load
duke
parents:
diff changeset
   355
    // revisit: enable editing of Entity
7f561c08de6b Initial load
duke
parents:
diff changeset
   356
    private void synchronize() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   357
        if (!fEnableSynchronize) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   358
            return;
7f561c08de6b Initial load
duke
parents:
diff changeset
   359
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   360
        DocumentType doctype;
7f561c08de6b Initial load
duke
parents:
diff changeset
   361
        NamedNodeMap entities;
7f561c08de6b Initial load
duke
parents:
diff changeset
   362
        EntityImpl entDef;
7f561c08de6b Initial load
duke
parents:
diff changeset
   363
        if (null != (doctype = getOwnerDocument().getDoctype()) &&
7f561c08de6b Initial load
duke
parents:
diff changeset
   364
            null != (entities = doctype.getEntities())) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   365
7f561c08de6b Initial load
duke
parents:
diff changeset
   366
            entDef = (EntityImpl)entities.getNamedItem(getNodeName());
7f561c08de6b Initial load
duke
parents:
diff changeset
   367
7f561c08de6b Initial load
duke
parents:
diff changeset
   368
            // No Entity by this name. If we had a change count, reset it.
7f561c08de6b Initial load
duke
parents:
diff changeset
   369
            if(null==entDef)
7f561c08de6b Initial load
duke
parents:
diff changeset
   370
                entityChanges=-1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   371
7f561c08de6b Initial load
duke
parents:
diff changeset
   372
            // If no kids availalble, wipe any pre-existing children.
7f561c08de6b Initial load
duke
parents:
diff changeset
   373
            // (See discussion above.)
7f561c08de6b Initial load
duke
parents:
diff changeset
   374
            // Note that we have to use the superclass to avoid recursion
7f561c08de6b Initial load
duke
parents:
diff changeset
   375
            // through Synchronize.
7f561c08de6b Initial load
duke
parents:
diff changeset
   376
            readOnly=false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   377
            if(null==entDef || !entDef.hasChildNodes())
7f561c08de6b Initial load
duke
parents:
diff changeset
   378
                for(Node kid=super.getFirstChild();
7f561c08de6b Initial load
duke
parents:
diff changeset
   379
                    kid!=null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   380
                    kid=super.getFirstChild())
7f561c08de6b Initial load
duke
parents:
diff changeset
   381
                    removeChild(kid);
7f561c08de6b Initial load
duke
parents:
diff changeset
   382
7f561c08de6b Initial load
duke
parents:
diff changeset
   383
            // If entity's definition changed, clone its kids
7f561c08de6b Initial load
duke
parents:
diff changeset
   384
            // (See discussion above.)
7f561c08de6b Initial load
duke
parents:
diff changeset
   385
            if(null!=entDef && entDef.changes!=entityChanges) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   386
                for(Node defkid=entDef.getFirstChild();
7f561c08de6b Initial load
duke
parents:
diff changeset
   387
                    defkid!=null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   388
                    defkid=defkid.getNextSibling()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   389
7f561c08de6b Initial load
duke
parents:
diff changeset
   390
                    NodeImpl newkid=(NodeImpl) defkid.cloneNode(true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   391
                    newkid.setReadOnly(true,true);
7f561c08de6b Initial load
duke
parents:
diff changeset
   392
                    insertBefore(newkid,null);
7f561c08de6b Initial load
duke
parents:
diff changeset
   393
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   394
                entityChanges=entDef.changes;
7f561c08de6b Initial load
duke
parents:
diff changeset
   395
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   396
            readOnly=true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   397
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   398
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   399
     /***/
7f561c08de6b Initial load
duke
parents:
diff changeset
   400
7f561c08de6b Initial load
duke
parents:
diff changeset
   401
7f561c08de6b Initial load
duke
parents:
diff changeset
   402
} // class EntityReferenceImpl