Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/ucb/source/ucp/file/filtask.cxx
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
20
#include <config_features.h>
21
22
#include <sal/config.h>
23
#include <sal/log.hxx>
24
25
#if HAVE_FEATURE_MACOSX_SANDBOX
26
#include <sys/stat.h>
27
#endif
28
29
#include <com/sun/star/beans/IllegalTypeException.hpp>
30
#include <com/sun/star/beans/NotRemoveableException.hpp>
31
#include <com/sun/star/beans/PropertyAttribute.hpp>
32
#include <com/sun/star/beans/PropertyExistException.hpp>
33
#include <com/sun/star/io/BufferSizeExceededException.hpp>
34
#include <com/sun/star/io/NotConnectedException.hpp>
35
#include <com/sun/star/io/IOException.hpp>
36
#include <com/sun/star/lang/IllegalAccessException.hpp>
37
#include <com/sun/star/task/InteractionClassification.hpp>
38
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
39
#include <com/sun/star/ucb/DuplicateCommandIdentifierException.hpp>
40
#include <com/sun/star/ucb/IOErrorCode.hpp>
41
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
42
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
43
#include <com/sun/star/ucb/NameClash.hpp>
44
#include <com/sun/star/ucb/OpenCommandArgument.hpp>
45
#include <com/sun/star/ucb/Store.hpp>
46
#include <com/sun/star/ucb/TransferInfo.hpp>
47
#include <comphelper/propertysequence.hxx>
48
#include <osl/diagnose.h>
49
#include <rtl/ref.hxx>
50
#include <rtl/uri.hxx>
51
52
#include "filtask.hxx"
53
#include "filcmd.hxx"
54
#include "filglob.hxx"
55
#include "filinpstr.hxx"
56
#include "filprp.hxx"
57
#include "filrset.hxx"
58
#include "filstr.hxx"
59
#include "prov.hxx"
60
61
/******************************************************************************/
62
/*                                                                            */
63
/*                              TaskHandling                                  */
64
/*                                                                            */
65
/******************************************************************************/
66
67
68
using namespace fileaccess;
69
using namespace com::sun::star;
70
using namespace com::sun::star::uno;
71
using namespace com::sun::star::ucb;
72
73
393k
TaskManager::UnqPathData::UnqPathData() = default;
74
75
51.6k
TaskManager::UnqPathData::UnqPathData(TaskManager::UnqPathData&&) = default;
76
77
78
TaskManager::UnqPathData::~UnqPathData()
79
444k
{
80
444k
}
81
82
TaskManager::MyProperty::MyProperty( const OUString&                         thePropertyName )
83
1.84M
    : PropertyName( thePropertyName )
84
1.84M
    , Handle(-1)
85
1.84M
    , isNative(false)
86
1.84M
    , State(beans::PropertyState_AMBIGUOUS_VALUE)
87
1.84M
    , Attributes(0)
88
1.84M
{
89
    // empty
90
1.84M
}
91
92
TaskManager::MyProperty::MyProperty( bool                               theisNative,
93
                               const OUString&                    thePropertyName,
94
                               sal_Int32                          theHandle,
95
                               const css::uno::Type&              theTyp,
96
                               const css::uno::Any&               theValue,
97
                               const css::beans::PropertyState&   theState,
98
                               sal_Int16                          theAttributes )
99
180
    : PropertyName( thePropertyName ),
100
180
      Handle( theHandle ),
101
180
      isNative( theisNative ),
102
180
      Typ( theTyp ),
103
180
      Value( theValue ),
104
180
      State( theState ),
105
180
      Attributes( theAttributes )
106
180
{
107
    // empty
108
180
}
109
110
#include "filinl.hxx"
111
112
        // Default properties
113
114
constexpr OUString Title( u"Title"_ustr );
115
constexpr OUString CasePreservingURL( u"CasePreservingURL"_ustr );
116
constexpr OUString IsDocument( u"IsDocument"_ustr );
117
constexpr OUString IsFolder( u"IsFolder"_ustr );
118
constexpr OUString DateModified( u"DateModified"_ustr );
119
constexpr OUString Size( u"Size"_ustr );
120
constexpr OUString IsVolume( u"IsVolume"_ustr );
121
constexpr OUString IsRemoveable( u"IsRemoveable"_ustr );
122
constexpr OUString IsRemote( u"IsRemote"_ustr );
123
constexpr OUString IsCompactDisc( u"IsCompactDisc"_ustr );
124
constexpr OUString IsFloppy( u"IsFloppy"_ustr );
125
constexpr OUString IsHidden( u"IsHidden"_ustr );
126
constexpr OUString ContentType( u"ContentType"_ustr );
127
constexpr OUString IsReadOnly( u"IsReadOnly"_ustr );
128
constexpr OUString CreatableContentsInfo( u"CreatableContentsInfo"_ustr );
129
130
TaskManager::TaskManager( const uno::Reference< uno::XComponentContext >& rxContext,
131
              FileProvider* pProvider, bool bWithConfig )
132
12
    : m_nCommandId( 0 ),
133
12
      m_pProvider( pProvider ),
134
12
      m_xContext( rxContext ),
135
      // Commands
136
12
      m_sCommandInfo{
137
12
          { /* Name    */ u"getCommandInfo"_ustr,
138
12
            /* Handle  */ -1,
139
12
            /* ArgType */ cppu::UnoType<void>::get() },
140
141
12
          { /* Name    */ u"getPropertySetInfo"_ustr,
142
12
            /* Handle  */ -1,
143
12
            /* ArgType */ cppu::UnoType<void>::get() },
144
145
12
          { /* Name    */ u"getPropertyValues"_ustr,
146
12
            /* Handle  */ -1,
147
12
            /* ArgType */ cppu::UnoType<uno::Sequence< beans::Property >>::get() },
148
149
12
          { /* Name    */ u"setPropertyValues"_ustr,
150
12
            /* Handle  */ -1,
151
12
            /* ArgType */ cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() },
152
153
12
          { /* Name    */ u"open"_ustr,
154
12
            /* Handle  */ -1,
155
12
            /* ArgType */ cppu::UnoType<OpenCommandArgument>::get() },
156
157
12
          { /* Name    */ u"transfer"_ustr,
158
12
            /* Handle  */ -1,
159
12
            /* ArgType */ cppu::UnoType<TransferInfo>::get() },
160
161
12
          { /* Name    */ u"delete"_ustr,
162
12
            /* Handle  */ -1,
163
12
            /* ArgType */ cppu::UnoType<sal_Bool>::get() },
164
165
12
          { /* Name    */ u"insert"_ustr,
166
12
            /* Handle  */ -1,
167
12
            /* ArgType */ cppu::UnoType<InsertCommandArgument>::get() },
168
169
12
          { /* Name    */ u"createNewContent"_ustr,
170
12
            /* Handle  */ -1,
171
12
            /* ArgType */ cppu::UnoType<ucb::ContentInfo>::get() } }
172
12
{
173
    // Title
174
12
    m_aDefaultProperties.insert( MyProperty( true,
175
12
                                             Title,
176
12
                                             -1 ,
177
12
                                             cppu::UnoType<OUString>::get(),
178
12
                                             uno::Any(),
179
12
                                             beans::PropertyState_DEFAULT_VALUE,
180
12
                                             beans::PropertyAttribute::MAYBEVOID
181
12
                                             | beans::PropertyAttribute::BOUND ) );
182
183
    // CasePreservingURL
184
12
    m_aDefaultProperties.insert(
185
12
        MyProperty( true,
186
12
                    CasePreservingURL,
187
12
                    -1 ,
188
12
                    cppu::UnoType<OUString>::get(),
189
12
                    uno::Any(),
190
12
                    beans::PropertyState_DEFAULT_VALUE,
191
12
                    beans::PropertyAttribute::MAYBEVOID
192
12
                    | beans::PropertyAttribute::BOUND
193
12
                    | beans::PropertyAttribute::READONLY ) );
194
195
196
    // IsFolder
197
12
    m_aDefaultProperties.insert( MyProperty( true,
198
12
                                             IsFolder,
199
12
                                             -1 ,
200
12
                                             cppu::UnoType<sal_Bool>::get(),
201
12
                                             uno::Any(),
202
12
                                             beans::PropertyState_DEFAULT_VALUE,
203
12
                                             beans::PropertyAttribute::MAYBEVOID
204
12
                                             | beans::PropertyAttribute::BOUND
205
12
                                             | beans::PropertyAttribute::READONLY ) );
206
207
208
    // IsDocument
209
12
    m_aDefaultProperties.insert( MyProperty( true,
210
12
                                             IsDocument,
211
12
                                             -1 ,
212
12
                                             cppu::UnoType<sal_Bool>::get(),
213
12
                                             uno::Any(),
214
12
                                             beans::PropertyState_DEFAULT_VALUE,
215
12
                                             beans::PropertyAttribute::MAYBEVOID
216
12
                                             | beans::PropertyAttribute::BOUND
217
12
                                             | beans::PropertyAttribute::READONLY ) );
218
219
    // Removable
220
12
    m_aDefaultProperties.insert( MyProperty( true,
221
12
                                             IsVolume,
222
12
                                             -1 ,
223
12
                                             cppu::UnoType<sal_Bool>::get(),
224
12
                                             uno::Any(),
225
12
                                             beans::PropertyState_DEFAULT_VALUE,
226
12
                                             beans::PropertyAttribute::MAYBEVOID
227
12
                                             | beans::PropertyAttribute::BOUND
228
12
                                             | beans::PropertyAttribute::READONLY ) );
229
230
231
    // Removable
232
12
    m_aDefaultProperties.insert( MyProperty( true,
233
12
                                             IsRemoveable,
234
12
                                             -1 ,
235
12
                                             cppu::UnoType<sal_Bool>::get(),
236
12
                                             uno::Any(),
237
12
                                             beans::PropertyState_DEFAULT_VALUE,
238
12
                                             beans::PropertyAttribute::MAYBEVOID
239
12
                                             | beans::PropertyAttribute::BOUND
240
12
                                             | beans::PropertyAttribute::READONLY ) );
241
242
    // Remote
243
12
    m_aDefaultProperties.insert( MyProperty( true,
244
12
                                             IsRemote,
245
12
                                             -1 ,
246
12
                                             cppu::UnoType<sal_Bool>::get(),
247
12
                                             uno::Any(),
248
12
                                             beans::PropertyState_DEFAULT_VALUE,
249
12
                                             beans::PropertyAttribute::MAYBEVOID
250
12
                                             | beans::PropertyAttribute::BOUND
251
12
                                             | beans::PropertyAttribute::READONLY ) );
252
253
    // CompactDisc
254
12
    m_aDefaultProperties.insert( MyProperty( true,
255
12
                                             IsCompactDisc,
256
12
                                             -1 ,
257
12
                                             cppu::UnoType<sal_Bool>::get(),
258
12
                                             uno::Any(),
259
12
                                             beans::PropertyState_DEFAULT_VALUE,
260
12
                                             beans::PropertyAttribute::MAYBEVOID
261
12
                                             | beans::PropertyAttribute::BOUND
262
12
                                             | beans::PropertyAttribute::READONLY ) );
263
264
    // Floppy
265
12
    m_aDefaultProperties.insert( MyProperty( true,
266
12
                                             IsFloppy,
267
12
                                             -1 ,
268
12
                                             cppu::UnoType<sal_Bool>::get(),
269
12
                                             uno::Any(),
270
12
                                             beans::PropertyState_DEFAULT_VALUE,
271
12
                                             beans::PropertyAttribute::MAYBEVOID
272
12
                                             | beans::PropertyAttribute::BOUND
273
12
                                             | beans::PropertyAttribute::READONLY ) );
274
275
    // Hidden
276
12
    m_aDefaultProperties.insert(
277
12
        MyProperty(
278
12
            true,
279
12
            IsHidden,
280
12
            -1 ,
281
12
            cppu::UnoType<sal_Bool>::get(),
282
12
            uno::Any(),
283
12
            beans::PropertyState_DEFAULT_VALUE,
284
12
            beans::PropertyAttribute::MAYBEVOID
285
12
            | beans::PropertyAttribute::BOUND
286
#if defined(_WIN32)
287
        ));
288
#else
289
12
    | beans::PropertyAttribute::READONLY)); // under unix/linux only readable
290
12
#endif
291
292
293
    // ContentType
294
12
    m_aDefaultProperties.insert( MyProperty( false,
295
12
                                             ContentType,
296
12
                                             -1 ,
297
12
                                             cppu::UnoType<OUString>::get(),
298
12
                                             uno::Any(OUString()),
299
12
                                             beans::PropertyState_DEFAULT_VALUE,
300
12
                                             beans::PropertyAttribute::MAYBEVOID
301
12
                                             | beans::PropertyAttribute::BOUND
302
12
                                             | beans::PropertyAttribute::READONLY ) );
303
304
305
    // DateModified
306
12
    m_aDefaultProperties.insert( MyProperty( true,
307
12
                                             DateModified,
308
12
                                             -1 ,
309
12
                                             cppu::UnoType<util::DateTime>::get(),
310
12
                                             uno::Any(),
311
12
                                             beans::PropertyState_DEFAULT_VALUE,
312
12
                                             beans::PropertyAttribute::MAYBEVOID
313
12
                                             | beans::PropertyAttribute::BOUND ) );
314
315
    // Size
316
12
    m_aDefaultProperties.insert( MyProperty( true,
317
12
                                             Size,
318
12
                                             -1,
319
12
                                             cppu::UnoType<sal_Int64>::get(),
320
12
                                             uno::Any(),
321
12
                                             beans::PropertyState_DEFAULT_VALUE,
322
12
                                             beans::PropertyAttribute::MAYBEVOID
323
12
                                             | beans::PropertyAttribute::BOUND ) );
324
325
    // IsReadOnly
326
12
    m_aDefaultProperties.insert( MyProperty( true,
327
12
                                             IsReadOnly,
328
12
                                             -1 ,
329
12
                                             cppu::UnoType<sal_Bool>::get(),
330
12
                                             uno::Any(),
331
12
                                             beans::PropertyState_DEFAULT_VALUE,
332
12
                                             beans::PropertyAttribute::MAYBEVOID
333
12
                                             | beans::PropertyAttribute::BOUND ) );
