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