1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <rtl/uri.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #include <osl/file.hxx>
33 #include "osl/diagnose.h"
34 #include <com/sun/star/ucb/OpenMode.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/ucb/XProgressHandler.hpp>
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #include <com/sun/star/io/XActiveDataStreamer.hpp>
39 #include <com/sun/star/io/XOutputStream.hpp>
40 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
41 #include <com/sun/star/io/XActiveDataSink.hpp>
42 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
43 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
44 #include <com/sun/star/ucb/ContentAction.hpp>
45 #include <com/sun/star/ucb/NameClash.hpp>
46 #include "filglob.hxx"
51 #include "filerror.hxx"
52 #include "filinsreq.hxx"
55 using namespace fileaccess
;
56 using namespace com::sun::star
;
57 using namespace com::sun::star::uno
;
58 using namespace com::sun::star::ucb
;
63 typedef cppu::OMultiTypeInterfaceContainerHelperVar
< rtl::OUString
,hashOUString
,equalOUString
>
64 PropertyListeners_impl
;
66 class fileaccess::PropertyListeners
67 : public PropertyListeners_impl
70 PropertyListeners( ::osl::Mutex
& aMutex
)
71 : PropertyListeners_impl( aMutex
)
77 /****************************************************************************************/
81 /****************************************************************************************/
83 ////////////////////////////////////////////////////////////////////////////////
84 // Private Constructor for just inserted Contents
86 BaseContent::BaseContent( shell
* pMyShell
,
87 const rtl::OUString
& parentName
,
89 : m_pMyShell( pMyShell
),
90 m_xContentIdentifier( 0 ),
91 m_aUncPath( parentName
),
93 m_nState( JustInserted
),
94 m_pDisposeEventListeners( 0 ),
95 m_pContentEventListeners( 0 ),
96 m_pPropertySetInfoChangeListeners( 0 ),
97 m_pPropertyListener( 0 )
99 m_pMyShell
->m_pProvider
->acquire();
100 // No registering, since we have no name
104 ////////////////////////////////////////////////////////////////////////////////
105 // Constructor for full featured Contents
107 BaseContent::BaseContent( shell
* pMyShell
,
108 const Reference
< XContentIdentifier
>& xContentIdentifier
,
109 const rtl::OUString
& aUncPath
)
110 : m_pMyShell( pMyShell
),
111 m_xContentIdentifier( xContentIdentifier
),
112 m_aUncPath( aUncPath
),
114 m_nState( FullFeatured
),
115 m_pDisposeEventListeners( 0 ),
116 m_pContentEventListeners( 0 ),
117 m_pPropertySetInfoChangeListeners( 0 ),
118 m_pPropertyListener( 0 )
120 m_pMyShell
->m_pProvider
->acquire();
121 m_pMyShell
->registerNotifier( m_aUncPath
,this );
122 m_pMyShell
->insertDefaultProperties( m_aUncPath
);
126 BaseContent::~BaseContent( )
128 if( ( m_nState
& FullFeatured
) || ( m_nState
& Deleted
) )
130 m_pMyShell
->deregisterNotifier( m_aUncPath
,this );
132 m_pMyShell
->m_pProvider
->release();
134 delete m_pDisposeEventListeners
;
135 delete m_pContentEventListeners
;
136 delete m_pPropertyListener
;
137 delete m_pPropertySetInfoChangeListeners
;
141 //////////////////////////////////////////////////////////////////////////
143 //////////////////////////////////////////////////////////////////////////
146 BaseContent::acquire( void )
149 OWeakObject::acquire();
154 BaseContent::release( void )
157 OWeakObject::release();
162 BaseContent::queryInterface( const Type
& rType
)
163 throw( RuntimeException
)
165 Any aRet
= cppu::queryInterface( rType
,
166 (static_cast< lang::XComponent
* >(this)),
167 (static_cast< lang::XTypeProvider
* >(this)),
168 (static_cast< lang::XServiceInfo
* >(this)),
169 (static_cast< XCommandProcessor
* >(this)),
170 (static_cast< container::XChild
* >(this)),
171 (static_cast< beans::XPropertiesChangeNotifier
* >(this)),
172 (static_cast< beans::XPropertyContainer
* >(this)),
173 (static_cast< XContentCreator
* >(this)),
174 (static_cast< beans::XPropertySetInfoChangeNotifier
* >(this)),
175 (static_cast< XContent
* >(this)) );
176 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
182 //////////////////////////////////////////////////////////////////////////////////////////
184 ////////////////////////////////////////////////////////////////////////////////////////
187 BaseContent::addEventListener( const Reference
< lang::XEventListener
>& Listener
)
188 throw( RuntimeException
)
190 osl::MutexGuard
aGuard( m_aMutex
);
192 if ( ! m_pDisposeEventListeners
)
193 m_pDisposeEventListeners
=
194 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex
);
196 m_pDisposeEventListeners
->addInterface( Listener
);
201 BaseContent::removeEventListener( const Reference
< lang::XEventListener
>& Listener
)
202 throw( RuntimeException
)
204 osl::MutexGuard
aGuard( m_aMutex
);
206 if ( m_pDisposeEventListeners
)
207 m_pDisposeEventListeners
->removeInterface( Listener
);
212 BaseContent::dispose()
213 throw( RuntimeException
)
215 lang::EventObject aEvt
;
216 cppu::OInterfaceContainerHelper
* pDisposeEventListeners
;
217 cppu::OInterfaceContainerHelper
* pContentEventListeners
;
218 cppu::OInterfaceContainerHelper
* pPropertySetInfoChangeListeners
;
219 PropertyListeners
* pPropertyListener
;
222 osl::MutexGuard
aGuard( m_aMutex
);
223 aEvt
.Source
= static_cast< XContent
* >( this );
226 pDisposeEventListeners
=
227 m_pDisposeEventListeners
, m_pDisposeEventListeners
= 0;
229 pContentEventListeners
=
230 m_pContentEventListeners
, m_pContentEventListeners
= 0;
232 pPropertySetInfoChangeListeners
=
233 m_pPropertySetInfoChangeListeners
,
234 m_pPropertySetInfoChangeListeners
= 0;
237 m_pPropertyListener
, m_pPropertyListener
= 0;
240 if ( pDisposeEventListeners
&& pDisposeEventListeners
->getLength() )
241 pDisposeEventListeners
->disposeAndClear( aEvt
);
243 if ( pContentEventListeners
&& pContentEventListeners
->getLength() )
244 pContentEventListeners
->disposeAndClear( aEvt
);
246 if( pPropertyListener
)
247 pPropertyListener
->disposeAndClear( aEvt
);
249 if( pPropertySetInfoChangeListeners
)
250 pPropertySetInfoChangeListeners
->disposeAndClear( aEvt
);
252 delete pDisposeEventListeners
;
253 delete pContentEventListeners
;
254 delete pPropertyListener
;
255 delete pPropertySetInfoChangeListeners
;
260 //////////////////////////////////////////////////////////////////////////////////////////
262 //////////////////////////////////////////////////////////////////////////////////////////
264 rtl::OUString SAL_CALL
265 BaseContent::getImplementationName()
266 throw( RuntimeException
)
268 return rtl::OUString("com.sun.star.comp.ucb.FileContent");
274 BaseContent::supportsService( const rtl::OUString
& ServiceName
)
275 throw( RuntimeException
)
277 if ( ServiceName
== "com.sun.star.ucb.FileContent" )
285 Sequence
< rtl::OUString
> SAL_CALL
286 BaseContent::getSupportedServiceNames()
287 throw( RuntimeException
)
289 Sequence
< rtl::OUString
> ret( 1 );
290 ret
[0] = rtl::OUString("com.sun.star.ucb.FileContent");
296 //////////////////////////////////////////////////////////////////////////////////////////
298 //////////////////////////////////////////////////////////////////////////////////////////
300 XTYPEPROVIDER_IMPL_10( BaseContent
,
308 beans::XPropertiesChangeNotifier
,
309 beans::XPropertyContainer
,
310 beans::XPropertySetInfoChangeNotifier
)
313 //////////////////////////////////////////////////////////////////////////////////////////
315 //////////////////////////////////////////////////////////////////////////////////////////
318 BaseContent::createCommandIdentifier( void )
319 throw( RuntimeException
)
321 return m_pMyShell
->getCommandId();
326 BaseContent::abort( sal_Int32 CommandId
)
327 throw( RuntimeException
)
329 m_pMyShell
->abort( CommandId
);
334 BaseContent::execute( const Command
& aCommand
,
336 const Reference
< XCommandEnvironment
>& Environment
)
338 CommandAbortedException
,
342 // A Command with commandid zero cannot be aborted
343 CommandId
= createCommandIdentifier();
345 m_pMyShell
->startTask( CommandId
,
350 if (aCommand
.Name
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("getPropertySetInfo"))) // No exceptions
352 aAny
<<= getPropertySetInfo( CommandId
);
354 else if (aCommand
.Name
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("getCommandInfo"))) // no exceptions
356 aAny
<<= getCommandInfo();
358 else if ( aCommand
.Name
== "setPropertyValues" )
360 Sequence
< beans::PropertyValue
> sPropertyValues
;
362 if( ! ( aCommand
.Argument
>>= sPropertyValues
) )
363 m_pMyShell
->installError( CommandId
,
364 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT
);
366 aAny
<<= setPropertyValues( CommandId
,sPropertyValues
); // calls endTask by itself
368 else if ( aCommand
.Name
== "getPropertyValues" )
370 Sequence
< beans::Property
> ListOfRequestedProperties
;
372 if( ! ( aCommand
.Argument
>>= ListOfRequestedProperties
) )
373 m_pMyShell
->installError( CommandId
,
374 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT
);
376 aAny
<<= getPropertyValues( CommandId
,
377 ListOfRequestedProperties
);
379 else if ( aCommand
.Name
== "open" )
381 OpenCommandArgument2 aOpenArgument
;
382 if( ! ( aCommand
.Argument
>>= aOpenArgument
) )
383 m_pMyShell
->installError( CommandId
,
384 TASKHANDLING_WRONG_OPEN_ARGUMENT
);
387 Reference
< XDynamicResultSet
> result
= open( CommandId
,aOpenArgument
);
392 else if ( aCommand
.Name
== "delete" )
394 if( ! aCommand
.Argument
.has
< sal_Bool
>() )
395 m_pMyShell
->installError( CommandId
,
396 TASKHANDLING_WRONG_DELETE_ARGUMENT
);
398 deleteContent( CommandId
);
400 else if ( aCommand
.Name
== "transfer" )
402 TransferInfo aTransferInfo
;
403 if( ! ( aCommand
.Argument
>>= aTransferInfo
) )
404 m_pMyShell
->installError( CommandId
,
405 TASKHANDLING_WRONG_TRANSFER_ARGUMENT
);
407 transfer( CommandId
, aTransferInfo
);
409 else if ( aCommand
.Name
== "insert" )
411 InsertCommandArgument aInsertArgument
;
412 if( ! ( aCommand
.Argument
>>= aInsertArgument
) )
413 m_pMyShell
->installError( CommandId
,
414 TASKHANDLING_WRONG_INSERT_ARGUMENT
);
416 insert( CommandId
,aInsertArgument
);
418 else if ( aCommand
.Name
== "getCasePreservingURL" )
420 Sequence
< beans::Property
> seq(1);
421 seq
[0] = beans::Property(
422 rtl::OUString("CasePreservingURL"),
424 getCppuType( static_cast< sal_Bool
* >(0) ),
426 Reference
< sdbc::XRow
> xRow
= getPropertyValues( CommandId
,seq
);
427 rtl::OUString CasePreservingURL
= xRow
->getString(1);
429 aAny
<<= CasePreservingURL
;
431 else if ( aCommand
.Name
== "createNewContent" )
433 ucb::ContentInfo aArg
;
434 if ( !( aCommand
.Argument
>>= aArg
) )
435 m_pMyShell
->installError( CommandId
,
436 TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT
);
438 aAny
<<= createNewContent( aArg
);
441 m_pMyShell
->installError( CommandId
,
442 TASKHANDLER_UNSUPPORTED_COMMAND
);
445 // This is the only function allowed to throw an exception
446 endTask( CommandId
);
454 BaseContent::addPropertiesChangeListener(
455 const Sequence
< rtl::OUString
>& PropertyNames
,
456 const Reference
< beans::XPropertiesChangeListener
>& Listener
)
457 throw( RuntimeException
)
459 if( ! Listener
.is() )
462 osl::MutexGuard
aGuard( m_aMutex
);
464 if( ! m_pPropertyListener
)
465 m_pPropertyListener
= new PropertyListeners( m_aEventListenerMutex
);
468 if( PropertyNames
.getLength() == 0 )
469 m_pPropertyListener
->addInterface( rtl::OUString(),Listener
);
472 Reference
< beans::XPropertySetInfo
> xProp
= m_pMyShell
->info_p( m_aUncPath
);
473 for( sal_Int32 i
= 0; i
< PropertyNames
.getLength(); ++i
)
474 if( xProp
->hasPropertyByName( PropertyNames
[i
] ) )
475 m_pPropertyListener
->addInterface( PropertyNames
[i
],Listener
);
481 BaseContent::removePropertiesChangeListener( const Sequence
< rtl::OUString
>& PropertyNames
,
482 const Reference
< beans::XPropertiesChangeListener
>& Listener
)
483 throw( RuntimeException
)
485 if( ! Listener
.is() )
488 osl::MutexGuard
aGuard( m_aMutex
);
490 if( ! m_pPropertyListener
)
493 for( sal_Int32 i
= 0; i
< PropertyNames
.getLength(); ++i
)
494 m_pPropertyListener
->removeInterface( PropertyNames
[i
],Listener
);
496 m_pPropertyListener
->removeInterface( rtl::OUString(), Listener
);
500 /////////////////////////////////////////////////////////////////////////////////////////
502 /////////////////////////////////////////////////////////////////////////////////////////
504 Reference
< ucb::XContentIdentifier
> SAL_CALL
505 BaseContent::getIdentifier()
506 throw( RuntimeException
)
508 return m_xContentIdentifier
;
512 rtl::OUString SAL_CALL
513 BaseContent::getContentType()
514 throw( RuntimeException
)
516 if( !( m_nState
& Deleted
) )
518 if( m_nState
& JustInserted
)
521 return m_pMyShell
->FolderContentType
;
523 return m_pMyShell
->FileContentType
;
530 Sequence
< beans::Property
> seq(1);
531 seq
[0] = beans::Property( rtl::OUString("IsDocument"),
533 getCppuType( static_cast< sal_Bool
* >(0) ),
535 Reference
< sdbc::XRow
> xRow
= getPropertyValues( -1,seq
);
536 sal_Bool IsDocument
= xRow
->getBoolean( 1 );
538 if ( !xRow
->wasNull() )
541 return m_pMyShell
->FileContentType
;
543 return m_pMyShell
->FolderContentType
;
547 OSL_FAIL( "BaseContent::getContentType - Property value was null!" );
550 catch (const sdbc::SQLException
&)
552 OSL_FAIL( "BaseContent::getContentType - Caught SQLException!" );
557 return rtl::OUString();
563 BaseContent::addContentEventListener(
564 const Reference
< XContentEventListener
>& Listener
)
565 throw( RuntimeException
)
567 osl::MutexGuard
aGuard( m_aMutex
);
569 if ( ! m_pContentEventListeners
)
570 m_pContentEventListeners
=
571 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex
);
574 m_pContentEventListeners
->addInterface( Listener
);
579 BaseContent::removeContentEventListener(
580 const Reference
< XContentEventListener
>& Listener
)
581 throw( RuntimeException
)
583 osl::MutexGuard
aGuard( m_aMutex
);
585 if ( m_pContentEventListeners
)
586 m_pContentEventListeners
->removeInterface( Listener
);
591 ////////////////////////////////////////////////////////////////////////////////
592 // XPropertyContainer
593 ////////////////////////////////////////////////////////////////////////////////
597 BaseContent::addProperty(
598 const rtl::OUString
& Name
,
599 sal_Int16 Attributes
,
600 const Any
& DefaultValue
)
601 throw( beans::PropertyExistException
,
602 beans::IllegalTypeException
,
603 lang::IllegalArgumentException
,
606 if( ( m_nState
& JustInserted
) || ( m_nState
& Deleted
) || Name
.isEmpty() )
608 throw lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>(), 0 );
611 m_pMyShell
->associate( m_aUncPath
,Name
,DefaultValue
,Attributes
);
616 BaseContent::removeProperty(
617 const rtl::OUString
& Name
)
618 throw( beans::UnknownPropertyException
,
619 beans::NotRemoveableException
,
623 if( m_nState
& Deleted
)
624 throw beans::UnknownPropertyException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
626 m_pMyShell
->deassociate( m_aUncPath
, Name
);
629 ////////////////////////////////////////////////////////////////////////////////
631 ////////////////////////////////////////////////////////////////////////////////
633 Sequence
< ContentInfo
> SAL_CALL
634 BaseContent::queryCreatableContentsInfo(
636 throw( RuntimeException
)
638 return m_pMyShell
->queryCreatableContentsInfo();
642 Reference
< XContent
> SAL_CALL
643 BaseContent::createNewContent(
644 const ContentInfo
& Info
)
645 throw( RuntimeException
)
648 if ( Info
.Type
.isEmpty() )
649 return Reference
< XContent
>();
652 = ( Info
.Type
.compareTo( m_pMyShell
->FolderContentType
) == 0 );
655 if ( Info
.Type
.compareTo( m_pMyShell
->FileContentType
) != 0 )
657 // Neither folder nor file to create!
658 return Reference
< XContent
>();
663 sal_Bool IsDocument
= false;
667 Sequence
< beans::Property
> seq(1);
668 seq
[0] = beans::Property( rtl::OUString("IsDocument"),
670 getCppuType( static_cast< sal_Bool
* >(0) ),
672 Reference
< sdbc::XRow
> xRow
= getPropertyValues( -1,seq
);
673 IsDocument
= xRow
->getBoolean( 1 );
675 if ( xRow
->wasNull() )
678 // OSL_FAIL( // "BaseContent::createNewContent - Property value was null!" );
679 // return Reference< XContent >();
682 catch (const sdbc::SQLException
&)
684 OSL_FAIL( "BaseContent::createNewContent - Caught SQLException!" );
685 return Reference
< XContent
>();
688 rtl::OUString dstUncPath
;
692 // KSO: Why is a document a XContentCreator? This is quite unusual.
693 dstUncPath
= getParentName( m_aUncPath
);
696 dstUncPath
= m_aUncPath
;
698 BaseContent
* p
= new BaseContent( m_pMyShell
, dstUncPath
, bFolder
);
699 return Reference
< XContent
>( p
);
703 ////////////////////////////////////////////////////////////////////////////////
704 // XPropertySetInfoChangeNotifier
705 ////////////////////////////////////////////////////////////////////////////////
709 BaseContent::addPropertySetInfoChangeListener(
710 const Reference
< beans::XPropertySetInfoChangeListener
>& Listener
)
711 throw( RuntimeException
)
713 osl::MutexGuard
aGuard( m_aMutex
);
714 if( ! m_pPropertySetInfoChangeListeners
)
715 m_pPropertySetInfoChangeListeners
= new cppu::OInterfaceContainerHelper( m_aEventListenerMutex
);
717 m_pPropertySetInfoChangeListeners
->addInterface( Listener
);
722 BaseContent::removePropertySetInfoChangeListener(
723 const Reference
< beans::XPropertySetInfoChangeListener
>& Listener
)
724 throw( RuntimeException
)
726 osl::MutexGuard
aGuard( m_aMutex
);
728 if( m_pPropertySetInfoChangeListeners
)
729 m_pPropertySetInfoChangeListeners
->removeInterface( Listener
);
733 ////////////////////////////////////////////////////////////////////////////////
735 ////////////////////////////////////////////////////////////////////////////////
737 Reference
< XInterface
> SAL_CALL
738 BaseContent::getParent(
740 throw( RuntimeException
)
742 rtl::OUString ParentUnq
= getParentName( m_aUncPath
);
743 rtl::OUString ParentUrl
;
746 sal_Bool err
= m_pMyShell
->getUrlFromUnq( ParentUnq
, ParentUrl
);
748 return Reference
< XInterface
>( 0 );
750 FileContentIdentifier
* p
= new FileContentIdentifier( m_pMyShell
,ParentUnq
);
751 Reference
< XContentIdentifier
> Identifier( p
);
755 Reference
< XContent
> content
= m_pMyShell
->m_pProvider
->queryContent( Identifier
);
756 return Reference
<XInterface
>(content
,UNO_QUERY
);
758 catch (const IllegalIdentifierException
&)
760 return Reference
< XInterface
>();
766 BaseContent::setParent(
767 const Reference
< XInterface
>& )
768 throw( lang::NoSupportException
,
771 throw lang::NoSupportException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
775 //////////////////////////////////////////////////////////////////////////////////////////
777 //////////////////////////////////////////////////////////////////////////////////////////
780 Reference
< XCommandInfo
> SAL_CALL
781 BaseContent::getCommandInfo()
782 throw( RuntimeException
)
784 if( m_nState
& Deleted
)
785 return Reference
< XCommandInfo
>();
787 return m_pMyShell
->info_c();
791 Reference
< beans::XPropertySetInfo
> SAL_CALL
792 BaseContent::getPropertySetInfo(
794 throw( RuntimeException
)
796 if( m_nState
& Deleted
)
797 return Reference
< beans::XPropertySetInfo
>();
799 return m_pMyShell
->info_p( m_aUncPath
);
805 Reference
< sdbc::XRow
> SAL_CALL
806 BaseContent::getPropertyValues(
807 sal_Int32 nMyCommandIdentifier
,
808 const Sequence
< beans::Property
>& PropertySet
)
809 throw( RuntimeException
)
811 sal_Int32 nProps
= PropertySet
.getLength();
813 return Reference
< sdbc::XRow
>();
815 if( m_nState
& Deleted
)
817 Sequence
< Any
> aValues( nProps
);
818 return Reference
< sdbc::XRow
>( new XRow_impl( m_pMyShell
, aValues
) );
821 if( m_nState
& JustInserted
)
823 Sequence
< Any
> aValues( nProps
);
824 Any
* pValues
= aValues
.getArray();
826 const beans::Property
* pProps
= PropertySet
.getConstArray();
828 for ( sal_Int32 n
= 0; n
< nProps
; ++n
)
830 const beans::Property
& rProp
= pProps
[ n
];
831 Any
& rValue
= pValues
[ n
];
833 if ( rProp
.Name
== "ContentType" )
835 rValue
<<= m_bFolder
? m_pMyShell
->FolderContentType
836 : m_pMyShell
->FileContentType
;
838 else if ( rProp
.Name
== "IsFolder" )
840 rValue
<<= m_bFolder
;
842 else if ( rProp
.Name
== "IsDocument" )
844 rValue
<<= sal_Bool( !m_bFolder
);
848 return Reference
< sdbc::XRow
>(
849 new XRow_impl( m_pMyShell
, aValues
) );
852 return m_pMyShell
->getv( nMyCommandIdentifier
,
858 Sequence
< Any
> SAL_CALL
859 BaseContent::setPropertyValues(
860 sal_Int32 nMyCommandIdentifier
,
861 const Sequence
< beans::PropertyValue
>& Values
)
864 if( m_nState
& Deleted
)
866 return Sequence
< Any
>( Values
.getLength() );
869 const rtl::OUString
Title("Title");
871 // Special handling for files which have to be inserted
872 if( m_nState
& JustInserted
)
874 for( sal_Int32 i
= 0; i
< Values
.getLength(); ++i
)
876 if( Values
[i
].Name
== Title
)
878 rtl::OUString NewTitle
;
879 if( Values
[i
].Value
>>= NewTitle
)
881 if ( m_nState
& NameForInsertionSet
)
883 // User wants to set another Title before "insert".
884 // m_aUncPath contains previous own URI.
886 sal_Int32 nLastSlash
= m_aUncPath
.lastIndexOf( '/' );
887 bool bTrailingSlash
= false;
888 if ( nLastSlash
== m_aUncPath
.getLength() - 1 )
890 bTrailingSlash
= true;
892 = m_aUncPath
.lastIndexOf( '/', nLastSlash
);
895 OSL_ENSURE( nLastSlash
!= -1,
896 "BaseContent::setPropertyValues: "
899 rtl::OUStringBuffer
aBuf(
900 m_aUncPath
.copy( 0, nLastSlash
+ 1 ) );
902 if ( !NewTitle
.isEmpty() )
904 aBuf
.append( NewTitle
);
905 if ( bTrailingSlash
)
906 aBuf
.append( sal_Unicode( '/' ) );
910 m_nState
&= ~NameForInsertionSet
;
913 m_aUncPath
= aBuf
.makeStringAndClear();
917 if ( !NewTitle
.isEmpty() )
919 // Initial Title before "insert".
920 // m_aUncPath contains parent's URI.
922 if( m_aUncPath
.lastIndexOf( sal_Unicode('/') ) != m_aUncPath
.getLength() - 1 )
923 m_aUncPath
+= rtl::OUString("/");
925 m_aUncPath
+= rtl::Uri::encode( NewTitle
,
926 rtl_UriCharClassPchar
,
927 rtl_UriEncodeIgnoreEscapes
,
928 RTL_TEXTENCODING_UTF8
);
929 m_nState
|= NameForInsertionSet
;
936 return Sequence
< Any
>( Values
.getLength() );
940 Sequence
< Any
> ret
= m_pMyShell
->setv( m_aUncPath
, // Does not handle Title
943 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
944 for( sal_Int32 i
= 0; i
< Values
.getLength(); ++i
)
946 if( Values
[i
].Name
!= Title
)
947 continue; // handled by setv
949 rtl::OUString NewTitle
;
950 if( !( Values
[i
].Value
>>= NewTitle
) )
952 ret
[i
] <<= beans::IllegalTypeException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>() );
955 else if( NewTitle
.isEmpty() )
957 ret
[i
] <<= lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX
), uno::Reference
< uno::XInterface
>(), 0 );
962 rtl::OUString aDstName
= getParentName( m_aUncPath
);
963 if( aDstName
.lastIndexOf( sal_Unicode('/') ) != aDstName
.getLength() - 1 )
964 aDstName
+= rtl::OUString("/");
966 aDstName
+= rtl::Uri::encode( NewTitle
,
967 rtl_UriCharClassPchar
,
968 rtl_UriEncodeIgnoreEscapes
,
969 RTL_TEXTENCODING_UTF8
);
971 m_pMyShell
->move( nMyCommandIdentifier
, // move notifies the children also;
978 endTask( nMyCommandIdentifier
);
980 catch(const Exception
& e
)
985 // NameChanges come back trough a ContentEvent
986 break; // only handling Title
995 Reference
< XDynamicResultSet
> SAL_CALL
997 sal_Int32 nMyCommandIdentifier
,
998 const OpenCommandArgument2
& aCommandArgument
)
1001 Reference
< XDynamicResultSet
> retValue( 0 );
1003 if( ( m_nState
& Deleted
) )
1005 m_pMyShell
->installError( nMyCommandIdentifier
,
1006 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND
);
1008 else if( m_nState
& JustInserted
)
1010 m_pMyShell
->installError( nMyCommandIdentifier
,
1011 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND
);
1015 if( aCommandArgument
.Mode
== OpenMode::DOCUMENT
||
1016 aCommandArgument
.Mode
== OpenMode::DOCUMENT_SHARE_DENY_NONE
)
1019 Reference
< io::XOutputStream
> outputStream( aCommandArgument
.Sink
,UNO_QUERY
);
1020 if( outputStream
.is() )
1022 m_pMyShell
->page( nMyCommandIdentifier
,
1027 sal_Bool bLock
= ( aCommandArgument
.Mode
!= OpenMode::DOCUMENT_SHARE_DENY_NONE
);
1029 Reference
< io::XActiveDataSink
> activeDataSink( aCommandArgument
.Sink
,UNO_QUERY
);
1030 if( activeDataSink
.is() )
1032 activeDataSink
->setInputStream( m_pMyShell
->open( nMyCommandIdentifier
,
1037 Reference
< io::XActiveDataStreamer
> activeDataStreamer( aCommandArgument
.Sink
,UNO_QUERY
);
1038 if( activeDataStreamer
.is() )
1040 activeDataStreamer
->setStream( m_pMyShell
->open_rw( nMyCommandIdentifier
,
1045 else if ( aCommandArgument
.Mode
== OpenMode::ALL
||
1046 aCommandArgument
.Mode
== OpenMode::FOLDERS
||
1047 aCommandArgument
.Mode
== OpenMode::DOCUMENTS
)
1049 retValue
= m_pMyShell
->ls( nMyCommandIdentifier
,
1051 aCommandArgument
.Mode
,
1052 aCommandArgument
.Properties
,
1053 aCommandArgument
.SortingInfo
);
1055 // else if( aCommandArgument.Mode ==
1056 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
1057 // aCommandArgument.Mode ==
1058 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1059 // m_pMyShell->installError( nMyCommandIdentifier,
1060 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1061 // aCommandArgument.Mode);
1063 m_pMyShell
->installError( nMyCommandIdentifier
,
1064 TASKHANDLING_UNSUPPORTED_OPEN_MODE
,
1065 aCommandArgument
.Mode
);
1074 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier
)
1077 if( m_nState
& Deleted
)
1080 if( m_pMyShell
->remove( nMyCommandIdentifier
,m_aUncPath
) )
1082 osl::MutexGuard
aGuard( m_aMutex
);
1083 m_nState
|= Deleted
;
1090 BaseContent::transfer( sal_Int32 nMyCommandIdentifier
,
1091 const TransferInfo
& aTransferInfo
)
1094 if( m_nState
& Deleted
)
1097 if( aTransferInfo
.SourceURL
.compareToAscii( "file:",5 ) != 0 )
1099 m_pMyShell
->installError( nMyCommandIdentifier
,
1100 TASKHANDLING_TRANSFER_INVALIDSCHEME
);
1104 rtl::OUString srcUnc
;
1105 if( m_pMyShell
->getUnqFromUrl( aTransferInfo
.SourceURL
,srcUnc
) )
1107 m_pMyShell
->installError( nMyCommandIdentifier
,
1108 TASKHANDLING_TRANSFER_INVALIDURL
);
1112 rtl::OUString srcUncPath
= srcUnc
;
1114 // Determine the new title !
1115 rtl::OUString NewTitle
;
1116 if( !aTransferInfo
.NewTitle
.isEmpty() )
1117 NewTitle
= rtl::Uri::encode( aTransferInfo
.NewTitle
,
1118 rtl_UriCharClassPchar
,
1119 rtl_UriEncodeIgnoreEscapes
,
1120 RTL_TEXTENCODING_UTF8
);
1122 NewTitle
= srcUncPath
.copy( 1 + srcUncPath
.lastIndexOf( sal_Unicode('/') ) );
1124 // Is destination a document or a folder ?
1125 Sequence
< beans::Property
> seq(1);
1126 seq
[0] = beans::Property( rtl::OUString("IsDocument"),
1128 getCppuType( static_cast< sal_Bool
* >(0) ),
1130 Reference
< sdbc::XRow
> xRow
= getPropertyValues( nMyCommandIdentifier
,seq
);
1131 sal_Bool IsDocument
= xRow
->getBoolean( 1 );
1132 if( xRow
->wasNull() )
1133 { // Destination file type could not be determined
1134 m_pMyShell
->installError( nMyCommandIdentifier
,
1135 TASKHANDLING_TRANSFER_DESTFILETYPE
);
1139 rtl::OUString dstUncPath
;
1142 sal_Int32 lastSlash
= m_aUncPath
.lastIndexOf( sal_Unicode('/') );
1143 dstUncPath
= m_aUncPath
.copy(0,lastSlash
);
1147 dstUncPath
= m_aUncPath
;
1149 dstUncPath
+= ( rtl::OUString("/") + NewTitle
);
1151 sal_Int32 NameClash
= aTransferInfo
.NameClash
;
1153 if( aTransferInfo
.MoveData
)
1154 m_pMyShell
->move( nMyCommandIdentifier
,srcUncPath
,dstUncPath
,NameClash
);
1156 m_pMyShell
->copy( nMyCommandIdentifier
,srcUncPath
,dstUncPath
,NameClash
);
1162 void SAL_CALL
BaseContent::insert( sal_Int32 nMyCommandIdentifier
,
1163 const InsertCommandArgument
& aInsertArgument
)
1166 if( m_nState
& FullFeatured
)
1168 m_pMyShell
->write( nMyCommandIdentifier
,
1170 aInsertArgument
.ReplaceExisting
,
1171 aInsertArgument
.Data
);
1175 if( ! ( m_nState
& JustInserted
) )
1177 m_pMyShell
->installError( nMyCommandIdentifier
,
1178 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND
);
1182 // Inserts the content, which has the flag m_bIsFresh
1184 if( ! (m_nState
& NameForInsertionSet
) )
1186 m_pMyShell
->installError( nMyCommandIdentifier
,
1187 TASKHANDLING_NONAMESET_INSERT_COMMAND
);
1191 // Inserting a document or a file?
1192 sal_Bool bDocument
= false;
1194 Sequence
< beans::Property
> seq(1);
1195 seq
[0] = beans::Property( rtl::OUString("IsDocument"),
1197 getCppuType( static_cast< sal_Bool
* >(0) ),
1200 Reference
< sdbc::XRow
> xRow
= getPropertyValues( -1,seq
);
1202 bool contentTypeSet
= true; // is set to false, if contentType not set
1205 bDocument
= xRow
->getBoolean( 1 );
1206 if( xRow
->wasNull() )
1207 contentTypeSet
= false;
1210 catch (const sdbc::SQLException
&)
1212 OSL_FAIL( "BaseContent::insert - Caught SQLException!" );
1213 contentTypeSet
= false;
1216 if( ! contentTypeSet
)
1218 m_pMyShell
->installError( nMyCommandIdentifier
,
1219 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND
);
1224 sal_Bool success
= false;
1226 success
= m_pMyShell
->mkfil( nMyCommandIdentifier
,
1228 aInsertArgument
.ReplaceExisting
,
1229 aInsertArgument
.Data
);
1234 success
= m_pMyShell
->mkdir( nMyCommandIdentifier
,
1236 aInsertArgument
.ReplaceExisting
);
1240 XInteractionRequestImpl
*aRequestImpl
=
1241 new XInteractionRequestImpl(
1243 getTitle(m_aUncPath
),
1244 rtl_UriDecodeWithCharset
,
1245 RTL_TEXTENCODING_UTF8
),
1246 (cppu::OWeakObject
*)this,
1247 m_pMyShell
,nMyCommandIdentifier
);
1248 uno::Reference
< task::XInteractionRequest
> aReq( aRequestImpl
);
1250 m_pMyShell
->handleTask( nMyCommandIdentifier
,aReq
);
1251 if( aRequestImpl
->aborted() ||
1252 aRequestImpl
->newName().isEmpty() )
1256 // determine new uncpath
1257 m_pMyShell
->clearError( nMyCommandIdentifier
);
1258 m_aUncPath
= getParentName( m_aUncPath
);
1259 if( m_aUncPath
.lastIndexOf( sal_Unicode('/') ) != m_aUncPath
.getLength() - 1 )
1260 m_aUncPath
+= rtl::OUString("/");
1262 m_aUncPath
+= rtl::Uri::encode( aRequestImpl
->newName(),
1263 rtl_UriCharClassPchar
,
1264 rtl_UriEncodeIgnoreEscapes
,
1265 RTL_TEXTENCODING_UTF8
);
1272 FileContentIdentifier
* p
= new FileContentIdentifier( m_pMyShell
,m_aUncPath
);
1273 m_xContentIdentifier
= Reference
< XContentIdentifier
>( p
);
1275 m_pMyShell
->registerNotifier( m_aUncPath
,this );
1276 m_pMyShell
->insertDefaultProperties( m_aUncPath
);
1278 osl::MutexGuard
aGuard( m_aMutex
);
1279 m_nState
= FullFeatured
;
1284 void SAL_CALL
BaseContent::endTask( sal_Int32 CommandId
)
1286 // This is the only function allowed to throw an exception
1287 m_pMyShell
->endTask( CommandId
,m_aUncPath
,this );
1292 ContentEventNotifier
*
1293 BaseContent::cDEL( void )
1295 osl::MutexGuard
aGuard( m_aMutex
);
1297 m_nState
|= Deleted
;
1299 ContentEventNotifier
* p
;
1300 if( m_pContentEventListeners
)
1301 p
= new ContentEventNotifier( m_pMyShell
,
1303 m_xContentIdentifier
,
1304 m_pContentEventListeners
->getElements() );
1312 ContentEventNotifier
*
1313 BaseContent::cEXC( const rtl::OUString aNewName
)
1315 osl::MutexGuard
aGuard( m_aMutex
);
1317 Reference
< XContentIdentifier
> xOldRef
= m_xContentIdentifier
;
1318 m_aUncPath
= aNewName
;
1319 FileContentIdentifier
* pp
= new FileContentIdentifier( m_pMyShell
,aNewName
);
1320 m_xContentIdentifier
= Reference
< XContentIdentifier
>( pp
);
1322 ContentEventNotifier
* p
= 0;
1323 if( m_pContentEventListeners
)
1324 p
= new ContentEventNotifier( m_pMyShell
,
1326 m_xContentIdentifier
,
1328 m_pContentEventListeners
->getElements() );
1334 ContentEventNotifier
*
1335 BaseContent::cCEL( void )
1337 osl::MutexGuard
aGuard( m_aMutex
);
1338 ContentEventNotifier
* p
= 0;
1339 if( m_pContentEventListeners
)
1340 p
= new ContentEventNotifier( m_pMyShell
,
1342 m_xContentIdentifier
,
1343 m_pContentEventListeners
->getElements() );
1348 PropertySetInfoChangeNotifier
*
1349 BaseContent::cPSL( void )
1351 osl::MutexGuard
aGuard( m_aMutex
);
1352 PropertySetInfoChangeNotifier
* p
= 0;
1353 if( m_pPropertySetInfoChangeListeners
)
1354 p
= new PropertySetInfoChangeNotifier( m_pMyShell
,
1356 m_xContentIdentifier
,
1357 m_pPropertySetInfoChangeListeners
->getElements() );
1364 PropertyChangeNotifier
*
1365 BaseContent::cPCL( void )
1367 osl::MutexGuard
aGuard( m_aMutex
);
1369 Sequence
< rtl::OUString
> seqNames
;
1371 if( m_pPropertyListener
)
1372 seqNames
= m_pPropertyListener
->getContainedTypes();
1374 PropertyChangeNotifier
* p
= 0;
1376 sal_Int32 length
= seqNames
.getLength();
1380 ListenerMap
* listener
= new ListenerMap();
1381 for( sal_Int32 i
= 0; i
< length
; ++i
)
1383 (*listener
)[seqNames
[i
]] = m_pPropertyListener
->getContainer( seqNames
[i
] )->getElements();
1386 p
= new PropertyChangeNotifier( m_pMyShell
,
1388 m_xContentIdentifier
,
1396 rtl::OUString
BaseContent::getKey( void )
1401 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */