bump product version to 7.2.5.1
[LibreOffice.git] / ucb / source / ucp / file / bc.cxx
blob07c3d846a35f0237f9694dedaaf4d989d3a8672e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <rtl/uri.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include <rtl/ref.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <com/sun/star/lang/NoSupportException.hpp>
26 #include <com/sun/star/sdbc/SQLException.hpp>
27 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
28 #include <com/sun/star/ucb/OpenMode.hpp>
29 #include <com/sun/star/beans/IllegalTypeException.hpp>
30 #include <com/sun/star/io/XActiveDataStreamer.hpp>
31 #include <com/sun/star/io/XOutputStream.hpp>
32 #include <com/sun/star/io/XActiveDataSink.hpp>
33 #include <com/sun/star/ucb/NameClash.hpp>
34 #include <comphelper/fileurl.hxx>
35 #include <cppuhelper/interfacecontainer.hxx>
36 #include <cppuhelper/supportsservice.hxx>
37 #include "filglob.hxx"
38 #include "filid.hxx"
39 #include "filrow.hxx"
40 #include "bc.hxx"
41 #include "prov.hxx"
42 #include "filerror.hxx"
43 #include "filinsreq.hxx"
45 using namespace fileaccess;
46 using namespace com::sun::star;
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::ucb;
50 #if OSL_DEBUG_LEVEL > 0
51 #define THROW_WHERE SAL_WHERE
52 #else
53 #define THROW_WHERE ""
54 #endif
56 typedef cppu::OMultiTypeInterfaceContainerHelperVar<OUString>
57 PropertyListeners_impl;
59 class fileaccess::PropertyListeners
60 : public PropertyListeners_impl
62 public:
63 explicit PropertyListeners( ::osl::Mutex& aMutex )
64 : PropertyListeners_impl( aMutex )
70 /****************************************************************************************/
71 /* */
72 /* BaseContent */
73 /* */
74 /****************************************************************************************/
77 // Private Constructor for just inserted Contents
79 BaseContent::BaseContent( TaskManager* pMyShell,
80 const OUString& parentName,
81 bool bFolder )
82 : m_pMyShell( pMyShell ),
83 m_aUncPath( parentName ),
84 m_bFolder( bFolder ),
85 m_nState( JustInserted )
87 m_pMyShell->m_pProvider->acquire();
88 // No registering, since we have no name
92 // Constructor for full featured Contents
94 BaseContent::BaseContent( TaskManager* pMyShell,
95 const Reference< XContentIdentifier >& xContentIdentifier,
96 const OUString& aUncPath )
97 : m_pMyShell( pMyShell ),
98 m_xContentIdentifier( xContentIdentifier ),
99 m_aUncPath( aUncPath ),
100 m_bFolder( false ),
101 m_nState( FullFeatured )
103 m_pMyShell->m_pProvider->acquire();
104 m_pMyShell->registerNotifier( m_aUncPath,this );
105 m_pMyShell->insertDefaultProperties( m_aUncPath );
109 BaseContent::~BaseContent( )
111 if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
113 m_pMyShell->deregisterNotifier( m_aUncPath,this );
115 m_pMyShell->m_pProvider->release();
119 // XComponent
122 void SAL_CALL
123 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
125 osl::MutexGuard aGuard( m_aMutex );
127 if ( ! m_pDisposeEventListeners )
128 m_pDisposeEventListeners.reset(
129 new comphelper::OInterfaceContainerHelper2( m_aEventListenerMutex ) );
131 m_pDisposeEventListeners->addInterface( Listener );
135 void SAL_CALL
136 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
138 osl::MutexGuard aGuard( m_aMutex );
140 if ( m_pDisposeEventListeners )
141 m_pDisposeEventListeners->removeInterface( Listener );
145 void SAL_CALL
146 BaseContent::dispose()
148 lang::EventObject aEvt;
149 std::unique_ptr<comphelper::OInterfaceContainerHelper2> pDisposeEventListeners;
150 std::unique_ptr<comphelper::OInterfaceContainerHelper2> pContentEventListeners;
151 std::unique_ptr<comphelper::OInterfaceContainerHelper2> pPropertySetInfoChangeListeners;
152 std::unique_ptr<PropertyListeners> pPropertyListener;
155 osl::MutexGuard aGuard( m_aMutex );
156 aEvt.Source = static_cast< XContent* >( this );
158 pDisposeEventListeners = std::move(m_pDisposeEventListeners);
159 pContentEventListeners = std::move(m_pContentEventListeners);
160 pPropertySetInfoChangeListeners = std::move(m_pPropertySetInfoChangeListeners);
161 pPropertyListener = std::move(m_pPropertyListener);
164 if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
165 pDisposeEventListeners->disposeAndClear( aEvt );
167 if ( pContentEventListeners && pContentEventListeners->getLength() )
168 pContentEventListeners->disposeAndClear( aEvt );
170 if( pPropertyListener )
171 pPropertyListener->disposeAndClear( aEvt );
173 if( pPropertySetInfoChangeListeners )
174 pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
177 // XServiceInfo
178 OUString SAL_CALL
179 BaseContent::getImplementationName()
181 return "com.sun.star.comp.ucb.FileContent";
184 sal_Bool SAL_CALL
185 BaseContent::supportsService( const OUString& ServiceName )
187 return cppu::supportsService( this, ServiceName );
190 Sequence< OUString > SAL_CALL
191 BaseContent::getSupportedServiceNames()
193 Sequence<OUString> ret { "com.sun.star.ucb.FileContent" };
194 return ret;
197 // XCommandProcessor
200 sal_Int32 SAL_CALL
201 BaseContent::createCommandIdentifier()
203 return m_pMyShell->getCommandId();
207 void SAL_CALL
208 BaseContent::abort( sal_Int32 /*CommandId*/ )
213 Any SAL_CALL
214 BaseContent::execute( const Command& aCommand,
215 sal_Int32 CommandId,
216 const Reference< XCommandEnvironment >& Environment )
218 if( ! CommandId )
219 // A Command with commandid zero cannot be aborted
220 CommandId = createCommandIdentifier();
222 m_pMyShell->startTask( CommandId,
223 Environment );
225 Any aAny;
227 if (aCommand.Name == "getPropertySetInfo") // No exceptions
229 aAny <<= getPropertySetInfo();
231 else if (aCommand.Name == "getCommandInfo") // no exceptions
233 aAny <<= getCommandInfo();
235 else if ( aCommand.Name == "setPropertyValues" )
237 Sequence< beans::PropertyValue > sPropertyValues;
239 if( ! ( aCommand.Argument >>= sPropertyValues ) )
240 m_pMyShell->installError( CommandId,
241 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
242 else
243 aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
245 else if ( aCommand.Name == "getPropertyValues" )
247 Sequence< beans::Property > ListOfRequestedProperties;
249 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
250 m_pMyShell->installError( CommandId,
251 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
252 else
253 aAny <<= getPropertyValues( CommandId,
254 ListOfRequestedProperties );
256 else if ( aCommand.Name == "open" )
258 OpenCommandArgument2 aOpenArgument;
259 if( ! ( aCommand.Argument >>= aOpenArgument ) )
260 m_pMyShell->installError( CommandId,
261 TASKHANDLING_WRONG_OPEN_ARGUMENT );
262 else
264 Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
265 if( result.is() )
266 aAny <<= result;
269 else if ( aCommand.Name == "delete" )
271 if( ! aCommand.Argument.has< bool >() )
272 m_pMyShell->installError( CommandId,
273 TASKHANDLING_WRONG_DELETE_ARGUMENT );
274 else
275 deleteContent( CommandId );
277 else if ( aCommand.Name == "transfer" )
279 TransferInfo aTransferInfo;
280 if( ! ( aCommand.Argument >>= aTransferInfo ) )
281 m_pMyShell->installError( CommandId,
282 TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
283 else
284 transfer( CommandId, aTransferInfo );
286 else if ( aCommand.Name == "insert" )
288 InsertCommandArgument aInsertArgument;
289 if( ! ( aCommand.Argument >>= aInsertArgument ) )
290 m_pMyShell->installError( CommandId,
291 TASKHANDLING_WRONG_INSERT_ARGUMENT );
292 else
293 insert( CommandId,aInsertArgument );
295 else if ( aCommand.Name == "getCasePreservingURL" )
297 Reference< sdbc::XRow > xRow = getPropertyValues( CommandId, { { "CasePreservingURL", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
298 OUString CasePreservingURL = xRow->getString(1);
299 if(!xRow->wasNull())
300 aAny <<= CasePreservingURL;
302 else if ( aCommand.Name == "createNewContent" )
304 ucb::ContentInfo aArg;
305 if ( !( aCommand.Argument >>= aArg ) )
306 m_pMyShell->installError( CommandId,
307 TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
308 else
309 aAny <<= createNewContent( aArg );
311 else
312 m_pMyShell->installError( CommandId,
313 TASKHANDLER_UNSUPPORTED_COMMAND );
316 // This is the only function allowed to throw an exception
317 endTask( CommandId );
319 return aAny;
323 void SAL_CALL
324 BaseContent::addPropertiesChangeListener(
325 const Sequence< OUString >& PropertyNames,
326 const Reference< beans::XPropertiesChangeListener >& Listener )
328 if( ! Listener.is() )
329 return;
331 osl::MutexGuard aGuard( m_aMutex );
333 if( ! m_pPropertyListener )
334 m_pPropertyListener.reset( new PropertyListeners( m_aEventListenerMutex ) );
337 if( !PropertyNames.hasElements() )
338 m_pPropertyListener->addInterface( OUString(),Listener );
339 else
341 Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
342 for( const auto& rName : PropertyNames )
343 if( xProp->hasPropertyByName( rName ) )
344 m_pPropertyListener->addInterface( rName,Listener );
349 void SAL_CALL
350 BaseContent::removePropertiesChangeListener( const Sequence< OUString >& PropertyNames,
351 const Reference< beans::XPropertiesChangeListener >& Listener )
353 if( ! Listener.is() )
354 return;
356 osl::MutexGuard aGuard( m_aMutex );
358 if( ! m_pPropertyListener )
359 return;
361 for( const auto& rName : PropertyNames )
362 m_pPropertyListener->removeInterface( rName,Listener );
364 m_pPropertyListener->removeInterface( OUString(), Listener );
368 // XContent
371 Reference< ucb::XContentIdentifier > SAL_CALL
372 BaseContent::getIdentifier()
374 return m_xContentIdentifier;
378 OUString SAL_CALL
379 BaseContent::getContentType()
381 if( !( m_nState & Deleted ) )
383 if( m_nState & JustInserted )
385 if ( m_bFolder )
386 return TaskManager::FolderContentType;
387 else
388 return TaskManager::FileContentType;
390 else
394 // Who am I ?
395 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
396 bool IsDocument = xRow->getBoolean( 1 );
398 if ( !xRow->wasNull() )
400 if ( IsDocument )
401 return TaskManager::FileContentType;
402 else
403 return TaskManager::FolderContentType;
405 else
407 OSL_FAIL( "BaseContent::getContentType - Property value was null!" );
410 catch (const sdbc::SQLException&)
412 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
417 return OUString();
421 void SAL_CALL
422 BaseContent::addContentEventListener(
423 const Reference< XContentEventListener >& Listener )
425 osl::MutexGuard aGuard( m_aMutex );
427 if ( ! m_pContentEventListeners )
428 m_pContentEventListeners.reset(
429 new comphelper::OInterfaceContainerHelper2( m_aEventListenerMutex ) );
432 m_pContentEventListeners->addInterface( Listener );
436 void SAL_CALL
437 BaseContent::removeContentEventListener(
438 const Reference< XContentEventListener >& Listener )
440 osl::MutexGuard aGuard( m_aMutex );
442 if ( m_pContentEventListeners )
443 m_pContentEventListeners->removeInterface( Listener );
447 // XPropertyContainer
450 void SAL_CALL
451 BaseContent::addProperty(
452 const OUString& Name,
453 sal_Int16 Attributes,
454 const Any& DefaultValue )
456 if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name.isEmpty() )
458 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
461 m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
465 void SAL_CALL
466 BaseContent::removeProperty( const OUString& Name )
469 if( m_nState & Deleted )
470 throw beans::UnknownPropertyException( Name );
472 m_pMyShell->deassociate( m_aUncPath, Name );
476 // XContentCreator
479 Sequence< ContentInfo > SAL_CALL
480 BaseContent::queryCreatableContentsInfo()
482 return TaskManager::queryCreatableContentsInfo();
486 Reference< XContent > SAL_CALL
487 BaseContent::createNewContent( const ContentInfo& Info )
489 // Check type.
490 if ( Info.Type.isEmpty() )
491 return Reference< XContent >();
493 bool bFolder = Info.Type == TaskManager::FolderContentType;
494 if ( !bFolder )
496 if ( Info.Type != TaskManager::FileContentType )
498 // Neither folder nor file to create!
499 return Reference< XContent >();
503 // Who am I ?
504 bool IsDocument = false;
508 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
509 IsDocument = xRow->getBoolean( 1 );
511 if ( xRow->wasNull() )
513 IsDocument = false;
514 // OSL_FAIL( // "BaseContent::createNewContent - Property value was null!" );
515 // return Reference< XContent >();
518 catch (const sdbc::SQLException&)
520 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
521 return Reference< XContent >();
524 OUString dstUncPath;
526 if( IsDocument )
528 // KSO: Why is a document a XContentCreator? This is quite unusual.
529 dstUncPath = getParentName( m_aUncPath );
531 else
532 dstUncPath = m_aUncPath;
534 return new BaseContent( m_pMyShell, dstUncPath, bFolder );
538 // XPropertySetInfoChangeNotifier
541 void SAL_CALL
542 BaseContent::addPropertySetInfoChangeListener(
543 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
545 osl::MutexGuard aGuard( m_aMutex );
546 if( ! m_pPropertySetInfoChangeListeners )
547 m_pPropertySetInfoChangeListeners.reset( new comphelper::OInterfaceContainerHelper2( m_aEventListenerMutex ) );
549 m_pPropertySetInfoChangeListeners->addInterface( Listener );
553 void SAL_CALL
554 BaseContent::removePropertySetInfoChangeListener(
555 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
557 osl::MutexGuard aGuard( m_aMutex );
559 if( m_pPropertySetInfoChangeListeners )
560 m_pPropertySetInfoChangeListeners->removeInterface( Listener );
564 // XChild
567 Reference< XInterface > SAL_CALL
568 BaseContent::getParent()
570 OUString ParentUnq = getParentName( m_aUncPath );
571 OUString ParentUrl;
574 bool err = fileaccess::TaskManager::getUrlFromUnq( ParentUnq, ParentUrl );
575 if( err )
576 return Reference< XInterface >( nullptr );
578 rtl::Reference<FileContentIdentifier> Identifier = new FileContentIdentifier( ParentUnq );
582 return Reference<XInterface>( m_pMyShell->m_pProvider->queryContent( Identifier ), UNO_QUERY );
584 catch (const IllegalIdentifierException&)
586 return Reference< XInterface >();
591 void SAL_CALL
592 BaseContent::setParent(
593 const Reference< XInterface >& )
595 throw lang::NoSupportException( THROW_WHERE );
599 // Private Methods
602 Reference< XCommandInfo >
603 BaseContent::getCommandInfo()
605 if( m_nState & Deleted )
606 return Reference< XCommandInfo >();
608 return m_pMyShell->info_c();
612 Reference< beans::XPropertySetInfo >
613 BaseContent::getPropertySetInfo()
615 if( m_nState & Deleted )
616 return Reference< beans::XPropertySetInfo >();
618 return m_pMyShell->info_p( m_aUncPath );
621 Reference< sdbc::XRow >
622 BaseContent::getPropertyValues(
623 sal_Int32 nMyCommandIdentifier,
624 const Sequence< beans::Property >& PropertySet )
626 sal_Int32 nProps = PropertySet.getLength();
627 if ( !nProps )
628 return Reference< sdbc::XRow >();
630 if( m_nState & Deleted )
632 Sequence< Any > aValues( nProps );
633 return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
636 if( m_nState & JustInserted )
638 Sequence< Any > aValues( nProps );
639 Any* pValues = aValues.getArray();
641 const beans::Property* pProps = PropertySet.getConstArray();
643 for ( sal_Int32 n = 0; n < nProps; ++n )
645 const beans::Property& rProp = pProps[ n ];
646 Any& rValue = pValues[ n ];
648 if ( rProp.Name == "ContentType" )
650 rValue <<= (m_bFolder ? OUString(TaskManager::FolderContentType)
651 : OUString(TaskManager::FileContentType));
653 else if ( rProp.Name == "IsFolder" )
655 rValue <<= m_bFolder;
657 else if ( rProp.Name == "IsDocument" )
659 rValue <<= !m_bFolder;
663 return Reference< sdbc::XRow >(
664 new XRow_impl( m_pMyShell, aValues ) );
667 return m_pMyShell->getv( nMyCommandIdentifier,
668 m_aUncPath,
669 PropertySet );
673 Sequence< Any >
674 BaseContent::setPropertyValues(
675 sal_Int32 nMyCommandIdentifier,
676 const Sequence< beans::PropertyValue >& Values )
678 if( m_nState & Deleted )
679 { // To do
680 return Sequence< Any >( Values.getLength() );
683 static const OUStringLiteral Title(u"Title");
685 // Special handling for files which have to be inserted
686 if( m_nState & JustInserted )
688 for( const auto& rValue : Values )
690 if( rValue.Name == Title )
692 OUString NewTitle;
693 if( rValue.Value >>= NewTitle )
695 if ( m_nState & NameForInsertionSet )
697 // User wants to set another Title before "insert".
698 // m_aUncPath contains previous own URI.
700 sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
701 bool bTrailingSlash = false;
702 if ( nLastSlash == m_aUncPath.getLength() - 1 )
704 bTrailingSlash = true;
705 nLastSlash
706 = m_aUncPath.lastIndexOf( '/', nLastSlash );
709 OSL_ENSURE( nLastSlash != -1,
710 "BaseContent::setPropertyValues: "
711 "Invalid URL!" );
713 OUStringBuffer aBuf(
714 m_aUncPath.subView( 0, nLastSlash + 1 ) );
716 if ( !NewTitle.isEmpty() )
718 aBuf.append( NewTitle );
719 if ( bTrailingSlash )
720 aBuf.append( '/' );
722 else
724 m_nState &= ~NameForInsertionSet;
727 m_aUncPath = aBuf.makeStringAndClear();
729 else
731 if ( !NewTitle.isEmpty() )
733 // Initial Title before "insert".
734 // m_aUncPath contains parent's URI.
736 if( !m_aUncPath.endsWith( "/" ) )
737 m_aUncPath += "/";
739 m_aUncPath += rtl::Uri::encode( NewTitle,
740 rtl_UriCharClassPchar,
741 rtl_UriEncodeIgnoreEscapes,
742 RTL_TEXTENCODING_UTF8 );
743 m_nState |= NameForInsertionSet;
750 return Sequence< Any >( Values.getLength() );
752 else
754 Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
755 Values );
757 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
758 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
760 if( Values[i].Name != Title )
761 continue; // handled by setv
763 OUString NewTitle;
764 if( !( Values[i].Value >>= NewTitle ) )
766 ret[i] <<= beans::IllegalTypeException( THROW_WHERE );
767 break;
769 else if( NewTitle.isEmpty() )
771 ret[i] <<= lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
772 break;
776 OUString aDstName = getParentName( m_aUncPath );
777 if( !aDstName.endsWith("/") )
778 aDstName += "/";
780 aDstName += rtl::Uri::encode( NewTitle,
781 rtl_UriCharClassPchar,
782 rtl_UriEncodeIgnoreEscapes,
783 RTL_TEXTENCODING_UTF8 );
785 m_pMyShell->move( nMyCommandIdentifier, // move notifies the children also;
786 m_aUncPath,
787 aDstName,
788 NameClash::KEEP );
792 endTask( nMyCommandIdentifier );
794 catch(const Exception& e)
796 ret[i] <<= e;
799 // NameChanges come back through a ContentEvent
800 break; // only handling Title
801 } // end for
803 return ret;
808 Reference< XDynamicResultSet >
809 BaseContent::open(
810 sal_Int32 nMyCommandIdentifier,
811 const OpenCommandArgument2& aCommandArgument )
813 Reference< XDynamicResultSet > retValue;
815 if( m_nState & Deleted )
817 m_pMyShell->installError( nMyCommandIdentifier,
818 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
820 else if( m_nState & JustInserted )
822 m_pMyShell->installError( nMyCommandIdentifier,
823 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
825 else
827 if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
828 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
831 Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
832 if( outputStream.is() )
834 m_pMyShell->page( nMyCommandIdentifier,
835 m_aUncPath,
836 outputStream );
839 bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
841 Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
842 if( activeDataSink.is() )
844 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
845 m_aUncPath,
846 bLock ) );
849 Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
850 if( activeDataStreamer.is() )
852 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
853 m_aUncPath,
854 bLock ) );
857 else if ( aCommandArgument.Mode == OpenMode::ALL ||
858 aCommandArgument.Mode == OpenMode::FOLDERS ||
859 aCommandArgument.Mode == OpenMode::DOCUMENTS )
861 retValue = m_pMyShell->ls( nMyCommandIdentifier,
862 m_aUncPath,
863 aCommandArgument.Mode,
864 aCommandArgument.Properties,
865 aCommandArgument.SortingInfo );
867 // else if( aCommandArgument.Mode ==
868 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
869 // aCommandArgument.Mode ==
870 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
871 // m_pMyShell->installError( nMyCommandIdentifier,
872 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
873 // aCommandArgument.Mode);
874 else
875 m_pMyShell->installError( nMyCommandIdentifier,
876 TASKHANDLING_UNSUPPORTED_OPEN_MODE,
877 aCommandArgument.Mode);
880 return retValue;
884 void
885 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
887 if( m_nState & Deleted )
888 return;
890 if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
892 osl::MutexGuard aGuard( m_aMutex );
893 m_nState |= Deleted;
898 void
899 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
900 const TransferInfo& aTransferInfo )
902 if( m_nState & Deleted )
903 return;
905 if( !comphelper::isFileUrl(aTransferInfo.SourceURL) )
907 m_pMyShell->installError( nMyCommandIdentifier,
908 TASKHANDLING_TRANSFER_INVALIDSCHEME );
909 return;
912 OUString srcUnc;
913 if( fileaccess::TaskManager::getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
915 m_pMyShell->installError( nMyCommandIdentifier,
916 TASKHANDLING_TRANSFER_INVALIDURL );
917 return;
920 OUString srcUncPath = srcUnc;
922 // Determine the new title !
923 OUString NewTitle;
924 if( !aTransferInfo.NewTitle.isEmpty() )
925 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
926 rtl_UriCharClassPchar,
927 rtl_UriEncodeIgnoreEscapes,
928 RTL_TEXTENCODING_UTF8 );
929 else
930 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( '/' ) );
932 // Is destination a document or a folder ?
933 Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,{ { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } } );
934 bool IsDocument = xRow->getBoolean( 1 );
935 if( xRow->wasNull() )
936 { // Destination file type could not be determined
937 m_pMyShell->installError( nMyCommandIdentifier,
938 TASKHANDLING_TRANSFER_DESTFILETYPE );
939 return;
942 OUString dstUncPath;
943 if( IsDocument )
944 { // as sibling
945 sal_Int32 lastSlash = m_aUncPath.lastIndexOf( '/' );
946 dstUncPath = m_aUncPath.copy(0,lastSlash );
948 else
949 // as child
950 dstUncPath = m_aUncPath;
952 dstUncPath += "/" + NewTitle;
954 sal_Int32 NameClash = aTransferInfo.NameClash;
956 if( aTransferInfo.MoveData )
957 m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
958 else
959 m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
963 void BaseContent::insert( sal_Int32 nMyCommandIdentifier,
964 const InsertCommandArgument& aInsertArgument )
966 if( m_nState & FullFeatured )
968 m_pMyShell->write( nMyCommandIdentifier,
969 m_aUncPath,
970 aInsertArgument.ReplaceExisting,
971 aInsertArgument.Data );
972 return;
975 if( ! ( m_nState & JustInserted ) )
977 m_pMyShell->installError( nMyCommandIdentifier,
978 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
979 return;
982 // Inserts the content, which has the flag m_bIsFresh
984 if( ! (m_nState & NameForInsertionSet) )
986 m_pMyShell->installError( nMyCommandIdentifier,
987 TASKHANDLING_NONAMESET_INSERT_COMMAND );
988 return;
991 // Inserting a document or a file?
992 bool bDocument = false;
994 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
996 bool contentTypeSet = true; // is set to false, if contentType not set
999 bDocument = xRow->getBoolean( 1 );
1000 if( xRow->wasNull() )
1001 contentTypeSet = false;
1004 catch (const sdbc::SQLException&)
1006 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
1007 contentTypeSet = false;
1010 if( ! contentTypeSet )
1012 m_pMyShell->installError( nMyCommandIdentifier,
1013 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1014 return;
1018 bool success = false;
1019 if( bDocument )
1020 success = m_pMyShell->mkfil( nMyCommandIdentifier,
1021 m_aUncPath,
1022 aInsertArgument.ReplaceExisting,
1023 aInsertArgument.Data );
1024 else
1026 while( ! success )
1028 success = m_pMyShell->mkdir( nMyCommandIdentifier,
1029 m_aUncPath,
1030 aInsertArgument.ReplaceExisting );
1031 if( success )
1032 break;
1034 XInteractionRequestImpl aRequestImpl(
1035 rtl::Uri::decode(
1036 getTitle(m_aUncPath),
1037 rtl_UriDecodeWithCharset,
1038 RTL_TEXTENCODING_UTF8),
1039 static_cast<cppu::OWeakObject*>(this),
1040 m_pMyShell,nMyCommandIdentifier);
1041 uno::Reference<task::XInteractionRequest> const& xReq(aRequestImpl.getRequest());
1043 m_pMyShell->handleTask( nMyCommandIdentifier, xReq );
1044 if (aRequestImpl.aborted() || aRequestImpl.newName().isEmpty())
1045 // means aborting
1046 break;
1048 // determine new uncpath
1049 m_pMyShell->clearError( nMyCommandIdentifier );
1050 m_aUncPath = getParentName( m_aUncPath );
1051 if( !m_aUncPath.endsWith( "/" ) )
1052 m_aUncPath += "/";
1054 m_aUncPath += rtl::Uri::encode( aRequestImpl.newName(),
1055 rtl_UriCharClassPchar,
1056 rtl_UriEncodeIgnoreEscapes,
1057 RTL_TEXTENCODING_UTF8 );
1061 if ( ! success )
1062 return;
1064 m_xContentIdentifier.set( new FileContentIdentifier( m_aUncPath ) );
1066 m_pMyShell->registerNotifier( m_aUncPath,this );
1067 m_pMyShell->insertDefaultProperties( m_aUncPath );
1069 osl::MutexGuard aGuard( m_aMutex );
1070 m_nState = FullFeatured;
1074 void BaseContent::endTask( sal_Int32 CommandId )
1076 // This is the only function allowed to throw an exception
1077 m_pMyShell->endTask( CommandId,m_aUncPath,this );
1081 std::unique_ptr<ContentEventNotifier>
1082 BaseContent::cDEL()
1084 osl::MutexGuard aGuard( m_aMutex );
1086 m_nState |= Deleted;
1088 std::unique_ptr<ContentEventNotifier> p;
1089 if( m_pContentEventListeners )
1091 p.reset( new ContentEventNotifier( m_pMyShell,
1092 this,
1093 m_xContentIdentifier,
1094 m_pContentEventListeners->getElements() ) );
1097 return p;
1101 std::unique_ptr<ContentEventNotifier>
1102 BaseContent::cEXC( const OUString& aNewName )
1104 osl::MutexGuard aGuard( m_aMutex );
1106 Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1107 m_aUncPath = aNewName;
1108 m_xContentIdentifier = new FileContentIdentifier( aNewName );
1110 std::unique_ptr<ContentEventNotifier> p;
1111 if( m_pContentEventListeners )
1112 p.reset( new ContentEventNotifier( m_pMyShell,
1113 this,
1114 m_xContentIdentifier,
1115 xOldRef,
1116 m_pContentEventListeners->getElements() ) );
1118 return p;
1122 std::unique_ptr<ContentEventNotifier>
1123 BaseContent::cCEL()
1125 osl::MutexGuard aGuard( m_aMutex );
1126 std::unique_ptr<ContentEventNotifier> p;
1127 if( m_pContentEventListeners )
1128 p.reset( new ContentEventNotifier( m_pMyShell,
1129 this,
1130 m_xContentIdentifier,
1131 m_pContentEventListeners->getElements() ) );
1133 return p;
1136 std::unique_ptr<PropertySetInfoChangeNotifier>
1137 BaseContent::cPSL()
1139 osl::MutexGuard aGuard( m_aMutex );
1140 std::unique_ptr<PropertySetInfoChangeNotifier> p;
1141 if( m_pPropertySetInfoChangeListeners )
1142 p.reset( new PropertySetInfoChangeNotifier( this,
1143 m_pPropertySetInfoChangeListeners->getElements() ) );
1145 return p;
1149 std::unique_ptr<PropertyChangeNotifier>
1150 BaseContent::cPCL()
1152 osl::MutexGuard aGuard( m_aMutex );
1154 if (!m_pPropertyListener)
1155 return nullptr;
1157 const Sequence< OUString > seqNames = m_pPropertyListener->getContainedTypes();
1159 std::unique_ptr<PropertyChangeNotifier> p;
1161 if( seqNames.hasElements() )
1163 ListenerMap listener;
1164 for( const auto& rName : seqNames )
1166 cppu::OInterfaceContainerHelper* pContainer = m_pPropertyListener->getContainer(rName);
1167 if (!pContainer)
1168 continue;
1169 listener[rName] = pContainer->getElements();
1172 p.reset( new PropertyChangeNotifier( this, std::move(listener) ) );
1175 return p;
1179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */