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