334
335
336
    // CreatableContentsInfo
337
12
    m_aDefaultProperties.insert( MyProperty( true,
338
12
                                             CreatableContentsInfo,
339
12
                                             -1 ,
340
12
                                             cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
341
12
                                             uno::Any(),
342
12
                                             beans::PropertyState_DEFAULT_VALUE,
343
12
                                             beans::PropertyAttribute::MAYBEVOID
344
12
                                             | beans::PropertyAttribute::BOUND
345
12
                                             | beans::PropertyAttribute::READONLY ) );
346
347
12
    if(bWithConfig)
348
0
    {
349
0
        uno::Reference< XPropertySetRegistryFactory > xRegFac = ucb::Store::create( m_xContext );
350
        // Open/create a registry
351
0
        m_xFileRegistry = xRegFac->createPropertySetRegistry( OUString() );
352
0
    }
353
12
}
354
355
356
TaskManager::~TaskManager()
357
0
{
358
0
}
359
360
361
void
362
TaskManager::startTask(
363
    sal_Int32 CommandId,
364
    const uno::Reference< XCommandEnvironment >& xCommandEnv )
365
157k
{
366
157k
    std::unique_lock aGuard( m_aMutex );
367
157k
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
368
157k
    if( it != m_aTaskMap.end() )
369
0
    {
370
0
        throw DuplicateCommandIdentifierException( u"" OSL_LOG_PREFIX ""_ustr );
371
0
    }
372
157k
    m_aTaskMap.emplace( CommandId, TaskHandling( xCommandEnv ));
373
157k
}
374
375
376
void
377
TaskManager::endTask( sal_Int32 CommandId,
378
                      const OUString& aUncPath,
379
                      BaseContent* pContent)
380
157k
{
381
157k
    std::unique_lock aGuard( m_aMutex );
382
157k
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
383
157k
    if( it == m_aTaskMap.end() )
384
0
        return;
385
386
157k
    TaskHandlerErr ErrorCode = it->second.getInstalledError();
387
157k
    sal_Int32 MinorCode = it->second.getMinorErrorCode();
388
157k
    bool isHandled = it->second.isHandled();
389
390
157k
    Reference< XCommandEnvironment > xComEnv
391
157k
        = it->second.getCommandEnvironment();
392
393
157k
    m_aTaskMap.erase( it );
394
395
157k
    aGuard.unlock();
396
397
157k
    if( ErrorCode != TaskHandlerErr::NO_ERROR )
398
0
        throw_handler(
399
0
            ErrorCode,
400
0
            MinorCode,
401
0
            xComEnv,
402
0
            aUncPath,
403
0
            pContent,
404
0
            isHandled);
405
157k
}
406
407
408
void TaskManager::clearError( sal_Int32 CommandId )
409
0
{
410
0
    std::unique_lock aGuard( m_aMutex );
411
0
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
412
0
    if( it != m_aTaskMap.end() )
413
0
        it->second.clearError();
414
0
}
415
416
417
void TaskManager::retrieveError( sal_Int32 CommandId,
418
                                          TaskHandlerErr &ErrorCode,
419
                                          sal_Int32 &minorCode)
420
0
{
421
0
    std::unique_lock aGuard( m_aMutex );
422
0
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
423
0
    if( it != m_aTaskMap.end() )
424
0
    {
425
0
        ErrorCode = it->second.getInstalledError();
426
0
        minorCode = it->second. getMinorErrorCode();
427
0
    }
428
0
}
429
430
431
void TaskManager::installError( sal_Int32 CommandId,
432
                                         TaskHandlerErr ErrorCode,
433
                                         sal_Int32 MinorCode )
434
0
{
435
0
    std::unique_lock aGuard( m_aMutex );
436
0
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
437
0
    if( it != m_aTaskMap.end() )
438
0
        it->second.installError( ErrorCode,MinorCode );
439
0
}
440
441
442
sal_Int32
443
TaskManager::getCommandId()
444
157k
{
445
157k
    std::unique_lock aGuard( m_aMutex );
446
157k
    return ++m_nCommandId;
447
157k
}
448
449
450
void TaskManager::handleTask(
451
    sal_Int32 CommandId,
452
    const uno::Reference< task::XInteractionRequest >& request )
453
0
{
454
0
    std::unique_lock aGuard( m_aMutex );
455
0
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
456
0
    uno::Reference< task::XInteractionHandler > xInt;
457
0
    if( it != m_aTaskMap.end() )
458
0
    {
459
0
        xInt = it->second.getInteractionHandler();
460
0
        if( xInt.is() )
461
0
            xInt->handle( request );
462
0
        it->second.setHandled();
463
0
    }
464
0
}
465
466
/*********************************************************************************/
467
/*                                                                               */
468
/*                     de/registerNotifier-Implementation                        */
469
/*                                                                               */
470
/*********************************************************************************/
471
472
473
//  This two methods register and deregister a change listener for the content belonging
474
//  to URL aUnqPath
475
476
477
void
478
TaskManager::registerNotifier( const OUString& aUnqPath, Notifier* pNotifier )
479
148k
{
480
148k
    std::unique_lock aGuard( m_aMutex );
481
482
148k
    ContentMap::iterator it =
483
148k
        m_aContent.emplace( aUnqPath, UnqPathData() ).first;
484
485
148k
    std::vector< Notifier* >& nlist = it->second.notifier;
486
487
148k
    std::vector<Notifier*>::iterator it1 = std::find(nlist.begin(), nlist.end(), pNotifier);
488
148k
    if( it1 != nlist.end() )               // Every "Notifier" only once
489
0
    {
490
0
        return;
491
0
    }
492
148k
    nlist.push_back( pNotifier );
493
148k
}
494
495
496
void
497
TaskManager::deregisterNotifier( const OUString& aUnqPath,Notifier* pNotifier )
498
148k
{
499
148k
    std::unique_lock aGuard( m_aMutex );
500
501
148k
    ContentMap::iterator it = m_aContent.find( aUnqPath );
502
148k
    if( it == m_aContent.end() )
503
0
        return;
504
505
148k
    std::erase(it->second.notifier, pNotifier);
506
507
148k
    if( it->second.notifier.empty() )
508
51.5k
        m_aContent.erase( it );
509
148k
}
510
511
512
/*********************************************************************************/
513
/*                                                                               */
514
/*                     de/associate-Implementation                               */
515
/*                                                                               */
516
/*********************************************************************************/
517
518
//  Used to associate and deassociate a new property with
519
//  the content belonging to URL UnqPath.
520
//  The default value and the attributes are input
521
522
523
void
524
TaskManager::associate( const OUString& aUnqPath,
525
                  const OUString& PropertyName,
526
                  const uno::Any& DefaultValue,
527
                  const sal_Int16 Attributes )
528
0
{
529
0
    MyProperty newProperty( false,
530
0
                            PropertyName,
531
0
                            -1,
532
0
                            DefaultValue.getValueType(),
533
0
                            DefaultValue,
534
0
                            beans::PropertyState_DEFAULT_VALUE,
535
0
                            Attributes );
536
537
0
    auto it1 = m_aDefaultProperties.find( newProperty );
538
0
    if( it1 != m_aDefaultProperties.end() )
539
0
        throw beans::PropertyExistException();
540
541
0
    {
542
0
        std::unique_lock aGuard( m_aMutex );
543
544
0
        ContentMap::iterator it = m_aContent.emplace( aUnqPath,UnqPathData() ).first;
545
546
        // Load the XPersistentPropertySetInfo and create it, if it does not exist
547
0
        load( it,true );
548
549
0
        PropertySet& properties = it->second.properties;
550
0
        it1 = properties.find( newProperty );
551
0
        if( it1 != properties.end() )
552
0
            throw beans::PropertyExistException();
553
554
        // Property does not exist
555
0
        properties.insert( newProperty );
556
0
        it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
557
0
    }
558
0
    notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
559
0
}
560
561
562
void
563
TaskManager::deassociate( const OUString& aUnqPath,
564
            const OUString& PropertyName )
565
0
{
566
0
    MyProperty oldProperty( PropertyName );
567
568
0
    auto it1 = m_aDefaultProperties.find( oldProperty );
569
0
    if( it1 != m_aDefaultProperties.end() )
570
0
        throw beans::NotRemoveableException();
571
572
0
    std::unique_lock aGuard( m_aMutex );
573
574
0
    ContentMap::iterator it = m_aContent.emplace( aUnqPath,UnqPathData() ).first;
575
576
0
    load( it, false );
577
578
0
    PropertySet& properties = it->second.properties;
579
580
0
    it1 = properties.find( oldProperty );
581
0
    if( it1 == properties.end() )
582
0
        throw beans::UnknownPropertyException( PropertyName );
583
584
0
    properties.erase( it1 );
585
586
0
    if( it->second.xC.is() )
587
0
        it->second.xC->removeProperty( PropertyName );
588
589
0
    if( properties.size() == 9 )
590
0
    {
591
0
        MyProperty ContentTProperty( ContentType );
592
593
0
        if( properties.find( ContentTProperty )->getState() == beans::PropertyState_DEFAULT_VALUE )
594
0
        {
595
0
            it->second.xS = nullptr;
596
0
            it->second.xC = nullptr;
597
0
            it->second.xA = nullptr;
598
0
            if(m_xFileRegistry.is())
599
0
                m_xFileRegistry->removePropertySet( aUnqPath );
600
0
        }
601
0
    }
602
0
    aGuard.unlock();
603
0
    notifyPropertyRemoved( getPropertySetListeners( aUnqPath ), PropertyName );
604
0
}
605
606
607
/*********************************************************************************/
608
/*                                                                               */
609
/*                     page-Implementation                                       */
610
/*                                                                               */
611
/*********************************************************************************/
612
613
//  Given an xOutputStream, this method writes the content of the file belonging to
614
//  URL aUnqPath into the XOutputStream
615
616
617
void TaskManager::page( sal_Int32 CommandId,
618
                           const OUString& aUnqPath,
619
                           const uno::Reference< io::XOutputStream >& xOutputStream )
620
0
{
621
0
    osl::File aFile( aUnqPath );
622
0
    osl::FileBase::RC err = aFile.open( osl_File_OpenFlag_Read );
623
624
0
    if( err != osl::FileBase::E_None )
625
0
    {
626
0
        aFile.close();
627
0
        installError( CommandId,
628
0
                      TaskHandlerErr::OPEN_FILE_FOR_PAGING,
629
0
                      err );
630
0
        return;
631
0
    }
632
633
0
    const sal_uInt64 bfz = 4*1024;
634
0
    sal_Int8 BFF[bfz];
635
0
    sal_uInt64 nrc;  // Retrieved number of Bytes;
636
637
0
    do
638
0
    {
639
0
        err = aFile.read( static_cast<void*>(BFF),bfz,nrc );
640
0
        if(  err == osl::FileBase::E_None )
641
0
        {
642
0
            uno::Sequence< sal_Int8 > seq( BFF, static_cast<sal_uInt32>(nrc) );
643
0
            try
644
0
            {
645
0
                xOutputStream->writeBytes( seq );
646
0
            }
647
0
            catch (const io::NotConnectedException&)
648
0
            {
649
0
                installError( CommandId,
650
0
                              TaskHandlerErr::NOTCONNECTED_FOR_PAGING );
651
0
                break;
652
0
            }
653
0
            catch (const io::BufferSizeExceededException&)
654
0
            {
655
0
                installError( CommandId,
656
0
                              TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_PAGING );
657
0
                break;
658
0
            }
659
0
            catch (const io::IOException&)
660
0
            {
661
0
                installError( CommandId,
662
0
                              TaskHandlerErr::IOEXCEPTION_FOR_PAGING );
663
0
                break;
664
0
            }
665
0
        }
666
0
        else
667
0
        {
668
0
            installError( CommandId,
669
0
                          TaskHandlerErr::READING_FILE_FOR_PAGING,
670
0
                          err );
671
0
            break;
672
0
        }
673
0
    } while( nrc == bfz );
674
675
676
0
    aFile.close();
677
678
679
0
    try
680
0
    {
681
0
        xOutputStream->closeOutput();
682
0
    }
683
0
    catch (const io::NotConnectedException&)
684
0
    {
685
0
    }
686
0
    catch (const io::BufferSizeExceededException&)
687
0
    {
688
0
    }
689
0
    catch (const io::IOException&)
690
0
    {
691
0
    }
692
0
}
693
694
695
/*********************************************************************************/
696
/*                                                                               */
697
/*                     open-Implementation                                       */
698
/*                                                                               */
699
/*********************************************************************************/
700
701
//  Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
702
703
704
uno::Reference< io::XInputStream >
705
TaskManager::open( sal_Int32 CommandId,
706
             const OUString& aUnqPath,
707
             bool bLock )
708
3.28k
{
709
3.28k
    rtl::Reference<XInputStream_impl> pInputStream(new XInputStream_impl( aUnqPath, bLock )); // from filinpstr.hxx
710
711
3.28k
    TaskHandlerErr ErrorCode = pInputStream->CtorSuccess();
712
713
3.28k
    if( ErrorCode != TaskHandlerErr::NO_ERROR )
714
0
    {
715
0
        installError( CommandId,
716
0
                      ErrorCode,
717
0
                      pInputStream->getMinorError() );
718
719
0
        pInputStream.clear();
720
0
    }
721
722
3.28k
    return pInputStream;
723
3.28k
}
724
725
726
/*********************************************************************************/
727
/*                                                                               */
728
/*                     open for read/write access-Implementation                 */
729
/*                                                                               */
730
/*********************************************************************************/
731
732
//  Given a file URL aUnqPath, this methods returns a XStream which can be used
733
//  to read and write from/to the file.
734
735
736
uno::Reference< io::XStream >
737
TaskManager::open_rw( sal_Int32 CommandId,
738
                const OUString& aUnqPath,
739
                bool bLock )
740
38.5k
{
741
38.5k
    rtl::Reference<XStream_impl> pStream(new XStream_impl( aUnqPath, bLock ));  // from filstr.hxx
742
743
38.5k
    TaskHandlerErr ErrorCode = pStream->CtorSuccess();
744
745
38.5k
    if( ErrorCode != TaskHandlerErr::NO_ERROR )
746
0
    {
747
0
        installError( CommandId,
748
0
                      ErrorCode,
749
0
                      pStream->getMinorError() );
750
751
0
        pStream.clear();
752
0
    }
753
38.5k
    return pStream;
754
38.5k
}
755
756
757
/*********************************************************************************/
758
/*                                                                               */
759
/*                       ls-Implementation                                       */
760
/*                                                                               */
761
/*********************************************************************************/
762
763
//  This method returns the result set containing the children of the directory belonging
764
//  to file URL aUnqPath
765
766
767
uno::Reference< XDynamicResultSet >
768
TaskManager::ls( sal_Int32 CommandId,
769
           const OUString& aUnqPath,
770
           const sal_Int32 OpenMode,
771
           const uno::Sequence< beans::Property >& seq,
772
           const uno::Sequence< NumberedSortingInfo >& seqSort )
773
106k
{
774
106k
    rtl::Reference<XResultSet_impl> p(new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort ));
775
776
106k
    TaskHandlerErr ErrorCode = p->CtorSuccess();
777
778
106k
    if( ErrorCode != TaskHandlerErr::NO_ERROR )
779
0
    {
780
0
        installError( CommandId,
781
0
                      ErrorCode,
782
0
                      p->getMinorError() );
783
784
0
        p.clear();
785
0
    }
786
787
106k
    return p;
788
106k
}
789
790
791
/*********************************************************************************/
792
/*                                                                               */
793
/*                          info_c implementation                                */
794
/*                                                                               */
795
/*********************************************************************************/
796
// Info for commands
797
798
uno::Reference< XCommandInfo >
799
TaskManager::info_c()
800
0
{
801
0
    return new XCommandInfo_impl( this );
802
0
}
803
804
805
/*********************************************************************************/
806
/*                                                                               */
807
/*                     info_p-Implementation                                     */
808
/*                                                                               */
809
/*********************************************************************************/
810
// Info for the properties
811
812
uno::Reference< beans::XPropertySetInfo >
813
TaskManager::info_p( const OUString& aUnqPath )
814
0
{
815
0
    std::unique_lock aGuard( m_aMutex );
816
0
    return new XPropertySetInfo_impl( this,aUnqPath );
817
0
}
818
819
820
/*********************************************************************************/
821
/*                                                                               */
822
/*                     setv-Implementation                                       */
823
/*                                                                               */
824
/*********************************************************************************/
825
826
//  Sets the values of the properties belonging to fileURL aUnqPath
827
828
829
uno::Sequence< uno::Any >
830
TaskManager::setv( const OUString& aUnqPath,
831
             const uno::Sequence< beans::PropertyValue >& values )
832
0
{
833
0
    std::unique_lock aGuard( m_aMutex );
834
835
0
    sal_Int32 propChanged = 0;
836
0
    uno::Sequence< uno::Any > ret( values.getLength() );
837
0
    auto retRange = asNonConstRange(ret);
838
0
    uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
839
0
    auto seqChangedRange = asNonConstRange(seqChanged);
840
841
0
    TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
842
0
    PropertySet& properties = it->second.properties;
843
0
    TaskManager::PropertySet::const_iterator it1;
844
0
    uno::Any aAny;
845
846
0
    for( sal_Int32 i = 0; i < values.getLength(); ++i )
847
0
    {
848
0
        MyProperty toset( values[i].Name );
849
0
        it1 = properties.find( toset );
850
0
        if( it1 == properties.end() )
851
0
        {
852
0
            retRange[i] <<= beans::UnknownPropertyException();
853
0
            continue;
854
0
        }
855
856
0
        aAny = it1->getValue();
857
0
        if( aAny == values[i].Value )
858
0
            continue;  // nothing needs to be changed
859
860
0
        if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
861
0
        {
862
0
            retRange[i] <<= lang::IllegalAccessException();
863
0
            continue;
864
0
        }
865
866
0
        seqChangedRange[ propChanged   ].PropertyName = values[i].Name;
867
0
        seqChangedRange[ propChanged   ].PropertyHandle   = -1;
868
0
        seqChangedRange[ propChanged   ].Further   = false;
869
0
        seqChangedRange[ propChanged   ].OldValue = aAny;
870
0
        seqChangedRange[ propChanged++ ].NewValue = values[i].Value;
871
872
0
        it1->setValue( values[i].Value );  // Put the new value into the local cash
873
874
0
        if( ! it1->IsNative() )
875
0
        {
876
            // Also put logical properties into storage
877
0
            if( !it->second.xS.is() )
878
0
                load( it, true );
879
880
0
            if( ( values[i].Name == ContentType ) &&
881
0
                it1->getState() == beans::PropertyState_DEFAULT_VALUE )
882
0
            {   // Special logic for ContentType
883
                //  09.07.01: Not reached anymore, because ContentType is readonly
884
0
                it1->setState( beans::PropertyState_DIRECT_VALUE );
885
0
                it->second.xC->addProperty( values[i].Name,
886
0
                                            beans::PropertyAttribute::MAYBEVOID,
887
0
                                            values[i].Value );
888
0
            }
889
890
0
            try
891
0
            {
892
0
                it->second.xS->setPropertyValue( values[i].Name,values[i].Value );
893
0
            }
894
0
            catch (const uno::Exception&e)
895
0
            {
896
0
                --propChanged; // unsuccessful setting
897
0
                retRange[i] <<= e;
898
0
            }
899
0
        }
900
0
        else
901
0
        {
902
            // native properties
903
            // Setting of physical file properties
904
0
            if( values[i].Name == Size )
905
0
            {
906
0
                sal_Int64 newSize = 0;
907
0
                if( values[i].Value >>= newSize )
908
0
                {   // valid value for the size
909
0
                    osl::File aFile(aUnqPath);
910
0
                    bool err =
911
0
                        aFile.open(osl_File_OpenFlag_Write) != osl::FileBase::E_None ||
912
0
                        aFile.setSize(sal_uInt64(newSize)) != osl::FileBase::E_None ||
913
0
                        aFile.close() != osl::FileBase::E_None;
914
915
0
                    if( err )
916
0
                    {
917
0
                        --propChanged; // unsuccessful setting
918
0
                        uno::Sequence<uno::Any> names(comphelper::InitAnyPropertySequence(
919
0
                        {
920
0
                            {"Uri", uno::Any(aUnqPath)}
921
0
                        }));
922
0
                        retRange[i] <<= InteractiveAugmentedIOException(
923
0
                            OUString(),
924
0
                            nullptr,
925
0
                            task::InteractionClassification_ERROR,
926
0
                            IOErrorCode_GENERAL,
927
0
                            names );
928
0
                    }
929
0
                }
930
0
                else
931
0
                    retRange[i] <<= beans::IllegalTypeException();
932
0
            }
933
0
            else if(values[i].Name == IsReadOnly ||
934
0
                    values[i].Name == IsHidden)
935
0
            {
936
0
                bool value = false;
937
0
                if( values[i].Value >>= value )
938
0
                {
939
0
                    osl::DirectoryItem aDirItem;
940
0
                    osl::FileBase::RC err =
941
0
                        osl::DirectoryItem::get(aUnqPath,aDirItem);
942
0
                    sal_uInt64 nAttributes(0);
943
0
                    if(err == osl::FileBase::E_None)
944
0
                    {
945
0
                        osl::FileStatus aFileStatus(osl_FileStatus_Mask_Attributes);
946
0
                        err = aDirItem.getFileStatus(aFileStatus);
947
0
                        if(err == osl::FileBase::E_None &&
948
0
                           aFileStatus.isValid(osl_FileStatus_Mask_Attributes))
949
0
                            nAttributes = aFileStatus.getAttributes();
950
0
                    }
951
                    // now we have the attributes provided all went well.
952
0
                    if(err == osl::FileBase::E_None) {
953
0
                        if(values[i].Name == IsReadOnly)
954
0
                        {
955
0
                            nAttributes &= ~(osl_File_Attribute_OwnWrite |
956
0
                                             osl_File_Attribute_GrpWrite |
957
0
                                             osl_File_Attribute_OthWrite |
958
0
                                             osl_File_Attribute_ReadOnly);
959
0
                            if(value)
960
0
                                nAttributes |= osl_File_Attribute_ReadOnly;
961
0
                            else
962
0
                                nAttributes |= (
963
0
                                    osl_File_Attribute_OwnWrite |
964
0
                                    osl_File_Attribute_GrpWrite |
965
0
                                    osl_File_Attribute_OthWrite);
966
0
                        }
967
0
                        else if(values[i].Name == IsHidden)
968
0
                        {
969
0
                            nAttributes &= ~(osl_File_Attribute_Hidden);
970
0
                            if(value)
971
0
                                nAttributes |= osl_File_Attribute_Hidden;
972
0
                        }
973
0
                        err = osl::File::setAttributes(
974
0
                            aUnqPath,nAttributes);
975
0
                    }
976
977
0
                    if( err != osl::FileBase::E_None )
978
0
                    {
979
0
                        --propChanged; // unsuccessful setting
980
0
                        uno::Sequence<uno::Any> names(comphelper::InitAnyPropertySequence(
981
0
                        {
982
0
                            {"Uri", uno::Any(aUnqPath)}
983
0
                        }));
984
0
                        IOErrorCode ioError;
985
0
                        switch( err )
986
0
                        {
987
0
                        case osl::FileBase::E_NOMEM:
988
                            // not enough memory for allocating structures <br>
989
0
                            ioError = IOErrorCode_OUT_OF_MEMORY;
990
0
                            break;
991
0
                        case osl::FileBase::E_INVAL:
992
                            // the format of the parameters was not valid<p>
993
0
                            ioError = IOErrorCode_INVALID_PARAMETER;
994
0
                            break;
995
0
                        case osl::FileBase::E_NAMETOOLONG:
996
                            // File name too long<br>
997
0
                            ioError = IOErrorCode_NAME_TOO_LONG;
998
0
                            break;
999
0
                        case osl::FileBase::E_NOENT:
1000
                            // No such file or directory<br>
1001
0
                        case osl::FileBase::E_NOLINK:
1002
                            // Link has been severed<br>
1003
0
                            ioError = IOErrorCode_NOT_EXISTING;
1004
0
                            break;
1005
0
                        case osl::FileBase::E_ROFS:
1006
                            // #i4735# handle ROFS transparently
1007
                            // as ACCESS_DENIED
1008
0
                        case  osl::FileBase::E_PERM:
1009
0
                        case osl::FileBase::E_ACCES:
1010
                            // permission denied<br>
1011
0
                            ioError = IOErrorCode_ACCESS_DENIED;
1012
0
                            break;
1013
0
                        case osl::FileBase::E_LOOP:
1014
                            // Too many symbolic links encountered<br>
1015
0
                        case osl::FileBase::E_FAULT:
1016
                            // Bad address<br>
1017
0
                        case osl::FileBase::E_IO:
1018
                            // I/O error<br>
1019
0
                        case osl::FileBase::E_NOSYS:
1020
                            // Function not implemented<br>
1021
0
                        case osl::FileBase::E_MULTIHOP:
1022
                            // Multihop attempted<br>
1023
0
                        case osl::FileBase::E_INTR:
1024
                            // function call was interrupted<p>
1025
0
                        default:
1026
0
                            ioError = IOErrorCode_GENERAL;
1027
0
                            break;
1028
0
                        }
1029
0
                        retRange[i] <<= InteractiveAugmentedIOException(
1030
0
                            OUString(),
1031
0
                            nullptr,
1032
0
                            task::InteractionClassification_ERROR,
1033
0
                            ioError,
1034
0
                            names );
1035
0
                    }
1036
0
                }
1037
0
                else
1038
0
                    retRange[i] <<= beans::IllegalTypeException();
1039
0
            }
1040
0
        }
1041
0
    }   // end for
1042
1043
0
    aGuard.unlock();
1044
0
    if( propChanged )
1045
0
    {
1046
0
        seqChanged.realloc( propChanged );
1047
0
        notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath ), seqChanged );
1048
0
    }
1049
1050
0
    return ret;
1051
0
}
1052
1053
/*********************************************************************************/
1054
/*                                                                               */
1055
/*                     getv-Implementation                                       */
1056
/*                                                                               */
1057
/*********************************************************************************/
1058
1059
//  Reads the values of the properties belonging to fileURL aUnqPath;
1060
//  Returns an XRow object containing the values in the requested order.
1061
1062
1063
uno::Reference< sdbc::XRow >
1064
TaskManager::getv( sal_Int32 CommandId,
1065
             const OUString& aUnqPath,
1066
             const uno::Sequence< beans::Property >& properties )
1067
9.73k
{
1068
9.73k
    uno::Sequence< uno::Any > seq( properties.getLength() );
1069
1070
9.73k
    sal_Int32 n_Mask;
1071
9.73k
    getMaskFromProperties( n_Mask,properties );
1072
9.73k
    osl::FileStatus aFileStatus( n_Mask );
1073
1074
9.73k
    osl::DirectoryItem aDirItem;
1075
9.73k
    osl::FileBase::RC nError1 = osl::DirectoryItem::get( aUnqPath,aDirItem );
1076
9.73k
    if( nError1 != osl::FileBase::E_None )
1077
0
        installError(CommandId,
1078
0
                     TaskHandlerErr::OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
1079
0
                     nError1);
1080
1081
9.73k
    osl::FileBase::RC nError2 = aDirItem.getFileStatus( aFileStatus );
1082
9.73k
    if( nError1 == osl::FileBase::E_None &&
1083
9.73k
        nError2 != osl::FileBase::E_None )
1084
0
        installError(CommandId,
1085
0
                     TaskHandlerErr::OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
1086
0
                     nError2);
1087
1088
9.73k
    {
1089
9.73k
        std::unique_lock aGuard( m_aMutex );
1090
1091
9.73k
        TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
1092
9.73k
        commit( aGuard, it, aFileStatus );
1093
1094
9.73k
        PropertySet& propset = it->second.properties;
1095
1096
9.73k
        std::transform(properties.begin(), properties.end(), seq.getArray(),
1097
9.73k
            [&propset](const beans::Property& rProp) -> uno::Any {
1098
9.73k
                MyProperty readProp( rProp.Name );
1099
9.73k
                auto it1 = propset.find( readProp );
1100
9.73k
                if( it1 == propset.end() )
1101
0
                    return uno::Any();
1102
9.73k
                return it1->getValue();
1103
9.73k
            });
1104
9.73k
    }
1105
1106
9.73k
    return new XRow_impl( this,seq );
1107
9.73k
}
1108
1109
1110
/********************************************************************************/
1111
/*                                                                              */
1112
/*                         transfer-commandos                                   */
1113
/*                                                                              */
1114
/********************************************************************************/
1115
1116
1117
/********************************************************************************/
1118
/*                                                                              */
1119
/*                         move-implementation                                  */
1120
/*                                                                              */
1121
/********************************************************************************/
1122
1123
//  Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
1124
1125
1126
void
1127
TaskManager::move( sal_Int32 CommandId,
1128
             const OUString& srcUnqPath,
1129
             const OUString& dstUnqPathIn,
1130
             const sal_Int32 NameClash )
