GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: DOMAttrNSImpl.cpp 901107 2010-01-20 08:45:02Z borisk $ 00020 */ 00021 00022 #include <xercesc/util/XMLUniDefs.hpp> 00023 #include "DOMAttrNSImpl.hpp" 00024 #include "DOMDocumentImpl.hpp" 00025 #include <xercesc/dom/DOMDocument.hpp> 00026 #include <xercesc/dom/DOMElement.hpp> 00027 #include <xercesc/dom/DOMException.hpp> 00028 00029 #include "assert.h" 00030 00031 XERCES_CPP_NAMESPACE_BEGIN 00032 00033 DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) : 00034 DOMAttrImpl(ownerDoc, nam) 00035 { 00036 this->fNamespaceURI=0; //DOM Level 2 00037 this->fLocalName=0; //DOM Level 2 00038 this->fPrefix=0; 00039 } 00040 00041 //Introduced in DOM Level 2 00042 DOMAttrNSImpl::DOMAttrNSImpl(DOMDocument *ownerDoc, 00043 const XMLCh *namespaceURI, 00044 const XMLCh *qualifiedName) : 00045 DOMAttrImpl(ownerDoc, qualifiedName) 00046 { 00047 setName(namespaceURI, qualifiedName); 00048 } 00049 00050 DOMAttrNSImpl:: 00051 DOMAttrNSImpl(DOMDocument *ownerDoc, 00052 const XMLCh *namespaceURI, 00053 const XMLCh *prefix, 00054 const XMLCh *localName, 00055 const XMLCh *qualifiedName) 00056 : DOMAttrImpl(ownerDoc, qualifiedName) 00057 { 00058 DOMDocumentImpl* docImpl = (DOMDocumentImpl*)fParent.fOwnerDocument; 00059 00060 if (prefix == 0 || *prefix == 0) 00061 { 00062 fPrefix = 0; 00063 fLocalName = fName; 00064 } 00065 else 00066 { 00067 fPrefix = docImpl->getPooledString(prefix); 00068 fLocalName = docImpl->getPooledString(localName); 00069 } 00070 00071 // DOM Level 3: namespace URI is never empty string. 00072 // 00073 const XMLCh * URI = DOMNodeImpl::mapPrefix 00074 ( 00075 fPrefix, 00076 (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI, 00077 DOMNode::ATTRIBUTE_NODE 00078 ); 00079 this -> fNamespaceURI = (URI == 0) ? 0 : docImpl->getPooledString(URI); 00080 } 00081 00082 DOMAttrNSImpl::DOMAttrNSImpl(const DOMAttrNSImpl &other, bool deep) : 00083 DOMAttrImpl(other, deep) 00084 { 00085 this->fNamespaceURI = other.fNamespaceURI; //DOM Level 2 00086 this->fLocalName = other.fLocalName; //DOM Level 2 00087 this->fPrefix = other.fPrefix; 00088 } 00089 00090 DOMNode * DOMAttrNSImpl::cloneNode(bool deep) const 00091 { 00092 DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ATTR_NS_OBJECT) DOMAttrNSImpl(*this, deep); 00093 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode); 00094 return newNode; 00095 } 00096 00097 const XMLCh * DOMAttrNSImpl::getNamespaceURI() const 00098 { 00099 return fNamespaceURI; 00100 } 00101 00102 const XMLCh * DOMAttrNSImpl::getPrefix() const 00103 { 00104 return fPrefix; 00105 } 00106 00107 const XMLCh * DOMAttrNSImpl::getLocalName() const 00108 { 00109 return fLocalName; 00110 } 00111 00112 void DOMAttrNSImpl::setPrefix(const XMLCh *prefix) 00113 { 00114 const XMLCh * xmlns = DOMNodeImpl::getXmlnsString(); 00115 00116 if (fNode.isReadOnly()) 00117 throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager); 00118 if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull || XMLString::equals(fLocalName, xmlns)) 00119 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00120 00121 if (prefix == 0 || prefix[0] == chNull) { 00122 fName = fLocalName; 00123 fPrefix = 0; 00124 return; 00125 } 00126 00127 DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument; 00128 00129 if (!doc->isXMLName(prefix)) 00130 throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager); 00131 00132 const XMLCh * xml = DOMNodeImpl::getXmlString(); 00133 const XMLCh * xmlURI = DOMNodeImpl::getXmlURIString(); 00134 const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString(); 00135 00136 if ((XMLString::equals(prefix, xml) && 00137 !XMLString::equals(fNamespaceURI, xmlURI)) 00138 || (XMLString::equals(prefix, xmlns) && 00139 !XMLString::equals(fNamespaceURI, xmlnsURI))) 00140 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00141 00142 if (XMLString::indexOf(prefix, chColon) != -1) { 00143 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00144 } 00145 00146 this-> fPrefix = doc->getPooledString(prefix); 00147 00148 XMLSize_t prefixLen = XMLString::stringLen(prefix); 00149 XMLSize_t newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName); 00150 XMLCh* newName; 00151 XMLCh temp[256]; 00152 if (newQualifiedNameLen >= 255) 00153 newName = (XMLCh*) doc->getMemoryManager()->allocate 00154 ( 00155 newQualifiedNameLen * sizeof(XMLCh) 00156 );//new XMLCh[newQualifiedNameLen]; 00157 else 00158 newName = temp; 00159 00160 // newName = prefix + chColon + fLocalName; 00161 XMLString::copyString(newName, prefix); 00162 newName[prefixLen] = chColon; 00163 XMLString::copyString(&newName[prefixLen+1], fLocalName); 00164 00165 fName = doc->getPooledString(newName); 00166 00167 if (newQualifiedNameLen >= 255) 00168 doc->getMemoryManager()->deallocate(newName);//delete[] newName; 00169 00170 } 00171 00172 void DOMAttrNSImpl::release() 00173 { 00174 if (fNode.isOwned() && !fNode.isToBeReleased()) 00175 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); 00176 00177 DOMDocumentImpl* doc = (DOMDocumentImpl*)fParent.fOwnerDocument; 00178 if (doc) { 00179 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0); 00180 fParent.release(); 00181 doc->release(this, DOMMemoryManager::ATTR_NS_OBJECT); 00182 } 00183 else { 00184 // shouldn't reach here 00185 throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); 00186 } 00187 } 00188 00189 00190 DOMNode* DOMAttrNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name) 00191 { 00192 DOMElement* el = getOwnerElement(); 00193 if (el) 00194 el->removeAttributeNode(this); 00195 00196 setName(namespaceURI, name); 00197 00198 if (el) 00199 el->setAttributeNodeNS(this); 00200 00201 return this; 00202 } 00203 00204 void DOMAttrNSImpl::setName(const XMLCh* namespaceURI, const XMLCh* qualifiedName) 00205 { 00206 DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *)fParent.fOwnerDocument; 00207 const XMLCh * xmlns = DOMNodeImpl::getXmlnsString(); 00208 const XMLCh * xmlnsURI = DOMNodeImpl::getXmlnsURIString(); 00209 this->fName = ownerDoc->getPooledString(qualifiedName); 00210 00211 int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName); 00212 if (index < 0) 00213 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00214 00215 bool xmlnsAlone = false; //true if attribute name is "xmlns" 00216 if (index == 0) 00217 { //qualifiedName contains no ':' 00218 if (XMLString::equals(this->fName, xmlns)) { 00219 if (!XMLString::equals(namespaceURI, xmlnsURI)) 00220 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00221 xmlnsAlone = true; 00222 } 00223 fPrefix = 0; 00224 fLocalName = fName; 00225 } 00226 else 00227 { 00228 fPrefix = ownerDoc->getPooledNString(fName, index); 00229 fLocalName = ownerDoc->getPooledString(fName+index+1); 00230 00231 // Before we carry on, we should check if the prefix or localName are valid XMLName 00232 if (!ownerDoc->isXMLName(fPrefix) || !ownerDoc->isXMLName(fLocalName)) 00233 throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager); 00234 } 00235 00236 // DOM Level 3: namespace URI is never empty string. 00237 const XMLCh * URI = xmlnsAlone ? xmlnsURI 00238 : DOMNodeImpl::mapPrefix 00239 ( 00240 fPrefix, 00241 (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI, 00242 DOMNode::ATTRIBUTE_NODE 00243 ); 00244 this -> fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI); 00245 } 00246 00247 XERCES_CPP_NAMESPACE_END