Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : :
36 : : #include "osl/diagnose.h"
37 : : #include "osl/doublecheckedlocking.h"
38 : : #include "rtl/ustrbuf.hxx"
39 : :
40 : : #include "com/sun/star/beans/PropertyAttribute.hpp"
41 : : #include "com/sun/star/beans/PropertyValue.hpp"
42 : : #include "com/sun/star/beans/XPropertySet.hpp"
43 : : #include "com/sun/star/embed/ElementModes.hpp"
44 : : #include "com/sun/star/embed/XStorage.hpp"
45 : : #include "com/sun/star/embed/XTransactedObject.hpp"
46 : : #include "com/sun/star/io/XActiveDataSink.hpp"
47 : : #include "com/sun/star/io/XActiveDataStreamer.hpp"
48 : : #include "com/sun/star/lang/IllegalAccessException.hpp"
49 : : #include "com/sun/star/sdbc/XRow.hpp"
50 : : #include "com/sun/star/ucb/ContentAction.hpp"
51 : : #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
52 : : #include "com/sun/star/ucb/InsertCommandArgument.hpp"
53 : : #include "com/sun/star/ucb/InteractiveBadTransferURLException.hpp"
54 : : #include "com/sun/star/ucb/MissingInputStreamException.hpp"
55 : : #include "com/sun/star/ucb/MissingPropertiesException.hpp"
56 : : #include "com/sun/star/ucb/NameClash.hpp"
57 : : #include "com/sun/star/ucb/NameClashException.hpp"
58 : : #include "com/sun/star/ucb/OpenCommandArgument2.hpp"
59 : : #include "com/sun/star/ucb/OpenMode.hpp"
60 : : #include "com/sun/star/ucb/TransferInfo.hpp"
61 : : #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
62 : : #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
63 : : #include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
64 : : #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
65 : : #include "com/sun/star/ucb/XCommandInfo.hpp"
66 : : #include "com/sun/star/ucb/XPersistentPropertySet.hpp"
67 : :
68 : : #include "ucbhelper/cancelcommandexecution.hxx"
69 : : #include "ucbhelper/contentidentifier.hxx"
70 : : #include "ucbhelper/propertyvalueset.hxx"
71 : :
72 : : #include "tdoc_content.hxx"
73 : : #include "tdoc_resultset.hxx"
74 : : #include "tdoc_passwordrequest.hxx"
75 : :
76 : : #include "../inc/urihelper.hxx"
77 : :
78 : : using namespace com::sun::star;
79 : : using namespace tdoc_ucp;
80 : :
81 : : //=========================================================================
82 : 0 : static ContentType lcl_getContentType( const rtl::OUString & rType )
83 : : {
84 [ # # ]: 0 : if ( rType == TDOC_ROOT_CONTENT_TYPE )
85 : 0 : return ROOT;
86 [ # # ]: 0 : else if ( rType == TDOC_DOCUMENT_CONTENT_TYPE )
87 : 0 : return DOCUMENT;
88 [ # # ]: 0 : else if ( rType == TDOC_FOLDER_CONTENT_TYPE )
89 : 0 : return FOLDER;
90 [ # # ]: 0 : else if ( rType == TDOC_STREAM_CONTENT_TYPE )
91 : 0 : return STREAM;
92 : : else
93 : : {
94 : : OSL_FAIL( "Content::Content - unsupported content type string" );
95 : 0 : return STREAM;
96 : : }
97 : : }
98 : :
99 : : //=========================================================================
100 : : //=========================================================================
101 : : //
102 : : // Content Implementation.
103 : : //
104 : : //=========================================================================
105 : : //=========================================================================
106 : :
107 : : // static ( "virtual" ctor )
108 : 95 : Content* Content::create(
109 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
110 : : ContentProvider* pProvider,
111 : : const uno::Reference< ucb::XContentIdentifier >& Identifier )
112 : : {
113 : : // Fail, if resource does not exist.
114 : 95 : ContentProperties aProps;
115 [ - + ]: 95 : if ( !Content::loadData( pProvider,
116 [ + - ]: 95 : Uri( Identifier->getContentIdentifier() ),
117 [ + - ][ + - ]: 95 : aProps ) )
118 : 0 : return 0;
119 : :
120 [ + - ]: 95 : return new Content( rxSMgr, pProvider, Identifier, aProps );
121 : : }
122 : :
123 : : //=========================================================================
124 : : // static ( "virtual" ctor )
125 : 0 : Content* Content::create(
126 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
127 : : ContentProvider* pProvider,
128 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
129 : : const ucb::ContentInfo& Info )
130 : : {
131 [ # # ]: 0 : if ( Info.Type.isEmpty() )
132 : 0 : return 0;
133 : :
134 [ # # ][ # # ]: 0 : if ( Info.Type != TDOC_FOLDER_CONTENT_TYPE && Info.Type != TDOC_STREAM_CONTENT_TYPE )
[ # # ]
135 : : {
136 : : OSL_FAIL( "Content::create - unsupported content type!" );
137 : 0 : return 0;
138 : : }
139 : :
140 [ # # ]: 0 : return new Content( rxSMgr, pProvider, Identifier, Info );
141 : : }
142 : :
143 : : //=========================================================================
144 : 95 : Content::Content(
145 : : const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
146 : : ContentProvider * pProvider,
147 : : const uno::Reference< ucb::XContentIdentifier > & Identifier,
148 : : const ContentProperties & rProps )
149 : : : ContentImplHelper( rxSMgr, pProvider, Identifier ),
150 : : m_aProps( rProps ),
151 : : m_eState( PERSISTENT ),
152 [ + - ]: 95 : m_pProvider( pProvider )
153 : : {
154 : 95 : }
155 : :
156 : : //=========================================================================
157 : : // ctor for a content just created via XContentCreator::createNewContent()
158 : 0 : Content::Content(
159 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
160 : : ContentProvider* pProvider,
161 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
162 : : const ucb::ContentInfo& Info )
163 : : : ContentImplHelper( rxSMgr, pProvider, Identifier ),
164 [ # # ]: 0 : m_aProps( lcl_getContentType( Info.Type ), rtl::OUString() ), // no Title (yet)
165 : : m_eState( TRANSIENT ),
166 [ # # ][ # # ]: 0 : m_pProvider( pProvider )
167 : : {
168 : 0 : }
169 : :
170 : : //=========================================================================
171 : : // virtual
172 : 95 : Content::~Content()
173 : : {
174 [ - + ]: 190 : }
175 : :
176 : : //=========================================================================
177 : : //
178 : : // XInterface methods.
179 : : //
180 : : //=========================================================================
181 : :
182 : : // virtual
183 : 685 : void SAL_CALL Content::acquire()
184 : : throw( )
185 : : {
186 : 685 : ContentImplHelper::acquire();
187 : 685 : }
188 : :
189 : : //=========================================================================
190 : : // virtual
191 : 685 : void SAL_CALL Content::release()
192 : : throw( )
193 : : {
194 : 685 : ContentImplHelper::release();
195 : 685 : }
196 : :
197 : : //=========================================================================
198 : : // virtual
199 : 90 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
200 : : throw ( uno::RuntimeException )
201 : : {
202 [ + - ]: 90 : uno::Any aRet = ContentImplHelper::queryInterface( rType );
203 : :
204 [ - + ]: 90 : if ( !aRet.hasValue() )
205 : : {
206 : : aRet = cppu::queryInterface(
207 [ # # ]: 0 : rType, static_cast< ucb::XContentCreator * >( this ) );
208 [ # # ]: 0 : if ( aRet.hasValue() )
209 : : {
210 [ # # ]: 0 : if ( !m_aProps.isContentCreator() )
211 : 0 : return uno::Any();
212 : : }
213 : : }
214 : :
215 : 90 : return aRet;
216 : : }
217 : :
218 : : //=========================================================================
219 : : //
220 : : // XTypeProvider methods.
221 : : //
222 : : //=========================================================================
223 : :
224 [ # # ][ # # ]: 0 : XTYPEPROVIDER_COMMON_IMPL( Content );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
225 : :
226 : : //=========================================================================
227 : : // virtual
228 : 0 : uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
229 : : throw( uno::RuntimeException )
230 : : {
231 : 0 : cppu::OTypeCollection * pCollection = 0;
232 : :
233 [ # # ]: 0 : if ( m_aProps.isContentCreator() )
234 : : {
235 : : static cppu::OTypeCollection* pFolderTypes = 0;
236 : :
237 : 0 : pCollection = pFolderTypes;
238 [ # # ]: 0 : if ( !pCollection )
239 : : {
240 [ # # ][ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
241 : :
242 : 0 : pCollection = pFolderTypes;
243 [ # # ]: 0 : if ( !pCollection )
244 : : {
245 : : static cppu::OTypeCollection aCollection(
246 [ # # ]: 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
247 [ # # ]: 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
248 [ # # ]: 0 : CPPU_TYPE_REF( lang::XComponent ),
249 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XContent ),
250 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
251 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
252 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
253 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
254 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
255 [ # # ]: 0 : CPPU_TYPE_REF( container::XChild ),
256 [ # # ][ # # ]: 0 : CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
257 : 0 : pCollection = &aCollection;
258 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
259 : 0 : pFolderTypes = pCollection;
260 [ # # ]: 0 : }
261 : : }
262 : : else {
263 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
264 : : }
265 : : }
266 : : else
267 : : {
268 : : static cppu::OTypeCollection* pDocumentTypes = 0;
269 : :
270 : 0 : pCollection = pDocumentTypes;
271 [ # # ]: 0 : if ( !pCollection )
272 : : {
273 [ # # ][ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
274 : :
275 : 0 : pCollection = pDocumentTypes;
276 [ # # ]: 0 : if ( !pCollection )
277 : : {
278 : : static cppu::OTypeCollection aCollection(
279 [ # # ]: 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
280 [ # # ]: 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
281 [ # # ]: 0 : CPPU_TYPE_REF( lang::XComponent ),
282 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XContent ),
283 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
284 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
285 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
286 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
287 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
288 [ # # ][ # # ]: 0 : CPPU_TYPE_REF( container::XChild ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
289 : 0 : pCollection = &aCollection;
290 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
291 : 0 : pDocumentTypes = pCollection;
292 [ # # ]: 0 : }
293 : : }
294 : : else {
295 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
296 : : }
297 : : }
298 : :
299 : 0 : return (*pCollection).getTypes();
300 : : }
301 : :
302 : : //=========================================================================
303 : : //
304 : : // XServiceInfo methods.
305 : : //
306 : : //=========================================================================
307 : :
308 : : // virtual
309 : 0 : rtl::OUString SAL_CALL Content::getImplementationName()
310 : : throw( uno::RuntimeException )
311 : : {
312 : 0 : return rtl::OUString( "com.sun.star.comp.ucb.TransientDocumentsContent" );
313 : : }
314 : :
315 : : //=========================================================================
316 : : // virtual
317 : 0 : uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
318 : : throw( uno::RuntimeException )
319 : : {
320 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
321 : :
322 [ # # ]: 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
323 : :
324 [ # # ]: 0 : if ( m_aProps.getType() == STREAM )
325 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( TDOC_STREAM_CONTENT_SERVICE_NAME );
326 [ # # ]: 0 : else if ( m_aProps.getType() == FOLDER )
327 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( TDOC_FOLDER_CONTENT_SERVICE_NAME );
328 [ # # ]: 0 : else if ( m_aProps.getType() == DOCUMENT )
329 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( TDOC_DOCUMENT_CONTENT_SERVICE_NAME );
330 : : else
331 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( TDOC_ROOT_CONTENT_SERVICE_NAME );
332 : :
333 [ # # ]: 0 : return aSNS;
334 : : }
335 : :
336 : : //=========================================================================
337 : : //
338 : : // XContent methods.
339 : : //
340 : : //=========================================================================
341 : :
342 : : // virtual
343 : 0 : rtl::OUString SAL_CALL Content::getContentType()
344 : : throw( uno::RuntimeException )
345 : : {
346 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
347 [ # # ]: 0 : return m_aProps.getContentType();
348 : : }
349 : :
350 : : //=========================================================================
351 : : // virtual
352 : : uno::Reference< ucb::XContentIdentifier > SAL_CALL
353 : 95 : Content::getIdentifier()
354 : : throw( uno::RuntimeException )
355 : : {
356 : : {
357 [ + - ]: 95 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
358 : :
359 : : // Transient?
360 [ - + ]: 95 : if ( m_eState == TRANSIENT )
361 : : {
362 : : // Transient contents have no identifier.
363 : 95 : return uno::Reference< ucb::XContentIdentifier >();
364 [ + - ][ + - ]: 95 : }
365 : : }
366 : 95 : return ContentImplHelper::getIdentifier();
367 : : }
368 : :
369 : : //=========================================================================
370 : : //
371 : : // XCommandProcessor methods.
372 : : //
373 : : //=========================================================================
374 : :
375 : : // virtual
376 : 45 : uno::Any SAL_CALL Content::execute(
377 : : const ucb::Command& aCommand,
378 : : sal_Int32 /*CommandId*/,
379 : : const uno::Reference< ucb::XCommandEnvironment >& Environment )
380 : : throw( uno::Exception,
381 : : ucb::CommandAbortedException,
382 : : uno::RuntimeException )
383 : : {
384 : 45 : uno::Any aRet;
385 : :
386 [ + - ]: 45 : if ( aCommand.Name == "getPropertyValues" )
387 : : {
388 : : //////////////////////////////////////////////////////////////////
389 : : // getPropertyValues
390 : : //////////////////////////////////////////////////////////////////
391 : :
392 [ + - ]: 45 : uno::Sequence< beans::Property > Properties;
393 [ + - ][ - + ]: 45 : if ( !( aCommand.Argument >>= Properties ) )
394 : : {
395 : : ucbhelper::cancelCommandExecution(
396 : : uno::makeAny( lang::IllegalArgumentException(
397 : : rtl::OUString( "Wrong argument type!" ),
398 : : static_cast< cppu::OWeakObject * >( this ),
399 : : -1 ) ),
400 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
401 : : // Unreachable
402 : : }
403 : :
404 [ + - ][ + - ]: 45 : aRet <<= getPropertyValues( Properties );
[ + - ]
405 : : }
406 [ # # ]: 0 : else if ( aCommand.Name == "setPropertyValues" )
407 : : {
408 : : //////////////////////////////////////////////////////////////////
409 : : // setPropertyValues
410 : : //////////////////////////////////////////////////////////////////
411 : :
412 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aProperties;
413 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aProperties ) )
414 : : {
415 : : ucbhelper::cancelCommandExecution(
416 : : uno::makeAny( lang::IllegalArgumentException(
417 : : rtl::OUString( "Wrong argument type!" ),
418 : : static_cast< cppu::OWeakObject * >( this ),
419 : : -1 ) ),
420 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
421 : : // Unreachable
422 : : }
423 : :
424 [ # # ]: 0 : if ( !aProperties.getLength() )
425 : : {
426 : : ucbhelper::cancelCommandExecution(
427 : : uno::makeAny( lang::IllegalArgumentException(
428 : : rtl::OUString( "No properties!" ),
429 : : static_cast< cppu::OWeakObject * >( this ),
430 : : -1 ) ),
431 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
432 : : // Unreachable
433 : : }
434 : :
435 [ # # ][ # # ]: 0 : aRet <<= setPropertyValues( aProperties, Environment );
[ # # ][ # # ]
436 : : }
437 [ # # ]: 0 : else if ( aCommand.Name == "getPropertySetInfo" )
438 : : {
439 : : //////////////////////////////////////////////////////////////////
440 : : // getPropertySetInfo
441 : : //////////////////////////////////////////////////////////////////
442 : :
443 [ # # ][ # # ]: 0 : aRet <<= getPropertySetInfo( Environment );
444 : : }
445 [ # # ]: 0 : else if ( aCommand.Name == "getCommandInfo" )
446 : : {
447 : : //////////////////////////////////////////////////////////////////
448 : : // getCommandInfo
449 : : //////////////////////////////////////////////////////////////////
450 : :
451 [ # # ][ # # ]: 0 : aRet <<= getCommandInfo( Environment );
452 : : }
453 [ # # ]: 0 : else if ( aCommand.Name == "open" )
454 : : {
455 : : //////////////////////////////////////////////////////////////////
456 : : // open
457 : : //////////////////////////////////////////////////////////////////
458 : :
459 [ # # ]: 0 : ucb::OpenCommandArgument2 aOpenCommand;
460 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
461 : : {
462 : : ucbhelper::cancelCommandExecution(
463 : : uno::makeAny( lang::IllegalArgumentException(
464 : : rtl::OUString( "Wrong argument type!" ),
465 : : static_cast< cppu::OWeakObject * >( this ),
466 : : -1 ) ),
467 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
468 : : // Unreachable
469 : : }
470 : :
471 [ # # ][ # # ]: 0 : aRet = open( aOpenCommand, Environment );
472 : : }
473 [ # # ]: 0 : else if ( aCommand.Name == "insert" )
474 : : {
475 : : //////////////////////////////////////////////////////////////////
476 : : // insert ( Supported by folders and streams only )
477 : : //////////////////////////////////////////////////////////////////
478 : :
479 : 0 : ContentType eType = m_aProps.getType();
480 [ # # ][ # # ]: 0 : if ( ( eType != FOLDER ) && ( eType != STREAM ) )
481 : : {
482 : : ucbhelper::cancelCommandExecution(
483 : : uno::makeAny( ucb::UnsupportedCommandException(
484 : : rtl::OUString( "insert command only supported by "
485 : : "folders and streams!" ),
486 : : static_cast< cppu::OWeakObject * >( this ) ) ),
487 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
488 : : // Unreachable
489 : : }
490 : :
491 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
492 [ # # ]: 0 : if ( eType == STREAM )
493 : : {
494 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
495 [ # # ]: 0 : Uri aParentUri( aUri.getParentUri() );
496 [ # # ][ # # ]: 0 : if ( aParentUri.isDocument() )
497 : : {
498 : : ucbhelper::cancelCommandExecution(
499 : : uno::makeAny( ucb::UnsupportedCommandException(
500 : : rtl::OUString( "insert command not supported by "
501 : : "streams that are direct children "
502 : : "of document root!" ),
503 : : static_cast< cppu::OWeakObject * >(
504 : : this ) ) ),
505 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
506 : : // Unreachable
507 : 0 : }
508 : : }
509 : : #endif
510 [ # # ]: 0 : ucb::InsertCommandArgument aArg;
511 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aArg ) )
512 : : {
513 : : ucbhelper::cancelCommandExecution(
514 : : uno::makeAny( lang::IllegalArgumentException(
515 : : rtl::OUString( "Wrong argument type!" ),
516 : : static_cast< cppu::OWeakObject * >( this ),
517 : : -1 ) ),
518 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
519 : : // Unreachable
520 : : }
521 : :
522 : : sal_Int32 nNameClash = aArg.ReplaceExisting
523 : : ? ucb::NameClash::OVERWRITE
524 [ # # ]: 0 : : ucb::NameClash::ERROR;
525 [ # # ][ # # ]: 0 : insert( aArg.Data, nNameClash, Environment );
526 : : }
527 [ # # ]: 0 : else if ( aCommand.Name == "delete" )
528 : : {
529 : : //////////////////////////////////////////////////////////////////
530 : : // delete ( Supported by folders and streams only )
531 : : //////////////////////////////////////////////////////////////////
532 : :
533 : : {
534 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
535 : :
536 : 0 : ContentType eType = m_aProps.getType();
537 [ # # ][ # # ]: 0 : if ( ( eType != FOLDER ) && ( eType != STREAM ) )
538 : : {
539 : : ucbhelper::cancelCommandExecution(
540 : : uno::makeAny( ucb::UnsupportedCommandException(
541 : : rtl::OUString( "delete command only supported by "
542 : : "folders and streams!" ),
543 : : static_cast< cppu::OWeakObject * >(
544 : : this ) ) ),
545 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
546 : : // Unreachable
547 [ # # ]: 0 : }
548 : : }
549 : :
550 : 0 : sal_Bool bDeletePhysical = sal_False;
551 : 0 : aCommand.Argument >>= bDeletePhysical;
552 [ # # ]: 0 : destroy( bDeletePhysical, Environment );
553 : :
554 : : // Remove own and all children's persistent data.
555 [ # # ][ # # ]: 0 : if ( !removeData() )
556 : : {
557 : : uno::Any aProps
558 : : = uno::makeAny(
559 : : beans::PropertyValue(
560 : : rtl::OUString( "Uri"),
561 : : -1,
562 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
563 : 0 : getContentIdentifier()),
564 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
565 : : ucbhelper::cancelCommandExecution(
566 : : ucb::IOErrorCode_CANT_WRITE,
567 : : uno::Sequence< uno::Any >(&aProps, 1),
568 : : Environment,
569 : : rtl::OUString( "Cannot remove persistent data!" ),
570 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
571 : : // Unreachable
572 : : }
573 : :
574 : : // Remove own and all children's Additional Core Properties.
575 [ # # ]: 0 : removeAdditionalPropertySet( sal_True );
576 : : }
577 [ # # ]: 0 : else if ( aCommand.Name == "transfer" )
578 : : {
579 : : //////////////////////////////////////////////////////////////////
580 : : // transfer ( Supported by document and folders only )
581 : : //////////////////////////////////////////////////////////////////
582 : :
583 : : {
584 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
585 : :
586 : 0 : ContentType eType = m_aProps.getType();
587 [ # # ][ # # ]: 0 : if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
588 : : {
589 : : ucbhelper::cancelCommandExecution(
590 : : uno::makeAny( ucb::UnsupportedCommandException(
591 : : rtl::OUString( "transfer command only supported "
592 : : "by folders and documents!" ),
593 : : static_cast< cppu::OWeakObject * >(
594 : : this ) ) ),
595 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
596 : : // Unreachable
597 [ # # ]: 0 : }
598 : : }
599 : :
600 : 0 : ucb::TransferInfo aInfo;
601 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aInfo ) )
602 : : {
603 : : OSL_FAIL( "Wrong argument type!" );
604 : : ucbhelper::cancelCommandExecution(
605 : : uno::makeAny( lang::IllegalArgumentException(
606 : : rtl::OUString( "Wrong argument type!" ),
607 : : static_cast< cppu::OWeakObject * >( this ),
608 : : -1 ) ),
609 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
610 : : // Unreachable
611 : : }
612 : :
613 [ # # ]: 0 : transfer( aInfo, Environment );
614 : : }
615 [ # # ]: 0 : else if ( aCommand.Name == "createNewContent" )
616 : : {
617 : : //////////////////////////////////////////////////////////////////
618 : : // createNewContent ( Supported by document and folders only )
619 : : //////////////////////////////////////////////////////////////////
620 : :
621 : : {
622 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
623 : :
624 : 0 : ContentType eType = m_aProps.getType();
625 [ # # ][ # # ]: 0 : if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
626 : : {
627 : : ucbhelper::cancelCommandExecution(
628 : : uno::makeAny( ucb::UnsupportedCommandException(
629 : : rtl::OUString( "createNewContent command only "
630 : : "supported by folders and "
631 : : "documents!" ),
632 : : static_cast< cppu::OWeakObject * >(
633 : : this ) ) ),
634 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
635 : : // Unreachable
636 [ # # ]: 0 : }
637 : : }
638 : :
639 [ # # ]: 0 : ucb::ContentInfo aInfo;
640 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aInfo ) )
641 : : {
642 : : OSL_FAIL( "Wrong argument type!" );
643 : : ucbhelper::cancelCommandExecution(
644 : : uno::makeAny( lang::IllegalArgumentException(
645 : : rtl::OUString( "Wrong argument type!" ),
646 : : static_cast< cppu::OWeakObject * >( this ),
647 : : -1 ) ),
648 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
649 : : // Unreachable
650 : : }
651 : :
652 [ # # ][ # # ]: 0 : aRet <<= createNewContent( aInfo );
[ # # ]
653 : : }
654 : : else
655 : : {
656 : : //////////////////////////////////////////////////////////////////
657 : : // Unsupported command
658 : : //////////////////////////////////////////////////////////////////
659 : :
660 : : ucbhelper::cancelCommandExecution(
661 : : uno::makeAny( ucb::UnsupportedCommandException(
662 : : rtl::OUString(),
663 : : static_cast< cppu::OWeakObject * >( this ) ) ),
664 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
665 : : // Unreachable
666 : : }
667 : :
668 : 45 : return aRet;
669 : : }
670 : :
671 : : //=========================================================================
672 : : // virtual
673 : 0 : void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
674 : : throw( uno::RuntimeException )
675 : : {
676 : 0 : }
677 : :
678 : : //=========================================================================
679 : : //
680 : : // XContentCreator methods.
681 : : //
682 : : //=========================================================================
683 : :
684 : : // virtual
685 : : uno::Sequence< ucb::ContentInfo > SAL_CALL
686 : 0 : Content::queryCreatableContentsInfo()
687 : : throw( uno::RuntimeException )
688 : : {
689 : 0 : return m_aProps.getCreatableContentsInfo();
690 : : }
691 : :
692 : : //=========================================================================
693 : : // virtual
694 : : uno::Reference< ucb::XContent > SAL_CALL
695 : 0 : Content::createNewContent( const ucb::ContentInfo& Info )
696 : : throw( uno::RuntimeException )
697 : : {
698 [ # # ]: 0 : if ( m_aProps.isContentCreator() )
699 : : {
700 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
701 : :
702 [ # # ]: 0 : if ( Info.Type.isEmpty() )
703 : 0 : return uno::Reference< ucb::XContent >();
704 : :
705 : 0 : sal_Bool bCreateFolder = Info.Type == TDOC_FOLDER_CONTENT_TYPE;
706 : :
707 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
708 : : // streams cannot be created as direct children of document root
709 [ # # ][ # # ]: 0 : if ( !bCreateFolder && ( m_aProps.getType() == DOCUMENT ) )
[ # # ]
710 : : {
711 : : OSL_FAIL( "Content::createNewContent - streams cannot be "
712 : : "created as direct children of document root!" );
713 : 0 : return uno::Reference< ucb::XContent >();
714 : : }
715 : : #endif
716 [ # # ][ # # ]: 0 : if ( !bCreateFolder && Info.Type != TDOC_STREAM_CONTENT_TYPE )
[ # # ]
717 : : {
718 : : OSL_FAIL( "Content::createNewContent - unsupported type!" );
719 : 0 : return uno::Reference< ucb::XContent >();
720 : : }
721 : :
722 [ # # ][ # # ]: 0 : rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
723 : :
724 : : OSL_ENSURE( !aURL.isEmpty(),
725 : : "Content::createNewContent - empty identifier!" );
726 : :
727 [ # # ]: 0 : if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
728 : 0 : aURL += rtl::OUString("/");
729 : :
730 [ # # ]: 0 : if ( bCreateFolder )
731 : 0 : aURL += rtl::OUString("New_Folder");
732 : : else
733 : 0 : aURL += rtl::OUString("New_Stream");
734 : :
735 : : uno::Reference< ucb::XContentIdentifier > xId
736 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
[ # # ]
737 : :
738 [ # # ][ # # ]: 0 : return create( m_xSMgr, m_pProvider, xId, Info );
[ # # ][ # # ]
739 : : }
740 : : else
741 : : {
742 : : OSL_FAIL( "createNewContent called on non-contentcreator object!" );
743 : 0 : return uno::Reference< ucb::XContent >();
744 : : }
745 : : }
746 : :
747 : : //=========================================================================
748 : : // virtual
749 : 0 : rtl::OUString Content::getParentURL()
750 : : {
751 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
752 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
753 [ # # ][ # # ]: 0 : return aUri.getParentUri();
754 : : }
755 : :
756 : : //=========================================================================
757 : : uno::Reference< ucb::XContentIdentifier >
758 : 0 : Content::makeNewIdentifier( const rtl::OUString& rTitle )
759 : : {
760 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
761 : :
762 : : // Assemble new content identifier...
763 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
764 [ # # ][ # # ]: 0 : rtl::OUStringBuffer aNewURL = aUri.getParentUri();
765 [ # # ]: 0 : aNewURL.append( ::ucb_impl::urihelper::encodeSegment( rTitle ) );
766 : :
767 : : return
768 : : uno::Reference< ucb::XContentIdentifier >(
769 : : new ::ucbhelper::ContentIdentifier(
770 [ # # ][ # # ]: 0 : m_xSMgr, aNewURL.makeStringAndClear() ) );
[ # # ][ # # ]
[ # # ]
771 : : }
772 : :
773 : : //=========================================================================
774 : 0 : void Content::queryChildren( ContentRefList& rChildren )
775 : : {
776 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
777 : :
778 : : // Only folders (root, documents, folders) have children.
779 [ # # ]: 0 : if ( !m_aProps.getIsFolder() )
780 : 0 : return;
781 : :
782 : : // Obtain a list with a snapshot of all currently instanciated contents
783 : : // from provider and extract the contents which are direct children
784 : : // of this content.
785 : :
786 [ # # ]: 0 : ::ucbhelper::ContentRefList aAllContents;
787 [ # # ]: 0 : m_xProvider->queryExistingContents( aAllContents );
788 : :
789 [ # # ][ # # ]: 0 : rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
790 : 0 : sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
791 : :
792 [ # # ]: 0 : if ( nURLPos != ( aURL.getLength() - 1 ) )
793 : : {
794 : : // No trailing slash found. Append.
795 : 0 : aURL += rtl::OUString("/");
796 : : }
797 : :
798 : 0 : sal_Int32 nLen = aURL.getLength();
799 : :
800 : 0 : ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
801 : 0 : ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
802 : :
803 [ # # ]: 0 : while ( it != end )
804 : : {
805 : 0 : ::ucbhelper::ContentImplHelperRef xChild = (*it);
806 : : rtl::OUString aChildURL
807 [ # # ][ # # ]: 0 : = xChild->getIdentifier()->getContentIdentifier();
[ # # ]
808 : :
809 : : // Is aURL a prefix of aChildURL?
810 [ # # ]: 0 : if ( ( aChildURL.getLength() > nLen ) &&
[ # # # # ]
811 : 0 : ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
812 : : {
813 : 0 : sal_Int32 nPos = nLen;
814 : 0 : nPos = aChildURL.indexOf( '/', nPos );
815 : :
816 [ # # ]: 0 : if ( ( nPos == -1 ) ||
[ # # # # ]
817 : 0 : ( nPos == ( aChildURL.getLength() - 1 ) ) )
818 : : {
819 : : // No further slashes / only a final slash. It's a child!
820 : : rChildren.push_back(
821 : : ContentRef(
822 [ # # ]: 0 : static_cast< Content * >( xChild.get() ) ) );
823 : : }
824 : : }
825 : 0 : ++it;
826 [ # # ][ # # ]: 0 : }
827 : : }
828 : :
829 : : //=========================================================================
830 : 0 : sal_Bool Content::exchangeIdentity(
831 : : const uno::Reference< ucb::XContentIdentifier >& xNewId )
832 : : {
833 [ # # ]: 0 : if ( !xNewId.is() )
834 : 0 : return sal_False;
835 : :
836 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
837 : :
838 [ # # ]: 0 : uno::Reference< ucb::XContent > xThis = this;
839 : :
840 : : // Already persistent?
841 [ # # ]: 0 : if ( m_eState != PERSISTENT )
842 : : {
843 : : OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
844 : 0 : return sal_False;
845 : : }
846 : :
847 : : // Only folders and streams can be renamed -> exchange identity.
848 : 0 : ContentType eType = m_aProps.getType();
849 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
850 : : {
851 : : OSL_FAIL( "Content::exchangeIdentity - "
852 : : "Not supported by root or document!" );
853 : 0 : return sal_False;
854 : : }
855 : :
856 : : // Exchange own identitity.
857 : :
858 : : // Fail, if a content with given id already exists.
859 [ # # ][ # # ]: 0 : if ( !hasData( Uri( xNewId->getContentIdentifier() ) ) )
[ # # ][ # # ]
860 : : {
861 [ # # ][ # # ]: 0 : rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
862 : :
863 [ # # ]: 0 : aGuard.clear();
864 [ # # ][ # # ]: 0 : if ( exchange( xNewId ) )
865 : : {
866 [ # # ]: 0 : if ( eType == FOLDER )
867 : : {
868 : : // Process instanciated children...
869 : :
870 [ # # ]: 0 : ContentRefList aChildren;
871 [ # # ]: 0 : queryChildren( aChildren );
872 : :
873 : 0 : ContentRefList::const_iterator it = aChildren.begin();
874 : 0 : ContentRefList::const_iterator end = aChildren.end();
875 : :
876 [ # # ]: 0 : while ( it != end )
877 : : {
878 : 0 : ContentRef xChild = (*it);
879 : :
880 : : // Create new content identifier for the child...
881 : : uno::Reference< ucb::XContentIdentifier > xOldChildId
882 [ # # ]: 0 : = xChild->getIdentifier();
883 : : rtl::OUString aOldChildURL
884 [ # # ][ # # ]: 0 : = xOldChildId->getContentIdentifier();
885 : : rtl::OUString aNewChildURL
886 : : = aOldChildURL.replaceAt(
887 : : 0,
888 : : aOldURL.getLength(),
889 [ # # ][ # # ]: 0 : xNewId->getContentIdentifier() );
890 : : uno::Reference< ucb::XContentIdentifier > xNewChildId
891 : : = new ::ucbhelper::ContentIdentifier(
892 [ # # ][ # # ]: 0 : m_xSMgr, aNewChildURL );
[ # # ]
893 : :
894 [ # # ][ # # ]: 0 : if ( !xChild->exchangeIdentity( xNewChildId ) )
895 : 0 : return sal_False;
896 : :
897 [ # # ]: 0 : ++it;
898 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
899 : : }
900 : 0 : return sal_True;
901 [ # # ]: 0 : }
902 : : }
903 : :
904 : : OSL_FAIL( "Content::exchangeIdentity - "
905 : : "Panic! Cannot exchange identity!" );
906 [ # # ]: 0 : return sal_False;
907 : : }
908 : :
909 : : //=========================================================================
910 : : // static
911 : 0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
912 : : const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
913 : : const uno::Sequence< beans::Property >& rProperties,
914 : : ContentProvider* pProvider,
915 : : const rtl::OUString& rContentId )
916 : : {
917 : 0 : ContentProperties aData;
918 [ # # ][ # # ]: 0 : if ( loadData( pProvider, rContentId, aData ) )
919 : : {
920 : : return getPropertyValues(
921 [ # # ]: 0 : rSMgr, rProperties, aData, pProvider, rContentId );
922 : : }
923 : : else
924 : : {
925 : : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
926 [ # # ]: 0 : = new ::ucbhelper::PropertyValueSet( rSMgr );
927 : :
928 : 0 : sal_Int32 nCount = rProperties.getLength();
929 [ # # ]: 0 : if ( nCount )
930 : : {
931 : 0 : const beans::Property* pProps = rProperties.getConstArray();
932 [ # # ]: 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
933 [ # # ]: 0 : xRow->appendVoid( pProps[ n ] );
934 : : }
935 : :
936 [ # # ][ # # ]: 0 : return uno::Reference< sdbc::XRow >( xRow.get() );
937 : 0 : }
938 : : }
939 : :
940 : : //=========================================================================
941 : : // static
942 : 45 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
943 : : const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
944 : : const uno::Sequence< beans::Property >& rProperties,
945 : : const ContentProperties& rData,
946 : : ContentProvider* pProvider,
947 : : const rtl::OUString& rContentId )
948 : : {
949 : : // Note: Empty sequence means "get values of all supported properties".
950 : :
951 : : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
952 [ + - ]: 45 : = new ::ucbhelper::PropertyValueSet( rSMgr );
953 : :
954 : 45 : sal_Int32 nCount = rProperties.getLength();
955 [ + - ]: 45 : if ( nCount )
956 : : {
957 : 45 : uno::Reference< beans::XPropertySet > xAdditionalPropSet;
958 : 45 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
959 : :
960 : 45 : const beans::Property* pProps = rProperties.getConstArray();
961 [ + + ]: 90 : for ( sal_Int32 n = 0; n < nCount; ++n )
962 : : {
963 : 45 : const beans::Property& rProp = pProps[ n ];
964 : :
965 : : // Process Core properties.
966 : :
967 [ - + ]: 45 : if ( rProp.Name == "ContentType" )
968 : : {
969 [ # # ]: 0 : xRow->appendString ( rProp, rData.getContentType() );
970 : : }
971 [ - + ]: 45 : else if ( rProp.Name == "Title" )
972 : : {
973 [ # # ]: 0 : xRow->appendString ( rProp, rData.getTitle() );
974 : : }
975 [ - + ]: 45 : else if ( rProp.Name == "IsDocument" )
976 : : {
977 [ # # ]: 0 : xRow->appendBoolean( rProp, rData.getIsDocument() );
978 : : }
979 [ - + ]: 45 : else if ( rProp.Name == "IsFolder" )
980 : : {
981 [ # # ]: 0 : xRow->appendBoolean( rProp, rData.getIsFolder() );
982 : : }
983 [ - + ]: 45 : else if ( rProp.Name == "CreatableContentsInfo" )
984 : : {
985 : : xRow->appendObject(
986 [ # # ][ # # ]: 0 : rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
[ # # ][ # # ]
987 : : }
988 [ - + ]: 45 : else if ( rProp.Name == "Storage" )
989 : : {
990 : : // Storage is only supported by folders.
991 : 0 : ContentType eType = rData.getType();
992 [ # # ]: 0 : if ( eType == FOLDER )
993 : : xRow->appendObject(
994 : : rProp,
995 : : uno::makeAny(
996 [ # # ][ # # ]: 0 : pProvider->queryStorageClone( rContentId ) ) );
[ # # ]
997 : : else
998 [ # # ]: 0 : xRow->appendVoid( rProp );
999 : : }
1000 [ + - ]: 45 : else if ( rProp.Name == "DocumentModel" )
1001 : : {
1002 : : // DocumentModel is only supported by documents.
1003 : 45 : ContentType eType = rData.getType();
1004 [ + - ]: 45 : if ( eType == DOCUMENT )
1005 : : xRow->appendObject(
1006 : : rProp,
1007 : : uno::makeAny(
1008 [ + - ][ + - ]: 45 : pProvider->queryDocumentModel( rContentId ) ) );
[ + - ]
1009 : : else
1010 [ # # ]: 0 : xRow->appendVoid( rProp );
1011 : : }
1012 : : else
1013 : : {
1014 : : // Not a Core Property! Maybe it's an Additional Core Property?!
1015 : :
1016 [ # # ][ # # ]: 0 : if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
[ # # ]
1017 : : {
1018 : : xAdditionalPropSet
1019 : : = uno::Reference< beans::XPropertySet >(
1020 : : pProvider->getAdditionalPropertySet( rContentId,
1021 : : sal_False ),
1022 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
1023 : 0 : bTriedToGetAdditonalPropSet = sal_True;
1024 : : }
1025 : :
1026 [ # # ]: 0 : if ( xAdditionalPropSet.is() )
1027 : : {
1028 [ # # ]: 0 : if ( !xRow->appendPropertySetValue(
1029 : : xAdditionalPropSet,
1030 [ # # ]: 0 : rProp ) )
1031 : : {
1032 : : // Append empty entry.
1033 [ # # ]: 0 : xRow->appendVoid( rProp );
1034 : : }
1035 : : }
1036 : : else
1037 : : {
1038 : : // Append empty entry.
1039 [ # # ]: 0 : xRow->appendVoid( rProp );
1040 : : }
1041 : : }
1042 : 45 : }
1043 : : }
1044 : : else
1045 : : {
1046 : : // Append all Core Properties.
1047 : : xRow->appendString (
1048 : : beans::Property( rtl::OUString("ContentType"),
1049 : : -1,
1050 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1051 : : beans::PropertyAttribute::BOUND
1052 : : | beans::PropertyAttribute::READONLY ),
1053 [ # # ]: 0 : rData.getContentType() );
1054 : :
1055 : 0 : ContentType eType = rData.getType();
1056 : :
1057 : : xRow->appendString (
1058 : : beans::Property( rtl::OUString("Title"),
1059 : : -1,
1060 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1061 : : // Title is read-only for root and documents.
1062 : : beans::PropertyAttribute::BOUND ||
1063 : : ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
1064 : : ? beans::PropertyAttribute::READONLY
1065 : : : 0 ),
1066 [ # # ]: 0 : rData.getTitle() );
1067 : : xRow->appendBoolean(
1068 : : beans::Property( rtl::OUString("IsDocument"),
1069 : : -1,
1070 [ # # ]: 0 : getCppuBooleanType(),
1071 : : beans::PropertyAttribute::BOUND
1072 : : | beans::PropertyAttribute::READONLY ),
1073 [ # # ]: 0 : rData.getIsDocument() );
1074 : : xRow->appendBoolean(
1075 : : beans::Property( rtl::OUString("IsFolder"),
1076 : : -1,
1077 [ # # ]: 0 : getCppuBooleanType(),
1078 : : beans::PropertyAttribute::BOUND
1079 : : | beans::PropertyAttribute::READONLY ),
1080 [ # # ]: 0 : rData.getIsFolder() );
1081 : : xRow->appendObject(
1082 : : beans::Property(
1083 : : rtl::OUString("CreatableContentsInfo"),
1084 : : -1,
1085 : : getCppuType( static_cast<
1086 [ # # ]: 0 : const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
1087 : : beans::PropertyAttribute::BOUND
1088 : : | beans::PropertyAttribute::READONLY ),
1089 [ # # ][ # # ]: 0 : uno::makeAny( rData.getCreatableContentsInfo() ) );
[ # # ][ # # ]
1090 : :
1091 : : // Storage is only supported by folders.
1092 [ # # ]: 0 : if ( eType == FOLDER )
1093 : : xRow->appendObject(
1094 : : beans::Property( rtl::OUString("Storage"),
1095 : : -1,
1096 : : getCppuType(
1097 : : static_cast<
1098 [ # # ]: 0 : const uno::Reference< embed::XStorage > * >( 0 ) ),
1099 : : beans::PropertyAttribute::BOUND
1100 : : | beans::PropertyAttribute::READONLY ),
1101 [ # # ][ # # ]: 0 : uno::makeAny( pProvider->queryStorageClone( rContentId ) ) );
[ # # ]
1102 : :
1103 : : // DocumentModel is only supported by documents.
1104 [ # # ]: 0 : if ( eType == DOCUMENT )
1105 : : xRow->appendObject(
1106 : : beans::Property( rtl::OUString("DocumentModel"),
1107 : : -1,
1108 : : getCppuType(
1109 : : static_cast<
1110 [ # # ]: 0 : const uno::Reference< frame::XModel > * >( 0 ) ),
1111 : : beans::PropertyAttribute::BOUND
1112 : : | beans::PropertyAttribute::READONLY ),
1113 : : uno::makeAny(
1114 [ # # ][ # # ]: 0 : pProvider->queryDocumentModel( rContentId ) ) );
[ # # ]
1115 : :
1116 : : // Append all Additional Core Properties.
1117 : :
1118 : : uno::Reference< beans::XPropertySet > xSet(
1119 : : pProvider->getAdditionalPropertySet( rContentId, sal_False ),
1120 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
1121 [ # # ]: 0 : xRow->appendPropertySet( xSet );
1122 : : }
1123 : :
1124 [ + - ][ + - ]: 45 : return uno::Reference< sdbc::XRow >( xRow.get() );
1125 : : }
1126 : :
1127 : : //=========================================================================
1128 : 45 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
1129 : : const uno::Sequence< beans::Property >& rProperties )
1130 : : {
1131 [ + - ]: 45 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1132 : : return getPropertyValues( m_xSMgr,
1133 : : rProperties,
1134 : : m_aProps,
1135 : : m_pProvider,
1136 [ + - ][ + - ]: 45 : m_xIdentifier->getContentIdentifier() );
[ + - ][ + - ]
1137 : : }
1138 : :
1139 : : //=========================================================================
1140 : 0 : uno::Sequence< uno::Any > Content::setPropertyValues(
1141 : : const uno::Sequence< beans::PropertyValue >& rValues,
1142 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1143 : : throw( uno::Exception )
1144 : : {
1145 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1146 : :
1147 [ # # ]: 0 : uno::Sequence< uno::Any > aRet( rValues.getLength() );
1148 [ # # ]: 0 : uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1149 : 0 : sal_Int32 nChanged = 0;
1150 : :
1151 [ # # ]: 0 : beans::PropertyChangeEvent aEvent;
1152 [ # # ]: 0 : aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1153 : 0 : aEvent.Further = sal_False;
1154 : : // aEvent.PropertyName =
1155 : 0 : aEvent.PropertyHandle = -1;
1156 : : // aEvent.OldValue =
1157 : : // aEvent.NewValue =
1158 : :
1159 : 0 : const beans::PropertyValue* pValues = rValues.getConstArray();
1160 : 0 : sal_Int32 nCount = rValues.getLength();
1161 : :
1162 : 0 : uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1163 : 0 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1164 : :
1165 : 0 : sal_Bool bExchange = sal_False;
1166 : 0 : rtl::OUString aOldTitle;
1167 : 0 : sal_Int32 nTitlePos = -1;
1168 : :
1169 [ # # ]: 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1170 : : {
1171 : 0 : const beans::PropertyValue& rValue = pValues[ n ];
1172 : :
1173 [ # # ]: 0 : if ( rValue.Name == "ContentType" )
1174 : : {
1175 : : // Read-only property!
1176 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1177 : : rtl::OUString( "Property is read-only!" ),
1178 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1179 : : }
1180 [ # # ]: 0 : else if ( rValue.Name == "IsDocument" )
1181 : : {
1182 : : // Read-only property!
1183 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1184 : : rtl::OUString( "Property is read-only!" ),
1185 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1186 : : }
1187 [ # # ]: 0 : else if ( rValue.Name == "IsFolder" )
1188 : : {
1189 : : // Read-only property!
1190 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1191 : : rtl::OUString( "Property is read-only!" ),
1192 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1193 : : }
1194 [ # # ]: 0 : else if ( rValue.Name == "CreatableContentsInfo" )
1195 : : {
1196 : : // Read-only property!
1197 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1198 : : rtl::OUString( "Property is read-only!" ),
1199 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1200 : : }
1201 [ # # ]: 0 : else if ( rValue.Name == "Title" )
1202 : : {
1203 : : // Title is read-only for root and documents.
1204 : 0 : ContentType eType = m_aProps.getType();
1205 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
1206 : : {
1207 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1208 : : rtl::OUString( "Property is read-only!" ),
1209 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1210 : : }
1211 : : else
1212 : : {
1213 : 0 : rtl::OUString aNewValue;
1214 [ # # ]: 0 : if ( rValue.Value >>= aNewValue )
1215 : : {
1216 : : // No empty titles!
1217 [ # # ]: 0 : if ( !aNewValue.isEmpty() )
1218 : : {
1219 [ # # ]: 0 : if ( aNewValue != m_aProps.getTitle() )
1220 : : {
1221 : : // modified title -> modified URL -> exchange !
1222 [ # # ]: 0 : if ( m_eState == PERSISTENT )
1223 : 0 : bExchange = sal_True;
1224 : :
1225 : 0 : aOldTitle = m_aProps.getTitle();
1226 : 0 : m_aProps.setTitle( aNewValue );
1227 : :
1228 : : // property change event will be sent later...
1229 : :
1230 : : // remember position within sequence of values
1231 : : // (for error handling).
1232 : 0 : nTitlePos = n;
1233 : : }
1234 : : }
1235 : : else
1236 : : {
1237 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalArgumentException(
1238 : : rtl::OUString( "Empty Title not allowed!" ),
1239 : : static_cast< cppu::OWeakObject * >( this ),
1240 [ # # ][ # # ]: 0 : -1 );
[ # # ][ # # ]
1241 : : }
1242 : : }
1243 : : else
1244 : : {
1245 [ # # ]: 0 : aRet[ n ] <<= beans::IllegalTypeException(
1246 : : rtl::OUString( "Title Property value has wrong type!" ),
1247 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1248 : 0 : }
1249 : : }
1250 : : }
1251 [ # # ]: 0 : else if ( rValue.Name == "Storage" )
1252 : : {
1253 : 0 : ContentType eType = m_aProps.getType();
1254 [ # # ]: 0 : if ( eType == FOLDER )
1255 : : {
1256 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1257 : : rtl::OUString( "Property is read-only!" ),
1258 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1259 : : }
1260 : : else
1261 : : {
1262 : : // Storage is only supported by folders.
1263 [ # # ]: 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1264 : : rtl::OUString( "Storage property only supported by folders" ),
1265 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1266 : : }
1267 : : }
1268 [ # # ]: 0 : else if ( rValue.Name == "DocumentModel" )
1269 : : {
1270 : 0 : ContentType eType = m_aProps.getType();
1271 [ # # ]: 0 : if ( eType == DOCUMENT )
1272 : : {
1273 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1274 : : rtl::OUString( "Property is read-only!" ),
1275 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1276 : : }
1277 : : else
1278 : : {
1279 : : // Storage is only supported by folders.
1280 [ # # ]: 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1281 : : rtl::OUString( "DocumentModel property only supported by "
1282 : : "documents" ),
1283 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1284 : : }
1285 : : }
1286 : : else
1287 : : {
1288 : : // Not a Core Property! Maybe it's an Additional Core Property?!
1289 : :
1290 [ # # ][ # # ]: 0 : if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
[ # # ]
1291 : : {
1292 [ # # ][ # # ]: 0 : xAdditionalPropSet = getAdditionalPropertySet( sal_False );
1293 : 0 : bTriedToGetAdditonalPropSet = sal_True;
1294 : : }
1295 : :
1296 [ # # ]: 0 : if ( xAdditionalPropSet.is() )
1297 : : {
1298 : : try
1299 : : {
1300 [ # # ]: 0 : uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
1301 [ # # ]: 0 : rValue.Name );
1302 [ # # ]: 0 : if ( aOldValue != rValue.Value )
1303 : : {
1304 [ # # ]: 0 : xAdditionalPropSet->setPropertyValue(
1305 [ # # ]: 0 : rValue.Name, rValue.Value );
1306 : :
1307 : 0 : aEvent.PropertyName = rValue.Name;
1308 : 0 : aEvent.OldValue = aOldValue;
1309 : 0 : aEvent.NewValue = rValue.Value;
1310 : :
1311 [ # # ][ # # ]: 0 : aChanges.getArray()[ nChanged ] = aEvent;
1312 : 0 : nChanged++;
1313 : 0 : }
1314 : : }
1315 [ # # ]: 0 : catch ( beans::UnknownPropertyException const & e )
1316 : : {
1317 [ # # # # ]: 0 : aRet[ n ] <<= e;
1318 : : }
1319 [ # # ]: 0 : catch ( lang::WrappedTargetException const & e )
1320 : : {
1321 [ # # # # ]: 0 : aRet[ n ] <<= e;
1322 : : }
1323 [ # # ]: 0 : catch ( beans::PropertyVetoException const & e )
1324 : : {
1325 [ # # # # ]: 0 : aRet[ n ] <<= e;
1326 : : }
1327 [ # # # # : 0 : catch ( lang::IllegalArgumentException const & e )
# # # ]
1328 : : {
1329 [ # # # # ]: 0 : aRet[ n ] <<= e;
1330 : : }
1331 : : }
1332 : : else
1333 : : {
1334 [ # # ]: 0 : aRet[ n ] <<= uno::Exception(
1335 : : rtl::OUString( "No property set for storing the value!" ),
1336 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1337 : : }
1338 : : }
1339 : : }
1340 : :
1341 [ # # ]: 0 : if ( bExchange )
1342 : : {
1343 : : uno::Reference< ucb::XContentIdentifier > xOldId
1344 : 0 : = m_xIdentifier;
1345 : : uno::Reference< ucb::XContentIdentifier > xNewId
1346 [ # # ]: 0 : = makeNewIdentifier( m_aProps.getTitle() );
1347 : :
1348 [ # # ]: 0 : aGuard.clear();
1349 [ # # ][ # # ]: 0 : if ( exchangeIdentity( xNewId ) )
1350 : : {
1351 : : // Adapt persistent data.
1352 [ # # ]: 0 : renameData( xOldId, xNewId );
1353 : :
1354 : : // Adapt Additional Core Properties.
1355 [ # # ]: 0 : renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1356 [ # # ]: 0 : xNewId->getContentIdentifier(),
1357 [ # # ][ # # ]: 0 : sal_True );
[ # # ]
1358 : : }
1359 : : else
1360 : : {
1361 : : // Roll-back.
1362 : 0 : m_aProps.setTitle( aOldTitle );
1363 : 0 : aOldTitle = rtl::OUString();
1364 : :
1365 : : // Set error .
1366 [ # # ]: 0 : aRet[ nTitlePos ] <<= uno::Exception(
1367 : : rtl::OUString("Exchange failed!"),
1368 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1369 : 0 : }
1370 : : }
1371 : :
1372 [ # # ]: 0 : if ( !aOldTitle.isEmpty() )
1373 : : {
1374 : 0 : aEvent.PropertyName = rtl::OUString("Title");
1375 [ # # ]: 0 : aEvent.OldValue = uno::makeAny( aOldTitle );
1376 [ # # ]: 0 : aEvent.NewValue = uno::makeAny( m_aProps.getTitle() );
1377 : :
1378 [ # # ][ # # ]: 0 : aChanges.getArray()[ nChanged ] = aEvent;
1379 : 0 : nChanged++;
1380 : : }
1381 : :
1382 [ # # ]: 0 : if ( nChanged > 0 )
1383 : : {
1384 : : // Save changes, if content was already made persistent.
1385 [ # # ][ # # ]: 0 : if ( !bExchange && ( m_eState == PERSISTENT ) )
1386 : : {
1387 [ # # ][ # # ]: 0 : if ( !storeData( uno::Reference< io::XInputStream >(), xEnv ) )
1388 : : {
1389 : : uno::Any aProps
1390 : : = uno::makeAny(
1391 : : beans::PropertyValue(
1392 : : rtl::OUString( "Uri"),
1393 : : -1,
1394 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1395 : 0 : getContentIdentifier()),
1396 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1397 : : ucbhelper::cancelCommandExecution(
1398 : : ucb::IOErrorCode_CANT_WRITE,
1399 : : uno::Sequence< uno::Any >(&aProps, 1),
1400 : : xEnv,
1401 : : rtl::OUString( "Cannot store persistent data!" ),
1402 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1403 : : // Unreachable
1404 : : }
1405 : : }
1406 : :
1407 [ # # ]: 0 : aChanges.realloc( nChanged );
1408 : :
1409 [ # # ]: 0 : aGuard.clear();
1410 [ # # ]: 0 : notifyPropertiesChange( aChanges );
1411 : : }
1412 : :
1413 [ # # ][ # # ]: 0 : return aRet;
[ # # ]
1414 : : }
1415 : :
1416 : : //=========================================================================
1417 : 0 : uno::Any Content::open(
1418 : : const ucb::OpenCommandArgument2& rArg,
1419 : : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1420 : : throw( uno::Exception )
1421 : : {
1422 [ # # ][ # # ]: 0 : if ( rArg.Mode == ucb::OpenMode::ALL ||
[ # # ]
1423 : : rArg.Mode == ucb::OpenMode::FOLDERS ||
1424 : : rArg.Mode == ucb::OpenMode::DOCUMENTS )
1425 : : {
1426 : : //////////////////////////////////////////////////////////////////
1427 : : // open command for a folder content
1428 : : //////////////////////////////////////////////////////////////////
1429 : :
1430 : : uno::Reference< ucb::XDynamicResultSet > xSet
1431 [ # # ][ # # ]: 0 : = new DynamicResultSet( m_xSMgr, this, rArg );
[ # # ]
1432 [ # # ]: 0 : return uno::makeAny( xSet );
1433 : : }
1434 : : else
1435 : : {
1436 : : //////////////////////////////////////////////////////////////////
1437 : : // open command for a document content
1438 : : //////////////////////////////////////////////////////////////////
1439 : :
1440 [ # # ][ # # ]: 0 : if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1441 : : ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1442 : : {
1443 : : // Currently(?) unsupported.
1444 : : ucbhelper::cancelCommandExecution(
1445 : : uno::makeAny( ucb::UnsupportedOpenModeException(
1446 : : rtl::OUString(),
1447 : : static_cast< cppu::OWeakObject * >( this ),
1448 : : sal_Int16( rArg.Mode ) ) ),
1449 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1450 : : // Unreachable
1451 : : }
1452 : :
1453 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1454 : :
1455 [ # # ][ # # ]: 0 : rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
1456 : :
1457 : : uno::Reference< io::XActiveDataStreamer > xDataStreamer(
1458 [ # # ]: 0 : rArg.Sink, uno::UNO_QUERY );
1459 [ # # ]: 0 : if ( xDataStreamer.is() )
1460 : : {
1461 : : // May throw CommandFailedException, DocumentPasswordRequest!
1462 [ # # ]: 0 : uno::Reference< io::XStream > xStream = getStream( xEnv );
1463 [ # # ]: 0 : if ( !xStream.is() )
1464 : : {
1465 : : // No interaction if we are not persistent!
1466 : : uno::Any aProps
1467 : : = uno::makeAny(
1468 : : beans::PropertyValue(
1469 : : rtl::OUString( "Uri"),
1470 : : -1,
1471 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1472 : 0 : getContentIdentifier()),
1473 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1474 : : ucbhelper::cancelCommandExecution(
1475 : : ucb::IOErrorCode_CANT_READ,
1476 : : uno::Sequence< uno::Any >(&aProps, 1),
1477 : : m_eState == PERSISTENT
1478 : : ? xEnv
1479 : : : uno::Reference< ucb::XCommandEnvironment >(),
1480 : : rtl::OUString( "Got no data stream!" ),
1481 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
[ # # ]
1482 : : // Unreachable
1483 : : }
1484 : :
1485 : : // Done.
1486 [ # # ][ # # ]: 0 : xDataStreamer->setStream( xStream );
1487 : : }
1488 : : else
1489 : : {
1490 [ # # ]: 0 : uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1491 [ # # ]: 0 : if ( xOut.is() )
1492 : : {
1493 : : // PUSH: write data into xOut
1494 : :
1495 : : // May throw CommandFailedException, DocumentPasswordRequest!
1496 [ # # ]: 0 : uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
1497 [ # # ]: 0 : if ( !xIn.is() )
1498 : : {
1499 : : // No interaction if we are not persistent!
1500 : : uno::Any aProps
1501 : : = uno::makeAny(
1502 : : beans::PropertyValue(
1503 : : rtl::OUString( "Uri"),
1504 : : -1,
1505 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1506 : 0 : getContentIdentifier()),
1507 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1508 : : ucbhelper::cancelCommandExecution(
1509 : : ucb::IOErrorCode_CANT_READ,
1510 : : uno::Sequence< uno::Any >(&aProps, 1),
1511 : : m_eState == PERSISTENT
1512 : : ? xEnv
1513 : : : uno::Reference< ucb::XCommandEnvironment >(),
1514 : : rtl::OUString("Got no data stream!"),
1515 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
[ # # ]
1516 : : // Unreachable
1517 : : }
1518 : :
1519 : : try
1520 : : {
1521 [ # # ]: 0 : uno::Sequence< sal_Int8 > aBuffer;
1522 [ # # ][ # # ]: 0 : sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1523 : :
1524 [ # # ]: 0 : while ( nRead > 0 )
1525 : : {
1526 [ # # ]: 0 : aBuffer.realloc( nRead );
1527 [ # # ][ # # ]: 0 : xOut->writeBytes( aBuffer );
1528 [ # # ]: 0 : aBuffer.realloc( 0 );
1529 [ # # ][ # # ]: 0 : nRead = xIn->readSomeBytes( aBuffer, 65536 );
1530 : : }
1531 : :
1532 [ # # ][ # # ]: 0 : xOut->closeOutput();
[ # # ]
[ # # # # ]
1533 : : }
1534 [ # # ]: 0 : catch ( io::NotConnectedException const & )
1535 : : {
1536 : : // closeOutput, readSomeBytes, writeBytes
1537 : : }
1538 [ # # ]: 0 : catch ( io::BufferSizeExceededException const & )
1539 : : {
1540 : : // closeOutput, readSomeBytes, writeBytes
1541 : : }
1542 [ # # ]: 0 : catch ( io::IOException const & )
1543 : : {
1544 : : // closeOutput, readSomeBytes, writeBytes
1545 : 0 : }
1546 : : }
1547 : : else
1548 : : {
1549 : : uno::Reference< io::XActiveDataSink > xDataSink(
1550 [ # # ]: 0 : rArg.Sink, uno::UNO_QUERY );
1551 [ # # ]: 0 : if ( xDataSink.is() )
1552 : : {
1553 : : // PULL: wait for client read
1554 : :
1555 : : // May throw CommandFailedException, DocumentPasswordRequest!
1556 [ # # ]: 0 : uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
1557 [ # # ]: 0 : if ( !xIn.is() )
1558 : : {
1559 : : // No interaction if we are not persistent!
1560 : : uno::Any aProps
1561 : : = uno::makeAny(
1562 : : beans::PropertyValue(
1563 : : rtl::OUString( "Uri"),
1564 : : -1,
1565 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1566 : 0 : getContentIdentifier()),
1567 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1568 : : ucbhelper::cancelCommandExecution(
1569 : : ucb::IOErrorCode_CANT_READ,
1570 : : uno::Sequence< uno::Any >(&aProps, 1),
1571 : : m_eState == PERSISTENT
1572 : : ? xEnv
1573 : : : uno::Reference<
1574 : : ucb::XCommandEnvironment >(),
1575 : : rtl::OUString( "Got no data stream!" ),
1576 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
[ # # ]
1577 : : // Unreachable
1578 : : }
1579 : :
1580 : : // Done.
1581 [ # # ][ # # ]: 0 : xDataSink->setInputStream( xIn );
1582 : : }
1583 : : else
1584 : : {
1585 : : ucbhelper::cancelCommandExecution(
1586 : : uno::makeAny(
1587 : : ucb::UnsupportedDataSinkException(
1588 : : rtl::OUString(),
1589 : : static_cast< cppu::OWeakObject * >( this ),
1590 : : rArg.Sink ) ),
1591 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1592 : : // Unreachable
1593 : 0 : }
1594 : 0 : }
1595 [ # # ]: 0 : }
1596 : : }
1597 : :
1598 : 0 : return uno::Any();
1599 : : }
1600 : :
1601 : : //=========================================================================
1602 : 0 : void Content::insert( const uno::Reference< io::XInputStream >& xData,
1603 : : sal_Int32 nNameClashResolve,
1604 : : const uno::Reference<
1605 : : ucb::XCommandEnvironment > & xEnv )
1606 : : throw( uno::Exception )
1607 : : {
1608 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1609 : :
1610 : 0 : ContentType eType = m_aProps.getType();
1611 : :
1612 : : OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
1613 : : "insert command only supported by streams and folders!" );
1614 : :
1615 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
1616 : :
1617 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
1618 : : #if OSL_DEBUG_LEVEL > 0
1619 : : if ( eType == STREAM )
1620 : : {
1621 : : Uri aParentUri( aUri.getParentUri() );
1622 : : OSL_ENSURE( !aParentUri.isDocument(),
1623 : : "insert command not supported by streams that are direct "
1624 : : "children of document root!" );
1625 : : }
1626 : : #endif
1627 : : #endif
1628 : :
1629 : : // Check, if all required properties were set.
1630 [ # # ]: 0 : if ( eType == FOLDER )
1631 : : {
1632 : : // Required: Title
1633 : :
1634 [ # # ]: 0 : if ( m_aProps.getTitle().isEmpty() )
1635 [ # # ]: 0 : m_aProps.setTitle( aUri.getDecodedName() );
1636 : : }
1637 : : else // stream
1638 : : {
1639 : : // Required: data
1640 : :
1641 [ # # ]: 0 : if ( !xData.is() )
1642 : : {
1643 : : ucbhelper::cancelCommandExecution(
1644 : : uno::makeAny( ucb::MissingInputStreamException(
1645 : : rtl::OUString(),
1646 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1647 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1648 : : // Unreachable
1649 : : }
1650 : :
1651 : : // Required: Title
1652 : :
1653 [ # # ]: 0 : if ( m_aProps.getTitle().isEmpty() )
1654 [ # # ]: 0 : m_aProps.setTitle( aUri.getDecodedName() );
1655 : : }
1656 : :
1657 [ # # ][ # # ]: 0 : rtl::OUStringBuffer aNewURL = aUri.getParentUri();
1658 [ # # ]: 0 : aNewURL.append( m_aProps.getTitle() );
1659 [ # # ]: 0 : Uri aNewUri( aNewURL.makeStringAndClear() );
1660 : :
1661 : : // Handle possible name clash...
1662 [ # # # # ]: 0 : switch ( nNameClashResolve )
1663 : : {
1664 : : // fail.
1665 : : case ucb::NameClash::ERROR:
1666 [ # # ][ # # ]: 0 : if ( hasData( aNewUri ) )
1667 : : {
1668 : : ucbhelper::cancelCommandExecution(
1669 : : uno::makeAny( ucb::NameClashException(
1670 : : rtl::OUString(),
1671 : : static_cast< cppu::OWeakObject * >( this ),
1672 : : task::InteractionClassification_ERROR,
1673 : 0 : m_aProps.getTitle() ) ),
1674 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1675 : : // Unreachable
1676 : : }
1677 : 0 : break;
1678 : :
1679 : : // replace (possibly) existing object.
1680 : : case ucb::NameClash::OVERWRITE:
1681 : 0 : break;
1682 : :
1683 : : // "invent" a new valid title.
1684 : : case ucb::NameClash::RENAME:
1685 [ # # ][ # # ]: 0 : if ( hasData( aNewUri ) )
1686 : : {
1687 : 0 : sal_Int32 nTry = 0;
1688 : :
1689 [ # # ][ # # ]: 0 : do
[ # # ]
1690 : : {
1691 [ # # ][ # # ]: 0 : rtl::OUStringBuffer aNew = aNewUri.getUri();
1692 [ # # ]: 0 : aNew.appendAscii( "_" );
1693 [ # # ]: 0 : aNew.append( rtl::OUString::valueOf( ++nTry ) );
1694 [ # # ]: 0 : aNewUri.setUri( aNew.makeStringAndClear() );
1695 : : }
1696 [ # # ]: 0 : while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1697 : :
1698 [ # # ]: 0 : if ( nTry == 1000 )
1699 : : {
1700 : : ucbhelper::cancelCommandExecution(
1701 : : uno::makeAny(
1702 : : ucb::UnsupportedNameClashException(
1703 : : rtl::OUString( "Unable to resolve name clash!" ),
1704 : : static_cast< cppu::OWeakObject * >( this ),
1705 : : nNameClashResolve ) ),
1706 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1707 : : // Unreachable
1708 : : }
1709 : : else
1710 : : {
1711 [ # # ]: 0 : rtl::OUStringBuffer aNewTitle = m_aProps.getTitle();
1712 [ # # ]: 0 : aNewTitle.appendAscii( "_" );
1713 [ # # ]: 0 : aNewTitle.append( rtl::OUString::valueOf( ++nTry ) );
1714 [ # # ]: 0 : m_aProps.setTitle( aNewTitle.makeStringAndClear() );
1715 : : }
1716 : : }
1717 : 0 : break;
1718 : :
1719 : : case ucb::NameClash::KEEP: // deprecated
1720 : : case ucb::NameClash::ASK:
1721 : : default:
1722 [ # # ][ # # ]: 0 : if ( hasData( aNewUri ) )
1723 : : {
1724 : : ucbhelper::cancelCommandExecution(
1725 : : uno::makeAny(
1726 : : ucb::UnsupportedNameClashException(
1727 : : rtl::OUString(),
1728 : : static_cast< cppu::OWeakObject * >( this ),
1729 : : nNameClashResolve ) ),
1730 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1731 : : // Unreachable
1732 : : }
1733 : 0 : break;
1734 : : }
1735 : :
1736 : : // Identifier changed?
1737 [ # # ]: 0 : sal_Bool bNewId = ( aUri != aNewUri );
1738 : :
1739 [ # # ]: 0 : if ( bNewId )
1740 : : {
1741 : : m_xIdentifier
1742 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewUri.getUri() );
[ # # ][ # # ]
1743 : : }
1744 : :
1745 [ # # ][ # # ]: 0 : if ( !storeData( xData, xEnv ) )
1746 : : {
1747 : : uno::Any aProps
1748 : : = uno::makeAny(beans::PropertyValue(
1749 : : rtl::OUString( "Uri"),
1750 : : -1,
1751 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1752 : 0 : getContentIdentifier()),
1753 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1754 : : ucbhelper::cancelCommandExecution(
1755 : : ucb::IOErrorCode_CANT_WRITE,
1756 : : uno::Sequence< uno::Any >(&aProps, 1),
1757 : : xEnv,
1758 : : rtl::OUString("Cannot store persistent data!"),
1759 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1760 : : // Unreachable
1761 : : }
1762 : :
1763 : 0 : m_eState = PERSISTENT;
1764 : :
1765 [ # # ]: 0 : if ( bNewId )
1766 : : {
1767 : : //loadData( m_pProvider, m_aUri, m_aProps );
1768 : :
1769 [ # # ]: 0 : aGuard.clear();
1770 [ # # ]: 0 : inserted();
1771 [ # # ]: 0 : }
1772 : 0 : }
1773 : :
1774 : : //=========================================================================
1775 : 0 : void Content::destroy( sal_Bool bDeletePhysical,
1776 : : const uno::Reference<
1777 : : ucb::XCommandEnvironment > & xEnv )
1778 : : throw( uno::Exception )
1779 : : {
1780 : : // @@@ take care about bDeletePhysical -> trashcan support
1781 : :
1782 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1783 : :
1784 : 0 : ContentType eType = m_aProps.getType();
1785 : :
1786 : : OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
1787 : : "delete command only supported by streams and folders!" );
1788 : :
1789 [ # # ]: 0 : uno::Reference< ucb::XContent > xThis = this;
1790 : :
1791 : : // Persistent?
1792 [ # # ]: 0 : if ( m_eState != PERSISTENT )
1793 : : {
1794 : : ucbhelper::cancelCommandExecution(
1795 : : uno::makeAny( ucb::UnsupportedCommandException(
1796 : : rtl::OUString( "Not persistent!" ),
1797 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1798 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1799 : : // Unreachable
1800 : : }
1801 : :
1802 : 0 : m_eState = DEAD;
1803 : :
1804 [ # # ]: 0 : aGuard.clear();
1805 [ # # ]: 0 : deleted();
1806 : :
1807 [ # # ]: 0 : if ( eType == FOLDER )
1808 : : {
1809 : : // Process instanciated children...
1810 : :
1811 [ # # ]: 0 : ContentRefList aChildren;
1812 [ # # ]: 0 : queryChildren( aChildren );
1813 : :
1814 : 0 : ContentRefList::const_iterator it = aChildren.begin();
1815 : 0 : ContentRefList::const_iterator end = aChildren.end();
1816 : :
1817 [ # # ]: 0 : while ( it != end )
1818 : : {
1819 [ # # ]: 0 : (*it)->destroy( bDeletePhysical, xEnv );
1820 : 0 : ++it;
1821 : 0 : }
1822 [ # # ]: 0 : }
1823 : 0 : }
1824 : :
1825 : : //=========================================================================
1826 : 0 : void Content::notifyDocumentClosed()
1827 : : {
1828 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1829 : :
1830 : 0 : m_eState = DEAD;
1831 : :
1832 : : // @@@ anything else to reset or such?
1833 : :
1834 : : // callback follows!
1835 [ # # ]: 0 : aGuard.clear();
1836 : :
1837 : : // Propagate destruction to content event listeners
1838 : : // Remove this from provider's content list.
1839 [ # # ][ # # ]: 0 : deleted();
1840 : 0 : }
1841 : :
1842 : : //=========================================================================
1843 : : uno::Reference< ucb::XContent >
1844 : 0 : Content::queryChildContent( const rtl::OUString & rRelativeChildUri )
1845 : : {
1846 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1847 : :
1848 [ # # ][ # # ]: 0 : const rtl::OUString aMyId = getIdentifier()->getContentIdentifier();
[ # # ]
1849 [ # # ]: 0 : rtl::OUStringBuffer aBuf( aMyId );
1850 [ # # ]: 0 : if ( aMyId.getStr()[ aMyId.getLength() - 1 ] != sal_Unicode( '/' ) )
1851 [ # # ]: 0 : aBuf.appendAscii( "/" );
1852 [ # # ]: 0 : if ( rRelativeChildUri.getStr()[ 0 ] != sal_Unicode( '/' ) )
1853 [ # # ]: 0 : aBuf.append( rRelativeChildUri );
1854 : : else
1855 [ # # ]: 0 : aBuf.append( rRelativeChildUri.copy( 1 ) );
1856 : :
1857 : : uno::Reference< ucb::XContentIdentifier > xChildId
1858 : : = new ::ucbhelper::ContentIdentifier(
1859 [ # # ][ # # ]: 0 : m_xSMgr, aBuf.makeStringAndClear() );
[ # # ][ # # ]
1860 : :
1861 : 0 : uno::Reference< ucb::XContent > xChild;
1862 : : try
1863 : : {
1864 [ # # ][ # # ]: 0 : xChild = m_pProvider->queryContent( xChildId );
[ # # ]
1865 : : }
1866 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
1867 : : {
1868 : : // handled below.
1869 : : }
1870 : :
1871 : : OSL_ENSURE( xChild.is(),
1872 : : "Content::queryChildContent - unable to create child content!" );
1873 [ # # ]: 0 : return xChild;
1874 : : }
1875 : :
1876 : : //=========================================================================
1877 : 0 : void Content::notifyChildRemoved( const rtl::OUString & rRelativeChildUri )
1878 : : {
1879 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1880 : :
1881 : : // Ugly! Need to create child content object, just to fill event properly.
1882 : : uno::Reference< ucb::XContent > xChild
1883 [ # # ]: 0 : = queryChildContent( rRelativeChildUri );
1884 : :
1885 [ # # ]: 0 : if ( xChild.is() )
1886 : : {
1887 : : // callback follows!
1888 [ # # ]: 0 : aGuard.clear();
1889 : :
1890 : : // Notify "REMOVED" event.
1891 : : ucb::ContentEvent aEvt(
1892 : : static_cast< cppu::OWeakObject * >( this ),
1893 : : ucb::ContentAction::REMOVED,
1894 : : xChild,
1895 [ # # ][ # # ]: 0 : getIdentifier() );
[ # # ]
1896 [ # # ][ # # ]: 0 : notifyContentEvent( aEvt );
1897 [ # # ]: 0 : }
1898 : 0 : }
1899 : :
1900 : : //=========================================================================
1901 : 0 : void Content::notifyChildInserted( const rtl::OUString & rRelativeChildUri )
1902 : : {
1903 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1904 : :
1905 : : // Ugly! Need to create child content object, just to fill event properly.
1906 : : uno::Reference< ucb::XContent > xChild
1907 [ # # ]: 0 : = queryChildContent( rRelativeChildUri );
1908 : :
1909 [ # # ]: 0 : if ( xChild.is() )
1910 : : {
1911 : : // callback follows!
1912 [ # # ]: 0 : aGuard.clear();
1913 : :
1914 : : // Notify "INSERTED" event.
1915 : : ucb::ContentEvent aEvt(
1916 : : static_cast< cppu::OWeakObject * >( this ),
1917 : : ucb::ContentAction::INSERTED,
1918 : : xChild,
1919 [ # # ][ # # ]: 0 : getIdentifier() );
[ # # ]
1920 [ # # ][ # # ]: 0 : notifyContentEvent( aEvt );
1921 [ # # ]: 0 : }
1922 : 0 : }
1923 : :
1924 : : //=========================================================================
1925 : 0 : void Content::transfer(
1926 : : const ucb::TransferInfo& rInfo,
1927 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1928 : : throw( uno::Exception )
1929 : : {
1930 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1931 : :
1932 : : // Persistent?
1933 [ # # ]: 0 : if ( m_eState != PERSISTENT )
1934 : : {
1935 : : ucbhelper::cancelCommandExecution(
1936 : : uno::makeAny( ucb::UnsupportedCommandException(
1937 : : rtl::OUString( "Not persistent!" ),
1938 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1939 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1940 : : // Unreachable
1941 : : }
1942 : :
1943 : : // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
1944 : :
1945 [ # # ]: 0 : if ( ( rInfo.SourceURL.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
1946 : : {
1947 : : // Invaild length (to short).
1948 : : ucbhelper::cancelCommandExecution(
1949 : : uno::makeAny( ucb::InteractiveBadTransferURLException(
1950 : : rtl::OUString(),
1951 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1952 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1953 : : // Unreachable
1954 : : }
1955 : :
1956 : : rtl::OUString aScheme
1957 : : = rInfo.SourceURL.copy( 0, TDOC_URL_SCHEME_LENGTH + 2 )
1958 : 0 : .toAsciiLowerCase();
1959 [ # # ]: 0 : if ( aScheme != TDOC_URL_SCHEME ":/" )
1960 : : {
1961 : : // Invalid scheme.
1962 : : ucbhelper::cancelCommandExecution(
1963 : : uno::makeAny( ucb::InteractiveBadTransferURLException(
1964 : : rtl::OUString(),
1965 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1966 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1967 : : // Unreachable
1968 : : }
1969 : :
1970 : : // Does source URI describe a tdoc folder or stream?
1971 : 0 : Uri aSourceUri( rInfo.SourceURL );
1972 [ # # ][ # # ]: 0 : if ( !aSourceUri.isValid() )
1973 : : {
1974 : : ucbhelper::cancelCommandExecution(
1975 : : uno::makeAny( lang::IllegalArgumentException(
1976 : : rtl::OUString( "Invalid source URI! Syntax!" ),
1977 : : static_cast< cppu::OWeakObject * >( this ),
1978 : : -1 ) ),
1979 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1980 : : // Unreachable
1981 : : }
1982 : :
1983 [ # # ][ # # ]: 0 : if ( aSourceUri.isRoot() || aSourceUri.isDocument() )
[ # # ][ # # ]
[ # # ]
1984 : : {
1985 : : ucbhelper::cancelCommandExecution(
1986 : : uno::makeAny( lang::IllegalArgumentException(
1987 : : rtl::OUString( "Invalid source URI! "
1988 : : "Must describe a folder or stream!" ),
1989 : : static_cast< cppu::OWeakObject * >( this ),
1990 : : -1 ) ),
1991 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1992 : : // Unreachable
1993 : : }
1994 : :
1995 : : // Is source not a parent of me / not me?
1996 [ # # ][ # # ]: 0 : rtl::OUString aId = m_xIdentifier->getContentIdentifier();
1997 : 0 : sal_Int32 nPos = aId.lastIndexOf( '/' );
1998 [ # # ]: 0 : if ( nPos != ( aId.getLength() - 1 ) )
1999 : : {
2000 : : // No trailing slash found. Append.
2001 : 0 : aId += rtl::OUString("/");
2002 : : }
2003 : :
2004 [ # # ]: 0 : if ( rInfo.SourceURL.getLength() <= aId.getLength() )
2005 : : {
2006 [ # # ]: 0 : if ( aId.compareTo(
2007 : 0 : rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
2008 : : {
2009 : : uno::Any aProps
2010 : : = uno::makeAny(beans::PropertyValue(
2011 : : rtl::OUString( "Uri"),
2012 : : -1,
2013 : : uno::makeAny( rInfo.SourceURL ),
2014 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2015 : : ucbhelper::cancelCommandExecution(
2016 : : ucb::IOErrorCode_RECURSIVE,
2017 : : uno::Sequence< uno::Any >(&aProps, 1),
2018 : : xEnv,
2019 : : rtl::OUString( "Target is equal to or is a child of source!" ),
2020 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2021 : : // Unreachable
2022 : : }
2023 : : }
2024 : :
2025 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
2026 [ # # ]: 0 : if ( m_aProps.getType() == DOCUMENT )
2027 : : {
2028 : 0 : bool bOK = false;
2029 : :
2030 : : uno::Reference< embed::XStorage > xStorage
2031 : : = m_pProvider->queryStorage(
2032 [ # # ][ # # ]: 0 : aSourceUri.getParentUri(), READ_WRITE_NOCREATE );
2033 [ # # ]: 0 : if ( xStorage.is() )
2034 : : {
2035 : : try
2036 : : {
2037 [ # # ][ # # ]: 0 : if ( xStorage->isStreamElement( aSourceUri.getDecodedName() ) )
[ # # ][ # # ]
2038 : : {
2039 : : ucbhelper::cancelCommandExecution(
2040 : : uno::makeAny( lang::IllegalArgumentException(
2041 : : rtl::OUString( "Invalid source URI! "
2042 : : "Streams cannot be created as "
2043 : : "children of document root!" ),
2044 : : static_cast< cppu::OWeakObject * >(
2045 : : this ),
2046 : : -1 ) ),
2047 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2048 : : // Unreachable
2049 : : }
2050 : 0 : bOK = true;
2051 : : }
2052 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
2053 : : {
2054 : : // handled below.
2055 : : }
2056 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2057 : : {
2058 : : // handled below.
2059 : : }
2060 [ # # ]: 0 : catch ( embed::InvalidStorageException const & )
2061 : : {
2062 : : // handled below.
2063 : : }
2064 : : }
2065 : :
2066 [ # # ]: 0 : if ( !bOK )
2067 : : {
2068 : : ucbhelper::cancelCommandExecution(
2069 : : uno::makeAny( lang::IllegalArgumentException(
2070 : : rtl::OUString( "Invalid source URI! "
2071 : : "Unabale to determine source type!" ),
2072 : : static_cast< cppu::OWeakObject * >( this ),
2073 : : -1 ) ),
2074 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
2075 : : // Unreachable
2076 : 0 : }
2077 : : }
2078 : : #endif
2079 : :
2080 : : /////////////////////////////////////////////////////////////////////////
2081 : : // Copy data.
2082 : : /////////////////////////////////////////////////////////////////////////
2083 : :
2084 : 0 : rtl::OUString aNewName( !rInfo.NewTitle.isEmpty()
2085 : : ? rInfo.NewTitle
2086 [ # # ][ # # ]: 0 : : aSourceUri.getDecodedName() );
2087 : :
2088 [ # # ][ # # ]: 0 : if ( !copyData( aSourceUri, aNewName ) )
2089 : : {
2090 : : uno::Any aProps
2091 : : = uno::makeAny(
2092 : : beans::PropertyValue(
2093 : : rtl::OUString( "Uri"),
2094 : : -1,
2095 : : uno::makeAny( rInfo.SourceURL ),
2096 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2097 : : ucbhelper::cancelCommandExecution(
2098 : : ucb::IOErrorCode_CANT_WRITE,
2099 : : uno::Sequence< uno::Any >(&aProps, 1),
2100 : : xEnv,
2101 : : rtl::OUString( "Cannot copy data!" ),
2102 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2103 : : // Unreachable
2104 : : }
2105 : :
2106 : : /////////////////////////////////////////////////////////////////////////
2107 : : // Copy own and all children's Additional Core Properties.
2108 : : /////////////////////////////////////////////////////////////////////////
2109 : :
2110 [ # # ][ # # ]: 0 : rtl::OUString aTargetUri = m_xIdentifier->getContentIdentifier();
2111 [ # # ]: 0 : if ( ( aTargetUri.lastIndexOf( '/' ) + 1 ) != aTargetUri.getLength() )
2112 : 0 : aTargetUri += rtl::OUString("/");
2113 : :
2114 [ # # ]: 0 : if ( !rInfo.NewTitle.isEmpty() )
2115 : 0 : aTargetUri += ::ucb_impl::urihelper::encodeSegment( rInfo.NewTitle );
2116 : : else
2117 [ # # ]: 0 : aTargetUri += aSourceUri.getName();
2118 : :
2119 [ # # ]: 0 : if ( !copyAdditionalPropertySet(
2120 [ # # ][ # # ]: 0 : aSourceUri.getUri(), aTargetUri, sal_True ) )
2121 : : {
2122 : : uno::Any aProps
2123 : : = uno::makeAny(
2124 : : beans::PropertyValue(
2125 : : rtl::OUString( "Uri"),
2126 : : -1,
2127 : : uno::makeAny( rInfo.SourceURL ),
2128 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2129 : : ucbhelper::cancelCommandExecution(
2130 : : ucb::IOErrorCode_CANT_WRITE,
2131 : : uno::Sequence< uno::Any >(&aProps, 1),
2132 : : xEnv,
2133 : : rtl::OUString( "Cannot copy additional properties!" ),
2134 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2135 : : // Unreachable
2136 : : }
2137 : :
2138 : : /////////////////////////////////////////////////////////////////////////
2139 : : // Propagate new content.
2140 : : /////////////////////////////////////////////////////////////////////////
2141 : :
2142 : 0 : rtl::Reference< Content > xTarget;
2143 : : try
2144 : : {
2145 : : uno::Reference< ucb::XContentIdentifier > xTargetId
2146 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, aTargetUri );
[ # # ]
2147 : :
2148 : : // Note: The static cast is okay here, because its sure that
2149 : : // m_xProvider is always the WebDAVContentProvider.
2150 : : xTarget = static_cast< Content * >(
2151 [ # # ][ # # ]: 0 : m_pProvider->queryContent( xTargetId ).get() );
[ # # ][ # # ]
[ # # ]
2152 : :
2153 : : }
2154 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
2155 : : {
2156 : : // queryContent
2157 : : }
2158 : :
2159 [ # # ]: 0 : if ( !xTarget.is() )
2160 : : {
2161 : : uno::Any aProps
2162 : : = uno::makeAny(beans::PropertyValue(
2163 : : rtl::OUString( "Uri"),
2164 : : -1,
2165 : : uno::makeAny( aTargetUri ),
2166 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2167 : : ucbhelper::cancelCommandExecution(
2168 : : ucb::IOErrorCode_CANT_READ,
2169 : : uno::Sequence< uno::Any >(&aProps, 1),
2170 : : xEnv,
2171 : : rtl::OUString( "Cannot instanciate target object!" ),
2172 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2173 : : // Unreachable
2174 : : }
2175 : :
2176 : : // Announce transfered content in its new folder.
2177 [ # # ]: 0 : xTarget->inserted();
2178 : :
2179 : : /////////////////////////////////////////////////////////////////////////
2180 : : // Remove source, if requested
2181 : : /////////////////////////////////////////////////////////////////////////
2182 : :
2183 [ # # ]: 0 : if ( rInfo.MoveData )
2184 : : {
2185 : 0 : rtl::Reference< Content > xSource;
2186 : : try
2187 : : {
2188 : : uno::Reference< ucb::XContentIdentifier >
2189 : : xSourceId = new ::ucbhelper::ContentIdentifier(
2190 [ # # ][ # # ]: 0 : m_xSMgr, rInfo.SourceURL );
[ # # ]
2191 : :
2192 : : // Note: The static cast is okay here, because its sure
2193 : : // that m_xProvider is always the ContentProvider.
2194 : : xSource = static_cast< Content * >(
2195 [ # # ][ # # ]: 0 : m_xProvider->queryContent( xSourceId ).get() );
[ # # ][ # # ]
[ # # ]
2196 : : }
2197 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
2198 : : {
2199 : : // queryContent
2200 : : }
2201 : :
2202 [ # # ]: 0 : if ( !xSource.is() )
2203 : : {
2204 : : uno::Any aProps
2205 : : = uno::makeAny(beans::PropertyValue(
2206 : : rtl::OUString( "Uri"),
2207 : : -1,
2208 : : uno::makeAny( rInfo.SourceURL ),
2209 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2210 : : ucbhelper::cancelCommandExecution(
2211 : : ucb::IOErrorCode_CANT_READ,
2212 : : uno::Sequence< uno::Any >(&aProps, 1),
2213 : : xEnv,
2214 : : rtl::OUString( "Cannot instanciate target object!" ),
2215 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2216 : : // Unreachable
2217 : : }
2218 : :
2219 : : // Propagate destruction (recursively).
2220 [ # # ]: 0 : xSource->destroy( sal_True, xEnv );
2221 : :
2222 : : // Remove all persistent data of source and its children.
2223 [ # # ][ # # ]: 0 : if ( !xSource->removeData() )
2224 : : {
2225 : : uno::Any aProps
2226 : : = uno::makeAny(
2227 : : beans::PropertyValue(
2228 : : rtl::OUString( "Uri"),
2229 : : -1,
2230 : : uno::makeAny( rInfo.SourceURL ),
2231 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2232 : : ucbhelper::cancelCommandExecution(
2233 : : ucb::IOErrorCode_CANT_WRITE,
2234 : : uno::Sequence< uno::Any >(&aProps, 1),
2235 : : xEnv,
2236 : : rtl::OUString( "Cannot remove persistent data of source object!" ),
2237 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2238 : : // Unreachable
2239 : : }
2240 : :
2241 : : // Remove own and all children's Additional Core Properties.
2242 [ # # ][ # # ]: 0 : if ( !xSource->removeAdditionalPropertySet( sal_True ) )
2243 : : {
2244 : : uno::Any aProps
2245 : : = uno::makeAny(
2246 : : beans::PropertyValue(
2247 : : rtl::OUString( "Uri"),
2248 : : -1,
2249 : : uno::makeAny( rInfo.SourceURL ),
2250 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
2251 : : ucbhelper::cancelCommandExecution(
2252 : : ucb::IOErrorCode_CANT_WRITE,
2253 : : uno::Sequence< uno::Any >(&aProps, 1),
2254 : : xEnv,
2255 : : rtl::OUString( "Cannot remove additional properties of source object!" ),
2256 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
2257 : : // Unreachable
2258 : 0 : }
2259 : :
2260 [ # # ]: 0 : } // rInfo.MoveData
2261 : 0 : }
2262 : :
2263 : : //=========================================================================
2264 : : //static
2265 : 0 : bool Content::hasData( ContentProvider* pProvider, const Uri & rUri )
2266 : : {
2267 [ # # ]: 0 : if ( rUri.isRoot() )
2268 : : {
2269 : 0 : return true; // root has no storage
2270 : : }
2271 [ # # ]: 0 : else if ( rUri.isDocument() )
2272 : : {
2273 : : uno::Reference< embed::XStorage > xStorage
2274 [ # # ][ # # ]: 0 : = pProvider->queryStorage( rUri.getUri(), READ );
2275 : 0 : return xStorage.is();
2276 : : }
2277 : : else
2278 : : {
2279 : : // folder or stream
2280 : :
2281 : : // Ask parent storage. In case that rUri describes a stream,
2282 : : // ContentProvider::queryStorage( rUri ) would return null.
2283 : :
2284 : : uno::Reference< embed::XStorage > xStorage
2285 [ # # ][ # # ]: 0 : = pProvider->queryStorage( rUri.getParentUri(), READ );
2286 : :
2287 [ # # ]: 0 : if ( !xStorage.is() )
2288 : 0 : return false;
2289 : :
2290 : : uno::Reference< container::XNameAccess > xParentNA(
2291 [ # # ]: 0 : xStorage, uno::UNO_QUERY );
2292 : :
2293 : : OSL_ENSURE( xParentNA.is(), "Got no css.container.XNameAccess!" );
2294 : :
2295 [ # # ][ # # ]: 0 : return xParentNA->hasByName( rUri.getDecodedName() );
[ # # ]
2296 : : }
2297 : : }
2298 : :
2299 : : //=========================================================================
2300 : : //static
2301 : 95 : bool Content::loadData( ContentProvider* pProvider,
2302 : : const Uri & rUri,
2303 : : ContentProperties& rProps )
2304 : : {
2305 [ - + ]: 95 : if ( rUri.isRoot() ) // root has no storage, but can always be created
2306 : : {
2307 : : rProps
2308 : : = ContentProperties(
2309 [ # # ]: 0 : ROOT, pProvider->queryStorageTitle( rUri.getUri() ) );
2310 : : }
2311 [ + - ]: 95 : else if ( rUri.isDocument() ) // document must have storage
2312 : : {
2313 : : uno::Reference< embed::XStorage > xStorage
2314 [ + - ][ + - ]: 95 : = pProvider->queryStorage( rUri.getUri(), READ );
2315 : :
2316 [ - + ]: 95 : if ( !xStorage.is() )
2317 : 0 : return false;
2318 : :
2319 : : rProps
2320 : : = ContentProperties(
2321 [ + - ][ + - ]: 95 : DOCUMENT, pProvider->queryStorageTitle( rUri.getUri() ) );
[ + - ][ + - ]
2322 : : }
2323 : : else // stream or folder; stream has no storage; folder has storage
2324 : : {
2325 : : uno::Reference< embed::XStorage > xStorage
2326 [ # # ][ # # ]: 0 : = pProvider->queryStorage( rUri.getParentUri(), READ );
2327 : :
2328 [ # # ]: 0 : if ( !xStorage.is() )
2329 : 0 : return false;
2330 : :
2331 : : // Check whether exists at all, is stream or folder
2332 : : try
2333 : : {
2334 : : // return: true -> folder
2335 : : // return: false -> stream
2336 : : // NoSuchElementException -> neither folder nor stream
2337 : : bool bIsFolder
2338 [ # # ][ # # ]: 0 : = xStorage->isStorageElement( rUri.getDecodedName() );
[ # # ]
2339 : :
2340 : : rProps
2341 : : = ContentProperties(
2342 : : bIsFolder ? FOLDER : STREAM,
2343 [ # # ][ # # ]: 0 : pProvider->queryStorageTitle( rUri.getUri() ) );
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2344 : : }
2345 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
2346 : : {
2347 : : // there is no element with such name
2348 : : //OSL_ENSURE( false, "Caught NoSuchElementException!" );
2349 : 0 : return false;
2350 : : }
2351 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2352 : : {
2353 : : // an illegal argument is provided
2354 : : OSL_FAIL( "Caught IllegalArgumentException!" );
2355 : 0 : return false;
2356 : : }
2357 [ # # ]: 0 : catch ( embed::InvalidStorageException const & )
2358 : : {
2359 : : // this storage is in invalid state for any reason
2360 : : OSL_FAIL( "Caught InvalidStorageException!" );
2361 : 0 : return false;
2362 : 0 : }
2363 : : }
2364 : 95 : return true;
2365 : : }
2366 : :
2367 : : //=========================================================================
2368 : 0 : bool Content::storeData( const uno::Reference< io::XInputStream >& xData,
2369 : : const uno::Reference<
2370 : : ucb::XCommandEnvironment >& xEnv )
2371 : : throw ( ucb::CommandFailedException,
2372 : : task::DocumentPasswordRequest )
2373 : : {
2374 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2375 : :
2376 : 0 : ContentType eType = m_aProps.getType();
2377 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
2378 : : {
2379 : : OSL_FAIL( "storeData not supported by root and documents!" );
2380 : 0 : return false;
2381 : : }
2382 : :
2383 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
2384 : :
2385 [ # # ]: 0 : if ( eType == FOLDER )
2386 : : {
2387 : : uno::Reference< embed::XStorage > xStorage
2388 [ # # ][ # # ]: 0 : = m_pProvider->queryStorage( aUri.getUri(), READ_WRITE_CREATE );
2389 : :
2390 [ # # ]: 0 : if ( !xStorage.is() )
2391 : 0 : return false;
2392 : :
2393 : : uno::Reference< beans::XPropertySet > xPropSet(
2394 [ # # ]: 0 : xStorage, uno::UNO_QUERY );
2395 : : OSL_ENSURE( xPropSet.is(),
2396 : : "Content::storeData - Got no XPropertySet interface!" );
2397 [ # # ]: 0 : if ( !xPropSet.is() )
2398 : 0 : return false;
2399 : :
2400 : : try
2401 : : {
2402 : : // According to MBA, if no mediatype is set, folder and all
2403 : : // its contents will be lost on save of the document!!!
2404 [ # # ]: 0 : xPropSet->setPropertyValue(
2405 : : rtl::OUString( "MediaType" ),
2406 : : uno::makeAny(
2407 : : rtl::OUString( // @@@ better mediatype
2408 [ # # ][ # # ]: 0 : "application/binary" ) ) );
[ # # # #
# ]
2409 : : }
2410 [ # # ]: 0 : catch ( beans::UnknownPropertyException const & )
2411 : : {
2412 : : OSL_FAIL( "Property MediaType not supported!" );
2413 : 0 : return false;
2414 : : }
2415 [ # # ]: 0 : catch ( beans::PropertyVetoException const & )
2416 : : {
2417 : : OSL_FAIL( "Caught PropertyVetoException!" );
2418 : 0 : return false;
2419 : : }
2420 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2421 : : {
2422 : : OSL_FAIL( "Caught IllegalArgumentException!" );
2423 : 0 : return false;
2424 : : }
2425 [ # # ]: 0 : catch ( lang::WrappedTargetException const & )
2426 : : {
2427 : : OSL_FAIL( "Caught WrappedTargetException!" );
2428 : 0 : return false;
2429 : : }
2430 : :
2431 [ # # ][ # # ]: 0 : if ( !commitStorage( xStorage ) )
2432 [ # # ][ # # ]: 0 : return false;
2433 : : }
2434 [ # # ]: 0 : else if ( eType == STREAM )
2435 : : {
2436 : : // stream
2437 : :
2438 : : // Important: Parent storage and output stream must be kept alive until
2439 : : // changes have been committed!
2440 : : uno::Reference< embed::XStorage > xStorage
2441 : : = m_pProvider->queryStorage(
2442 [ # # ][ # # ]: 0 : aUri.getParentUri(), READ_WRITE_CREATE );
2443 : 0 : uno::Reference< io::XOutputStream > xOut;
2444 : :
2445 [ # # ]: 0 : if ( !xStorage.is() )
2446 : 0 : return false;
2447 : :
2448 [ # # ]: 0 : if ( xData.is() )
2449 : : {
2450 : : // May throw CommandFailedException, DocumentPasswordRequest!
2451 [ # # ][ # # ]: 0 : xOut = getTruncatedOutputStream( xEnv );
2452 : :
2453 : : OSL_ENSURE( xOut.is(), "No target data stream!" );
2454 : :
2455 : : try
2456 : : {
2457 [ # # ]: 0 : uno::Sequence< sal_Int8 > aBuffer;
2458 [ # # ][ # # ]: 0 : sal_Int32 nRead = xData->readSomeBytes( aBuffer, 65536 );
2459 : :
2460 [ # # ]: 0 : while ( nRead > 0 )
2461 : : {
2462 [ # # ]: 0 : aBuffer.realloc( nRead );
2463 [ # # ][ # # ]: 0 : xOut->writeBytes( aBuffer );
2464 [ # # ]: 0 : aBuffer.realloc( 0 );
2465 [ # # ][ # # ]: 0 : nRead = xData->readSomeBytes( aBuffer, 65536 );
2466 : : }
2467 : :
2468 [ # # ][ # # ]: 0 : closeOutputStream( xOut );
2469 : : }
2470 [ # # ]: 0 : catch ( io::NotConnectedException const & )
2471 : : {
2472 : : // readSomeBytes, writeBytes
2473 : : OSL_FAIL( "Caught NotConnectedException!" );
2474 [ # # ]: 0 : closeOutputStream( xOut );
2475 : 0 : return false;
2476 : : }
2477 [ # # ]: 0 : catch ( io::BufferSizeExceededException const & )
2478 : : {
2479 : : // readSomeBytes, writeBytes
2480 : : OSL_FAIL( "Caught BufferSizeExceededException!" );
2481 [ # # ]: 0 : closeOutputStream( xOut );
2482 : 0 : return false;
2483 : : }
2484 [ # # ]: 0 : catch ( io::IOException const & )
2485 : : {
2486 : : // readSomeBytes, writeBytes
2487 : : OSL_FAIL( "Caught IOException!" );
2488 [ # # ]: 0 : closeOutputStream( xOut );
2489 : 0 : return false;
2490 : : }
2491 [ # # # # ]: 0 : catch ( ... )
2492 : : {
2493 [ # # ]: 0 : closeOutputStream( xOut );
2494 : 0 : throw;
2495 : : }
2496 : : }
2497 : :
2498 : : // Commit changes.
2499 [ # # ][ # # ]: 0 : if ( !commitStorage( xStorage ) )
2500 [ # # ][ # # ]: 0 : return false;
2501 : : }
2502 : : else
2503 : : {
2504 : : OSL_FAIL( "Unknown content type!" );
2505 : 0 : return false;
2506 : : }
2507 [ # # ]: 0 : return true;
2508 : : }
2509 : :
2510 : : //=========================================================================
2511 : 0 : bool Content::renameData(
2512 : : const uno::Reference< ucb::XContentIdentifier >& xOldId,
2513 : : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2514 : : {
2515 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2516 : :
2517 : 0 : ContentType eType = m_aProps.getType();
2518 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
2519 : : {
2520 : : OSL_FAIL( "renameData not supported by root and documents!" );
2521 : 0 : return false;
2522 : : }
2523 : :
2524 [ # # ][ # # ]: 0 : Uri aOldUri( xOldId->getContentIdentifier() );
2525 : : uno::Reference< embed::XStorage > xStorage
2526 : : = m_pProvider->queryStorage(
2527 [ # # ][ # # ]: 0 : aOldUri.getParentUri(), READ_WRITE_NOCREATE );
2528 : :
2529 [ # # ]: 0 : if ( !xStorage.is() )
2530 : 0 : return false;
2531 : :
2532 : : try
2533 : : {
2534 [ # # ][ # # ]: 0 : Uri aNewUri( xNewId->getContentIdentifier() );
2535 [ # # ]: 0 : xStorage->renameElement(
2536 [ # # ][ # # ]: 0 : aOldUri.getDecodedName(), aNewUri.getDecodedName() );
[ # # ][ # #
# # # #
# ]
2537 : : }
2538 [ # # ]: 0 : catch ( embed::InvalidStorageException const & )
2539 : : {
2540 : : // this storage is in invalid state for eny reason
2541 : : OSL_FAIL( "Caught InvalidStorageException!" );
2542 : 0 : return false;
2543 : : }
2544 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2545 : : {
2546 : : // an illegal argument is provided
2547 : : OSL_FAIL( "Caught IllegalArgumentException!" );
2548 : 0 : return false;
2549 : : }
2550 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
2551 : : {
2552 : : // there is no element with old name in this storage
2553 : : OSL_FAIL( "Caught NoSuchElementException!" );
2554 : 0 : return false;
2555 : : }
2556 [ # # ]: 0 : catch ( container::ElementExistException const & )
2557 : : {
2558 : : // an element with new name already exists in this storage
2559 : : OSL_FAIL( "Caught ElementExistException!" );
2560 : 0 : return false;
2561 : : }
2562 [ # # ]: 0 : catch ( io::IOException const & )
2563 : : {
2564 : : // in case of io errors during renaming
2565 : : OSL_FAIL( "Caught IOException!" );
2566 : 0 : return false;
2567 : : }
2568 [ # # ]: 0 : catch ( embed::StorageWrappedTargetException const & )
2569 : : {
2570 : : // wraps other exceptions
2571 : : OSL_FAIL( "Caught StorageWrappedTargetException!" );
2572 : 0 : return false;
2573 : : }
2574 : :
2575 [ # # ][ # # ]: 0 : return commitStorage( xStorage );
2576 : : }
2577 : :
2578 : : //=========================================================================
2579 : 0 : bool Content::removeData()
2580 : : {
2581 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2582 : :
2583 : 0 : ContentType eType = m_aProps.getType();
2584 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
2585 : : {
2586 : : OSL_FAIL( "removeData not supported by root and documents!" );
2587 : 0 : return false;
2588 : : }
2589 : :
2590 [ # # ][ # # ]: 0 : Uri aUri( m_xIdentifier->getContentIdentifier() );
2591 : : uno::Reference< embed::XStorage > xStorage
2592 : : = m_pProvider->queryStorage(
2593 [ # # ][ # # ]: 0 : aUri.getParentUri(), READ_WRITE_NOCREATE );
2594 : :
2595 [ # # ]: 0 : if ( !xStorage.is() )
2596 : 0 : return false;
2597 : :
2598 : : try
2599 : : {
2600 [ # # ][ # # ]: 0 : xStorage->removeElement( aUri.getDecodedName() );
[ # # ]
2601 : : }
2602 [ # # ]: 0 : catch ( embed::InvalidStorageException const & )
2603 : : {
2604 : : // this storage is in invalid state for eny reason
2605 : : OSL_FAIL( "Caught InvalidStorageException!" );
2606 : 0 : return false;
2607 : : }
2608 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2609 : : {
2610 : : // an illegal argument is provided
2611 : : OSL_FAIL( "Caught IllegalArgumentException!" );
2612 : 0 : return false;
2613 : : }
2614 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
2615 : : {
2616 : : // there is no element with this name in this storage
2617 : : OSL_FAIL( "Caught NoSuchElementException!" );
2618 : 0 : return false;
2619 : : }
2620 [ # # ]: 0 : catch ( io::IOException const & )
2621 : : {
2622 : : // in case of io errors during renaming
2623 : : OSL_FAIL( "Caught IOException!" );
2624 : 0 : return false;
2625 : : }
2626 [ # # ]: 0 : catch ( embed::StorageWrappedTargetException const & )
2627 : : {
2628 : : // wraps other exceptions
2629 : : OSL_FAIL( "Caught StorageWrappedTargetException!" );
2630 : 0 : return false;
2631 : : }
2632 : :
2633 [ # # ][ # # ]: 0 : return commitStorage( xStorage );
[ # # # #
# # ]
2634 : : }
2635 : :
2636 : : //=========================================================================
2637 : 0 : bool Content::copyData( const Uri & rSourceUri, const rtl::OUString & rNewName )
2638 : : {
2639 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2640 : :
2641 : 0 : ContentType eType = m_aProps.getType();
2642 [ # # ][ # # ]: 0 : if ( ( eType == ROOT ) || ( eType == STREAM ) )
2643 : : {
2644 : : OSL_FAIL( "copyData not supported by root and streams!" );
2645 : 0 : return false;
2646 : : }
2647 : :
2648 [ # # ][ # # ]: 0 : Uri aDestUri( m_xIdentifier->getContentIdentifier() );
2649 : : uno::Reference< embed::XStorage > xDestStorage
2650 [ # # ][ # # ]: 0 : = m_pProvider->queryStorage( aDestUri.getUri(), READ_WRITE_NOCREATE );
2651 : :
2652 [ # # ]: 0 : if ( !xDestStorage.is() )
2653 : 0 : return false;
2654 : :
2655 : : uno::Reference< embed::XStorage > xSourceStorage
2656 [ # # ][ # # ]: 0 : = m_pProvider->queryStorage( rSourceUri.getParentUri(), READ );
2657 : :
2658 [ # # ]: 0 : if ( !xSourceStorage.is() )
2659 : 0 : return false;
2660 : :
2661 : : try
2662 : : {
2663 [ # # ][ # # ]: 0 : xSourceStorage->copyElementTo( rSourceUri.getDecodedName(),
2664 : : xDestStorage,
2665 [ # # ]: 0 : rNewName );
2666 : : }
2667 [ # # ]: 0 : catch ( embed::InvalidStorageException const & )
2668 : : {
2669 : : // this storage is in invalid state for eny reason
2670 : : OSL_FAIL( "Caught InvalidStorageException!" );
2671 : 0 : return false;
2672 : : }
2673 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
2674 : : {
2675 : : // an illegal argument is provided
2676 : : OSL_FAIL( "Caught IllegalArgumentException!" );
2677 : 0 : return false;
2678 : : }
2679 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
2680 : : {
2681 : : // there is no element with this name in this storage
2682 : : OSL_FAIL( "Caught NoSuchElementException!" );
2683 : 0 : return false;
2684 : : }
2685 [ # # ]: 0 : catch ( container::ElementExistException const & )
2686 : : {
2687 : : // there is no element with this name in this storage
2688 : : OSL_FAIL( "Caught ElementExistException!" );
2689 : 0 : return false;
2690 : : }
2691 [ # # ]: 0 : catch ( io::IOException const & )
2692 : : {
2693 : : // in case of io errors during renaming
2694 : : OSL_FAIL( "Caught IOException!" );
2695 : 0 : return false;
2696 : : }
2697 [ # # ]: 0 : catch ( embed::StorageWrappedTargetException const & )
2698 : : {
2699 : : // wraps other exceptions
2700 : : OSL_FAIL( "Caught StorageWrappedTargetException!" );
2701 : 0 : return false;
2702 : : }
2703 : :
2704 [ # # ][ # # ]: 0 : return commitStorage( xDestStorage );
[ # # # #
# # # ]
2705 : : }
2706 : :
2707 : : //=========================================================================
2708 : : // static
2709 : 0 : bool Content::commitStorage( const uno::Reference< embed::XStorage > & xStorage )
2710 : : {
2711 : : // Commit changes
2712 [ # # ]: 0 : uno::Reference< embed::XTransactedObject > xTO( xStorage, uno::UNO_QUERY );
2713 : :
2714 : : OSL_ENSURE( xTO.is(),
2715 : : "Required interface css.embed.XTransactedObject missing!" );
2716 : : try
2717 : : {
2718 [ # # ][ # # ]: 0 : xTO->commit();
2719 : : }
2720 [ # # ]: 0 : catch ( io::IOException const & )
2721 : : {
2722 : : OSL_FAIL( "Caught IOException!" );
2723 : 0 : return false;
2724 : : }
2725 [ # # ]: 0 : catch ( lang::WrappedTargetException const & )
2726 : : {
2727 : : OSL_FAIL( "Caught WrappedTargetException!" );
2728 : 0 : return false;
2729 : : }
2730 : :
2731 [ # # # ]: 0 : return true;
2732 : : }
2733 : :
2734 : : //=========================================================================
2735 : : // static
2736 : 0 : bool Content::closeOutputStream(
2737 : : const uno::Reference< io::XOutputStream > & xOut )
2738 : : {
2739 [ # # ]: 0 : if ( xOut.is() )
2740 : : {
2741 : : try
2742 : : {
2743 [ # # ][ # # ]: 0 : xOut->closeOutput();
2744 : 0 : return true;
2745 : : }
2746 : 0 : catch ( io::NotConnectedException const & )
2747 : : {
2748 : : OSL_FAIL( "Caught NotConnectedException!" );
2749 : : }
2750 : 0 : catch ( io::BufferSizeExceededException const & )
2751 : : {
2752 : : OSL_FAIL( "Caught BufferSizeExceededException!" );
2753 : : }
2754 : 0 : catch ( io::IOException const & )
2755 : : {
2756 : : OSL_FAIL( "Caught IOException!" );
2757 : : }
2758 : : }
2759 [ # # # # ]: 0 : return false;
2760 : : }
2761 : :
2762 : : //=========================================================================
2763 : 0 : static rtl::OUString obtainPassword(
2764 : : const rtl::OUString & rName,
2765 : : task::PasswordRequestMode eMode,
2766 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2767 : : throw ( ucb::CommandFailedException,
2768 : : task::DocumentPasswordRequest )
2769 : : {
2770 : : rtl::Reference< DocumentPasswordRequest > xRequest
2771 [ # # ]: 0 : = new DocumentPasswordRequest( eMode, rName );
2772 : :
2773 [ # # ]: 0 : if ( xEnv.is() )
2774 : : {
2775 : : uno::Reference< task::XInteractionHandler > xIH
2776 [ # # ][ # # ]: 0 : = xEnv->getInteractionHandler();
2777 [ # # ]: 0 : if ( xIH.is() )
2778 : : {
2779 [ # # ][ # # ]: 0 : xIH->handle( xRequest.get() );
[ # # ][ # # ]
2780 : :
2781 : : rtl::Reference< ucbhelper::InteractionContinuation > xSelection
2782 [ # # ]: 0 : = xRequest->getSelection();
2783 : :
2784 [ # # ]: 0 : if ( xSelection.is() )
2785 : : {
2786 : : // Handler handled the request.
2787 : : uno::Reference< task::XInteractionAbort > xAbort(
2788 [ # # ]: 0 : xSelection.get(), uno::UNO_QUERY );
2789 [ # # ]: 0 : if ( xAbort.is() )
2790 : : {
2791 : : throw ucb::CommandFailedException(
2792 : : rtl::OUString( "Abort requested by Interaction Handler." ),
2793 : : uno::Reference< uno::XInterface >(),
2794 [ # # ][ # # ]: 0 : xRequest->getRequest() );
2795 : : }
2796 : :
2797 : : uno::Reference< task::XInteractionPassword > xPassword(
2798 [ # # ]: 0 : xSelection.get(), uno::UNO_QUERY );
2799 [ # # ]: 0 : if ( xPassword.is() )
2800 : : {
2801 [ # # ][ # # ]: 0 : return xPassword->getPassword();
2802 : : }
2803 : :
2804 : : // Unknown selection. Should never happen.
2805 : : throw ucb::CommandFailedException(
2806 : : rtl::OUString( "Interaction Handler selected unknown continuation!" ),
2807 : : uno::Reference< uno::XInterface >(),
2808 [ # # ][ # # ]: 0 : xRequest->getRequest() );
2809 [ # # ]: 0 : }
2810 [ # # ]: 0 : }
2811 : : }
2812 : :
2813 : : // No IH or IH did not handle exception.
2814 [ # # ]: 0 : task::DocumentPasswordRequest aRequest;
2815 [ # # ][ # # ]: 0 : xRequest->getRequest() >>= aRequest;
2816 [ # # ]: 0 : throw aRequest;
2817 : : }
2818 : :
2819 : : //=========================================================================
2820 : 0 : uno::Reference< io::XInputStream > Content::getInputStream(
2821 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2822 : : throw ( ucb::CommandFailedException,
2823 : : task::DocumentPasswordRequest )
2824 : : {
2825 : 0 : rtl::OUString aUri;
2826 : 0 : rtl::OUString aPassword;
2827 : 0 : bool bPasswordRequested = false;
2828 : :
2829 : : {
2830 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2831 : :
2832 : : OSL_ENSURE( m_aProps.getType() == STREAM,
2833 : : "Content::getInputStream - content is no stream!" );
2834 : :
2835 [ # # ][ # # ]: 0 : aUri = Uri( m_xIdentifier->getContentIdentifier() ).getUri();
[ # # ][ # # ]
2836 : : }
2837 : :
2838 : 0 : for ( ;; )
2839 : : {
2840 : : try
2841 : : {
2842 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2843 : : return uno::Reference< io::XInputStream >(
2844 [ # # ][ # # ]: 0 : m_pProvider->queryInputStream( aUri, aPassword ) );
2845 : : }
2846 [ # # # # ]: 0 : catch ( packages::WrongPasswordException const & )
2847 : : {
2848 : : // Obtain (new) password.
2849 : : aPassword
2850 : : = obtainPassword( aUri, /* @@@ find better title */
2851 : : bPasswordRequested
2852 : : ? task::PasswordRequestMode_PASSWORD_REENTER
2853 : : : task::PasswordRequestMode_PASSWORD_ENTER,
2854 [ # # # # ]: 0 : xEnv );
2855 : 0 : bPasswordRequested = true;
2856 : : }
2857 : 0 : }
2858 : : }
2859 : :
2860 : : //=========================================================================
2861 : 0 : static uno::Reference< io::XOutputStream > lcl_getTruncatedOutputStream(
2862 : : const rtl::OUString & rUri,
2863 : : ContentProvider * pProvider,
2864 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2865 : : throw ( ucb::CommandFailedException,
2866 : : task::DocumentPasswordRequest )
2867 : : {
2868 : 0 : rtl::OUString aPassword;
2869 : 0 : bool bPasswordRequested = false;
2870 : 0 : for ( ;; )
2871 : : {
2872 : : try
2873 : : {
2874 : : return uno::Reference< io::XOutputStream >(
2875 : : pProvider->queryOutputStream(
2876 [ # # ]: 0 : rUri, aPassword, true /* truncate */ ) );
2877 : : }
2878 [ # # # # ]: 0 : catch ( packages::WrongPasswordException const & )
2879 : : {
2880 : : // Obtain (new) password.
2881 : : aPassword
2882 : : = obtainPassword( rUri, /* @@@ find better title */
2883 : : bPasswordRequested
2884 : : ? task::PasswordRequestMode_PASSWORD_REENTER
2885 : : : task::PasswordRequestMode_PASSWORD_ENTER,
2886 [ # # # # ]: 0 : xEnv );
2887 : 0 : bPasswordRequested = true;
2888 : : }
2889 : 0 : }
2890 : : }
2891 : :
2892 : : //=========================================================================
2893 : 0 : uno::Reference< io::XOutputStream > Content::getTruncatedOutputStream(
2894 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2895 : : throw ( ucb::CommandFailedException,
2896 : : task::DocumentPasswordRequest )
2897 : : {
2898 : : OSL_ENSURE( m_aProps.getType() == STREAM,
2899 : : "Content::getTruncatedOutputStream - content is no stream!" );
2900 : :
2901 : : return lcl_getTruncatedOutputStream(
2902 [ # # ]: 0 : Uri( m_xIdentifier->getContentIdentifier() ).getUri(),
2903 : : m_pProvider,
2904 [ # # ]: 0 : xEnv );
2905 : : }
2906 : :
2907 : : //=========================================================================
2908 : 0 : uno::Reference< io::XStream > Content::getStream(
2909 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2910 : : throw ( ucb::CommandFailedException,
2911 : : task::DocumentPasswordRequest )
2912 : : {
2913 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2914 : :
2915 : : OSL_ENSURE( m_aProps.getType() == STREAM,
2916 : : "Content::getStream - content is no stream!" );
2917 : :
2918 [ # # ][ # # ]: 0 : rtl::OUString aUri( Uri( m_xIdentifier->getContentIdentifier() ).getUri() );
[ # # ]
2919 : 0 : rtl::OUString aPassword;
2920 : 0 : bool bPasswordRequested = false;
2921 : 0 : for ( ;; )
2922 : : {
2923 : : try
2924 : : {
2925 : : return uno::Reference< io::XStream >(
2926 : : m_pProvider->queryStream(
2927 [ # # ]: 0 : aUri, aPassword, false /* no truncate */ ) );
2928 : : }
2929 [ # # # # ]: 0 : catch ( packages::WrongPasswordException const & )
2930 : : {
2931 : : // Obtain (new) password.
2932 : : aPassword
2933 : : = obtainPassword( aUri, /* @@@ find better title */
2934 : : bPasswordRequested
2935 : : ? task::PasswordRequestMode_PASSWORD_REENTER
2936 : : : task::PasswordRequestMode_PASSWORD_ENTER,
2937 [ # # # # ]: 0 : xEnv );
2938 : 0 : bPasswordRequested = true;
2939 : : }
2940 [ # # ]: 0 : }
2941 : : }
2942 : :
2943 : : //=========================================================================
2944 : : //=========================================================================
2945 : : //
2946 : : // ContentProperties Implementation.
2947 : : //
2948 : : //=========================================================================
2949 : : //=========================================================================
2950 : :
2951 : : uno::Sequence< ucb::ContentInfo >
2952 : 0 : ContentProperties::getCreatableContentsInfo() const
2953 : : {
2954 [ # # ]: 0 : if ( isContentCreator() )
2955 : : {
2956 [ # # ]: 0 : uno::Sequence< beans::Property > aProps( 1 );
2957 : : aProps.getArray()[ 0 ] = beans::Property(
2958 : : rtl::OUString("Title"),
2959 : : -1,
2960 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
2961 [ # # ]: 0 : beans::PropertyAttribute::BOUND );
2962 : :
2963 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
2964 [ # # ]: 0 : if ( getType() == DOCUMENT )
2965 : : {
2966 : : // streams cannot be created as direct children of document root
2967 [ # # ]: 0 : uno::Sequence< ucb::ContentInfo > aSeq( 1 );
2968 : :
2969 : : // Folder.
2970 [ # # ]: 0 : aSeq.getArray()[ 0 ].Type
2971 : 0 : = rtl::OUString( TDOC_FOLDER_CONTENT_TYPE );
2972 [ # # ]: 0 : aSeq.getArray()[ 0 ].Attributes
2973 : 0 : = ucb::ContentInfoAttribute::KIND_FOLDER;
2974 [ # # ][ # # ]: 0 : aSeq.getArray()[ 0 ].Properties = aProps;
2975 : :
2976 [ # # ][ # # ]: 0 : return aSeq;
2977 : : }
2978 : : else
2979 : : {
2980 : : #endif
2981 [ # # ]: 0 : uno::Sequence< ucb::ContentInfo > aSeq( 2 );
2982 : :
2983 : : // Folder.
2984 [ # # ]: 0 : aSeq.getArray()[ 0 ].Type
2985 : 0 : = rtl::OUString( TDOC_FOLDER_CONTENT_TYPE );
2986 [ # # ]: 0 : aSeq.getArray()[ 0 ].Attributes
2987 : 0 : = ucb::ContentInfoAttribute::KIND_FOLDER;
2988 [ # # ][ # # ]: 0 : aSeq.getArray()[ 0 ].Properties = aProps;
2989 : :
2990 : : // Stream.
2991 [ # # ]: 0 : aSeq.getArray()[ 1 ].Type
2992 : 0 : = rtl::OUString( TDOC_STREAM_CONTENT_TYPE );
2993 [ # # ]: 0 : aSeq.getArray()[ 1 ].Attributes
2994 : : = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
2995 : 0 : | ucb::ContentInfoAttribute::KIND_DOCUMENT;
2996 [ # # ][ # # ]: 0 : aSeq.getArray()[ 1 ].Properties = aProps;
2997 : :
2998 [ # # ][ # # ]: 0 : return aSeq;
2999 : : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
3000 [ # # ]: 0 : }
3001 : : #endif
3002 : : }
3003 : : else
3004 : : {
3005 : : OSL_FAIL( "getCreatableContentsInfo called on non-contentcreator "
3006 : : "object!" );
3007 : :
3008 : 0 : return uno::Sequence< ucb::ContentInfo >( 0 );
3009 : : }
3010 : : }
3011 : :
3012 : : //=========================================================================
3013 : 0 : bool ContentProperties::isContentCreator() const
3014 : : {
3015 [ # # ][ # # ]: 0 : return ( getType() == FOLDER ) || ( getType() == DOCUMENT );
3016 : : }
3017 : :
3018 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|