1131
0
{
1132
    // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
1133
    // srcUnqPath and dstUnqPathIn are equal
1134
0
    if( srcUnqPath == dstUnqPathIn )
1135
0
        return;
1136
1137
0
    osl::FileBase::RC nError;
1138
0
    OUString dstUnqPath( dstUnqPathIn );
1139
1140
0
    switch( NameClash )
1141
0
    {
1142
0
    case NameClash::KEEP:
1143
0
        {
1144
0
            nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1145
0
            if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
1146
0
            {
1147
0
                installError( CommandId,
1148
0
                              TaskHandlerErr::KEEPERROR_FOR_MOVE,
1149
0
                              nError );
1150
0
                return;
1151
0
            }
1152
0
            break;
1153
0
        }
1154
0
    case NameClash::OVERWRITE:
1155
0
        {
1156
            // stat to determine whether we have a symlink
1157
0
            OUString targetPath(dstUnqPath);
1158
1159
0
            osl::FileStatus aStatus(osl_FileStatus_Mask_Type|osl_FileStatus_Mask_LinkTargetURL);
1160
0
            osl::DirectoryItem aItem;
1161
0
            (void)osl::DirectoryItem::get(dstUnqPath,aItem);
1162
0
            (void)aItem.getFileStatus(aStatus);
1163
1164
0
            if( aStatus.isValid(osl_FileStatus_Mask_Type)          &&
1165
0
                aStatus.isValid(osl_FileStatus_Mask_LinkTargetURL) &&
1166
0
                aStatus.getFileType() == osl::FileStatus::Link )
1167
0
                targetPath = aStatus.getLinkTargetURL();
1168
1169
            // Will do nothing if file does not exist.
1170
0
            osl::File::remove( targetPath );
1171
1172
0
            nError = osl_File_move( srcUnqPath,targetPath );
1173
0
            if( nError != osl::FileBase::E_None )
1174
0
            {
1175
0
                installError( CommandId,
1176
0
                              TaskHandlerErr::OVERWRITE_FOR_MOVE,
1177
0
                              nError );
1178
0
                return;
1179
0
            }
1180
0
            break;
1181
0
        }
1182
0
    case NameClash::RENAME:
1183
0
        {
1184
0
            OUString newDstUnqPath;
1185
0
            nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1186
0
            if( nError == osl::FileBase::E_EXIST )
1187
0
            {
1188
                // "invent" a new valid title.
1189
1190
0
                sal_Int32 nPos = -1;
1191
0
                sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
1192
0
                sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
1193
0
                if( ( nLastSlash < nLastDot )                  // dot is part of last(!) path segment
1194
0
                    && ( nLastSlash != ( nLastDot - 1 ) ) )    // file name does not start with a dot
1195
0
                    nPos = nLastDot;
1196
0
                else
1197
0
                    nPos = dstUnqPath.getLength();
1198
1199
0
                sal_Int32 nTry = 0;
1200
1201
0
                do
1202
0
                {
1203
0
                    newDstUnqPath = dstUnqPath;
1204
1205
0
                    OUString aPostfix =  "_" + OUString::number( ++nTry );
1206
1207
0
                    newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostfix );
1208
1209
0
                    nError = osl_File_move( srcUnqPath,newDstUnqPath,true );
1210
0
                }
1211
0
                while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
1212
0
            }
1213
1214
0
            if( nError == osl::FileBase::E_EXIST )
1215
0
            {
1216
0
                installError( CommandId,
1217
0
                              TaskHandlerErr::RENAME_FOR_MOVE );
1218
0
                return;
1219
0
            }
1220
0
            else if( nError != osl::FileBase::E_None )
1221
0
            {
1222
0
                installError( CommandId,
1223
0
                              TaskHandlerErr::RENAMEMOVE_FOR_MOVE,
1224
0
                              nError );
1225
0
                return;
1226
0
            }
1227
0
            else
1228
0
                dstUnqPath = newDstUnqPath;
1229
1230
0
            break;
1231
0
        }
1232
0
    case NameClash::ERROR:
1233
0
        {
1234
0
            nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1235
0
            if( nError == osl::FileBase::E_EXIST )
1236
0
            {
1237
0
                installError( CommandId,
1238
0
                              TaskHandlerErr::NAMECLASH_FOR_MOVE );
1239
0
                return;
1240
0
            }
1241
0
            else if( nError != osl::FileBase::E_None )
1242
0
            {
1243
0
                installError( CommandId,
1244
0
                              TaskHandlerErr::NAMECLASHMOVE_FOR_MOVE,
1245
0
                              nError );
1246
0
                return;
1247
0
            }
1248
0
            break;
1249
0
        }
1250
0
        case NameClash::ASK:
1251
0
        default:
1252
0
        {
1253
0
            nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1254
0
            if( nError == osl::FileBase::E_EXIST )
1255
0
            {
1256
0
                installError( CommandId,
1257
0
                              TaskHandlerErr::NAMECLASHSUPPORT_FOR_MOVE,
1258
0
                              NameClash::ASK);
1259
0
                return;
1260
0
            }
1261
0
        }
1262
0
        break;
1263
0
    }
1264
1265
    // Determine, whether we have moved a file or a folder
1266
0
    osl::DirectoryItem aItem;
1267
0
    nError = osl::DirectoryItem::get( dstUnqPath,aItem );
1268
0
    if( nError != osl::FileBase::E_None )
1269
0
    {
1270
0
        installError( CommandId,
1271
0
                      TaskHandlerErr::TRANSFER_BY_MOVE_SOURCE,
1272
0
                      nError );
1273
0
        return;
1274
0
    }
1275
0
    osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
1276
0
    nError = aItem.getFileStatus( aStatus );
1277
0
    if( nError != osl::FileBase::E_None || ! aStatus.isValid( osl_FileStatus_Mask_Type ) )
1278
0
    {
1279
0
        installError( CommandId,
1280
0
                      TaskHandlerErr::TRANSFER_BY_MOVE_SOURCESTAT,
1281
0
                      nError );
1282
0
        return;
1283
0
    }
1284
0
    bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );
1285
1286
1287
0
    copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );
1288
1289
0
    OUString aDstParent = getParentName( dstUnqPath );
1290
0
    OUString aSrcParent = getParentName( srcUnqPath );
1291
1292
0
    notifyInsert( getContentEventListeners( aDstParent ),dstUnqPath );
1293
0
    if(  aDstParent != aSrcParent )
1294
0
        notifyContentRemoved( getContentEventListeners( aSrcParent ),srcUnqPath );
1295
1296
0
    notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) );
1297
0
    erasePersistentSet( srcUnqPath,!isDocument );
1298
0
}
1299
1300
1301
/********************************************************************************/
1302
/*                                                                              */
1303
/*                         copy-implementation                                  */
1304
/*                                                                              */
1305
/********************************************************************************/
1306
1307
//  Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
1308
1309
1310
namespace {
1311
1312
bool getType(
1313
    TaskManager & task, sal_Int32 id, OUString const & fileUrl,
1314
    osl::DirectoryItem * item, osl::FileStatus::Type * type)
1315
0
{
1316
0
    assert(item != nullptr && type != nullptr);
1317
0
    osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
1318
0
    if (err != osl::FileBase::E_None) {
1319
0
        task.installError(id, TaskHandlerErr::TRANSFER_BY_COPY_SOURCE, err);
1320
0
        return false;
1321
0
    }
1322
0
    osl::FileStatus stat(osl_FileStatus_Mask_Type);
1323
0
    err = item->getFileStatus(stat);
1324
0
    if (err != osl::FileBase::E_None) {
1325
0
        task.installError(id, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT, err);
1326
0
        return false;
1327
0
    }
1328
0
    *type = stat.getFileType();
1329
0
    return true;
1330
0
}
1331
1332
}
1333
1334
void
1335
TaskManager::copy(
1336
    sal_Int32 CommandId,
1337
    const OUString& srcUnqPath,
1338
    const OUString& dstUnqPathIn,
1339
    sal_Int32 NameClash )
1340
0
{
1341
0
    osl::FileBase::RC nError;
1342
0
    OUString dstUnqPath( dstUnqPathIn );
1343
1344
    // Resolve symbolic links within the source path.  If srcUnqPath denotes a
1345
    // symbolic link (targeting either a file or a folder), the contents of the
1346
    // target is copied (recursively, in the case of a folder).  However, if
1347
    // recursively copying the contents of a folder causes a symbolic link to be
1348
    // copied, the symbolic link itself is copied.
1349
0
    osl::DirectoryItem item;
1350
0
    osl::FileStatus::Type type;
1351
0
    if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
1352
0
        return;
1353
0
    }
1354
0
    OUString rslvdSrcUnqPath;
1355
0
    if (type == osl::FileStatus::Link) {
1356
0
        osl::FileStatus stat(osl_FileStatus_Mask_LinkTargetURL);
1357
0
        nError = item.getFileStatus(stat);
1358
0
        if (nError != osl::FileBase::E_None) {
1359
0
            installError(
1360
0
                CommandId, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT, nError);
1361
0
            return;
1362
0
        }
1363
0
        rslvdSrcUnqPath = stat.getLinkTargetURL();
1364
0
        if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
1365
0
            return;
1366
0
        }
1367
0
    } else {
1368
0
        rslvdSrcUnqPath = srcUnqPath;
1369
0
    }
1370
1371
0
    bool isDocument
1372
0
        = type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
1373
0
    FileUrlType IsWhat = isDocument ? FileUrlType::File : FileUrlType::Folder;
1374
1375
0
    switch( NameClash )
1376
0
    {
1377
0
        case NameClash::KEEP:
1378
0
        {
1379
0
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1380
0
            if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
1381
0
            {
1382
0
                installError( CommandId,
1383
0
                              TaskHandlerErr::KEEPERROR_FOR_COPY,
1384
0
                              nError );
1385
0
                return;
1386
0
            }
1387
0
            break;
1388
0
        }
1389
0
        case NameClash::OVERWRITE:
1390
0
        {
1391
            // remove (..., MustExist = sal_False).
1392
0
            remove( CommandId, dstUnqPath, IsWhat, false );
1393
1394
            // copy.
1395
0
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
1396
0
            if( nError != osl::FileBase::E_None )
1397
0
            {
1398
0
                installError( CommandId,
1399
0
                              TaskHandlerErr::OVERWRITE_FOR_COPY,
1400
0
                              nError );
1401
0
                return;
1402
0
            }
1403
0
            break;
1404
0
        }
1405
0
        case NameClash::RENAME:
1406
0
        {
1407
0
            OUString newDstUnqPath = dstUnqPath;
1408
0
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1409
1410
0
            if( nError == osl::FileBase::E_EXIST )
1411
0
            {
1412
                // "invent" a new valid title.
1413
1414
0
                sal_Int32 nPos = -1;
1415
0
                sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
1416
0
                sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
1417
0
                if ( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
1418
0
                     && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
1419
0
                    nPos = nLastDot;
1420
0
                else
1421
0
                    nPos = dstUnqPath.getLength();
1422
1423
0
                sal_Int32 nTry = 0;
1424
1425
0
                do
1426
0
                {
1427
0
                    newDstUnqPath = dstUnqPath;
1428
1429
0
                    OUString aPostfix =  "_" + OUString::number( ++nTry );
1430
1431
0
                    newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostfix );
1432
1433
0
                    nError = copy_recursive( rslvdSrcUnqPath,newDstUnqPath,IsWhat,true );
1434
0
                }
1435
0
                while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
1436
0
            }
1437
1438
0
            if( nError == osl::FileBase::E_EXIST )
1439
0
            {
1440
0
                installError( CommandId,
1441
0
                              TaskHandlerErr::RENAME_FOR_COPY );
1442
0
                return;
1443
0
            }
1444
0
            else if( nError != osl::FileBase::E_None )
1445
0
            {
1446
0
                installError( CommandId,
1447
0
                              TaskHandlerErr::RENAMEMOVE_FOR_COPY,
1448
0
                              nError );
1449
0
                return;
1450
0
            }
1451
0
            else
1452
0
                dstUnqPath = newDstUnqPath;
1453
1454
0
            break;
1455
0
        }
1456
0
        case NameClash::ERROR:
1457
0
        {
1458
0
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1459
1460
0
            if( nError == osl::FileBase::E_EXIST )
1461
0
            {
1462
0
                installError( CommandId,
1463
0
                              TaskHandlerErr::NAMECLASH_FOR_COPY );
1464
0
                return;
1465
0
            }
1466
0
            else if( nError != osl::FileBase::E_None )
1467
0
            {
1468
0
                installError( CommandId,
1469
0
                              TaskHandlerErr::NAMECLASHMOVE_FOR_COPY,
1470
0
                              nError );
1471
0
                return;
1472
0
            }
1473
0
            break;
1474
0
        }
1475
0
        case NameClash::ASK:
1476
0
        default:
1477
0
        {
1478
0
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1479
1480
0
            if( nError == osl::FileBase::E_EXIST )
1481
0
            {
1482
0
                installError( CommandId,
1483
0
                              TaskHandlerErr::NAMECLASHSUPPORT_FOR_COPY,
1484
0
                              NameClash);
1485
0
                return;
1486
0
            }
1487
0
            break;
1488
0
        }
1489
0
    }
