source: icXML/icXML-devel/src/xercesc/dom/impl/DOMAttrNSImpl.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 7.8 KB
RevLine 
[2722]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: DOMAttrNSImpl.cpp 901107 2010-01-20 08:45:02Z borisk $
20 */
21
22#include <xercesc/util/XMLUniDefs.hpp>
23#include "DOMAttrNSImpl.hpp"
24#include "DOMDocumentImpl.hpp"
25#include <xercesc/dom/DOMDocument.hpp>
26#include <xercesc/dom/DOMElement.hpp>
27#include <xercesc/dom/DOMException.hpp>
28
29#include "assert.h"
30
31XERCES_CPP_NAMESPACE_BEGIN
32
33DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
34DOMAttrImpl(ownerDoc, nam)
35{
36    this->fNamespaceURI=0;      //DOM Level 2
37    this->fLocalName=0;       //DOM Level 2
38    this->fPrefix=0;
39}
40
41//Introduced in DOM Level 2
42DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc,
43                           const XMLCh *namespaceURI,
44                           const XMLCh *qualifiedName) :
45DOMAttrImpl(ownerDoc, qualifiedName)
46{
47    setName(namespaceURI, qualifiedName);
48}
49
50DOMAttrNSImpl::
51DOMAttrNSImpl(DOMDocument *ownerDoc,
52              const XMLCh *namespaceURI,
53              const XMLCh *prefix,
54              const XMLCh *localName,
55              const XMLCh *qualifiedName)
56    : DOMAttrImpl(ownerDoc, qualifiedName)
57{
58  DOMDocumentImpl* docImpl = (DOMDocumentImpl*)fParent.fOwnerDocument;
59
60  if (prefix == 0 || *prefix == 0)
61  {
62    fPrefix = 0;
63    fLocalName = fName;
64  }
65  else
66  {
67    fPrefix = docImpl->getPooledString(prefix);
68    fLocalName = docImpl->getPooledString(localName);
69  }
70
71  // DOM Level 3: namespace URI is never empty string.
72  //
73  const XMLCh * URI = DOMNodeImpl::mapPrefix
74    (
75      fPrefix,
76      (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
77      DOMNode::ATTRIBUTE_NODE
78    );
79  this -> fNamespaceURI = (URI == 0) ? 0 : docImpl->getPooledString(URI);
80}
81
82DOMAttrNSImpl::DOMAttrNSImpl(const DOMAttrNSImpl &other, bool deep) :
83DOMAttrImpl(other, deep)
84{
85    this->fNamespaceURI = other.fNamespaceURI;  //DOM Level 2
86    this->fLocalName = other.fLocalName;          //DOM Level 2
87    this->fPrefix = other.fPrefix;
88}
89
90DOMNode * DOMAttrNSImpl::cloneNode(bool deep) const
91{
92    DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ATTR_NS_OBJECT) DOMAttrNSImpl(*this, deep);
93    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
94    return newNode;
95}
96
97const XMLCh * DOMAttrNSImpl::getNamespaceURI() const
98{
99    return fNamespaceURI;
100}
101
102const XMLCh * DOMAttrNSImpl::getPrefix() const
103{
104    return fPrefix;
105}
106
107const XMLCh * DOMAttrNSImpl::getLocalName() const
108{
109    return fLocalName;
110}
111
112void DOMAttrNSImpl::setPrefix(const XMLCh *prefix)
113{
114    const XMLCh * xmlns = DOMNodeImpl::getXmlnsString();
115
116    if (fNode.isReadOnly())
117        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
118    if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull || XMLString::equals(fLocalName, xmlns))
119        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
120
121    if (prefix == 0 || prefix[0] == chNull) {
122        fName = fLocalName;
123        fPrefix = 0;
124        return;
125    }
126
127    DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
128
129    if (!doc->isXMLName(prefix))
130        throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager);
131
132    const XMLCh * xml = DOMNodeImpl::getXmlString();
133    const XMLCh * xmlURI = DOMNodeImpl::getXmlURIString();
134    const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString();
135
136    if ((XMLString::equals(prefix, xml) &&
137         !XMLString::equals(fNamespaceURI, xmlURI))
138        || (XMLString::equals(prefix, xmlns) &&
139            !XMLString::equals(fNamespaceURI, xmlnsURI)))
140        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
141
142    if (XMLString::indexOf(prefix, chColon) != -1) {
143        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
144    }
145
146    this-> fPrefix = doc->getPooledString(prefix);
147
148    XMLSize_t prefixLen = XMLString::stringLen(prefix);
149    XMLSize_t newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName);
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
172void DOMAttrNSImpl::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::ATTR_NS_OBJECT);
182    }
183    else {
184        // shouldn't reach here
185        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
186    }
187}
188
189
190DOMNode* DOMAttrNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
191{
192    DOMElement* el = getOwnerElement();
193    if (el)
194        el->removeAttributeNode(this);
195
196    setName(namespaceURI, name);
197
198    if (el)
199        el->setAttributeNodeNS(this);
200
201    return this;
202}
203
204void DOMAttrNSImpl::setName(const XMLCh* namespaceURI, const XMLCh* qualifiedName)
205{
206    DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *)fParent.fOwnerDocument;
207    const XMLCh * xmlns = DOMNodeImpl::getXmlnsString();
208    const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString();
209    this->fName = ownerDoc->getPooledString(qualifiedName);
210
211    int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
212    if (index < 0)
213        throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
214
215    bool xmlnsAlone = false;    //true if attribute name is "xmlns"
216    if (index == 0)
217    {   //qualifiedName contains no ':'
218        if (XMLString::equals(this->fName, xmlns)) {
219            if (!XMLString::equals(namespaceURI, xmlnsURI))
220                throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
221            xmlnsAlone = true;
222        }
223        fPrefix = 0;
224        fLocalName = fName;
225    }
226    else
227    {
228        fPrefix = ownerDoc->getPooledNString(fName, index);
229        fLocalName = ownerDoc->getPooledString(fName+index+1);
230
231        // Before we carry on, we should check if the prefix or localName are valid XMLName
232        if (!ownerDoc->isXMLName(fPrefix) || !ownerDoc->isXMLName(fLocalName))
233            throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
234    }
235
236    // DOM Level 3: namespace URI is never empty string.
237    const XMLCh * URI = xmlnsAlone ? xmlnsURI
238        : DOMNodeImpl::mapPrefix
239          (
240              fPrefix,
241              (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
242              DOMNode::ATTRIBUTE_NODE
243          );
244    this -> fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI);
245}
246
247XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.