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