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_xmloff.hxx"
26 #include <com/sun/star/document/XImporter.hpp>
27 #include <com/sun/star/util/XModifiable.hpp>
28 #include <com/sun/star/util/XModifiable2.hpp>
29 #include <com/sun/star/frame/XStorable.hpp>
30
31 // #110680#
32 //#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
33 //#include <comphelper/processfactory.hxx>
34 //#endif
35 #include <tools/globname.hxx>
36 #include <sot/clsids.hxx>
37 #include <tools/globname.hxx>
38 #include <sot/clsids.hxx>
39 #include <xmloff/nmspmap.hxx>
40 #include <xmloff/xmlimp.hxx>
41 #include "xmloff/xmlnmspe.hxx"
42 #include <xmloff/xmltoken.hxx>
43 #include "xmloff/xmlerror.hxx"
44 #include <xmloff/attrlist.hxx>
45 #include "xmloff/XMLFilterServiceNames.h"
46 #include "XMLEmbeddedObjectImportContext.hxx"
47
48 using ::rtl::OUString;
49 using ::rtl::OUStringBuffer;
50
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::util;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::frame;
56 using namespace ::com::sun::star::document;
57 using namespace ::com::sun::star::xml::sax;
58 using namespace ::xmloff::token;
59
60 struct XMLServiceMapEntry_Impl
61 {
62 enum XMLTokenEnum eClass;
63 const sal_Char *sFilterService;
64 sal_Int32 nFilterServiceLen;
65 };
66
67 #define SERVICE_MAP_ENTRY( cls, app ) \
68 { XML_##cls, \
69 XML_IMPORT_FILTER_##app, sizeof(XML_IMPORT_FILTER_##app)-1}
70
71 const XMLServiceMapEntry_Impl aServiceMap[] =
72 {
73 SERVICE_MAP_ENTRY( TEXT, WRITER ),
74 SERVICE_MAP_ENTRY( ONLINE_TEXT, WRITER ),
75 SERVICE_MAP_ENTRY( SPREADSHEET, CALC ),
76 SERVICE_MAP_ENTRY( DRAWING, DRAW ),
77 SERVICE_MAP_ENTRY( GRAPHICS, DRAW ),
78 SERVICE_MAP_ENTRY( PRESENTATION, IMPRESS ),
79 SERVICE_MAP_ENTRY( CHART, CHART ),
80 { XML_TOKEN_INVALID, 0, 0 }
81 };
82
83 class XMLEmbeddedObjectImportContext_Impl : public SvXMLImportContext
84 {
85 ::com::sun::star::uno::Reference<
86 ::com::sun::star::xml::sax::XDocumentHandler > xHandler;
87
88 public:
89 TYPEINFO();
90
91 XMLEmbeddedObjectImportContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
92 const ::rtl::OUString& rLName,
93 const ::com::sun::star::uno::Reference<
94 ::com::sun::star::xml::sax::XDocumentHandler >& rHandler );
95
96 virtual ~XMLEmbeddedObjectImportContext_Impl();
97
98 virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
99 const ::rtl::OUString& rLocalName,
100 const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
101
102 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
103
104 virtual void EndElement();
105
106 virtual void Characters( const ::rtl::OUString& rChars );
107 };
108
109 TYPEINIT1( XMLEmbeddedObjectImportContext_Impl, SvXMLImportContext );
110
XMLEmbeddedObjectImportContext_Impl(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName,const Reference<XDocumentHandler> & rHandler)111 XMLEmbeddedObjectImportContext_Impl::XMLEmbeddedObjectImportContext_Impl(
112 SvXMLImport& rImport, sal_uInt16 nPrfx,
113 const OUString& rLName,
114 const Reference< XDocumentHandler >& rHandler ) :
115 SvXMLImportContext( rImport, nPrfx, rLName ),
116 xHandler( rHandler )
117 {
118 }
119
~XMLEmbeddedObjectImportContext_Impl()120 XMLEmbeddedObjectImportContext_Impl::~XMLEmbeddedObjectImportContext_Impl()
121 {
122 }
123
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<XAttributeList> &)124 SvXMLImportContext *XMLEmbeddedObjectImportContext_Impl::CreateChildContext(
125 sal_uInt16 nPrefix,
126 const OUString& rLocalName,
127 const Reference< XAttributeList >& )
128 {
129 return new XMLEmbeddedObjectImportContext_Impl( GetImport(),
130 nPrefix, rLocalName,
131 xHandler );
132 }
133
StartElement(const Reference<XAttributeList> & xAttrList)134 void XMLEmbeddedObjectImportContext_Impl::StartElement(
135 const Reference< XAttributeList >& xAttrList )
136 {
137 xHandler->startElement( GetImport().GetNamespaceMap().GetQNameByKey(
138 GetPrefix(), GetLocalName() ),
139 xAttrList );
140 }
141
EndElement()142 void XMLEmbeddedObjectImportContext_Impl::EndElement()
143 {
144 xHandler->endElement( GetImport().GetNamespaceMap().GetQNameByKey(
145 GetPrefix(), GetLocalName() ) );
146 }
147
Characters(const OUString & rChars)148 void XMLEmbeddedObjectImportContext_Impl::Characters( const OUString& rChars )
149 {
150 xHandler->characters( rChars );
151 }
152
153 //-----------------------------------------------------------------------------
154
155 TYPEINIT1( XMLEmbeddedObjectImportContext, SvXMLImportContext );
156
SetComponent(Reference<XComponent> & rComp)157 sal_Bool XMLEmbeddedObjectImportContext::SetComponent(
158 Reference< XComponent >& rComp )
159 {
160 if( !rComp.is() || !sFilterService.getLength() )
161 return sal_False;
162
163
164 Sequence<Any> aArgs( 0 );
165
166 // #110680#
167 // Reference< XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory();
168 Reference< XMultiServiceFactory > xServiceFactory = GetImport().getServiceFactory();
169
170 xHandler = Reference < XDocumentHandler >(
171 xServiceFactory->createInstanceWithArguments( sFilterService, aArgs),
172 UNO_QUERY);
173
174 if( !xHandler.is() )
175 return sal_False;
176
177 try
178 {
179 Reference < XModifiable2 > xModifiable2( rComp, UNO_QUERY_THROW );
180 xModifiable2->disableSetModified();
181 }
182 catch( Exception& )
183 {
184 }
185
186 Reference < XImporter > xImporter( xHandler, UNO_QUERY );
187 xImporter->setTargetDocument( rComp );
188
189 xComp = rComp; // keep ref to component only if there is a handler
190
191 return sal_True;
192 }
193
XMLEmbeddedObjectImportContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName,const Reference<XAttributeList> & xAttrList)194 XMLEmbeddedObjectImportContext::XMLEmbeddedObjectImportContext(
195 SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
196 const Reference< XAttributeList >& xAttrList ) :
197 SvXMLImportContext( rImport, nPrfx, rLName )
198 {
199 SvGlobalName aName;
200
201 if( nPrfx == XML_NAMESPACE_MATH &&
202 IsXMLToken( rLName, XML_MATH ) )
203 {
204 sFilterService = OUString( RTL_CONSTASCII_USTRINGPARAM(XML_IMPORT_FILTER_MATH) );
205 aName = SvGlobalName(SO3_SM_CLASSID);
206 }
207 else if( nPrfx == XML_NAMESPACE_OFFICE &&
208 IsXMLToken( rLName, XML_DOCUMENT ) )
209 {
210 OUString sMime;
211
212 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
213 for( sal_Int16 i=0; i < nAttrCount; i++ )
214 {
215 const OUString& rAttrName = xAttrList->getNameByIndex( i );
216 OUString aLocalName;
217 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
218 if( nPrefix == XML_NAMESPACE_OFFICE &&
219 IsXMLToken( aLocalName, XML_MIMETYPE ) )
220 {
221 sMime = xAttrList->getValueByIndex( i );
222 break;
223 }
224 }
225
226 OUString sClass;
227 static const char * aTmp[] =
228 {
229 "application/vnd.oasis.openoffice.",
230 "application/x-vnd.oasis.openoffice.",
231 "application/vnd.oasis.opendocument.",
232 "application/x-vnd.oasis.opendocument.",
233 NULL
234 };
235 for (int k=0; aTmp[k]; k++)
236 {
237 ::rtl::OUString sTmpString = ::rtl::OUString::createFromAscii(aTmp[k]);
238 if( sMime.matchAsciiL( aTmp[k], sTmpString.getLength() ) )
239 {
240 sClass = sMime.copy( sTmpString.getLength() );
241 break;
242 }
243 }
244
245 if( sClass.getLength() )
246 {
247 const XMLServiceMapEntry_Impl *pEntry = aServiceMap;
248 while( pEntry->eClass != XML_TOKEN_INVALID )
249 {
250 if( IsXMLToken( sClass, pEntry->eClass ) )
251 {
252 sFilterService = OUString( pEntry->sFilterService,
253 pEntry->nFilterServiceLen,
254 RTL_TEXTENCODING_ASCII_US );
255
256 switch( pEntry->eClass )
257 {
258 case XML_TEXT: aName = SvGlobalName(SO3_SW_CLASSID); break;
259 case XML_ONLINE_TEXT: aName = SvGlobalName(SO3_SWWEB_CLASSID); break;
260 case XML_SPREADSHEET: aName = SvGlobalName(SO3_SC_CLASSID); break;
261 case XML_DRAWING:
262 case XML_GRAPHICS:
263 case XML_IMAGE: aName = SvGlobalName(SO3_SDRAW_CLASSID); break;
264 case XML_PRESENTATION: aName = SvGlobalName(SO3_SIMPRESS_CLASSID); break;
265 case XML_CHART: aName = SvGlobalName(SO3_SCH_CLASSID); break;
266 default:
267 break;
268 }
269
270 break;
271 }
272 pEntry++;
273 }
274 }
275 }
276
277 sCLSID = aName.GetHexName();
278 }
279
~XMLEmbeddedObjectImportContext()280 XMLEmbeddedObjectImportContext::~XMLEmbeddedObjectImportContext()
281 {
282 }
283
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<XAttributeList> &)284 SvXMLImportContext *XMLEmbeddedObjectImportContext::CreateChildContext(
285 sal_uInt16 nPrefix, const OUString& rLocalName,
286 const Reference< XAttributeList >& )
287 {
288 if( xHandler.is() )
289 return new XMLEmbeddedObjectImportContext_Impl( GetImport(),
290 nPrefix, rLocalName,
291 xHandler );
292 else
293 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
294 }
295
StartElement(const Reference<XAttributeList> & rAttrList)296 void XMLEmbeddedObjectImportContext::StartElement(
297 const Reference< XAttributeList >& rAttrList )
298 {
299 if( xHandler.is() )
300 {
301 xHandler->startDocument();
302 // #i34042: copy namespace declarations
303 SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList );
304 Reference< XAttributeList > xAttrList( pAttrList );
305 const SvXMLNamespaceMap& rNamespaceMap = GetImport().GetNamespaceMap();
306 sal_uInt16 nPos = rNamespaceMap.GetFirstKey();
307 while( USHRT_MAX != nPos )
308 {
309 OUString aAttrName( rNamespaceMap.GetAttrNameByKey( nPos ) );
310 if( 0 == xAttrList->getValueByName( aAttrName ).getLength() )
311 {
312 pAttrList->AddAttribute( aAttrName,
313 rNamespaceMap.GetNameByKey( nPos ) );
314 }
315 nPos = rNamespaceMap.GetNextKey( nPos );
316 }
317 xHandler->startElement( GetImport().GetNamespaceMap().GetQNameByKey(
318 GetPrefix(), GetLocalName() ),
319 xAttrList );
320 }
321 }
322
EndElement()323 void XMLEmbeddedObjectImportContext::EndElement()
324 {
325 if( xHandler.is() )
326 {
327 xHandler->endElement( GetImport().GetNamespaceMap().GetQNameByKey(
328 GetPrefix(), GetLocalName() ) );
329 xHandler->endDocument();
330
331
332 // storing part is commented out since it should be done through the object, not the model
333 // TODO/LATER: probably an object should be provided here an be stored here
334
335 // // Save the object. That's required because the object should not be
336 // // modified (it has been loaded just now). Setting it to unmodified
337 // // only does not work, because it is then assumed that it has been
338 // // stored.
339 // Reference < XStorable > xStorable( xComp, UNO_QUERY );
340 // if( xStorable.is() )
341 // {
342 // try
343 // {
344 // xStorable->store();
345 // }
346 // catch( ::com::sun::star::beans::PropertyVetoException& )
347 // {
348 // Sequence<OUString> aSeq( 0 );
349 // GetImport().SetError( XMLERROR_FLAG_WARNING |
350 // XMLERROR_API,
351 // aSeq );
352 // }
353 // }
354
355 try
356 {
357 Reference < XModifiable2 > xModifiable2( xComp, UNO_QUERY_THROW );
358 xModifiable2->enableSetModified();
359 xModifiable2->setModified( sal_True ); // trigger new replacement image generation
360 }
361 catch( Exception& )
362 {
363 }
364
365
366 // // reset modifies state for the object since it has been imported
367 // // completely and therefor hasn't been modified.
368 // Reference < XModifiable > xModifiable( xComp, UNO_QUERY );
369 // if( xModifiable.is() )
370 // {
371 // try
372 // {
373 // xModifiable->setModified( sal_False );
374 // }
375 // catch( ::com::sun::star::beans::PropertyVetoException& e )
376 // {
377 // Sequence<OUString> aSeq( 0 );
378 // GetImport().SetError( XMLERROR_FLAG_WARNING |
379 // XMLERROR_API,
380 // aSeq );
381 // }
382 // }
383 }
384 }
385
Characters(const::rtl::OUString & rChars)386 void XMLEmbeddedObjectImportContext::Characters( const ::rtl::OUString& rChars )
387 {
388 if( xHandler.is() )
389 xHandler->characters( rChars );
390 }
391
392