1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * $Id$
20 */
21
22 #include <xercesc/dom/DOMException.hpp>
23 #include <xercesc/dom/DOMNode.hpp>
24 #include <xercesc/dom/DOMEntityReference.hpp>
25 #include "DOMEntityImpl.hpp"
26 #include "DOMDocumentImpl.hpp"
27
28 XERCES_CPP_NAMESPACE_BEGIN
29
DOMEntityImpl(DOMDocument * ownerDoc,const XMLCh * eName)30 DOMEntityImpl::DOMEntityImpl(DOMDocument *ownerDoc, const XMLCh *eName)
31 : fNode(this, ownerDoc),
32 fParent(this, ownerDoc),
33 fPublicId(0),
34 fSystemId(0),
35 fNotationName(0),
36 fRefEntity(0),
37 fInputEncoding(0),
38 fXmlEncoding(0),
39 fXmlVersion(0),
40 fBaseURI(0),
41 fEntityRefNodeCloned(false)
42 {
43 fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(eName);
44 fNode.setReadOnly(true, true);
45 }
46
47
DOMEntityImpl(const DOMEntityImpl & other,bool deep)48 DOMEntityImpl::DOMEntityImpl(const DOMEntityImpl &other, bool deep)
49 : DOMEntity(other),
50 fNode(this, other.fNode),
51 fParent(this, other.fParent),
52 fName(other.fName),
53 fPublicId(other.fPublicId),
54 fSystemId(other.fSystemId),
55 fNotationName(other.fNotationName),
56 fRefEntity(other.fRefEntity),
57 fInputEncoding(other.fInputEncoding),
58 fXmlEncoding(other.fXmlEncoding),
59 fXmlVersion(other.fXmlVersion),
60 fBaseURI(other.fBaseURI),
61 fEntityRefNodeCloned(false)
62 {
63 if (deep)
64 fParent.cloneChildren(&other);
65 fNode.setReadOnly(true, true);
66 }
67
68
~DOMEntityImpl()69 DOMEntityImpl::~DOMEntityImpl() {
70 }
71
72
cloneNode(bool deep) const73 DOMNode *DOMEntityImpl::cloneNode(bool deep) const
74 {
75 DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ENTITY_OBJECT) DOMEntityImpl(*this, deep);
76 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
77 return newNode;
78 }
79
80
getNodeName() const81 const XMLCh * DOMEntityImpl::getNodeName() const {
82 return fName;
83 }
84
85
getNodeType() const86 DOMNode::NodeType DOMEntityImpl::getNodeType() const {
87 return DOMNode::ENTITY_NODE;
88 }
89
90
getNotationName() const91 const XMLCh * DOMEntityImpl::getNotationName() const
92 {
93 return fNotationName;
94 }
95
96
getPublicId() const97 const XMLCh * DOMEntityImpl::getPublicId() const {
98 return fPublicId;
99 }
100
101
getSystemId() const102 const XMLCh * DOMEntityImpl::getSystemId() const
103 {
104 return fSystemId;
105 }
106
107
getBaseURI() const108 const XMLCh* DOMEntityImpl::getBaseURI() const
109 {
110 return fBaseURI;
111 }
112
113
setNodeValue(const XMLCh * arg)114 void DOMEntityImpl::setNodeValue(const XMLCh *arg)
115 {
116 fNode.setNodeValue(arg);
117 }
118
119
setNotationName(const XMLCh * arg)120 void DOMEntityImpl::setNotationName(const XMLCh *arg)
121 {
122 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
123 fNotationName = doc->cloneString(arg);
124 }
125
126
setPublicId(const XMLCh * arg)127 void DOMEntityImpl::setPublicId(const XMLCh *arg)
128 {
129 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
130 fPublicId = doc->cloneString(arg);
131 }
132
133
setSystemId(const XMLCh * arg)134 void DOMEntityImpl::setSystemId(const XMLCh *arg)
135 {
136 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
137 fSystemId = doc->cloneString(arg);
138 }
139
140
setBaseURI(const XMLCh * baseURI)141 void DOMEntityImpl::setBaseURI(const XMLCh* baseURI) {
142 if (baseURI && *baseURI) {
143 XMLCh* temp = (XMLCh*) ((DOMDocumentImpl *)fParent.fOwnerDocument)->allocate((XMLString::stringLen(baseURI) + 9)*sizeof(XMLCh));
144 XMLString::fixURI(baseURI, temp);
145 fBaseURI = temp;
146 }
147 else
148 fBaseURI = 0;
149 }
150
151
setEntityRef(DOMEntityReference * other)152 void DOMEntityImpl::setEntityRef(DOMEntityReference* other)
153 {
154 fRefEntity = other;
155 }
156
157
getEntityRef() const158 DOMEntityReference* DOMEntityImpl::getEntityRef() const
159 {
160 return fRefEntity;
161 }
162
cloneEntityRefTree() const163 void DOMEntityImpl::cloneEntityRefTree() const
164 {
165 if (fEntityRefNodeCloned)
166 return;
167
168 // cast off const. This method is const because it is
169 // called from a bunch of logically const methods, like
170 // getFirstChild().
171 DOMEntityImpl *ncThis = (DOMEntityImpl *)this;
172
173 //lazily clone the entityRef tree to this entity
174 if (fParent.fFirstChild != 0)
175 return;
176
177 if (!fRefEntity)
178 return;
179
180 ncThis->fEntityRefNodeCloned = true;
181 ncThis->fNode.setReadOnly(false, true);
182 ncThis->fParent.cloneChildren(fRefEntity);
183 ncThis->fNode.setReadOnly(true, true);
184 }
185
getFirstChild() const186 DOMNode * DOMEntityImpl::getFirstChild() const
187 {
188 cloneEntityRefTree();
189 return fParent.fFirstChild;
190 }
191
getLastChild() const192 DOMNode * DOMEntityImpl::getLastChild() const
193 {
194 cloneEntityRefTree();
195 return fParent.getLastChild();
196 }
197
getChildNodes() const198 DOMNodeList* DOMEntityImpl::getChildNodes() const
199 {
200 cloneEntityRefTree();
201 return this->fParent.getChildNodes();
202
203 }
204
hasChildNodes() const205 bool DOMEntityImpl::hasChildNodes() const
206 {
207 cloneEntityRefTree();
208 return fParent.fFirstChild!=0;
209 }
210
211
release()212 void DOMEntityImpl::release()
213 {
214 if (fNode.isOwned() && !fNode.isToBeReleased())
215 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
216
217 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
218 if (doc) {
219 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
220 fParent.release();
221 doc->release(this, DOMMemoryManager::ENTITY_OBJECT);
222 }
223 else {
224 // shouldn't reach here
225 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
226 }
227 }
228
229 //
230 // Functions inherited from Node
231 //
232
appendChild(DOMNode * newChild)233 DOMNode* DOMEntityImpl::appendChild(DOMNode *newChild) {cloneEntityRefTree(); return fParent.appendChild (newChild); }
getAttributes() const234 DOMNamedNodeMap* DOMEntityImpl::getAttributes() const {return fNode.getAttributes (); }
getLocalName() const235 const XMLCh* DOMEntityImpl::getLocalName() const {return fNode.getLocalName (); }
getNamespaceURI() const236 const XMLCh* DOMEntityImpl::getNamespaceURI() const {return fNode.getNamespaceURI (); }
getNextSibling() const237 DOMNode* DOMEntityImpl::getNextSibling() const {return fNode.getNextSibling (); }
getNodeValue() const238 const XMLCh* DOMEntityImpl::getNodeValue() const {return fNode.getNodeValue (); }
getOwnerDocument() const239 DOMDocument* DOMEntityImpl::getOwnerDocument() const {return fParent.fOwnerDocument; }
getPrefix() const240 const XMLCh* DOMEntityImpl::getPrefix() const {return fNode.getPrefix (); }
getParentNode() const241 DOMNode* DOMEntityImpl::getParentNode() const {return fNode.getParentNode (); }
getPreviousSibling() const242 DOMNode* DOMEntityImpl::getPreviousSibling() const {return fNode.getPreviousSibling (); }
insertBefore(DOMNode * newChild,DOMNode * refChild)243 DOMNode* DOMEntityImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
244 {cloneEntityRefTree(); return fParent.insertBefore (newChild, refChild); }
normalize()245 void DOMEntityImpl::normalize() {cloneEntityRefTree(); fParent.normalize (); }
removeChild(DOMNode * oldChild)246 DOMNode* DOMEntityImpl::removeChild(DOMNode *oldChild) {cloneEntityRefTree(); return fParent.removeChild (oldChild); }
replaceChild(DOMNode * newChild,DOMNode * oldChild)247 DOMNode* DOMEntityImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
248 {cloneEntityRefTree(); return fParent.replaceChild (newChild, oldChild); }
isSupported(const XMLCh * feature,const XMLCh * version) const249 bool DOMEntityImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
250 {return fNode.isSupported (feature, version); }
setPrefix(const XMLCh * prefix)251 void DOMEntityImpl::setPrefix(const XMLCh *prefix) {fNode.setPrefix(prefix); }
hasAttributes() const252 bool DOMEntityImpl::hasAttributes() const {return fNode.hasAttributes(); }
isSameNode(const DOMNode * other) const253 bool DOMEntityImpl::isSameNode(const DOMNode* other) const {return fNode.isSameNode(other); }
isEqualNode(const DOMNode * arg) const254 bool DOMEntityImpl::isEqualNode(const DOMNode* arg) const {cloneEntityRefTree(); return fParent.isEqualNode(arg); }
setUserData(const XMLCh * key,void * data,DOMUserDataHandler * handler)255 void* DOMEntityImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
256 {return fNode.setUserData(key, data, handler); }
getUserData(const XMLCh * key) const257 void* DOMEntityImpl::getUserData(const XMLCh* key) const {return fNode.getUserData(key); }
compareDocumentPosition(const DOMNode * other) const258 short DOMEntityImpl::compareDocumentPosition(const DOMNode* other) const {return fNode.compareDocumentPosition(other); }
getTextContent() const259 const XMLCh* DOMEntityImpl::getTextContent() const {return fNode.getTextContent(); }
setTextContent(const XMLCh * textContent)260 void DOMEntityImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
lookupPrefix(const XMLCh * namespaceURI) const261 const XMLCh* DOMEntityImpl::lookupPrefix(const XMLCh* namespaceURI) const {return fNode.lookupPrefix(namespaceURI); }
isDefaultNamespace(const XMLCh * namespaceURI) const262 bool DOMEntityImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
lookupNamespaceURI(const XMLCh * prefix) const263 const XMLCh* DOMEntityImpl::lookupNamespaceURI(const XMLCh* prefix) const {return fNode.lookupNamespaceURI(prefix); }
getFeature(const XMLCh * feature,const XMLCh * version) const264 void* DOMEntityImpl::getFeature(const XMLCh* feature, const XMLCh* version) const {return fNode.getFeature(feature, version); }
265
266 // Macro-in implementation accessors.
267 DOMNODEIMPL_IMPL(DOMEntityImpl);
268 DOMPARENTIMPL_IMPL(DOMEntityImpl);
269
270 //Introduced in DOM Level 3
getInputEncoding() const271 const XMLCh* DOMEntityImpl::getInputEncoding() const {
272 return fInputEncoding;
273 }
274
setInputEncoding(const XMLCh * actualEncoding)275 void DOMEntityImpl::setInputEncoding(const XMLCh* actualEncoding){
276 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
277 fInputEncoding = doc->cloneString(actualEncoding);
278 }
279
getXmlEncoding() const280 const XMLCh* DOMEntityImpl::getXmlEncoding() const {
281 return fXmlEncoding;
282 }
283
setXmlEncoding(const XMLCh * encoding)284 void DOMEntityImpl::setXmlEncoding(const XMLCh* encoding){
285 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
286 fXmlEncoding = doc->cloneString(encoding);
287 }
288
getXmlVersion() const289 const XMLCh* DOMEntityImpl::getXmlVersion() const {
290 return fXmlVersion;
291 }
292
setXmlVersion(const XMLCh * version)293 void DOMEntityImpl::setXmlVersion(const XMLCh* version){
294 DOMDocumentImpl *doc = (DOMDocumentImpl *)fParent.fOwnerDocument;
295 fXmlVersion = doc->cloneString(version);
296 }
297
298 XERCES_CPP_NAMESPACE_END
299