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