1490
1491
0
    copyPersistentSet( srcUnqPath,dstUnqPath, !isDocument );
1492
0
    notifyInsert( getContentEventListeners( getParentName( dstUnqPath ) ),dstUnqPath );
1493
0
}
1494
1495
1496
/********************************************************************************/
1497
/*                                                                              */
1498
/*                         remove-implementation                                */
1499
/*                                                                              */
1500
/********************************************************************************/
1501
1502
//  Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
1503
//  Return: success of operation
1504
1505
1506
bool
1507
TaskManager::remove( sal_Int32 CommandId,
1508
               const OUString& aUnqPath,
1509
               FileUrlType IsWhat,
1510
               bool  MustExist )
1511
0
{
1512
0
    sal_Int32 nMask = osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL;
1513
1514
0
    osl::DirectoryItem aItem;
1515
0
    osl::FileStatus aStatus( nMask );
1516
0
    osl::FileBase::RC nError;
1517
1518
0
    if( IsWhat == FileUrlType::Unknown ) // Determine whether we are removing a directory or a file
1519
0
    {
1520
0
        nError = osl::DirectoryItem::get( aUnqPath, aItem );
1521
0
        if( nError != osl::FileBase::E_None )
1522
0
        {
1523
0
            if (MustExist)
1524
0
            {
1525
0
                installError( CommandId,
1526
0
                              TaskHandlerErr::NOSUCHFILEORDIR_FOR_REMOVE,
1527
0
                              nError );
1528
0
            }
1529
0
            return (!MustExist);
1530
0
        }
1531
1532
0
        nError = aItem.getFileStatus( aStatus );
1533
0
        if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
1534
0
        {
1535
0
            installError( CommandId,
1536
0
                          TaskHandlerErr::VALIDFILESTATUS_FOR_REMOVE,
1537
0
                          nError != osl::FileBase::E_None ? nError : 0 );
1538
0
            return false;
1539
0
        }
1540
1541
0
        if( aStatus.getFileType() == osl::FileStatus::Regular ||
1542
0
            aStatus.getFileType() == osl::FileStatus::Link )
1543
0
            IsWhat = FileUrlType::File;
1544
0
        else if(  aStatus.getFileType() == osl::FileStatus::Directory ||
1545
0
                  aStatus.getFileType() == osl::FileStatus::Volume )
1546
0
            IsWhat = FileUrlType::Folder;
1547
0
    }
1548
1549
1550
0
    if( IsWhat == FileUrlType::File )
1551
0
    {
1552
0
        nError = osl::File::remove( aUnqPath );
1553
0
        if( nError != osl::FileBase::E_None )
1554
0
        {
1555
0
            if (MustExist)
1556
0
            {
1557
0
                installError( CommandId,
1558
0
                              TaskHandlerErr::DELETEFILE_FOR_REMOVE,
1559
0
                              nError );
1560
0
            }
1561
0
            return (!MustExist);
1562
0
        }
1563
0
        else
1564
0
        {
1565
0
            notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
1566
0
            erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
1567
0
        }
1568
0
    }
1569
0
    else if( IsWhat == FileUrlType::Folder )
1570
0
    {
1571
0
        osl::Directory aDirectory( aUnqPath );
1572
1573
0
        nError = aDirectory.open();
1574
0
        if( nError != osl::FileBase::E_None )
1575
0
        {
1576
0
            if (MustExist)
1577
0
            {
1578
0
                installError( CommandId,
1579
0
                              TaskHandlerErr::OPENDIRECTORY_FOR_REMOVE,
1580
0
                              nError );
1581
0
            }
1582
0
            return (!MustExist);
1583
0
        }
1584
1585
0
        bool whileSuccess = true;
1586
0
        FileUrlType recurse = FileUrlType::Unknown;
1587
0
        OUString name;
1588
1589
0
        nError = aDirectory.getNextItem( aItem );
1590
0
        while( nError == osl::FileBase::E_None )
1591
0
        {
1592
0
            nError = aItem.getFileStatus( aStatus );
1593
0
            if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
1594
0
            {
1595
0
                installError( CommandId,
1596
0
                              TaskHandlerErr::VALIDFILESTATUSWHILE_FOR_REMOVE,
1597
0
                              nError != osl::FileBase::E_None ? nError : 0 );
1598
0
                whileSuccess = false;
1599
0
                break;
1600
0
            }
1601
1602
0
            if( aStatus.getFileType() == osl::FileStatus::Regular ||
1603
0
                aStatus.getFileType() == osl::FileStatus::Link )
1604
0
                recurse = FileUrlType::File;
1605
0
            else if( aStatus.getFileType() == osl::FileStatus::Directory ||
1606
0
                     aStatus.getFileType() == osl::FileStatus::Volume )
1607
0
                recurse = FileUrlType::Folder;
1608
1609
0
            name = aStatus.getFileURL();
1610
0
            whileSuccess = remove( CommandId, name, recurse, MustExist );
1611
0
            if( !whileSuccess )
1612
0
                break;
1613
1614
0
            nError = aDirectory.getNextItem( aItem );
1615
0
        }
1616
1617
0
        aDirectory.close();
1618
1619
0
        if( ! whileSuccess )
1620
0
            return false;     // error code is installed
1621
1622
0
        if( nError != osl::FileBase::E_NOENT )
1623
0
        {
1624
0
            installError( CommandId,
1625
0
                          TaskHandlerErr::DIRECTORYEXHAUSTED_FOR_REMOVE,
1626
0
                          nError );
1627
0
            return false;
1628
0
        }
1629
1630
0
        nError = osl::Directory::remove( aUnqPath );
1631
0
        if( nError != osl::FileBase::E_None )
1632
0
        {
1633
0
            if (MustExist)
1634
0
            {
1635
0
                installError( CommandId,
1636
0
                              TaskHandlerErr::DELETEDIRECTORY_FOR_REMOVE,
1637
0
                              nError );
1638
0
            }
1639
0
            return (!MustExist);
1640
0
        }
1641
0
        else
1642
0
        {
1643
0
            notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
1644
0
            erasePersistentSet( aUnqPath );
1645
0
        }
1646
0
    }
1647
0
    else   // Don't know what to remove
1648
0
    {
1649
0
        installError( CommandId,
1650
0
                      TaskHandlerErr::FILETYPE_FOR_REMOVE );
1651
0
        return false;
1652
0
    }
1653
1654
0
    return true;
1655
0
}
1656
1657
1658
/********************************************************************************/
1659
/*                                                                              */
1660
/*                         mkdir-implementation                                 */
1661
/*                                                                              */
1662
/********************************************************************************/
1663
1664
//  Creates new directory with given URL, recursively if necessary
1665
//  Return:: success of operation
1666
1667
1668
bool
1669
TaskManager::mkdir( sal_Int32 CommandId,
1670
              const OUString& rUnqPath,
1671
              bool OverWrite )
1672
0
{
1673
0
    OUString aUnqPath;
1674
1675
    // remove trailing slash
1676
0
    if ( rUnqPath.endsWith("/") )
1677
0
        aUnqPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
1678
0
    else
1679
0
        aUnqPath = rUnqPath;
1680
1681
0
    osl::FileBase::RC nError = osl::Directory::create( aUnqPath );
1682
1683
0
    switch ( nError )
1684
0
    {
1685
0
        case osl::FileBase::E_EXIST:   // Directory cannot be overwritten
1686
0
        {
1687
0
            if( !OverWrite )
1688
0
            {
1689
0
                installError( CommandId,
1690
0
                              TaskHandlerErr::FOLDER_EXISTS_MKDIR );
1691
0
                return false;
1692
0
            }
1693
0
            else
1694
0
                return true;
1695
0
        }
1696
0
        case osl::FileBase::E_INVAL:
1697
0
        {
1698
0
            installError(CommandId,
1699
0
                         TaskHandlerErr::INVALID_NAME_MKDIR);
1700
0
            return false;
1701
0
        }
1702
0
        case osl::FileBase::E_None:
1703
0
        {
1704
0
            OUString aPrtPath = getParentName( aUnqPath );
1705
0
            notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
1706
0
            return true;
1707
0
        }
1708
0
        default:
1709
0
            return ensuredir(
1710
0
                CommandId,
1711
0
                aUnqPath,
1712
0
                TaskHandlerErr::CREATEDIRECTORY_MKDIR );
1713
0
    }
1714
0
}
1715
1716
1717
/********************************************************************************/
1718
/*                                                                              */
1719
/*                         mkfil-implementation                                 */
1720
/*                                                                              */
1721
/********************************************************************************/
1722
1723
//  Creates new file with given URL.
1724
//  The content of aInputStream becomes the content of the file
1725
//  Return:: success of operation
1726
1727
1728
bool
1729
TaskManager::mkfil( sal_Int32 CommandId,
1730
              const OUString& aUnqPath,
1731
              bool Overwrite,
1732
              const uno::Reference< io::XInputStream >& aInputStream )
1733
0
{
1734
    // return value unimportant
1735
0
    bool bSuccess = write( CommandId,
1736
0
                               aUnqPath,
1737
0
                               Overwrite,
1738
0
                               aInputStream );
1739
0
    if ( bSuccess )
1740
0
    {
1741
0
        OUString aPrtPath = getParentName( aUnqPath );
1742
0
        notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
1743
0
    }
1744
0
    return bSuccess;
1745
0
}
1746
1747
1748
/********************************************************************************/
1749
/*                                                                              */
1750
/*                         write-implementation                                 */
1751
/*                                                                              */
1752
/********************************************************************************/
1753
1754
//  writes to the file with given URL.
1755
//  The content of aInputStream becomes the content of the file
1756
//  Return:: success of operation
1757
1758
1759
bool
1760
TaskManager::write( sal_Int32 CommandId,
1761
              const OUString& aUnqPath,
1762
              bool OverWrite,
1763
              const uno::Reference< io::XInputStream >& aInputStream )
1764
0
{
1765
0
    if( ! aInputStream.is() )
1766
0
    {
1767
0
        installError( CommandId,
1768
0
                      TaskHandlerErr::INPUTSTREAM_FOR_WRITE );
1769
0
        return false;
1770
0
    }
1771
1772
    // Create parent path, if necessary.
1773
0
    if ( ! ensuredir( CommandId,
1774
0
                      getParentName( aUnqPath ),
1775
0
                      TaskHandlerErr::ENSUREDIR_FOR_WRITE ) )
1776
0
        return false;
1777
1778
0
    osl::FileBase::RC err;
1779
0
    osl::File aFile( aUnqPath );
1780
1781
0
    if( OverWrite )
1782
0
    {
1783
0
        err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
1784
1785
0
        if( err != osl::FileBase::E_None )
1786
0
        {
1787
0
            aFile.close();
1788
0
            err = aFile.open( osl_File_OpenFlag_Write );
1789
1790
0
            if( err != osl::FileBase::E_None )
1791
0
            {
1792
0
                installError( CommandId,
1793
0
                              TaskHandlerErr::NO_OPEN_FILE_FOR_OVERWRITE,
1794
0
                              err );
1795
0
                return false;
1796
0
            }
1797
1798
            // the existing file was just opened and should be overwritten now,
1799
            // truncate it first
1800
1801
0
            err = aFile.setSize( 0 );
1802
0
            if( err != osl::FileBase::E_None  )
1803
0
            {
1804
0
                installError( CommandId,
1805
0
                              TaskHandlerErr::FILESIZE_FOR_WRITE,
1806
0
                              err );
1807
0
                return false;
1808
0
            }
1809
0
        }
1810
0
    }
1811
0
    else
1812
0
    {
1813
0
        err = aFile.open( osl_File_OpenFlag_Read | osl_File_OpenFlag_NoLock );
1814
0
        if( err == osl::FileBase::E_None )  // The file exists and shall not be overwritten
1815
0
        {
1816
0
            installError( CommandId,
1817
0
                          TaskHandlerErr::NOREPLACE_FOR_WRITE,  // Now an exception
1818
0
                          err );
1819
1820
0
            aFile.close();
1821
0
            return false;
1822
0
        }
1823
1824
        // as a temporary solution the creation does not lock the file at all
1825
        // in future it should be possible to create the file without lock explicitly
1826
0
        err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock );
1827
1828
0
        if( err != osl::FileBase::E_None )
1829
0
        {
1830
0
            aFile.close();
1831
0
            installError( CommandId,
1832
0
                          TaskHandlerErr::NO_OPEN_FILE_FOR_WRITE,
1833
0
                          err );
1834
0
            return false;
1835
0
        }
1836
0
    }
1837
1838
0
    bool bSuccess = true;
1839
1840
0
    sal_uInt64 nWrittenBytes;
1841
0
    sal_Int32 nReadBytes = 0, nRequestedBytes = 32768 /*32k*/;
1842
0
    uno::Sequence< sal_Int8 > seq( nRequestedBytes );
1843
1844
0
    do
1845
0
    {
1846
0
        try
1847
0
        {
1848
0
            nReadBytes = aInputStream->readBytes( seq,
1849
0
                                                  nRequestedBytes );
1850
0
        }
1851
0
        catch( const io::NotConnectedException& )
1852
0
        {
1853
0
            installError( CommandId,
1854
0
                          TaskHandlerErr::NOTCONNECTED_FOR_WRITE );
1855
0
            bSuccess = false;
1856
0
            break;
1857
0
        }
1858
0
        catch( const io::BufferSizeExceededException& )
1859
0
        {
1860
0
            installError( CommandId,
1861
0
                          TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_WRITE );
1862
0
            bSuccess = false;
1863
0
            break;
1864
0
        }
1865
0
        catch( const io::IOException& )
1866
0
        {
1867
0
            installError( CommandId,
1868
0
                          TaskHandlerErr::IOEXCEPTION_FOR_WRITE );
1869
0
            bSuccess = false;
1870
0
            break;
1871
0
        }
1872
1873
0
        if( nReadBytes )
1874
0
        {
1875
0
            const sal_Int8* p = seq.getConstArray();
1876
1877
0
            err = aFile.write( static_cast<void const *>(p),
1878
0
                               sal_uInt64( nReadBytes ),
1879
0
                               nWrittenBytes );
1880
1881
0
            if( err != osl::FileBase::E_None )
1882
0
            {
1883
0
                installError( CommandId,
1884
0
                              TaskHandlerErr::FILEIOERROR_FOR_WRITE,
1885
0
                              err );
1886
0
                bSuccess = false;
1887
0
                break;
1888
0
            }
1889
0
            else if( nWrittenBytes != sal_uInt64( nReadBytes ) )
1890
0
            {
1891
0
                installError( CommandId,
1892
0
                              TaskHandlerErr::FILEIOERROR_FOR_NO_SPACE );
1893
0
                bSuccess = false;
1894
0
                break;
1895
0
            }
1896
0
        }
1897
0
    } while( nReadBytes == nRequestedBytes );
