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