xref: /AOO41X/main/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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 namepspace 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 //      // completly and therfor 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