1898
1899
0
    err = aFile.close();
1900
0
    if( err != osl::FileBase::E_None  )
1901
0
    {
1902
0
        installError( CommandId,
1903
0
                      TaskHandlerErr::FILEIOERROR_FOR_WRITE,
1904
0
                      err );
1905
0
        bSuccess = false;
1906
0
    }
1907
1908
0
    return bSuccess;
1909
0
}
1910
1911
1912
/*********************************************************************************/
1913
/*                                                                               */
1914
/*                 insertDefaultProperties-Implementation                        */
1915
/*                                                                               */
1916
/*********************************************************************************/
1917
1918
1919
void TaskManager::insertDefaultProperties( const OUString& aUnqPath )
1920
148k
{
1921
148k
    std::unique_lock aGuard(m_aMutex);
1922
148k
    insertDefaultProperties(aGuard, aUnqPath);
1923
148k
}
1924
1925
void TaskManager::insertDefaultProperties( std::unique_lock<std::mutex>& /*rGuard*/, const OUString& aUnqPath )
1926
244k
{
1927
244k
    ContentMap::iterator it =
1928
244k
        m_aContent.emplace( aUnqPath,UnqPathData() ).first;
1929
1930
244k
    load( it, false );
1931
1932
244k
    MyProperty ContentTProperty( ContentType );
1933
1934
244k
    PropertySet& properties = it->second.properties;
1935
244k
    bool ContentNotDefau = properties.find( ContentTProperty ) != properties.end();
1936
1937
244k
    properties.reserve(properties.size() + m_aDefaultProperties.size());
1938
244k
    for (auto const& defaultprop : m_aDefaultProperties)
1939
3.67M
    {
1940
3.67M
        if( !ContentNotDefau || defaultprop.getPropertyName() != ContentType )
1941
3.47M
            properties.insert( defaultprop );
1942
3.67M
    }
1943
244k
}
1944
1945
1946
/******************************************************************************/
1947
/*                                                                            */
1948
/*                          mapping of file urls                              */
1949
/*                          to uncpath and vice versa                         */
1950
/*                                                                            */
1951
/******************************************************************************/
1952
1953
1954
bool TaskManager::getUnqFromUrl( const OUString& Url, OUString& Unq )
1955
148k
{
1956
148k
    if ( Url == "file:///" || Url == "file://localhost/" || Url == "file://127.0.0.1/" )
1957
0
    {
1958
0
        Unq = "file:///";
1959
0
        return false;
1960
0
    }
1961
1962
148k
    bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Url,Unq );
1963
1964
148k
    Unq = Url;
1965
1966
148k
    sal_Int32 l = Unq.getLength()-1;
1967
148k
    if( ! err && Unq.endsWith("/") &&
1968
0
        Unq.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) != -1 )
1969
0
        Unq = Unq.copy(0, l);
1970
1971
148k
    return err;
1972
148k
}
1973
1974
1975
bool TaskManager::getUrlFromUnq( const OUString& Unq,OUString& Url )
1976
38.6k
{
1977
38.6k
    bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Unq,Url );
1978
1979
38.6k
    Url = Unq;
1980
1981
38.6k
    return err;
1982
38.6k
}
1983
1984
1985
// Helper function for public copy
1986
1987
osl::FileBase::RC
1988
TaskManager::copy_recursive( const OUString& srcUnqPath,
1989
                       const OUString& dstUnqPath,
1990
                       FileUrlType TypeToCopy,
1991
                       bool testExistBeforeCopy )
1992
0
{
1993
0
    osl::FileBase::RC err = osl::FileBase::E_None;
1994
1995
0
    if( TypeToCopy == FileUrlType::File ) // Document
1996
0
    {
1997
0
        err = osl_File_copy( srcUnqPath,dstUnqPath,testExistBeforeCopy );
1998
0
    }
1999
0
    else if( TypeToCopy == FileUrlType::Folder )
2000
0
    {
2001
0
        osl::Directory aDir( srcUnqPath );
2002
0
        (void)aDir.open();
2003
2004
0
        err = osl::Directory::create( dstUnqPath );
2005
0
        osl::FileBase::RC next = err;
2006
0
        if( err == osl::FileBase::E_None )
2007
0
        {
2008
0
            sal_Int32 const n_Mask = osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Type;
2009
2010
0
            osl::DirectoryItem aDirItem;
2011
2012
0
            while( err == osl::FileBase::E_None )
2013
0
            {
2014
0
                next = aDir.getNextItem( aDirItem );
2015
0
                if (next != osl::FileBase::E_None )
2016
0
                    break;
2017
0
                bool IsDoc = false;
2018
0
                osl::FileStatus aFileStatus( n_Mask );
2019
0
                aDirItem.getFileStatus( aFileStatus );
2020
0
                if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
2021
0
                    IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
2022
2023
                // Getting the information for the next recursive copy
2024
0
                FileUrlType newTypeToCopy = IsDoc ? FileUrlType::File : FileUrlType::Folder;
2025
2026
0
                OUString newSrcUnqPath;
2027
0
                if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
2028
0
                    newSrcUnqPath = aFileStatus.getFileURL();
2029
2030
0
                OUString newDstUnqPath = dstUnqPath;
2031
0
                OUString tit;
2032
0
                if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
2033
0
                    tit = rtl::Uri::encode( aFileStatus.getFileName(),
2034
0
                                          rtl_UriCharClassPchar,
2035
0
                                          rtl_UriEncodeIgnoreEscapes,
2036
0
                                          RTL_TEXTENCODING_UTF8 );
2037
2038
0
                if( !newDstUnqPath.endsWith( "/" ) )
2039
0
                    newDstUnqPath += "/";
2040
2041
0
                newDstUnqPath += tit;
2042
2043
0
                if ( newSrcUnqPath != dstUnqPath )
2044
0
                    err = copy_recursive( newSrcUnqPath,newDstUnqPath,newTypeToCopy,false );
2045
0
            }
2046
2047
0
            if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
2048
0
                err = next;
2049
0
        }
2050
0
        aDir.close();
2051
0
    }
2052
2053
0
    return err;
2054
0
}
2055
2056
2057
// Helper function for mkfil,mkdir and write
2058
// Creates whole path
2059
// returns success of the operation
2060
2061
2062
bool TaskManager::ensuredir( sal_Int32 CommandId,
2063
                                    const OUString& rUnqPath,
2064
                                    TaskHandlerErr errorCode )
2065
0
{
2066
0
    OUString aPath;
2067
2068
0
    if ( rUnqPath.isEmpty() )
2069
0
        return false;
2070
2071
0
    if ( rUnqPath.endsWith("/") )
2072
0
        aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
2073
0
    else
2074
0
        aPath = rUnqPath;
2075
2076
#if HAVE_FEATURE_MACOSX_SANDBOX
2077
2078
    // Avoid annoying sandbox messages in the system.log from the
2079
    // below aDirectory.open(), which ends up calling opendir().
2080
    // Surely it is easier to just call stat()? Calling stat() on an
2081
    // arbitrary (?) directory does not seem to cause any sandbox
2082
    // violation, while opendir() does. (Sorry I could not be bothered
2083
    // to use some complex cross-platform abstraction over stat() here
2084
    // in this macOS specific code block.)
2085
2086
    OUString aDirName;
2087
    struct stat s;
2088
    if( osl::FileBase::getSystemPathFromFileURL( aPath, aDirName ) == osl::FileBase::E_None &&
2089
        stat(OUStringToOString( aDirName, RTL_TEXTENCODING_UTF8).getStr(), &s ) == 0 &&
2090
        S_ISDIR( s.st_mode ) )
2091
        return sal_True;
2092
#endif
2093
2094
    // HACK: create directory on a mount point with nobrowse option
2095
    // returns ENOSYS in any case !!
2096
0
    osl::Directory aDirectory( aPath );
2097
0
    osl::FileBase::RC nError = aDirectory.open();
2098
0
    aDirectory.close();
2099
2100
0
    if( nError == osl::File::E_None )
2101
0
        return true;
2102
2103
0
    nError = osl::Directory::create( aPath );
2104
2105
0
    if( nError == osl::File::E_None )
2106
0
        notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
2107
2108
0
    bool  bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
2109
2110
0
    if( ! bSuccess )
2111
0
    {
2112
0
        OUString aParentDir = getParentName( aPath );
2113
2114
0
        if ( aParentDir != aPath )
2115
0
        {   // Create first the parent directory
2116
0
            bSuccess = ensuredir( CommandId,
2117
0
                                  getParentName( aPath ),
2118
0
                                  errorCode );
2119
2120
            // After parent directory structure exists try it one's more
2121
2122
0
            if ( bSuccess )
2123
0
            {   // Parent directory exists, retry creation of directory
2124
0
                nError = osl::Directory::create( aPath );
2125
2126
0
                if( nError == osl::File::E_None )
2127
0
                    notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
2128
2129
0
                bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
2130
0
            }
2131
0
        }
2132
0
    }
2133
2134
0
    if( ! bSuccess )
2135
0
        installError( CommandId,
2136
0
                      errorCode,
2137
0
                      nError );
2138
2139
0
    return bSuccess;
2140
0
}
2141
2142
2143
//  Given a sequence of properties seq, this method determines the mask
2144
//  used to instantiate an osl::FileStatus, so that a call to
2145
//  osl::DirectoryItem::getFileStatus fills the required fields.
2146
2147
2148
void
2149
TaskManager::getMaskFromProperties(
2150
    sal_Int32& n_Mask,
2151
    const uno::Sequence< beans::Property >& seq )
2152
106k
{
2153
106k
    n_Mask = 0;
2154
106k
    for(const auto& rProp : seq) {
2155
106k
        if(rProp.Name == Title)
2156
96.6k
            n_Mask |= osl_FileStatus_Mask_FileName;
2157
9.73k
        else if(rProp.Name == CasePreservingURL)
2158
0
            n_Mask |= osl_FileStatus_Mask_FileURL;
2159
9.73k
        else if(rProp.Name == IsDocument ||
2160
9.73k
                rProp.Name == IsFolder ||
2161
0
                rProp.Name == IsVolume ||
2162
0
                rProp.Name == IsRemoveable ||
2163
0
                rProp.Name == IsRemote ||
2164
0
                rProp.Name == IsCompactDisc ||
2165
0
                rProp.Name == IsFloppy ||
2166
0
                rProp.Name == ContentType)
2167
9.73k
            n_Mask |= (osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL);
2168
0
        else if(rProp.Name == Size)
2169
0
            n_Mask |= (osl_FileStatus_Mask_FileSize |
2170
0
                      osl_FileStatus_Mask_Type |
2171
0
                      osl_FileStatus_Mask_LinkTargetURL);
2172
0
        else if(rProp.Name == IsHidden ||
2173
0
                rProp.Name == IsReadOnly)
2174
0
            n_Mask |= osl_FileStatus_Mask_Attributes;
2175
0
        else if(rProp.Name == DateModified)
2176
0
            n_Mask |= osl_FileStatus_Mask_ModifyTime;
2177
106k
    }
2178
106k
}
2179
2180
2181
/*********************************************************************************/
2182
/*                                                                               */
2183
/*                     load-Implementation                                       */
2184
/*                                                                               */
2185
/*********************************************************************************/
2186
2187
//  Load the properties from configuration, if create == true create them.
2188
//  The Properties are stored under the url belonging to it->first.
2189
2190
2191
void
2192
TaskManager::load( const ContentMap::iterator& it, bool create )
2193
244k
{
2194
244k
    if(  ( it->second.xS.is() && it->second.xC.is() && it->second.xA.is() )
2195
244k
        || !m_xFileRegistry.is() )
2196
244k
        return;
2197
2198
2199
0
    uno::Reference< ucb::XPersistentPropertySet > xS = m_xFileRegistry->openPropertySet( it->first,create );
2200
0
    if( xS.is() )
2201
0
    {
2202
0
        it->second.xS = xS;
2203
0
        it->second.xC.set(xS, uno::UNO_QUERY);
2204
0
        it->second.xA.set(xS, uno::UNO_QUERY);
2205
2206
        // Now put in all values in the storage in the local hash;
2207
2208
0
        PropertySet& properties = it->second.properties;
2209
0
        const uno::Sequence< beans::Property > seq = xS->getPropertySetInfo()->getProperties();
2210
2211
0
        for( const auto& rProp : seq )
2212
0
        {
2213
0
            MyProperty readProp( false,
2214
0
                                 rProp.Name,
2215
0
                                 rProp.Handle,
2216
0
                                 rProp.Type,
2217
0
                                 xS->getPropertyValue( rProp.Name ),
2218
0
                                 beans::PropertyState_DIRECT_VALUE,
2219
0
                                 rProp.Attributes );
2220
0
            properties.insert( readProp );
2221
0
        }
2222
0
    }
2223
0
    else if( create )
2224
0
    {
2225
        // Catastrophic error
2226
0
    }
2227
0
}
2228
2229
2230
/*********************************************************************************/
2231
/*                                                                               */
2232
/*                     commit-Implementation                                     */
2233
/*                                                                               */
2234
/*********************************************************************************/
2235
// Commit inserts the determined properties in the filestatus object into
2236
// the internal map, so that is possible to determine on a subsequent
2237
// setting of file properties which properties have changed without filestat
2238
2239
2240
void
2241
TaskManager::commit( std::unique_lock<std::mutex>& rGuard,
2242
               const TaskManager::ContentMap::iterator& it,
2243
               const osl::FileStatus& aFileStatus )
