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/util/XMLUniDefs.hpp>
23 #include "DOMElementNSImpl.hpp"
24 #include "DOMDocumentImpl.hpp"
25 #include "DOMTypeInfoImpl.hpp"
26 #include "DOMCasts.hpp"
27 #include <xercesc/dom/DOMException.hpp>
28 #include <xercesc/util/XMLUri.hpp>
29 #include <xercesc/util/OutOfMemoryException.hpp>
30
31 XERCES_CPP_NAMESPACE_BEGIN
32
DOMElementNSImpl(DOMDocument * ownerDoc,const XMLCh * nam)33 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
34 DOMElementImpl(ownerDoc, nam)
35 {
36 this->fNamespaceURI=0; //DOM Level 2
37 this->fLocalName=0; //DOM Level 2
38 this->fPrefix=0;
39 this->fSchemaType = 0;
40 }
41
42 //Introduced in DOM Level 2
DOMElementNSImpl(DOMDocument * ownerDoc,const XMLCh * namespaceURI,const XMLCh * qualifiedName)43 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc,
44 const XMLCh *namespaceURI,
45 const XMLCh *qualifiedName) :
46 DOMElementImpl(ownerDoc, qualifiedName)
47 {
48 setName(namespaceURI, qualifiedName);
49 this->fSchemaType = 0;
50 }
51
DOMElementNSImpl(DOMDocument * ownerDoc,const XMLCh * namespaceURI,const XMLCh * prefix,const XMLCh * localName,const XMLCh * qualifiedName)52 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc,
53 const XMLCh *namespaceURI,
54 const XMLCh *prefix,
55 const XMLCh *localName,
56 const XMLCh *qualifiedName)
57 : DOMElementImpl(ownerDoc, qualifiedName)
58 {
59 this->fSchemaType = 0;
60
61 DOMDocumentImpl* docImpl = (DOMDocumentImpl*)fParent.fOwnerDocument;
62
63 if (prefix == 0 || *prefix == 0)
64 {
65 fPrefix = 0;
66 fLocalName = fName;
67 }
68 else
69 {
70 fPrefix = docImpl->getPooledString(prefix);
71 fLocalName = docImpl->getPooledString(localName);
72 }
73
74 // DOM Level 3: namespace URI is never empty string.
75 //
76 const XMLCh * URI = DOMNodeImpl::mapPrefix (
77 fPrefix,
78 (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
79 DOMNode::ELEMENT_NODE);
80
81 fNamespaceURI = (URI == 0) ? 0 : docImpl->getPooledString(URI);
82 }
83
DOMElementNSImpl(const DOMElementNSImpl & other,bool deep)84 DOMElementNSImpl::DOMElementNSImpl(const DOMElementNSImpl &other, bool deep) :
85 DOMElementImpl(other, deep)
86 {
87 this->fNamespaceURI = other.fNamespaceURI; //DOM Level 2
88 this->fLocalName = other.fLocalName; //DOM Level 2
89 this->fPrefix = other.fPrefix;
90 this->fSchemaType = other.fSchemaType;
91 }
92
cloneNode(bool deep) const93 DOMNode * DOMElementNSImpl::cloneNode(bool deep) const {
94 DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ELEMENT_NS_OBJECT) DOMElementNSImpl(*this, deep);
95 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
96 return newNode;
97 }
98
getNamespaceURI() const99 const XMLCh * DOMElementNSImpl::getNamespaceURI() const
100 {
101 return fNamespaceURI;
102 }
103
getPrefix() const104 const XMLCh * DOMElementNSImpl::getPrefix() const
105 {
106 return fPrefix;
107 }
108
109
getLocalName() const110 const XMLCh * DOMElementNSImpl::getLocalName() const
111 {
112 return fLocalName;
113 }
114
setPrefix(const XMLCh * prefix)115 void DOMElementNSImpl::setPrefix(const XMLCh *prefix)
116 {
117 if (fNode.isReadOnly())
118 throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
119 if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull)
120 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
121
122 if (prefix == 0 || *prefix == 0) {
123 fPrefix = 0;
124 fName = fLocalName;
125 return;
126 }
127
128 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
129
130 if(!doc->isXMLName(prefix))
131 throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager);
132
133 const XMLCh * xml = DOMNodeImpl::getXmlString();
134 const XMLCh * xmlURI = DOMNodeImpl::getXmlURIString();
135
136 if (XMLString::equals(prefix, xml) &&
137 !XMLString::equals(fNamespaceURI, xmlURI))
138 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
139
140
141 if (XMLString::indexOf(prefix, chColon) != -1) {
142 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
143 }
144
145 this-> fPrefix = doc->getPooledString(prefix);
146
147 XMLSize_t prefixLen = XMLString::stringLen(prefix);
148 XMLSize_t newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName);
149
150 XMLCh *newName;
151 XMLCh temp[256];
152 if (newQualifiedNameLen >= 255)
153 newName = (XMLCh*) doc->getMemoryManager()->allocate
154 (
155 newQualifiedNameLen * sizeof(XMLCh)
156 );//new XMLCh[newQualifiedNameLen];
157 else
158 newName = temp;
159
160 // newName = prefix + chColon + fLocalName;
161 XMLString::copyString(newName, prefix);
162 newName[prefixLen] = chColon;
163 XMLString::copyString(&newName[prefixLen+1], fLocalName);
164
165 fName = doc->getPooledString(newName);
166
167 if (newQualifiedNameLen >= 255)
168 doc->getMemoryManager()->deallocate(newName);//delete[] newName;
169
170 }
171
release()172 void DOMElementNSImpl::release()
173 {
174 if (fNode.isOwned() && !fNode.isToBeReleased())
175 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
176
177 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
178 if (doc) {
179 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
180 fParent.release();
181 doc->release(this, DOMMemoryManager::ELEMENT_NS_OBJECT);
182 }
183 else {
184 // shouldn't reach here
185 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
186 }
187 }
188
rename(const XMLCh * namespaceURI,const XMLCh * name)189 DOMNode* DOMElementNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
190 {
191 setName(namespaceURI, name);
192 fAttributes->reconcileDefaultAttributes(getDefaultAttributes());
193 // and fire user data NODE_RENAMED event
194 castToNodeImpl(this)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, this);
195
196 return this;
197 }
198
setName(const XMLCh * namespaceURI,const XMLCh * qualifiedName)199 void DOMElementNSImpl::setName(const XMLCh *namespaceURI,
200 const XMLCh *qualifiedName)
201 {
202 DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *) fParent.fOwnerDocument;
203 this->fName = ownerDoc->getPooledString(qualifiedName);
204
205 int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
206 if (index < 0)
207 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
208
209 if (index == 0)
210 {
211 //qualifiedName contains no ':'
212 //
213 fPrefix = 0;
214 fLocalName = fName;
215 }
216 else
217 { //0 < index < this->name.length()-1
218 //
219 fPrefix = ownerDoc->getPooledNString(qualifiedName, index);
220 fLocalName = ownerDoc->getPooledString(fName+index+1);
221
222 // Before we carry on, we should check if the prefix or localName are valid XMLName
223 if (!ownerDoc->isXMLName(fPrefix) || !ownerDoc->isXMLName(fLocalName))
224 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
225 }
226
227 // DOM Level 3: namespace URI is never empty string.
228 //
229 const XMLCh * URI = DOMNodeImpl::mapPrefix (
230 fPrefix,
231 (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
232 DOMNode::ELEMENT_NODE);
233
234 fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI);
235 }
236
getSchemaTypeInfo() const237 const DOMTypeInfo *DOMElementNSImpl::getSchemaTypeInfo() const
238 {
239 if(!fSchemaType)
240 return &DOMTypeInfoImpl::g_DtdValidatedElement;
241 return fSchemaType;
242 }
243
setSchemaTypeInfo(const DOMTypeInfoImpl * typeInfo)244 void DOMElementNSImpl::setSchemaTypeInfo(const DOMTypeInfoImpl* typeInfo)
245 {
246 fSchemaType = typeInfo;
247 }
248
isSupported(const XMLCh * feature,const XMLCh * version) const249 bool DOMElementNSImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
250 {
251 // check for '+DOMPSVITypeInfo'
252 if(feature && *feature=='+' && XMLString::equals(feature+1, XMLUni::fgXercescInterfacePSVITypeInfo))
253 return true;
254 return fNode.isSupported (feature, version);
255 }
256
getFeature(const XMLCh * feature,const XMLCh * version) const257 void* DOMElementNSImpl::getFeature(const XMLCh* feature, const XMLCh* version) const
258 {
259 if(XMLString::equals(feature, XMLUni::fgXercescInterfacePSVITypeInfo))
260 return (DOMPSVITypeInfo*)fSchemaType;
261 return DOMElementImpl::getFeature(feature, version);
262 }
263
264 XERCES_CPP_NAMESPACE_END
265