Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/ucb/source/ucp/file/filtask.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
#pragma once
20
21
#include <o3tl/sorted_vector.hxx>
22
#include <osl/file.hxx>
23
#include <rtl/ustring.hxx>
24
25
#include <osl/mutex.hxx>
26
#include <com/sun/star/uno/Sequence.hxx>
27
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
28
#include <com/sun/star/ucb/XCommandInfo.hpp>
29
#include <com/sun/star/beans/Property.hpp>
30
#include <com/sun/star/beans/PropertyValue.hpp>
31
#include <com/sun/star/io/XStream.hpp>
32
#include <com/sun/star/io/XOutputStream.hpp>
33
#include <com/sun/star/io/XInputStream.hpp>
34
#include <com/sun/star/beans/XPropertySetInfo.hpp>
35
#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
36
#include <com/sun/star/sdbc/XRow.hpp>
37
#include <com/sun/star/uno/XComponentContext.hpp>
38
#include <com/sun/star/ucb/XDynamicResultSet.hpp>
39
#include <com/sun/star/beans/XPropertyContainer.hpp>
40
#include <com/sun/star/beans/XPropertyAccess.hpp>
41
#include <com/sun/star/ucb/ContentInfo.hpp>
42
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
43
#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
44
#include <com/sun/star/ucb/XPropertySetRegistry.hpp>
45
#include <com/sun/star/task/XInteractionHandler.hpp>
46
#include <com/sun/star/task/XInteractionRequest.hpp>
47
#include "filerror.hxx"
48
#include "filnot.hxx"
49
#include <mutex>
50
#include <unordered_map>
51
#include <unordered_set>
52
#include <vector>
53
54
namespace fileaccess
55
{
56
    class BaseContent;
57
    class FileProvider;
58
59
    /*
60
     * The relevant methods in this class all have as first argument the CommandId,
61
     * so if necessary, every method has access to its relevant XInteractionHandler and
62
     * XProgressHandler.
63
     */
64
65
66
    class TaskManager
67
    {
68
        friend class XPropertySetInfo_impl;
69
        friend class XResultSet_impl;
70
        friend class XCommandInfo_impl;
71
72
    private:
73
74
        class TaskHandling
75
        {
76
        private:
77
78
            bool m_bHandled;
79
            TaskHandlerErr m_nErrorCode;
80
            sal_Int32 m_nMinorCode;
81
            css::uno::Reference< css::task::XInteractionHandler > m_xInteractionHandler;
82
            css::uno::Reference< css::ucb::XCommandEnvironment >  m_xCommandEnvironment;
83
84
85
        public:
86
87
            explicit TaskHandling(
88
                css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv )
89
174k
                : m_bHandled( false ),
90
174k
                  m_nErrorCode( TaskHandlerErr::NO_ERROR ),
91
174k
                  m_nMinorCode( 0 ),
92
174k
                  m_xCommandEnvironment( std::move(xCommandEnv) )
93
174k
            {
94
174k
            }
95
96
            void setHandled()
97
0
            {
98
0
                m_bHandled = true;
99
0
            }
100
101
            bool isHandled() const
102
174k
            {
103
174k
                return m_bHandled;
104
174k
            }
105
106
            void clearError()
107
0
            {
108
0
                m_nErrorCode = TaskHandlerErr::NO_ERROR;
109
0
                m_nMinorCode = 0;
110
0
            }
111
112
            void installError( TaskHandlerErr nErrorCode,
113
                                        sal_Int32 nMinorCode )
114
0
            {
115
0
                m_nErrorCode = nErrorCode;
116
0
                m_nMinorCode = nMinorCode;
117
0
            }
118
119
            TaskHandlerErr getInstalledError() const
120
174k
            {
121
174k
                return m_nErrorCode;
122
174k
            }
123
124
            sal_Int32 getMinorErrorCode() const
125
174k
            {
126
174k
                return m_nMinorCode;
127
174k
            }
128
129
            css::uno::Reference< css::task::XInteractionHandler > const &
130
            getInteractionHandler()
131
0
            {
132
0
                if( ! m_xInteractionHandler.is() && m_xCommandEnvironment.is() )
133
0
                    m_xInteractionHandler = m_xCommandEnvironment->getInteractionHandler();
134
135
0
                return m_xInteractionHandler;
136
0
            }
137
138
            const css::uno::Reference< css::ucb::XCommandEnvironment >&
139
            getCommandEnvironment() const
140
174k
            {
141
174k
                return m_xCommandEnvironment;
142
174k
            }
143
144
        };  // end class TaskHandling
145
146
147
        typedef std::unordered_map< sal_Int32,TaskHandling > TaskMap;
148
    private:
149
150
        std::mutex                                                          m_aMutex;
151
        sal_Int32                                                           m_nCommandId;
152
        TaskMap                                                             m_aTaskMap;
153
154
155
    public:
156
        class MyProperty
157
        {
158
        private:
159
            OUString                    PropertyName;
160
            sal_Int32                   Handle;
161
            bool                        isNative;
162
            css::uno::Type              Typ;        // Duplicates information in Value
163
            css::uno::Any               Value;
164
            css::beans::PropertyState   State;
165
            sal_Int16                   Attributes;
166
        public:
167
            explicit MyProperty( const OUString&  thePropertyName );
168
            MyProperty( bool                              theIsNative,
169
                        const OUString&                   thePropertyName,
170
                        sal_Int32                         theHandle,
171
                        const css::uno::Type&             theTyp,
172
                        const css::uno::Any&              theValue,
173
                        const css::beans::PropertyState&  theState,
174
                        sal_Int16                         theAttributes );
175
176
            inline const bool& IsNative() const;
177
56.5M
            const OUString& getPropertyName() const { return PropertyName; }
178
            inline const sal_Int32& getHandle() const;
179
            inline const css::uno::Type& getType() const;
180
            inline const css::uno::Any& getValue() const;
181
            inline const css::beans::PropertyState& getState() const;
182
            inline const sal_Int16& getAttributes() const;
183
184
            // The set* functions are declared const, because the key of "this" stays intact
185
            inline void setValue( css::uno::Any theValue ) const;
186
            inline void setState( const css::beans::PropertyState& theState ) const;
187
        };
188
189
        struct MyPropertyLess
190
        {
191
            bool operator()( const MyProperty& rKey1, const MyProperty& rKey2 ) const
192
26.6M
            {
193
26.6M
                return rKey1.getPropertyName() < rKey2.getPropertyName();
194
26.6M
            }
195
        };
196
197
        typedef o3tl::sorted_vector< MyProperty, MyPropertyLess > PropertySet;
198
199
        class UnqPathData
200
        {
201
        public:
202
            UnqPathData();
203
            UnqPathData(UnqPathData&&);
204
            ~UnqPathData();
205
206
            PropertySet properties;
207
            std::vector< Notifier* > notifier;
208
209
            // Three views on the PersistentPropertySet
210
            css::uno::Reference< css::ucb::XPersistentPropertySet >   xS;
211
            css::uno::Reference< css::beans::XPropertyContainer >     xC;
212
            css::uno::Reference< css::beans::XPropertyAccess >        xA;
213
        };
214
215
        typedef std::unordered_map< OUString,UnqPathData > ContentMap;
216
217
        TaskManager( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
218
               FileProvider* pProvider, bool bWithConfig );
219
        ~TaskManager();
220
221
        /// @throws css::ucb::DuplicateCommandIdentifierException
222
        void startTask(
223
            sal_Int32 CommandId,
224
            const css::uno::Reference< css::ucb::XCommandEnvironment >&  xCommandEnv );
225
226
        sal_Int32 getCommandId();
227
228
229
        /**
230
         *  The error code may be one of the error codes defined in
231
         *  filerror.hxx.
232
         *  The minor code refines the information given in ErrorCode.
233
         */
234
235
        void installError( sal_Int32 CommandId,
236
                                    TaskHandlerErr ErrorCode,
237
                                    sal_Int32 minorCode = 0 );
238
239
        void retrieveError( sal_Int32 CommandId,
240
                                     TaskHandlerErr &ErrorCode,
241
                                     sal_Int32 &minorCode);
242
243
        /**
244
         *  Deinstalls the task and evaluates a possibly set error code.
245
         *  "endTask" throws in case an error code is set the corresponding exception.
246
         */
247
248
        void endTask( sal_Int32 CommandId,
249
                               // the physical URL of the object
250
                               const OUString& aUnqPath,
251
                               BaseContent* pContent);
252
253
254
        /**
255
         *  Handles an interactionrequest
256
         */
257
258
        void handleTask( sal_Int32 CommandId,
259
                                  const css::uno::Reference< css::task::XInteractionRequest >& request );
260
261
        /**
262
         *  Clears any error which are set on the commandid
263
         */
264
265
        void clearError( sal_Int32 );
266
267
        /**
268
         *  This two methods register and deregister a change listener for the content belonging
269
         *  to URL aUnqPath
270
         */
271
272
        void registerNotifier( const OUString& aUnqPath,Notifier* pNotifier );
273
274
        void deregisterNotifier( const OUString& aUnqPath,Notifier* pNotifier );
275
276
277
        /**
278
         *  Used to associate and deassociate a new property with
279
         *  the content belonging to URL UnqPath.
280
         *  The default value and the attributes are input
281
         *
282
         *  @throws css::beans::PropertyExistException
283
         *  @throws css::beans::IllegalTypeException
284
         *  @throws css::uno::RuntimeException
285
         */
286
287
        void associate( const OUString& UnqPath,
288
                                 const OUString& PropertyName,
289
                                 const css::uno::Any& DefaultValue,
290
                                 const sal_Int16 Attributes );
291
292
        /// @throws css::beans::UnknownPropertyException
293
        /// @throws css::beans::NotRemoveableException
294
        /// @throws css::uno::RuntimeException
295
        void deassociate( const OUString& UnqPath,
296
                                   const OUString& PropertyName );
297
298
299
        //  Every method having a command id is not allowed to throw anything,
300
        //  but instead must install every error code in the task handler
301
302
303
        /**
304
         *  Given an xOutputStream, this method writes the content of the file belonging to
305
         *  URL aUnqPath into the XOutputStream
306
         */
307
308
        void page( sal_Int32 CommandId,
309
                            const OUString& aUnqPath,
310
                            const css::uno::Reference< css::io::XOutputStream >& xOutputStream );
311
312
313
        /**
314
         *  Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
315
         */
316
317
        css::uno::Reference< css::io::XInputStream >
318
        open( sal_Int32 CommandId,
319
              const OUString& aUnqPath,
320
              bool bLock );
321
322
323
        /**
324
         *  Given a file URL aUnqPath, this methods returns a XStream which can be used
325
         *  to read and write from/to the file.
326
         */
327
328
        css::uno::Reference< css::io::XStream >
329
        open_rw( sal_Int32 CommandId,
330
                 const OUString& aUnqPath,
331
                 bool bLock );
332
333
334
        /**
335
         *  This method returns the result set containing the children of the directory belonging
336
         *  to file URL aUnqPath
337
         */
338
339
        css::uno::Reference< css::ucb::XDynamicResultSet >
340
        ls( sal_Int32 CommandId,
341
            const OUString& aUnqPath,
342
            const sal_Int32 OpenMode,
343
            const css::uno::Sequence< css::beans::Property >& sProperty,
344
            const css::uno::Sequence< css::ucb::NumberedSortingInfo > & sSortingInfo );
345
346
347
        /**
348
         *  Info methods
349
         */
350
351
        // Info for commands
352
        css::uno::Reference< css::ucb::XCommandInfo >
353
        info_c();
354
355
        // Info for the properties
356
        css::uno::Reference< css::beans::XPropertySetInfo >
357
        info_p( const OUString& aUnqPath );
358
359
360
        /**
361
         *  Sets the values of the properties belonging to fileURL aUnqPath
362
         */
363
364
        css::uno::Sequence< css::uno::Any >
365
        setv( const OUString& aUnqPath,
366
              const css::uno::Sequence< css::beans::PropertyValue >& values );
367
368
369
        /**
370
         *  Reads the values of the properties belonging to fileURL aUnqPath;
371
         *  Returns an XRow object containing the values in the requested order.
372
         */
373
374
        css::uno::Reference< css::sdbc::XRow >
375
        getv( sal_Int32 CommandId,
376
              const OUString& aUnqPath,
377
              const css::uno::Sequence< css::beans::Property >& properties );
378
379
380
        /********************************************************************************/
381
        /*                         transfer-commands                                    */
382
        /********************************************************************************/
383
384
        /**
385
         *  Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories )
386
         */
387
388
        void
389
        move( sal_Int32 CommandId,
390
              const OUString& srcUnqPath,   // Full file(folder)-path
391
              const OUString& dstUnqPath,   // Path to the destination-directory
392
              const sal_Int32 NameClash );
393
394
        /**
395
         *  Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
396
         */
397
398
        void
399
        copy( sal_Int32 CommandId,               // See "move"
400
              const OUString& srcUnqPath,
401
              const OUString& dstUnqPath,
402
              sal_Int32 NameClash );
403
404
        enum class FileUrlType { Folder = 1, File = -1, Unknown = 0 };
405
406
        /**
407
         *  Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
408
         */
409
410
        bool
411
        remove( sal_Int32 CommandId,
412
                const OUString& aUnqPath,
413
                FileUrlType eTypeToMove = FileUrlType::Unknown,
414
                bool  MustExist  = true );
415
416
417
        /********************************************************************************/
418
        /*                         write and create - commandos                         */
419
        /********************************************************************************/
420
421
        /**
422
         *  Creates new directory with given URL, recursively if necessary
423
         *  Return:: success of operation
424
         */
425
426
        bool
427
        mkdir( sal_Int32 CommandId,
428
               const OUString& aDirectoryName,
429
               bool OverWrite );
430
431
432
        /**
433
         *  Creates new file with given URL.
434
         *  The content of aInputStream becomes the content of the file
435
         *  Return:: success of operation
436
         */
437
438
        bool
439
        mkfil( sal_Int32 CommandId,
440
               const OUString& aFileName,
441
               bool OverWrite,
442
               const css::uno::Reference< css::io::XInputStream >& aInputStream );
443
444
445
        /**
446
         *  writes to the file with given URL.
447
         *  The content of aInputStream becomes the content of the file
448
         *  Return:: success of operation
449
         */
450
        bool
451
        write( sal_Int32 CommandId,
452
               const OUString& aUnqPath,
453
               bool OverWrite,
454
               const css::uno::Reference< css::io::XInputStream >& aInputStream );
455
456
457
        void insertDefaultProperties( const OUString& aUnqPath );
458
459
        static css::uno::Sequence< css::ucb::ContentInfo >
460
        queryCreatableContentsInfo();
461
462
463
        /******************************************************************************/
464
        /*                                                                            */
465
        /*                          mapping of file urls                              */
466
        /*                          to uncpath and vice versa                         */
467
        /*                                                                            */
468
        /******************************************************************************/
469
470
        static bool getUnqFromUrl( const OUString& Url, OUString& Unq );
471
472
        static bool getUrlFromUnq( const OUString& Unq, OUString& Url );
473
474
475
        FileProvider*                                             m_pProvider;
476
        css::uno::Reference< css::uno::XComponentContext >        m_xContext;
477
        css::uno::Reference< css::ucb::XPropertySetRegistry >     m_xFileRegistry;
478
479
    private:
480
481
        void insertDefaultProperties( std::unique_lock<std::mutex>& rGuard, const OUString& aUnqPath );
482
483
        /********************************************************************************/
484
        /*                              get eventListeners                              */
485
        /********************************************************************************/
486
487
        std::vector< ContentEventNotifier >
488
        getContentEventListeners( const OUString& aName );
489
490
        std::vector< ContentEventNotifier >
491
        getContentDeletedEventListeners( const OUString& aName );
492
493
        std::vector< ContentEventNotifier >
494
        getContentExchangedEventListeners( const OUString& aOldPrefix,
495
                                           const OUString& aNewPrefix,
496
                                           bool withChildren );
497
498
        std::vector< PropertyChangeNotifier >
499
        getPropertyChangeNotifier( const OUString& aName );
500
501
        std::vector< PropertySetInfoChangeNotifier >
502
        getPropertySetListeners( const OUString& aName );
503
504
505
        /********************************************************************************/
506
        /*                              notify eventListeners                           */
507
        /********************************************************************************/
508
509
        static void notifyPropertyChanges(
510
            const std::vector<PropertyChangeNotifier>& listeners,
511
            const css::uno::Sequence<css::beans::PropertyChangeEvent>& seqChanged);
512
513
        static void notifyContentExchanged(
514
            const std::vector<ContentEventNotifier>& listeners_vec);
515
516
        static void
517
        notifyInsert(const std::vector<ContentEventNotifier>& listeners,
518
                     const OUString& aChildName);
519
520
        static void
521
        notifyContentDeleted(const std::vector<ContentEventNotifier>& listeners);
522
523
        static void
524
        notifyContentRemoved(const std::vector<ContentEventNotifier>& listeners,
525
                             const OUString& aChildName);
526
527
        static void notifyPropertyAdded(
528
            const std::vector<PropertySetInfoChangeNotifier>& listeners,
529
            const OUString& aPropertyName);
530
531
        static void notifyPropertyRemoved(
532
            const std::vector<PropertySetInfoChangeNotifier>& listeners,
533
            const OUString& aPropertyName);
534
535
        /********************************************************************************/
536
        /*                       remove persistent propertyset                          */
537
        /********************************************************************************/
538
539
        void erasePersistentSetWithoutChildren( const OUString& aUnqPath );
540
        void erasePersistentSet( const OUString& aUnqPath,
541
                                          bool withChildren = false );
542
543
        /********************************************************************************/
544
        /*                       copy persistent propertyset                            */
545
        /*                       from srcUnqPath to dstUnqPath                          */
546
        /********************************************************************************/
547
548
        void copyPersistentSetWithoutChildren( const OUString& srcUnqPath,
549
                                const OUString& dstUnqPath );
550
        void copyPersistentSet( const OUString& srcUnqPath,
551
                                         const OUString& dstUnqPath,
552
                                         bool withChildren );
553
554
555
        // Special optimized method for getting the properties of a directoryitem, which
556
        // is returned by osl::DirectoryItem::getNextItem()
557
558
        bool
559
        getv( const css::uno::Sequence< css::beans::Property >& properties,
560
              osl::DirectoryItem& DirItem,
561
              OUString& aUnqPath,
562
              bool&      bIsRegular,
563
              css::uno::Reference< css::sdbc::XRow > & row );
564
565
566
        /**
567
         *  Load the properties from configuration, if create == true create them.
568
         *  The Properties are stored under the url belonging to it->first.
569
         */
570
571
        void load( const TaskManager::ContentMap::iterator& it,
572
                            bool create );
573
574
        /**
575
         *  Commit inserts the determined properties in the filestatus object into
576
         *  the internal map, so that is possible to determine on a subsequent
577
         *  setting of file properties which properties have changed without filestat
578
         */
579
580
        void
581
        commit(
582
            std::unique_lock<std::mutex>& rGuard,
583
            const TaskManager::ContentMap::iterator& it,
584
            const osl::FileStatus& aFileStatus );
585
586
        /**
587
         *  Given a Sequence of properties seq, this method determines the mask
588
         *  used to instantiate an osl::FileStatus, so that a call to
589
         *  osl::DirectoryItem::getFileStatus fills the required fields.
590
         */
591
592
        static void
593
        getMaskFromProperties(
594
            sal_Int32& n_Mask,
595
            const css::uno::Sequence< css::beans::Property >& seq );
596
597
598
        // Helper function for public copy
599
600
        osl::FileBase::RC
601
        copy_recursive(
602
            const OUString& srcUnqPath,
603
            const OUString& dstUnqPath,
604
            FileUrlType TypeToCopy,
605
            bool  testExistence );
606
607
608
        // Helper function for mkfil,mkdir and write
609
        // Creates whole path
610
        // returns success of the operation
611
        // The call determines the errorCode, which should be used to install
612
        // any error
613
614
        bool
615
        ensuredir( sal_Int32 CommandId,
616
                   const OUString& aDirectoryName,
617
                   TaskHandlerErr errorCode );
618
619
        // General
620
        ContentMap  m_aContent;
621
622
623
    public:
624
625
        static constexpr OUString FolderContentType =
626
            u"application/vnd.sun.staroffice.fsys-folder"_ustr;
627
        static constexpr OUString FileContentType =
628
            u"application/vnd.sun.staroffice.fsys-file"_ustr;
629
630
631
    private:
632
633
        PropertySet                                   m_aDefaultProperties;
634
        css::uno::Sequence< css::ucb::CommandInfo >   m_sCommandInfo;
635
636
    public:
637
        // Miscellaneous:
638
        // Methods for "writeComponentInfo" and "createComponentFactory"
639
640
        static void getScheme( OUString& Scheme );
641
    };
642
643
} // end namespace TaskHandling
644
645
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */