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 /** Attention: stl headers must(!) be included at first. Otherwise it can make trouble
28                with solaris headers ...
29 */
30 #include <vector>
31 
32 #include <stdio.h>
33 
34 #include <xml/saxnamespacefilter.hxx>
35 
36 #include <comphelper/attributelist.hxx>
37 
38 #include <vcl/svapp.hxx>
39 #include <rtl/logfile.hxx>
40 
41 using namespace ::com::sun::star::xml::sax;
42 using namespace ::com::sun::star::uno;
43 
44 const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
45 const ::rtl::OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ));
46 
47 namespace framework{
48 
49 
SaxNamespaceFilter(Reference<XDocumentHandler> & rSax1DocumentHandler)50 SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) :
51 	ThreadHelpBase( &Application::GetSolarMutex() ),
52 	 m_xLocator( 0 ),
53 	 xDocumentHandler( rSax1DocumentHandler ),
54 	 m_nDepth( 0 )
55 {
56 }
57 
~SaxNamespaceFilter()58 SaxNamespaceFilter::~SaxNamespaceFilter()
59 {
60 }
61 
62 // XDocumentHandler
startDocument(void)63 void SAL_CALL SaxNamespaceFilter::startDocument(void)
64 	throw (	SAXException, RuntimeException )
65 {
66 }
67 
endDocument(void)68 void SAL_CALL SaxNamespaceFilter::endDocument(void)
69 	throw(	SAXException, RuntimeException )
70 {
71 }
72 
startElement(const rtl::OUString & rName,const Reference<XAttributeList> & xAttribs)73 void SAL_CALL SaxNamespaceFilter::startElement(
74 	const rtl::OUString& rName, const Reference< XAttributeList > &xAttribs )
75 	throw(	SAXException, RuntimeException )
76 {
77 	XMLNamespaces aXMLNamespaces;
78 	if ( !m_aNamespaceStack.empty() )
79 		aXMLNamespaces = m_aNamespaceStack.top();
80 
81 	::comphelper::AttributeList* pNewList = new ::comphelper::AttributeList();
82 
83 	// examine all namespaces for this level
84 	::std::vector< sal_Int16 > aAttributeIndexes;
85 	{
86 		for ( sal_Int16 i=0; i< xAttribs->getLength(); i++ )
87 		{
88 			::rtl::OUString aName = xAttribs->getNameByIndex( i );
89 			if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 )
90 				aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i ));
91 			else
92 				aAttributeIndexes.push_back( i );
93 		}
94 	}
95 
96 	// current namespaces for this level
97 	m_aNamespaceStack.push( aXMLNamespaces );
98 
99 	try
100 	{
101 		// apply namespaces to all remaining attributes
102 		for ( ::std::vector< sal_Int16 >::const_iterator i(
103 				aAttributeIndexes.begin());
104 			  i != aAttributeIndexes.end(); ++i )
105 		{
106 			::rtl::OUString aAttributeName			 = xAttribs->getNameByIndex( *i );
107 			::rtl::OUString aValue					 = xAttribs->getValueByIndex( *i );
108 			::rtl::OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName );
109 			pNewList->AddAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue );
110 		}
111 	}
112 	catch ( SAXException& e )
113 	{
114 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
115 		throw e;
116 	}
117 
118 	::rtl::OUString aNamespaceElementName;
119 
120 	try
121 	{
122 		 aNamespaceElementName = aXMLNamespaces.applyNSToElementName( rName );
123 	}
124 	catch ( SAXException& e )
125 	{
126 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
127 		throw e;
128 	}
129 
130 	xDocumentHandler->startElement( aNamespaceElementName, pNewList );
131 }
132 
endElement(const rtl::OUString & aName)133 void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName)
134 	throw(	SAXException, RuntimeException )
135 {
136 	XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top();
137 	::rtl::OUString aNamespaceElementName;
138 
139 	try
140 	{
141 		aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
142 	}
143 	catch ( SAXException& e )
144 	{
145 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
146 		throw e;
147 	}
148 
149 	xDocumentHandler->endElement( aNamespaceElementName );
150 	m_aNamespaceStack.pop();
151 }
152 
characters(const rtl::OUString & aChars)153 void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars)
154 	throw(	SAXException, RuntimeException )
155 {
156 	xDocumentHandler->characters( aChars );
157 }
158 
ignorableWhitespace(const rtl::OUString & aWhitespaces)159 void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces)
160 	throw(	SAXException, RuntimeException )
161 {
162 	xDocumentHandler->ignorableWhitespace( aWhitespaces );
163 }
164 
processingInstruction(const rtl::OUString & aTarget,const rtl::OUString & aData)165 void SAL_CALL SaxNamespaceFilter::processingInstruction(
166 	const rtl::OUString& aTarget, const rtl::OUString& aData)
167 	throw(	SAXException, RuntimeException )
168 {
169 	xDocumentHandler->processingInstruction( aTarget, aData );
170 }
171 
setDocumentLocator(const Reference<XLocator> & xLocator)172 void SAL_CALL SaxNamespaceFilter::setDocumentLocator(
173 	const Reference< XLocator > &xLocator)
174 	throw(	SAXException, RuntimeException )
175 {
176 	m_xLocator = xLocator;
177 	xDocumentHandler->setDocumentLocator( xLocator );
178 }
179 
getErrorLineString()180 ::rtl::OUString SaxNamespaceFilter::getErrorLineString()
181 {
182 	char buffer[32];
183 
184 	if ( m_xLocator.is() )
185 	{
186 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
187 		return ::rtl::OUString::createFromAscii( buffer );
188 	}
189 	else
190 		return ::rtl::OUString();
191 }
192 
193 } // namespace
194