1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 /** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
32                with solaris headers ...
33 */
34 #include <vector>
35 
36 #include <stdio.h>
37 
38 #include <xml/saxnamespacefilter.hxx>
39 
40 #include <comphelper/attributelist.hxx>
41 
42 #include <vcl/svapp.hxx>
43 #include <rtl/logfile.hxx>
44 
45 using namespace ::com::sun::star::xml::sax;
46 using namespace ::com::sun::star::uno;
47 
48 const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
49 const ::rtl::OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ));
50 
51 namespace framework{
52 
53 
54 SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) :
55     ThreadHelpBase( &Application::GetSolarMutex() ),
56      m_xLocator( 0 ),
57      xDocumentHandler( rSax1DocumentHandler ),
58      m_nDepth( 0 )
59 {
60 }
61 
62 SaxNamespaceFilter::~SaxNamespaceFilter()
63 {
64 }
65 
66 // XDocumentHandler
67 void SAL_CALL SaxNamespaceFilter::startDocument(void)
68 	throw (	SAXException, RuntimeException )
69 {
70 }
71 
72 void SAL_CALL SaxNamespaceFilter::endDocument(void)
73 	throw(	SAXException, RuntimeException )
74 {
75 }
76 
77 void SAL_CALL SaxNamespaceFilter::startElement(
78 	const rtl::OUString& rName, const Reference< XAttributeList > &xAttribs )
79 	throw(	SAXException, RuntimeException )
80 {
81 	XMLNamespaces aXMLNamespaces;
82 	if ( !m_aNamespaceStack.empty() )
83 		aXMLNamespaces = m_aNamespaceStack.top();
84 
85 	::comphelper::AttributeList* pNewList = new ::comphelper::AttributeList();
86 
87 	// examine all namespaces for this level
88 	::std::vector< sal_Int16 > aAttributeIndexes;
89 	{
90 		for ( sal_Int16 i=0; i< xAttribs->getLength(); i++ )
91 		{
92 			::rtl::OUString aName = xAttribs->getNameByIndex( i );
93 			if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 )
94 				aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i ));
95 			else
96 				aAttributeIndexes.push_back( i );
97 		}
98 	}
99 
100 	// current namespaces for this level
101 	m_aNamespaceStack.push( aXMLNamespaces );
102 
103 	try
104 	{
105 		// apply namespaces to all remaing attributes
106 		for ( ::std::vector< sal_Int16 >::const_iterator i(
107                   aAttributeIndexes.begin());
108               i != aAttributeIndexes.end(); ++i )
109 		{
110 			::rtl::OUString aAttributeName			 = xAttribs->getNameByIndex( *i );
111 			::rtl::OUString aValue					 = xAttribs->getValueByIndex( *i );
112 			::rtl::OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName );
113 			pNewList->AddAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue );
114 		}
115 	}
116 	catch ( SAXException& e )
117 	{
118 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
119 		throw e;
120 	}
121 
122 	::rtl::OUString aNamespaceElementName;
123 
124 	try
125 	{
126 		 aNamespaceElementName = aXMLNamespaces.applyNSToElementName( rName );
127 	}
128 	catch ( SAXException& e )
129 	{
130 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
131 		throw e;
132 	}
133 
134 	xDocumentHandler->startElement( aNamespaceElementName, pNewList );
135 }
136 
137 void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName)
138 	throw(	SAXException, RuntimeException )
139 {
140 	XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top();
141 	::rtl::OUString aNamespaceElementName;
142 
143 	try
144 	{
145 		aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
146 	}
147 	catch ( SAXException& e )
148 	{
149 		e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
150 		throw e;
151 	}
152 
153 	xDocumentHandler->endElement( aNamespaceElementName );
154 	m_aNamespaceStack.pop();
155 }
156 
157 void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars)
158 	throw(	SAXException, RuntimeException )
159 {
160 	xDocumentHandler->characters( aChars );
161 }
162 
163 void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces)
164 	throw(	SAXException, RuntimeException )
165 {
166 	xDocumentHandler->ignorableWhitespace( aWhitespaces );
167 }
168 
169 void SAL_CALL SaxNamespaceFilter::processingInstruction(
170 	const rtl::OUString& aTarget, const rtl::OUString& aData)
171 	throw(	SAXException, RuntimeException )
172 {
173 	xDocumentHandler->processingInstruction( aTarget, aData );
174 }
175 
176 void SAL_CALL SaxNamespaceFilter::setDocumentLocator(
177 	const Reference< XLocator > &xLocator)
178 	throw(	SAXException, RuntimeException )
179 {
180 	m_xLocator = xLocator;
181 	xDocumentHandler->setDocumentLocator( xLocator );
182 }
183 
184 ::rtl::OUString SaxNamespaceFilter::getErrorLineString()
185 {
186 	char buffer[32];
187 
188 	if ( m_xLocator.is() )
189 	{
190 		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
191 		return ::rtl::OUString::createFromAscii( buffer );
192 	}
193 	else
194 		return ::rtl::OUString();
195 }
196 
197 } // namespace
198 
199