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 20 : ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
105 : {
106 20 : if ( bIsFolder )
107 : {
108 8 : uno::Sequence< beans::Property > aProps( 1 );
109 16 : aProps.getArray()[ 0 ] = beans::Property(
110 : OUString("Title"),
111 : -1,
112 8 : cppu::UnoType<OUString>::get(),
113 8 : beans::PropertyAttribute::BOUND );
114 :
115 16 : uno::Sequence< ucb::ContentInfo > aSeq( 2 );
116 :
117 : // Folder.
118 8 : aSeq.getArray()[ 0 ].Type
119 16 : = Content::getContentType( rUri.getScheme(), true );
120 8 : aSeq.getArray()[ 0 ].Attributes
121 8 : = ucb::ContentInfoAttribute::KIND_FOLDER;
122 8 : aSeq.getArray()[ 0 ].Properties = aProps;
123 :
124 : // Stream.
125 8 : aSeq.getArray()[ 1 ].Type
126 16 : = Content::getContentType( rUri.getScheme(), false );
127 8 : aSeq.getArray()[ 1 ].Attributes
128 : = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
129 8 : | ucb::ContentInfoAttribute::KIND_DOCUMENT;
130 8 : aSeq.getArray()[ 1 ].Properties = aProps;
131 :
132 16 : return aSeq;
133 : }
134 : else
135 : {
136 12 : return uno::Sequence< ucb::ContentInfo >( 0 );
137 : }
138 : }
139 :
140 :
141 :
142 :
143 : // Content Implementation.
144 :
145 :
146 :
147 :
148 : // static ( "virtual" ctor )
149 50 : Content* Content::create(
150 : const uno::Reference< uno::XComponentContext >& rxContext,
151 : ContentProvider* pProvider,
152 : const uno::Reference< ucb::XContentIdentifier >& Identifier )
153 : {
154 50 : OUString aURL = Identifier->getContentIdentifier();
155 100 : PackageUri aURI( aURL );
156 100 : ContentProperties aProps;
157 100 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
158 :
159 50 : if ( loadData( pProvider, aURI, aProps, xPackage ) )
160 : {
161 : // resource exists
162 :
163 50 : sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
164 50 : if ( ( nLastSlash + 1 ) == aURL.getLength() )
165 : {
166 : // Client explicitly requested a folder!
167 6 : if ( !aProps.bIsFolder )
168 0 : return 0;
169 : }
170 :
171 : uno::Reference< ucb::XContentIdentifier > xId
172 50 : = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
173 50 : 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 50 : }
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 82 : OUString Content::getContentType(
230 : const OUString& aScheme, bool bFolder )
231 : {
232 : return ( OUString("application/")
233 164 : + aScheme
234 164 : + ( bFolder
235 : ? OUString("-folder")
236 246 : : OUString("-stream") ) );
237 : }
238 :
239 :
240 50 : 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 50 : m_nModifiedProps( NONE_MODIFIED )
254 : {
255 50 : }
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 100 : Content::~Content()
278 : {
279 100 : }
280 :
281 :
282 :
283 : // XInterface methods.
284 :
285 :
286 :
287 : // virtual
288 876 : void SAL_CALL Content::acquire()
289 : throw( )
290 : {
291 876 : ContentImplHelper::acquire();
292 876 : }
293 :
294 :
295 : // virtual
296 876 : void SAL_CALL Content::release()
297 : throw( )
298 : {
299 876 : ContentImplHelper::release();
300 876 : }
301 :
302 :
303 : // virtual
304 176 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
305 : throw ( uno::RuntimeException, std::exception )
306 : {
307 176 : uno::Any aRet;
308 :
309 176 : if ( isFolder() )
310 280 : aRet = cppu::queryInterface(
311 140 : rType, static_cast< ucb::XContentCreator * >( this ) );
312 :
313 176 : 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 122 : 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 122 : uno::Any aRet;
456 :
457 122 : if ( aCommand.Name == "getPropertyValues" )
458 : {
459 :
460 : // getPropertyValues
461 :
462 :
463 54 : uno::Sequence< beans::Property > Properties;
464 54 : 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 54 : aRet <<= getPropertyValues( Properties );
476 : }
477 68 : 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 68 : else if ( aCommand.Name == "getPropertySetInfo" )
509 : {
510 :
511 : // getPropertySetInfo
512 :
513 :
514 : // Note: Implemented by base class.
515 20 : aRet <<= getPropertySetInfo( Environment );
516 : }
517 48 : else if ( aCommand.Name == "getCommandInfo" )
518 : {
519 :
520 : // getCommandInfo
521 :
522 :
523 : // Note: Implemented by base class.
524 0 : aRet <<= getCommandInfo( Environment );
525 : }
526 48 : else if ( aCommand.Name == "open" )
527 : {
528 :
529 : // open
530 :
531 :
532 48 : ucb::OpenCommandArgument2 aOpenCommand;
533 48 : 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 48 : 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 122 : 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 16 : 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 16 : ContentProperties aData;
772 32 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
773 16 : 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 16 : 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 16 : }
798 : }
799 :
800 :
801 : // static
802 70 : 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 70 : = new ::ucbhelper::PropertyValueSet( rxContext );
814 :
815 70 : sal_Int32 nCount = rProperties.getLength();
816 70 : if ( nCount )
817 : {
818 70 : uno::Reference< beans::XPropertySet > xAdditionalPropSet;
819 70 : bool bTriedToGetAdditionalPropSet = false;
820 :
821 70 : const beans::Property* pProps = rProperties.getConstArray();
822 324 : for ( sal_Int32 n = 0; n < nCount; ++n )
823 : {
824 254 : const beans::Property& rProp = pProps[ n ];
825 :
826 : // Process Core properties.
827 :
828 254 : if ( rProp.Name == "ContentType" )
829 : {
830 20 : xRow->appendString ( rProp, rData.aContentType );
831 : }
832 234 : else if ( rProp.Name == "Title" )
833 : {
834 20 : xRow->appendString ( rProp, rData.aTitle );
835 : }
836 214 : else if ( rProp.Name == "IsDocument" )
837 : {
838 42 : xRow->appendBoolean( rProp, rData.bIsDocument );
839 : }
840 172 : else if ( rProp.Name == "IsFolder" )
841 : {
842 42 : xRow->appendBoolean( rProp, rData.bIsFolder );
843 : }
844 130 : else if ( rProp.Name == "CreatableContentsInfo" )
845 : {
846 : xRow->appendObject(
847 : rProp, uno::makeAny(
848 : rData.getCreatableContentsInfo(
849 20 : PackageUri( rContentId ) ) ) );
850 : }
851 110 : else if ( rProp.Name == "MediaType" )
852 : {
853 46 : xRow->appendString ( rProp, rData.aMediaType );
854 : }
855 64 : else if ( rProp.Name == "Size" )
856 : {
857 : // Property only available for streams.
858 12 : if ( rData.bIsDocument )
859 12 : xRow->appendLong( rProp, rData.nSize );
860 : else
861 0 : xRow->appendVoid( rProp );
862 : }
863 52 : else if ( rProp.Name == "Compressed" )
864 : {
865 : // Property only available for streams.
866 12 : if ( rData.bIsDocument )
867 12 : xRow->appendBoolean( rProp, rData.bCompressed );
868 : else
869 0 : xRow->appendVoid( rProp );
870 : }
871 40 : else if ( rProp.Name == "Encrypted" )
872 : {
873 : // Property only available for streams.
874 12 : if ( rData.bIsDocument )
875 12 : xRow->appendBoolean( rProp, rData.bEncrypted );
876 : else
877 0 : xRow->appendVoid( rProp );
878 : }
879 28 : else if ( rProp.Name == "HasEncryptedEntries" )
880 : {
881 : // Property only available for root folder.
882 4 : PackageUri aURI( rContentId );
883 4 : if ( aURI.isRootFolder() )
884 4 : 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 24 : if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
893 : {
894 : xAdditionalPropSet
895 40 : = uno::Reference< beans::XPropertySet >(
896 : rProvider->getAdditionalPropertySet( rContentId,
897 : false ),
898 20 : uno::UNO_QUERY );
899 20 : bTriedToGetAdditionalPropSet = true;
900 : }
901 :
902 24 : 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 24 : xRow->appendVoid( rProp );
916 : }
917 : }
918 70 : }
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 : 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 : cppu::UnoType<OUString>::get(),
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 : cppu::UnoType<sal_Int64>::get(),
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 70 : return uno::Reference< sdbc::XRow >( xRow.get() );
1024 : }
1025 :
1026 :
1027 54 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
1028 : const uno::Sequence< beans::Property >& rProperties )
1029 : {
1030 54 : 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 54 : 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 : bool bTriedToGetAdditionalPropSet = false;
1065 0 : bool bExchange = false;
1066 0 : bool bStore = 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 = 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 = 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 : 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 = 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 : 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 = 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 = 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 = 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 48 : uno::Any Content::open(
1452 : const ucb::OpenCommandArgument2& rArg,
1453 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1454 : throw( uno::Exception )
1455 : {
1456 62 : if ( rArg.Mode == ucb::OpenMode::ALL ||
1457 28 : rArg.Mode == ucb::OpenMode::FOLDERS ||
1458 14 : rArg.Mode == ucb::OpenMode::DOCUMENTS )
1459 : {
1460 :
1461 : // open command for a folder content
1462 :
1463 :
1464 : uno::Reference< ucb::XDynamicResultSet > xSet
1465 34 : = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1466 34 : return uno::makeAny( xSet );
1467 : }
1468 : else
1469 : {
1470 :
1471 : // open command for a document content
1472 :
1473 :
1474 28 : if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1475 14 : ( 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 14 : uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1488 14 : if ( xOut.is() )
1489 : {
1490 : // PUSH: write data into xOut
1491 :
1492 2 : uno::Reference< io::XInputStream > xIn = getInputStream();
1493 2 : 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 2 : uno::Sequence< sal_Int8 > aBuffer;
1519 2 : sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1520 :
1521 6 : while ( nRead > 0 )
1522 : {
1523 2 : aBuffer.realloc( nRead );
1524 2 : xOut->writeBytes( aBuffer );
1525 2 : aBuffer.realloc( 0 );
1526 2 : nRead = xIn->readSomeBytes( aBuffer, 65536 );
1527 : }
1528 :
1529 2 : 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 2 : }
1543 : }
1544 : else
1545 : {
1546 : uno::Reference< io::XActiveDataSink > xDataSink(
1547 12 : rArg.Sink, uno::UNO_QUERY );
1548 12 : if ( xDataSink.is() )
1549 : {
1550 : // PULL: wait for client read
1551 :
1552 12 : uno::Reference< io::XInputStream > xIn = getInputStream();
1553 12 : 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 12 : 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 12 : }
1593 14 : }
1594 : }
1595 :
1596 14 : 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 : 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 : 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 instantiated 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.startsWith( rInfo.SourceURL ) )
1843 : {
1844 : uno::Any aProps
1845 : = uno::makeAny(beans::PropertyValue(
1846 : OUString( "Uri"),
1847 : -1,
1848 : uno::makeAny(rInfo.SourceURL),
1849 0 : beans::PropertyState_DIRECT_VALUE));
1850 : ucbhelper::cancelCommandExecution(
1851 : ucb::IOErrorCode_RECURSIVE,
1852 : uno::Sequence< uno::Any >(&aProps, 1),
1853 : xEnv,
1854 : OUString( "Target is equal to or is a child of source!" ),
1855 0 : this );
1856 : // Unreachable
1857 : }
1858 : }
1859 :
1860 :
1861 : // 0) Obtain content object for source.
1862 :
1863 :
1864 : uno::Reference< ucb::XContentIdentifier > xId
1865 0 : = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1866 :
1867 : // Note: The static cast is okay here, because its sure that
1868 : // m_xProvider is always the PackageContentProvider.
1869 0 : rtl::Reference< Content > xSource;
1870 :
1871 : try
1872 : {
1873 0 : xSource = static_cast< Content * >(
1874 0 : m_xProvider->queryContent( xId ).get() );
1875 : }
1876 0 : catch ( ucb::IllegalIdentifierException const & )
1877 : {
1878 : // queryContent
1879 : }
1880 :
1881 0 : if ( !xSource.is() )
1882 : {
1883 : uno::Any aProps
1884 : = uno::makeAny(beans::PropertyValue(
1885 : OUString( "Uri"),
1886 : -1,
1887 0 : uno::makeAny(xId->getContentIdentifier()),
1888 0 : beans::PropertyState_DIRECT_VALUE));
1889 : ucbhelper::cancelCommandExecution(
1890 : ucb::IOErrorCode_CANT_READ,
1891 : uno::Sequence< uno::Any >(&aProps, 1),
1892 : xEnv,
1893 : OUString( "Cannot instanciate source object!" ),
1894 0 : this );
1895 : // Unreachable
1896 : }
1897 :
1898 :
1899 : // 1) Create new child content.
1900 :
1901 :
1902 0 : OUString aType = xSource->isFolder()
1903 0 : ? getContentType( m_aUri.getScheme(), true )
1904 0 : : getContentType( m_aUri.getScheme(), false );
1905 0 : ucb::ContentInfo aContentInfo;
1906 0 : aContentInfo.Type = aType;
1907 0 : aContentInfo.Attributes = 0;
1908 :
1909 : // Note: The static cast is okay here, because its sure that
1910 : // createNewContent always creates a Content.
1911 : rtl::Reference< Content > xTarget
1912 0 : = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1913 0 : if ( !xTarget.is() )
1914 : {
1915 : uno::Any aProps
1916 : = uno::makeAny(beans::PropertyValue(
1917 : OUString( "Folder"),
1918 : -1,
1919 : uno::makeAny(aId),
1920 0 : beans::PropertyState_DIRECT_VALUE));
1921 : ucbhelper::cancelCommandExecution(
1922 : ucb::IOErrorCode_CANT_CREATE,
1923 : uno::Sequence< uno::Any >(&aProps, 1),
1924 : xEnv,
1925 : OUString( "XContentCreator::createNewContent failed!" ),
1926 0 : this );
1927 : // Unreachable
1928 : }
1929 :
1930 :
1931 : // 2) Copy data from source content to child content.
1932 :
1933 :
1934 : uno::Sequence< beans::Property > aSourceProps
1935 0 : = xSource->getPropertySetInfo( xEnv )->getProperties();
1936 0 : sal_Int32 nCount = aSourceProps.getLength();
1937 :
1938 0 : if ( nCount )
1939 : {
1940 0 : bool bHadTitle = rInfo.NewTitle.isEmpty();
1941 :
1942 : // Get all source values.
1943 : uno::Reference< sdbc::XRow > xRow
1944 0 : = xSource->getPropertyValues( aSourceProps );
1945 :
1946 0 : uno::Sequence< beans::PropertyValue > aValues( nCount );
1947 0 : beans::PropertyValue* pValues = aValues.getArray();
1948 :
1949 0 : const beans::Property* pProps = aSourceProps.getConstArray();
1950 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1951 : {
1952 0 : const beans::Property& rProp = pProps[ n ];
1953 0 : beans::PropertyValue& rValue = pValues[ n ];
1954 :
1955 0 : rValue.Name = rProp.Name;
1956 0 : rValue.Handle = rProp.Handle;
1957 :
1958 0 : if ( !bHadTitle && rProp.Name == "Title" )
1959 : {
1960 : // Set new title instead of original.
1961 0 : bHadTitle = true;
1962 0 : rValue.Value <<= rInfo.NewTitle;
1963 : }
1964 : else
1965 : rValue.Value
1966 0 : = xRow->getObject( n + 1,
1967 : uno::Reference<
1968 0 : container::XNameAccess >() );
1969 :
1970 0 : rValue.State = beans::PropertyState_DIRECT_VALUE;
1971 :
1972 0 : if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1973 : {
1974 : // Add Additional Core Property.
1975 : try
1976 : {
1977 0 : xTarget->addProperty( rProp.Name,
1978 : rProp.Attributes,
1979 0 : rValue.Value );
1980 : }
1981 0 : catch ( beans::PropertyExistException const & )
1982 : {
1983 : }
1984 0 : catch ( beans::IllegalTypeException const & )
1985 : {
1986 : }
1987 0 : catch ( lang::IllegalArgumentException const & )
1988 : {
1989 : }
1990 : }
1991 : }
1992 :
1993 : // Set target values.
1994 0 : xTarget->setPropertyValues( aValues, xEnv );
1995 : }
1996 :
1997 :
1998 : // 3) Commit (insert) child.
1999 :
2000 :
2001 0 : xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
2002 :
2003 :
2004 : // 4) Transfer (copy) children of source.
2005 :
2006 :
2007 0 : if ( xSource->isFolder() )
2008 : {
2009 : uno::Reference< container::XEnumeration > xIter
2010 0 : = xSource->getIterator();
2011 0 : if ( xIter.is() )
2012 : {
2013 0 : while ( xIter->hasMoreElements() )
2014 : {
2015 : try
2016 : {
2017 0 : uno::Reference< container::XNamed > xNamed;
2018 0 : xIter->nextElement() >>= xNamed;
2019 :
2020 0 : if ( !xNamed.is() )
2021 : {
2022 : OSL_FAIL( "Content::transfer - Got no XNamed!" );
2023 0 : break;
2024 : }
2025 :
2026 0 : OUString aName = xNamed->getName();
2027 :
2028 0 : if ( aName.isEmpty() )
2029 : {
2030 : OSL_FAIL( "Content::transfer - Empty name!" );
2031 0 : break;
2032 : }
2033 :
2034 0 : OUString aChildId = xId->getContentIdentifier();
2035 0 : if ( ( aChildId.lastIndexOf( '/' ) + 1 )
2036 0 : != aChildId.getLength() )
2037 0 : aChildId += "/";
2038 :
2039 0 : aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
2040 :
2041 0 : ucb::TransferInfo aInfo;
2042 0 : aInfo.MoveData = sal_False;
2043 0 : aInfo.NewTitle = "";
2044 0 : aInfo.SourceURL = aChildId;
2045 0 : aInfo.NameClash = rInfo.NameClash;
2046 :
2047 : // Transfer child to target.
2048 0 : xTarget->transfer( aInfo, xEnv );
2049 : }
2050 0 : catch ( container::NoSuchElementException const & )
2051 : {
2052 : }
2053 0 : catch ( lang::WrappedTargetException const & )
2054 : {
2055 : }
2056 : }
2057 0 : }
2058 : }
2059 :
2060 :
2061 : // 5) Destroy source ( when moving only ) .
2062 :
2063 :
2064 0 : if ( rInfo.MoveData )
2065 : {
2066 0 : xSource->destroy( true, xEnv );
2067 :
2068 : // Remove all persistent data of source and its children.
2069 0 : if ( !xSource->removeData() )
2070 : {
2071 : uno::Any aProps
2072 : = uno::makeAny(
2073 : beans::PropertyValue(
2074 : OUString( "Uri"),
2075 : -1,
2076 : uno::makeAny(
2077 0 : xSource->m_xIdentifier->
2078 0 : getContentIdentifier()),
2079 0 : beans::PropertyState_DIRECT_VALUE));
2080 : ucbhelper::cancelCommandExecution(
2081 : ucb::IOErrorCode_CANT_WRITE,
2082 : uno::Sequence< uno::Any >(&aProps, 1),
2083 : xEnv,
2084 : OUString( "Cannot remove persistent data of source object!" ),
2085 0 : this );
2086 : // Unreachable
2087 : }
2088 :
2089 : // Remove own and all children's Additional Core Properties.
2090 0 : xSource->removeAdditionalPropertySet( true );
2091 0 : }
2092 0 : }
2093 :
2094 :
2095 0 : bool Content::exchangeIdentity(
2096 : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2097 : {
2098 0 : if ( !xNewId.is() )
2099 0 : return false;
2100 :
2101 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2102 :
2103 0 : uno::Reference< ucb::XContent > xThis = this;
2104 :
2105 : // Already persistent?
2106 0 : if ( m_eState != PERSISTENT )
2107 : {
2108 : OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2109 0 : return false;
2110 : }
2111 :
2112 : // Exchange own identitity.
2113 :
2114 : // Fail, if a content with given id already exists.
2115 0 : PackageUri aNewUri( xNewId->getContentIdentifier() );
2116 0 : if ( !hasData( aNewUri ) )
2117 : {
2118 0 : OUString aOldURL = m_xIdentifier->getContentIdentifier();
2119 :
2120 0 : aGuard.clear();
2121 0 : if ( exchange( xNewId ) )
2122 : {
2123 0 : m_aUri = aNewUri;
2124 0 : if ( isFolder() )
2125 : {
2126 : // Process instantiated children...
2127 :
2128 0 : ContentRefList aChildren;
2129 0 : queryChildren( aChildren );
2130 :
2131 0 : ContentRefList::const_iterator it = aChildren.begin();
2132 0 : ContentRefList::const_iterator end = aChildren.end();
2133 :
2134 0 : while ( it != end )
2135 : {
2136 0 : ContentRef xChild = (*it);
2137 :
2138 : // Create new content identifier for the child...
2139 : uno::Reference< ucb::XContentIdentifier > xOldChildId
2140 0 : = xChild->getIdentifier();
2141 : OUString aOldChildURL
2142 0 : = xOldChildId->getContentIdentifier();
2143 : OUString aNewChildURL
2144 : = aOldChildURL.replaceAt(
2145 : 0,
2146 : aOldURL.getLength(),
2147 0 : xNewId->getContentIdentifier() );
2148 : uno::Reference< ucb::XContentIdentifier > xNewChildId
2149 0 : = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2150 :
2151 0 : if ( !xChild->exchangeIdentity( xNewChildId ) )
2152 0 : return false;
2153 :
2154 0 : ++it;
2155 0 : }
2156 : }
2157 0 : return true;
2158 0 : }
2159 : }
2160 :
2161 : OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2162 0 : return false;
2163 : }
2164 :
2165 :
2166 0 : void Content::queryChildren( ContentRefList& rChildren )
2167 : {
2168 : // Obtain a list with a snapshot of all currently instantiated contents
2169 : // from provider and extract the contents which are direct children
2170 : // of this content.
2171 :
2172 0 : ::ucbhelper::ContentRefList aAllContents;
2173 0 : m_xProvider->queryExistingContents( aAllContents );
2174 :
2175 0 : OUString aURL = m_xIdentifier->getContentIdentifier();
2176 :
2177 : OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2178 : "Content::queryChildren - Invalid URL!" );
2179 :
2180 0 : aURL += "/";
2181 :
2182 0 : sal_Int32 nLen = aURL.getLength();
2183 :
2184 0 : ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2185 0 : ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2186 :
2187 0 : while ( it != end )
2188 : {
2189 0 : ::ucbhelper::ContentImplHelperRef xChild = (*it);
2190 : OUString aChildURL
2191 0 : = xChild->getIdentifier()->getContentIdentifier();
2192 :
2193 : // Is aURL a prefix of aChildURL?
2194 0 : if ( ( aChildURL.getLength() > nLen ) &&
2195 0 : ( aChildURL.startsWith( aURL ) ) )
2196 : {
2197 0 : if ( aChildURL.indexOf( '/', nLen ) == -1 )
2198 : {
2199 : // No further slashes. It's a child!
2200 : rChildren.push_back(
2201 : ContentRef(
2202 0 : static_cast< Content * >( xChild.get() ) ) );
2203 : }
2204 : }
2205 0 : ++it;
2206 0 : }
2207 0 : }
2208 :
2209 :
2210 48 : uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2211 : const PackageUri& rURI )
2212 : {
2213 48 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2214 :
2215 96 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
2216 48 : if ( rURI.getPackage() == m_aUri.getPackage() )
2217 : {
2218 48 : if ( !m_xPackage.is() )
2219 0 : m_xPackage = m_pProvider->createPackage( m_aUri );
2220 :
2221 48 : return m_xPackage;
2222 : }
2223 :
2224 48 : return m_pProvider->createPackage( rURI );
2225 : }
2226 :
2227 :
2228 48 : uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2229 : {
2230 48 : return getPackage( m_aUri );
2231 : }
2232 :
2233 :
2234 : // static
2235 0 : bool Content::hasData(
2236 : ContentProvider* pProvider,
2237 : const PackageUri& rURI,
2238 : uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2239 : {
2240 0 : rxPackage = pProvider->createPackage( rURI );
2241 0 : return rxPackage->hasByHierarchicalName( rURI.getPath() );
2242 : }
2243 :
2244 :
2245 0 : bool Content::hasData( const PackageUri& rURI )
2246 : {
2247 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2248 :
2249 0 : uno::Reference< container::XHierarchicalNameAccess > xPackage;
2250 0 : if ( rURI.getPackage() == m_aUri.getPackage() )
2251 : {
2252 0 : xPackage = getPackage();
2253 0 : return xPackage->hasByHierarchicalName( rURI.getPath() );
2254 : }
2255 :
2256 0 : return hasData( m_pProvider, rURI, xPackage );
2257 : }
2258 :
2259 :
2260 : //static
2261 66 : bool Content::loadData(
2262 : ContentProvider* pProvider,
2263 : const PackageUri& rURI,
2264 : ContentProperties& rProps,
2265 : uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2266 : {
2267 66 : rxPackage = pProvider->createPackage( rURI );
2268 :
2269 66 : if ( rURI.isRootFolder() )
2270 : {
2271 : // Properties available only from package
2272 : uno::Reference< beans::XPropertySet > xPackagePropSet(
2273 32 : rxPackage, uno::UNO_QUERY );
2274 :
2275 : OSL_ENSURE( xPackagePropSet.is(),
2276 : "Content::loadData - "
2277 : "Got no XPropertySet interface from package!" );
2278 :
2279 32 : if ( xPackagePropSet.is() )
2280 : {
2281 : // HasEncryptedEntries ( only avalibale at root folder )
2282 : try
2283 : {
2284 : uno::Any aHasEncryptedEntries
2285 32 : = xPackagePropSet->getPropertyValue(
2286 32 : OUString( "HasEncryptedEntries" ) );
2287 32 : if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2288 : {
2289 : OSL_FAIL( "Content::loadData - "
2290 : "Got no HasEncryptedEntries value!" );
2291 0 : return false;
2292 32 : }
2293 : }
2294 0 : catch ( beans::UnknownPropertyException const & )
2295 : {
2296 : OSL_FAIL( "Content::loadData - "
2297 : "Got no HasEncryptedEntries value!" );
2298 0 : return false;
2299 : }
2300 0 : catch ( lang::WrappedTargetException const & )
2301 : {
2302 : OSL_FAIL( "Content::loadData - "
2303 : "Got no HasEncryptedEntries value!" );
2304 0 : return false;
2305 : }
2306 32 : }
2307 : }
2308 :
2309 66 : if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2310 0 : return false;
2311 :
2312 : try
2313 : {
2314 66 : uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2315 66 : if ( aEntry.hasValue() )
2316 : {
2317 66 : uno::Reference< beans::XPropertySet > xPropSet;
2318 66 : aEntry >>= xPropSet;
2319 :
2320 66 : if ( !xPropSet.is() )
2321 : {
2322 : OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2323 0 : return false;
2324 : }
2325 :
2326 : // Title
2327 66 : rProps.aTitle = rURI.getName();
2328 :
2329 : // MediaType
2330 : try
2331 : {
2332 : uno::Any aMediaType
2333 66 : = xPropSet->getPropertyValue(
2334 66 : OUString("MediaType") );
2335 66 : if ( !( aMediaType >>= rProps.aMediaType ) )
2336 : {
2337 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2338 0 : return false;
2339 66 : }
2340 : }
2341 0 : catch ( beans::UnknownPropertyException const & )
2342 : {
2343 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2344 0 : return false;
2345 : }
2346 0 : catch ( lang::WrappedTargetException const & )
2347 : {
2348 : OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2349 0 : return false;
2350 : }
2351 :
2352 132 : uno::Reference< container::XEnumerationAccess > xEnumAccess;
2353 66 : aEntry >>= xEnumAccess;
2354 :
2355 : // ContentType / IsFolder / IsDocument
2356 66 : if ( xEnumAccess.is() )
2357 : {
2358 : // folder
2359 40 : rProps.aContentType = getContentType( rURI.getScheme(), true );
2360 40 : rProps.bIsDocument = false;
2361 40 : rProps.bIsFolder = true;
2362 : }
2363 : else
2364 : {
2365 : // stream
2366 26 : rProps.aContentType = getContentType( rURI.getScheme(), false );
2367 26 : rProps.bIsDocument = true;
2368 26 : rProps.bIsFolder = false;
2369 : }
2370 :
2371 66 : if ( rProps.bIsDocument )
2372 : {
2373 : // Size ( only available for streams )
2374 : try
2375 : {
2376 : uno::Any aSize
2377 26 : = xPropSet->getPropertyValue(
2378 26 : OUString("Size") );
2379 26 : if ( !( aSize >>= rProps.nSize ) )
2380 : {
2381 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2382 0 : return false;
2383 26 : }
2384 : }
2385 0 : catch ( beans::UnknownPropertyException const & )
2386 : {
2387 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2388 0 : return false;
2389 : }
2390 0 : catch ( lang::WrappedTargetException const & )
2391 : {
2392 : OSL_FAIL( "Content::loadData - Got no Size value!" );
2393 0 : return false;
2394 : }
2395 :
2396 : // Compressed ( only available for streams )
2397 : try
2398 : {
2399 : uno::Any aCompressed
2400 26 : = xPropSet->getPropertyValue(
2401 26 : OUString("Compressed") );
2402 26 : if ( !( aCompressed >>= rProps.bCompressed ) )
2403 : {
2404 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2405 0 : return false;
2406 26 : }
2407 : }
2408 0 : catch ( beans::UnknownPropertyException const & )
2409 : {
2410 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2411 0 : return false;
2412 : }
2413 0 : catch ( lang::WrappedTargetException const & )
2414 : {
2415 : OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2416 0 : return false;
2417 : }
2418 :
2419 : // Encrypted ( only available for streams )
2420 : try
2421 : {
2422 : uno::Any aEncrypted
2423 26 : = xPropSet->getPropertyValue(
2424 26 : OUString("Encrypted") );
2425 26 : if ( !( aEncrypted >>= rProps.bEncrypted ) )
2426 : {
2427 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2428 0 : return false;
2429 26 : }
2430 : }
2431 0 : catch ( beans::UnknownPropertyException const & )
2432 : {
2433 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2434 0 : return false;
2435 : }
2436 0 : catch ( lang::WrappedTargetException const & )
2437 : {
2438 : OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2439 0 : return false;
2440 : }
2441 : }
2442 132 : return true;
2443 0 : }
2444 : }
2445 0 : catch ( container::NoSuchElementException const & )
2446 : {
2447 : // getByHierarchicalName
2448 : }
2449 :
2450 0 : return false;
2451 : }
2452 :
2453 :
2454 0 : bool Content::renameData(
2455 : const uno::Reference< ucb::XContentIdentifier >& xOldId,
2456 : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2457 : {
2458 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2459 :
2460 0 : PackageUri aURI( xOldId->getContentIdentifier() );
2461 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2462 0 : aURI );
2463 :
2464 0 : if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2465 0 : return false;
2466 :
2467 : try
2468 : {
2469 0 : uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2470 0 : uno::Reference< container::XNamed > xNamed;
2471 0 : aEntry >>= xNamed;
2472 :
2473 0 : if ( !xNamed.is() )
2474 : {
2475 : OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2476 0 : return false;
2477 : }
2478 :
2479 0 : PackageUri aNewURI( xNewId->getContentIdentifier() );
2480 :
2481 : // No success indicator!? No return value / exceptions specified.
2482 0 : xNamed->setName( aNewURI.getName() );
2483 :
2484 0 : return true;
2485 : }
2486 0 : catch ( container::NoSuchElementException const & )
2487 : {
2488 : // getByHierarchicalName
2489 : }
2490 :
2491 0 : return false;
2492 : }
2493 :
2494 :
2495 0 : bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2496 : {
2497 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2498 :
2499 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2500 :
2501 : uno::Reference< beans::XPropertySet > xPackagePropSet(
2502 0 : xNA, uno::UNO_QUERY );
2503 : OSL_ENSURE( xPackagePropSet.is(),
2504 : "Content::storeData - "
2505 : "Got no XPropertySet interface from package!" );
2506 :
2507 0 : if ( !xPackagePropSet.is() )
2508 0 : return false;
2509 :
2510 0 : if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2511 : {
2512 0 : if ( m_aUri.isRootFolder() )
2513 : {
2514 : // Property available only from package and from streams (see below)
2515 : try
2516 : {
2517 0 : xPackagePropSet->setPropertyValue(
2518 : OUString("EncryptionKey"),
2519 0 : uno::makeAny( m_aProps.aEncryptionKey ) );
2520 0 : m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2521 : }
2522 0 : catch ( beans::UnknownPropertyException const & )
2523 : {
2524 : // setPropertyValue
2525 : }
2526 0 : catch ( beans::PropertyVetoException const & )
2527 : {
2528 : // setPropertyValue
2529 : }
2530 0 : catch ( lang::IllegalArgumentException const & )
2531 : {
2532 : // setPropertyValue
2533 : }
2534 0 : catch ( lang::WrappedTargetException const & )
2535 : {
2536 : // setPropertyValue
2537 : }
2538 : }
2539 : }
2540 :
2541 0 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2542 : {
2543 : // if ( !bCreate )
2544 : // return sal_True;
2545 :
2546 : try
2547 : {
2548 : // Create new resource...
2549 : uno::Reference< lang::XSingleServiceFactory > xFac(
2550 0 : xNA, uno::UNO_QUERY );
2551 0 : if ( !xFac.is() )
2552 : {
2553 : OSL_FAIL( "Content::storeData - "
2554 : "Got no XSingleServiceFactory interface!" );
2555 0 : return false;
2556 : }
2557 :
2558 0 : uno::Sequence< uno::Any > aArgs( 1 );
2559 0 : aArgs[ 0 ] <<= isFolder();
2560 :
2561 : uno::Reference< uno::XInterface > xNew
2562 0 : = xFac->createInstanceWithArguments( aArgs );
2563 :
2564 0 : if ( !xNew.is() )
2565 : {
2566 : OSL_FAIL( "Content::storeData - createInstance failed!" );
2567 0 : return false;
2568 : }
2569 :
2570 0 : PackageUri aParentUri( getParentURL() );
2571 : uno::Any aEntry
2572 0 : = xNA->getByHierarchicalName( aParentUri.getPath() );
2573 0 : uno::Reference< container::XNameContainer > xParentContainer;
2574 0 : aEntry >>= xParentContainer;
2575 :
2576 0 : if ( !xParentContainer.is() )
2577 : {
2578 : OSL_FAIL( "Content::storeData - "
2579 : "Got no XNameContainer interface!" );
2580 0 : return false;
2581 : }
2582 :
2583 0 : xParentContainer->insertByName( m_aProps.aTitle,
2584 0 : uno::makeAny( xNew ) );
2585 : }
2586 0 : catch ( lang::IllegalArgumentException const & )
2587 : {
2588 : // insertByName
2589 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2590 0 : return false;
2591 : }
2592 0 : catch ( uno::RuntimeException const & )
2593 : {
2594 0 : throw;
2595 : }
2596 0 : catch ( container::ElementExistException const & )
2597 : {
2598 : // insertByName
2599 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2600 0 : return false;
2601 : }
2602 0 : catch ( lang::WrappedTargetException const & )
2603 : {
2604 : // insertByName
2605 : OSL_FAIL( "Content::storeData - insertByName failed!" );
2606 0 : return false;
2607 : }
2608 0 : catch ( container::NoSuchElementException const & )
2609 : {
2610 : // getByHierarchicalName
2611 : OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2612 0 : return false;
2613 : }
2614 0 : catch ( uno::Exception const & )
2615 : {
2616 : // createInstanceWithArguments
2617 : OSL_FAIL( "Content::storeData - Error!" );
2618 0 : return false;
2619 : }
2620 : }
2621 :
2622 0 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2623 0 : return false;
2624 :
2625 : try
2626 : {
2627 0 : uno::Reference< beans::XPropertySet > xPropSet;
2628 0 : xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2629 :
2630 0 : if ( !xPropSet.is() )
2631 : {
2632 : OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2633 0 : return false;
2634 : }
2635 :
2636 :
2637 : // Store property values...
2638 :
2639 :
2640 0 : if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2641 : {
2642 0 : xPropSet->setPropertyValue(
2643 : OUString("MediaType"),
2644 0 : uno::makeAny( m_aProps.aMediaType ) );
2645 0 : m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2646 : }
2647 :
2648 0 : if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2649 : {
2650 0 : if ( !isFolder() )
2651 0 : xPropSet->setPropertyValue(
2652 : OUString("Compressed"),
2653 0 : uno::makeAny( m_aProps.bCompressed ) );
2654 :
2655 0 : m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2656 : }
2657 :
2658 0 : if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2659 : {
2660 0 : if ( !isFolder() )
2661 0 : xPropSet->setPropertyValue(
2662 : OUString("Encrypted"),
2663 0 : uno::makeAny( m_aProps.bEncrypted ) );
2664 :
2665 0 : m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2666 : }
2667 :
2668 0 : if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2669 : {
2670 0 : if ( !isFolder() )
2671 0 : xPropSet->setPropertyValue(
2672 : OUString("EncryptionKey"),
2673 0 : uno::makeAny( m_aProps.aEncryptionKey ) );
2674 :
2675 0 : m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2676 : }
2677 :
2678 :
2679 : // Store data stream...
2680 :
2681 :
2682 0 : if ( xStream.is() && !isFolder() )
2683 : {
2684 : uno::Reference< io::XActiveDataSink > xSink(
2685 0 : xPropSet, uno::UNO_QUERY );
2686 :
2687 0 : if ( !xSink.is() )
2688 : {
2689 : OSL_FAIL( "Content::storeData - "
2690 : "Got no XActiveDataSink interface!" );
2691 0 : return false;
2692 : }
2693 :
2694 0 : xSink->setInputStream( xStream );
2695 : }
2696 :
2697 0 : return true;
2698 : }
2699 0 : catch ( container::NoSuchElementException const & )
2700 : {
2701 : // getByHierarchicalName
2702 : }
2703 0 : catch ( beans::UnknownPropertyException const & )
2704 : {
2705 : // setPropertyValue
2706 : }
2707 0 : catch ( beans::PropertyVetoException const & )
2708 : {
2709 : // setPropertyValue
2710 : }
2711 0 : catch ( lang::IllegalArgumentException const & )
2712 : {
2713 : // setPropertyValue
2714 : }
2715 0 : catch ( lang::WrappedTargetException const & )
2716 : {
2717 : // setPropertyValue
2718 : }
2719 :
2720 : OSL_FAIL( "Content::storeData - Error!" );
2721 0 : return false;
2722 : }
2723 :
2724 :
2725 0 : bool Content::removeData()
2726 : {
2727 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2728 :
2729 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2730 :
2731 0 : PackageUri aParentUri( getParentURL() );
2732 0 : if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2733 0 : return false;
2734 :
2735 : try
2736 : {
2737 0 : uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2738 0 : uno::Reference< container::XNameContainer > xContainer;
2739 0 : aEntry >>= xContainer;
2740 :
2741 0 : if ( !xContainer.is() )
2742 : {
2743 : OSL_FAIL( "Content::removeData - "
2744 : "Got no XNameContainer interface!" );
2745 0 : return false;
2746 : }
2747 :
2748 0 : xContainer->removeByName( m_aUri.getName() );
2749 0 : return true;
2750 : }
2751 0 : catch ( container::NoSuchElementException const & )
2752 : {
2753 : // getByHierarchicalName, removeByName
2754 : }
2755 0 : catch ( lang::WrappedTargetException const & )
2756 : {
2757 : // removeByName
2758 : }
2759 :
2760 : OSL_FAIL( "Content::removeData - Error!" );
2761 0 : return false;
2762 : }
2763 :
2764 :
2765 0 : bool Content::flushData()
2766 : {
2767 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2768 :
2769 : // Note: XChangesBatch is only implemented by the package itself, not
2770 : // by the single entries. Maybe this has to change...
2771 :
2772 0 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2773 :
2774 0 : uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2775 0 : if ( !xBatch.is() )
2776 : {
2777 : OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2778 0 : return false;
2779 : }
2780 :
2781 : try
2782 : {
2783 0 : xBatch->commitChanges();
2784 0 : return true;
2785 : }
2786 0 : catch ( lang::WrappedTargetException const & )
2787 : {
2788 : }
2789 :
2790 : OSL_FAIL( "Content::flushData - Error!" );
2791 0 : return false;
2792 : }
2793 :
2794 :
2795 14 : uno::Reference< io::XInputStream > Content::getInputStream()
2796 : {
2797 14 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2798 :
2799 14 : uno::Reference< io::XInputStream > xStream;
2800 28 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2801 :
2802 14 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2803 0 : return xStream;
2804 :
2805 : try
2806 : {
2807 14 : uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2808 28 : uno::Reference< io::XActiveDataSink > xSink;
2809 14 : aEntry >>= xSink;
2810 :
2811 14 : if ( !xSink.is() )
2812 : {
2813 : OSL_FAIL( "Content::getInputStream - "
2814 : "Got no XActiveDataSink interface!" );
2815 0 : return xStream;
2816 : }
2817 :
2818 14 : xStream = xSink->getInputStream();
2819 :
2820 : OSL_ENSURE( xStream.is(),
2821 14 : "Content::getInputStream - Got no stream!" );
2822 : }
2823 0 : catch ( container::NoSuchElementException const & )
2824 : {
2825 : // getByHierarchicalName
2826 : }
2827 :
2828 28 : return xStream;
2829 : }
2830 :
2831 :
2832 34 : uno::Reference< container::XEnumeration > Content::getIterator()
2833 : {
2834 34 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2835 :
2836 34 : uno::Reference< container::XEnumeration > xIter;
2837 68 : uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2838 :
2839 34 : if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2840 0 : return xIter;
2841 :
2842 : try
2843 : {
2844 34 : uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2845 68 : uno::Reference< container::XEnumerationAccess > xIterFac;
2846 34 : aEntry >>= xIterFac;
2847 :
2848 34 : if ( !xIterFac.is() )
2849 : {
2850 : OSL_FAIL( "Content::getIterator - "
2851 : "Got no XEnumerationAccess interface!" );
2852 0 : return xIter;
2853 : }
2854 :
2855 34 : xIter = xIterFac->createEnumeration();
2856 :
2857 : OSL_ENSURE( xIter.is(),
2858 34 : "Content::getIterator - Got no iterator!" );
2859 : }
2860 0 : catch ( container::NoSuchElementException const & )
2861 : {
2862 : // getByHierarchicalName
2863 : }
2864 :
2865 68 : return xIter;
2866 : }
2867 :
2868 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|