xref: /AOO41X/main/framework/source/fwe/xml/xmlnamespaces.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include <xml/xmlnamespaces.hxx>
28 
29 using namespace ::com::sun::star::xml::sax;
30 using namespace ::com::sun::star::uno;
31 
32 const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
33 
34 namespace framework
35 {
36 
XMLNamespaces()37 XMLNamespaces::XMLNamespaces()
38 {
39 }
40 
XMLNamespaces(const XMLNamespaces & aXMLNamespaces)41 XMLNamespaces::XMLNamespaces( const XMLNamespaces& aXMLNamespaces )
42 {
43     m_aDefaultNamespace = aXMLNamespaces.m_aDefaultNamespace;
44     m_aNamespaceMap = aXMLNamespaces.m_aNamespaceMap;
45 }
46 
~XMLNamespaces()47 XMLNamespaces::~XMLNamespaces()
48 {
49 }
50 
addNamespace(const::rtl::OUString & aName,const::rtl::OUString & aValue)51 void XMLNamespaces::addNamespace( const ::rtl::OUString& aName, const ::rtl::OUString& aValue ) throw( SAXException )
52 {
53     NamespaceMap::iterator p;
54     ::rtl::OUString aNamespaceName( aName );
55     sal_Int32 nXMLNamespaceLength = aXMLAttributeNamespace.getLength();
56 
57     // delete preceding "xmlns"
58     if ( aNamespaceName.compareTo( aXMLAttributeNamespace, nXMLNamespaceLength ) == 0 )
59     {
60         if ( aNamespaceName.getLength() == nXMLNamespaceLength )
61         {
62             aNamespaceName = ::rtl::OUString();
63         }
64         else if ( aNamespaceName.getLength() >= nXMLNamespaceLength+2 )
65         {
66             aNamespaceName = aNamespaceName.copy( nXMLNamespaceLength+1 );
67         }
68         else
69         {
70             // a xml namespace without name is not allowed (e.g. "xmlns:" )
71             ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "A xml namespace without name is not allowed!" ));
72             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
73         }
74     }
75 
76     if ( aValue.getLength() == 0 && aNamespaceName.getLength() > 0 )
77     {
78         // namespace should be reseted - as xml draft states this is only allowed
79         // for the default namespace - check and throw exception if check fails
80         ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Clearing xml namespace only allowed for default namespace!" ));
81         throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
82     }
83     else
84     {
85         if ( aNamespaceName.getLength() == 0 )
86             m_aDefaultNamespace = aValue;
87         else
88         {
89             p = m_aNamespaceMap.find( aNamespaceName );
90             if ( p != m_aNamespaceMap.end() )
91             {
92                 // replace current namespace definition
93                 m_aNamespaceMap.erase( p );
94                 m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
95             }
96             else
97             {
98                 m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
99             }
100         }
101     }
102 }
103 
applyNSToAttributeName(const::rtl::OUString & aName) const104 ::rtl::OUString XMLNamespaces::applyNSToAttributeName( const ::rtl::OUString& aName ) const throw( SAXException )
105 {
106     // xml draft: there is no default namespace for attributes!
107 
108     int index;
109     if (( index = aName.indexOf( ':' )) > 0 )
110     {
111         if ( aName.getLength() > index+1 )
112         {
113             ::rtl::OUString aAttributeName = getNamespaceValue( aName.copy( 0, index ) );
114             aAttributeName += ::rtl::OUString::createFromAscii( "^" );
115             aAttributeName += aName.copy( index+1 );
116             return aAttributeName;
117         }
118         else
119         {
120             // attribute with namespace but without name "namespace:" is not allowed!!
121             ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
122             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
123         }
124     }
125 
126     return aName;
127 }
128 
applyNSToElementName(const::rtl::OUString & aName) const129 ::rtl::OUString XMLNamespaces::applyNSToElementName( const ::rtl::OUString& aName ) const   throw( SAXException )
130 {
131     // xml draft: element names can have a default namespace
132 
133     int         index = aName.indexOf( ':' );
134     ::rtl::OUString aNamespace;
135     ::rtl::OUString aElementName = aName;
136 
137     if ( index > 0 )
138         aNamespace = getNamespaceValue( aName.copy( 0, index ) );
139     else
140         aNamespace = m_aDefaultNamespace;
141 
142     if ( aNamespace.getLength() > 0 )
143     {
144         aElementName = aNamespace;
145         aElementName += ::rtl::OUString::createFromAscii( "^" );
146     }
147     else
148         return aName;
149 
150     if ( index > 0 )
151     {
152         if ( aName.getLength() > index+1 )
153             aElementName += aName.copy( index+1 );
154         else
155         {
156             // attribute with namespace but without a name is not allowed (e.g. "cfg:" )
157             ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
158             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
159         }
160     }
161     else
162         aElementName += aName;
163 
164     return aElementName;
165 }
166 
getNamespaceValue(const::rtl::OUString & aNamespace) const167 ::rtl::OUString XMLNamespaces::getNamespaceValue( const ::rtl::OUString& aNamespace ) const throw( SAXException )
168 {
169     if ( aNamespace.getLength() == 0 )
170         return m_aDefaultNamespace;
171     else
172     {
173         NamespaceMap::const_iterator p;
174         p = m_aNamespaceMap.find( aNamespace );
175         if ( p != m_aNamespaceMap.end() )
176             return p->second;
177         else
178         {
179             // namespace not defined => throw exception!
180             ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "XML namespace used but not defined!" ));
181             throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
182         }
183     }
184 }
185 
186 }
187 
188