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