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