2244
106k
{
2245
106k
    TaskManager::PropertySet::const_iterator it1;
2246
2247
106k
    if( it->second.properties.empty() )
2248
0
    {
2249
0
        OUString aPath = it->first;
2250
0
        insertDefaultProperties( rGuard, aPath );
2251
0
    }
2252
2253
106k
    PropertySet& properties = it->second.properties;
2254
2255
106k
    it1 = properties.find( MyProperty( Title ) );
2256
106k
    if( it1 != properties.end() )
2257
106k
    {
2258
106k
        if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
2259
96.6k
        {
2260
96.6k
            it1->setValue( uno::Any(aFileStatus.getFileName()) );
2261
96.6k
        }
2262
106k
    }
2263
2264
106k
    it1 = properties.find( MyProperty( CasePreservingURL ) );
2265
106k
    if( it1 != properties.end() )
2266
106k
    {
2267
106k
        if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
2268
96.6k
        {
2269
96.6k
            it1->setValue( uno::Any(aFileStatus.getFileURL()) );
2270
96.6k
        }
2271
106k
    }
2272
2273
2274
106k
    bool isDirectory;
2275
2276
106k
    sal_Int64 dirSize = 0;
2277
2278
106k
    if( aFileStatus.isValid( osl_FileStatus_Mask_FileSize ) )
2279
96.6k
        dirSize = aFileStatus.getFileSize();
2280
2281
106k
    if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
2282
106k
    {
2283
106k
        bool isFile,isVolume;
2284
106k
        if( osl::FileStatus::Link == aFileStatus.getFileType() &&
2285
0
            aFileStatus.isValid( osl_FileStatus_Mask_LinkTargetURL ) )
2286
0
        {
2287
0
            osl::DirectoryItem aDirItem;
2288
0
            osl::FileStatus aFileStatus2( osl_FileStatus_Mask_Type );
2289
0
            if( osl::FileBase::E_None == osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(),aDirItem ) &&
2290
0
                osl::FileBase::E_None == aDirItem.getFileStatus( aFileStatus2 )    &&
2291
0
                aFileStatus2.isValid( osl_FileStatus_Mask_Type ) )
2292
0
            {
2293
0
                isVolume = osl::FileStatus::Volume == aFileStatus2.getFileType();
2294
0
                isDirectory =
2295
0
                    osl::FileStatus::Volume == aFileStatus2.getFileType() ||
2296
0
                    osl::FileStatus::Directory == aFileStatus2.getFileType();
2297
0
                isFile =
2298
0
                    osl::FileStatus::Regular == aFileStatus2.getFileType();
2299
2300
0
                if( aFileStatus2.isValid( osl_FileStatus_Mask_FileSize ) )
2301
0
                    dirSize = aFileStatus2.getFileSize();
2302
0
            }
2303
0
            else
2304
0
            {
2305
                // extremely ugly, but otherwise default construction
2306
                // of aDirItem and aFileStatus2
2307
                // before the preceding if
2308
0
                isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
2309
0
                isDirectory =
2310
0
                    osl::FileStatus::Volume == aFileStatus.getFileType() ||
2311
0
                    osl::FileStatus::Directory == aFileStatus.getFileType();
2312
0
                isFile =
2313
0
                    osl::FileStatus::Regular == aFileStatus.getFileType();
2314
0
            }
2315
0
        }
2316
106k
        else
2317
106k
        {
2318
106k
            isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
2319
106k
            isDirectory =
2320
106k
                osl::FileStatus::Volume == aFileStatus.getFileType() ||
2321
106k
                osl::FileStatus::Directory == aFileStatus.getFileType();
2322
106k
            isFile =
2323
106k
                osl::FileStatus::Regular == aFileStatus.getFileType();
2324
106k
        }
2325
2326
106k
        it1 = properties.find( MyProperty( IsVolume ) );
2327
106k
        if( it1 != properties.end() )
2328
106k
            it1->setValue( uno::Any( isVolume ) );
2329
2330
106k
        it1 = properties.find( MyProperty( IsFolder ) );
2331
106k
        if( it1 != properties.end() )
2332
106k
            it1->setValue( uno::Any( isDirectory ) );
2333
2334
106k
        it1 = properties.find( MyProperty( IsDocument ) );
2335
106k
        if( it1 != properties.end() )
2336
106k
            it1->setValue( uno::Any( isFile ) );
2337
2338
106k
        osl::VolumeInfo aVolumeInfo( osl_VolumeInfo_Mask_Attributes );
2339
106k
        if( isVolume &&
2340
0
            osl::FileBase::E_None == osl::Directory::getVolumeInfo( it->first,aVolumeInfo ) &&
2341
0
            aVolumeInfo.isValid( osl_VolumeInfo_Mask_Attributes ) )
2342
0
        {
2343
            // Retrieve the flags;
2344
0
            bool isRemote = aVolumeInfo.getRemoteFlag();
2345
0
            bool isRemoveable = aVolumeInfo.getRemoveableFlag();
2346
0
            bool isCompactDisc = aVolumeInfo.getCompactDiscFlag();
2347
0
            bool isFloppy = aVolumeInfo.getFloppyDiskFlag();
2348
2349
0
            it1 = properties.find( MyProperty( IsRemote ) );
2350
0
            if( it1 != properties.end() )
2351
0
                it1->setValue( uno::Any( isRemote ) );
2352
2353
0
            it1 = properties.find( MyProperty( IsRemoveable ) );
2354
0
            if( it1 != properties.end() )
2355
0
                it1->setValue( uno::Any( isRemoveable ) );
2356
2357
0
            it1 = properties.find( MyProperty( IsCompactDisc ) );
2358
0
            if( it1 != properties.end() )
2359
0
                it1->setValue( uno::Any( isCompactDisc ) );
2360
2361
0
            it1 = properties.find( MyProperty( IsFloppy ) );
2362
0
            if( it1 != properties.end() )
2363
0
                it1->setValue( uno::Any( isFloppy ) );
2364
0
        }
2365
106k
        else
2366
106k
        {
2367
106k
            uno::Any aAny(false);
2368
106k
            it1 = properties.find( MyProperty( IsRemote ) );
2369
106k
            if( it1 != properties.end() )
2370
106k
                it1->setValue( aAny );
2371
2372
106k
            it1 = properties.find( MyProperty( IsRemoveable ) );
2373
106k
            if( it1 != properties.end() )
2374
106k
                it1->setValue( aAny );
2375
2376
106k
            it1 = properties.find( MyProperty( IsCompactDisc ) );
2377
106k
            if( it1 != properties.end() )
2378
106k
                it1->setValue( aAny );
2379
2380
106k
            it1 = properties.find( MyProperty( IsFloppy ) );
2381
106k
            if( it1 != properties.end() )
2382
106k
                it1->setValue( aAny );
2383
106k
        }
2384
106k
    }
2385
0
    else
2386
0
    {
2387
0
        isDirectory = false;
2388
0
    }
2389
2390
106k
    it1 = properties.find( MyProperty( Size ) );
2391
106k
    if( it1 != properties.end() )
2392
106k
        it1->setValue( uno::Any( dirSize ) );
2393
2394
106k
    it1 = properties.find( MyProperty( IsReadOnly ) );
2395
106k
    if( it1 != properties.end() )
2396
106k
    {
2397
106k
        if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
2398
106k
        {
2399
106k
            sal_uInt64 Attr = aFileStatus.getAttributes();
2400
106k
            bool readonly = ( Attr & osl_File_Attribute_ReadOnly ) != 0;
2401
106k
            it1->setValue( uno::Any( readonly ) );
2402
106k
        }
2403
106k
    }
2404
2405
106k
    it1 = properties.find( MyProperty( IsHidden ) );
2406
106k
    if( it1 != properties.end() )
2407
106k
    {
2408
106k
        if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
2409
106k
        {
2410
106k
            sal_uInt64 Attr = aFileStatus.getAttributes();
2411
106k
            bool ishidden = ( Attr & osl_File_Attribute_Hidden ) != 0;
2412
106k
            it1->setValue( uno::Any( ishidden ) );
2413
106k
        }
2414
106k
    }
2415
2416
106k
    it1 = properties.find( MyProperty( DateModified ) );
2417
106k
    if( it1 != properties.end() )
2418
106k
    {
2419
106k
        if( aFileStatus.isValid( osl_FileStatus_Mask_ModifyTime ) )
2420
106k
        {
2421
106k
            TimeValue temp = aFileStatus.getModifyTime();
2422
2423
            // Convert system time to local time (for EA)
2424
106k
            TimeValue myLocalTime;
2425
106k
            if (!osl_getLocalTimeFromSystemTime( &temp, &myLocalTime ))
2426
0
            {
2427
0
                SAL_WARN(
2428
0
                    "ucb.ucp.file",
2429
0
                    "cannot convert (" << temp.Seconds << ", " << temp.Nanosec
2430
0
                        << ") to local time");
2431
0
                myLocalTime = temp;
2432
0
            }
2433
2434
106k
            oslDateTime myDateTime;
2435
106k
            osl_getDateTimeFromTimeValue( &myLocalTime, &myDateTime );
2436
106k
            util::DateTime aDateTime;
2437
2438
106k
            aDateTime.NanoSeconds = myDateTime.NanoSeconds;
2439
106k
            aDateTime.Seconds = myDateTime.Seconds;
2440
106k
            aDateTime.Minutes = myDateTime.Minutes;
2441
106k
            aDateTime.Hours = myDateTime.Hours;
2442
106k
            aDateTime.Day = myDateTime.Day;
2443
106k
            aDateTime.Month = myDateTime.Month;
2444
106k
            aDateTime.Year = myDateTime.Year;
2445
106k
            it1->setValue( uno::Any( aDateTime ) );
2446
106k
        }
2447
106k
    }
2448
2449
106k
    it1 = properties.find( MyProperty( CreatableContentsInfo ) );
2450
106k
    if( it1 != properties.end() )
2451
106k
        it1->setValue( uno::Any(
2452
106k
            isDirectory || !aFileStatus.isValid( osl_FileStatus_Mask_Type )
2453
106k
                ? queryCreatableContentsInfo()
2454
106k
                : uno::Sequence< ucb::ContentInfo >() ) );
2455
106k
}
2456
2457
2458
// Special optimized method for getting the properties of a
2459
// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
2460
2461
2462
bool
2463
TaskManager::getv(
2464
    const uno::Sequence< beans::Property >& properties,
2465
    osl::DirectoryItem& aDirItem,
2466
    OUString& aUnqPath,
2467
    bool& aIsRegular,
2468
    uno::Reference< sdbc::XRow > & row )
2469
96.6k
{
2470
96.6k
    uno::Sequence< uno::Any > seq( properties.getLength() );
2471
2472
96.6k
    sal_Int32 n_Mask;
2473
96.6k
    getMaskFromProperties( n_Mask,properties );
2474
2475
    // Always retrieve the type and the target URL because item might be a link
2476
96.6k
    osl::FileStatus aFileStatus( n_Mask |
2477
96.6k
                                 osl_FileStatus_Mask_FileURL |
2478
96.6k
                                 osl_FileStatus_Mask_Type |
2479
96.6k
                                 osl_FileStatus_Mask_LinkTargetURL );
2480
2481
96.6k
    osl::FileBase::RC aRes = aDirItem.getFileStatus( aFileStatus );
2482
96.6k
    if ( aRes != osl::FileBase::E_None )
2483
0
    {
2484
0
        SAL_WARN(
2485
0
            "ucb.ucp.file",
2486
0
            "osl::DirectoryItem::getFileStatus failed with " << +aRes);
2487
0
        return false;
2488
0
    }
2489
2490
96.6k
    aUnqPath = aFileStatus.getFileURL();
2491
2492
    // If the directory item type is a link retrieve the type of the target
2493
2494
96.6k
    if ( aFileStatus.getFileType() == osl::FileStatus::Link )
2495
0
    {
2496
        // Assume failure
2497
0
        aIsRegular = false;
2498
0
        osl::DirectoryItem aTargetItem;
2499
0
        (void)osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
2500
0
        if ( aTargetItem.is() )
2501
0
        {
2502
0
            osl::FileStatus aTargetStatus( osl_FileStatus_Mask_Type );
2503
2504
0
            if ( osl::FileBase::E_None == aTargetItem.getFileStatus( aTargetStatus ) )
2505
0
                aIsRegular =
2506
0
                    aTargetStatus.getFileType() == osl::FileStatus::Regular;
2507
0
        }
2508
0
    }
2509
96.6k
    else
2510
96.6k
        aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
2511
2512
96.6k
    {
2513
96.6k
        std::unique_lock aGuard( m_aMutex );
2514
2515
96.6k
        insertDefaultProperties( aGuard, aUnqPath );
2516
2517
96.6k
        TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
2518
96.6k
        commit( aGuard, it, aFileStatus );
2519
2520
96.6k
        PropertySet& propset = it->second.properties;
2521
2522
96.6k
        std::transform(properties.begin(), properties.end(), seq.getArray(),
2523
96.6k
            [&propset](const beans::Property& rProp) -> uno::Any {
2524
96.6k
                MyProperty readProp( rProp.Name );
2525
96.6k
                auto it1 = propset.find( readProp );
2526
96.6k
                if( it1 == propset.end() )
2527
0
                    return uno::Any();
2528
96.6k
                return it1->getValue();
2529
96.6k
            });
2530
96.6k
    }
2531
2532
96.6k
    row = new XRow_impl( this,seq );
2533
96.6k
    return true;
2534
96.6k
}
2535
2536
2537
// EventListener
2538
2539
2540
std::vector< ContentEventNotifier >
2541
TaskManager::getContentEventListeners( const OUString& aName )
2542
0
{
2543
0
    std::vector< ContentEventNotifier > listeners;
2544
0
    {
2545
0
        std::unique_lock aGuard( m_aMutex );
2546
0
        TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2547
0
        if( it != m_aContent.end() && !it->second.notifier.empty() )
2548
0
        {
2549
0
            std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2550
0
            for (auto const& pointer : listOfNotifiers)
2551
0
            {
2552
0
                std::optional<ContentEventNotifier> notifier = pointer->cCEL();
2553
0
                if( notifier )
2554
0
                    listeners.push_back( std::move(*notifier) );
2555
0
            }
2556
0
        }
2557
0
    }
2558
0
    return listeners;
2559
0
}
2560
2561
2562
std::vector< ContentEventNotifier >
2563
TaskManager::getContentDeletedEventListeners( const OUString& aName )
2564
0
{
2565
0
    std::vector< ContentEventNotifier > listeners;
2566
0
    {
2567
0
        std::unique_lock aGuard( m_aMutex );
2568
0
        TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2569
0
        if( it != m_aContent.end() && !it->second.notifier.empty() )
2570
0
        {
2571
0
            std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2572
0
            for (auto const& pointer : listOfNotifiers)
2573
0
            {
2574
0
                std::optional<ContentEventNotifier> notifier = pointer->cDEL();
2575
0
                if( notifier )
2576
0
                    listeners.push_back( std::move(*notifier) );
2577
0
            }
2578
0
        }
2579
0
    }
2580
0
    return listeners;
2581
0
}
2582
2583
void TaskManager::notifyInsert(const std::vector<ContentEventNotifier>& listeners,
2584
                               const OUString& aChildName)
