1 /*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5 /*
6 * Copyright 1999-2002,2004 The Apache Software Foundation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xerces.internal.dom;
22
23 /**
24 * EntityReference models the XML &entityname; syntax, when used for
25 * entities defined by the DOM. Entities hardcoded into XML, such as
26 * character entities, should instead have been translated into text
27 * by the code which generated the DOM tree.
28 * <P>
29 * An XML processor has the alternative of fully expanding Entities
30 * into the normal document tree. If it does so, no EntityReference nodes
31 * will appear.
32 * <P>
33 * Similarly, non-validating XML processors are not required to read
34 * or process entity declarations made in the external subset or
35 * declared in external parameter entities. Hence, some applications
36 * may not make the replacement value available for Parsed Entities
37 * of these types.
38 * <P>
39 * EntityReference behaves as a read-only node, and the children of
40 * the EntityReference (which reflect those of the Entity, and should
41 * also be read-only) give its replacement value, if any. They are
42 * supposed to automagically stay in synch if the DocumentType is
43 * updated with new values for the Entity.
44 * <P>
45 * The defined behavior makes efficient storage difficult for the DOM
46 * implementor. We can't just look aside to the Entity's definition
47 * in the DocumentType since those nodes have the wrong parent (unless
48 * we can come up with a clever "imaginary parent" mechanism). We
49 * must at least appear to clone those children... which raises the
50 * issue of keeping the reference synchronized with its parent.
51 * This leads me back to the "cached image of centrally defined data"
52 * solution, much as I dislike it.
53 * <P>
54 * For now I have decided, since REC-DOM-Level-1-19980818 doesn't
55 * cover this in much detail, that synchronization doesn't have to be
56 * considered while the user is deep in the tree. That is, if you're
57 * looking within one of the EntityReferennce's children and the Entity
58 * changes, you won't be informed; instead, you will continue to access
59 * the same object -- which may or may not still be part of the tree.
60 * This is the same behavior that obtains elsewhere in the DOM if the
61 * subtree you're looking at is deleted from its parent, so it's
62 * acceptable here. (If it really bothers folks, we could set things
63 * up so deleted subtrees are walked and marked invalid, but that's
64 * not part of the DOM's defined behavior.)
65 * <P>
66 * As a result, only the EntityReference itself has to be aware of
67 * changes in the Entity. And it can take advantage of the same
68 * structure-change-monitoring code I implemented to support
69 * DeepNodeList.
70 *
71 * @xerces.internal
72 *
73 * @since PR-DOM-Level-1-19980818.
74 */
75 public class DeferredEntityReferenceImpl
76 extends EntityReferenceImpl
77 implements DeferredNode {
78
79 //
80 // Constants
81 //
82
83 /** Serialization version. */
84 static final long serialVersionUID = 390319091370032223L;
85
86 //
87 // Data
88 //
89
90 /** Node index. */
91 protected transient int fNodeIndex;
92
93 //
94 // Constructors
95 //
96
97 /**
98 * This is the deferred constructor. Only the fNodeIndex is given here.
99 * All other data, can be requested from the ownerDocument via the index.
100 */
101 DeferredEntityReferenceImpl(DeferredDocumentImpl ownerDocument,
102 int nodeIndex) {
103 super(ownerDocument, null);
104
105 fNodeIndex = nodeIndex;
106 needsSyncData(true);
107
108 } // <init>(DeferredDocumentImpl,int)
109
110 //
111 // DeferredNode methods
112 //
113
114 /** Returns the node index. */
115 public int getNodeIndex() {
116 return fNodeIndex;
117 }
118
119 //
120 // Protected methods
121 //
122
123 /**
124 * Synchronize the entity data. This is special because of the way
125 * that the "fast" version stores the information.
126 */
127 protected void synchronizeData() {
128
129 // no need to sychronize again
130 needsSyncData(false);
131
132 // get the node data
133 DeferredDocumentImpl ownerDocument =
134 (DeferredDocumentImpl)this.ownerDocument;
135 name = ownerDocument.getNodeName(fNodeIndex);
136 baseURI = ownerDocument.getNodeValue(fNodeIndex);
137
138 } // synchronizeData()
139
140 /** Synchronize the children. */
141 protected void synchronizeChildren() {
142
143 // no need to synchronize again
144 needsSyncChildren(false);
145
146 // get children
147 isReadOnly(false);
148 DeferredDocumentImpl ownerDocument =
149 (DeferredDocumentImpl) ownerDocument();
150 ownerDocument.synchronizeChildren(this, fNodeIndex);
151 setReadOnly(true, true);
152
153 } // synchronizeChildren()
154
155 } // class DeferredEntityReferenceImpl