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( true ),
91 : bEncrypted( false ),
92 0 : bHasEncryptedEntries( 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 10 : ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
105 : {
106 10 : if ( bIsFolder )
107 : {
108 4 : uno::Sequence< beans::Property > aProps( 1 );
109 8 : aProps.getArray()[ 0 ] = beans::Property(
110 : OUString("Title"),
111 : -1,
112 4 : cppu::UnoType<OUString>::get(),
113 4 : beans::PropertyAttribute::BOUND );
114 :
115 8 : uno::Sequence< ucb::ContentInfo > aSeq( 2 );
116 :
117 : // Folder.
118 4 : aSeq.getArray()[ 0 ].Type
119 8 : = Content::getContentType( rUri.getScheme(), true );
120 4 : aSeq.getArray()[ 0 ].Attributes
121 4 : = ucb::ContentInfoAttribute::KIND_FOLDER;
122 4 : aSeq.getArray()[ 0 ].Properties = aProps;
123 :
124 : // Stream.
125 4 : aSeq.getArray()[ 1 ].Type
126 8 : = Content::getContentType( rUri.getScheme(), false );
127 4 : aSeq.getArray()[ 1 ].Attributes
128 : = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
129 4 : | ucb::ContentInfoAttribute::KIND_DOCUMENT;
130 4 : aSeq.getArray()[ 1 ].Properties = aProps;
131 :
132 8 : return aSeq;
133 : }
134 : else
135 : {
136 6 : return uno::Sequence< ucb::ContentInfo >( 0 );
137 : }
138 : }
139 :
140 :
141 :
142 :
143 : // Content Implementation.
144 :
145 :
146 :
147 :
148 : // static ( "virtual" ctor )
149 25 : Content* Content::create(
150 : const uno::Reference< uno::XComponentContext >& rxContext,
151 : ContentProvider* pProvider,
152 : const uno::Reference< ucb::XContentIdentifier >& Identifier )
153 : {
154 25 : OUString aURL = Identifier->getContentIdentifier();
155 50 : PackageUri aURI( aURL );
156 50 : ContentProperties aProps;
157 50 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
158 :
159 25 : if ( loadData( pProvider, aURI, aProps, xPackage ) )
160 : {
161 : // resource exists
162 :
163 25 : sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
164 25 : if ( ( nLastSlash + 1 ) == aURL.getLength() )
165 : {
166 : // Client explicitly requested a folder!
167 3 : if ( !aProps.bIsFolder )
168 0 : return 0;
169 : }
170 :
171 : uno::Reference< ucb::XContentIdentifier > xId
172 25 : = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
173 25 : return new Content( rxContext, pProvider, xId, xPackage, aURI, aProps );
174 : }
175 : else
176 : {
177 : // resource doesn't exist
178 :
179 0 : bool bFolder = 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 = 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(), true );
192 : else
193 0 : aInfo.Type = getContentType( aURI.getScheme(), false );
194 :
195 0 : return new Content( rxContext, pProvider, xId, xPackage, aURI, aInfo );
196 25 : }
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(), true ) ) &&
214 : !Info.Type.equalsIgnoreAsciiCase(
215 0 : getContentType( aURI.getScheme(), 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 41 : OUString Content::getContentType(
230 : const OUString& aScheme, bool bFolder )
231 : {
232 : return ( "application/"
233 82 : + aScheme
234 82 : + ( bFolder
235 : ? OUString("-folder")
236 123 : : OUString("-stream") ) );
237 : }
238 :
239 :
240 25 : 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 25 : m_nModifiedProps( NONE_MODIFIED )
254 : {
255 25 : }
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 50 : Content::~Content()
278 : {
279 50 : }
280 :
281 :
282 :
283 : // XInterface methods.
284 :
285 :
286 :
287 : // virtual
288 438 : void SAL_CALL Content::acquire()
289 : throw( )
290 : {
291 438 : ContentImplHelper::acquire();
292 438 : }
293 :
294 :
295 : // virtual
296 438 : void SAL_CALL Content::release()
297 : throw( )
298 : {
299 438 : ContentImplHelper::release();
300 438 : }
301 :
302 :
303 : // virtual
304 88 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
305 : throw ( uno::RuntimeException, std::exception )
306 : {
307 88 : uno::Any aRet;
308 :
309 88 : if ( isFolder() )
310 140 : aRet = cppu::queryInterface(
311 70 : rType, static_cast< ucb::XContentCreator * >( this ) );
312 :
313 88 : 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 61 : 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 61 : uno::Any aRet;
456 :
457 61 : if ( aCommand.Name == "getPropertyValues" )
458 : {
459 :
460 : // getPropertyValues
461 :
462 :
463 27 : uno::Sequence< beans::Property > Properties;
464 27 : 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 27 : aRet <<= getPropertyValues( Properties );
476 : }
477 34 : 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 34 : else if ( aCommand.Name == "getPropertySetInfo" )
509 : {
510 :
511 : // getPropertySetInfo
512 :
513 :
514 : // Note: Implemented by base class.
515 10 : aRet <<= getPropertySetInfo( Environment );
516 : }
517 24 : else if ( aCommand.Name == "getCommandInfo" )
518 : {
519 :
520 : // getCommandInfo
521 :
522 :
523 : // Note: Implemented by base class.
524 0 : aRet <<= getCommandInfo( Environment );
525 : }
526 24 : else if ( aCommand.Name == "open" )
527 : {
528 :
529 : // open
530 :
531 :
532 24 : ucb::OpenCommandArgument2 aOpenCommand;
533 24 : 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 24 : 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 : bool bDeletePhysical = 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 61 : 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(), true ) ) &&
726 : !Info.Type.equalsIgnoreAsciiCase(
727 0 : getContentType( m_aUri.getScheme(), 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(), 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 8 : 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 8 : ContentProperties aData;
772 16 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
773 8 : 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 8 : 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 8 : }
798 : }
799 :
800 :
801 : // static
802 35 : 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 35 : = new ::ucbhelper::PropertyValueSet( rxContext );
814 :
815 35 : sal_Int32 nCount = rProperties.getLength();
816 35 : if ( nCount )
817 : {
818 35 : uno::Reference< beans::XPropertySet > xAdditionalPropSet;
819 35 : bool bTriedToGetAdditionalPropSet = false;
820 :
821 35 : const beans::Property* pProps = rProperties.getConstArray();
822 162 : for ( sal_Int32 n = 0; n < nCount; ++n )
823 : {
824 127 : const beans::Property& rProp = pProps[ n ];
825 :
826 : // Process Core properties.
827 :
828 127 : if ( rProp.Name == "ContentType" )
829 : {
830 10 : xRow->appendString ( rProp, rData.aContentType );
831 : }
832 117 : else if ( rProp.Name == "Title" )
833 : {
834 10 : xRow->appendString ( rProp, rData.aTitle );
835 : }
836 107 : else if ( rProp.Name == "IsDocument" )
837 : {
838 21 : xRow->appendBoolean( rProp, rData.bIsDocument );
839 : }
840 86 : else if ( rProp.Name == "IsFolder" )
841 : {
842 21 : xRow->appendBoolean( rProp, rData.bIsFolder );
843 : }
844 65 : else if ( rProp.Name == "CreatableContentsInfo" )
845 : {
846 : xRow->appendObject(
847 : rProp, uno::makeAny(
848 : rData.getCreatableContentsInfo(
849 10 : PackageUri( rContentId ) ) ) );
850 : }
851 55 : else if ( rProp.Name == "MediaType" )
852 : {
853 23 : xRow->appendString ( rProp, rData.aMediaType );
854 : }
855 32 : else if ( rProp.Name == "Size" )
856 : {
857 : // Property only available for streams.
858 6 : if ( rData.bIsDocument )
859 6 : xRow->appendLong( rProp, rData.nSize );
860 : else
861 0 : xRow->appendVoid( rProp );
862 : }
863 26 : else if ( rProp.Name == "Compressed" )
864 : {
865 : // Property only available for streams.
866 6 : if ( rData.bIsDocument )
867 6 : xRow->appendBoolean( rProp, rData.bCompressed );
868 : else
869 0 : xRow->appendVoid( rProp );
870 : }
871 20 : else if ( rProp.Name == "Encrypted" )
872 : {
873 : // Property only available for streams.
874 6 : if ( rData.bIsDocument )
875 6 : xRow->appendBoolean( rProp, rData.bEncrypted );
876 : else
877 0 : xRow->appendVoid( rProp );
878 : }
879 14 : else if ( rProp.Name == "HasEncryptedEntries" )
880 : {
881 : // Property only available for root folder.
882 2 : PackageUri aURI( rContentId );
883 2 : if ( aURI.isRootFolder() )
884 2 : 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 12 : if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
893 : {
894 : xAdditionalPropSet
895 20 : = uno::Reference< beans::XPropertySet >(
896 : rProvider->getAdditionalPropertySet( rContentId,
897 : false ),
898 10 : uno::UNO_QUERY );
899 10 : bTriedToGetAdditionalPropSet = true;
900 : }
901 :
902 12 : 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 12 : xRow->appendVoid( rProp );
916 : }
917 : }
918 35 : }
919 : }
920 : else
921 : {
922 : // Append all Core Properties.
923 : xRow->appendString (
924 : beans::Property(
925 : OUString("ContentType"),
926 : -1,
927 0 : cppu::UnoType<OUString>::get(),
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 : cppu::UnoType<OUString>::get(),
936 : beans::PropertyAttribute::BOUND ),
937 0 : rData.aTitle );
938 : xRow->appendBoolean(
939 : beans::Property(
940 : OUString("IsDocument"),
941 : -1,
942 0 : cppu::UnoType<bool>::get(),
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 : cppu::UnoType<bool>::get(),
951 : beans::PropertyAttribute::BOUND
952 : | beans::PropertyAttribute::READONLY ),
953 0 : rData.bIsFolder );
954 : xRow->appendObject(
955 : beans::Property(
956 : OUString("CreatableContentsInfo"),
957 : -1,
958 0 : cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
959 : beans::PropertyAttribute::BOUND
960 : | beans::PropertyAttribute::READONLY ),
961 : uno::makeAny(
962 0 : rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
963 : xRow->appendString(
964 : beans::Property(
965 : OUString("MediaType"),
966 : -1,
967 0 : cppu::UnoType<OUString>::get(),
968 : beans::PropertyAttribute::BOUND ),
969 0 : rData.aMediaType );
970 :
971 : // Properties only available for streams.
972 0 : if ( rData.bIsDocument )
973 : {
974 : xRow->appendLong(
975 : beans::Property(
976 : OUString("Size"),
977 : -1,
978 0 : cppu::UnoType<sal_Int64>::get(),
979 : beans::PropertyAttribute::BOUND
980 : | beans::PropertyAttribute::READONLY ),
981 0 : rData.nSize );
982 :
983 : xRow->appendBoolean(
984 : beans::Property(
985 : OUString("Compressed"),
986 : -1,
987 0 : cppu::UnoType<bool>::get(),
988 : beans::PropertyAttribute::BOUND ),
989 0 : rData.bCompressed );
990 :
991 : xRow->appendBoolean(
992 : beans::Property(
993 : OUString("Encrypted"),
994 : -1,
995 0 : cppu::UnoType<bool>::get(),
996 : beans::PropertyAttribute::BOUND ),
997 0 : rData.bEncrypted );
998 : }
999 :
1000 : // Properties only available for root folder.
1001 0 : PackageUri aURI( rContentId );
1002 0 : if ( aURI.isRootFolder() )
1003 : {
1004 : xRow->appendBoolean(
1005 : beans::Property(
1006 : OUString("HasEncryptedEntries"),
1007 : -1,
1008 0 : cppu::UnoType<bool>::get(),
1009 : beans::PropertyAttribute::BOUND
1010 : | beans::PropertyAttribute::READONLY ),
1011 0 : rData.bHasEncryptedEntries );
1012 : }
1013 :
1014 : // Append all Additional Core Properties.
1015 :
1016 : uno::Reference< beans::XPropertySet > xSet(
1017 : rProvider->getAdditionalPropertySet( rContentId, false ),
1018 0 : uno::UNO_QUERY );
1019 0 : xRow->appendPropertySet( xSet );
1020 : }
1021 :
1022 35 : return uno::Reference< sdbc::XRow >( xRow.get() );
1023 : }
1024 :
1025 :
1026 27 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
1027 : const uno::Sequence< beans::Property >& rProperties )
1028 : {
1029 27 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1030 : return getPropertyValues( m_xContext,
1031 : rProperties,
1032 : m_aProps,
1033 : rtl::Reference<
1034 : ::ucbhelper::ContentProviderImplHelper >(
1035 : m_xProvider.get() ),
1036 27 : m_xIdentifier->getContentIdentifier() );
1037 : }
1038 :
1039 :
1040 0 : uno::Sequence< uno::Any > Content::setPropertyValues(
1041 : const uno::Sequence< beans::PropertyValue >& rValues,
1042 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1043 : throw( uno::Exception )
1044 : {
1045 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1046 :
1047 0 : uno::Sequence< uno::Any > aRet( rValues.getLength() );
1048 0 : uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1049 0 : sal_Int32 nChanged = 0;
1050 :
1051 0 : beans::PropertyChangeEvent aEvent;
1052 0 : aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1053 0 : aEvent.Further = sal_False;
1054 : // aEvent.PropertyName =
1055 0 : aEvent.PropertyHandle = -1;
1056 : // aEvent.OldValue =
1057 : // aEvent.NewValue =
1058 :
1059 0 : const beans::PropertyValue* pValues = rValues.getConstArray();
1060 0 : sal_Int32 nCount = rValues.getLength();
1061 :
1062 0 : uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1063 0 : bool bTriedToGetAdditionalPropSet = false;
1064 0 : bool bExchange = false;
1065 0 : bool bStore = false;
1066 0 : OUString aNewTitle;
1067 0 : sal_Int32 nTitlePos = -1;
1068 :
1069 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1070 : {
1071 0 : const beans::PropertyValue& rValue = pValues[ n ];
1072 :
1073 0 : if ( rValue.Name == "ContentType" )
1074 : {
1075 : // Read-only property!
1076 0 : aRet[ n ] <<= lang::IllegalAccessException(
1077 : OUString(
1078 : "Property is read-only!" ),
1079 0 : static_cast< cppu::OWeakObject * >( this ) );
1080 : }
1081 0 : else if ( rValue.Name == "IsDocument" )
1082 : {
1083 : // Read-only property!
1084 0 : aRet[ n ] <<= lang::IllegalAccessException(
1085 : OUString(
1086 : "Property is read-only!" ),
1087 0 : static_cast< cppu::OWeakObject * >( this ) );
1088 : }
1089 0 : else if ( rValue.Name == "IsFolder" )
1090 : {
1091 : // Read-only property!
1092 0 : aRet[ n ] <<= lang::IllegalAccessException(
1093 : OUString(
1094 : "Property is read-only!" ),
1095 0 : static_cast< cppu::OWeakObject * >( this ) );
1096 : }
1097 0 : else if ( rValue.Name == "CreatableContentsInfo" )
1098 : {
1099 : // Read-only property!
1100 0 : aRet[ n ] <<= lang::IllegalAccessException(
1101 : OUString(
1102 : "Property is read-only!" ),
1103 0 : static_cast< cppu::OWeakObject * >( this ) );
1104 : }
1105 0 : else if ( rValue.Name == "Title" )
1106 : {
1107 0 : if ( m_aUri.isRootFolder() )
1108 : {
1109 : // Read-only property!
1110 0 : aRet[ n ] <<= lang::IllegalAccessException(
1111 : OUString(
1112 : "Property is read-only!" ),
1113 0 : static_cast< cppu::OWeakObject * >( this ) );
1114 : }
1115 : else
1116 : {
1117 0 : OUString aNewValue;
1118 0 : if ( rValue.Value >>= aNewValue )
1119 : {
1120 : // No empty titles!
1121 0 : if ( !aNewValue.isEmpty() )
1122 : {
1123 0 : if ( aNewValue != m_aProps.aTitle )
1124 : {
1125 : // modified title -> modified URL -> exchange !
1126 0 : if ( m_eState == PERSISTENT )
1127 0 : bExchange = true;
1128 :
1129 : // new value will be set later...
1130 0 : aNewTitle = aNewValue;
1131 :
1132 : // remember position within sequence of values
1133 : // (for error handling).
1134 0 : nTitlePos = n;
1135 : }
1136 : }
1137 : else
1138 : {
1139 0 : aRet[ n ] <<=
1140 : lang::IllegalArgumentException(
1141 : OUString(
1142 : "Empty title not allowed!" ),
1143 : static_cast< cppu::OWeakObject * >( this ),
1144 0 : -1 );
1145 : }
1146 : }
1147 : else
1148 : {
1149 0 : aRet[ n ] <<=
1150 : beans::IllegalTypeException(
1151 : OUString(
1152 : "Property value has wrong type!" ),
1153 0 : static_cast< cppu::OWeakObject * >( this ) );
1154 0 : }
1155 : }
1156 : }
1157 0 : else if ( rValue.Name == "MediaType" )
1158 : {
1159 0 : OUString aNewValue;
1160 0 : if ( rValue.Value >>= aNewValue )
1161 : {
1162 0 : if ( aNewValue != m_aProps.aMediaType )
1163 : {
1164 0 : aEvent.PropertyName = rValue.Name;
1165 0 : aEvent.OldValue = uno::makeAny( m_aProps.aMediaType );
1166 0 : aEvent.NewValue = uno::makeAny( aNewValue );
1167 :
1168 0 : m_aProps.aMediaType = aNewValue;
1169 0 : nChanged++;
1170 0 : bStore = true;
1171 0 : m_nModifiedProps |= MEDIATYPE_MODIFIED;
1172 : }
1173 : }
1174 : else
1175 : {
1176 0 : aRet[ n ] <<= beans::IllegalTypeException(
1177 : OUString(
1178 : "Property value has wrong type!" ),
1179 0 : static_cast< cppu::OWeakObject * >( this ) );
1180 0 : }
1181 : }
1182 0 : else if ( rValue.Name == "Size" )
1183 : {
1184 : // Read-only property!
1185 0 : aRet[ n ] <<= lang::IllegalAccessException(
1186 : OUString(
1187 : "Property is read-only!" ),
1188 0 : static_cast< cppu::OWeakObject * >( this ) );
1189 : }
1190 0 : else if ( rValue.Name == "Compressed" )
1191 : {
1192 : // Property only available for streams.
1193 0 : if ( m_aProps.bIsDocument )
1194 : {
1195 : bool bNewValue;
1196 0 : if ( rValue.Value >>= bNewValue )
1197 : {
1198 0 : if ( bNewValue != m_aProps.bCompressed )
1199 : {
1200 0 : aEvent.PropertyName = rValue.Name;
1201 0 : aEvent.OldValue = uno::makeAny( m_aProps.bCompressed );
1202 0 : aEvent.NewValue = uno::makeAny( bNewValue );
1203 :
1204 0 : m_aProps.bCompressed = bNewValue;
1205 0 : nChanged++;
1206 0 : bStore = true;
1207 0 : m_nModifiedProps |= COMPRESSED_MODIFIED;
1208 : }
1209 : }
1210 : else
1211 : {
1212 0 : aRet[ n ] <<= beans::IllegalTypeException(
1213 : OUString(
1214 : "Property value has wrong type!" ),
1215 0 : static_cast< cppu::OWeakObject * >( this ) );
1216 : }
1217 : }
1218 : else
1219 : {
1220 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1221 : OUString(
1222 : "Compressed only supported by streams!" ),
1223 0 : static_cast< cppu::OWeakObject * >( this ) );
1224 : }
1225 : }
1226 0 : else if ( rValue.Name == "Encrypted" )
1227 : {
1228 : // Property only available for streams.
1229 0 : if ( m_aProps.bIsDocument )
1230 : {
1231 : bool bNewValue;
1232 0 : if ( rValue.Value >>= bNewValue )
1233 : {
1234 0 : if ( bNewValue != m_aProps.bEncrypted )
1235 : {
1236 0 : aEvent.PropertyName = rValue.Name;
1237 0 : aEvent.OldValue = uno::makeAny( m_aProps.bEncrypted );
1238 0 : aEvent.NewValue = uno::makeAny( bNewValue );
1239 :
1240 0 : m_aProps.bEncrypted = bNewValue;
1241 0 : nChanged++;
1242 0 : bStore = true;
1243 0 : m_nModifiedProps |= ENCRYPTED_MODIFIED;
1244 : }
1245 : }
1246 : else
1247 : {
1248 0 : aRet[ n ] <<= beans::IllegalTypeException(
1249 : OUString(
1250 : "Property value has wrong type!" ),
1251 0 : static_cast< cppu::OWeakObject * >( this ) );
1252 : }
1253 : }
1254 : else
1255 : {
1256 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1257 : OUString(
1258 : "Encrypted only supported by streams!" ),
1259 0 : static_cast< cppu::OWeakObject * >( this ) );
1260 : }
1261 : }
1262 0 : else if ( rValue.Name == "HasEncryptedEntries" )
1263 : {
1264 : // Read-only property!
1265 0 : aRet[ n ] <<= lang::IllegalAccessException(
1266 : OUString(
1267 : "Property is read-only!" ),
1268 0 : static_cast< cppu::OWeakObject * >( this ) );
1269 : }
1270 0 : else if ( rValue.Name == "EncryptionKey" )
1271 : {
1272 : // @@@ This is a temporary solution. In the future submitting
1273 : // the key should be done using an interaction handler!
1274 :
1275 : // Write-Only property. Only supported by root folder and streams
1276 : // (all non-root folders of a package have the same encryption key).
1277 0 : if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
1278 : {
1279 0 : uno::Sequence < sal_Int8 > aNewValue;
1280 0 : if ( rValue.Value >>= aNewValue )
1281 : {
1282 0 : if ( aNewValue != m_aProps.aEncryptionKey )
1283 : {
1284 0 : aEvent.PropertyName = rValue.Name;
1285 0 : aEvent.OldValue = uno::makeAny(
1286 0 : m_aProps.aEncryptionKey );
1287 0 : aEvent.NewValue = uno::makeAny( aNewValue );
1288 :
1289 0 : m_aProps.aEncryptionKey = aNewValue;
1290 0 : nChanged++;
1291 0 : bStore = true;
1292 0 : m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
1293 : }
1294 : }
1295 : else
1296 : {
1297 0 : aRet[ n ] <<= beans::IllegalTypeException(
1298 : OUString(
1299 : "Property value has wrong type!" ),
1300 0 : static_cast< cppu::OWeakObject * >( this ) );
1301 0 : }
1302 : }
1303 : else
1304 : {
1305 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1306 : OUString(
1307 : "EncryptionKey not supported by non-root folder!" ),
1308 0 : static_cast< cppu::OWeakObject * >( this ) );
1309 : }
1310 : }
1311 : else
1312 : {
1313 : // Not a Core Property! Maybe it's an Additional Core Property?!
1314 :
1315 0 : if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1316 : {
1317 0 : xAdditionalPropSet = getAdditionalPropertySet( false );
1318 0 : bTriedToGetAdditionalPropSet = true;
1319 : }
1320 :
1321 0 : if ( xAdditionalPropSet.is() )
1322 : {
1323 : try
1324 : {
1325 : uno::Any aOldValue
1326 0 : = xAdditionalPropSet->getPropertyValue( rValue.Name );
1327 0 : if ( aOldValue != rValue.Value )
1328 : {
1329 0 : xAdditionalPropSet->setPropertyValue(
1330 0 : rValue.Name, rValue.Value );
1331 :
1332 0 : aEvent.PropertyName = rValue.Name;
1333 0 : aEvent.OldValue = aOldValue;
1334 0 : aEvent.NewValue = rValue.Value;
1335 :
1336 0 : aChanges.getArray()[ nChanged ] = aEvent;
1337 0 : nChanged++;
1338 0 : }
1339 : }
1340 0 : catch ( beans::UnknownPropertyException const & e )
1341 : {
1342 0 : aRet[ n ] <<= e;
1343 : }
1344 0 : catch ( lang::WrappedTargetException const & e )
1345 : {
1346 0 : aRet[ n ] <<= e;
1347 : }
1348 0 : catch ( beans::PropertyVetoException const & e )
1349 : {
1350 0 : aRet[ n ] <<= e;
1351 : }
1352 0 : catch ( lang::IllegalArgumentException const & e )
1353 : {
1354 0 : aRet[ n ] <<= e;
1355 : }
1356 : }
1357 : else
1358 : {
1359 0 : aRet[ n ] <<= uno::Exception(
1360 : OUString(
1361 : "No property set for storing the value!" ),
1362 0 : static_cast< cppu::OWeakObject * >( this ) );
1363 : }
1364 : }
1365 : }
1366 :
1367 0 : if ( bExchange )
1368 : {
1369 0 : uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
1370 :
1371 : // Assemble new content identifier...
1372 0 : OUString aNewURL = m_aUri.getParentUri();
1373 0 : aNewURL += "/";
1374 0 : aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle );
1375 : uno::Reference< ucb::XContentIdentifier > xNewId
1376 0 : = new ::ucbhelper::ContentIdentifier( aNewURL );
1377 :
1378 0 : aGuard.clear();
1379 0 : if ( exchangeIdentity( xNewId ) )
1380 : {
1381 : // Adapt persistent data.
1382 0 : renameData( xOldId, xNewId );
1383 :
1384 : // Adapt Additional Core Properties.
1385 0 : renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1386 0 : xNewId->getContentIdentifier(),
1387 0 : true );
1388 : }
1389 : else
1390 : {
1391 : // Do not set new title!
1392 0 : aNewTitle.clear();
1393 :
1394 : // Set error .
1395 0 : aRet[ nTitlePos ] <<= uno::Exception(
1396 : OUString("Exchange failed!"),
1397 0 : static_cast< cppu::OWeakObject * >( this ) );
1398 0 : }
1399 : }
1400 :
1401 0 : if ( !aNewTitle.isEmpty() )
1402 : {
1403 0 : aEvent.PropertyName = "Title";
1404 0 : aEvent.OldValue = uno::makeAny( m_aProps.aTitle );
1405 0 : aEvent.NewValue = uno::makeAny( aNewTitle );
1406 :
1407 0 : m_aProps.aTitle = aNewTitle;
1408 :
1409 0 : aChanges.getArray()[ nChanged ] = aEvent;
1410 0 : nChanged++;
1411 : }
1412 :
1413 0 : if ( nChanged > 0 )
1414 : {
1415 : // Save changes, if content was already made persistent.
1416 0 : if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
1417 0 : ( bStore && ( m_eState == PERSISTENT ) ) )
1418 : {
1419 0 : if ( !storeData( uno::Reference< io::XInputStream >() ) )
1420 : {
1421 : uno::Any aProps
1422 : = uno::makeAny(
1423 : beans::PropertyValue(
1424 : OUString(
1425 : "Uri"),
1426 : -1,
1427 0 : uno::makeAny(m_xIdentifier->
1428 0 : getContentIdentifier()),
1429 0 : beans::PropertyState_DIRECT_VALUE));
1430 : ucbhelper::cancelCommandExecution(
1431 : ucb::IOErrorCode_CANT_WRITE,
1432 : uno::Sequence< uno::Any >(&aProps, 1),
1433 : xEnv,
1434 : OUString(
1435 : "Cannot store persistent data!" ),
1436 0 : this );
1437 : // Unreachable
1438 : }
1439 : }
1440 :
1441 0 : aGuard.clear();
1442 0 : aChanges.realloc( nChanged );
1443 0 : notifyPropertiesChange( aChanges );
1444 : }
1445 :
1446 0 : return aRet;
1447 : }
1448 :
1449 :
1450 24 : uno::Any Content::open(
1451 : const ucb::OpenCommandArgument2& rArg,
1452 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1453 : throw( uno::Exception )
1454 : {
1455 31 : if ( rArg.Mode == ucb::OpenMode::ALL ||
1456 14 : rArg.Mode == ucb::OpenMode::FOLDERS ||
1457 7 : rArg.Mode == ucb::OpenMode::DOCUMENTS )
1458 : {
1459 :
1460 : // open command for a folder content
1461 :
1462 :
1463 : uno::Reference< ucb::XDynamicResultSet > xSet
1464 17 : = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1465 17 : return uno::makeAny( xSet );
1466 : }
1467 : else
1468 : {
1469 :
1470 : // open command for a document content
1471 :
1472 :
1473 14 : if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1474 7 : ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1475 : {
1476 : // Currently(?) unsupported.
1477 : ucbhelper::cancelCommandExecution(
1478 : uno::makeAny( ucb::UnsupportedOpenModeException(
1479 : OUString(),
1480 : static_cast< cppu::OWeakObject * >( this ),
1481 : sal_Int16( rArg.Mode ) ) ),
1482 0 : xEnv );
1483 : // Unreachable
1484 : }
1485 :
1486 7 : uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1487 7 : if ( xOut.is() )
1488 : {
1489 : // PUSH: write data into xOut
1490 :
1491 1 : uno::Reference< io::XInputStream > xIn = getInputStream();
1492 1 : if ( !xIn.is() )
1493 : {
1494 : // No interaction if we are not persistent!
1495 : uno::Any aProps
1496 : = uno::makeAny(
1497 : beans::PropertyValue(
1498 : OUString(
1499 : "Uri"),
1500 : -1,
1501 0 : uno::makeAny(m_xIdentifier->
1502 0 : getContentIdentifier()),
1503 0 : beans::PropertyState_DIRECT_VALUE));
1504 : ucbhelper::cancelCommandExecution(
1505 : ucb::IOErrorCode_CANT_READ,
1506 : uno::Sequence< uno::Any >(&aProps, 1),
1507 0 : m_eState == PERSISTENT
1508 : ? xEnv
1509 : : uno::Reference< ucb::XCommandEnvironment >(),
1510 : OUString("Got no data stream!"),
1511 0 : this );
1512 : // Unreachable
1513 : }
1514 :
1515 : try
1516 : {
1517 1 : uno::Sequence< sal_Int8 > aBuffer;
1518 1 : sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1519 :
1520 3 : while ( nRead > 0 )
1521 : {
1522 1 : aBuffer.realloc( nRead );
1523 1 : xOut->writeBytes( aBuffer );
1524 1 : aBuffer.realloc( 0 );
1525 1 : nRead = xIn->readSomeBytes( aBuffer, 65536 );
1526 : }
1527 :
1528 1 : xOut->closeOutput();
1529 : }
1530 0 : catch ( io::NotConnectedException const & )
1531 : {
1532 : // closeOutput, readSomeBytes, writeBytes
1533 : }
1534 0 : catch ( io::BufferSizeExceededException const & )
1535 : {
1536 : // closeOutput, readSomeBytes, writeBytes
1537 : }
1538 0 : catch ( io::IOException const & )
1539 : {
1540 : // closeOutput, readSomeBytes, writeBytes
1541 1 : }
1542 : }
1543 : else
1544 : {
1545 : uno::Reference< io::XActiveDataSink > xDataSink(
1546 6 : rArg.Sink, uno::UNO_QUERY );
1547 6 : if ( xDataSink.is() )
1548 : {
1549 : // PULL: wait for client read
1550 :
1551 6 : uno::Reference< io::XInputStream > xIn = getInputStream();
1552 6 : if ( !xIn.is() )
1553 : {
1554 : // No interaction if we are not persistent!
1555 : uno::Any aProps
1556 : = uno::makeAny(
1557 : beans::PropertyValue(
1558 : OUString( "Uri"),
1559 : -1,
1560 0 : uno::makeAny(m_xIdentifier->
1561 0 : getContentIdentifier()),
1562 0 : beans::PropertyState_DIRECT_VALUE));
1563 : ucbhelper::cancelCommandExecution(
1564 : ucb::IOErrorCode_CANT_READ,
1565 : uno::Sequence< uno::Any >(&aProps, 1),
1566 0 : m_eState == PERSISTENT
1567 : ? xEnv
1568 : : uno::Reference<
1569 : ucb::XCommandEnvironment >(),
1570 : OUString( "Got no data stream!" ),
1571 0 : this );
1572 : // Unreachable
1573 : }
1574 :
1575 : // Done.
1576 6 : xDataSink->setInputStream( xIn );
1577 : }
1578 : else
1579 : {
1580 : // Note: aOpenCommand.Sink may contain an XStream
1581 : // implementation. Support for this type of
1582 : // sink is optional...
1583 : ucbhelper::cancelCommandExecution(
1584 : uno::makeAny(
1585 : ucb::UnsupportedDataSinkException(
1586 : OUString(),
1587 : static_cast< cppu::OWeakObject * >( this ),
1588 : rArg.Sink ) ),
1589 0 : xEnv );
1590 : // Unreachable
1591 6 : }
1592 7 : }
1593 : }
1594 :
1595 7 : return uno::Any();
1596 : }
1597 :
1598 :
1599 0 : void Content::insert(
1600 : const uno::Reference< io::XInputStream >& xStream,
1601 : sal_Int32 nNameClashResolve,
1602 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1603 : throw( uno::Exception )
1604 : {
1605 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1606 :
1607 : // Check, if all required properties were set.
1608 0 : if ( isFolder() )
1609 : {
1610 : // Required: Title
1611 :
1612 0 : if ( m_aProps.aTitle.isEmpty() )
1613 0 : m_aProps.aTitle = m_aUri.getName();
1614 : }
1615 : else
1616 : {
1617 : // Required: rArg.Data
1618 :
1619 0 : if ( !xStream.is() )
1620 : {
1621 : ucbhelper::cancelCommandExecution(
1622 : uno::makeAny( ucb::MissingInputStreamException(
1623 : OUString(),
1624 : static_cast< cppu::OWeakObject * >( this ) ) ),
1625 0 : xEnv );
1626 : // Unreachable
1627 : }
1628 :
1629 : // Required: Title
1630 :
1631 0 : if ( m_aProps.aTitle.isEmpty() )
1632 0 : m_aProps.aTitle = m_aUri.getName();
1633 : }
1634 :
1635 0 : OUString aNewURL = m_aUri.getParentUri();
1636 0 : if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
1637 0 : aNewURL += "/";
1638 0 : aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
1639 0 : PackageUri aNewUri( aNewURL );
1640 :
1641 : // Handle possible name clash...
1642 0 : switch ( nNameClashResolve )
1643 : {
1644 : // fail.
1645 : case ucb::NameClash::ERROR:
1646 0 : if ( hasData( aNewUri ) )
1647 : {
1648 : ucbhelper::cancelCommandExecution(
1649 : uno::makeAny( ucb::NameClashException(
1650 : OUString(),
1651 : static_cast< cppu::OWeakObject * >( this ),
1652 : task::InteractionClassification_ERROR,
1653 : m_aProps.aTitle ) ),
1654 0 : xEnv );
1655 : // Unreachable
1656 : }
1657 0 : break;
1658 :
1659 : // replace (possibly) existing object.
1660 : case ucb::NameClash::OVERWRITE:
1661 0 : break;
1662 :
1663 : // "invent" a new valid title.
1664 : case ucb::NameClash::RENAME:
1665 0 : if ( hasData( aNewUri ) )
1666 : {
1667 0 : sal_Int32 nTry = 0;
1668 :
1669 0 : do
1670 : {
1671 0 : OUString aNew = aNewUri.getUri();
1672 0 : aNew += "_";
1673 0 : aNew += OUString::number( ++nTry );
1674 0 : aNewUri.setUri( aNew );
1675 : }
1676 0 : while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1677 :
1678 0 : if ( nTry == 1000 )
1679 : {
1680 : ucbhelper::cancelCommandExecution(
1681 : uno::makeAny(
1682 : ucb::UnsupportedNameClashException(
1683 : OUString( "Unable to resolve name clash!" ),
1684 : static_cast< cppu::OWeakObject * >( this ),
1685 : nNameClashResolve ) ),
1686 0 : xEnv );
1687 : // Unreachable
1688 : }
1689 : else
1690 : {
1691 0 : m_aProps.aTitle += "_";
1692 0 : m_aProps.aTitle += OUString::number( nTry );
1693 : }
1694 : }
1695 0 : break;
1696 :
1697 : case ucb::NameClash::KEEP: // deprecated
1698 : case ucb::NameClash::ASK:
1699 : default:
1700 0 : if ( hasData( aNewUri ) )
1701 : {
1702 : ucbhelper::cancelCommandExecution(
1703 : uno::makeAny(
1704 : ucb::UnsupportedNameClashException(
1705 : OUString(),
1706 : static_cast< cppu::OWeakObject * >( this ),
1707 : nNameClashResolve ) ),
1708 0 : xEnv );
1709 : // Unreachable
1710 : }
1711 0 : break;
1712 : }
1713 :
1714 : // Identifier changed?
1715 0 : bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
1716 :
1717 0 : if ( bNewId )
1718 : {
1719 0 : m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1720 0 : m_aUri = aNewUri;
1721 : }
1722 :
1723 0 : if ( !storeData( xStream ) )
1724 : {
1725 : uno::Any aProps
1726 : = uno::makeAny(beans::PropertyValue(
1727 : OUString( "Uri"),
1728 : -1,
1729 0 : uno::makeAny(m_xIdentifier->
1730 0 : getContentIdentifier()),
1731 0 : beans::PropertyState_DIRECT_VALUE));
1732 : ucbhelper::cancelCommandExecution(
1733 : ucb::IOErrorCode_CANT_WRITE,
1734 : uno::Sequence< uno::Any >(&aProps, 1),
1735 : xEnv,
1736 : OUString("Cannot store persistent data!"),
1737 0 : this );
1738 : // Unreachable
1739 : }
1740 :
1741 0 : m_eState = PERSISTENT;
1742 :
1743 0 : if ( bNewId )
1744 : {
1745 : // Take over correct default values from underlying packager...
1746 0 : uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1747 : loadData( m_pProvider,
1748 : m_aUri,
1749 : m_aProps,
1750 0 : xXHierarchicalNameAccess );
1751 :
1752 0 : aGuard.clear();
1753 0 : inserted();
1754 0 : }
1755 0 : }
1756 :
1757 :
1758 0 : void Content::destroy(
1759 : bool bDeletePhysical,
1760 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1761 : throw( uno::Exception )
1762 : {
1763 : // @@@ take care about bDeletePhysical -> trashcan support
1764 :
1765 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1766 :
1767 0 : uno::Reference< ucb::XContent > xThis = this;
1768 :
1769 : // Persistent?
1770 0 : if ( m_eState != PERSISTENT )
1771 : {
1772 : ucbhelper::cancelCommandExecution(
1773 : uno::makeAny( ucb::UnsupportedCommandException(
1774 : OUString( "Not persistent!" ),
1775 : static_cast< cppu::OWeakObject * >( this ) ) ),
1776 0 : xEnv );
1777 : // Unreachable
1778 : }
1779 :
1780 0 : m_eState = DEAD;
1781 :
1782 0 : aGuard.clear();
1783 0 : deleted();
1784 :
1785 0 : if ( isFolder() )
1786 : {
1787 : // Process instantiated children...
1788 :
1789 0 : ContentRefList aChildren;
1790 0 : queryChildren( aChildren );
1791 :
1792 0 : ContentRefList::const_iterator it = aChildren.begin();
1793 0 : ContentRefList::const_iterator end = aChildren.end();
1794 :
1795 0 : while ( it != end )
1796 : {
1797 0 : (*it)->destroy( bDeletePhysical, xEnv );
1798 0 : ++it;
1799 0 : }
1800 0 : }
1801 0 : }
1802 :
1803 :
1804 0 : void Content::transfer(
1805 : const ucb::TransferInfo& rInfo,
1806 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1807 : throw( uno::Exception )
1808 : {
1809 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1810 :
1811 : // Persistent?
1812 0 : if ( m_eState != PERSISTENT )
1813 : {
1814 : ucbhelper::cancelCommandExecution(
1815 : uno::makeAny( ucb::UnsupportedCommandException(
1816 : OUString( "Not persistent!" ),
1817 : static_cast< cppu::OWeakObject * >( this ) ) ),
1818 0 : xEnv );
1819 : // Unreachable
1820 : }
1821 :
1822 : // Is source a package content?
1823 0 : if ( ( rInfo.SourceURL.isEmpty() ) ||
1824 : ( rInfo.SourceURL.compareTo(
1825 0 : m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
1826 : {
1827 : ucbhelper::cancelCommandExecution(
1828 : uno::makeAny( ucb::InteractiveBadTransferURLException(
1829 : OUString(),
1830 : static_cast< cppu::OWeakObject * >( this ) ) ),
1831 0 : xEnv );
1832 : // Unreachable
1833 : }
1834 :
1835 : // Is source not a parent of me / not me?
1836 0 : OUString aId = m_aUri.getParentUri();
1837 0 : aId += "/";
1838 :
1839 0 : if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1840 : {
1841 0 : if ( aId.startsWith( rInfo.SourceURL ) )
1842 : {
1843 : uno::Any aProps
1844 : = uno::makeAny(beans::PropertyValue(
1845 : OUString( "Uri"),
1846 : -1,
1847 : uno::makeAny(rInfo.SourceURL),
1848 0 : beans::PropertyState_DIRECT_VALUE));
1849 : ucbhelper::cancelCommandExecution(
1850 : ucb::IOErrorCode_RECURSIVE,
1851 : uno::Sequence< uno::Any >(&aProps, 1),
1852 : xEnv,
1853 : OUString( "Target is equal to or is a child of source!" ),
1854 0 : this );
1855 : // Unreachable
1856 : }
1857 : }
1858 :
1859 :
1860 : // 0) Obtain content object for source.
1861 :
1862 :
1863 : uno::Reference< ucb::XContentIdentifier > xId
1864 0 : = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1865 :
1866 : // Note: The static cast is okay here, because its sure that
1867 : // m_xProvider is always the PackageContentProvider.
1868 0 : rtl::Reference< Content > xSource;
1869 :
1870 : try
1871 : {
1872 0 : xSource = static_cast< Content * >(
1873 0 : m_xProvider->queryContent( xId ).get() );
1874 : }
1875 0 : catch ( ucb::IllegalIdentifierException const & )
1876 : {
1877 : // queryContent
1878 : }
1879 :
1880 0 : if ( !xSource.is() )
1881 : {
1882 : uno::Any aProps
1883 : = uno::makeAny(beans::PropertyValue(
1884 : OUString( "Uri"),
1885 : -1,
1886 0 : uno::makeAny(xId->getContentIdentifier()),
1887 0 : beans::PropertyState_DIRECT_VALUE));
1888 : ucbhelper::cancelCommandExecution(
1889 : ucb::IOErrorCode_CANT_READ,
1890 : uno::Sequence< uno::Any >(&aProps, 1),
1891 : xEnv,
1892 : OUString( "Cannot instanciate source object!" ),
1893 0 : this );
1894 : // Unreachable
1895 : }
1896 :
1897 :
1898 : // 1) Create new child content.
1899 :
1900 :
1901 0 : OUString aType = xSource->isFolder()
1902 0 : ? getContentType( m_aUri.getScheme(), true )
1903 0 : : getContentType( m_aUri.getScheme(), false );
1904 0 : ucb::ContentInfo aContentInfo;
1905 0 : aContentInfo.Type = aType;
1906 0 : aContentInfo.Attributes = 0;
1907 :
1908 : // Note: The static cast is okay here, because its sure that
1909 : // createNewContent always creates a Content.
1910 : rtl::Reference< Content > xTarget
1911 0 : = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1912 0 : if ( !xTarget.is() )
1913 : {
1914 : uno::Any aProps
1915 : = uno::makeAny(beans::PropertyValue(
1916 : OUString( "Folder"),
1917 : -1,
1918 : uno::makeAny(aId),
1919 0 : beans::PropertyState_DIRECT_VALUE));
1920 : ucbhelper::cancelCommandExecution(
1921 : ucb::IOErrorCode_CANT_CREATE,
1922 : uno::Sequence< uno::Any >(&aProps, 1),
1923 : xEnv,
1924 : OUString( "XContentCreator::createNewContent failed!" ),
1925 0 : this );
1926 : // Unreachable
1927 : }
1928 :
1929 :
1930 : // 2) Copy data from source content to child content.
1931 :
1932 :
1933 : uno::Sequence< beans::Property > aSourceProps
1934 0 : = xSource->getPropertySetInfo( xEnv )->getProperties();
1935 0 : sal_Int32 nCount = aSourceProps.getLength();
1936 :
1937 0 : if ( nCount )
1938 : {
1939 0 : bool bHadTitle = rInfo.NewTitle.isEmpty();
1940 :
1941 : // Get all source values.
1942 : uno::Reference< sdbc::XRow > xRow
1943 0 : = xSource->getPropertyValues( aSourceProps );
1944 :
1945 0 : uno::Sequence< beans::PropertyValue > aValues( nCount );
1946 0 : beans::PropertyValue* pValues = aValues.getArray();
1947 :
1948 0 : const beans::Property* pProps = aSourceProps.getConstArray();
1949 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1950 : {
1951 0 : const beans::Property& rProp = pProps[ n ];
1952 0 : beans::PropertyValue& rValue = pValues[ n ];
1953 :
1954 0 : rValue.Name = rProp.Name;
1955 0 : rValue.Handle = rProp.Handle;
1956 :
1957 0 : if ( !bHadTitle && rProp.Name == "Title" )
1958 : {
1959 : // Set new title instead of original.
1960 0 : bHadTitle = true;
1961 0 : rValue.Value <<= rInfo.NewTitle;
1962 : }
1963 : else
1964 : rValue.Value
1965 0 : = xRow->getObject( n + 1,
1966 : uno::Reference<
1967 0 : container::XNameAccess >() );
1968 :
1969 0 : rValue.State = beans::PropertyState_DIRECT_VALUE;
1970 :
1971 0 : if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1972 : {
1973 : // Add Additional Core Property.
1974 : try
1975 : {
1976 0 : xTarget->addProperty( rProp.Name,
1977 : rProp.Attributes,
1978 0 : rValue.Value );
1979 : }
1980 0 : catch ( beans::PropertyExistException const & )
1981 : {
1982 : }
1983 0 : catch ( beans::IllegalTypeException const & )
1984 : {
1985 : }
1986 0 : catch ( lang::IllegalArgumentException const & )
1987 : {
1988 : }
1989 : }
1990 : }
1991 :
1992 : // Set target values.
1993 0 : xTarget->setPropertyValues( aValues, xEnv );
1994 : }
1995 :
1996 :
1997 : // 3) Commit (insert) child.
1998 :
1999 :
2000 0 : xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
2001 :
2002 :
2003 : // 4) Transfer (copy) children of source.
2004 :
2005 :
2006 0 : if ( xSource->isFolder() )
2007 : {
2008 : uno::Reference< container::XEnumeration > xIter
2009 0 : = xSource->getIterator();
2010 0 : if ( xIter.is() )
2011 : {
2012 0 : while ( xIter->hasMoreElements() )
2013 : {
2014 : try
2015 : {
2016 0 : uno::Reference< container::XNamed > xNamed;
2017 0 : xIter->nextElement() >>= xNamed;
2018 :
2019 0 : if ( !xNamed.is() )
2020 : {
2021 : OSL_FAIL( "Content::transfer - Got no XNamed!" );
2022 0 : break;
2023 : }
2024 :
2025 0 : OUString aName = xNamed->getName();
2026 :
2027 0 : if ( aName.isEmpty() )
2028 : {
2029 : OSL_FAIL( "Content::transfer - Empty name!" );
2030 0 : break;
2031 : }
2032 :
2033 0 : OUString aChildId = xId->getContentIdentifier();
2034 0 : if ( ( aChildId.lastIndexOf( '/' ) + 1 )
2035 0 : != aChildId.getLength() )
2036 0 : aChildId += "/";
2037 :
2038 0 : aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
2039 :
2040 0 : ucb::TransferInfo aInfo;
2041 0 : aInfo.MoveData = sal_False;
2042 0 : aInfo.NewTitle.clear();
2043 0 : aInfo.SourceURL = aChildId;
2044 0 : aInfo.NameClash = rInfo.NameClash;
2045 :
2046 : // Transfer child to target.
2047 0 : xTarget->transfer( aInfo, xEnv );
2048 : }
2049 0 : catch ( container::NoSuchElementException const & )
2050 : {
2051 : }
2052 0 : catch ( lang::WrappedTargetException const & )
2053 : {
2054 : }
2055 : }
2056 0 : }
2057 : }
2058 :
2059 :
2060 : // 5) Destroy source ( when moving only ) .
2061 :
2062 :
2063 0 : if ( rInfo.MoveData )
2064 : {
2065 0 : xSource->destroy( true, xEnv );
2066 :
2067 : // Remove all persistent data of source and its children.
2068 0 : if ( !xSource->removeData() )
2069 : {
2070 : uno::Any aProps
2071 : = uno::makeAny(
2072 : beans::PropertyValue(
2073 : OUString( "Uri"),
2074 : -1,
2075 : uno::makeAny(
2076 0 : xSource->m_xIdentifier->
2077 0 : getContentIdentifier()),
2078 0 : beans::PropertyState_DIRECT_VALUE));
2079 : ucbhelper::cancelCommandExecution(
2080 : ucb::IOErrorCode_CANT_WRITE,
2081 : uno::Sequence< uno::Any >(&aProps, 1),
2082 : xEnv,
2083 : OUString( "Cannot remove persistent data of source object!" ),
2084 0 : this );
2085 : // Unreachable
2086 : }
2087 :
2088 : // Remove own and all children's Additional Core Properties.
2089 0 : xSource->removeAdditionalPropertySet( true );
2090 0 : }
2091 0 : }
2092 :
2093 :
2094 0 : bool Content::exchangeIdentity(
2095 : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2096 : {
2097 0 : if ( !xNewId.is() )
2098 0 : return false;
2099 :
2100 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2101 :
2102 0 : uno::Reference< ucb::XContent > xThis = this;
2103 :
2104 : // Already persistent?
2105 0 : if ( m_eState != PERSISTENT )
2106 : {
2107 : OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2108 0 : return false;
2109 : }
2110 :
2111 : // Exchange own identitity.
2112 :
2113 : // Fail, if a content with given id already exists.
2114 0 : PackageUri aNewUri( xNewId->getContentIdentifier() );
2115 0 : if ( !hasData( aNewUri ) )
2116 : {
2117 0 : OUString aOldURL = m_xIdentifier->getContentIdentifier();
2118 :
2119 0 : aGuard.clear();
2120 0 : if ( exchange( xNewId ) )
2121 : {
2122 0 : m_aUri = aNewUri;
2123 0 : if ( isFolder() )
2124 : {
2125 : // Process instantiated children...
2126 :
2127 0 : ContentRefList aChildren;
2128 0 : queryChildren( aChildren );
2129 :
2130 0 : ContentRefList::const_iterator it = aChildren.begin();
2131 0 : ContentRefList::const_iterator end = aChildren.end();
2132 :
2133 0 : while ( it != end )
2134 : {
2135 0 : ContentRef xChild = (*it);
2136 :
2137 : // Create new content identifier for the child...
2138 : uno::Reference< ucb::XContentIdentifier > xOldChildId
2139 0 : = xChild->getIdentifier();
2140 : OUString aOldChildURL
2141 0 : = xOldChildId->getContentIdentifier();
2142 : OUString aNewChildURL
2143 : = aOldChildURL.replaceAt(
2144 : 0,
2145 : aOldURL.getLength(),
2146 0 : xNewId->getContentIdentifier() );
2147 : uno::Reference< ucb::XContentIdentifier > xNewChildId
2148 0 : = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2149 :
2150 0 : if ( !xChild->exchangeIdentity( xNewChildId ) )
2151 0 : return false;
2152 :
2153 0 : ++it;
2154 0 : }
2155 : }
2156 0 : return true;
2157 0 : }
2158 : }
2159 :
2160 : OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2161 0 : return false;
2162 : }
2163 :
2164 :
2165 0 : void Content::queryChildren( ContentRefList& rChildren )
2166 : {
2167 : // Obtain a list with a snapshot of all currently instantiated contents
2168 : // from provider and extract the contents which are direct children
2169 : // of this content.
2170 :
2171 0 : ::ucbhelper::ContentRefList aAllContents;
2172 0 : m_xProvider->queryExistingContents( aAllContents );
2173 :
2174 0 : OUString aURL = m_xIdentifier->getContentIdentifier();
2175 :
2176 : OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2177 : "Content::queryChildren - Invalid URL!" );
2178 :
2179 0 : aURL += "/";
2180 :
2181 0 : sal_Int32 nLen = aURL.getLength();
2182 :
2183 0 : ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2184 0 : ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2185 :
2186 0 : while ( it != end )
2187 : {
2188 0 : ::ucbhelper::ContentImplHelperRef xChild = (*it);
2189 : OUString aChildURL
2190 0 : = xChild->getIdentifier()->getContentIdentifier();
2191 :
2192 : // Is aURL a prefix of aChildURL?
2193 0 : if ( ( aChildURL.getLength() > nLen ) &&
2194 0 : ( aChildURL.startsWith( aURL ) ) )
2195 : {
2196 0 : if ( aChildURL.indexOf( '/', nLen ) == -1 )
2197 : {
2198 : // No further slashes. It's a child!
2199 : rChildren.push_back(
2200 : ContentRef(
2201 0 : static_cast< Content * >( xChild.get() ) ) );
2202 : }
2203 : }
2204 0 : ++it;
2205 0 : }
2206 0 : }
2207 :
2208 :
2209 24 : uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2210 : const PackageUri& rURI )
2211 : {
2212 24 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2213 :
2214 48 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
2215 24 : if ( rURI.getPackage() == m_aUri.getPackage() )
2216 : {
2217 24 : if ( !m_xPackage.is() )
2218 0 : m_xPackage = m_pProvider->createPackage( m_aUri );
2219 :
2220 24 : return m_xPackage;
2221 : }
2222 :
2223 24 : return m_pProvider->createPackage( rURI );
2224 : }
2225 :
2226 :
2227 24 : uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2228 : {
2229 24 : return getPackage( m_aUri );
2230 : }
2231 :
2232 :
2233 : // static
2234 0 : bool Content::hasData(
2235 : ContentProvider* pProvider,
2236 : const PackageUri& rURI,
2237 : uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2238 : {
2239 0 : rxPackage = pProvider->createPackage( rURI );
2240 0 : return rxPackage->hasByHierarchicalName( rURI.getPath() );
2241 : }
2242 :
2243 :
2244 0 : bool Content::hasData( const PackageUri& rURI )
2245 : {
2246 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2247 :
2248 0 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
2249 0 : if ( rURI.getPackage() == m_aUri.getPackage() )
2250 : {
2251 0 : xPackage = getPackage();
2252 0 : return xPackage->hasByHierarchicalName( rURI.getPath() );
2253 : }
2254 :
2255 0 : return hasData( m_pProvider, rURI, xPackage );
2256 : }
2257 :
2258 :
2259 : //static
2260 33 : bool Content::loadData(
2261 : ContentProvider* pProvider,
2262 : const PackageUri& rURI,
2263 : ContentProperties& rProps,
2264 : uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2265 : {
2266 33 : rxPackage = pProvider->createPackage( rURI );
2267 :
2268 33 : if ( rURI.isRootFolder() )
2269 : {
2270 : // Properties available only from package
2271 : uno::Reference< beans::XPropertySet > xPackagePropSet(
2272 16 : rxPackage, uno::UNO_QUERY );
2273 :
2274 : OSL_ENSURE( xPackagePropSet.is(),
2275 : "Content::loadData - "
2276 : "Got no XPropertySet interface from package!" );
2277 :
2278 16 : if ( xPackagePropSet.is() )
2279 : {
2280 : // HasEncryptedEntries ( only avalibale at root folder )
2281 : try
2282 : {
2283 : uno::Any aHasEncryptedEntries
2284 16 : = xPackagePropSet->getPropertyValue(
2285 16 : OUString( "HasEncryptedEntries" ) );
2286 16 : if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2287 : {
2288 : OSL_FAIL( "Content::loadData - "
2289 : "Got no HasEncryptedEntries value!" );
2290 0 : return false;
2291 16 : }
2292 : }
2293 0 : catch ( beans::UnknownPropertyException const & )
2294 : {
2295 : OSL_FAIL( "Content::loadData - "
2296 : "Got no HasEncryptedEntries value!" );
2297 0 : return false;
2298 : }
2299 0 : catch ( lang::WrappedTargetException const & )
2300 : {
2301 : OSL_FAIL( "Content::loadData - "
2302 : "Got no HasEncryptedEntries value!" );
2303 0 : return false;
2304 : }
2305 16 : }
2306 : }
2307 :
2308 33 : if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2309 0 : return false;
2310 :
2311 : try
2312 : {
2313 33 : uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2314 33 : if ( aEntry.hasValue() )
2315 : {
2316 33 : uno::Reference< beans::XPropertySet > xPropSet;
2317 33 : aEntry >>= xPropSet;
2318 :
2319 33 : if ( !xPropSet.is() )
2320 : {
2321 : OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2322 0 : return false;
2323 : }
2324 :
2325 : // Title
2326 33 : rProps.aTitle = rURI.getName();
2327 :
2328 : // MediaType
2329 : try
2330 : {
2331 : uno::Any aMediaType
2332 33 : = xPropSet->getPropertyValue(
2333 33 : OUString("MediaType") );
2334 33 : if ( !( aMediaType >>= rProps.aMediaType ) )
2335 : {
2336 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2337 0 : return false;
2338 33 : }
2339 : }
2340 0 : catch ( beans::UnknownPropertyException const & )
2341 : {
2342 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2343 0 : return false;
2344 : }
2345 0 : catch ( lang::WrappedTargetException const & )
2346 : {
2347 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2348 0 : return false;
2349 : }
2350 :
2351 66 : uno::Reference< container::XEnumerationAccess > xEnumAccess;
2352 33 : aEntry >>= xEnumAccess;
2353 :
2354 : // ContentType / IsFolder / IsDocument
2355 33 : if ( xEnumAccess.is() )
2356 : {
2357 : // folder
2358 20 : rProps.aContentType = getContentType( rURI.getScheme(), true );
2359 20 : rProps.bIsDocument = false;
2360 20 : rProps.bIsFolder = true;
2361 : }
2362 : else
2363 : {
2364 : // stream
2365 13 : rProps.aContentType = getContentType( rURI.getScheme(), false );
2366 13 : rProps.bIsDocument = true;
2367 13 : rProps.bIsFolder = false;
2368 : }
2369 :
2370 33 : if ( rProps.bIsDocument )
2371 : {
2372 : // Size ( only available for streams )
2373 : try
2374 : {
2375 : uno::Any aSize
2376 13 : = xPropSet->getPropertyValue(
2377 13 : OUString("Size") );
2378 13 : if ( !( aSize >>= rProps.nSize ) )
2379 : {
2380 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2381 0 : return false;
2382 13 : }
2383 : }
2384 0 : catch ( beans::UnknownPropertyException const & )
2385 : {
2386 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2387 0 : return false;
2388 : }
2389 0 : catch ( lang::WrappedTargetException const & )
2390 : {
2391 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2392 0 : return false;
2393 : }
2394 :
2395 : // Compressed ( only available for streams )
2396 : try
2397 : {
2398 : uno::Any aCompressed
2399 13 : = xPropSet->getPropertyValue(
2400 13 : OUString("Compressed") );
2401 13 : if ( !( aCompressed >>= rProps.bCompressed ) )
2402 : {
2403 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2404 0 : return false;
2405 13 : }
2406 : }
2407 0 : catch ( beans::UnknownPropertyException const & )
2408 : {
2409 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2410 0 : return false;
2411 : }
2412 0 : catch ( lang::WrappedTargetException const & )
2413 : {
2414 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2415 0 : return false;
2416 : }
2417 :
2418 : // Encrypted ( only available for streams )
2419 : try
2420 : {
2421 : uno::Any aEncrypted
2422 13 : = xPropSet->getPropertyValue(
2423 13 : OUString("Encrypted") );
2424 13 : if ( !( aEncrypted >>= rProps.bEncrypted ) )
2425 : {
2426 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2427 0 : return false;
2428 13 : }
2429 : }
2430 0 : catch ( beans::UnknownPropertyException const & )
2431 : {
2432 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2433 0 : return false;
2434 : }
2435 0 : catch ( lang::WrappedTargetException const & )
2436 : {
2437 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2438 0 : return false;
2439 : }
2440 : }
2441 66 : return true;
2442 0 : }
2443 : }
2444 0 : catch ( container::NoSuchElementException const & )
2445 : {
2446 : // getByHierarchicalName
2447 : }
2448 :
2449 0 : return false;
2450 : }
2451 :
2452 :
2453 0 : bool Content::renameData(
2454 : const uno::Reference< ucb::XContentIdentifier >& xOldId,
2455 : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2456 : {
2457 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2458 :
2459 0 : PackageUri aURI( xOldId->getContentIdentifier() );
2460 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2461 0 : aURI );
2462 :
2463 0 : if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2464 0 : return false;
2465 :
2466 : try
2467 : {
2468 0 : uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2469 0 : uno::Reference< container::XNamed > xNamed;
2470 0 : aEntry >>= xNamed;
2471 :
2472 0 : if ( !xNamed.is() )
2473 : {
2474 : OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2475 0 : return false;
2476 : }
2477 :
2478 0 : PackageUri aNewURI( xNewId->getContentIdentifier() );
2479 :
2480 : // No success indicator!? No return value / exceptions specified.
2481 0 : xNamed->setName( aNewURI.getName() );
2482 :
2483 0 : return true;
2484 : }
2485 0 : catch ( container::NoSuchElementException const & )
2486 : {
2487 : // getByHierarchicalName
2488 : }
2489 :
2490 0 : return false;
2491 : }
2492 :
2493 :
2494 0 : bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2495 : {
2496 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2497 :
2498 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2499 :
2500 : uno::Reference< beans::XPropertySet > xPackagePropSet(
2501 0 : xNA, uno::UNO_QUERY );
2502 : OSL_ENSURE( xPackagePropSet.is(),
2503 : "Content::storeData - "
2504 : "Got no XPropertySet interface from package!" );
2505 :
2506 0 : if ( !xPackagePropSet.is() )
2507 0 : return false;
2508 :
2509 0 : if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2510 : {
2511 0 : if ( m_aUri.isRootFolder() )
2512 : {
2513 : // Property available only from package and from streams (see below)
2514 : try
2515 : {
2516 0 : xPackagePropSet->setPropertyValue(
2517 : OUString("EncryptionKey"),
2518 0 : uno::makeAny( m_aProps.aEncryptionKey ) );
2519 0 : m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2520 : }
2521 0 : catch ( beans::UnknownPropertyException const & )
2522 : {
2523 : // setPropertyValue
2524 : }
2525 0 : catch ( beans::PropertyVetoException const & )
2526 : {
2527 : // setPropertyValue
2528 : }
2529 0 : catch ( lang::IllegalArgumentException const & )
2530 : {
2531 : // setPropertyValue
2532 : }
2533 0 : catch ( lang::WrappedTargetException const & )
2534 : {
2535 : // setPropertyValue
2536 : }
2537 : }
2538 : }
2539 :
2540 0 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2541 : {
2542 : // if ( !bCreate )
2543 : // return sal_True;
2544 :
2545 : try
2546 : {
2547 : // Create new resource...
2548 : uno::Reference< lang::XSingleServiceFactory > xFac(
2549 0 : xNA, uno::UNO_QUERY );
2550 0 : if ( !xFac.is() )
2551 : {
2552 : OSL_FAIL( "Content::storeData - "
2553 : "Got no XSingleServiceFactory interface!" );
2554 0 : return false;
2555 : }
2556 :
2557 0 : uno::Sequence< uno::Any > aArgs( 1 );
2558 0 : aArgs[ 0 ] <<= isFolder();
2559 :
2560 : uno::Reference< uno::XInterface > xNew
2561 0 : = xFac->createInstanceWithArguments( aArgs );
2562 :
2563 0 : if ( !xNew.is() )
2564 : {
2565 : OSL_FAIL( "Content::storeData - createInstance failed!" );
2566 0 : return false;
2567 : }
2568 :
2569 0 : PackageUri aParentUri( getParentURL() );
2570 : uno::Any aEntry
2571 0 : = xNA->getByHierarchicalName( aParentUri.getPath() );
2572 0 : uno::Reference< container::XNameContainer > xParentContainer;
2573 0 : aEntry >>= xParentContainer;
2574 :
2575 0 : if ( !xParentContainer.is() )
2576 : {
2577 : OSL_FAIL( "Content::storeData - "
2578 : "Got no XNameContainer interface!" );
2579 0 : return false;
2580 : }
2581 :
2582 0 : xParentContainer->insertByName( m_aProps.aTitle,
2583 0 : uno::makeAny( xNew ) );
2584 : }
2585 0 : catch ( lang::IllegalArgumentException const & )
2586 : {
2587 : // insertByName
2588 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2589 0 : return false;
2590 : }
2591 0 : catch ( uno::RuntimeException const & )
2592 : {
2593 0 : throw;
2594 : }
2595 0 : catch ( container::ElementExistException const & )
2596 : {
2597 : // insertByName
2598 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2599 0 : return false;
2600 : }
2601 0 : catch ( lang::WrappedTargetException const & )
2602 : {
2603 : // insertByName
2604 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2605 0 : return false;
2606 : }
2607 0 : catch ( container::NoSuchElementException const & )
2608 : {
2609 : // getByHierarchicalName
2610 : OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2611 0 : return false;
2612 : }
2613 0 : catch ( uno::Exception const & )
2614 : {
2615 : // createInstanceWithArguments
2616 : OSL_FAIL( "Content::storeData - Error!" );
2617 0 : return false;
2618 : }
2619 : }
2620 :
2621 0 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2622 0 : return false;
2623 :
2624 : try
2625 : {
2626 0 : uno::Reference< beans::XPropertySet > xPropSet;
2627 0 : xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2628 :
2629 0 : if ( !xPropSet.is() )
2630 : {
2631 : OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2632 0 : return false;
2633 : }
2634 :
2635 :
2636 : // Store property values...
2637 :
2638 :
2639 0 : if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2640 : {
2641 0 : xPropSet->setPropertyValue(
2642 : OUString("MediaType"),
2643 0 : uno::makeAny( m_aProps.aMediaType ) );
2644 0 : m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2645 : }
2646 :
2647 0 : if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2648 : {
2649 0 : if ( !isFolder() )
2650 0 : xPropSet->setPropertyValue(
2651 : OUString("Compressed"),
2652 0 : uno::makeAny( m_aProps.bCompressed ) );
2653 :
2654 0 : m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2655 : }
2656 :
2657 0 : if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2658 : {
2659 0 : if ( !isFolder() )
2660 0 : xPropSet->setPropertyValue(
2661 : OUString("Encrypted"),
2662 0 : uno::makeAny( m_aProps.bEncrypted ) );
2663 :
2664 0 : m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2665 : }
2666 :
2667 0 : if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2668 : {
2669 0 : if ( !isFolder() )
2670 0 : xPropSet->setPropertyValue(
2671 : OUString("EncryptionKey"),
2672 0 : uno::makeAny( m_aProps.aEncryptionKey ) );
2673 :
2674 0 : m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2675 : }
2676 :
2677 :
2678 : // Store data stream...
2679 :
2680 :
2681 0 : if ( xStream.is() && !isFolder() )
2682 : {
2683 : uno::Reference< io::XActiveDataSink > xSink(
2684 0 : xPropSet, uno::UNO_QUERY );
2685 :
2686 0 : if ( !xSink.is() )
2687 : {
2688 : OSL_FAIL( "Content::storeData - "
2689 : "Got no XActiveDataSink interface!" );
2690 0 : return false;
2691 : }
2692 :
2693 0 : xSink->setInputStream( xStream );
2694 : }
2695 :
2696 0 : return true;
2697 : }
2698 0 : catch ( container::NoSuchElementException const & )
2699 : {
2700 : // getByHierarchicalName
2701 : }
2702 0 : catch ( beans::UnknownPropertyException const & )
2703 : {
2704 : // setPropertyValue
2705 : }
2706 0 : catch ( beans::PropertyVetoException const & )
2707 : {
2708 : // setPropertyValue
2709 : }
2710 0 : catch ( lang::IllegalArgumentException const & )
2711 : {
2712 : // setPropertyValue
2713 : }
2714 0 : catch ( lang::WrappedTargetException const & )
2715 : {
2716 : // setPropertyValue
2717 : }
2718 :
2719 : OSL_FAIL( "Content::storeData - Error!" );
2720 0 : return false;
2721 : }
2722 :
2723 :
2724 0 : bool Content::removeData()
2725 : {
2726 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2727 :
2728 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2729 :
2730 0 : PackageUri aParentUri( getParentURL() );
2731 0 : if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2732 0 : return false;
2733 :
2734 : try
2735 : {
2736 0 : uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2737 0 : uno::Reference< container::XNameContainer > xContainer;
2738 0 : aEntry >>= xContainer;
2739 :
2740 0 : if ( !xContainer.is() )
2741 : {
2742 : OSL_FAIL( "Content::removeData - "
2743 : "Got no XNameContainer interface!" );
2744 0 : return false;
2745 : }
2746 :
2747 0 : xContainer->removeByName( m_aUri.getName() );
2748 0 : return true;
2749 : }
2750 0 : catch ( container::NoSuchElementException const & )
2751 : {
2752 : // getByHierarchicalName, removeByName
2753 : }
2754 0 : catch ( lang::WrappedTargetException const & )
2755 : {
2756 : // removeByName
2757 : }
2758 :
2759 : OSL_FAIL( "Content::removeData - Error!" );
2760 0 : return false;
2761 : }
2762 :
2763 :
2764 0 : bool Content::flushData()
2765 : {
2766 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2767 :
2768 : // Note: XChangesBatch is only implemented by the package itself, not
2769 : // by the single entries. Maybe this has to change...
2770 :
2771 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2772 :
2773 0 : uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2774 0 : if ( !xBatch.is() )
2775 : {
2776 : OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2777 0 : return false;
2778 : }
2779 :
2780 : try
2781 : {
2782 0 : xBatch->commitChanges();
2783 0 : return true;
2784 : }
2785 0 : catch ( lang::WrappedTargetException const & )
2786 : {
2787 : }
2788 :
2789 : OSL_FAIL( "Content::flushData - Error!" );
2790 0 : return false;
2791 : }
2792 :
2793 :
2794 7 : uno::Reference< io::XInputStream > Content::getInputStream()
2795 : {
2796 7 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2797 :
2798 7 : uno::Reference< io::XInputStream > xStream;
2799 14 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2800 :
2801 7 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2802 0 : return xStream;
2803 :
2804 : try
2805 : {
2806 7 : uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2807 14 : uno::Reference< io::XActiveDataSink > xSink;
2808 7 : aEntry >>= xSink;
2809 :
2810 7 : if ( !xSink.is() )
2811 : {
2812 : OSL_FAIL( "Content::getInputStream - "
2813 : "Got no XActiveDataSink interface!" );
2814 0 : return xStream;
2815 : }
2816 :
2817 7 : xStream = xSink->getInputStream();
2818 :
2819 : OSL_ENSURE( xStream.is(),
2820 7 : "Content::getInputStream - Got no stream!" );
2821 : }
2822 0 : catch ( container::NoSuchElementException const & )
2823 : {
2824 : // getByHierarchicalName
2825 : }
2826 :
2827 14 : return xStream;
2828 : }
2829 :
2830 :
2831 17 : uno::Reference< container::XEnumeration > Content::getIterator()
2832 : {
2833 17 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2834 :
2835 17 : uno::Reference< container::XEnumeration > xIter;
2836 34 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2837 :
2838 17 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2839 0 : return xIter;
2840 :
2841 : try
2842 : {
2843 17 : uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2844 34 : uno::Reference< container::XEnumerationAccess > xIterFac;
2845 17 : aEntry >>= xIterFac;
2846 :
2847 17 : if ( !xIterFac.is() )
2848 : {
2849 : OSL_FAIL( "Content::getIterator - "
2850 : "Got no XEnumerationAccess interface!" );
2851 0 : return xIter;
2852 : }
2853 :
2854 17 : xIter = xIterFac->createEnumeration();
2855 :
2856 : OSL_ENSURE( xIter.is(),
2857 17 : "Content::getIterator - Got no iterator!" );
2858 : }
2859 0 : catch ( container::NoSuchElementException const & )
2860 : {
2861 : // getByHierarchicalName
2862 : }
2863 :
2864 34 : return xIter;
2865 : }
2866 :
2867 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|