Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / ucb / source / ucp / file / bc.cxx
blob9b061869033120ffc79f9b9670eb69b50db50af0
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 <comphelper/diagnose_ex.hxx>
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/supportsservice.hxx>
36 #include <utility>
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 class fileaccess::PropertyListeners
58 typedef comphelper::OInterfaceContainerHelper4<beans::XPropertiesChangeListener> ContainerHelper;
59 std::unordered_map<OUString, ContainerHelper> m_aMap;
61 public:
62 void disposeAndClear(std::unique_lock<std::mutex>& rGuard, const lang::EventObject& rEvt)
64 // create a copy, because do not fire event in a guarded section
65 std::unordered_map<OUString, ContainerHelper> tempMap = std::move(m_aMap);
66 for (auto& rPair : tempMap)
67 rPair.second.disposeAndClear(rGuard, rEvt);
69 void addInterface(std::unique_lock<std::mutex>& rGuard, const OUString& rKey, const uno::Reference<beans::XPropertiesChangeListener>& rListener)
71 m_aMap[rKey].addInterface(rGuard, rListener);
73 void removeInterface(std::unique_lock<std::mutex>& rGuard, const OUString& rKey, const uno::Reference<beans::XPropertiesChangeListener>& rListener)
75 // search container with id rKey
76 auto iter = m_aMap.find(rKey);
77 // container found?
78 if (iter != m_aMap.end())
79 iter->second.removeInterface(rGuard, rListener);
81 std::vector< OUString > getContainedTypes(std::unique_lock<std::mutex>& rGuard) const
83 std::vector<OUString> aInterfaceTypes;
84 aInterfaceTypes.reserve(m_aMap.size());
85 for (const auto& rPair : m_aMap)
86 // are interfaces added to this container?
87 if (rPair.second.getLength(rGuard))
88 // yes, put the type in the array
89 aInterfaceTypes.push_back(rPair.first);
90 return aInterfaceTypes;
92 comphelper::OInterfaceContainerHelper4<beans::XPropertiesChangeListener>* getContainer(std::unique_lock<std::mutex>& , const OUString& rKey)
94 auto iter = m_aMap.find(rKey);
95 if (iter != m_aMap.end())
96 return &iter->second;
97 return nullptr;
102 /****************************************************************************************/
103 /* */
104 /* BaseContent */
105 /* */
106 /****************************************************************************************/
109 // Private Constructor for just inserted Contents
111 BaseContent::BaseContent( TaskManager* pMyShell,
112 OUString parentName,
113 bool bFolder )
114 : m_pMyShell( pMyShell ),
115 m_aUncPath(std::move( parentName )),
116 m_bFolder( bFolder ),
117 m_nState( JustInserted )
119 m_pMyShell->m_pProvider->acquire();
120 // No registering, since we have no name
124 // Constructor for full featured Contents
126 BaseContent::BaseContent( TaskManager* pMyShell,
127 const Reference< XContentIdentifier >& xContentIdentifier,
128 OUString aUncPath )
129 : m_pMyShell( pMyShell ),
130 m_xContentIdentifier( xContentIdentifier ),
131 m_aUncPath(std::move( aUncPath )),
132 m_bFolder( false ),
133 m_nState( FullFeatured )
135 m_pMyShell->m_pProvider->acquire();
136 m_pMyShell->registerNotifier( m_aUncPath,this );
137 m_pMyShell->insertDefaultProperties( m_aUncPath );
141 BaseContent::~BaseContent( )
143 if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
145 m_pMyShell->deregisterNotifier( m_aUncPath,this );
147 m_pMyShell->m_pProvider->release();
151 // XComponent
154 void SAL_CALL
155 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
157 std::unique_lock aGuard( m_aMutex );
159 m_aDisposeEventListeners.addInterface( aGuard, Listener );
163 void SAL_CALL
164 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
166 std::unique_lock aGuard( m_aMutex );
168 m_aDisposeEventListeners.removeInterface( aGuard, Listener );
172 void SAL_CALL
173 BaseContent::dispose()
175 lang::EventObject aEvt;
176 aEvt.Source = static_cast< XContent* >( this );
178 std::unique_lock aGuard( m_aMutex );
180 std::unique_ptr<PropertyListeners> pPropertyListener = std::move(m_pPropertyListener);
182 m_aDisposeEventListeners.disposeAndClear( aGuard, aEvt );
183 m_aContentEventListeners.disposeAndClear( aGuard, aEvt );
185 if( pPropertyListener )
186 pPropertyListener->disposeAndClear( aGuard, aEvt );
188 m_aPropertySetInfoChangeListeners.disposeAndClear( aGuard, aEvt );
191 // XServiceInfo
192 OUString SAL_CALL
193 BaseContent::getImplementationName()
195 return "com.sun.star.comp.ucb.FileContent";
198 sal_Bool SAL_CALL
199 BaseContent::supportsService( const OUString& ServiceName )
201 return cppu::supportsService( this, ServiceName );
204 Sequence< OUString > SAL_CALL
205 BaseContent::getSupportedServiceNames()
207 Sequence<OUString> ret { "com.sun.star.ucb.FileContent" };
208 return ret;
211 // XCommandProcessor
214 sal_Int32 SAL_CALL
215 BaseContent::createCommandIdentifier()
217 return m_pMyShell->getCommandId();
221 void SAL_CALL
222 BaseContent::abort( sal_Int32 /*CommandId*/ )
227 Any SAL_CALL
228 BaseContent::execute( const Command& aCommand,
229 sal_Int32 CommandId,
230 const Reference< XCommandEnvironment >& Environment )
232 if( ! CommandId )
233 // A Command with commandid zero cannot be aborted
234 CommandId = createCommandIdentifier();
236 m_pMyShell->startTask( CommandId,
237 Environment );
239 Any aAny;
241 if (aCommand.Name == "getPropertySetInfo") // No exceptions
243 aAny <<= getPropertySetInfo();
245 else if (aCommand.Name == "getCommandInfo") // no exceptions
247 aAny <<= getCommandInfo();
249 else if ( aCommand.Name == "setPropertyValues" )
251 Sequence< beans::PropertyValue > sPropertyValues;
253 if( ! ( aCommand.Argument >>= sPropertyValues ) )
254 m_pMyShell->installError( CommandId,
255 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
256 else
257 aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
259 else if ( aCommand.Name == "getPropertyValues" )
261 Sequence< beans::Property > ListOfRequestedProperties;
263 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
264 m_pMyShell->installError( CommandId,
265 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
266 else
267 aAny <<= getPropertyValues( CommandId,
268 ListOfRequestedProperties );
270 else if ( aCommand.Name == "open" )
272 OpenCommandArgument2 aOpenArgument;
273 if( ! ( aCommand.Argument >>= aOpenArgument ) )
274 m_pMyShell->installError( CommandId,
275 TASKHANDLING_WRONG_OPEN_ARGUMENT );
276 else
278 Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
279 if( result.is() )
280 aAny <<= result;
283 else if ( aCommand.Name == "delete" )
285 if( ! aCommand.Argument.has< bool >() )
286 m_pMyShell->installError( CommandId,
287 TASKHANDLING_WRONG_DELETE_ARGUMENT );
288 else
289 deleteContent( CommandId );
291 else if ( aCommand.Name == "transfer" )
293 TransferInfo aTransferInfo;
294 if( ! ( aCommand.Argument >>= aTransferInfo ) )
295 m_pMyShell->installError( CommandId,
296 TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
297 else
298 transfer( CommandId, aTransferInfo );
300 else if ( aCommand.Name == "insert" )
302 InsertCommandArgument aInsertArgument;
303 if( ! ( aCommand.Argument >>= aInsertArgument ) )
304 m_pMyShell->installError( CommandId,
305 TASKHANDLING_WRONG_INSERT_ARGUMENT );
306 else
307 insert( CommandId,aInsertArgument );
309 else if ( aCommand.Name == "getCasePreservingURL" )
311 Reference< sdbc::XRow > xRow = getPropertyValues( CommandId, { { "CasePreservingURL", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
312 OUString CasePreservingURL = xRow->getString(1);
313 if(!xRow->wasNull())
314 aAny <<= CasePreservingURL;
316 else if ( aCommand.Name == "createNewContent" )
318 ucb::ContentInfo aArg;
319 if ( !( aCommand.Argument >>= aArg ) )
320 m_pMyShell->installError( CommandId,
321 TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
322 else
323 aAny <<= createNewContent( aArg );
325 else
326 m_pMyShell->installError( CommandId,
327 TASKHANDLER_UNSUPPORTED_COMMAND );
330 // This is the only function allowed to throw an exception
331 endTask( CommandId );
333 return aAny;
337 void SAL_CALL
338 BaseContent::addPropertiesChangeListener(
339 const Sequence< OUString >& PropertyNames,
340 const Reference< beans::XPropertiesChangeListener >& Listener )
342 if( ! Listener.is() )
343 return;
345 std::unique_lock aGuard( m_aMutex );
347 if( ! m_pPropertyListener )
348 m_pPropertyListener.reset( new PropertyListeners );
351 if( !PropertyNames.hasElements() )
352 m_pPropertyListener->addInterface( aGuard, OUString(),Listener );
353 else
355 Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
356 for( const auto& rName : PropertyNames )
357 if( xProp->hasPropertyByName( rName ) )
358 m_pPropertyListener->addInterface( aGuard, rName,Listener );
363 void SAL_CALL
364 BaseContent::removePropertiesChangeListener( const Sequence< OUString >& PropertyNames,
365 const Reference< beans::XPropertiesChangeListener >& Listener )
367 if( ! Listener.is() )
368 return;
370 std::unique_lock aGuard( m_aMutex );
372 if( ! m_pPropertyListener )
373 return;
375 for( const auto& rName : PropertyNames )
376 m_pPropertyListener->removeInterface( aGuard, rName,Listener );
378 m_pPropertyListener->removeInterface( aGuard, OUString(), Listener );
382 // XContent
385 Reference< ucb::XContentIdentifier > SAL_CALL
386 BaseContent::getIdentifier()
388 return m_xContentIdentifier;
392 OUString SAL_CALL
393 BaseContent::getContentType()
395 if( !( m_nState & Deleted ) )
397 if( m_nState & JustInserted )
399 if ( m_bFolder )
400 return TaskManager::FolderContentType;
401 else
402 return TaskManager::FileContentType;
404 else
408 // Who am I ?
409 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
410 bool IsDocument = xRow->getBoolean( 1 );
412 if ( !xRow->wasNull() )
414 if ( IsDocument )
415 return TaskManager::FileContentType;
416 else
417 return TaskManager::FolderContentType;
419 else
421 OSL_FAIL( "BaseContent::getContentType - Property value was null!" );
424 catch (const sdbc::SQLException&)
426 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
431 return OUString();
435 void SAL_CALL
436 BaseContent::addContentEventListener(
437 const Reference< XContentEventListener >& Listener )
439 std::unique_lock aGuard( m_aMutex );
441 m_aContentEventListeners.addInterface( aGuard, Listener );
445 void SAL_CALL
446 BaseContent::removeContentEventListener(
447 const Reference< XContentEventListener >& Listener )
449 std::unique_lock aGuard( m_aMutex );
451 m_aContentEventListeners.removeInterface( aGuard, Listener );
455 // XPropertyContainer
458 void SAL_CALL
459 BaseContent::addProperty(
460 const OUString& Name,
461 sal_Int16 Attributes,
462 const Any& DefaultValue )
464 if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name.isEmpty() )
466 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
469 m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
473 void SAL_CALL
474 BaseContent::removeProperty( const OUString& Name )
477 if( m_nState & Deleted )
478 throw beans::UnknownPropertyException( Name );
480 m_pMyShell->deassociate( m_aUncPath, Name );
484 // XContentCreator
487 Sequence< ContentInfo > SAL_CALL
488 BaseContent::queryCreatableContentsInfo()
490 return TaskManager::queryCreatableContentsInfo();
494 Reference< XContent > SAL_CALL
495 BaseContent::createNewContent( const ContentInfo& Info )
497 // Check type.
498 if ( Info.Type.isEmpty() )
499 return Reference< XContent >();
501 bool bFolder = Info.Type == TaskManager::FolderContentType;
502 if ( !bFolder )
504 if ( Info.Type != TaskManager::FileContentType )
506 // Neither folder nor file to create!
507 return Reference< XContent >();
511 // Who am I ?
512 bool IsDocument = false;
516 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
517 IsDocument = xRow->getBoolean( 1 );
519 if ( xRow->wasNull() )
521 IsDocument = false;
522 // OSL_FAIL( // "BaseContent::createNewContent - Property value was null!" );
523 // return Reference< XContent >();
526 catch (const sdbc::SQLException&)
528 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
529 return Reference< XContent >();
532 OUString dstUncPath;
534 if( IsDocument )
536 // KSO: Why is a document a XContentCreator? This is quite unusual.
537 dstUncPath = getParentName( m_aUncPath );
539 else
540 dstUncPath = m_aUncPath;
542 return new BaseContent( m_pMyShell, dstUncPath, bFolder );
546 // XPropertySetInfoChangeNotifier
549 void SAL_CALL
550 BaseContent::addPropertySetInfoChangeListener(
551 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
553 std::unique_lock aGuard( m_aMutex );
555 m_aPropertySetInfoChangeListeners.addInterface( aGuard, Listener );
559 void SAL_CALL
560 BaseContent::removePropertySetInfoChangeListener(
561 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
563 std::unique_lock aGuard( m_aMutex );
565 m_aPropertySetInfoChangeListeners.removeInterface( aGuard, Listener );
569 // XChild
572 Reference< XInterface > SAL_CALL
573 BaseContent::getParent()
575 OUString ParentUnq = getParentName( m_aUncPath );
576 OUString ParentUrl;
579 bool err = fileaccess::TaskManager::getUrlFromUnq( ParentUnq, ParentUrl );
580 if( err )
581 return Reference< XInterface >( nullptr );
583 rtl::Reference<FileContentIdentifier> Identifier = new FileContentIdentifier( ParentUnq );
587 return Reference<XInterface>( m_pMyShell->m_pProvider->queryContent( Identifier ), UNO_QUERY );
589 catch (const IllegalIdentifierException&)
591 return Reference< XInterface >();
596 void SAL_CALL
597 BaseContent::setParent(
598 const Reference< XInterface >& )
600 throw lang::NoSupportException( THROW_WHERE );
604 // Private Methods
607 Reference< XCommandInfo >
608 BaseContent::getCommandInfo()
610 if( m_nState & Deleted )
611 return Reference< XCommandInfo >();
613 return m_pMyShell->info_c();
617 Reference< beans::XPropertySetInfo >
618 BaseContent::getPropertySetInfo()
620 if( m_nState & Deleted )
621 return Reference< beans::XPropertySetInfo >();
623 return m_pMyShell->info_p( m_aUncPath );
626 Reference< sdbc::XRow >
627 BaseContent::getPropertyValues(
628 sal_Int32 nMyCommandIdentifier,
629 const Sequence< beans::Property >& PropertySet )
631 sal_Int32 nProps = PropertySet.getLength();
632 if ( !nProps )
633 return Reference< sdbc::XRow >();
635 if( m_nState & Deleted )
637 Sequence< Any > aValues( nProps );
638 return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
641 if( m_nState & JustInserted )
643 Sequence< Any > aValues( nProps );
644 Any* pValues = aValues.getArray();
646 const beans::Property* pProps = PropertySet.getConstArray();
648 for ( sal_Int32 n = 0; n < nProps; ++n )
650 const beans::Property& rProp = pProps[ n ];
651 Any& rValue = pValues[ n ];
653 if ( rProp.Name == "ContentType" )
655 rValue <<= (m_bFolder ? OUString(TaskManager::FolderContentType)
656 : OUString(TaskManager::FileContentType));
658 else if ( rProp.Name == "IsFolder" )
660 rValue <<= m_bFolder;
662 else if ( rProp.Name == "IsDocument" )
664 rValue <<= !m_bFolder;
668 return Reference< sdbc::XRow >(
669 new XRow_impl( m_pMyShell, aValues ) );
672 return m_pMyShell->getv( nMyCommandIdentifier,
673 m_aUncPath,
674 PropertySet );
678 Sequence< Any >
679 BaseContent::setPropertyValues(
680 sal_Int32 nMyCommandIdentifier,
681 const Sequence< beans::PropertyValue >& Values )
683 if( m_nState & Deleted )
684 { // To do
685 return Sequence< Any >( Values.getLength() );
688 static const OUStringLiteral Title(u"Title");
690 // Special handling for files which have to be inserted
691 if( m_nState & JustInserted )
693 for( const auto& rValue : Values )
695 if( rValue.Name == Title )
697 OUString NewTitle;
698 if( rValue.Value >>= NewTitle )
700 if ( m_nState & NameForInsertionSet )
702 // User wants to set another Title before "insert".
703 // m_aUncPath contains previous own URI.
705 sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
706 bool bTrailingSlash = false;
707 if ( nLastSlash == m_aUncPath.getLength() - 1 )
709 bTrailingSlash = true;
710 nLastSlash
711 = m_aUncPath.lastIndexOf( '/', nLastSlash );
714 OSL_ENSURE( nLastSlash != -1,
715 "BaseContent::setPropertyValues: "
716 "Invalid URL!" );
718 OUStringBuffer aBuf(
719 m_aUncPath.subView( 0, nLastSlash + 1 ) );
721 if ( !NewTitle.isEmpty() )
723 aBuf.append( NewTitle );
724 if ( bTrailingSlash )
725 aBuf.append( '/' );
727 else
729 m_nState &= ~NameForInsertionSet;
732 m_aUncPath = aBuf.makeStringAndClear();
734 else
736 if ( !NewTitle.isEmpty() )
738 // Initial Title before "insert".
739 // m_aUncPath contains parent's URI.
741 if( !m_aUncPath.endsWith( "/" ) )
742 m_aUncPath += "/";
744 m_aUncPath += rtl::Uri::encode( NewTitle,
745 rtl_UriCharClassPchar,
746 rtl_UriEncodeIgnoreEscapes,
747 RTL_TEXTENCODING_UTF8 );
748 m_nState |= NameForInsertionSet;
755 return Sequence< Any >( Values.getLength() );
757 else
759 Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
760 Values );
761 auto retRange = asNonConstRange(ret);
763 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
764 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
766 if( Values[i].Name != Title )
767 continue; // handled by setv
769 OUString NewTitle;
770 if( !( Values[i].Value >>= NewTitle ) )
772 retRange[i] <<= beans::IllegalTypeException( THROW_WHERE );
773 break;
775 else if( NewTitle.isEmpty() )
777 retRange[i] <<= lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
778 break;
782 OUString aDstName = getParentName( m_aUncPath );
783 if( !aDstName.endsWith("/") )
784 aDstName += "/";
786 aDstName += rtl::Uri::encode( NewTitle,
787 rtl_UriCharClassPchar,
788 rtl_UriEncodeIgnoreEscapes,
789 RTL_TEXTENCODING_UTF8 );
791 m_pMyShell->move( nMyCommandIdentifier, // move notifies the children also;
792 m_aUncPath,
793 aDstName,
794 NameClash::KEEP );
798 endTask( nMyCommandIdentifier );
800 catch(const Exception& e)
802 retRange[i] <<= e;
805 // NameChanges come back through a ContentEvent
806 break; // only handling Title
807 } // end for
809 return ret;
814 Reference< XDynamicResultSet >
815 BaseContent::open(
816 sal_Int32 nMyCommandIdentifier,
817 const OpenCommandArgument2& aCommandArgument )
819 Reference< XDynamicResultSet > retValue;
821 if( m_nState & Deleted )
823 m_pMyShell->installError( nMyCommandIdentifier,
824 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
826 else if( m_nState & JustInserted )
828 m_pMyShell->installError( nMyCommandIdentifier,
829 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
831 else
833 if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
834 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
837 Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
838 if( outputStream.is() )
840 m_pMyShell->page( nMyCommandIdentifier,
841 m_aUncPath,
842 outputStream );
845 bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
847 Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
848 if( activeDataSink.is() )
850 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
851 m_aUncPath,
852 bLock ) );
855 Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
856 if( activeDataStreamer.is() )
858 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
859 m_aUncPath,
860 bLock ) );
863 else if ( aCommandArgument.Mode == OpenMode::ALL ||
864 aCommandArgument.Mode == OpenMode::FOLDERS ||
865 aCommandArgument.Mode == OpenMode::DOCUMENTS )
867 retValue = m_pMyShell->ls( nMyCommandIdentifier,
868 m_aUncPath,
869 aCommandArgument.Mode,
870 aCommandArgument.Properties,
871 aCommandArgument.SortingInfo );
873 // else if( aCommandArgument.Mode ==
874 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
875 // aCommandArgument.Mode ==
876 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
877 // m_pMyShell->installError( nMyCommandIdentifier,
878 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
879 // aCommandArgument.Mode);
880 else
881 m_pMyShell->installError( nMyCommandIdentifier,
882 TASKHANDLING_UNSUPPORTED_OPEN_MODE,
883 aCommandArgument.Mode);
886 return retValue;
890 void
891 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
893 if( m_nState & Deleted )
894 return;
896 if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
898 std::unique_lock aGuard( m_aMutex );
899 m_nState |= Deleted;
904 void
905 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
906 const TransferInfo& aTransferInfo )
908 if( m_nState & Deleted )
909 return;
911 if( !comphelper::isFileUrl(aTransferInfo.SourceURL) )
913 m_pMyShell->installError( nMyCommandIdentifier,
914 TASKHANDLING_TRANSFER_INVALIDSCHEME );
915 return;
918 OUString srcUnc;
919 if( fileaccess::TaskManager::getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
921 m_pMyShell->installError( nMyCommandIdentifier,
922 TASKHANDLING_TRANSFER_INVALIDURL );
923 return;
926 OUString srcUncPath = srcUnc;
928 // Determine the new title !
929 OUString NewTitle;
930 if( !aTransferInfo.NewTitle.isEmpty() )
931 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
932 rtl_UriCharClassPchar,
933 rtl_UriEncodeIgnoreEscapes,
934 RTL_TEXTENCODING_UTF8 );
935 else
936 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( '/' ) );
938 // Is destination a document or a folder ?
939 Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,{ { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } } );
940 bool IsDocument = xRow->getBoolean( 1 );
941 if( xRow->wasNull() )
942 { // Destination file type could not be determined
943 m_pMyShell->installError( nMyCommandIdentifier,
944 TASKHANDLING_TRANSFER_DESTFILETYPE );
945 return;
948 OUString dstUncPath;
949 if( IsDocument )
950 { // as sibling
951 sal_Int32 lastSlash = m_aUncPath.lastIndexOf( '/' );
952 dstUncPath = m_aUncPath.copy(0,lastSlash );
954 else
955 // as child
956 dstUncPath = m_aUncPath;
958 dstUncPath += "/" + NewTitle;
960 sal_Int32 NameClash = aTransferInfo.NameClash;
962 if( aTransferInfo.MoveData )
963 m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
964 else
965 m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
969 void BaseContent::insert( sal_Int32 nMyCommandIdentifier,
970 const InsertCommandArgument& aInsertArgument )
972 if( m_nState & FullFeatured )
974 m_pMyShell->write( nMyCommandIdentifier,
975 m_aUncPath,
976 aInsertArgument.ReplaceExisting,
977 aInsertArgument.Data );
978 return;
981 if( ! ( m_nState & JustInserted ) )
983 m_pMyShell->installError( nMyCommandIdentifier,
984 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
985 return;
988 // Inserts the content, which has the flag m_bIsFresh
990 if( ! (m_nState & NameForInsertionSet) )
992 m_pMyShell->installError( nMyCommandIdentifier,
993 TASKHANDLING_NONAMESET_INSERT_COMMAND );
994 return;
997 // Inserting a document or a file?
998 bool bDocument = false;
1000 Reference< sdbc::XRow > xRow = getPropertyValues( -1, { { "IsDocument", -1, cppu::UnoType<sal_Bool>::get(), 0 } });
1002 bool contentTypeSet = true; // is set to false, if contentType not set
1005 bDocument = xRow->getBoolean( 1 );
1006 if( xRow->wasNull() )
1007 contentTypeSet = false;
1010 catch (const sdbc::SQLException&)
1012 TOOLS_WARN_EXCEPTION("ucb.ucp.file", "");
1013 contentTypeSet = false;
1016 if( ! contentTypeSet )
1018 m_pMyShell->installError( nMyCommandIdentifier,
1019 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1020 return;
1024 bool success = false;
1025 if( bDocument )
1026 success = m_pMyShell->mkfil( nMyCommandIdentifier,
1027 m_aUncPath,
1028 aInsertArgument.ReplaceExisting,
1029 aInsertArgument.Data );
1030 else
1032 while( ! success )
1034 success = m_pMyShell->mkdir( nMyCommandIdentifier,
1035 m_aUncPath,
1036 aInsertArgument.ReplaceExisting );
1037 if( success )
1038 break;
1040 XInteractionRequestImpl aRequestImpl(
1041 rtl::Uri::decode(
1042 OUString(getTitle(m_aUncPath)),
1043 rtl_UriDecodeWithCharset,
1044 RTL_TEXTENCODING_UTF8),
1045 static_cast<cppu::OWeakObject*>(this),
1046 m_pMyShell,nMyCommandIdentifier);
1047 uno::Reference<task::XInteractionRequest> const& xReq(aRequestImpl.getRequest());
1049 m_pMyShell->handleTask( nMyCommandIdentifier, xReq );
1050 if (aRequestImpl.aborted() || aRequestImpl.newName().isEmpty())
1051 // means aborting
1052 break;
1054 // determine new uncpath
1055 m_pMyShell->clearError( nMyCommandIdentifier );
1056 m_aUncPath = getParentName( m_aUncPath );
1057 if( !m_aUncPath.endsWith( "/" ) )
1058 m_aUncPath += "/";
1060 m_aUncPath += rtl::Uri::encode( aRequestImpl.newName(),
1061 rtl_UriCharClassPchar,
1062 rtl_UriEncodeIgnoreEscapes,
1063 RTL_TEXTENCODING_UTF8 );
1067 if ( ! success )
1068 return;
1070 m_xContentIdentifier.set( new FileContentIdentifier( m_aUncPath ) );
1072 m_pMyShell->registerNotifier( m_aUncPath,this );
1073 m_pMyShell->insertDefaultProperties( m_aUncPath );
1075 std::unique_lock aGuard( m_aMutex );
1076 m_nState = FullFeatured;
1080 void BaseContent::endTask( sal_Int32 CommandId )
1082 // This is the only function allowed to throw an exception
1083 m_pMyShell->endTask( CommandId,m_aUncPath,this );
1087 std::optional<ContentEventNotifier>
1088 BaseContent::cDEL()
1090 std::unique_lock aGuard( m_aMutex );
1092 m_nState |= Deleted;
1094 if( m_aContentEventListeners.getLength(aGuard) == 0 )
1095 return {};
1097 return ContentEventNotifier( m_pMyShell,
1098 this,
1099 m_xContentIdentifier,
1100 m_aContentEventListeners.getElements(aGuard) );
1104 std::optional<ContentEventNotifier>
1105 BaseContent::cEXC( const OUString& aNewName )
1107 std::unique_lock aGuard( m_aMutex );
1109 Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1110 m_aUncPath = aNewName;
1111 m_xContentIdentifier = new FileContentIdentifier( aNewName );
1113 if( m_aContentEventListeners.getLength(aGuard) == 0 )
1114 return {};
1115 return ContentEventNotifier( m_pMyShell,
1116 this,
1117 m_xContentIdentifier,
1118 xOldRef,
1119 m_aContentEventListeners.getElements(aGuard) );
1123 std::optional<ContentEventNotifier>
1124 BaseContent::cCEL()
1126 std::unique_lock aGuard( m_aMutex );
1127 if( m_aContentEventListeners.getLength(aGuard) == 0 )
1128 return {};
1129 return ContentEventNotifier( m_pMyShell,
1130 this,
1131 m_xContentIdentifier,
1132 m_aContentEventListeners.getElements(aGuard) );
1135 std::optional<PropertySetInfoChangeNotifier>
1136 BaseContent::cPSL()
1138 std::unique_lock aGuard( m_aMutex );
1139 if( m_aPropertySetInfoChangeListeners.getLength(aGuard) == 0 )
1140 return {};
1141 return PropertySetInfoChangeNotifier( this, m_aPropertySetInfoChangeListeners.getElements(aGuard) );
1145 std::optional<PropertyChangeNotifier>
1146 BaseContent::cPCL()
1148 std::unique_lock aGuard( m_aMutex );
1150 if (!m_pPropertyListener)
1151 return {};
1153 const std::vector< OUString > seqNames = m_pPropertyListener->getContainedTypes(aGuard);
1154 if( seqNames.empty() )
1155 return {};
1157 ListenerMap listener;
1158 for( const auto& rName : seqNames )
1160 comphelper::OInterfaceContainerHelper4<beans::XPropertiesChangeListener>* pContainer = m_pPropertyListener->getContainer(aGuard, rName);
1161 if (!pContainer)
1162 continue;
1163 listener[rName] = pContainer->getElements(aGuard);
1166 return PropertyChangeNotifier( this, std::move(listener) );
1170 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */