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