Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / comphelper / source / misc / mediadescriptor.cxx
blob1957ab633a21132af774cfdf1c3e69794637afe3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/mediadescriptor.hxx>
21 #include <comphelper/namedvaluecollection.hxx>
22 #include <comphelper/stillreadwriteinteraction.hxx>
24 #include <com/sun/star/ucb/XContent.hpp>
25 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
26 #include <com/sun/star/task/XInteractionHandler.hpp>
27 #include <com/sun/star/io/XStream.hpp>
28 #include <com/sun/star/io/XActiveDataSink.hpp>
29 #include <com/sun/star/io/XSeekable.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/lang/IllegalArgumentException.hpp>
32 #include <com/sun/star/util/XURLTransformer.hpp>
33 #include <com/sun/star/ucb/InteractiveIOException.hpp>
34 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
35 #include <com/sun/star/ucb/CommandFailedException.hpp>
36 #include <com/sun/star/task/XInteractionAbort.hpp>
37 #include <com/sun/star/uri/UriReferenceFactory.hpp>
38 #include <com/sun/star/uri/XUriReference.hpp>
39 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
40 #include <com/sun/star/container/XNameAccess.hpp>
41 #include <officecfg/Office/Common.hxx>
42 #include <ucbhelper/interceptedinteraction.hxx>
43 #include <ucbhelper/content.hxx>
44 #include <ucbhelper/commandenvironment.hxx>
45 #include <ucbhelper/activedatasink.hxx>
46 #include <comphelper/processfactory.hxx>
48 #include <rtl/ustrbuf.hxx>
51 namespace comphelper{
53 const ::rtl::OUString& MediaDescriptor::PROP_ABORTED()
55 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Aborted"));
56 return sProp;
59 const ::rtl::OUString& MediaDescriptor::PROP_ASTEMPLATE()
61 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("AsTemplate"));
62 return sProp;
65 const ::rtl::OUString& MediaDescriptor::PROP_COMPONENTDATA()
67 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ComponentData"));
68 return sProp;
71 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTSERVICE()
73 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
74 return sProp;
77 const ::rtl::OUString& MediaDescriptor::PROP_ENCRYPTIONDATA()
79 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("EncryptionData"));
80 return sProp;
83 const ::rtl::OUString& MediaDescriptor::PROP_FILENAME()
85 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FileName"));
86 return sProp;
89 const ::rtl::OUString& MediaDescriptor::PROP_FILTERNAME()
91 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterName"));
92 return sProp;
95 const OUString& MediaDescriptor::PROP_FILTERPROVIDER()
97 static const OUString aProp("FilterProvider");
98 return aProp;
101 const ::rtl::OUString& MediaDescriptor::PROP_FILTEROPTIONS()
103 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterOptions"));
104 return sProp;
107 const ::rtl::OUString& MediaDescriptor::PROP_FRAME()
109 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Frame"));
110 return sProp;
113 const ::rtl::OUString& MediaDescriptor::PROP_FRAMENAME()
115 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
116 return sProp;
119 const ::rtl::OUString& MediaDescriptor::PROP_HIDDEN()
121 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
122 return sProp;
125 const ::rtl::OUString& MediaDescriptor::PROP_INPUTSTREAM()
127 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InputStream"));
128 return sProp;
131 const ::rtl::OUString& MediaDescriptor::PROP_INTERACTIONHANDLER()
133 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler"));
134 return sProp;
137 const ::rtl::OUString& MediaDescriptor::PROP_JUMPMARK()
139 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("JumpMark"));
140 return sProp;
143 const ::rtl::OUString& MediaDescriptor::PROP_MACROEXECUTIONMODE()
145 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode"));
146 return sProp;
149 const ::rtl::OUString& MediaDescriptor::PROP_MEDIATYPE()
151 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
152 return sProp;
155 const ::rtl::OUString& MediaDescriptor::PROP_MINIMIZED()
157 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Minimized"));
158 return sProp;
161 const ::rtl::OUString& MediaDescriptor::PROP_NOAUTOSAVE()
163 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("NoAutoSave"));
164 return sProp;
167 const ::rtl::OUString& MediaDescriptor::PROP_OPENNEWVIEW()
169 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OpenNewView"));
170 return sProp;
173 const ::rtl::OUString& MediaDescriptor::PROP_OUTPUTSTREAM()
175 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OutputStream"));
176 return sProp;
179 const ::rtl::OUString& MediaDescriptor::PROP_POSTDATA()
181 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PostData"));
182 return sProp;
185 const ::rtl::OUString& MediaDescriptor::PROP_PREVIEW()
187 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Preview"));
188 return sProp;
191 const ::rtl::OUString& MediaDescriptor::PROP_READONLY()
193 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
194 return sProp;
197 const ::rtl::OUString& MediaDescriptor::PROP_REFERRER()
199 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Referer"));
200 return sProp;
203 const ::rtl::OUString& MediaDescriptor::PROP_STATUSINDICATOR()
205 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator"));
206 return sProp;
209 const ::rtl::OUString& MediaDescriptor::PROP_STREAM()
211 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Stream"));
212 return sProp;
215 const ::rtl::OUString& MediaDescriptor::PROP_STREAMFOROUTPUT()
217 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StreamForOutput"));
218 return sProp;
221 const ::rtl::OUString& MediaDescriptor::PROP_TEMPLATENAME()
223 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TemplateName"));
224 return sProp;
227 const ::rtl::OUString& MediaDescriptor::PROP_TYPENAME()
229 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
230 return sProp;
233 const ::rtl::OUString& MediaDescriptor::PROP_UCBCONTENT()
235 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UCBContent"));
236 return sProp;
239 const ::rtl::OUString& MediaDescriptor::PROP_UPDATEDOCMODE()
241 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UpdateDocMode"));
242 return sProp;
245 const ::rtl::OUString& MediaDescriptor::PROP_URL()
247 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("URL"));
248 return sProp;
251 const ::rtl::OUString& MediaDescriptor::PROP_VERSION()
253 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Version"));
254 return sProp;
257 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTTITLE()
259 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle"));
260 return sProp;
263 const ::rtl::OUString& MediaDescriptor::PROP_MODEL()
265 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Model"));
266 return sProp;
269 const ::rtl::OUString& MediaDescriptor::PROP_PASSWORD()
271 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Password"));
272 return sProp;
275 const ::rtl::OUString& MediaDescriptor::PROP_TITLE()
277 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Title"));
278 return sProp;
281 const ::rtl::OUString& MediaDescriptor::PROP_SALVAGEDFILE()
283 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("SalvagedFile"));
284 return sProp;
287 const ::rtl::OUString& MediaDescriptor::PROP_VIEWONLY()
289 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewOnly"));
290 return sProp;
293 const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTBASEURL()
295 static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
296 return sProp;
299 MediaDescriptor::MediaDescriptor()
300 : SequenceAsHashMap()
304 MediaDescriptor::MediaDescriptor(const css::uno::Sequence< css::beans::PropertyValue >& lSource)
305 : SequenceAsHashMap(lSource)
309 sal_Bool MediaDescriptor::isStreamReadOnly() const
311 static ::rtl::OUString CONTENTSCHEME_FILE( RTL_CONSTASCII_USTRINGPARAM( "file" ));
312 static ::rtl::OUString CONTENTPROP_ISREADONLY( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ));
313 static sal_Bool READONLY_FALLBACK = sal_False;
315 sal_Bool bReadOnly = READONLY_FALLBACK;
317 // check for explicit readonly state
318 const_iterator pIt = find(MediaDescriptor::PROP_READONLY());
319 if (pIt != end())
321 pIt->second >>= bReadOnly;
322 return bReadOnly;
325 // streams based on post data are readonly by definition
326 pIt = find(MediaDescriptor::PROP_POSTDATA());
327 if (pIt != end())
328 return sal_True;
330 // A XStream capsulate XInputStream and XOutputStream ...
331 // If it exists - the file must be open in read/write mode!
332 pIt = find(MediaDescriptor::PROP_STREAM());
333 if (pIt != end())
334 return sal_False;
336 // Only file system content provider is able to provide XStream
337 // so for this content impossibility to create XStream triggers
338 // switch to readonly mode.
341 css::uno::Reference< css::ucb::XContent > xContent = getUnpackedValueOrDefault(MediaDescriptor::PROP_UCBCONTENT(), css::uno::Reference< css::ucb::XContent >());
342 if (xContent.is())
344 css::uno::Reference< css::ucb::XContentIdentifier > xId(xContent->getIdentifier(), css::uno::UNO_QUERY);
345 ::rtl::OUString aScheme;
346 if (xId.is())
347 aScheme = xId->getContentProviderScheme();
349 if (aScheme.equalsIgnoreAsciiCase(CONTENTSCHEME_FILE))
350 bReadOnly = sal_True;
351 else
353 ::ucbhelper::Content aContent(xContent, css::uno::Reference< css::ucb::XCommandEnvironment >(), getProcessComponentContext());
354 aContent.getPropertyValue(CONTENTPROP_ISREADONLY) >>= bReadOnly;
358 catch(const css::uno::RuntimeException& )
359 { throw; }
360 catch(const css::uno::Exception&)
363 return bReadOnly;
366 // ----------------------------------------------------------------------------
368 css::uno::Any MediaDescriptor::getComponentDataEntry( const ::rtl::OUString& rName ) const
370 css::uno::Any aEntry;
371 SequenceAsHashMap::const_iterator aPropertyIter = find( PROP_COMPONENTDATA() );
372 if( aPropertyIter != end() )
373 return NamedValueCollection( aPropertyIter->second ).get( rName );
374 return css::uno::Any();
377 void MediaDescriptor::setComponentDataEntry( const ::rtl::OUString& rName, const css::uno::Any& rValue )
379 if( rValue.hasValue() )
381 // get or create the 'ComponentData' property entry
382 css::uno::Any& rCompDataAny = operator[]( PROP_COMPONENTDATA() );
383 // insert the value (retain sequence type, create NamedValue elements by default)
384 bool bHasNamedValues = !rCompDataAny.hasValue() || rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >();
385 bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >();
386 OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::setComponentDataEntry - incompatible 'ComponentData' property in media descriptor" );
387 if( bHasNamedValues || bHasPropValues )
389 // insert or overwrite the passed value
390 SequenceAsHashMap aCompDataMap( rCompDataAny );
391 aCompDataMap[ rName ] = rValue;
392 // write back the sequence (restore sequence with correct element type)
393 rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues );
396 else
398 // if an empty Any is passed, clear the entry
399 clearComponentDataEntry( rName );
403 void MediaDescriptor::clearComponentDataEntry( const ::rtl::OUString& rName )
405 SequenceAsHashMap::iterator aPropertyIter = find( PROP_COMPONENTDATA() );
406 if( aPropertyIter != end() )
408 css::uno::Any& rCompDataAny = aPropertyIter->second;
409 bool bHasNamedValues = rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >();
410 bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >();
411 OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::clearComponentDataEntry - incompatible 'ComponentData' property in media descriptor" );
412 if( bHasNamedValues || bHasPropValues )
414 // remove the value with the passed name
415 SequenceAsHashMap aCompDataMap( rCompDataAny );
416 aCompDataMap.erase( rName );
417 // write back the sequence, or remove it completely if it is empty
418 if( aCompDataMap.empty() )
419 erase( aPropertyIter );
420 else
421 rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues );
426 sal_Bool MediaDescriptor::addInputStream()
428 return impl_addInputStream( sal_True );
431 /*-----------------------------------------------*/
432 sal_Bool MediaDescriptor::addInputStreamOwnLock()
434 return impl_addInputStream(
435 officecfg::Office::Common::Misc::UseDocumentSystemFileLocking::get());
438 /*-----------------------------------------------*/
439 sal_Bool MediaDescriptor::impl_addInputStream( sal_Bool bLockFile )
441 // check for an already existing stream item first
442 const_iterator pIt = find(MediaDescriptor::PROP_INPUTSTREAM());
443 if (pIt != end())
444 return sal_True;
448 // No stream available - create a new one
449 // a) data comes as PostData ...
450 pIt = find(MediaDescriptor::PROP_POSTDATA());
451 if (pIt != end())
453 const css::uno::Any& rPostData = pIt->second;
454 css::uno::Reference< css::io::XInputStream > xPostData;
455 rPostData >>= xPostData;
457 return impl_openStreamWithPostData( xPostData );
460 // b) ... or we must get it from the given URL
461 ::rtl::OUString sURL = getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), ::rtl::OUString());
462 if (sURL.isEmpty())
463 throw css::uno::Exception(
464 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found no URL." )),
465 css::uno::Reference< css::uno::XInterface >());
467 // Parse URL! Only the main part has to be used further. E.g. a jumpmark can make trouble
468 ::rtl::OUString sNormalizedURL = impl_normalizeURL( sURL );
469 return impl_openStreamWithURL( sNormalizedURL, bLockFile );
471 #if OSL_DEBUG_LEVEL > 0
472 catch(const css::uno::Exception& ex)
474 ::rtl::OUStringBuffer sMsg(256);
475 sMsg.appendAscii("Invalid MediaDescriptor detected:\n");
476 sMsg.append (ex.Message );
477 OSL_FAIL(::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr());
479 #else
480 catch(const css::uno::Exception&)
482 #endif
484 return sal_False;
487 sal_Bool MediaDescriptor::impl_openStreamWithPostData( const css::uno::Reference< css::io::XInputStream >& _rxPostData )
488 throw(::com::sun::star::uno::RuntimeException)
490 if ( !_rxPostData.is() )
491 throw css::lang::IllegalArgumentException(
492 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found invalid PostData." )),
493 css::uno::Reference< css::uno::XInterface >(), 1);
495 // PostData can't be used in read/write mode!
496 (*this)[MediaDescriptor::PROP_READONLY()] <<= sal_True;
498 // prepare the environment
499 css::uno::Reference< css::task::XInteractionHandler > xInteraction = getUnpackedValueOrDefault(
500 MediaDescriptor::PROP_INTERACTIONHANDLER(),
501 css::uno::Reference< css::task::XInteractionHandler >());
502 css::uno::Reference< css::ucb::XProgressHandler > xProgress;
503 ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress);
504 css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY);
506 // media type
507 ::rtl::OUString sMediaType = getUnpackedValueOrDefault(MediaDescriptor::PROP_MEDIATYPE(), ::rtl::OUString());
508 if (sMediaType.isEmpty())
510 sMediaType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-www-form-urlencoded" ));
511 (*this)[MediaDescriptor::PROP_MEDIATYPE()] <<= sMediaType;
514 // url
515 ::rtl::OUString sURL( getUnpackedValueOrDefault( PROP_URL(), ::rtl::OUString() ) );
517 css::uno::Reference< css::io::XInputStream > xResultStream;
520 // seek PostData stream to the beginning
521 css::uno::Reference< css::io::XSeekable > xSeek( _rxPostData, css::uno::UNO_QUERY );
522 if ( xSeek.is() )
523 xSeek->seek( 0 );
525 // a content for the URL
526 ::ucbhelper::Content aContent( sURL, xCommandEnv, getProcessComponentContext() );
528 // use post command
529 css::ucb::PostCommandArgument2 aPostArgument;
530 aPostArgument.Source = _rxPostData;
531 css::uno::Reference< css::io::XActiveDataSink > xSink( new ucbhelper::ActiveDataSink );
532 aPostArgument.Sink = xSink;
533 aPostArgument.MediaType = sMediaType;
534 aPostArgument.Referer = getUnpackedValueOrDefault( PROP_REFERRER(), ::rtl::OUString() );
536 ::rtl::OUString sCommandName( RTL_CONSTASCII_USTRINGPARAM( "post" ) );
537 aContent.executeCommand( sCommandName, css::uno::makeAny( aPostArgument ) );
539 // get result
540 xResultStream = xSink->getInputStream();
542 catch( const css::uno::Exception& )
546 // success?
547 if ( !xResultStream.is() )
549 OSL_FAIL( "no valid reply to the HTTP-Post" );
550 return sal_False;
553 (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xResultStream;
554 return sal_True;
557 /*-----------------------------------------------*/
558 sal_Bool MediaDescriptor::impl_openStreamWithURL( const ::rtl::OUString& sURL, sal_Bool bLockFile )
559 throw(::com::sun::star::uno::RuntimeException)
561 // prepare the environment
562 css::uno::Reference< css::task::XInteractionHandler > xOrgInteraction = getUnpackedValueOrDefault(
563 MediaDescriptor::PROP_INTERACTIONHANDLER(),
564 css::uno::Reference< css::task::XInteractionHandler >());
566 StillReadWriteInteraction* pInteraction = new StillReadWriteInteraction(xOrgInteraction);
567 css::uno::Reference< css::task::XInteractionHandler > xInteraction(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY);
569 css::uno::Reference< css::ucb::XProgressHandler > xProgress;
570 ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress);
571 css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY);
573 // try to create the content
574 // no content -> no stream => return immediatly with FALSE
575 ::ucbhelper::Content aContent;
576 css::uno::Reference< css::ucb::XContent > xContent;
579 aContent = ::ucbhelper::Content(sURL, xCommandEnv, getProcessComponentContext());
580 xContent = aContent.get();
582 catch(const css::uno::RuntimeException&)
583 { throw; }
584 catch(const css::ucb::ContentCreationException&)
585 { return sal_False; } // TODO error handling
586 catch(const css::uno::Exception&)
587 { return sal_False; } // TODO error handling
589 // try to open the file in read/write mode
590 // (if its allowed to do so).
591 // But handle errors in a "hidden mode". Because
592 // we try it readonly later - if read/write isnt an option.
593 css::uno::Reference< css::io::XStream > xStream ;
594 css::uno::Reference< css::io::XInputStream > xInputStream;
596 sal_Bool bReadOnly = sal_False;
597 sal_Bool bModeRequestedExplicitly = sal_False;
598 const_iterator pIt = find(MediaDescriptor::PROP_READONLY());
599 if (pIt != end())
601 pIt->second >>= bReadOnly;
602 bModeRequestedExplicitly = sal_True;
605 if ( !bReadOnly && bLockFile )
609 // TODO: use "special" still interaction to supress error messages
610 xStream = aContent.openWriteableStream();
611 if (xStream.is())
612 xInputStream = xStream->getInputStream();
614 catch(const css::uno::RuntimeException&)
615 { throw; }
616 catch(const css::uno::Exception&)
618 // ignore exception, if reason was problem reasoned on
619 // open it in WRITEABLE mode! Then we try it READONLY
620 // later a second time.
621 // All other errors must be handled as real error an
622 // break this method.
623 if (!pInteraction->wasWriteError() || bModeRequestedExplicitly)
624 return sal_False;
625 xStream.clear();
626 xInputStream.clear();
630 // If opening of the stream in read/write mode wasnt allowed
631 // or failed by an error - we must try it in readonly mode.
632 if (!xInputStream.is())
634 rtl::OUString aScheme;
638 css::uno::Reference< css::ucb::XContentIdentifier > xContId(
639 aContent.get().is() ? aContent.get()->getIdentifier() : 0 );
641 if ( xContId.is() )
642 aScheme = xContId->getContentProviderScheme();
644 // Only file system content provider is able to provide XStream
645 // so for this content impossibility to create XStream triggers
646 // switch to readonly mode in case of opening with locking on
647 if( bLockFile && aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file")) )
648 bReadOnly = sal_True;
649 else
651 sal_Bool bRequestReadOnly = bReadOnly;
652 aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bReadOnly;
653 if ( bReadOnly && !bRequestReadOnly && bModeRequestedExplicitly )
654 return sal_False; // the document is explicitly requested with WRITEABLE mode
657 catch(const css::uno::RuntimeException&)
658 { throw; }
659 catch(const css::uno::Exception&)
660 { /* no error handling if IsReadOnly property does not exist for UCP */ }
662 if ( bReadOnly )
663 (*this)[MediaDescriptor::PROP_READONLY()] <<= bReadOnly;
665 pInteraction->resetInterceptions();
666 pInteraction->resetErrorStates();
669 // all the contents except file-URLs should be opened as usual
670 if ( bLockFile || !aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file")) )
671 xInputStream = aContent.openStream();
672 else
673 xInputStream = aContent.openStreamNoLock();
675 catch(const css::uno::RuntimeException&)
676 { throw; }
677 catch(const css::uno::Exception&)
678 { return sal_False; }
681 // add streams to the descriptor
682 if (xContent.is())
683 (*this)[MediaDescriptor::PROP_UCBCONTENT()] <<= xContent;
684 if (xStream.is())
685 (*this)[MediaDescriptor::PROP_STREAM()] <<= xStream;
686 if (xInputStream.is())
687 (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xInputStream;
689 // At least we need an input stream. The r/w stream is optional ...
690 return xInputStream.is();
693 ::rtl::OUString MediaDescriptor::impl_normalizeURL(const ::rtl::OUString& sURL)
695 /* Remove Jumpmarks (fragments) of an URL only here.
696 They are not part of any URL and as a result may be
697 no ucb content can be created then.
698 On the other side arguments must exists ... because
699 they are part of an URL.
701 Do not use the URLTransformer service here. Because
702 it parses the URL in another way. It's main part isnt enough
703 and it's complete part contains the jumpmark (fragment) parameter ...
708 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
709 css::uno::Reference< css::uri::XUriReferenceFactory > xUriFactory = css::uri::UriReferenceFactory::create(xContext);;
710 css::uno::Reference< css::uri::XUriReference > xUriRef = xUriFactory->parse(sURL);
711 if (xUriRef.is())
713 xUriRef->clearFragment();
714 return xUriRef->getUriReference();
717 catch(const css::uno::RuntimeException&)
718 { throw; }
719 catch(const css::uno::Exception&)
722 // If an error ocurred ... return the original URL.
723 // It's a try .-)
724 return sURL;
727 } // namespace comphelper
729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */