001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.dom;
019:
020: /**
021: * EntityReference models the XML &entityname; syntax, when used for
022: * entities defined by the DOM. Entities hardcoded into XML, such as
023: * character entities, should instead have been translated into text
024: * by the code which generated the DOM tree.
025: * <P>
026: * An XML processor has the alternative of fully expanding Entities
027: * into the normal document tree. If it does so, no EntityReference nodes
028: * will appear.
029: * <P>
030: * Similarly, non-validating XML processors are not required to read
031: * or process entity declarations made in the external subset or
032: * declared in external parameter entities. Hence, some applications
033: * may not make the replacement value available for Parsed Entities
034: * of these types.
035: * <P>
036: * EntityReference behaves as a read-only node, and the children of
037: * the EntityReference (which reflect those of the Entity, and should
038: * also be read-only) give its replacement value, if any. They are
039: * supposed to automagically stay in synch if the DocumentType is
040: * updated with new values for the Entity.
041: * <P>
042: * The defined behavior makes efficient storage difficult for the DOM
043: * implementor. We can't just look aside to the Entity's definition
044: * in the DocumentType since those nodes have the wrong parent (unless
045: * we can come up with a clever "imaginary parent" mechanism). We
046: * must at least appear to clone those children... which raises the
047: * issue of keeping the reference synchronized with its parent.
048: * This leads me back to the "cached image of centrally defined data"
049: * solution, much as I dislike it.
050: * <P>
051: * For now I have decided, since REC-DOM-Level-1-19980818 doesn't
052: * cover this in much detail, that synchronization doesn't have to be
053: * considered while the user is deep in the tree. That is, if you're
054: * looking within one of the EntityReferennce's children and the Entity
055: * changes, you won't be informed; instead, you will continue to access
056: * the same object -- which may or may not still be part of the tree.
057: * This is the same behavior that obtains elsewhere in the DOM if the
058: * subtree you're looking at is deleted from its parent, so it's
059: * acceptable here. (If it really bothers folks, we could set things
060: * up so deleted subtrees are walked and marked invalid, but that's
061: * not part of the DOM's defined behavior.)
062: * <P>
063: * As a result, only the EntityReference itself has to be aware of
064: * changes in the Entity. And it can take advantage of the same
065: * structure-change-monitoring code I implemented to support
066: * DeepNodeList.
067: *
068: * @xerces.internal
069: *
070: * @version $Id: DeferredEntityReferenceImpl.java 447266 2006-09-18 05:57:49Z mrglavas $
071: * @since PR-DOM-Level-1-19980818.
072: */
073: public class DeferredEntityReferenceImpl extends EntityReferenceImpl
074: implements DeferredNode {
075:
076: //
077: // Constants
078: //
079:
080: /** Serialization version. */
081: static final long serialVersionUID = 390319091370032223L;
082:
083: //
084: // Data
085: //
086:
087: /** Node index. */
088: protected transient int fNodeIndex;
089:
090: //
091: // Constructors
092: //
093:
094: /**
095: * This is the deferred constructor. Only the fNodeIndex is given here.
096: * All other data, can be requested from the ownerDocument via the index.
097: */
098: DeferredEntityReferenceImpl(DeferredDocumentImpl ownerDocument,
099: int nodeIndex) {
100: super (ownerDocument, null);
101:
102: fNodeIndex = nodeIndex;
103: needsSyncData(true);
104:
105: } // <init>(DeferredDocumentImpl,int)
106:
107: //
108: // DeferredNode methods
109: //
110:
111: /** Returns the node index. */
112: public int getNodeIndex() {
113: return fNodeIndex;
114: }
115:
116: //
117: // Protected methods
118: //
119:
120: /**
121: * Synchronize the entity data. This is special because of the way
122: * that the "fast" version stores the information.
123: */
124: protected void synchronizeData() {
125:
126: // no need to sychronize again
127: needsSyncData(false);
128:
129: // get the node data
130: DeferredDocumentImpl ownerDocument = (DeferredDocumentImpl) this .ownerDocument;
131: name = ownerDocument.getNodeName(fNodeIndex);
132: baseURI = ownerDocument.getNodeValue(fNodeIndex);
133:
134: } // synchronizeData()
135:
136: /** Synchronize the children. */
137: protected void synchronizeChildren() {
138:
139: // no need to synchronize again
140: needsSyncChildren(false);
141:
142: // get children
143: isReadOnly(false);
144: DeferredDocumentImpl ownerDocument = (DeferredDocumentImpl) ownerDocument();
145: ownerDocument.synchronizeChildren(this , fNodeIndex);
146: setReadOnly(true, true);
147:
148: } // synchronizeChildren()
149:
150: } // class DeferredEntityReferenceImpl
|