20 #include <rtl/uri.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include <rtl/ref.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>
49 #if OSL_DEBUG_LEVEL > 0
50 #define THROW_WHERE SAL_WHERE
52 #define THROW_WHERE ""
58 std::unordered_map<OUString, ContainerHelper>
m_aMap;
61 void disposeAndClear(std::unique_lock<std::mutex>& rGuard,
const lang::EventObject& rEvt)
64 std::unordered_map<OUString, ContainerHelper> tempMap = std::move(m_aMap);
65 for (
auto& rPair : tempMap)
66 rPair.second.disposeAndClear(rGuard, rEvt);
68 void addInterface(std::unique_lock<std::mutex>& rGuard,
const OUString& rKey,
const uno::Reference<beans::XPropertiesChangeListener>& rListener)
70 m_aMap[rKey].addInterface(rGuard, rListener);
72 void removeInterface(std::unique_lock<std::mutex>& rGuard,
const OUString& rKey,
const uno::Reference<beans::XPropertiesChangeListener>& rListener)
75 auto iter = m_aMap.find(rKey);
77 if (iter != m_aMap.end())
78 iter->second.removeInterface(rGuard, rListener);
82 std::vector<OUString> aInterfaceTypes;
83 aInterfaceTypes.reserve(m_aMap.size());
84 for (
const auto& rPair : m_aMap)
86 if (rPair.second.getLength(rGuard))
88 aInterfaceTypes.push_back(rPair.first);
89 return aInterfaceTypes;
93 auto iter = m_aMap.find(rKey);
94 if (iter != m_aMap.end())
111 const OUString& parentName,
113 : m_pMyShell( pMyShell ),
114 m_aUncPath( parentName ),
115 m_bFolder( bFolder ),
116 m_nState( JustInserted )
127 const OUString& aUncPath )
128 : m_pMyShell( pMyShell ),
129 m_xContentIdentifier( xContentIdentifier ),
130 m_aUncPath( aUncPath ),
132 m_nState( FullFeatured )
156 std::unique_lock aGuard(
m_aMutex );
165 std::unique_lock aGuard(
m_aMutex );
174 lang::EventObject aEvt;
175 aEvt.Source =
static_cast< XContent*
>( this );
177 std::unique_lock aGuard(
m_aMutex );
184 if( pPropertyListener )
185 pPropertyListener->disposeAndClear( aGuard, aEvt );
194 return "com.sun.star.comp.ucb.FileContent";
240 if (aCommand.Name ==
"getPropertySetInfo")
244 else if (aCommand.Name ==
"getCommandInfo")
248 else if ( aCommand.Name ==
"setPropertyValues" )
252 if( ! ( aCommand.Argument >>= sPropertyValues ) )
258 else if ( aCommand.Name ==
"getPropertyValues" )
262 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
267 ListOfRequestedProperties );
269 else if ( aCommand.Name ==
"open" )
271 OpenCommandArgument2 aOpenArgument;
272 if( ! ( aCommand.Argument >>= aOpenArgument ) )
282 else if ( aCommand.Name ==
"delete" )
284 if( ! aCommand.Argument.has<
bool >() )
290 else if ( aCommand.Name ==
"transfer" )
292 TransferInfo aTransferInfo;
293 if( ! ( aCommand.Argument >>= aTransferInfo ) )
297 transfer( CommandId, aTransferInfo );
299 else if ( aCommand.Name ==
"insert" )
301 InsertCommandArgument aInsertArgument;
302 if( ! ( aCommand.Argument >>= aInsertArgument ) )
306 insert( CommandId,aInsertArgument );
308 else if ( aCommand.Name ==
"getCasePreservingURL" )
313 aAny <<= CasePreservingURL;
315 else if ( aCommand.Name ==
"createNewContent" )
317 ucb::ContentInfo aArg;
318 if ( !( aCommand.Argument >>= aArg ) )
341 if( ! Listener.is() )
344 std::unique_lock aGuard(
m_aMutex );
350 if( !PropertyNames.hasElements() )
355 for(
const auto& rName : PropertyNames )
356 if( xProp->hasPropertyByName( rName ) )
366 if( ! Listener.is() )
369 std::unique_lock aGuard(
m_aMutex );
374 for(
const auto& rName : PropertyNames )
411 if ( !xRow->wasNull() )
420 OSL_FAIL(
"BaseContent::getContentType - Property value was null!" );
423 catch (
const sdbc::SQLException&)
438 std::unique_lock aGuard(
m_aMutex );
448 std::unique_lock aGuard(
m_aMutex );
459 const OUString& Name,
460 sal_Int16 Attributes,
461 const Any& DefaultValue )
465 throw lang::IllegalArgumentException(
THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
477 throw beans::UnknownPropertyException( Name );
497 if ( Info.Type.isEmpty() )
516 IsDocument = xRow->getBoolean( 1 );
518 if ( xRow->wasNull() )
525 catch (
const sdbc::SQLException&)
552 std::unique_lock aGuard(
m_aMutex );
562 std::unique_lock aGuard(
m_aMutex );
588 catch (
const IllegalIdentifierException&)
627 sal_Int32 nMyCommandIdentifier,
630 sal_Int32 nProps = PropertySet.getLength();
645 const beans::Property* pProps = PropertySet.getConstArray();
647 for ( sal_Int32
n = 0;
n < nProps; ++
n )
649 const beans::Property& rProp = pProps[
n ];
650 Any& rValue = pValues[
n ];
652 if ( rProp.Name ==
"ContentType" )
657 else if ( rProp.Name ==
"IsFolder" )
661 else if ( rProp.Name ==
"IsDocument" )
679 sal_Int32 nMyCommandIdentifier,
687 static const OUStringLiteral
Title(
u"Title");
692 for(
const auto& rValue : Values )
694 if( rValue.Name == Title )
697 if( rValue.Value >>= NewTitle )
704 sal_Int32 nLastSlash =
m_aUncPath.lastIndexOf(
'/' );
705 bool bTrailingSlash =
false;
706 if ( nLastSlash ==
m_aUncPath.getLength() - 1 )
708 bTrailingSlash =
true;
713 OSL_ENSURE( nLastSlash != -1,
714 "BaseContent::setPropertyValues: "
720 if ( !NewTitle.isEmpty() )
722 aBuf.append( NewTitle );
723 if ( bTrailingSlash )
735 if ( !NewTitle.isEmpty() )
744 rtl_UriCharClassPchar,
745 rtl_UriEncodeIgnoreEscapes,
746 RTL_TEXTENCODING_UTF8 );
760 auto retRange = asNonConstRange(ret);
763 for( sal_Int32
i = 0;
i < Values.getLength(); ++
i )
765 if( Values[
i].
Name != Title )
769 if( !( Values[
i].
Value >>= NewTitle ) )
771 retRange[
i] <<= beans::IllegalTypeException(
THROW_WHERE );
774 else if( NewTitle.isEmpty() )
776 retRange[
i] <<= lang::IllegalArgumentException(
THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
782 if( !aDstName.endsWith(
"/") )
785 aDstName += rtl::Uri::encode( NewTitle,
786 rtl_UriCharClassPchar,
787 rtl_UriEncodeIgnoreEscapes,
788 RTL_TEXTENCODING_UTF8 );
797 endTask( nMyCommandIdentifier );
815 sal_Int32 nMyCommandIdentifier,
816 const OpenCommandArgument2& aCommandArgument )
833 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
837 if( outputStream.is() )
844 bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
847 if( activeDataSink.is() )
849 activeDataSink->setInputStream(
m_pMyShell->
open( nMyCommandIdentifier,
855 if( activeDataStreamer.is() )
862 else if ( aCommandArgument.Mode == OpenMode::ALL ||
863 aCommandArgument.Mode == OpenMode::FOLDERS ||
864 aCommandArgument.Mode == OpenMode::DOCUMENTS )
868 aCommandArgument.Mode,
869 aCommandArgument.Properties,
870 aCommandArgument.SortingInfo );
882 aCommandArgument.Mode);
897 std::unique_lock aGuard(
m_aMutex );
905 const TransferInfo& aTransferInfo )
925 OUString srcUncPath = srcUnc;
929 if( !aTransferInfo.NewTitle.isEmpty() )
930 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
931 rtl_UriCharClassPchar,
932 rtl_UriEncodeIgnoreEscapes,
933 RTL_TEXTENCODING_UTF8 );
935 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf(
'/' ) );
940 if( xRow->wasNull() )
950 sal_Int32 lastSlash =
m_aUncPath.lastIndexOf(
'/' );
957 dstUncPath +=
"/" + NewTitle;
959 sal_Int32 NameClash = aTransferInfo.NameClash;
961 if( aTransferInfo.MoveData )
962 m_pMyShell->
move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
964 m_pMyShell->
copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
969 const InsertCommandArgument& aInsertArgument )
975 aInsertArgument.ReplaceExisting,
976 aInsertArgument.Data );
997 bool bDocument =
false;
1001 bool contentTypeSet =
true;
1004 bDocument = xRow->getBoolean( 1 );
1005 if( xRow->wasNull() )
1006 contentTypeSet =
false;
1009 catch (
const sdbc::SQLException&)
1012 contentTypeSet =
false;
1015 if( ! contentTypeSet )
1023 bool success =
false;
1027 aInsertArgument.ReplaceExisting,
1028 aInsertArgument.Data );
1035 aInsertArgument.ReplaceExisting );
1042 rtl_UriDecodeWithCharset,
1043 RTL_TEXTENCODING_UTF8),
1044 static_cast<cppu::OWeakObject*>(
this),
1046 uno::Reference<task::XInteractionRequest>
const& xReq(aRequestImpl.
getRequest());
1060 rtl_UriCharClassPchar,
1061 rtl_UriEncodeIgnoreEscapes,
1062 RTL_TEXTENCODING_UTF8 );
1074 std::unique_lock aGuard(
m_aMutex );
1086 std::optional<ContentEventNotifier>
1089 std::unique_lock aGuard(
m_aMutex );
1103 std::optional<ContentEventNotifier>
1106 std::unique_lock aGuard(
m_aMutex );
1122 std::optional<ContentEventNotifier>
1125 std::unique_lock aGuard(
m_aMutex );
1134 std::optional<PropertySetInfoChangeNotifier>
1137 std::unique_lock aGuard(
m_aMutex );
1144 std::optional<PropertyChangeNotifier>
1147 std::unique_lock aGuard(
m_aMutex );
1153 if( seqNames.empty() )
1157 for(
const auto& rName : seqNames )
1162 listener[rName] = pContainer->
getElements(aGuard);
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT
#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT
css::uno::Reference< css::ucb::XCommandInfo > getCommandInfo()
constexpr OUStringLiteral IsDocument(u"IsDocument")
#define TASKHANDLING_WRONG_DELETE_ARGUMENT
css::uno::Reference< css::ucb::XContentIdentifier > m_xContentIdentifier
#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &Parent) override
void endTask(sal_Int32 CommandId, const OUString &aUnqPath, BaseContent *pContent)
Deinstalls the task and evaluates a possibly set error code.
std::optional< ContentEventNotifier > cCEL() override
void deleteContent(sal_Int32 nMyCommandIdentifier)
#define TASKHANDLING_UNSUPPORTED_OPEN_MODE
friend class ContentEventNotifier
virtual void SAL_CALL abort(sal_Int32 CommandId) override
std::unordered_map< OUString, std::vector< css::uno::Reference< css::beans::XPropertiesChangeListener > > > ListenerMap
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
css::uno::Reference< css::ucb::XDynamicResultSet > open(sal_Int32 nMyCommandIdentifier, const css::ucb::OpenCommandArgument2 &aCommandArgument)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void deassociate(const OUString &UnqPath, const OUString &PropertyName)
virtual void SAL_CALL addContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
bool remove(sal_Int32 CommandId, const OUString &aUnqPath, FileUrlType eTypeToMove=FileUrlType::Unknown, bool MustExist=true)
Deletes the content belonging to fileURL aUnqPath( recursively in case of directory ) ...
void insertDefaultProperties(const OUString &aUnqPath)
virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND
#define TASKHANDLING_TRANSFER_INVALIDURL
comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aDisposeEventListeners
virtual void SAL_CALL addProperty(const OUString &Name, sal_Int16 Attributes, const css::uno::Any &DefaultValue) override
static constexpr OUStringLiteral FolderContentType
#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND
#define TASKHANDLER_UNSUPPORTED_COMMAND
virtual void SAL_CALL dispose() override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
void installError(sal_Int32 CommandId, sal_Int32 ErrorCode, sal_Int32 minorCode=TASKHANDLER_NO_ERROR)
The error code may be one of the error codes defined in filerror.hxx.
virtual sal_Int32 SAL_CALL createCommandIdentifier() override
FileProvider * m_pProvider
std::unique_ptr< PropertyListeners > m_pPropertyListener
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
comphelper::OInterfaceContainerHelper4< css::beans::XPropertySetInfoChangeListener > m_aPropertySetInfoChangeListeners
void disposeAndClear(std::unique_lock< std::mutex > &rGuard, const lang::EventObject &rEvt)
#define TASKHANDLING_TRANSFER_DESTFILETYPE
virtual void SAL_CALL addPropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
comphelper::OInterfaceContainerHelper4< css::ucb::XContentEventListener > m_aContentEventListeners
virtual OUString SAL_CALL getContentType() override
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL createNewContent(const css::ucb::ContentInfo &Info) override
void transfer(sal_Int32 nMyCommandIdentifier, const css::ucb::TransferInfo &aTransferInfo)
static bool getUrlFromUnq(const OUString &Unq, OUString &Url)
static constexpr OUStringLiteral FileContentType
bool mkfil(sal_Int32 CommandId, const OUString &aFileName, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
Creates new file with given URL.
#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND
#define TASKHANDLING_TRANSFER_INVALIDSCHEME
#define TOOLS_WARN_EXCEPTION(area, stream)
comphelper::OInterfaceContainerHelper4< beans::XPropertiesChangeListener > * getContainer(std::unique_lock< std::mutex > &, const OUString &rKey)
std::unordered_map< OUString, ContainerHelper > m_aMap
virtual OUString SAL_CALL getImplementationName() override
#define TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
std::optional< PropertyChangeNotifier > cPCL() override
void copy(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, sal_Int32 NameClash)
Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories ) ...
css::uno::Reference< css::task::XInteractionRequest > const & getRequest() const
static css::uno::Sequence< css::ucb::ContentInfo > queryCreatableContentsInfo()
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
css::uno::Type const & get()
virtual void SAL_CALL removePropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
OUString getParentName(std::u16string_view aFileName)
void insert(sal_Int32 nMyCommandIdentifier, const css::ucb::InsertCommandArgument &aInsertArgument)
void deregisterNotifier(const OUString &aUnqPath, Notifier *pNotifier)
constexpr OUStringLiteral CasePreservingURL(u"CasePreservingURL")
css::uno::Reference< css::io::XStream > open_rw(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XStream which can be used to read and write from/to...
virtual void SAL_CALL removeContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
virtual ~BaseContent() override
std::vector< css::uno::Reference< ListenerT > > getElements(std::unique_lock< std::mutex > &rGuard) const
css::uno::Reference< css::sdbc::XRow > getv(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Sequence< css::beans::Property > &properties)
Reads the values of the properties belonging to fileURL aUnqPath; Returns an XRow object containing t...
const PropertyValue * pValues
std::u16string_view getTitle(std::u16string_view aPath)
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
css::uno::Sequence< css::uno::Any > setPropertyValues(sal_Int32 nMyCommandIdentifier, const css::uno::Sequence< css::beans::PropertyValue > &Values)
css::uno::Reference< css::ucb::XCommandInfo > info_c()
Info methods.
css::uno::Reference< css::io::XInputStream > open(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file...
virtual css::uno::Sequence< css::ucb::ContentInfo > SAL_CALL queryCreatableContentsInfo() override
#define TASKHANDLING_WRONG_OPEN_ARGUMENT
std::vector< OUString > getContainedTypes(std::unique_lock< std::mutex > &rGuard) const
static bool getUnqFromUrl(const OUString &Url, OUString &Unq)
COMPHELPER_DLLPUBLIC bool isFileUrl(OUString const &url)
virtual void SAL_CALL removeProperty(const OUString &Name) override
css::uno::Reference< css::ucb::XDynamicResultSet > ls(sal_Int32 CommandId, const OUString &aUnqPath, const sal_Int32 OpenMode, const css::uno::Sequence< css::beans::Property > &sProperty, const css::uno::Sequence< css::ucb::NumberedSortingInfo > &sSortingInfo)
This method returns the result set containing the children of the directory belonging to file URL aUn...
std::optional< ContentEventNotifier > cEXC(const OUString &aNewName) override
comphelper::OInterfaceContainerHelper4< beans::XPropertiesChangeListener > ContainerHelper
void move(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, const sal_Int32 NameClash)
Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories ) ...
void page(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Reference< css::io::XOutputStream > &xOutputStream)
Given an xOutputStream, this method writes the content of the file belonging to URL aUnqPath into the...
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL getIdentifier() override
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
css::uno::Sequence< css::uno::Any > setv(const OUString &aUnqPath, const css::uno::Sequence< css::beans::PropertyValue > &values)
Sets the values of the properties belonging to fileURL aUnqPath.
css::uno::Reference< css::beans::XPropertySetInfo > info_p(const OUString &aUnqPath)
bool write(sal_Int32 CommandId, const OUString &aUnqPath, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
writes to the file with given URL.
BaseContent(TaskManager *pMyShell, const OUString &parentName, bool bFolder)
void endTask(sal_Int32 CommandId)
std::optional< PropertySetInfoChangeNotifier > cPSL() override
std::optional< ContentEventNotifier > cDEL() override
#define TASKHANDLING_WRONG_INSERT_ARGUMENT
css::uno::Reference< css::beans::XPropertySetInfo > getPropertySetInfo()
bool mkdir(sal_Int32 CommandId, const OUString &aDirectoryName, bool OverWrite)
Creates new directory with given URL, recursively if necessary Return:: success of operation...
#define TASKHANDLING_NONAMESET_INSERT_COMMAND
void registerNotifier(const OUString &aUnqPath, Notifier *pNotifier)
This two methods register and deregister a change listener for the content belonging to URL aUnqPath...
#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND
void startTask(sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &xCommandEnv)
css::uno::Reference< css::sdbc::XRow > getPropertyValues(sal_Int32 nMyCommandIdentifier, const css::uno::Sequence< css::beans::Property > &PropertySet)
virtual void SAL_CALL removePropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
void clearError(sal_Int32)
Clears any error which are set on the commandid.
void handleTask(sal_Int32 CommandId, const css::uno::Reference< css::task::XInteractionRequest > &request)
Handles an interactionrequest.
void removeInterface(std::unique_lock< std::mutex > &rGuard, const OUString &rKey, const uno::Reference< beans::XPropertiesChangeListener > &rListener)
void associate(const OUString &UnqPath, const OUString &PropertyName, const css::uno::Any &DefaultValue, const sal_Int16 Attributes)
Used to associate and deassociate a new property with the content belonging to URL UnqPath...
bool m_bDetectedRangeSegmentation false
void addInterface(std::unique_lock< std::mutex > &rGuard, const OUString &rKey, const uno::Reference< beans::XPropertiesChangeListener > &rListener)