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