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