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 : : - optimize transfer command. "Move" should be implementable much more
35 : : efficient!
36 : :
37 : : **************************************************************************
38 : :
39 : : - Root Folder vs. 'normal' Folder
40 : : - root doesn't support command 'delete'
41 : : - root doesn't support command 'insert'
42 : : - root needs not created via XContentCreator - queryContent with root
43 : : folder id ( HIERARCHY_ROOT_FOLDER_URL ) always returns a value != 0
44 : : - root has no parent.
45 : :
46 : : *************************************************************************/
47 : : #include <osl/diagnose.h>
48 : :
49 : : #include "osl/doublecheckedlocking.h"
50 : : #include <rtl/ustring.h>
51 : : #include <rtl/ustring.hxx>
52 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
53 : : #include <com/sun/star/beans/PropertyState.hpp>
54 : : #include <com/sun/star/beans/PropertyValue.hpp>
55 : : #include <com/sun/star/beans/XPropertyAccess.hpp>
56 : : #include <com/sun/star/lang/IllegalAccessException.hpp>
57 : : #include <com/sun/star/sdbc/XRow.hpp>
58 : : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
59 : : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
60 : : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
61 : : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
62 : : #include <com/sun/star/ucb/NameClash.hpp>
63 : : #include <com/sun/star/ucb/NameClashException.hpp>
64 : : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
65 : : #include <com/sun/star/ucb/TransferInfo.hpp>
66 : : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
67 : : #include <com/sun/star/ucb/XCommandInfo.hpp>
68 : : #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
69 : : #include <com/sun/star/uno/Any.hxx>
70 : : #include <com/sun/star/uno/Sequence.hxx>
71 : : #include <ucbhelper/contentidentifier.hxx>
72 : : #include <ucbhelper/propertyvalueset.hxx>
73 : : #include <ucbhelper/cancelcommandexecution.hxx>
74 : : #include "hierarchycontent.hxx"
75 : : #include "hierarchyprovider.hxx"
76 : : #include "dynamicresultset.hxx"
77 : : #include "hierarchyuri.hxx"
78 : :
79 : : #include "../inc/urihelper.hxx"
80 : :
81 : : using namespace com::sun::star;
82 : : using namespace hierarchy_ucp;
83 : :
84 : : //=========================================================================
85 : : //=========================================================================
86 : : //
87 : : // HierarchyContent Implementation.
88 : : //
89 : : //=========================================================================
90 : : //=========================================================================
91 : :
92 : : // static ( "virtual" ctor )
93 : 54 : HierarchyContent* HierarchyContent::create(
94 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
95 : : HierarchyContentProvider* pProvider,
96 : : const uno::Reference< ucb::XContentIdentifier >& Identifier )
97 : : {
98 : : // Fail, if content does not exist.
99 : 54 : HierarchyContentProperties aProps;
100 [ + + ][ + - ]: 54 : if ( !loadData( rxSMgr, pProvider, Identifier, aProps ) )
101 : 44 : return 0;
102 : :
103 [ + - ]: 54 : return new HierarchyContent( rxSMgr, pProvider, Identifier, aProps );
104 : : }
105 : :
106 : : //=========================================================================
107 : : // static ( "virtual" ctor )
108 : 30 : HierarchyContent* HierarchyContent::create(
109 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
110 : : HierarchyContentProvider* pProvider,
111 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
112 : : const ucb::ContentInfo& Info )
113 : : {
114 [ - + ]: 30 : if ( Info.Type.isEmpty() )
115 : 0 : return 0;
116 : :
117 [ + + ][ - + ]: 30 : if ( Info.Type != HIERARCHY_FOLDER_CONTENT_TYPE && Info.Type != HIERARCHY_LINK_CONTENT_TYPE )
[ - + ]
118 : 0 : return 0;
119 : :
120 [ + - ]: 30 : return new HierarchyContent( rxSMgr, pProvider, Identifier, Info );
121 : : }
122 : :
123 : : //=========================================================================
124 : 10 : HierarchyContent::HierarchyContent(
125 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
126 : : HierarchyContentProvider* pProvider,
127 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
128 : : const HierarchyContentProperties& rProps )
129 : : : ContentImplHelper( rxSMgr, pProvider, Identifier ),
130 : : m_aProps( rProps ),
131 : : m_eState( PERSISTENT ),
132 : : m_pProvider( pProvider ),
133 : : m_bCheckedReadOnly( false ),
134 [ + - ]: 10 : m_bIsReadOnly( true )
135 : : {
136 [ + - ]: 10 : setKind( Identifier );
137 : 10 : }
138 : :
139 : : //=========================================================================
140 : 30 : HierarchyContent::HierarchyContent(
141 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
142 : : HierarchyContentProvider* pProvider,
143 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
144 : : const ucb::ContentInfo& Info )
145 : : : ContentImplHelper( rxSMgr, pProvider, Identifier ),
146 : 30 : m_aProps( Info.Type == HIERARCHY_FOLDER_CONTENT_TYPE ? HierarchyEntryData::FOLDER : HierarchyEntryData::LINK ),
147 : : m_eState( TRANSIENT ),
148 : : m_pProvider( pProvider ),
149 : : m_bCheckedReadOnly( false ),
150 [ + - ][ + + ]: 60 : m_bIsReadOnly( true )
[ + - ]
151 : : {
152 [ + - ]: 30 : setKind( Identifier );
153 : 30 : }
154 : :
155 : : //=========================================================================
156 : : // virtual
157 : 40 : HierarchyContent::~HierarchyContent()
158 : : {
159 [ - + ]: 80 : }
160 : :
161 : : //=========================================================================
162 : : //
163 : : // XInterface methods.
164 : : //
165 : : //=========================================================================
166 : :
167 : : // virtual
168 : 3346 : void SAL_CALL HierarchyContent::acquire()
169 : : throw( )
170 : : {
171 : 3346 : ContentImplHelper::acquire();
172 : 3346 : }
173 : :
174 : : //=========================================================================
175 : : // virtual
176 : 3346 : void SAL_CALL HierarchyContent::release()
177 : : throw( )
178 : : {
179 : 3346 : ContentImplHelper::release();
180 : 3346 : }
181 : :
182 : : //=========================================================================
183 : : // virtual
184 : 580 : uno::Any SAL_CALL HierarchyContent::queryInterface( const uno::Type & rType )
185 : : throw ( uno::RuntimeException )
186 : : {
187 [ + - ]: 580 : uno::Any aRet = ContentImplHelper::queryInterface( rType );
188 : :
189 [ - + ]: 580 : if ( !aRet.hasValue() )
190 : : {
191 : : // Note: isReadOnly may be relative expensive. So avoid calling it
192 : : // unless it is really necessary.
193 : : aRet = cppu::queryInterface(
194 [ # # ]: 0 : rType, static_cast< ucb::XContentCreator * >( this ) );
195 [ # # ]: 0 : if ( aRet.hasValue() )
196 : : {
197 [ # # ][ # # ]: 0 : if ( !isFolder() || isReadOnly() )
[ # # ][ # # ]
198 : 0 : return uno::Any();
199 : : }
200 : : }
201 : :
202 : 580 : return aRet;
203 : : }
204 : :
205 : : //=========================================================================
206 : : //
207 : : // XTypeProvider methods.
208 : : //
209 : : //=========================================================================
210 : :
211 [ # # ][ # # ]: 0 : XTYPEPROVIDER_COMMON_IMPL( HierarchyContent );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
212 : :
213 : : //=========================================================================
214 : : // virtual
215 : 0 : uno::Sequence< uno::Type > SAL_CALL HierarchyContent::getTypes()
216 : : throw( uno::RuntimeException )
217 : : {
218 : 0 : cppu::OTypeCollection * pCollection = 0;
219 : :
220 [ # # ][ # # ]: 0 : if ( isFolder() && !isReadOnly() )
[ # # ]
221 : : {
222 : : static cppu::OTypeCollection* pFolderTypes = 0;
223 : :
224 : 0 : pCollection = pFolderTypes;
225 [ # # ]: 0 : if ( !pCollection )
226 : : {
227 [ # # ][ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
228 : :
229 : 0 : pCollection = pFolderTypes;
230 [ # # ]: 0 : if ( !pCollection )
231 : : {
232 : : static cppu::OTypeCollection aCollection(
233 [ # # ]: 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
234 [ # # ]: 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
235 [ # # ]: 0 : CPPU_TYPE_REF( lang::XComponent ),
236 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XContent ),
237 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
238 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
239 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
240 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
241 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
242 [ # # ]: 0 : CPPU_TYPE_REF( container::XChild ),
243 [ # # ][ # # ]: 0 : CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
244 : 0 : pCollection = &aCollection;
245 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
246 : 0 : pFolderTypes = pCollection;
247 [ # # ]: 0 : }
248 : : }
249 : : else {
250 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
251 : : }
252 : : }
253 : : else
254 : : {
255 : : static cppu::OTypeCollection* pDocumentTypes = 0;
256 : :
257 : 0 : pCollection = pDocumentTypes;
258 [ # # ]: 0 : if ( !pCollection )
259 : : {
260 [ # # ][ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
261 : :
262 : 0 : pCollection = pDocumentTypes;
263 [ # # ]: 0 : if ( !pCollection )
264 : : {
265 : : static cppu::OTypeCollection aCollection(
266 [ # # ]: 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
267 [ # # ]: 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
268 [ # # ]: 0 : CPPU_TYPE_REF( lang::XComponent ),
269 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XContent ),
270 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
271 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
272 [ # # ]: 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
273 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
274 [ # # ]: 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
275 [ # # ][ # # ]: 0 : CPPU_TYPE_REF( container::XChild ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
276 : 0 : pCollection = &aCollection;
277 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
278 : 0 : pDocumentTypes = pCollection;
279 [ # # ]: 0 : }
280 : : }
281 : : else {
282 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
283 : : }
284 : : }
285 : :
286 : 0 : return (*pCollection).getTypes();
287 : : }
288 : :
289 : : //=========================================================================
290 : : //
291 : : // XServiceInfo methods.
292 : : //
293 : : //=========================================================================
294 : :
295 : : // virtual
296 : 0 : rtl::OUString SAL_CALL HierarchyContent::getImplementationName()
297 : : throw( uno::RuntimeException )
298 : : {
299 : 0 : return rtl::OUString( "com.sun.star.comp.ucb.HierarchyContent" );
300 : : }
301 : :
302 : : //=========================================================================
303 : : // virtual
304 : : uno::Sequence< rtl::OUString > SAL_CALL
305 : 0 : HierarchyContent::getSupportedServiceNames()
306 : : throw( uno::RuntimeException )
307 : : {
308 : 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
309 : :
310 [ # # ]: 0 : if ( m_eKind == LINK )
311 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( HIERARCHY_LINK_CONTENT_SERVICE_NAME );
312 [ # # ]: 0 : else if ( m_eKind == FOLDER )
313 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( HIERARCHY_FOLDER_CONTENT_SERVICE_NAME );
314 : : else
315 [ # # ]: 0 : aSNS.getArray()[ 0 ] = rtl::OUString( HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME );
316 : :
317 : 0 : return aSNS;
318 : : }
319 : :
320 : : //=========================================================================
321 : : //
322 : : // XContent methods.
323 : : //
324 : : //=========================================================================
325 : :
326 : : // virtual
327 : 0 : rtl::OUString SAL_CALL HierarchyContent::getContentType()
328 : : throw( uno::RuntimeException )
329 : : {
330 : 0 : return m_aProps.getContentType();
331 : : }
332 : :
333 : : //=========================================================================
334 : : // virtual
335 : : uno::Reference< ucb::XContentIdentifier > SAL_CALL
336 : 138 : HierarchyContent::getIdentifier()
337 : : throw( uno::RuntimeException )
338 : : {
339 : : // Transient?
340 [ - + ]: 138 : if ( m_eState == TRANSIENT )
341 : : {
342 : : // Transient contents have no identifier.
343 : 0 : return uno::Reference< ucb::XContentIdentifier >();
344 : : }
345 : :
346 : 138 : return ContentImplHelper::getIdentifier();
347 : : }
348 : :
349 : : //=========================================================================
350 : : //
351 : : // XCommandProcessor methods.
352 : : //
353 : : //=========================================================================
354 : :
355 : : // virtual
356 : 168 : uno::Any SAL_CALL HierarchyContent::execute(
357 : : const ucb::Command& aCommand,
358 : : sal_Int32 /*CommandId*/,
359 : : const uno::Reference< ucb::XCommandEnvironment >& Environment )
360 : : throw( uno::Exception,
361 : : ucb::CommandAbortedException,
362 : : uno::RuntimeException )
363 : : {
364 : 168 : uno::Any aRet;
365 : :
366 [ - + ]: 168 : if ( aCommand.Name == "getPropertyValues" )
367 : : {
368 : : //////////////////////////////////////////////////////////////////
369 : : // getPropertyValues
370 : : //////////////////////////////////////////////////////////////////
371 : :
372 [ # # ]: 0 : uno::Sequence< beans::Property > Properties;
373 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= Properties ) )
374 : : {
375 : : ucbhelper::cancelCommandExecution(
376 : : uno::makeAny( lang::IllegalArgumentException(
377 : : rtl::OUString( "Wrong argument type!" ),
378 : : static_cast< cppu::OWeakObject * >( this ),
379 : : -1 ) ),
380 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
381 : : // Unreachable
382 : : }
383 : :
384 [ # # ][ # # ]: 0 : aRet <<= getPropertyValues( Properties );
[ # # ]
385 : : }
386 [ + + ]: 168 : else if ( aCommand.Name == "setPropertyValues" )
387 : : {
388 : : //////////////////////////////////////////////////////////////////
389 : : // setPropertyValues
390 : : //////////////////////////////////////////////////////////////////
391 : :
392 [ + - ]: 64 : uno::Sequence< beans::PropertyValue > aProperties;
393 [ + - ][ - + ]: 64 : if ( !( aCommand.Argument >>= aProperties ) )
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 [ - + ]: 64 : if ( !aProperties.getLength() )
405 : : {
406 : : ucbhelper::cancelCommandExecution(
407 : : uno::makeAny( lang::IllegalArgumentException(
408 : : rtl::OUString( "No properties!" ),
409 : : static_cast< cppu::OWeakObject * >( this ),
410 : : -1 ) ),
411 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
412 : : // Unreachable
413 : : }
414 : :
415 [ + - ][ + - ]: 64 : aRet <<= setPropertyValues( aProperties, Environment );
[ + - ][ + - ]
416 : : }
417 [ + + ]: 104 : else if ( aCommand.Name == "getPropertySetInfo" )
418 : : {
419 : : //////////////////////////////////////////////////////////////////
420 : : // getPropertySetInfo
421 : : //////////////////////////////////////////////////////////////////
422 : :
423 [ + - ][ + - ]: 34 : aRet <<= getPropertySetInfo( Environment );
424 : : }
425 [ - + ]: 70 : else if ( aCommand.Name == "getCommandInfo" )
426 : : {
427 : : //////////////////////////////////////////////////////////////////
428 : : // getCommandInfo
429 : : //////////////////////////////////////////////////////////////////
430 : :
431 [ # # ][ # # ]: 0 : aRet <<= getCommandInfo( Environment );
432 : : }
433 [ + + ][ + - ]: 70 : else if ( aCommand.Name == "open" && isFolder() )
[ + + ]
434 : : {
435 : : //////////////////////////////////////////////////////////////////
436 : : // open command for a folder content
437 : : //////////////////////////////////////////////////////////////////
438 : :
439 [ + - ]: 10 : ucb::OpenCommandArgument2 aOpenCommand;
440 [ + - ][ - + ]: 10 : if ( !( aCommand.Argument >>= aOpenCommand ) )
441 : : {
442 : : ucbhelper::cancelCommandExecution(
443 : : uno::makeAny( lang::IllegalArgumentException(
444 : : rtl::OUString( "Wrong argument type!" ),
445 : : static_cast< cppu::OWeakObject * >( this ),
446 : : -1 ) ),
447 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
448 : : // Unreachable
449 : : }
450 : :
451 : : uno::Reference< ucb::XDynamicResultSet > xSet
452 [ + - ][ + - ]: 10 : = new DynamicResultSet( m_xSMgr, this, aOpenCommand );
[ + - ]
453 [ + - ][ + - ]: 10 : aRet <<= xSet;
454 : : }
455 [ + + ][ + - ]: 60 : else if ( aCommand.Name == "insert" && ( m_eKind != ROOT ) && !isReadOnly() )
[ + - ][ + - ]
[ + + ]
456 : : {
457 : : //////////////////////////////////////////////////////////////////
458 : : // insert
459 : : // ( Not available at root folder )
460 : : //////////////////////////////////////////////////////////////////
461 : :
462 [ + - ]: 30 : ucb::InsertCommandArgument aArg;
463 [ + - ][ - + ]: 30 : if ( !( aCommand.Argument >>= aArg ) )
464 : : {
465 : : ucbhelper::cancelCommandExecution(
466 : : uno::makeAny( lang::IllegalArgumentException(
467 : : rtl::OUString( "Wrong argument type!" ),
468 : : static_cast< cppu::OWeakObject * >( this ),
469 : : -1 ) ),
470 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
471 : : // Unreachable
472 : : }
473 : :
474 : : sal_Int32 nNameClash = aArg.ReplaceExisting
475 : : ? ucb::NameClash::OVERWRITE
476 [ - + ]: 30 : : ucb::NameClash::ERROR;
477 [ + - ][ + - ]: 30 : insert( nNameClash, Environment );
478 : : }
479 [ - + ][ # # ]: 30 : else if ( aCommand.Name == "delete" && ( m_eKind != ROOT ) && !isReadOnly() )
[ # # ][ # # ]
[ - + ]
480 : : {
481 : : //////////////////////////////////////////////////////////////////
482 : : // delete
483 : : // ( Not available at root folder )
484 : : //////////////////////////////////////////////////////////////////
485 : :
486 : 0 : sal_Bool bDeletePhysical = sal_False;
487 : 0 : aCommand.Argument >>= bDeletePhysical;
488 [ # # ]: 0 : destroy( bDeletePhysical, Environment );
489 : :
490 : : // Remove own and all children's persistent data.
491 [ # # ][ # # ]: 0 : if ( !removeData() )
492 : : {
493 : : uno::Any aProps
494 : : = uno::makeAny(
495 : : beans::PropertyValue(
496 : : rtl::OUString( "Uri"),
497 : : -1,
498 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
499 : 0 : getContentIdentifier()),
500 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
501 : : ucbhelper::cancelCommandExecution(
502 : : ucb::IOErrorCode_CANT_WRITE,
503 : : uno::Sequence< uno::Any >(&aProps, 1),
504 : : Environment,
505 : : rtl::OUString( "Cannot remove persistent data!" ),
506 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
507 : : // Unreachable
508 : : }
509 : :
510 : : // Remove own and all children's Additional Core Properties.
511 [ # # ]: 0 : removeAdditionalPropertySet( sal_True );
512 : : }
513 [ - + ][ # # ]: 30 : else if ( aCommand.Name == "transfer" && isFolder() && !isReadOnly() )
[ # # ][ # # ]
[ - + ]
514 : : {
515 : : //////////////////////////////////////////////////////////////////
516 : : // transfer
517 : : // ( Not available at link objects )
518 : : //////////////////////////////////////////////////////////////////
519 : :
520 : 0 : ucb::TransferInfo aInfo;
521 [ # # ][ # # ]: 0 : if ( !( aCommand.Argument >>= aInfo ) )
522 : : {
523 : : OSL_FAIL( "Wrong argument type!" );
524 : : ucbhelper::cancelCommandExecution(
525 : : uno::makeAny( lang::IllegalArgumentException(
526 : : rtl::OUString( "Wrong argument type!" ),
527 : : static_cast< cppu::OWeakObject * >( this ),
528 : : -1 ) ),
529 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
530 : : // Unreachable
531 : : }
532 : :
533 [ # # ]: 0 : transfer( aInfo, Environment );
534 : : }
535 [ + - ][ + - ]: 30 : else if ( aCommand.Name == "createNewContent" && isFolder() && !isReadOnly() )
[ + - ][ + - ]
[ + - ]
536 : : {
537 : : //////////////////////////////////////////////////////////////////
538 : : // createNewContent
539 : : // ( Not available at link objects )
540 : : //////////////////////////////////////////////////////////////////
541 : :
542 [ + - ]: 30 : ucb::ContentInfo aInfo;
543 [ + - ][ - + ]: 30 : if ( !( aCommand.Argument >>= aInfo ) )
544 : : {
545 : : OSL_FAIL( "Wrong argument type!" );
546 : : ucbhelper::cancelCommandExecution(
547 : : uno::makeAny( lang::IllegalArgumentException(
548 : : rtl::OUString( "Wrong argument type!" ),
549 : : static_cast< cppu::OWeakObject * >( this ),
550 : : -1 ) ),
551 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
552 : : // Unreachable
553 : : }
554 : :
555 [ + - ][ + - ]: 30 : aRet <<= createNewContent( aInfo );
[ + - ]
556 : : }
557 : : else
558 : : {
559 : : //////////////////////////////////////////////////////////////////
560 : : // Unsupported command
561 : : //////////////////////////////////////////////////////////////////
562 : :
563 : : ucbhelper::cancelCommandExecution(
564 : : uno::makeAny( ucb::UnsupportedCommandException(
565 : : rtl::OUString(),
566 : : static_cast< cppu::OWeakObject * >( this ) ) ),
567 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
568 : : // Unreachable
569 : : }
570 : :
571 : 168 : return aRet;
572 : : }
573 : :
574 : : //=========================================================================
575 : : // virtual
576 : 0 : void SAL_CALL HierarchyContent::abort( sal_Int32 /*CommandId*/ )
577 : : throw( uno::RuntimeException )
578 : : {
579 : : // @@@ Generally, no action takes much time...
580 : 0 : }
581 : :
582 : : //=========================================================================
583 : : //
584 : : // XContentCreator methods.
585 : : //
586 : : //=========================================================================
587 : :
588 : : // virtual
589 : : uno::Sequence< ucb::ContentInfo > SAL_CALL
590 : 0 : HierarchyContent::queryCreatableContentsInfo()
591 : : throw( uno::RuntimeException )
592 : : {
593 : 0 : return m_aProps.getCreatableContentsInfo();
594 : : }
595 : :
596 : : //=========================================================================
597 : : // virtual
598 : : uno::Reference< ucb::XContent > SAL_CALL
599 : 30 : HierarchyContent::createNewContent( const ucb::ContentInfo& Info )
600 : : throw( uno::RuntimeException )
601 : : {
602 [ + - ]: 30 : if ( isFolder() )
603 : : {
604 [ + - ]: 30 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
605 : :
606 [ - + ]: 30 : if ( Info.Type.isEmpty() )
607 : 0 : return uno::Reference< ucb::XContent >();
608 : :
609 : 30 : sal_Bool bCreateFolder = Info.Type == HIERARCHY_FOLDER_CONTENT_TYPE;
610 : :
611 [ - + ][ - + ]: 30 : if ( !bCreateFolder && Info.Type != HIERARCHY_LINK_CONTENT_TYPE )
[ + + ]
612 : 0 : return uno::Reference< ucb::XContent >();
613 : :
614 [ + - ][ + - ]: 30 : rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
615 : :
616 : : OSL_ENSURE( !aURL.isEmpty(),
617 : : "HierarchyContent::createNewContent - empty identifier!" );
618 : :
619 [ + + ]: 30 : if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
620 : 28 : aURL += rtl::OUString("/");
621 : :
622 [ + + ]: 30 : if ( bCreateFolder )
623 : 10 : aURL += rtl::OUString("New_Folder");
624 : : else
625 : 20 : aURL += rtl::OUString("New_Link");
626 : :
627 : : uno::Reference< ucb::XContentIdentifier > xId
628 [ + - ][ + - ]: 30 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
[ + - ]
629 : :
630 [ + - ][ + - ]: 30 : return create( m_xSMgr, m_pProvider, xId, Info );
[ + - ][ + - ]
631 : : }
632 : : else
633 : : {
634 : : OSL_FAIL( "createNewContent called on non-folder object!" );
635 : 30 : return uno::Reference< ucb::XContent >();
636 : : }
637 : : }
638 : :
639 : : //=========================================================================
640 : : // virtual
641 : 30 : rtl::OUString HierarchyContent::getParentURL()
642 : : {
643 [ + - ][ + - ]: 30 : HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
644 [ + - ]: 30 : return aUri.getParentUri();
645 : : }
646 : :
647 : : //=========================================================================
648 : : //static
649 : 30 : sal_Bool HierarchyContent::hasData(
650 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
651 : : HierarchyContentProvider* pProvider,
652 : : const uno::Reference< ucb::XContentIdentifier >& Identifier )
653 : : {
654 [ + - ][ + - ]: 30 : rtl::OUString aURL = Identifier->getContentIdentifier();
655 : :
656 : : // Am I a root folder?
657 : 30 : HierarchyUri aUri( aURL );
658 [ - + ][ + - ]: 30 : if ( aUri.isRootFolder() )
659 : : {
660 : : // hasData must always return 'true' for root folder
661 : : // even if no persistent data exist!!!
662 : 0 : return sal_True;
663 : : }
664 : :
665 [ + - ][ + - ]: 30 : return HierarchyEntry( rxSMgr, pProvider, aURL ).hasData();
[ + - ]
666 : : }
667 : :
668 : : //=========================================================================
669 : : //static
670 : 54 : sal_Bool HierarchyContent::loadData(
671 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
672 : : HierarchyContentProvider* pProvider,
673 : : const uno::Reference< ucb::XContentIdentifier >& Identifier,
674 : : HierarchyContentProperties& rProps )
675 : : {
676 [ + - ][ + - ]: 54 : rtl::OUString aURL = Identifier->getContentIdentifier();
677 : :
678 : : // Am I a root folder?
679 : 54 : HierarchyUri aUri( aURL );
680 [ + + ][ + - ]: 54 : if ( aUri.isRootFolder() )
681 : : {
682 [ + - ]: 4 : rProps = HierarchyContentProperties( HierarchyEntryData::FOLDER );
683 : : }
684 : : else
685 : : {
686 [ + - ]: 50 : HierarchyEntry aEntry( rxSMgr, pProvider, aURL );
687 : 50 : HierarchyEntryData aData;
688 [ + + ][ + - ]: 50 : if ( !aEntry.getData( aData ) )
689 : 44 : return sal_False;
690 : :
691 [ + - ][ + + ]: 50 : rProps = HierarchyContentProperties( aData );
[ + - ][ + + ]
692 : : }
693 : 54 : return sal_True;
694 : : }
695 : :
696 : : //=========================================================================
697 : 36 : sal_Bool HierarchyContent::storeData()
698 : : {
699 : : HierarchyEntry aEntry(
700 [ + - ][ + - ]: 36 : m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
[ + - ]
701 [ + - ][ + - ]: 36 : return aEntry.setData( m_aProps.getHierarchyEntryData(), sal_True );
702 : : }
703 : :
704 : : //=========================================================================
705 : 0 : sal_Bool HierarchyContent::renameData(
706 : : const uno::Reference< ucb::XContentIdentifier >& xOldId,
707 : : const uno::Reference< ucb::XContentIdentifier >& xNewId )
708 : : {
709 : : HierarchyEntry aEntry(
710 [ # # ][ # # ]: 0 : m_xSMgr, m_pProvider, xOldId->getContentIdentifier() );
[ # # ]
711 [ # # ]: 0 : return aEntry.move( xNewId->getContentIdentifier(),
712 [ # # ][ # # ]: 0 : m_aProps.getHierarchyEntryData() );
[ # # ]
713 : : }
714 : :
715 : : //=========================================================================
716 : 0 : sal_Bool HierarchyContent::removeData()
717 : : {
718 : : HierarchyEntry aEntry(
719 [ # # ][ # # ]: 0 : m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
[ # # ]
720 [ # # ][ # # ]: 0 : return aEntry.remove();
721 : : }
722 : :
723 : : //=========================================================================
724 : 40 : void HierarchyContent::setKind(
725 : : const uno::Reference< ucb::XContentIdentifier >& Identifier )
726 : : {
727 [ + + ]: 40 : if ( m_aProps.getIsFolder() )
728 : : {
729 : : // Am I a root folder?
730 [ + - ][ + - ]: 20 : HierarchyUri aUri( Identifier->getContentIdentifier() );
731 [ + + ][ + - ]: 20 : if ( aUri.isRootFolder() )
732 : 4 : m_eKind = ROOT;
733 : : else
734 : 20 : m_eKind = FOLDER;
735 : : }
736 : : else
737 : 20 : m_eKind = LINK;
738 : 40 : }
739 : :
740 : : //=========================================================================
741 : 144 : bool HierarchyContent::isReadOnly()
742 : : {
743 [ + + ]: 144 : if ( !m_bCheckedReadOnly )
744 : : {
745 [ + - ]: 32 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
746 [ + - ]: 32 : if ( !m_bCheckedReadOnly )
747 : : {
748 : 32 : m_bCheckedReadOnly = true;
749 : 32 : m_bIsReadOnly = true;
750 : :
751 [ + - ][ + - ]: 32 : HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
752 : : uno::Reference< lang::XMultiServiceFactory > xConfigProv
753 [ + - ][ + - ]: 32 : = m_pProvider->getConfigProvider( aUri.getService() );
754 [ + - ]: 32 : if ( xConfigProv.is() )
755 : : {
756 : : uno::Sequence< rtl::OUString > aNames
757 [ + - ][ + - ]: 32 : = xConfigProv->getAvailableServiceNames();
758 : 32 : sal_Int32 nCount = aNames.getLength();
759 [ + - ]: 64 : for ( sal_Int32 n = 0; n < nCount; ++n )
760 : : {
761 [ + - ][ + + ]: 64 : if ( aNames[ n ] == "com.sun.star.ucb.HierarchyDataReadWriteAccess" )
762 : : {
763 : 32 : m_bIsReadOnly = false;
764 : 32 : break;
765 : : }
766 [ + - ]: 32 : }
767 : 32 : }
768 [ + - ]: 32 : }
769 : : }
770 : :
771 : 144 : return m_bIsReadOnly;
772 : : }
773 : :
774 : : //=========================================================================
775 : : uno::Reference< ucb::XContentIdentifier >
776 : 30 : HierarchyContent::makeNewIdentifier( const rtl::OUString& rTitle )
777 : : {
778 [ + - ]: 30 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
779 : :
780 : : // Assemble new content identifier...
781 [ + - ][ + - ]: 30 : HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
782 [ + - ]: 30 : rtl::OUString aNewURL = aUri.getParentUri();
783 : 30 : aNewURL += rtl::OUString("/");
784 : 30 : aNewURL += ::ucb_impl::urihelper::encodeSegment( rTitle );
785 : :
786 : : return uno::Reference< ucb::XContentIdentifier >(
787 [ + - ][ + - ]: 30 : new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL ) );
[ + - ][ + - ]
788 : : }
789 : :
790 : : //=========================================================================
791 : 0 : void HierarchyContent::queryChildren( HierarchyContentRefList& rChildren )
792 : : {
793 [ # # ][ # # ]: 0 : if ( ( m_eKind != FOLDER ) && ( m_eKind != ROOT ) )
794 : 0 : return;
795 : :
796 : : // Obtain a list with a snapshot of all currently instanciated contents
797 : : // from provider and extract the contents which are direct children
798 : : // of this content.
799 : :
800 [ # # ]: 0 : ::ucbhelper::ContentRefList aAllContents;
801 [ # # ]: 0 : m_xProvider->queryExistingContents( aAllContents );
802 : :
803 [ # # ][ # # ]: 0 : rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
804 : 0 : sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
805 : :
806 [ # # ]: 0 : if ( nURLPos != ( aURL.getLength() - 1 ) )
807 : : {
808 : : // No trailing slash found. Append.
809 : 0 : aURL += rtl::OUString("/");
810 : : }
811 : :
812 : 0 : sal_Int32 nLen = aURL.getLength();
813 : :
814 : 0 : ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
815 : 0 : ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
816 : :
817 [ # # ]: 0 : while ( it != end )
818 : : {
819 : 0 : ::ucbhelper::ContentImplHelperRef xChild = (*it);
820 : : rtl::OUString aChildURL
821 [ # # ][ # # ]: 0 : = xChild->getIdentifier()->getContentIdentifier();
[ # # ]
822 : :
823 : : // Is aURL a prefix of aChildURL?
824 [ # # ]: 0 : if ( ( aChildURL.getLength() > nLen ) &&
[ # # # # ]
825 : 0 : ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
826 : : {
827 : 0 : sal_Int32 nPos = nLen;
828 : 0 : nPos = aChildURL.indexOf( '/', nPos );
829 : :
830 [ # # ]: 0 : if ( ( nPos == -1 ) ||
[ # # # # ]
831 : 0 : ( nPos == ( aChildURL.getLength() - 1 ) ) )
832 : : {
833 : : // No further slashes/ only a final slash. It's a child!
834 : : rChildren.push_back(
835 : : HierarchyContentRef(
836 [ # # ]: 0 : static_cast< HierarchyContent * >( xChild.get() ) ) );
837 : : }
838 : : }
839 : 0 : ++it;
840 : 0 : }
841 : : }
842 : :
843 : : //=========================================================================
844 : 0 : sal_Bool HierarchyContent::exchangeIdentity(
845 : : const uno::Reference< ucb::XContentIdentifier >& xNewId )
846 : : {
847 [ # # ]: 0 : if ( !xNewId.is() )
848 : 0 : return sal_False;
849 : :
850 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
851 : :
852 [ # # ]: 0 : uno::Reference< ucb::XContent > xThis = this;
853 : :
854 : : // Already persistent?
855 [ # # ]: 0 : if ( m_eState != PERSISTENT )
856 : : {
857 : : OSL_FAIL( "HierarchyContent::exchangeIdentity - Not persistent!" );
858 : 0 : return sal_False;
859 : : }
860 : :
861 : : // Am I the root folder?
862 [ # # ]: 0 : if ( m_eKind == ROOT )
863 : : {
864 : : OSL_FAIL( "HierarchyContent::exchangeIdentity - "
865 : : "Not supported by root folder!" );
866 : 0 : return sal_False;
867 : : }
868 : :
869 : : // Exchange own identitity.
870 : :
871 : : // Fail, if a content with given id already exists.
872 [ # # ][ # # ]: 0 : if ( !hasData( xNewId ) )
873 : : {
874 [ # # ][ # # ]: 0 : rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
875 : :
876 [ # # ]: 0 : aGuard.clear();
877 [ # # ][ # # ]: 0 : if ( exchange( xNewId ) )
878 : : {
879 [ # # ]: 0 : if ( m_eKind == FOLDER )
880 : : {
881 : : // Process instanciated children...
882 : :
883 [ # # ]: 0 : HierarchyContentRefList aChildren;
884 [ # # ]: 0 : queryChildren( aChildren );
885 : :
886 : 0 : HierarchyContentRefList::const_iterator it = aChildren.begin();
887 : 0 : HierarchyContentRefList::const_iterator end = aChildren.end();
888 : :
889 [ # # ]: 0 : while ( it != end )
890 : : {
891 : 0 : HierarchyContentRef xChild = (*it);
892 : :
893 : : // Create new content identifier for the child...
894 : : uno::Reference< ucb::XContentIdentifier > xOldChildId
895 [ # # ]: 0 : = xChild->getIdentifier();
896 : : rtl::OUString aOldChildURL
897 [ # # ][ # # ]: 0 : = xOldChildId->getContentIdentifier();
898 : : rtl::OUString aNewChildURL
899 : : = aOldChildURL.replaceAt(
900 : : 0,
901 : : aOldURL.getLength(),
902 [ # # ][ # # ]: 0 : xNewId->getContentIdentifier() );
903 : : uno::Reference< ucb::XContentIdentifier > xNewChildId
904 : : = new ::ucbhelper::ContentIdentifier(
905 [ # # ][ # # ]: 0 : m_xSMgr, aNewChildURL );
[ # # ]
906 : :
907 [ # # ][ # # ]: 0 : if ( !xChild->exchangeIdentity( xNewChildId ) )
908 : 0 : return sal_False;
909 : :
910 [ # # ]: 0 : ++it;
911 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
912 : : }
913 : 0 : return sal_True;
914 [ # # ]: 0 : }
915 : : }
916 : :
917 : : OSL_FAIL( "HierarchyContent::exchangeIdentity - "
918 : : "Panic! Cannot exchange identity!" );
919 [ # # ]: 0 : return sal_False;
920 : : }
921 : :
922 : : //=========================================================================
923 : : // static
924 : 26 : uno::Reference< sdbc::XRow > HierarchyContent::getPropertyValues(
925 : : const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
926 : : const uno::Sequence< beans::Property >& rProperties,
927 : : const HierarchyContentProperties& rData,
928 : : HierarchyContentProvider* pProvider,
929 : : const rtl::OUString& rContentId )
930 : : {
931 : : // Note: Empty sequence means "get values of all supported properties".
932 : :
933 : : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
934 [ + - ]: 26 : = new ::ucbhelper::PropertyValueSet( rSMgr );
935 : :
936 : 26 : sal_Int32 nCount = rProperties.getLength();
937 [ + - ]: 26 : if ( nCount )
938 : : {
939 : 26 : uno::Reference< beans::XPropertySet > xAdditionalPropSet;
940 : 26 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
941 : :
942 : 26 : const beans::Property* pProps = rProperties.getConstArray();
943 [ + + ]: 72 : for ( sal_Int32 n = 0; n < nCount; ++n )
944 : : {
945 : 46 : const beans::Property& rProp = pProps[ n ];
946 : :
947 : : // Process Core properties.
948 : :
949 [ - + ]: 46 : if ( rProp.Name == "ContentType" )
950 : : {
951 [ # # ]: 0 : xRow->appendString ( rProp, rData.getContentType() );
952 : : }
953 [ + + ]: 46 : else if ( rProp.Name == "Title" )
954 : : {
955 [ + - ]: 26 : xRow->appendString ( rProp, rData.getTitle() );
956 : : }
957 [ - + ]: 20 : else if ( rProp.Name == "IsDocument" )
958 : : {
959 [ # # ]: 0 : xRow->appendBoolean( rProp, rData.getIsDocument() );
960 : : }
961 [ - + ]: 20 : else if ( rProp.Name == "IsFolder" )
962 : : {
963 [ # # ]: 0 : xRow->appendBoolean( rProp, rData.getIsFolder() );
964 : : }
965 [ - + ]: 20 : else if ( rProp.Name == "CreatableContentsInfo" )
966 : : {
967 : : xRow->appendObject(
968 [ # # ][ # # ]: 0 : rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
[ # # ][ # # ]
969 : : }
970 [ + - ]: 20 : else if ( rProp.Name == "TargetURL" )
971 : : {
972 : : // TargetURL is only supported by links.
973 : :
974 [ + - ]: 20 : if ( rData.getIsDocument() )
975 [ + - ]: 20 : xRow->appendString( rProp, rData.getTargetURL() );
976 : : else
977 [ # # ]: 0 : xRow->appendVoid( rProp );
978 : : }
979 : : else
980 : : {
981 : : // Not a Core Property! Maybe it's an Additional Core Property?!
982 : :
983 [ # # ][ # # ]: 0 : if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
[ # # ]
984 : : {
985 : : xAdditionalPropSet
986 : : = uno::Reference< beans::XPropertySet >(
987 : : pProvider->getAdditionalPropertySet( rContentId,
988 : : sal_False ),
989 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
990 : 0 : bTriedToGetAdditonalPropSet = sal_True;
991 : : }
992 : :
993 [ # # ]: 0 : if ( xAdditionalPropSet.is() )
994 : : {
995 [ # # ]: 0 : if ( !xRow->appendPropertySetValue(
996 : : xAdditionalPropSet,
997 [ # # ]: 0 : rProp ) )
998 : : {
999 : : // Append empty entry.
1000 [ # # ]: 0 : xRow->appendVoid( rProp );
1001 : : }
1002 : : }
1003 : : else
1004 : : {
1005 : : // Append empty entry.
1006 [ # # ]: 0 : xRow->appendVoid( rProp );
1007 : : }
1008 : : }
1009 : 26 : }
1010 : : }
1011 : : else
1012 : : {
1013 : : // Append all Core Properties.
1014 : : xRow->appendString (
1015 : : beans::Property( rtl::OUString("ContentType"),
1016 : : -1,
1017 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1018 : : beans::PropertyAttribute::BOUND
1019 : : | beans::PropertyAttribute::READONLY ),
1020 [ # # ]: 0 : rData.getContentType() );
1021 : : xRow->appendString (
1022 : : beans::Property( rtl::OUString("Title"),
1023 : : -1,
1024 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1025 : : // @@@ Might actually be read-only!
1026 : : beans::PropertyAttribute::BOUND ),
1027 [ # # ]: 0 : rData.getTitle() );
1028 : : xRow->appendBoolean(
1029 : : beans::Property( rtl::OUString("IsDocument"),
1030 : : -1,
1031 [ # # ]: 0 : getCppuBooleanType(),
1032 : : beans::PropertyAttribute::BOUND
1033 : : | beans::PropertyAttribute::READONLY ),
1034 [ # # ]: 0 : rData.getIsDocument() );
1035 : : xRow->appendBoolean(
1036 : : beans::Property( rtl::OUString("IsFolder"),
1037 : : -1,
1038 [ # # ]: 0 : getCppuBooleanType(),
1039 : : beans::PropertyAttribute::BOUND
1040 : : | beans::PropertyAttribute::READONLY ),
1041 [ # # ]: 0 : rData.getIsFolder() );
1042 : :
1043 [ # # ]: 0 : if ( rData.getIsDocument() )
1044 : : xRow->appendString(
1045 : : beans::Property( rtl::OUString("TargetURL"),
1046 : : -1,
1047 : : getCppuType(
1048 [ # # ]: 0 : static_cast< const rtl::OUString * >( 0 ) ),
1049 : : // @@@ Might actually be read-only!
1050 : : beans::PropertyAttribute::BOUND ),
1051 [ # # ]: 0 : rData.getTargetURL() );
1052 : : xRow->appendObject(
1053 : : beans::Property(
1054 : : rtl::OUString("CreatableContentsInfo"),
1055 : : -1,
1056 : : getCppuType( static_cast<
1057 [ # # ]: 0 : const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
1058 : : beans::PropertyAttribute::BOUND
1059 : : | beans::PropertyAttribute::READONLY ),
1060 [ # # ][ # # ]: 0 : uno::makeAny( rData.getCreatableContentsInfo() ) );
[ # # ][ # # ]
1061 : :
1062 : : // Append all Additional Core Properties.
1063 : :
1064 : : uno::Reference< beans::XPropertySet > xSet(
1065 : : pProvider->getAdditionalPropertySet( rContentId, sal_False ),
1066 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
1067 [ # # ]: 0 : xRow->appendPropertySet( xSet );
1068 : : }
1069 : :
1070 [ + - ][ + - ]: 26 : return uno::Reference< sdbc::XRow >( xRow.get() );
1071 : : }
1072 : :
1073 : : //=========================================================================
1074 : 0 : uno::Reference< sdbc::XRow > HierarchyContent::getPropertyValues(
1075 : : const uno::Sequence< beans::Property >& rProperties )
1076 : : {
1077 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1078 : : return getPropertyValues( m_xSMgr,
1079 : : rProperties,
1080 : : m_aProps,
1081 : : m_pProvider,
1082 [ # # ][ # # ]: 0 : m_xIdentifier->getContentIdentifier() );
[ # # ][ # # ]
1083 : : }
1084 : :
1085 : : //=========================================================================
1086 : 64 : uno::Sequence< uno::Any > HierarchyContent::setPropertyValues(
1087 : : const uno::Sequence< beans::PropertyValue >& rValues,
1088 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1089 : : throw( uno::Exception )
1090 : : {
1091 [ + - ]: 64 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1092 : :
1093 [ + - ]: 64 : uno::Sequence< uno::Any > aRet( rValues.getLength() );
1094 [ + - ]: 64 : uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1095 : 64 : sal_Int32 nChanged = 0;
1096 : :
1097 [ + - ]: 64 : beans::PropertyChangeEvent aEvent;
1098 [ + - ]: 64 : aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1099 : 64 : aEvent.Further = sal_False;
1100 : : // aEvent.PropertyName =
1101 : 64 : aEvent.PropertyHandle = -1;
1102 : : // aEvent.OldValue =
1103 : : // aEvent.NewValue =
1104 : :
1105 : 64 : const beans::PropertyValue* pValues = rValues.getConstArray();
1106 : 64 : sal_Int32 nCount = rValues.getLength();
1107 : :
1108 : 64 : uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1109 : 64 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1110 : :
1111 : 64 : sal_Bool bExchange = sal_False;
1112 : 64 : rtl::OUString aOldTitle;
1113 : 64 : rtl::OUString aOldName;
1114 : 64 : sal_Int32 nTitlePos = -1;
1115 : :
1116 [ + + ]: 178 : for ( sal_Int32 n = 0; n < nCount; ++n )
1117 : : {
1118 : 114 : const beans::PropertyValue& rValue = pValues[ n ];
1119 : :
1120 [ - + ]: 114 : if ( rValue.Name == "ContentType" )
1121 : : {
1122 : : // Read-only property!
1123 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1124 : : rtl::OUString( "Property is read-only!" ),
1125 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1126 : : }
1127 [ - + ]: 114 : else if ( rValue.Name == "IsDocument" )
1128 : : {
1129 : : // Read-only property!
1130 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1131 : : rtl::OUString( "Property is read-only!" ),
1132 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1133 : : }
1134 [ + + ]: 114 : else if ( rValue.Name == "IsFolder" )
1135 : : {
1136 : : // Read-only property!
1137 [ + - ]: 30 : aRet[ n ] <<= lang::IllegalAccessException(
1138 : : rtl::OUString( "Property is read-only!" ),
1139 [ + - ][ + - ]: 60 : static_cast< cppu::OWeakObject * >( this ) );
[ + - ][ + - ]
1140 : : }
1141 [ - + ]: 84 : else if ( rValue.Name == "CreatableContentsInfo" )
1142 : : {
1143 : : // Read-only property!
1144 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1145 : : rtl::OUString( "Property is read-only!" ),
1146 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1147 : : }
1148 [ + + ]: 84 : else if ( rValue.Name == "Title" )
1149 : : {
1150 [ + - ][ - + ]: 30 : if ( isReadOnly() )
1151 : : {
1152 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1153 : : rtl::OUString( "Property is read-only!" ),
1154 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1155 : : }
1156 : : else
1157 : : {
1158 : 30 : rtl::OUString aNewValue;
1159 [ + - ]: 30 : if ( rValue.Value >>= aNewValue )
1160 : : {
1161 : : // No empty titles!
1162 [ + - ]: 30 : if ( !aNewValue.isEmpty() )
1163 : : {
1164 [ + - ]: 30 : if ( aNewValue != m_aProps.getTitle() )
1165 : : {
1166 : : // modified title -> modified URL -> exchange !
1167 [ - + ]: 30 : if ( m_eState == PERSISTENT )
1168 : 0 : bExchange = sal_True;
1169 : :
1170 : 30 : aOldTitle = m_aProps.getTitle();
1171 : 30 : aOldName = m_aProps.getName();
1172 : :
1173 : 30 : m_aProps.setTitle( aNewValue );
1174 : : m_aProps.setName(
1175 : : ::ucb_impl::urihelper::encodeSegment(
1176 : 30 : aNewValue ) );
1177 : :
1178 : : // property change event will be set later...
1179 : :
1180 : : // remember position within sequence of values
1181 : : // (for error handling).
1182 : 30 : nTitlePos = n;
1183 : : }
1184 : : }
1185 : : else
1186 : : {
1187 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalArgumentException(
1188 : : rtl::OUString( "Empty title not allowed!" ),
1189 : : static_cast< cppu::OWeakObject * >( this ),
1190 [ # # ][ # # ]: 0 : -1 );
[ # # ][ # # ]
1191 : : }
1192 : : }
1193 : : else
1194 : : {
1195 [ # # ]: 0 : aRet[ n ] <<= beans::IllegalTypeException(
1196 : : rtl::OUString( "Property value has wrong type!" ),
1197 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1198 : 30 : }
1199 : : }
1200 : : }
1201 [ + + ]: 54 : else if ( rValue.Name == "TargetURL" )
1202 : : {
1203 [ + - ][ - + ]: 20 : if ( isReadOnly() )
1204 : : {
1205 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalAccessException(
1206 : : rtl::OUString( "Property is read-only!" ),
1207 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1208 : : }
1209 : : else
1210 : : {
1211 : : // TargetURL is only supported by links.
1212 : :
1213 [ + - ]: 20 : if ( m_eKind == LINK )
1214 : : {
1215 : 20 : rtl::OUString aNewValue;
1216 [ + - ]: 20 : if ( rValue.Value >>= aNewValue )
1217 : : {
1218 : : // No empty target URL's!
1219 [ + - ]: 20 : if ( !aNewValue.isEmpty() )
1220 : : {
1221 [ + - ]: 20 : if ( aNewValue != m_aProps.getTargetURL() )
1222 : : {
1223 : 20 : aEvent.PropertyName = rValue.Name;
1224 : : aEvent.OldValue
1225 [ + - ]: 20 : = uno::makeAny( m_aProps.getTargetURL() );
1226 : : aEvent.NewValue
1227 [ + - ]: 20 : = uno::makeAny( aNewValue );
1228 : :
1229 [ + - ][ + - ]: 20 : aChanges.getArray()[ nChanged ] = aEvent;
1230 : :
1231 : 20 : m_aProps.setTargetURL( aNewValue );
1232 : 20 : nChanged++;
1233 : : }
1234 : : }
1235 : : else
1236 : : {
1237 [ # # ]: 0 : aRet[ n ] <<= lang::IllegalArgumentException(
1238 : : rtl::OUString( "Empty target URL 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( "Property value has wrong type!" ),
1247 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1248 : 20 : }
1249 : : }
1250 : : else
1251 : : {
1252 [ # # ]: 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1253 : : rtl::OUString( "TargetURL only supported by links!" ),
1254 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1255 : : }
1256 : : }
1257 : : }
1258 : : else
1259 : : {
1260 : : // Not a Core Property! Maybe it's an Additional Core Property?!
1261 : :
1262 [ + - ][ + - ]: 34 : if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
[ + - ]
1263 : : {
1264 [ + - ][ + - ]: 34 : xAdditionalPropSet = getAdditionalPropertySet( sal_False );
1265 : 34 : bTriedToGetAdditonalPropSet = sal_True;
1266 : : }
1267 : :
1268 [ + - ]: 34 : if ( xAdditionalPropSet.is() )
1269 : : {
1270 : : try
1271 : : {
1272 [ + - ]: 34 : uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
1273 [ + - ]: 34 : rValue.Name );
1274 [ + + ]: 34 : if ( aOldValue != rValue.Value )
1275 : : {
1276 [ + - ]: 6 : xAdditionalPropSet->setPropertyValue(
1277 [ + - ]: 6 : rValue.Name, rValue.Value );
1278 : :
1279 : 6 : aEvent.PropertyName = rValue.Name;
1280 : 6 : aEvent.OldValue = aOldValue;
1281 : 6 : aEvent.NewValue = rValue.Value;
1282 : :
1283 [ + - ][ + - ]: 6 : aChanges.getArray()[ nChanged ] = aEvent;
1284 : 6 : nChanged++;
1285 : 34 : }
1286 : : }
1287 [ # # ]: 0 : catch ( beans::UnknownPropertyException const & e )
1288 : : {
1289 [ # # # # ]: 0 : aRet[ n ] <<= e;
1290 : : }
1291 [ # # ]: 0 : catch ( lang::WrappedTargetException const & e )
1292 : : {
1293 [ # # # # ]: 0 : aRet[ n ] <<= e;
1294 : : }
1295 [ # # ]: 0 : catch ( beans::PropertyVetoException const & e )
1296 : : {
1297 [ # # # # ]: 0 : aRet[ n ] <<= e;
1298 : : }
1299 [ # # # # : 0 : catch ( lang::IllegalArgumentException const & e )
# # # ]
1300 : : {
1301 [ # # # # ]: 0 : aRet[ n ] <<= e;
1302 : : }
1303 : : }
1304 : : else
1305 : : {
1306 [ # # ]: 0 : aRet[ n ] <<= uno::Exception(
1307 : : rtl::OUString( "No property set for storing the value!" ),
1308 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1309 : : }
1310 : : }
1311 : : }
1312 : :
1313 [ - + ]: 64 : if ( bExchange )
1314 : : {
1315 : : uno::Reference< ucb::XContentIdentifier > xOldId
1316 : 0 : = m_xIdentifier;
1317 : : uno::Reference< ucb::XContentIdentifier > xNewId
1318 [ # # ]: 0 : = makeNewIdentifier( m_aProps.getTitle() );
1319 : :
1320 [ # # ]: 0 : aGuard.clear();
1321 [ # # ][ # # ]: 0 : if ( exchangeIdentity( xNewId ) )
1322 : : {
1323 : : // Adapt persistent data.
1324 [ # # ]: 0 : renameData( xOldId, xNewId );
1325 : :
1326 : : // Adapt Additional Core Properties.
1327 [ # # ]: 0 : renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1328 [ # # ]: 0 : xNewId->getContentIdentifier(),
1329 [ # # ][ # # ]: 0 : sal_True );
[ # # ]
1330 : : }
1331 : : else
1332 : : {
1333 : : // Roll-back.
1334 : 0 : m_aProps.setTitle( aOldTitle );
1335 : 0 : m_aProps.setName ( aOldName );
1336 : :
1337 : 0 : aOldTitle = aOldName = rtl::OUString();
1338 : :
1339 : : // Set error .
1340 [ # # ]: 0 : aRet[ nTitlePos ] <<= uno::Exception(
1341 : : rtl::OUString("Exchange failed!"),
1342 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ) );
[ # # ][ # # ]
1343 : 0 : }
1344 : : }
1345 : :
1346 [ - + ]: 64 : if ( !aOldTitle.isEmpty() )
1347 : : {
1348 : 0 : aEvent.PropertyName = rtl::OUString("Title");
1349 [ # # ]: 0 : aEvent.OldValue = uno::makeAny( aOldTitle );
1350 [ # # ]: 0 : aEvent.NewValue = uno::makeAny( m_aProps.getTitle() );
1351 : :
1352 [ # # ][ # # ]: 0 : aChanges.getArray()[ nChanged ] = aEvent;
1353 : 0 : nChanged++;
1354 : : }
1355 : :
1356 [ + + ]: 64 : if ( nChanged > 0 )
1357 : : {
1358 : : // Save changes, if content was already made persistent.
1359 [ + - ][ + + ]: 26 : if ( !bExchange && ( m_eState == PERSISTENT ) )
1360 : : {
1361 [ + - ][ - + ]: 6 : if ( !storeData() )
1362 : : {
1363 : : uno::Any aProps
1364 : : = uno::makeAny(
1365 : : beans::PropertyValue(
1366 : : rtl::OUString( "Uri"),
1367 : : -1,
1368 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1369 : 0 : getContentIdentifier()),
1370 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1371 : : ucbhelper::cancelCommandExecution(
1372 : : ucb::IOErrorCode_CANT_WRITE,
1373 : : uno::Sequence< uno::Any >(&aProps, 1),
1374 : : xEnv,
1375 : : rtl::OUString( "Cannot store persistent data!" ),
1376 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1377 : : // Unreachable
1378 : : }
1379 : : }
1380 : :
1381 [ + - ]: 26 : aChanges.realloc( nChanged );
1382 : :
1383 [ + - ]: 26 : aGuard.clear();
1384 [ + - ]: 26 : notifyPropertiesChange( aChanges );
1385 : : }
1386 : :
1387 [ + - ][ + - ]: 64 : return aRet;
[ + - ]
1388 : : }
1389 : :
1390 : : //=========================================================================
1391 : 30 : void HierarchyContent::insert( sal_Int32 nNameClashResolve,
1392 : : const uno::Reference<
1393 : : ucb::XCommandEnvironment > & xEnv )
1394 : : throw( uno::Exception )
1395 : : {
1396 [ + - ]: 30 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1397 : :
1398 : : // Am I the root folder?
1399 [ - + ]: 30 : if ( m_eKind == ROOT )
1400 : : {
1401 : : ucbhelper::cancelCommandExecution(
1402 : : uno::makeAny( ucb::UnsupportedCommandException(
1403 : : rtl::OUString( "Not supported by root folder!" ),
1404 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1405 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1406 : : // Unreachable
1407 : : }
1408 : :
1409 : : // Check, if all required properties were set.
1410 [ - + ]: 30 : if ( m_aProps.getTitle().isEmpty() )
1411 : : {
1412 [ # # ]: 0 : uno::Sequence< rtl::OUString > aProps( 1 );
1413 [ # # ]: 0 : aProps[ 0 ] = rtl::OUString("Title");
1414 : : ucbhelper::cancelCommandExecution(
1415 : : uno::makeAny( ucb::MissingPropertiesException(
1416 : : rtl::OUString(),
1417 : : static_cast< cppu::OWeakObject * >( this ),
1418 : : aProps ) ),
1419 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ][ # # ]
1420 : : // Unreachable
1421 : : }
1422 : :
1423 : : // Assemble new content identifier...
1424 : :
1425 : : uno::Reference< ucb::XContentIdentifier > xId
1426 [ + - ]: 30 : = makeNewIdentifier( m_aProps.getTitle() );
1427 : :
1428 : : // Handle possible name clash...
1429 : :
1430 [ + - - - ]: 30 : switch ( nNameClashResolve )
1431 : : {
1432 : : // fail.
1433 : : case ucb::NameClash::ERROR:
1434 [ + - ][ - + ]: 30 : if ( hasData( xId ) )
1435 : : {
1436 : : ucbhelper::cancelCommandExecution(
1437 : : uno::makeAny(
1438 : : ucb::NameClashException(
1439 : : rtl::OUString(),
1440 : : static_cast< cppu::OWeakObject * >( this ),
1441 : : task::InteractionClassification_ERROR,
1442 : 0 : m_aProps.getTitle() ) ),
1443 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1444 : : // Unreachable
1445 : : }
1446 : 30 : break;
1447 : :
1448 : : // replace existing object.
1449 : : case ucb::NameClash::OVERWRITE:
1450 : 0 : break;
1451 : :
1452 : : // "invent" a new valid title.
1453 : : case ucb::NameClash::RENAME:
1454 [ # # ][ # # ]: 0 : if ( hasData( xId ) )
1455 : : {
1456 : 0 : sal_Int32 nTry = 0;
1457 : :
1458 [ # # ][ # # ]: 0 : do
[ # # ]
1459 : : {
1460 [ # # ][ # # ]: 0 : rtl::OUString aNewId = xId->getContentIdentifier();
1461 : 0 : aNewId += rtl::OUString("_");
1462 : 0 : aNewId += rtl::OUString::valueOf( ++nTry );
1463 [ # # ][ # # ]: 0 : xId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewId );
[ # # ]
1464 : : }
1465 [ # # ]: 0 : while ( hasData( xId ) && ( nTry < 1000 ) );
1466 : :
1467 [ # # ]: 0 : if ( nTry == 1000 )
1468 : : {
1469 : : ucbhelper::cancelCommandExecution(
1470 : : uno::makeAny(
1471 : : ucb::UnsupportedNameClashException(
1472 : : rtl::OUString( "Unable to resolve name clash!" ),
1473 : : static_cast< cppu::OWeakObject * >( this ),
1474 : : nNameClashResolve ) ),
1475 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1476 : : // Unreachable
1477 : : }
1478 : : else
1479 : : {
1480 : 0 : rtl::OUString aNewTitle( m_aProps.getTitle() );
1481 : 0 : aNewTitle += rtl::OUString("_");
1482 : 0 : aNewTitle += rtl::OUString::valueOf( nTry );
1483 : 0 : m_aProps.setTitle( aNewTitle );
1484 : : }
1485 : : }
1486 : 0 : break;
1487 : :
1488 : : case ucb::NameClash::KEEP: // deprecated
1489 : : case ucb::NameClash::ASK:
1490 : : default:
1491 [ # # ][ # # ]: 0 : if ( hasData( xId ) )
1492 : : {
1493 : : ucbhelper::cancelCommandExecution(
1494 : : uno::makeAny(
1495 : : ucb::UnsupportedNameClashException(
1496 : : rtl::OUString(),
1497 : : static_cast< cppu::OWeakObject * >( this ),
1498 : : nNameClashResolve ) ),
1499 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1500 : : // Unreachable
1501 : : }
1502 : 0 : break;
1503 : : }
1504 : :
1505 : : // Identifier changed?
1506 [ + - ]: 30 : sal_Bool bNewId = ( xId->getContentIdentifier()
1507 [ + - ][ + - ]: 60 : != m_xIdentifier->getContentIdentifier() );
[ + - ]
1508 [ + - ]: 30 : m_xIdentifier = xId;
1509 : :
1510 [ + - ][ - + ]: 30 : if ( !storeData() )
1511 : : {
1512 : : uno::Any aProps
1513 : : = uno::makeAny(beans::PropertyValue(
1514 : : rtl::OUString( "Uri"),
1515 : : -1,
1516 [ # # ]: 0 : uno::makeAny(m_xIdentifier->
1517 : 0 : getContentIdentifier()),
1518 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1519 : : ucbhelper::cancelCommandExecution(
1520 : : ucb::IOErrorCode_CANT_WRITE,
1521 : : uno::Sequence< uno::Any >(&aProps, 1),
1522 : : xEnv,
1523 : : rtl::OUString("Cannot store persistent data!"),
1524 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1525 : : // Unreachable
1526 : : }
1527 : :
1528 : 30 : m_eState = PERSISTENT;
1529 : :
1530 [ + - ]: 30 : if ( bNewId )
1531 : : {
1532 [ + - ]: 30 : aGuard.clear();
1533 [ + - ]: 30 : inserted();
1534 [ + - ]: 30 : }
1535 : 30 : }
1536 : :
1537 : : //=========================================================================
1538 : 0 : void HierarchyContent::destroy( sal_Bool bDeletePhysical,
1539 : : const uno::Reference<
1540 : : ucb::XCommandEnvironment > & xEnv )
1541 : : throw( uno::Exception )
1542 : : {
1543 : : // @@@ take care about bDeletePhysical -> trashcan support
1544 : :
1545 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1546 : :
1547 [ # # ]: 0 : uno::Reference< ucb::XContent > xThis = this;
1548 : :
1549 : : // Persistent?
1550 [ # # ]: 0 : if ( m_eState != PERSISTENT )
1551 : : {
1552 : : ucbhelper::cancelCommandExecution(
1553 : : uno::makeAny( ucb::UnsupportedCommandException(
1554 : : rtl::OUString( "Not persistent!" ),
1555 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1556 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1557 : : // Unreachable
1558 : : }
1559 : :
1560 : : // Am I the root folder?
1561 [ # # ]: 0 : if ( m_eKind == ROOT )
1562 : : {
1563 : : ucbhelper::cancelCommandExecution(
1564 : : uno::makeAny( ucb::UnsupportedCommandException(
1565 : : rtl::OUString( "Not supported by root folder!" ),
1566 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1567 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1568 : : // Unreachable
1569 : : }
1570 : :
1571 : 0 : m_eState = DEAD;
1572 : :
1573 [ # # ]: 0 : aGuard.clear();
1574 [ # # ]: 0 : deleted();
1575 : :
1576 [ # # ]: 0 : if ( m_eKind == FOLDER )
1577 : : {
1578 : : // Process instanciated children...
1579 : :
1580 [ # # ]: 0 : HierarchyContentRefList aChildren;
1581 [ # # ]: 0 : queryChildren( aChildren );
1582 : :
1583 : 0 : HierarchyContentRefList::const_iterator it = aChildren.begin();
1584 : 0 : HierarchyContentRefList::const_iterator end = aChildren.end();
1585 : :
1586 [ # # ]: 0 : while ( it != end )
1587 : : {
1588 [ # # ]: 0 : (*it)->destroy( bDeletePhysical, xEnv );
1589 : 0 : ++it;
1590 : 0 : }
1591 [ # # ]: 0 : }
1592 : 0 : }
1593 : :
1594 : : //=========================================================================
1595 : 0 : void HierarchyContent::transfer(
1596 : : const ucb::TransferInfo& rInfo,
1597 : : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1598 : : throw( uno::Exception )
1599 : : {
1600 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1601 : :
1602 : : // Persistent?
1603 [ # # ]: 0 : if ( m_eState != PERSISTENT )
1604 : : {
1605 : : ucbhelper::cancelCommandExecution(
1606 : : uno::makeAny( ucb::UnsupportedCommandException(
1607 : : rtl::OUString( "Not persistent!" ),
1608 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1609 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1610 : : // Unreachable
1611 : : }
1612 : :
1613 : : // Is source a hierarchy content?
1614 [ # # # # ]: 0 : if ( ( rInfo.SourceURL.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 2 ) ||
[ # # ]
1615 : : ( rInfo.SourceURL.compareToAscii( HIERARCHY_URL_SCHEME ":/",
1616 : 0 : HIERARCHY_URL_SCHEME_LENGTH + 2 )
1617 : : != 0 ) )
1618 : : {
1619 : : ucbhelper::cancelCommandExecution(
1620 : : uno::makeAny( ucb::InteractiveBadTransferURLException(
1621 : : rtl::OUString(),
1622 : : static_cast< cppu::OWeakObject * >( this ) ) ),
1623 [ # # ][ # # ]: 0 : xEnv );
[ # # ][ # # ]
[ # # ]
1624 : : // Unreachable
1625 : : }
1626 : :
1627 : : // Is source not a parent of me / not me?
1628 [ # # ][ # # ]: 0 : rtl::OUString aId = m_xIdentifier->getContentIdentifier();
1629 : 0 : sal_Int32 nPos = aId.lastIndexOf( '/' );
1630 [ # # ]: 0 : if ( nPos != ( aId.getLength() - 1 ) )
1631 : : {
1632 : : // No trailing slash found. Append.
1633 : 0 : aId += rtl::OUString("/");
1634 : : }
1635 : :
1636 [ # # ]: 0 : if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1637 : : {
1638 [ # # ]: 0 : if ( aId.compareTo(
1639 : 0 : rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
1640 : : {
1641 : : uno::Any aProps
1642 : : = uno::makeAny(beans::PropertyValue(
1643 : : rtl::OUString( "Uri"),
1644 : : -1,
1645 : : uno::makeAny(rInfo.SourceURL),
1646 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
1647 : : ucbhelper::cancelCommandExecution(
1648 : : ucb::IOErrorCode_RECURSIVE,
1649 : : uno::Sequence< uno::Any >(&aProps, 1),
1650 : : xEnv,
1651 : : rtl::OUString( "Target is equal to or is a child of source!" ),
1652 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1653 : : // Unreachable
1654 : : }
1655 : : }
1656 : :
1657 : : //////////////////////////////////////////////////////////////////////
1658 : : // 0) Obtain content object for source.
1659 : : //////////////////////////////////////////////////////////////////////
1660 : :
1661 : : uno::Reference< ucb::XContentIdentifier > xId
1662 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, rInfo.SourceURL );
[ # # ]
1663 : :
1664 : : // Note: The static cast is okay here, because its sure that
1665 : : // m_xProvider is always the HierarchyContentProvider.
1666 : 0 : rtl::Reference< HierarchyContent > xSource;
1667 : :
1668 : : try
1669 : : {
1670 : : xSource = static_cast< HierarchyContent * >(
1671 [ # # ][ # # ]: 0 : m_xProvider->queryContent( xId ).get() );
[ # # ][ # # ]
[ # # ]
1672 : : }
1673 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
1674 : : {
1675 : : // queryContent
1676 : : }
1677 : :
1678 [ # # ]: 0 : if ( !xSource.is() )
1679 : : {
1680 : : uno::Any aProps
1681 : : = uno::makeAny(beans::PropertyValue(
1682 : : rtl::OUString( "Uri"),
1683 : : -1,
1684 [ # # ]: 0 : uno::makeAny(xId->getContentIdentifier()),
1685 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1686 : : ucbhelper::cancelCommandExecution(
1687 : : ucb::IOErrorCode_CANT_READ,
1688 : : uno::Sequence< uno::Any >(&aProps, 1),
1689 : : xEnv,
1690 : : rtl::OUString( "Cannot instanciate source object!" ),
1691 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1692 : : // Unreachable
1693 : : }
1694 : :
1695 : : //////////////////////////////////////////////////////////////////////
1696 : : // 1) Create new child content.
1697 : : //////////////////////////////////////////////////////////////////////
1698 : :
1699 : 0 : rtl::OUString aType = xSource->isFolder()
1700 : : ? rtl::OUString( HIERARCHY_FOLDER_CONTENT_TYPE )
1701 [ # # ][ # # ]: 0 : : rtl::OUString( HIERARCHY_LINK_CONTENT_TYPE );
[ # # ]
1702 [ # # ]: 0 : ucb::ContentInfo aContentInfo;
1703 : 0 : aContentInfo.Type = aType;
1704 : 0 : aContentInfo.Attributes = 0;
1705 : :
1706 : : // Note: The static cast is okay here, because its sure that
1707 : : // createNewContent always creates a HierarchyContent.
1708 : : rtl::Reference< HierarchyContent > xTarget
1709 : : = static_cast< HierarchyContent * >(
1710 [ # # ][ # # ]: 0 : createNewContent( aContentInfo ).get() );
[ # # ]
1711 [ # # ]: 0 : if ( !xTarget.is() )
1712 : : {
1713 : : uno::Any aProps
1714 : : = uno::makeAny(beans::PropertyValue(
1715 : : rtl::OUString( "Folder"),
1716 : : -1,
1717 : : uno::makeAny(aId),
1718 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
1719 : : ucbhelper::cancelCommandExecution(
1720 : : ucb::IOErrorCode_CANT_CREATE,
1721 : : uno::Sequence< uno::Any >(&aProps, 1),
1722 : : xEnv,
1723 : : rtl::OUString( "XContentCreator::createNewContent failed!" ),
1724 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1725 : : // Unreachable
1726 : : }
1727 : :
1728 : : //////////////////////////////////////////////////////////////////////
1729 : : // 2) Copy data from source content to child content.
1730 : : //////////////////////////////////////////////////////////////////////
1731 : :
1732 : : uno::Sequence< beans::Property > aSourceProps
1733 [ # # ][ # # ]: 0 : = xSource->getPropertySetInfo( xEnv )->getProperties();
[ # # ]
1734 : 0 : sal_Int32 nCount = aSourceProps.getLength();
1735 : :
1736 [ # # ]: 0 : if ( nCount )
1737 : : {
1738 : 0 : sal_Bool bHadTitle = rInfo.NewTitle.isEmpty();
1739 : :
1740 : : // Get all source values.
1741 : : uno::Reference< sdbc::XRow > xRow
1742 [ # # ]: 0 : = xSource->getPropertyValues( aSourceProps );
1743 : :
1744 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aValues( nCount );
1745 [ # # ]: 0 : beans::PropertyValue* pValues = aValues.getArray();
1746 : :
1747 : 0 : const beans::Property* pProps = aSourceProps.getConstArray();
1748 [ # # ]: 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1749 : : {
1750 : 0 : const beans::Property& rProp = pProps[ n ];
1751 : 0 : beans::PropertyValue& rValue = pValues[ n ];
1752 : :
1753 : 0 : rValue.Name = rProp.Name;
1754 : 0 : rValue.Handle = rProp.Handle;
1755 : :
1756 [ # # ][ # # ]: 0 : if ( !bHadTitle && rProp.Name == "Title" )
[ # # ]
1757 : : {
1758 : : // Set new title instead of original.
1759 : 0 : bHadTitle = sal_True;
1760 [ # # ]: 0 : rValue.Value <<= rInfo.NewTitle;
1761 : : }
1762 : : else
1763 [ # # ]: 0 : rValue.Value = xRow->getObject(
1764 : : n + 1,
1765 [ # # ]: 0 : uno::Reference< container::XNameAccess >() );
[ # # # # ]
1766 : :
1767 : 0 : rValue.State = beans::PropertyState_DIRECT_VALUE;
1768 : :
1769 [ # # ]: 0 : if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1770 : : {
1771 : : // Add Additional Core Property.
1772 : : try
1773 : : {
1774 : 0 : xTarget->addProperty( rProp.Name,
1775 : : rProp.Attributes,
1776 [ # # ]: 0 : rValue.Value );
1777 : : }
1778 [ # # ]: 0 : catch ( beans::PropertyExistException const & )
1779 : : {
1780 : : }
1781 [ # # ]: 0 : catch ( beans::IllegalTypeException const & )
1782 : : {
1783 : : }
1784 [ # # ]: 0 : catch ( lang::IllegalArgumentException const & )
1785 : : {
1786 : : }
1787 : : }
1788 : : }
1789 : :
1790 : : // Set target values.
1791 [ # # ][ # # ]: 0 : xTarget->setPropertyValues( aValues, xEnv );
[ # # ]
1792 : : }
1793 : :
1794 : : //////////////////////////////////////////////////////////////////////
1795 : : // 3) Commit (insert) child.
1796 : : //////////////////////////////////////////////////////////////////////
1797 : :
1798 [ # # ]: 0 : xTarget->insert( rInfo.NameClash, xEnv );
1799 : :
1800 : : //////////////////////////////////////////////////////////////////////
1801 : : // 4) Transfer (copy) children of source.
1802 : : //////////////////////////////////////////////////////////////////////
1803 : :
1804 [ # # ]: 0 : if ( xSource->isFolder() )
1805 : : {
1806 : : HierarchyEntry aFolder(
1807 [ # # ][ # # ]: 0 : m_xSMgr, m_pProvider, xId->getContentIdentifier() );
[ # # ]
1808 [ # # ]: 0 : HierarchyEntry::iterator it;
1809 : :
1810 [ # # ][ # # ]: 0 : while ( aFolder.next( it ) )
1811 : : {
1812 [ # # ]: 0 : const HierarchyEntryData& rResult = *it;
1813 : :
1814 [ # # ][ # # ]: 0 : rtl::OUString aChildId = xId->getContentIdentifier();
1815 [ # # ]: 0 : if ( ( aChildId.lastIndexOf( '/' ) + 1 ) != aChildId.getLength() )
1816 : 0 : aChildId += rtl::OUString("/");
1817 : :
1818 : 0 : aChildId += rResult.getName();
1819 : :
1820 : 0 : ucb::TransferInfo aInfo;
1821 : 0 : aInfo.MoveData = sal_False;
1822 : 0 : aInfo.NewTitle = rtl::OUString();
1823 : 0 : aInfo.SourceURL = aChildId;
1824 : 0 : aInfo.NameClash = rInfo.NameClash;
1825 : :
1826 : : // Transfer child to target.
1827 [ # # ]: 0 : xTarget->transfer( aInfo, xEnv );
1828 [ # # ][ # # ]: 0 : }
1829 : : }
1830 : :
1831 : : //////////////////////////////////////////////////////////////////////
1832 : : // 5) Destroy source ( when moving only ) .
1833 : : //////////////////////////////////////////////////////////////////////
1834 : :
1835 [ # # ]: 0 : if ( rInfo.MoveData )
1836 : : {
1837 [ # # ]: 0 : xSource->destroy( sal_True, xEnv );
1838 : :
1839 : : // Remove all persistent data of source and its children.
1840 [ # # ][ # # ]: 0 : if ( !xSource->removeData() )
1841 : : {
1842 : : uno::Any aProps
1843 : : = uno::makeAny(
1844 : : beans::PropertyValue(
1845 : : rtl::OUString( "Uri"),
1846 : : -1,
1847 : : uno::makeAny(
1848 [ # # ]: 0 : xSource->m_xIdentifier->
1849 : 0 : getContentIdentifier()),
1850 [ # # ][ # # ]: 0 : beans::PropertyState_DIRECT_VALUE));
[ # # ]
1851 : : ucbhelper::cancelCommandExecution(
1852 : : ucb::IOErrorCode_CANT_WRITE,
1853 : : uno::Sequence< uno::Any >(&aProps, 1),
1854 : : xEnv,
1855 : : rtl::OUString( "Cannot remove persistent data of source object!" ),
1856 [ # # ][ # # ]: 0 : this );
[ # # ][ # # ]
1857 : : // Unreachable
1858 : : }
1859 : :
1860 : : // Remove own and all children's Additional Core Properties.
1861 [ # # ]: 0 : xSource->removeAdditionalPropertySet( sal_True );
1862 [ # # ][ # # ]: 0 : }
[ # # ]
1863 : 0 : }
1864 : :
1865 : : //=========================================================================
1866 : : //=========================================================================
1867 : : //
1868 : : // HierarchyContentProperties Implementation.
1869 : : //
1870 : : //=========================================================================
1871 : : //=========================================================================
1872 : :
1873 : : uno::Sequence< ucb::ContentInfo >
1874 : 0 : HierarchyContentProperties::getCreatableContentsInfo() const
1875 : : {
1876 [ # # ]: 0 : if ( getIsFolder() )
1877 : : {
1878 [ # # ]: 0 : uno::Sequence< ucb::ContentInfo > aSeq( 2 );
1879 : :
1880 : : // Folder.
1881 [ # # ]: 0 : aSeq.getArray()[ 0 ].Type
1882 : 0 : = rtl::OUString( HIERARCHY_FOLDER_CONTENT_TYPE );
1883 [ # # ]: 0 : aSeq.getArray()[ 0 ].Attributes
1884 : 0 : = ucb::ContentInfoAttribute::KIND_FOLDER;
1885 : :
1886 [ # # ]: 0 : uno::Sequence< beans::Property > aFolderProps( 1 );
1887 : : aFolderProps.getArray()[ 0 ] = beans::Property(
1888 : : rtl::OUString("Title"),
1889 : : -1,
1890 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1891 [ # # ]: 0 : beans::PropertyAttribute::BOUND );
1892 [ # # ][ # # ]: 0 : aSeq.getArray()[ 0 ].Properties = aFolderProps;
1893 : :
1894 : : // Link.
1895 [ # # ]: 0 : aSeq.getArray()[ 1 ].Type
1896 : 0 : = rtl::OUString( HIERARCHY_LINK_CONTENT_TYPE );
1897 [ # # ]: 0 : aSeq.getArray()[ 1 ].Attributes
1898 : 0 : = ucb::ContentInfoAttribute::KIND_LINK;
1899 : :
1900 [ # # ]: 0 : uno::Sequence< beans::Property > aLinkProps( 2 );
1901 : : aLinkProps.getArray()[ 0 ] = beans::Property(
1902 : : rtl::OUString("Title"),
1903 : : -1,
1904 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1905 [ # # ]: 0 : beans::PropertyAttribute::BOUND );
1906 [ # # ]: 0 : aLinkProps.getArray()[ 1 ] = beans::Property(
1907 : : rtl::OUString("TargetURL"),
1908 : : -1,
1909 [ # # ]: 0 : getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1910 : 0 : beans::PropertyAttribute::BOUND );
1911 [ # # ][ # # ]: 0 : aSeq.getArray()[ 1 ].Properties = aLinkProps;
1912 : :
1913 [ # # ][ # # ]: 0 : return aSeq;
[ # # ][ # # ]
1914 : : }
1915 : : else
1916 : : {
1917 : 0 : return uno::Sequence< ucb::ContentInfo >( 0 );
1918 : : }
1919 : : }
1920 : :
1921 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|