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