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