Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include <comphelper/mediadescriptor.hxx>
21 : : #include <comphelper/namedvaluecollection.hxx>
22 : : #include <comphelper/stillreadwriteinteraction.hxx>
23 : :
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/XUriReferenceFactory.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>
47 : :
48 : : #include <rtl/ustrbuf.hxx>
49 : :
50 : :
51 : : namespace comphelper{
52 : :
53 : : namespace css = ::com::sun::star;
54 : :
55 : :
56 : 210 : const ::rtl::OUString& MediaDescriptor::PROP_ABORTED()
57 : : {
58 [ + + ][ + - ]: 210 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Aborted"));
[ + - ][ # # ]
59 : 210 : return sProp;
60 : : }
61 : :
62 : 1140 : const ::rtl::OUString& MediaDescriptor::PROP_ASTEMPLATE()
63 : : {
64 [ + + ][ + - ]: 1140 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("AsTemplate"));
[ + - ][ # # ]
65 : 1140 : return sProp;
66 : : }
67 : :
68 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_COMPONENTDATA()
69 : : {
70 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ComponentData"));
[ # # ][ # # ]
71 : 0 : return sProp;
72 : : }
73 : :
74 : 3685 : const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTSERVICE()
75 : : {
76 [ + + ][ + - ]: 3685 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
[ + - ][ # # ]
77 : 3685 : return sProp;
78 : : }
79 : :
80 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_ENCRYPTIONDATA()
81 : : {
82 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("EncryptionData"));
[ # # ][ # # ]
83 : 0 : return sProp;
84 : : }
85 : :
86 : 1763 : const ::rtl::OUString& MediaDescriptor::PROP_FILENAME()
87 : : {
88 [ + + ][ + - ]: 1763 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FileName"));
[ + - ][ # # ]
89 : 1763 : return sProp;
90 : : }
91 : :
92 : 9183 : const ::rtl::OUString& MediaDescriptor::PROP_FILTERNAME()
93 : : {
94 [ + + ][ + - ]: 9183 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterName"));
[ + - ][ # # ]
95 : 9183 : return sProp;
96 : : }
97 : :
98 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_FILTEROPTIONS()
99 : : {
100 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterOptions"));
[ # # ][ # # ]
101 : 0 : return sProp;
102 : : }
103 : :
104 : 462 : const ::rtl::OUString& MediaDescriptor::PROP_FRAME()
105 : : {
106 [ + + ][ + - ]: 462 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Frame"));
[ + - ][ # # ]
107 : 462 : return sProp;
108 : : }
109 : :
110 : 1763 : const ::rtl::OUString& MediaDescriptor::PROP_FRAMENAME()
111 : : {
112 [ + + ][ + - ]: 1763 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
[ + - ][ # # ]
113 : 1763 : return sProp;
114 : : }
115 : :
116 : 4094 : const ::rtl::OUString& MediaDescriptor::PROP_HIDDEN()
117 : : {
118 [ + + ][ + - ]: 4094 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
[ + - ][ # # ]
119 : 4094 : return sProp;
120 : : }
121 : :
122 : 15129 : const ::rtl::OUString& MediaDescriptor::PROP_INPUTSTREAM()
123 : : {
124 [ + + ][ + - ]: 15129 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InputStream"));
[ + - ][ # # ]
125 : 15129 : return sProp;
126 : : }
127 : :
128 : 5813 : const ::rtl::OUString& MediaDescriptor::PROP_INTERACTIONHANDLER()
129 : : {
130 [ + + ][ + - ]: 5813 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler"));
[ + - ][ # # ]
131 : 5813 : return sProp;
132 : : }
133 : :
134 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_JUMPMARK()
135 : : {
136 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("JumpMark"));
[ # # ][ # # ]
137 : 0 : return sProp;
138 : : }
139 : :
140 : 2968 : const ::rtl::OUString& MediaDescriptor::PROP_MACROEXECUTIONMODE()
141 : : {
142 [ + + ][ + - ]: 2968 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode"));
[ + - ][ # # ]
143 : 2968 : return sProp;
144 : : }
145 : :
146 : 32 : const ::rtl::OUString& MediaDescriptor::PROP_MEDIATYPE()
147 : : {
148 [ + + ][ + - ]: 32 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
[ + - ][ # # ]
149 : 32 : return sProp;
150 : : }
151 : :
152 : 3526 : const ::rtl::OUString& MediaDescriptor::PROP_MINIMIZED()
153 : : {
154 [ + + ][ + - ]: 3526 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Minimized"));
[ + - ][ # # ]
155 : 3526 : return sProp;
156 : : }
157 : :
158 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_NOAUTOSAVE()
159 : : {
160 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("NoAutoSave"));
[ # # ][ # # ]
161 : 0 : return sProp;
162 : : }
163 : :
164 : 1126 : const ::rtl::OUString& MediaDescriptor::PROP_OPENNEWVIEW()
165 : : {
166 [ + + ][ + - ]: 1126 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OpenNewView"));
[ + - ][ # # ]
167 : 1126 : return sProp;
168 : : }
169 : :
170 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_OUTPUTSTREAM()
171 : : {
172 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OutputStream"));
[ # # ][ # # ]
173 : 0 : return sProp;
174 : : }
175 : :
176 : 2140 : const ::rtl::OUString& MediaDescriptor::PROP_POSTDATA()
177 : : {
178 [ + + ][ + - ]: 2140 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PostData"));
[ + - ][ # # ]
179 : 2140 : return sProp;
180 : : }
181 : :
182 : 3550 : const ::rtl::OUString& MediaDescriptor::PROP_PREVIEW()
183 : : {
184 [ + + ][ + - ]: 3550 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Preview"));
[ + - ][ # # ]
185 : 3550 : return sProp;
186 : : }
187 : :
188 : 11295 : const ::rtl::OUString& MediaDescriptor::PROP_READONLY()
189 : : {
190 [ + + ][ + - ]: 11295 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
[ + - ][ # # ]
191 : 11295 : return sProp;
192 : : }
193 : :
194 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_REFERRER()
195 : : {
196 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Referer"));
[ # # ][ # # ]
197 : 0 : return sProp;
198 : : }
199 : :
200 : 3968 : const ::rtl::OUString& MediaDescriptor::PROP_STATUSINDICATOR()
201 : : {
202 [ + + ][ + - ]: 3968 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator"));
[ + - ][ # # ]
203 : 3968 : return sProp;
204 : : }
205 : :
206 : 2399 : const ::rtl::OUString& MediaDescriptor::PROP_STREAM()
207 : : {
208 [ + + ][ + - ]: 2399 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Stream"));
[ + - ][ # # ]
209 : 2399 : return sProp;
210 : : }
211 : :
212 : 135 : const ::rtl::OUString& MediaDescriptor::PROP_STREAMFOROUTPUT()
213 : : {
214 [ + + ][ + - ]: 135 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StreamForOutput"));
[ + - ][ # # ]
215 : 135 : return sProp;
216 : : }
217 : :
218 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_TEMPLATENAME()
219 : : {
220 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TemplateName"));
[ # # ][ # # ]
221 : 0 : return sProp;
222 : : }
223 : :
224 : 11217 : const ::rtl::OUString& MediaDescriptor::PROP_TYPENAME()
225 : : {
226 [ + + ][ + - ]: 11217 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
[ + - ][ # # ]
227 : 11217 : return sProp;
228 : : }
229 : :
230 : 2083 : const ::rtl::OUString& MediaDescriptor::PROP_UCBCONTENT()
231 : : {
232 [ + + ][ + - ]: 2083 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UCBContent"));
[ + - ][ # # ]
233 : 2083 : return sProp;
234 : : }
235 : :
236 : 3508 : const ::rtl::OUString& MediaDescriptor::PROP_UPDATEDOCMODE()
237 : : {
238 [ + + ][ + - ]: 3508 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UpdateDocMode"));
[ + - ][ # # ]
239 : 3508 : return sProp;
240 : : }
241 : :
242 : 10532 : const ::rtl::OUString& MediaDescriptor::PROP_URL()
243 : : {
244 [ + + ][ + - ]: 10532 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("URL"));
[ + - ][ # # ]
245 : 10532 : return sProp;
246 : : }
247 : :
248 : 563 : const ::rtl::OUString& MediaDescriptor::PROP_VERSION()
249 : : {
250 [ + + ][ + - ]: 563 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Version"));
[ + - ][ # # ]
251 : 563 : return sProp;
252 : : }
253 : :
254 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTTITLE()
255 : : {
256 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle"));
[ # # ][ # # ]
257 : 0 : return sProp;
258 : : }
259 : :
260 : 1817 : const ::rtl::OUString& MediaDescriptor::PROP_MODEL()
261 : : {
262 [ + + ][ + - ]: 1817 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Model"));
[ + - ][ # # ]
263 : 1817 : return sProp;
264 : : }
265 : :
266 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_PASSWORD()
267 : : {
268 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Password"));
[ # # ][ # # ]
269 : 0 : return sProp;
270 : : }
271 : :
272 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_TITLE()
273 : : {
274 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Title"));
[ # # ][ # # ]
275 : 0 : return sProp;
276 : : }
277 : :
278 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_SALVAGEDFILE()
279 : : {
280 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("SalvagedFile"));
[ # # ][ # # ]
281 : 0 : return sProp;
282 : : }
283 : :
284 : 0 : const ::rtl::OUString& MediaDescriptor::PROP_VIEWONLY()
285 : : {
286 [ # # ][ # # ]: 0 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewOnly"));
[ # # ][ # # ]
287 : 0 : return sProp;
288 : : }
289 : :
290 : 8 : const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTBASEURL()
291 : : {
292 [ + + ][ + - ]: 8 : static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
[ + - ][ # # ]
293 : 8 : return sProp;
294 : : }
295 : :
296 : 1891 : MediaDescriptor::MediaDescriptor()
297 : 1891 : : SequenceAsHashMap()
298 : : {
299 : 1891 : }
300 : :
301 : 6589 : MediaDescriptor::MediaDescriptor(const css::uno::Sequence< css::beans::PropertyValue >& lSource)
302 : 6589 : : SequenceAsHashMap(lSource)
303 : : {
304 : 6589 : }
305 : :
306 : 8 : sal_Bool MediaDescriptor::isStreamReadOnly() const
307 : : {
308 [ + + ][ + - ]: 8 : static ::rtl::OUString CONTENTSCHEME_FILE( RTL_CONSTASCII_USTRINGPARAM( "file" ));
[ + - ][ # # ]
309 [ + + ][ + - ]: 8 : static ::rtl::OUString CONTENTPROP_ISREADONLY( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ));
[ + - ][ # # ]
310 : : static sal_Bool READONLY_FALLBACK = sal_False;
311 : :
312 : 8 : sal_Bool bReadOnly = READONLY_FALLBACK;
313 : :
314 : : // check for explicit readonly state
315 [ + - ][ + - ]: 8 : const_iterator pIt = find(MediaDescriptor::PROP_READONLY());
316 [ + - ][ + - ]: 8 : if (pIt != end())
317 : : {
318 [ + - ]: 8 : pIt->second >>= bReadOnly;
319 : 8 : return bReadOnly;
320 : : }
321 : :
322 : : // streams based on post data are readonly by definition
323 [ # # ][ # # ]: 0 : pIt = find(MediaDescriptor::PROP_POSTDATA());
324 [ # # ][ # # ]: 0 : if (pIt != end())
325 : 0 : return sal_True;
326 : :
327 : : // A XStream capsulate XInputStream and XOutputStream ...
328 : : // If it exists - the file must be open in read/write mode!
329 [ # # ][ # # ]: 0 : pIt = find(MediaDescriptor::PROP_STREAM());
330 [ # # ][ # # ]: 0 : if (pIt != end())
331 : 0 : return sal_False;
332 : :
333 : : // Only file system content provider is able to provide XStream
334 : : // so for this content impossibility to create XStream triggers
335 : : // switch to readonly mode.
336 : : try
337 : : {
338 [ # # ][ # # ]: 0 : css::uno::Reference< css::ucb::XContent > xContent = getUnpackedValueOrDefault(MediaDescriptor::PROP_UCBCONTENT(), css::uno::Reference< css::ucb::XContent >());
339 [ # # ]: 0 : if (xContent.is())
340 : : {
341 [ # # ][ # # ]: 0 : css::uno::Reference< css::ucb::XContentIdentifier > xId(xContent->getIdentifier(), css::uno::UNO_QUERY);
[ # # ]
342 : 0 : ::rtl::OUString aScheme;
343 [ # # ]: 0 : if (xId.is())
344 [ # # ][ # # ]: 0 : aScheme = xId->getContentProviderScheme();
345 : :
346 [ # # ]: 0 : if (aScheme.equalsIgnoreAsciiCase(CONTENTSCHEME_FILE))
347 : 0 : bReadOnly = sal_True;
348 : : else
349 : : {
350 [ # # ]: 0 : ::ucbhelper::Content aContent(xContent, css::uno::Reference< css::ucb::XCommandEnvironment >());
351 [ # # ][ # # ]: 0 : aContent.getPropertyValue(CONTENTPROP_ISREADONLY) >>= bReadOnly;
352 : 0 : }
353 : 0 : }
354 : : }
355 [ # # # ]: 0 : catch(const css::uno::RuntimeException& )
356 : 0 : { throw; }
357 [ # # ]: 0 : catch(const css::uno::Exception&)
358 : : {}
359 : :
360 : 8 : return bReadOnly;
361 : : }
362 : :
363 : : // ----------------------------------------------------------------------------
364 : :
365 : 0 : css::uno::Any MediaDescriptor::getComponentDataEntry( const ::rtl::OUString& rName ) const
366 : : {
367 : 0 : css::uno::Any aEntry;
368 [ # # ][ # # ]: 0 : SequenceAsHashMap::const_iterator aPropertyIter = find( PROP_COMPONENTDATA() );
369 [ # # ][ # # ]: 0 : if( aPropertyIter != end() )
370 [ # # ][ # # ]: 0 : return NamedValueCollection( aPropertyIter->second ).get( rName );
[ # # ][ # # ]
371 : 0 : return css::uno::Any();
372 : : }
373 : :
374 : 0 : void MediaDescriptor::setComponentDataEntry( const ::rtl::OUString& rName, const css::uno::Any& rValue )
375 : : {
376 [ # # ]: 0 : if( rValue.hasValue() )
377 : : {
378 : : // get or create the 'ComponentData' property entry
379 : 0 : css::uno::Any& rCompDataAny = operator[]( PROP_COMPONENTDATA() );
380 : : // insert the value (retain sequence type, create NamedValue elements by default)
381 [ # # ][ # # ]: 0 : bool bHasNamedValues = !rCompDataAny.hasValue() || rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >();
382 : 0 : bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >();
383 : : OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::setComponentDataEntry - incompatible 'ComponentData' property in media descriptor" );
384 [ # # ][ # # ]: 0 : if( bHasNamedValues || bHasPropValues )
385 : : {
386 : : // insert or overwrite the passed value
387 [ # # ]: 0 : SequenceAsHashMap aCompDataMap( rCompDataAny );
388 [ # # ]: 0 : aCompDataMap[ rName ] = rValue;
389 : : // write back the sequence (restore sequence with correct element type)
390 [ # # ][ # # ]: 0 : rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues );
391 : : }
392 : : }
393 : : else
394 : : {
395 : : // if an empty Any is passed, clear the entry
396 : 0 : clearComponentDataEntry( rName );
397 : : }
398 : 0 : }
399 : :
400 : 0 : void MediaDescriptor::clearComponentDataEntry( const ::rtl::OUString& rName )
401 : : {
402 [ # # ][ # # ]: 0 : SequenceAsHashMap::iterator aPropertyIter = find( PROP_COMPONENTDATA() );
403 [ # # ][ # # ]: 0 : if( aPropertyIter != end() )
404 : : {
405 [ # # ]: 0 : css::uno::Any& rCompDataAny = aPropertyIter->second;
406 [ # # ]: 0 : bool bHasNamedValues = rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >();
407 [ # # ]: 0 : bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >();
408 : : OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::clearComponentDataEntry - incompatible 'ComponentData' property in media descriptor" );
409 [ # # ][ # # ]: 0 : if( bHasNamedValues || bHasPropValues )
410 : : {
411 : : // remove the value with the passed name
412 [ # # ]: 0 : SequenceAsHashMap aCompDataMap( rCompDataAny );
413 [ # # ]: 0 : aCompDataMap.erase( rName );
414 : : // write back the sequence, or remove it completely if it is empty
415 [ # # ]: 0 : if( aCompDataMap.empty() )
416 [ # # ]: 0 : erase( aPropertyIter );
417 : : else
418 [ # # ][ # # ]: 0 : rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues );
419 : : }
420 : : }
421 : 0 : }
422 : :
423 : 1628 : sal_Bool MediaDescriptor::addInputStream()
424 : : {
425 : 1628 : return impl_addInputStream( sal_True );
426 : : }
427 : :
428 : : /*-----------------------------------------------*/
429 : 4358 : sal_Bool MediaDescriptor::addInputStreamOwnLock()
430 : : {
431 : : return impl_addInputStream(
432 [ + - ]: 8716 : officecfg::Office::Common::Misc::UseDocumentSystemFileLocking::get());
433 : : }
434 : :
435 : : /*-----------------------------------------------*/
436 : 5986 : sal_Bool MediaDescriptor::impl_addInputStream( sal_Bool bLockFile )
437 : : {
438 : : // check for an already existing stream item first
439 [ + - ][ + - ]: 5986 : const_iterator pIt = find(MediaDescriptor::PROP_INPUTSTREAM());
440 [ + + ][ + - ]: 5986 : if (pIt != end())
441 : 3846 : return sal_True;
442 : :
443 : : try
444 : : {
445 : : // No stream available - create a new one
446 : : // a) data comes as PostData ...
447 [ + - ][ + - ]: 2140 : pIt = find(MediaDescriptor::PROP_POSTDATA());
448 [ - + ][ + - ]: 2140 : if (pIt != end())
449 : : {
450 [ # # ]: 0 : const css::uno::Any& rPostData = pIt->second;
451 : 0 : css::uno::Reference< css::io::XInputStream > xPostData;
452 [ # # ]: 0 : rPostData >>= xPostData;
453 : :
454 [ # # ]: 0 : return impl_openStreamWithPostData( xPostData );
455 : : }
456 : :
457 : : // b) ... or we must get it from the given URL
458 [ + - ][ + - ]: 2140 : ::rtl::OUString sURL = getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), ::rtl::OUString());
459 [ + + ]: 2140 : if (sURL.isEmpty())
460 : : throw css::uno::Exception(
461 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found no URL." )),
462 [ + - ][ + - ]: 2 : css::uno::Reference< css::uno::XInterface >());
463 : :
464 : : // Parse URL! Only the main part has to be used further. E.g. a jumpmark can make trouble
465 [ + - ]: 2138 : ::rtl::OUString sNormalizedURL = impl_normalizeURL( sURL );
466 [ + - ][ - + ]: 2140 : return impl_openStreamWithURL( sNormalizedURL, bLockFile );
467 : : }
468 : : #if OSL_DEBUG_LEVEL > 0
469 : : catch(const css::uno::Exception& ex)
470 : : {
471 : : ::rtl::OUStringBuffer sMsg(256);
472 : : sMsg.appendAscii("Invalid MediaDescriptor detected:\n");
473 : : sMsg.append (ex.Message );
474 : : OSL_FAIL(::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr());
475 : : }
476 : : #else
477 [ + - ]: 2 : catch(const css::uno::Exception&)
478 : : {}
479 : : #endif
480 : :
481 : 5986 : return sal_False;
482 : : }
483 : :
484 : 0 : sal_Bool MediaDescriptor::impl_openStreamWithPostData( const css::uno::Reference< css::io::XInputStream >& _rxPostData )
485 : : throw(::com::sun::star::uno::RuntimeException)
486 : : {
487 [ # # ]: 0 : if ( !_rxPostData.is() )
488 : : throw css::lang::IllegalArgumentException(
489 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found invalid PostData." )),
490 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >(), 1);
491 : :
492 : : // PostData can't be used in read/write mode!
493 [ # # ][ # # ]: 0 : (*this)[MediaDescriptor::PROP_READONLY()] <<= sal_True;
[ # # ]
494 : :
495 : : // prepare the environment
496 : : css::uno::Reference< css::task::XInteractionHandler > xInteraction = getUnpackedValueOrDefault(
497 [ # # ]: 0 : MediaDescriptor::PROP_INTERACTIONHANDLER(),
498 [ # # ]: 0 : css::uno::Reference< css::task::XInteractionHandler >());
499 : 0 : css::uno::Reference< css::ucb::XProgressHandler > xProgress;
500 [ # # ]: 0 : ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress);
501 [ # # ][ # # ]: 0 : css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY);
502 : :
503 : : // media type
504 [ # # ][ # # ]: 0 : ::rtl::OUString sMediaType = getUnpackedValueOrDefault(MediaDescriptor::PROP_MEDIATYPE(), ::rtl::OUString());
505 [ # # ]: 0 : if (sMediaType.isEmpty())
506 : : {
507 [ # # ]: 0 : sMediaType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-www-form-urlencoded" ));
508 [ # # ][ # # ]: 0 : (*this)[MediaDescriptor::PROP_MEDIATYPE()] <<= sMediaType;
[ # # ]
509 : : }
510 : :
511 : : // url
512 [ # # ][ # # ]: 0 : ::rtl::OUString sURL( getUnpackedValueOrDefault( PROP_URL(), ::rtl::OUString() ) );
513 : :
514 : 0 : css::uno::Reference< css::io::XInputStream > xResultStream;
515 : : try
516 : : {
517 : : // seek PostData stream to the beginning
518 [ # # ]: 0 : css::uno::Reference< css::io::XSeekable > xSeek( _rxPostData, css::uno::UNO_QUERY );
519 [ # # ]: 0 : if ( xSeek.is() )
520 [ # # ][ # # ]: 0 : xSeek->seek( 0 );
521 : :
522 : : // a content for the URL
523 [ # # ]: 0 : ::ucbhelper::Content aContent( sURL, xCommandEnv );
524 : :
525 : : // use post command
526 [ # # ]: 0 : css::ucb::PostCommandArgument2 aPostArgument;
527 [ # # ]: 0 : aPostArgument.Source = _rxPostData;
528 [ # # ][ # # ]: 0 : css::uno::Reference< css::io::XActiveDataSink > xSink( new ucbhelper::ActiveDataSink );
[ # # ]
529 [ # # ]: 0 : aPostArgument.Sink = xSink;
530 : 0 : aPostArgument.MediaType = sMediaType;
531 [ # # ][ # # ]: 0 : aPostArgument.Referer = getUnpackedValueOrDefault( PROP_REFERRER(), ::rtl::OUString() );
532 : :
533 [ # # ]: 0 : ::rtl::OUString sCommandName( RTL_CONSTASCII_USTRINGPARAM( "post" ) );
534 [ # # ][ # # ]: 0 : aContent.executeCommand( sCommandName, css::uno::makeAny( aPostArgument ) );
535 : :
536 : : // get result
537 [ # # ][ # # ]: 0 : xResultStream = xSink->getInputStream();
[ # # ][ # # ]
[ # # ][ # # ]
538 : : }
539 [ # # ]: 0 : catch( const css::uno::Exception& )
540 : : {
541 : : }
542 : :
543 : : // success?
544 [ # # ]: 0 : if ( !xResultStream.is() )
545 : : {
546 : : OSL_FAIL( "no valid reply to the HTTP-Post" );
547 : 0 : return sal_False;
548 : : }
549 : :
550 [ # # ][ # # ]: 0 : (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xResultStream;
[ # # ]
551 : 0 : return sal_True;
552 : : }
553 : :
554 : : /*-----------------------------------------------*/
555 : 2138 : sal_Bool MediaDescriptor::impl_openStreamWithURL( const ::rtl::OUString& sURL, sal_Bool bLockFile )
556 : : throw(::com::sun::star::uno::RuntimeException)
557 : : {
558 : : // prepare the environment
559 : : css::uno::Reference< css::task::XInteractionHandler > xOrgInteraction = getUnpackedValueOrDefault(
560 [ + - ]: 2138 : MediaDescriptor::PROP_INTERACTIONHANDLER(),
561 [ + - ]: 4276 : css::uno::Reference< css::task::XInteractionHandler >());
562 : :
563 [ + - ]: 2138 : StillReadWriteInteraction* pInteraction = new StillReadWriteInteraction(xOrgInteraction);
564 [ + - ][ + - ]: 2138 : css::uno::Reference< css::task::XInteractionHandler > xInteraction(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY);
565 : :
566 : 2138 : css::uno::Reference< css::ucb::XProgressHandler > xProgress;
567 [ + - ]: 2138 : ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress);
568 [ + - ][ + - ]: 2138 : css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY);
569 : :
570 : : // try to create the content
571 : : // no content -> no stream => return immediatly with FALSE
572 [ + - ]: 2138 : ::ucbhelper::Content aContent;
573 : 2138 : css::uno::Reference< css::ucb::XContent > xContent;
574 : : try
575 : : {
576 [ + - ][ + - ]: 2138 : aContent = ::ucbhelper::Content(sURL, xCommandEnv);
[ + - ]
577 [ + - ][ + - ]: 2138 : xContent = aContent.get();
578 : : }
579 [ # # # # ]: 0 : catch(const css::uno::RuntimeException&)
580 : 0 : { throw; }
581 [ # # ]: 0 : catch(const css::ucb::ContentCreationException&)
582 : 0 : { return sal_False; } // TODO error handling
583 [ # # ]: 0 : catch(const css::uno::Exception&)
584 : 0 : { return sal_False; } // TODO error handling
585 : :
586 : : // try to open the file in read/write mode
587 : : // (if its allowed to do so).
588 : : // But handle errors in a "hidden mode". Because
589 : : // we try it readonly later - if read/write isnt an option.
590 : 2138 : css::uno::Reference< css::io::XStream > xStream ;
591 : 2138 : css::uno::Reference< css::io::XInputStream > xInputStream;
592 : :
593 : 2138 : sal_Bool bReadOnly = sal_False;
594 : 2138 : sal_Bool bModeRequestedExplicitly = sal_False;
595 [ + - ][ + - ]: 2138 : const_iterator pIt = find(MediaDescriptor::PROP_READONLY());
596 [ + + ][ + - ]: 2138 : if (pIt != end())
597 : : {
598 [ + - ]: 626 : pIt->second >>= bReadOnly;
599 : 626 : bModeRequestedExplicitly = sal_True;
600 : : }
601 : :
602 [ + + ][ + + ]: 2138 : if ( !bReadOnly && bLockFile )
603 : : {
604 : : try
605 : : {
606 : : // TODO: use "special" still interaction to supress error messages
607 [ + + ][ + - ]: 954 : xStream = aContent.openWriteableStream();
608 [ + - ]: 934 : if (xStream.is())
609 [ + - ][ + - ]: 934 : xInputStream = xStream->getInputStream();
[ + - ]
610 : : }
611 : 0 : catch(const css::uno::RuntimeException&)
612 : 0 : { throw; }
613 [ - - + ]: 40 : catch(const css::uno::Exception&)
[ + - ]
614 : : {
615 : : // ignore exception, if reason was problem reasoned on
616 : : // open it in WRITEABLE mode! Then we try it READONLY
617 : : // later a second time.
618 : : // All other errors must be handled as real error an
619 : : // break this method.
620 [ + - ][ - + ]: 20 : if (!pInteraction->wasWriteError() || bModeRequestedExplicitly)
[ - + ][ - + ]
621 : 0 : return sal_False;
622 : 20 : xStream.clear();
623 [ + - ]: 40 : xInputStream.clear();
624 : : }
625 : : }
626 : :
627 : : // If opening of the stream in read/write mode wasnt allowed
628 : : // or failed by an error - we must try it in readonly mode.
629 [ + + ]: 2138 : if (!xInputStream.is())
630 : : {
631 : 1204 : rtl::OUString aScheme;
632 : :
633 : : try
634 : : {
635 : : css::uno::Reference< css::ucb::XContentIdentifier > xContId(
636 [ + - ][ + - ]: 1204 : aContent.get().is() ? aContent.get()->getIdentifier() : 0 );
[ + - ][ + - ]
[ # # ][ + - ]
[ # # ][ + - ]
637 : :
638 [ + - ]: 1204 : if ( xContId.is() )
639 [ + - ][ + - ]: 1204 : aScheme = xContId->getContentProviderScheme();
640 : :
641 : : // Only file system content provider is able to provide XStream
642 : : // so for this content impossibility to create XStream triggers
643 : : // switch to readonly mode in case of opening with locking on
644 [ + + ][ + - ]: 1204 : if( bLockFile && aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file")) )
[ + + ]
645 : 619 : bReadOnly = sal_True;
646 : : else
647 : : {
648 : 585 : sal_Bool bRequestReadOnly = bReadOnly;
649 [ + - ][ + + ]: 585 : aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bReadOnly;
650 [ # # ][ # # ]: 567 : if ( bReadOnly && !bRequestReadOnly && bModeRequestedExplicitly )
[ - + ]
651 : 1186 : return sal_False; // the document is explicitly requested with WRITEABLE mode
652 [ + - ]: 1204 : }
653 : : }
654 [ - - + ]: 18 : catch(const css::uno::RuntimeException&)
655 : 0 : { throw; }
656 [ + - ]: 18 : catch(const css::uno::Exception&)
657 : : { /* no error handling if IsReadOnly property does not exist for UCP */ }
658 : :
659 [ + + ]: 1204 : if ( bReadOnly )
660 [ + - ][ + - ]: 637 : (*this)[MediaDescriptor::PROP_READONLY()] <<= bReadOnly;
[ + - ]
661 : :
662 [ + - ]: 1204 : pInteraction->resetInterceptions();
663 [ + - ]: 1204 : pInteraction->resetErrorStates();
664 : : try
665 : : {
666 : : // all the contents except file-URLs should be opened as usual
667 [ + + ][ - + ]: 1204 : if ( bLockFile || !aScheme.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file")) )
[ + + ]
668 [ + + ][ + - ]: 619 : xInputStream = aContent.openStream();
669 : : else
670 [ + + ][ + - ]: 1167 : xInputStream = aContent.openStreamNoLock();
671 : : }
672 [ - - + ]: 55 : catch(const css::uno::RuntimeException&)
673 : 0 : { throw; }
674 [ + - ]: 55 : catch(const css::uno::Exception&)
675 [ + + ]: 1204 : { return sal_False; }
676 : : }
677 : :
678 : : // add streams to the descriptor
679 [ + - ]: 2083 : if (xContent.is())
680 [ + - ][ + - ]: 2083 : (*this)[MediaDescriptor::PROP_UCBCONTENT()] <<= xContent;
[ + - ]
681 [ + + ]: 2083 : if (xStream.is())
682 [ + - ][ + - ]: 934 : (*this)[MediaDescriptor::PROP_STREAM()] <<= xStream;
[ + - ]
683 [ + - ]: 2083 : if (xInputStream.is())
684 [ + - ][ + - ]: 2083 : (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xInputStream;
[ + - ]
685 : :
686 : : // At least we need an input stream. The r/w stream is optional ...
687 [ + - ]: 2138 : return xInputStream.is();
688 : : }
689 : :
690 : 2138 : ::rtl::OUString MediaDescriptor::impl_normalizeURL(const ::rtl::OUString& sURL)
691 : : {
692 : : /* Remove Jumpmarks (fragments) of an URL only here.
693 : : They are not part of any URL and as a result may be
694 : : no ucb content can be created then.
695 : : On the other side arguments must exists ... because
696 : : they are part of an URL.
697 : :
698 : : Do not use the URLTransformer service here. Because
699 : : it parses the URL in another way. It's main part isnt enough
700 : : and it's complete part contains the jumpmark (fragment) parameter ...
701 : : */
702 [ + + ][ + - ]: 2138 : static ::rtl::OUString SERVICENAME_URIREFERENCEFACTORY( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" ));
[ + - ][ # # ]
703 : :
704 : : try
705 : : {
706 [ + - ]: 2138 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
707 [ + - ][ + - ]: 2138 : css::uno::Reference< css::uri::XUriReferenceFactory > xUriFactory(xSMGR->createInstance(SERVICENAME_URIREFERENCEFACTORY), css::uno::UNO_QUERY_THROW);
[ + - ]
708 [ + - ][ + - ]: 2138 : css::uno::Reference< css::uri::XUriReference > xUriRef = xUriFactory->parse(sURL);
709 [ + - ]: 2138 : if (xUriRef.is())
710 : : {
711 [ + - ][ + - ]: 2138 : xUriRef->clearFragment();
712 [ + - ][ + - ]: 2138 : return xUriRef->getUriReference();
713 [ + - ][ + - ]: 2138 : }
[ - + ]
714 : : }
715 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
716 : 0 : { throw; }
717 : 0 : catch(const css::uno::Exception&)
718 : : {}
719 : :
720 : : // If an error ocurred ... return the original URL.
721 : : // It's a try .-)
722 : 2138 : return sURL;
723 : : }
724 : :
725 : : } // namespace comphelper
726 : :
727 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|