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