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_comphelper.hxx" 30 #include <comphelper/mediadescriptor.hxx> 31 #include <comphelper/namedvaluecollection.hxx> 32 #include <comphelper/stillreadwriteinteraction.hxx> 33 34 #include <com/sun/star/ucb/XContent.hpp> 35 #include <com/sun/star/ucb/XCommandEnvironment.hpp> 36 #include <com/sun/star/task/XInteractionHandler.hpp> 37 #include <com/sun/star/io/XStream.hpp> 38 #include <com/sun/star/io/XActiveDataSink.hpp> 39 #include <com/sun/star/io/XSeekable.hpp> 40 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 41 #include <com/sun/star/lang/IllegalArgumentException.hpp> 42 #include <com/sun/star/util/XURLTransformer.hpp> 43 #include <com/sun/star/ucb/InteractiveIOException.hpp> 44 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> 45 #include <com/sun/star/ucb/CommandFailedException.hpp> 46 #include <com/sun/star/task/XInteractionAbort.hpp> 47 #include <com/sun/star/uri/XUriReferenceFactory.hpp> 48 #include <com/sun/star/uri/XUriReference.hpp> 49 #include <com/sun/star/ucb/PostCommandArgument2.hpp> 50 #include <com/sun/star/container/XNameAccess.hpp> 51 52 #include <ucbhelper/interceptedinteraction.hxx> 53 #include <ucbhelper/content.hxx> 54 #include <ucbhelper/commandenvironment.hxx> 55 #include <ucbhelper/activedatasink.hxx> 56 #include <comphelper/processfactory.hxx> 57 #include <comphelper/configurationhelper.hxx> 58 59 #include <rtl/ustrbuf.hxx> 60 61 //_______________________________________________ 62 // namespace 63 64 namespace comphelper{ 65 66 namespace css = ::com::sun::star; 67 68 //_______________________________________________ 69 // definitions 70 71 /*----------------------------------------------- 72 10.03.2004 07:35 73 -----------------------------------------------*/ 74 const ::rtl::OUString& MediaDescriptor::PROP_ABORTED() 75 { 76 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Aborted")); 77 return sProp; 78 } 79 80 const ::rtl::OUString& MediaDescriptor::PROP_ASTEMPLATE() 81 { 82 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")); 83 return sProp; 84 } 85 86 const ::rtl::OUString& MediaDescriptor::PROP_CHARACTERSET() 87 { 88 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("CharacterSet")); 89 return sProp; 90 } 91 92 const ::rtl::OUString& MediaDescriptor::PROP_COMPONENTDATA() 93 { 94 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ComponentData")); 95 return sProp; 96 } 97 98 const ::rtl::OUString& MediaDescriptor::PROP_DEEPDETECTION() 99 { 100 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DeepDetection")); 101 return sProp; 102 } 103 104 const ::rtl::OUString& MediaDescriptor::PROP_DETECTSERVICE() 105 { 106 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DetectService")); 107 return sProp; 108 } 109 110 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTSERVICE() 111 { 112 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentService")); 113 return sProp; 114 } 115 116 const ::rtl::OUString& MediaDescriptor::PROP_ENCRYPTIONDATA() 117 { 118 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("EncryptionData")); 119 return sProp; 120 } 121 122 const ::rtl::OUString& MediaDescriptor::PROP_EXTENSION() 123 { 124 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Extension")); 125 return sProp; 126 } 127 128 const ::rtl::OUString& MediaDescriptor::PROP_FILENAME() 129 { 130 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FileName")); 131 return sProp; 132 } 133 134 const ::rtl::OUString& MediaDescriptor::PROP_FILTERNAME() 135 { 136 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterName")); 137 return sProp; 138 } 139 140 const ::rtl::OUString& MediaDescriptor::PROP_FILTEROPTIONS() 141 { 142 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterOptions")); 143 return sProp; 144 } 145 146 const ::rtl::OUString& MediaDescriptor::PROP_FORMAT() 147 { 148 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Format")); 149 return sProp; 150 } 151 152 const ::rtl::OUString& MediaDescriptor::PROP_FRAME() 153 { 154 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Frame")); 155 return sProp; 156 } 157 158 const ::rtl::OUString& MediaDescriptor::PROP_FRAMENAME() 159 { 160 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FrameName")); 161 return sProp; 162 } 163 164 const ::rtl::OUString& MediaDescriptor::PROP_HIDDEN() 165 { 166 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Hidden")); 167 return sProp; 168 } 169 170 const ::rtl::OUString& MediaDescriptor::PROP_INPUTSTREAM() 171 { 172 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InputStream")); 173 return sProp; 174 } 175 176 const ::rtl::OUString& MediaDescriptor::PROP_INTERACTIONHANDLER() 177 { 178 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")); 179 return sProp; 180 } 181 182 const ::rtl::OUString& MediaDescriptor::PROP_JUMPMARK() 183 { 184 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("JumpMark")); 185 return sProp; 186 } 187 188 const ::rtl::OUString& MediaDescriptor::PROP_MACROEXECUTIONMODE() 189 { 190 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode")); 191 return sProp; 192 } 193 194 const ::rtl::OUString& MediaDescriptor::PROP_MEDIATYPE() 195 { 196 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MediaType")); 197 return sProp; 198 } 199 200 const ::rtl::OUString& MediaDescriptor::PROP_MINIMIZED() 201 { 202 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Minimized")); 203 return sProp; 204 } 205 206 const ::rtl::OUString& MediaDescriptor::PROP_NOAUTOSAVE() 207 { 208 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("NoAutoSave")); 209 return sProp; 210 } 211 212 const ::rtl::OUString& MediaDescriptor::PROP_OPENNEWVIEW() 213 { 214 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OpenNewView")); 215 return sProp; 216 } 217 218 const ::rtl::OUString& MediaDescriptor::PROP_OUTPUTSTREAM() 219 { 220 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OutputStream")); 221 return sProp; 222 } 223 224 const ::rtl::OUString& MediaDescriptor::PROP_PATTERN() 225 { 226 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Pattern")); 227 return sProp; 228 } 229 230 const ::rtl::OUString& MediaDescriptor::PROP_POSSIZE() 231 { 232 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PosSize")); 233 return sProp; 234 } 235 236 const ::rtl::OUString& MediaDescriptor::PROP_POSTDATA() 237 { 238 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PostData")); 239 return sProp; 240 } 241 242 const ::rtl::OUString& MediaDescriptor::PROP_POSTSTRING() 243 { 244 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PostString")); 245 return sProp; 246 } 247 248 const ::rtl::OUString& MediaDescriptor::PROP_PREVIEW() 249 { 250 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Preview")); 251 return sProp; 252 } 253 254 const ::rtl::OUString& MediaDescriptor::PROP_READONLY() 255 { 256 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")); 257 return sProp; 258 } 259 260 const ::rtl::OUString& MediaDescriptor::PROP_REFERRER() 261 { 262 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Referer")); 263 return sProp; 264 } 265 266 const ::rtl::OUString& MediaDescriptor::PROP_SILENT() 267 { 268 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Silent")); 269 return sProp; 270 } 271 272 const ::rtl::OUString& MediaDescriptor::PROP_STATUSINDICATOR() 273 { 274 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator")); 275 return sProp; 276 } 277 278 const ::rtl::OUString& MediaDescriptor::PROP_STREAM() 279 { 280 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Stream")); 281 return sProp; 282 } 283 284 const ::rtl::OUString& MediaDescriptor::PROP_STREAMFOROUTPUT() 285 { 286 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StreamForOutput")); 287 return sProp; 288 } 289 290 const ::rtl::OUString& MediaDescriptor::PROP_TEMPLATENAME() 291 { 292 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TemplateName")); 293 return sProp; 294 } 295 296 const ::rtl::OUString& MediaDescriptor::PROP_TEMPLATEREGIONNAME() 297 { 298 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TemplateRegionName")); 299 return sProp; 300 } 301 302 const ::rtl::OUString& MediaDescriptor::PROP_TYPENAME() 303 { 304 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TypeName")); 305 return sProp; 306 } 307 308 const ::rtl::OUString& MediaDescriptor::PROP_UCBCONTENT() 309 { 310 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UCBContent")); 311 return sProp; 312 } 313 314 const ::rtl::OUString& MediaDescriptor::PROP_UPDATEDOCMODE() 315 { 316 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UpdateDocMode")); 317 return sProp; 318 } 319 320 const ::rtl::OUString& MediaDescriptor::PROP_URL() 321 { 322 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("URL")); 323 return sProp; 324 } 325 326 const ::rtl::OUString& MediaDescriptor::PROP_VERSION() 327 { 328 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Version")); 329 return sProp; 330 } 331 332 const ::rtl::OUString& MediaDescriptor::PROP_VIEWID() 333 { 334 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewId")); 335 return sProp; 336 } 337 338 const ::rtl::OUString& MediaDescriptor::PROP_REPAIRPACKAGE() 339 { 340 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")); 341 return sProp; 342 } 343 344 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTTITLE() 345 { 346 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")); 347 return sProp; 348 } 349 350 const ::rtl::OUString& MediaDescriptor::PROP_MODEL() 351 { 352 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Model")); 353 return sProp; 354 } 355 356 const ::rtl::OUString& MediaDescriptor::PROP_PASSWORD() 357 { 358 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Password")); 359 return sProp; 360 } 361 362 const ::rtl::OUString& MediaDescriptor::PROP_TITLE() 363 { 364 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Title")); 365 return sProp; 366 } 367 368 const ::rtl::OUString& MediaDescriptor::PROP_SALVAGEDFILE() 369 { 370 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("SalvagedFile")); 371 return sProp; 372 } 373 374 const ::rtl::OUString& MediaDescriptor::PROP_VIEWONLY() 375 { 376 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewOnly")); 377 return sProp; 378 } 379 380 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTBASEURL() 381 { 382 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL")); 383 return sProp; 384 } 385 386 const ::rtl::OUString& MediaDescriptor::PROP_VIEWCONTROLLERNAME() 387 { 388 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewControllerName")); 389 return sProp; 390 } 391 /*----------------------------------------------- 392 10.03.2004 08:09 393 -----------------------------------------------*/ 394 MediaDescriptor::MediaDescriptor() 395 : SequenceAsHashMap() 396 { 397 } 398 399 /*----------------------------------------------- 400 10.03.2004 08:09 401 -----------------------------------------------*/ 402 MediaDescriptor::MediaDescriptor(const css::uno::Any& aSource) 403 : SequenceAsHashMap(aSource) 404 { 405 } 406 407 /*----------------------------------------------- 408 10.03.2004 08:09 409 -----------------------------------------------*/ 410 MediaDescriptor::MediaDescriptor(const css::uno::Sequence< css::beans::PropertyValue >& lSource) 411 : SequenceAsHashMap(lSource) 412 { 413 } 414 415 /*----------------------------------------------- 416 10.03.2004 08:09 417 -----------------------------------------------*/ 418 MediaDescriptor::MediaDescriptor(const css::uno::Sequence< css::beans::NamedValue >& lSource) 419 : SequenceAsHashMap(lSource) 420 { 421 } 422 423 /*----------------------------------------------- 424 18.11.2004 13:37 425 -----------------------------------------------*/ 426 sal_Bool MediaDescriptor::isStreamReadOnly() const 427 { 428 static ::rtl::OUString CONTENTSCHEME_FILE = ::rtl::OUString::createFromAscii("file"); 429 static ::rtl::OUString CONTENTPROP_ISREADONLY = ::rtl::OUString::createFromAscii("IsReadOnly"); 430 static sal_Bool READONLY_FALLBACK = sal_False; 431 432 sal_Bool bReadOnly = READONLY_FALLBACK; 433 434 // check for explicit readonly state 435 const_iterator pIt = find(MediaDescriptor::PROP_READONLY()); 436 if (pIt != end()) 437 { 438 pIt->second >>= bReadOnly; 439 return bReadOnly; 440 } 441 442 // streams based on post data are readonly by definition 443 pIt = find(MediaDescriptor::PROP_POSTDATA()); 444 if (pIt != end()) 445 return sal_True; 446 447 // A XStream capsulate XInputStream and XOutputStream ... 448 // If it exists - the file must be open in read/write mode! 449 pIt = find(MediaDescriptor::PROP_STREAM()); 450 if (pIt != end()) 451 return sal_False; 452 453 // Only file system content provider is able to provide XStream 454 // so for this content impossibility to create XStream triggers 455 // switch to readonly mode. 456 try 457 { 458 css::uno::Reference< css::ucb::XContent > xContent = getUnpackedValueOrDefault(MediaDescriptor::PROP_UCBCONTENT(), css::uno::Reference< css::ucb::XContent >()); 459 if (xContent.is()) 460 { 461 css::uno::Reference< css::ucb::XContentIdentifier > xId(xContent->getIdentifier(), css::uno::UNO_QUERY); 462 ::rtl::OUString aScheme; 463 if (xId.is()) 464 aScheme = xId->getContentProviderScheme(); 465 466 if (aScheme.equalsIgnoreAsciiCase(CONTENTSCHEME_FILE)) 467 bReadOnly = sal_True; 468 else 469 { 470 ::ucbhelper::Content aContent(xContent, css::uno::Reference< css::ucb::XCommandEnvironment >()); 471 aContent.getPropertyValue(CONTENTPROP_ISREADONLY) >>= bReadOnly; 472 } 473 } 474 } 475 catch(const css::uno::RuntimeException& exRun) 476 { throw exRun; } 477 catch(const css::uno::Exception&) 478 {} 479 480 return bReadOnly; 481 } 482 483 // ---------------------------------------------------------------------------- 484 485 css::uno::Any MediaDescriptor::getComponentDataEntry( const ::rtl::OUString& rName ) const 486 { 487 css::uno::Any aEntry; 488 SequenceAsHashMap::const_iterator aPropertyIter = find( PROP_COMPONENTDATA() ); 489 if( aPropertyIter != end() ) 490 return NamedValueCollection( aPropertyIter->second ).get( rName ); 491 return css::uno::Any(); 492 } 493 494 void MediaDescriptor::setComponentDataEntry( const ::rtl::OUString& rName, const css::uno::Any& rValue ) 495 { 496 if( rValue.hasValue() ) 497 { 498 // get or create the 'ComponentData' property entry 499 css::uno::Any& rCompDataAny = operator[]( PROP_COMPONENTDATA() ); 500 // insert the value (retain sequence type, create NamedValue elements by default) 501 bool bHasNamedValues = !rCompDataAny.hasValue() || rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >(); 502 bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >(); 503 OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::setComponentDataEntry - incompatible 'ComponentData' property in media descriptor" ); 504 if( bHasNamedValues || bHasPropValues ) 505 { 506 // insert or overwrite the passed value 507 SequenceAsHashMap aCompDataMap( rCompDataAny ); 508 aCompDataMap[ rName ] = rValue; 509 // write back the sequence (restore sequence with correct element type) 510 rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues ); 511 } 512 } 513 else 514 { 515 // if an empty Any is passed, clear the entry 516 clearComponentDataEntry( rName ); 517 } 518 } 519 520 void MediaDescriptor::clearComponentDataEntry( const ::rtl::OUString& rName ) 521 { 522 SequenceAsHashMap::iterator aPropertyIter = find( PROP_COMPONENTDATA() ); 523 if( aPropertyIter != end() ) 524 { 525 css::uno::Any& rCompDataAny = aPropertyIter->second; 526 bool bHasNamedValues = rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >(); 527 bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >(); 528 OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::clearComponentDataEntry - incompatible 'ComponentData' property in media descriptor" ); 529 if( bHasNamedValues || bHasPropValues ) 530 { 531 // remove the value with the passed name 532 SequenceAsHashMap aCompDataMap( rCompDataAny ); 533 aCompDataMap.erase( rName ); 534 // write back the sequence, or remove it completely if it is empty 535 if( aCompDataMap.empty() ) 536 erase( aPropertyIter ); 537 else 538 rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues ); 539 } 540 } 541 } 542 543 /*----------------------------------------------- 544 10.03.2004 09:02 545 -----------------------------------------------*/ 546 sal_Bool MediaDescriptor::addInputStream() 547 { 548 return impl_addInputStream( sal_True ); 549 } 550 551 /*-----------------------------------------------*/ 552 sal_Bool MediaDescriptor::addInputStreamOwnLock() 553 { 554 // Own lock file implementation 555 556 sal_Bool bUseLock = sal_True; // the system file locking is used per default 557 try 558 { 559 560 css::uno::Reference< css::uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig( 561 ::comphelper::getProcessServiceFactory(), 562 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ), 563 ::comphelper::ConfigurationHelper::E_STANDARD ); 564 if ( !xCommonConfig.is() ) 565 throw css::uno::RuntimeException(); 566 567 ::comphelper::ConfigurationHelper::readRelativeKey( 568 xCommonConfig, 569 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ), 570 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseLock; 571 } 572 catch( const css::uno::Exception& ) 573 { 574 } 575 576 return impl_addInputStream( bUseLock ); 577 } 578 579 /*-----------------------------------------------*/ 580 sal_Bool MediaDescriptor::impl_addInputStream( sal_Bool bLockFile ) 581 { 582 // check for an already existing stream item first 583 const_iterator pIt = find(MediaDescriptor::PROP_INPUTSTREAM()); 584 if (pIt != end()) 585 return sal_True; 586 587 try 588 { 589 // No stream available - create a new one 590 // a) data comes as PostData ... 591 pIt = find(MediaDescriptor::PROP_POSTDATA()); 592 if (pIt != end()) 593 { 594 const css::uno::Any& rPostData = pIt->second; 595 css::uno::Reference< css::io::XInputStream > xPostData; 596 rPostData >>= xPostData; 597 598 return impl_openStreamWithPostData( xPostData ); 599 } 600 601 // b) ... or we must get it from the given URL 602 ::rtl::OUString sURL = getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), ::rtl::OUString()); 603 if (!sURL.getLength()) 604 throw css::uno::Exception( 605 ::rtl::OUString::createFromAscii("Found no URL."), 606 css::uno::Reference< css::uno::XInterface >()); 607 608 // Parse URL! Only the main part has to be used further. E.g. a jumpmark can make trouble 609 ::rtl::OUString sNormalizedURL = impl_normalizeURL( sURL ); 610 return impl_openStreamWithURL( sNormalizedURL, bLockFile ); 611 } 612 #if OSL_DEBUG_LEVEL>0 613 catch(const css::uno::Exception& ex) 614 { 615 ::rtl::OUStringBuffer sMsg(256); 616 sMsg.appendAscii("Invalid MediaDescriptor detected:\n"); 617 sMsg.append (ex.Message ); 618 OSL_ENSURE(sal_False, ::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr()); 619 } 620 #else 621 catch(const css::uno::Exception&) 622 {} 623 #endif 624 625 return sal_False; 626 } 627 628 /*----------------------------------------------- 629 25.03.2004 12:38 630 -----------------------------------------------*/ 631 sal_Bool MediaDescriptor::impl_openStreamWithPostData( const css::uno::Reference< css::io::XInputStream >& _rxPostData ) 632 throw(::com::sun::star::uno::RuntimeException) 633 { 634 if ( !_rxPostData.is() ) 635 throw css::lang::IllegalArgumentException( 636 ::rtl::OUString::createFromAscii("Found invalid PostData."), 637 css::uno::Reference< css::uno::XInterface >(), 1); 638 639 // PostData can't be used in read/write mode! 640 (*this)[MediaDescriptor::PROP_READONLY()] <<= sal_True; 641 642 // prepare the environment 643 css::uno::Reference< css::task::XInteractionHandler > xInteraction = getUnpackedValueOrDefault( 644 MediaDescriptor::PROP_INTERACTIONHANDLER(), 645 css::uno::Reference< css::task::XInteractionHandler >()); 646 css::uno::Reference< css::ucb::XProgressHandler > xProgress; 647 ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress); 648 css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY); 649 650 // media type 651 ::rtl::OUString sMediaType = getUnpackedValueOrDefault(MediaDescriptor::PROP_MEDIATYPE(), ::rtl::OUString()); 652 if (!sMediaType.getLength()) 653 { 654 sMediaType = ::rtl::OUString::createFromAscii("application/x-www-form-urlencoded"); 655 (*this)[MediaDescriptor::PROP_MEDIATYPE()] <<= sMediaType; 656 } 657 658 // url 659 ::rtl::OUString sURL( getUnpackedValueOrDefault( PROP_URL(), ::rtl::OUString() ) ); 660 661 css::uno::Reference< css::io::XInputStream > xResultStream; 662 try 663 { 664 // seek PostData stream to the beginning 665 css::uno::Reference< css::io::XSeekable > xSeek( _rxPostData, css::uno::UNO_QUERY ); 666 if ( xSeek.is() ) 667 xSeek->seek( 0 ); 668 669 // a content for the URL 670 ::ucbhelper::Content aContent( sURL, xCommandEnv ); 671 672 // use post command 673 css::ucb::PostCommandArgument2 aPostArgument; 674 aPostArgument.Source = _rxPostData; 675 css::uno::Reference< css::io::XActiveDataSink > xSink( new ucbhelper::ActiveDataSink ); 676 aPostArgument.Sink = xSink; 677 aPostArgument.MediaType = sMediaType; 678 aPostArgument.Referer = getUnpackedValueOrDefault( PROP_REFERRER(), ::rtl::OUString() ); 679 680 ::rtl::OUString sCommandName( RTL_CONSTASCII_USTRINGPARAM( "post" ) ); 681 aContent.executeCommand( sCommandName, css::uno::makeAny( aPostArgument ) ); 682 683 // get result 684 xResultStream = xSink->getInputStream(); 685 } 686 catch( const css::uno::Exception& ) 687 { 688 } 689 690 // success? 691 if ( !xResultStream.is() ) 692 { 693 OSL_ENSURE( false, "no valid reply to the HTTP-Post" ); 694 return sal_False; 695 } 696 697 (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xResultStream; 698 return sal_True; 699 } 700 701 /*-----------------------------------------------*/ 702 703 /*----------------------------------------------- 704 25.03.2004 12:29 705 -----------------------------------------------*/ 706 sal_Bool MediaDescriptor::impl_openStreamWithURL( const ::rtl::OUString& sURL, sal_Bool bLockFile ) 707 throw(::com::sun::star::uno::RuntimeException) 708 { 709 // prepare the environment 710 css::uno::Reference< css::task::XInteractionHandler > xOrgInteraction = getUnpackedValueOrDefault( 711 MediaDescriptor::PROP_INTERACTIONHANDLER(), 712 css::uno::Reference< css::task::XInteractionHandler >()); 713 714 StillReadWriteInteraction* pInteraction = new StillReadWriteInteraction(xOrgInteraction); 715 css::uno::Reference< css::task::XInteractionHandler > xInteraction(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY); 716 717 css::uno::Reference< css::ucb::XProgressHandler > xProgress; 718 ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress); 719 css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY); 720 721 // try to create the content 722 // no content -> no stream => return immediatly with FALSE 723 ::ucbhelper::Content aContent; 724 css::uno::Reference< css::ucb::XContent > xContent; 725 try 726 { 727 aContent = ::ucbhelper::Content(sURL, xCommandEnv); 728 xContent = aContent.get(); 729 } 730 catch(const css::uno::RuntimeException&) 731 { throw; } 732 catch(const css::ucb::ContentCreationException&) 733 { return sal_False; } // TODO error handling 734 catch(const css::uno::Exception&) 735 { return sal_False; } // TODO error handling 736 737 // try to open the file in read/write mode 738 // (if its allowed to do so). 739 // But handle errors in a "hidden mode". Because 740 // we try it readonly later - if read/write isnt an option. 741 css::uno::Reference< css::io::XStream > xStream ; 742 css::uno::Reference< css::io::XInputStream > xInputStream; 743 744 sal_Bool bReadOnly = sal_False; 745 sal_Bool bModeRequestedExplicitly = sal_False; 746 const_iterator pIt = find(MediaDescriptor::PROP_READONLY()); 747 if (pIt != end()) 748 { 749 pIt->second >>= bReadOnly; 750 bModeRequestedExplicitly = sal_True; 751 } 752 753 if ( !bReadOnly && bLockFile ) 754 { 755 try 756 { 757 // TODO: use "special" still interaction to supress error messages 758 xStream = aContent.openWriteableStream(); 759 if (xStream.is()) 760 xInputStream = xStream->getInputStream(); 761 } 762 catch(const css::uno::RuntimeException&) 763 { throw; } 764 catch(const css::uno::Exception&) 765 { 766 // ignore exception, if reason was problem reasoned on 767 // open it in WRITEABLE mode! Then we try it READONLY 768 // later a second time. 769 // All other errors must be handled as real error an 770 // break this method. 771 if (!pInteraction->wasWriteError() || bModeRequestedExplicitly) 772 return sal_False; 773 xStream.clear(); 774 xInputStream.clear(); 775 } 776 } 777 778 // If opening of the stream in read/write mode wasnt allowed 779 // or failed by an error - we must try it in readonly mode. 780 if (!xInputStream.is()) 781 { 782 rtl::OUString aScheme; 783 784 try 785 { 786 css::uno::Reference< css::ucb::XContentIdentifier > xContId( 787 aContent.get().is() ? aContent.get()->getIdentifier() : 0 ); 788 789 if ( xContId.is() ) 790 aScheme = xContId->getContentProviderScheme(); 791 792 // Only file system content provider is able to provide XStream 793 // so for this content impossibility to create XStream triggers 794 // switch to readonly mode in case of opening with locking on 795 if( bLockFile && aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) 796 bReadOnly = sal_True; 797 else 798 { 799 sal_Bool bRequestReadOnly = bReadOnly; 800 aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bReadOnly; 801 if ( bReadOnly && !bRequestReadOnly && bModeRequestedExplicitly ) 802 return sal_False; // the document is explicitly requested with WRITEABLE mode 803 } 804 } 805 catch(const css::uno::RuntimeException&) 806 { throw; } 807 catch(const css::uno::Exception&) 808 { /* no error handling if IsReadOnly property does not exist for UCP */ } 809 810 if ( bReadOnly ) 811 (*this)[MediaDescriptor::PROP_READONLY()] <<= bReadOnly; 812 813 pInteraction->resetInterceptions(); 814 pInteraction->resetErrorStates(); 815 try 816 { 817 // all the contents except file-URLs should be opened as usual 818 if ( bLockFile || !aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) 819 xInputStream = aContent.openStream(); 820 else 821 xInputStream = aContent.openStreamNoLock(); 822 } 823 catch(const css::uno::RuntimeException&) 824 { throw; } 825 catch(const css::uno::Exception&) 826 { return sal_False; } 827 } 828 829 // add streams to the descriptor 830 if (xContent.is()) 831 (*this)[MediaDescriptor::PROP_UCBCONTENT()] <<= xContent; 832 if (xStream.is()) 833 (*this)[MediaDescriptor::PROP_STREAM()] <<= xStream; 834 if (xInputStream.is()) 835 (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xInputStream; 836 837 // At least we need an input stream. The r/w stream is optional ... 838 return xInputStream.is(); 839 } 840 841 /*----------------------------------------------- 842 10.09.2004 10:51 843 -----------------------------------------------*/ 844 ::rtl::OUString MediaDescriptor::impl_normalizeURL(const ::rtl::OUString& sURL) 845 { 846 /* Remove Jumpmarks (fragments) of an URL only here. 847 They are not part of any URL and as a result may be 848 no ucb content can be created then. 849 On the other side arguments must exists ... because 850 they are part of an URL. 851 852 Do not use the URLTransformer service here. Because 853 it parses the URL in another way. It's main part isnt enough 854 and it's complete part contains the jumpmark (fragment) parameter ... 855 */ 856 static ::rtl::OUString SERVICENAME_URIREFERENCEFACTORY = ::rtl::OUString::createFromAscii("com.sun.star.uri.UriReferenceFactory"); 857 858 try 859 { 860 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); 861 css::uno::Reference< css::uri::XUriReferenceFactory > xUriFactory(xSMGR->createInstance(SERVICENAME_URIREFERENCEFACTORY), css::uno::UNO_QUERY_THROW); 862 css::uno::Reference< css::uri::XUriReference > xUriRef = xUriFactory->parse(sURL); 863 if (xUriRef.is()) 864 { 865 xUriRef->clearFragment(); 866 return xUriRef->getUriReference(); 867 } 868 } 869 catch(const css::uno::RuntimeException& exRun) 870 { throw exRun; } 871 catch(const css::uno::Exception&) 872 {} 873 874 // If an error ocurred ... return the original URL. 875 // It's a try .-) 876 return sURL; 877 } 878 879 } // namespace comphelper 880 881