GME  13
DOMElementNSImpl.cpp
Go to the documentation of this file.
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: DOMElementNSImpl.cpp 678709 2008-07-22 10:56:56Z borisk $
00020  */
00021 
00022 #include <xercesc/util/XMLUniDefs.hpp>
00023 #include "DOMElementNSImpl.hpp"
00024 #include "DOMDocumentImpl.hpp"
00025 #include "DOMTypeInfoImpl.hpp"
00026 #include "DOMCasts.hpp"
00027 #include <xercesc/dom/DOMException.hpp>
00028 #include <xercesc/util/XMLUri.hpp>
00029 #include <xercesc/util/OutOfMemoryException.hpp>
00030 
00031 XERCES_CPP_NAMESPACE_BEGIN
00032 
00033 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
00034     DOMElementImpl(ownerDoc, nam)
00035 {
00036     this->fNamespaceURI=0;        //DOM Level 2
00037     this->fLocalName=0;       //DOM Level 2
00038     this->fPrefix=0;
00039     this->fSchemaType = 0;
00040 }
00041 
00042 //Introduced in DOM Level 2
00043 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc,
00044                                    const XMLCh *namespaceURI,
00045                                    const XMLCh *qualifiedName) :
00046     DOMElementImpl(ownerDoc, qualifiedName)
00047 {
00048   setName(namespaceURI, qualifiedName);
00049   this->fSchemaType = 0;
00050 }
00051 
00052 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc,
00053                                    const XMLCh *namespaceURI,
00054                                    const XMLCh *prefix,
00055                                    const XMLCh *localName,
00056                                    const XMLCh *qualifiedName)
00057     : DOMElementImpl(ownerDoc, qualifiedName)
00058 {
00059   this->fSchemaType = 0;
00060 
00061   DOMDocumentImpl* docImpl = (DOMDocumentImpl*)fParent.fOwnerDocument;
00062 
00063   if (prefix == 0 || *prefix == 0)
00064   {
00065     fPrefix = 0;
00066     fLocalName = fName;
00067   }
00068   else
00069   {
00070     fPrefix = docImpl->getPooledString(prefix);
00071     fLocalName = docImpl->getPooledString(localName);
00072   }
00073 
00074   // DOM Level 3: namespace URI is never empty string.
00075   //
00076   const XMLCh * URI = DOMNodeImpl::mapPrefix (
00077     fPrefix,
00078     (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
00079     DOMNode::ELEMENT_NODE);
00080 
00081   fNamespaceURI = (URI == 0) ? 0 : docImpl->getPooledString(URI);
00082 }
00083 
00084 DOMElementNSImpl::DOMElementNSImpl(const DOMElementNSImpl &other, bool deep) :
00085     DOMElementImpl(other, deep)
00086 {
00087     this->fNamespaceURI = other.fNamespaceURI;          //DOM Level 2
00088     this->fLocalName = other.fLocalName;                //DOM Level 2
00089     this->fPrefix = other.fPrefix;
00090     this->fSchemaType = other.fSchemaType;
00091 }
00092 
00093 DOMNode * DOMElementNSImpl::cloneNode(bool deep) const {
00094     DOMNode* newNode = new (fParent.fOwnerDocument, DOMMemoryManager::ELEMENT_NS_OBJECT) DOMElementNSImpl(*this, deep);
00095     fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
00096     return newNode;
00097 }
00098 
00099 const XMLCh * DOMElementNSImpl::getNamespaceURI() const
00100 {
00101     return fNamespaceURI;
00102 }
00103 
00104 const XMLCh * DOMElementNSImpl::getPrefix() const
00105 {
00106     return fPrefix;
00107 }
00108 
00109 
00110 const XMLCh * DOMElementNSImpl::getLocalName() const
00111 {
00112     return fLocalName;
00113 }
00114 
00115 void DOMElementNSImpl::setPrefix(const XMLCh *prefix)
00116 {
00117     if (fNode.isReadOnly())
00118         throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
00119     if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull)
00120         throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
00121 
00122     if (prefix == 0 || *prefix == 0) {
00123         fPrefix = 0;
00124         fName = fLocalName;
00125         return;
00126     }
00127 
00128     DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
00129 
00130     if(!doc->isXMLName(prefix))
00131         throw DOMException(DOMException::INVALID_CHARACTER_ERR,0, GetDOMNodeMemoryManager);
00132 
00133     const XMLCh * xml      = DOMNodeImpl::getXmlString();
00134     const XMLCh * xmlURI   = DOMNodeImpl::getXmlURIString();
00135 
00136     if (XMLString::equals(prefix, xml) &&
00137         !XMLString::equals(fNamespaceURI, xmlURI))
00138         throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
00139 
00140 
00141     if (XMLString::indexOf(prefix, chColon) != -1) {
00142         throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
00143     }
00144 
00145     this-> fPrefix = doc->getPooledString(prefix);
00146 
00147     XMLSize_t prefixLen = XMLString::stringLen(prefix);
00148     XMLSize_t newQualifiedNameLen = prefixLen+1+XMLString::stringLen(fLocalName);
00149 
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 DOMElementNSImpl::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::ELEMENT_NS_OBJECT);
00182     }
00183     else {
00184         // shouldn't reach here
00185         throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
00186     }
00187 }
00188 
00189 DOMNode* DOMElementNSImpl::rename(const XMLCh* namespaceURI, const XMLCh* name)
00190 {
00191     setName(namespaceURI, name);
00192     fAttributes->reconcileDefaultAttributes(getDefaultAttributes());
00193     // and fire user data NODE_RENAMED event
00194     castToNodeImpl(this)->callUserDataHandlers(DOMUserDataHandler::NODE_RENAMED, this, this);
00195 
00196     return this;
00197 }
00198 
00199 void DOMElementNSImpl::setName(const XMLCh *namespaceURI,
00200                                const XMLCh *qualifiedName)
00201 {
00202     DOMDocumentImpl* ownerDoc = (DOMDocumentImpl *) fParent.fOwnerDocument;
00203     this->fName = ownerDoc->getPooledString(qualifiedName);
00204 
00205     int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
00206     if (index < 0)
00207         throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
00208 
00209     if (index == 0)
00210     {
00211         //qualifiedName contains no ':'
00212         //
00213         fPrefix = 0;
00214         fLocalName = fName;
00215     }
00216     else
00217     {   //0 < index < this->name.length()-1
00218         //
00219         fPrefix = ownerDoc->getPooledNString(qualifiedName, index);
00220         fLocalName = ownerDoc->getPooledString(fName+index+1);
00221 
00222         // Before we carry on, we should check if the prefix or localName are valid XMLName
00223         if (!ownerDoc->isXMLName(fPrefix) || !ownerDoc->isXMLName(fLocalName))
00224           throw DOMException(DOMException::NAMESPACE_ERR, 0, GetDOMNodeMemoryManager);
00225     }
00226 
00227     // DOM Level 3: namespace URI is never empty string.
00228     //
00229     const XMLCh * URI = DOMNodeImpl::mapPrefix (
00230       fPrefix,
00231       (!namespaceURI || !*namespaceURI) ? 0 : namespaceURI,
00232       DOMNode::ELEMENT_NODE);
00233 
00234     fNamespaceURI = (URI == 0) ? 0 : ownerDoc->getPooledString(URI);
00235 }
00236 
00237 const DOMTypeInfo *DOMElementNSImpl::getSchemaTypeInfo() const
00238 {
00239     if(!fSchemaType)
00240         return &DOMTypeInfoImpl::g_DtdValidatedElement;
00241     return fSchemaType;
00242 }
00243 
00244 void DOMElementNSImpl::setSchemaTypeInfo(const DOMTypeInfoImpl* typeInfo)
00245 {
00246     fSchemaType = typeInfo;
00247 }
00248 
00249 bool DOMElementNSImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
00250 {
00251     // check for '+DOMPSVITypeInfo'
00252     if(feature && *feature=='+' && XMLString::equals(feature+1, XMLUni::fgXercescInterfacePSVITypeInfo))
00253         return true;
00254     return fNode.isSupported (feature, version);
00255 }
00256 
00257 void* DOMElementNSImpl::getFeature(const XMLCh* feature, const XMLCh* version) const
00258 {
00259     if(XMLString::equals(feature, XMLUni::fgXercescInterfacePSVITypeInfo))
00260         return (DOMPSVITypeInfo*)fSchemaType;
00261     return DOMElementImpl::getFeature(feature, version);
00262 }
00263 
00264 XERCES_CPP_NAMESPACE_END