2585
0
{
2586
0
    for (const auto & l : listeners )
2587
0
    {
2588
0
        l.notifyChildInserted( aChildName );
2589
0
    }
2590
0
}
2591
2592
void TaskManager::notifyContentDeleted(
2593
    const std::vector<ContentEventNotifier>& listeners)
2594
0
{
2595
0
    for( auto const & l : listeners )
2596
0
    {
2597
0
        l.notifyDeleted();
2598
0
    }
2599
0
}
2600
2601
void TaskManager::notifyContentRemoved(
2602
    const std::vector<ContentEventNotifier>& listeners, const OUString& aChildName)
2603
0
{
2604
0
    for( auto const & l : listeners )
2605
0
    {
2606
0
        l.notifyRemoved( aChildName );
2607
0
    }
2608
0
}
2609
2610
2611
std::vector< PropertySetInfoChangeNotifier >
2612
TaskManager::getPropertySetListeners( const OUString& aName )
2613
0
{
2614
0
    std::vector< PropertySetInfoChangeNotifier > listeners;
2615
0
    {
2616
0
        std::unique_lock aGuard( m_aMutex );
2617
0
        TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2618
0
        if( it != m_aContent.end() && !it->second.notifier.empty() )
2619
0
        {
2620
0
            std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2621
0
            for (auto const& pointer : listOfNotifiers)
2622
0
            {
2623
0
                std::optional<PropertySetInfoChangeNotifier> notifier = pointer->cPSL();
2624
0
                if( notifier )
2625
0
                    listeners.push_back( std::move(*notifier) );
2626
0
            }
2627
0
        }
2628
0
    }
2629
0
    return listeners;
2630
0
}
2631
2632
void TaskManager::notifyPropertyAdded(
2633
    const std::vector<PropertySetInfoChangeNotifier>& listeners,
2634
    const OUString& aPropertyName)
2635
0
{
2636
0
    for( auto const & l : listeners )
2637
0
    {
2638
0
        l.notifyPropertyAdded( aPropertyName );
2639
0
    }
2640
0
}
2641
2642
void TaskManager::notifyPropertyRemoved(
2643
    const std::vector<PropertySetInfoChangeNotifier>& listeners,
2644
    const OUString& aPropertyName)
2645
0
{
2646
0
    for( auto const & l : listeners )
2647
0
    {
2648
0
        l.notifyPropertyRemoved( aPropertyName );
2649
0
    }
2650
0
}
2651
2652
2653
std::vector< ContentEventNotifier >
2654
TaskManager::getContentExchangedEventListeners( const OUString& aOldPrefix,
2655
                                          const OUString& aNewPrefix,
2656
                                          bool withChildren )
2657
0
{
2658
0
    std::vector< ContentEventNotifier > aVector;
2659
2660
0
    sal_Int32 count;
2661
0
    OUString aOldName;
2662
0
    OUString aNewName;
2663
0
    std::vector< OUString > oldChildList;
2664
2665
0
    {
2666
0
        std::unique_lock aGuard( m_aMutex );
2667
2668
0
        if( ! withChildren )
2669
0
        {
2670
0
            aOldName = aOldPrefix;
2671
0
            aNewName = aNewPrefix;
2672
0
            count = 1;
2673
0
        }
2674
0
        else
2675
0
        {
2676
0
            for (auto const& content : m_aContent)
2677
0
            {
2678
0
                if( isChild( aOldPrefix, content.first ) )
2679
0
                {
2680
0
                    oldChildList.push_back( content.first );
2681
0
                }
2682
0
            }
2683
0
            count = oldChildList.size();
2684
0
        }
2685
2686
2687
0
        for( sal_Int32 j = 0; j < count; ++j )
2688
0
        {
2689
0
            if( withChildren )
2690
0
            {
2691
0
                aOldName = oldChildList[j];
2692
0
                aNewName = newName( aNewPrefix,aOldPrefix,aOldName );
2693
0
            }
2694
2695
0
            TaskManager::ContentMap::iterator itold = m_aContent.find( aOldName );
2696
0
            if( itold != m_aContent.end() )
2697
0
            {
2698
0
                TaskManager::ContentMap::iterator itnew = m_aContent.emplace(
2699
0
                    aNewName,UnqPathData() ).first;
2700
2701
                // copy Ownership also
2702
0
                itnew->second.properties = std::move(itold->second.properties);
2703
2704
                // copy existing list
2705
0
                std::vector< Notifier* > copyList;
2706
0
                std::swap(copyList, itnew->second.notifier);
2707
0
                itnew->second.notifier = std::move(itold->second.notifier);
2708
2709
0
                m_aContent.erase( itold );
2710
2711
0
                if (itnew != m_aContent.end())
2712
0
                {
2713
0
                    if (!itnew->second.notifier.empty())
2714
0
                    {
2715
0
                        std::vector<Notifier*>& listOfNotifiers = itnew->second.notifier;
2716
0
                        for (auto const& pointer : listOfNotifiers)
2717
0
                        {
2718
0
                            std::optional<ContentEventNotifier> notifier = pointer->cEXC( aNewName );
2719
0
                            if( notifier )
2720
0
                                aVector.push_back( std::move(*notifier) );
2721
0
                        }
2722
0
                    }
2723
2724
                    // Merge with preexisting notifiers
2725
                    // However, these may be in status BaseContent::Deleted
2726
0
                    itnew->second.notifier.insert(itnew->second.notifier.end(),
2727
0
                        copyList.begin(), copyList.end() );
2728
0
                }
2729
0
            }
2730
0
        }
2731
0
    }
2732
2733
0
    return aVector;
2734
0
}
2735
2736
void TaskManager::notifyContentExchanged(
2737
    const std::vector<ContentEventNotifier>& listeners_vec)
2738
0
{
2739
0
    for( auto & l : listeners_vec)
2740
0
    {
2741
0
        l.notifyExchanged();
2742
0
    }
2743
0
}
2744
2745
2746
std::vector< PropertyChangeNotifier >
2747
TaskManager::getPropertyChangeNotifier( const OUString& aName )
2748
0
{
2749
0
    std::vector< PropertyChangeNotifier > listeners;
2750
0
    {
2751
0
        std::unique_lock aGuard( m_aMutex );
2752
0
        TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2753
0
        if( it != m_aContent.end() && !it->second.notifier.empty() )
2754
0
        {
2755
0
            std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2756
0
            for (auto const& pointer : listOfNotifiers)
2757
0
            {
2758
0
                std::optional<PropertyChangeNotifier> notifier = pointer->cPCL();
2759
0
                if( notifier )
2760
0
                    listeners.push_back( std::move(*notifier) );
2761
0
            }
2762
0
        }
2763
0
    }
2764
0
    return listeners;
2765
0
}
2766
2767
void TaskManager::notifyPropertyChanges(
2768
    const std::vector<PropertyChangeNotifier>& listeners,
2769
    const uno::Sequence<beans::PropertyChangeEvent>& seqChanged)
2770
0
{
2771
0
    for( auto const & l : listeners )
2772
0
    {
2773
0
        l.notifyPropertyChanged( seqChanged );
2774
0
    }
2775
0
}
2776
2777
2778
/********************************************************************************/
2779
/*                       remove persistent propertyset                          */
2780
/********************************************************************************/
2781
2782
void
2783
TaskManager::erasePersistentSetWithoutChildren( const OUString& aUnqPath )
2784
0
{
2785
0
    {
2786
        // Release possible references
2787
0
        std::unique_lock aGuard( m_aMutex );
2788
0
        ContentMap::iterator it = m_aContent.find( aUnqPath );
2789
0
        if( it != m_aContent.end() )
2790
0
        {
2791
0
            it->second.xS = nullptr;
2792
0
            it->second.xC = nullptr;
2793
0
            it->second.xA = nullptr;
2794
2795
0
            it->second.properties.clear();
2796
0
        }
2797
0
    }
2798
2799
0
    m_xFileRegistry->removePropertySet( aUnqPath );
2800
0
}
2801
2802
void
2803
TaskManager::erasePersistentSet( const OUString& aUnqPath,
2804
                           bool withChildren )
2805
0
{
2806
0
    if( ! m_xFileRegistry.is() )
2807
0
    {
2808
0
        OSL_ASSERT( m_xFileRegistry.is() );
2809
0
        return;
2810
0
    }
2811
2812
0
    if( ! withChildren )
2813
0
    {
2814
0
        erasePersistentSetWithoutChildren(aUnqPath);
2815
0
        return;
2816
0
    }
2817
2818
0
    uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
2819
0
    const uno::Sequence< OUString > seqNames = xName->getElementNames();
2820
2821
0
    OUString old_Name = aUnqPath;
2822
2823
0
    for( const auto& rName : seqNames )
2824
0
    {
2825
0
        if( ! ( isChild( old_Name,rName ) ) )
2826
0
            continue;
2827
2828
0
        old_Name = rName;
2829
2830
0
        erasePersistentSetWithoutChildren(old_Name);
2831
0
    }
2832
0
}
2833
2834
2835
/********************************************************************************/
2836
/*                       copy persistent propertyset                            */
2837
/*                       from srcUnqPath to dstUnqPath                          */
2838
/********************************************************************************/
2839
2840
void
2841
TaskManager::copyPersistentSetWithoutChildren( const OUString& srcUnqPath,
2842
                          const OUString& dstUnqPath )
2843
0
{
2844
0
    uno::Reference< XPersistentPropertySet > x_src =
2845
0
            m_xFileRegistry->openPropertySet( srcUnqPath,false );
2846
0
    m_xFileRegistry->removePropertySet( dstUnqPath );
2847
2848
0
    if( ! x_src.is() )
2849
0
        return;
2850
2851
0
    const uno::Sequence< beans::Property > seqProperty =
2852
0
        x_src->getPropertySetInfo()->getProperties();
2853
2854
0
    if( ! seqProperty.hasElements() )
2855
0
        return;
2856
2857
0
    uno::Reference< XPersistentPropertySet >
2858
0
        x_dstS = m_xFileRegistry->openPropertySet( dstUnqPath,true );
2859
0
    uno::Reference< beans::XPropertyContainer >
2860
0
        x_dstC( x_dstS,uno::UNO_QUERY );
2861
2862
0
    for( const auto& rProperty : seqProperty )
2863
0
    {
2864
0
        x_dstC->addProperty( rProperty.Name,
2865
0
                             rProperty.Attributes,
2866
0
                             x_src->getPropertyValue( rProperty.Name ) );
2867
0
    }
2868
0
}
2869
2870
void
2871
TaskManager::copyPersistentSet( const OUString& srcUnqPath,
2872
                          const OUString& dstUnqPath,
2873
                          bool withChildren )
2874
0
{
2875
0
    if( ! m_xFileRegistry.is() )
2876
0
    {
2877
0
        OSL_ASSERT( m_xFileRegistry.is() );
2878
0
        return;
2879
0
    }
2880
2881
0
    if( ! withChildren )
2882
0
    {
2883
0
        copyPersistentSetWithoutChildren(srcUnqPath, dstUnqPath);
2884
0
        return;
2885
0
    }
2886
2887
0
    uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
2888
0
    const uno::Sequence< OUString > seqNames = xName->getElementNames();
2889
2890
0
    OUString new_Name;
2891
2892
0
    for( const auto& rName : seqNames )
2893
0
    {
2894
0
        if( ! ( isChild( srcUnqPath,rName ) ) )
2895
0
            continue;
2896
2897
0
        new_Name = newName( dstUnqPath,srcUnqPath,rName );
2898
2899
0
        copyPersistentSetWithoutChildren(rName, new_Name);
2900
0
    }
2901
0
}
2902
2903
uno::Sequence< ucb::ContentInfo > TaskManager::queryCreatableContentsInfo()
2904
9.73k
{
2905
2906
2907
9.73k
    uno::Sequence< beans::Property > props
2908
9.73k
    {
2909
9.73k
        { u"Title"_ustr, -1, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND }
2910
9.73k
    };
2911
9.73k
    return
2912
9.73k
    {
2913
9.73k
        { FileContentType, ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM | ucb::ContentInfoAttribute::KIND_DOCUMENT, props },
2914
9.73k
        { FolderContentType, ucb::ContentInfoAttribute::KIND_FOLDER, props }
2915
9.73k
    };
2916
9.73k
}
2917
2918
/*******************************************************************************/
2919
/*                                                                             */
2920
/*                 some miscellaneous static functions                        */
2921
/*                                                                             */
2922
/*******************************************************************************/
2923
2924
void
2925
TaskManager::getScheme( OUString& Scheme )
2926
186k
{
2927
186k
  Scheme = "file";
2928
186k
}
2929
2930
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */