xref: /aoo42x/main/ucb/source/ucp/file/bc.cxx (revision 47e5fad4)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26 #include <rtl/uri.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <osl/file.hxx>
29 
30 #include "osl/diagnose.h"
31 #include <com/sun/star/ucb/OpenMode.hpp>
32 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #endif
35 #include <com/sun/star/ucb/XProgressHandler.hpp>
36 #include <com/sun/star/task/XInteractionHandler.hpp>
37 #include <com/sun/star/io/XActiveDataStreamer.hpp>
38 #include <com/sun/star/io/XOutputStream.hpp>
39 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
40 #include <com/sun/star/io/XActiveDataSink.hpp>
41 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
42 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
43 #include <com/sun/star/ucb/ContentAction.hpp>
44 #include <com/sun/star/ucb/NameClash.hpp>
45 #include "filglob.hxx"
46 #include "filid.hxx"
47 #include "filrow.hxx"
48 #include "bc.hxx"
49 #include "prov.hxx"
50 #ifndef _FILERROR_HXX_
51 #include "filerror.hxx"
52 #endif
53 #include "filinsreq.hxx"
54 
55 
56 using namespace fileaccess;
57 using namespace com::sun::star;
58 using namespace com::sun::star::uno;
59 using namespace com::sun::star::ucb;
60 
61 // PropertyListeners
62 
63 
64 typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
65 PropertyListeners_impl;
66 
67 class fileaccess::PropertyListeners
68     : public PropertyListeners_impl
69 {
70 public:
71     PropertyListeners( ::osl::Mutex& aMutex )
72         : PropertyListeners_impl( aMutex )
73     {
74     }
75 };
76 
77 
78 /****************************************************************************************/
79 /*                                                                                      */
80 /*                    BaseContent                                                       */
81 /*                                                                                      */
82 /****************************************************************************************/
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 // Private Constructor for just inserted Contents
86 
87 BaseContent::BaseContent( shell* pMyShell,
88                           const rtl::OUString& parentName,
89                           sal_Bool bFolder )
90     : m_pMyShell( pMyShell ),
91       m_xContentIdentifier( 0 ),
92       m_aUncPath( parentName ),
93       m_bFolder( bFolder ),
94       m_nState( JustInserted ),
95       m_pDisposeEventListeners( 0 ),
96       m_pContentEventListeners( 0 ),
97       m_pPropertySetInfoChangeListeners( 0 ),
98       m_pPropertyListener( 0 )
99 {
100     m_pMyShell->m_pProvider->acquire();
101     // No registering, since we have no name
102 }
103 
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 // Constructor for full featured Contents
107 
108 BaseContent::BaseContent( shell* pMyShell,
109                           const Reference< XContentIdentifier >& xContentIdentifier,
110                           const rtl::OUString& aUncPath )
111     : m_pMyShell( pMyShell ),
112       m_xContentIdentifier( xContentIdentifier ),
113       m_aUncPath( aUncPath ),
114       m_bFolder( false ),
115       m_nState( FullFeatured ),
116       m_pDisposeEventListeners( 0 ),
117       m_pContentEventListeners( 0 ),
118       m_pPropertySetInfoChangeListeners( 0 ),
119       m_pPropertyListener( 0 )
120 {
121     m_pMyShell->m_pProvider->acquire();
122     m_pMyShell->registerNotifier( m_aUncPath,this );
123     m_pMyShell->insertDefaultProperties( m_aUncPath );
124 }
125 
126 
127 BaseContent::~BaseContent( )
128 {
129     if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
130     {
131         m_pMyShell->deregisterNotifier( m_aUncPath,this );
132     }
133     m_pMyShell->m_pProvider->release();
134 
135     delete m_pDisposeEventListeners;
136     delete m_pContentEventListeners;
137     delete m_pPropertyListener;
138     delete m_pPropertySetInfoChangeListeners;
139 }
140 
141 
142 //////////////////////////////////////////////////////////////////////////
143 // XInterface
144 //////////////////////////////////////////////////////////////////////////
145 
146 void SAL_CALL
147 BaseContent::acquire( void )
148     throw()
149 {
150     OWeakObject::acquire();
151 }
152 
153 
154 void SAL_CALL
155 BaseContent::release( void )
156     throw()
157 {
158     OWeakObject::release();
159 }
160 
161 
162 Any SAL_CALL
163 BaseContent::queryInterface( const Type& rType )
164     throw( RuntimeException )
165 {
166     Any aRet = cppu::queryInterface( rType,
167                                      SAL_STATIC_CAST( lang::XComponent*, this ),
168                                      SAL_STATIC_CAST( lang::XTypeProvider*, this ),
169                                      SAL_STATIC_CAST( lang::XServiceInfo*, this ),
170                                      SAL_STATIC_CAST( XCommandProcessor*, this ),
171                                      SAL_STATIC_CAST( container::XChild*, this ),
172                                      SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ),
173                                      SAL_STATIC_CAST( beans::XPropertyContainer*, this ),
174                                      SAL_STATIC_CAST( XContentCreator*,this ),
175                                      SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ),
176                                      SAL_STATIC_CAST( XContent*,this) );
177     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
178 }
179 
180 
181 
182 
183 //////////////////////////////////////////////////////////////////////////////////////////
184 // XComponent
185 ////////////////////////////////////////////////////////////////////////////////////////
186 
187 void SAL_CALL
188 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
189     throw( RuntimeException )
190 {
191     osl::MutexGuard aGuard( m_aMutex );
192 
193     if ( ! m_pDisposeEventListeners )
194         m_pDisposeEventListeners =
195             new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
196 
197     m_pDisposeEventListeners->addInterface( Listener );
198 }
199 
200 
201 void SAL_CALL
202 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
203     throw( RuntimeException )
204 {
205     osl::MutexGuard aGuard( m_aMutex );
206 
207     if ( m_pDisposeEventListeners )
208         m_pDisposeEventListeners->removeInterface( Listener );
209 }
210 
211 
212 void SAL_CALL
213 BaseContent::dispose()
214     throw( RuntimeException )
215 {
216     lang::EventObject aEvt;
217     cppu::OInterfaceContainerHelper* pDisposeEventListeners;
218     cppu::OInterfaceContainerHelper* pContentEventListeners;
219     cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
220     PropertyListeners* pPropertyListener;
221 
222     {
223         osl::MutexGuard aGuard( m_aMutex );
224         aEvt.Source = static_cast< XContent* >( this );
225 
226 
227         pDisposeEventListeners =
228             m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
229 
230         pContentEventListeners =
231             m_pContentEventListeners, m_pContentEventListeners = 0;
232 
233         pPropertySetInfoChangeListeners =
234             m_pPropertySetInfoChangeListeners,
235             m_pPropertySetInfoChangeListeners = 0;
236 
237         pPropertyListener =
238             m_pPropertyListener, m_pPropertyListener = 0;
239     }
240 
241     if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
242         pDisposeEventListeners->disposeAndClear( aEvt );
243 
244     if ( pContentEventListeners && pContentEventListeners->getLength() )
245         pContentEventListeners->disposeAndClear( aEvt );
246 
247     if( pPropertyListener )
248         pPropertyListener->disposeAndClear( aEvt );
249 
250     if( pPropertySetInfoChangeListeners )
251         pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
252 
253     delete pDisposeEventListeners;
254     delete pContentEventListeners;
255     delete pPropertyListener;
256     delete pPropertySetInfoChangeListeners;
257 }
258 
259 
260 
261 //////////////////////////////////////////////////////////////////////////////////////////
262 //  XServiceInfo
263 //////////////////////////////////////////////////////////////////////////////////////////
264 
265 rtl::OUString SAL_CALL
266 BaseContent::getImplementationName()
267     throw( RuntimeException)
268 {
269     return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" );
270 }
271 
272 
273 
274 sal_Bool SAL_CALL
275 BaseContent::supportsService( const rtl::OUString& ServiceName )
276     throw( RuntimeException)
277 {
278     if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 )
279         return true;
280     else
281         return false;
282 }
283 
284 
285 
286 Sequence< rtl::OUString > SAL_CALL
287 BaseContent::getSupportedServiceNames()
288     throw( RuntimeException )
289 {
290     Sequence< rtl::OUString > ret( 1 );
291     ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" );
292     return ret;
293 }
294 
295 
296 
297 //////////////////////////////////////////////////////////////////////////////////////////
298 //  XTypeProvider
299 //////////////////////////////////////////////////////////////////////////////////////////
300 
301 XTYPEPROVIDER_IMPL_10( BaseContent,
302                        lang::XComponent,
303                        lang::XTypeProvider,
304                        lang::XServiceInfo,
305                        XCommandProcessor,
306                        XContentCreator,
307                        XContent,
308                        container::XChild,
309                        beans::XPropertiesChangeNotifier,
310                        beans::XPropertyContainer,
311                        beans::XPropertySetInfoChangeNotifier )
312 
313 
314 //////////////////////////////////////////////////////////////////////////////////////////
315 //  XCommandProcessor
316 //////////////////////////////////////////////////////////////////////////////////////////
317 
318 sal_Int32 SAL_CALL
319 BaseContent::createCommandIdentifier( void )
320     throw( RuntimeException )
321 {
322     return m_pMyShell->getCommandId();
323 }
324 
325 
326 void SAL_CALL
327 BaseContent::abort( sal_Int32 CommandId )
328     throw( RuntimeException )
329 {
330     m_pMyShell->abort( CommandId );
331 }
332 
333 
334 Any SAL_CALL
335 BaseContent::execute( const Command& aCommand,
336                       sal_Int32 CommandId,
337                       const Reference< XCommandEnvironment >& Environment )
338     throw( Exception,
339            CommandAbortedException,
340            RuntimeException )
341 {
342     if( ! CommandId )
343         // A Command with commandid zero cannot be aborted
344         CommandId = createCommandIdentifier();
345 
346     m_pMyShell->startTask( CommandId,
347                            Environment );
348 
349     Any aAny;
350 
351     if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) )  // No exceptions
352     {
353         aAny <<= getPropertySetInfo( CommandId );
354     }
355     else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) )  // no exceptions
356     {
357         aAny <<= getCommandInfo();
358     }
359     else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) )
360     {
361         Sequence< beans::PropertyValue > sPropertyValues;
362 
363         if( ! ( aCommand.Argument >>= sPropertyValues ) )
364             m_pMyShell->installError( CommandId,
365                                       TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
366         else
367             aAny <<= setPropertyValues( CommandId,sPropertyValues );  // calls endTask by itself
368     }
369     else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) )
370     {
371         Sequence< beans::Property > ListOfRequestedProperties;
372 
373         if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
374             m_pMyShell->installError( CommandId,
375                                       TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
376         else
377             aAny <<= getPropertyValues( CommandId,
378                                         ListOfRequestedProperties );
379     }
380     else if( ! aCommand.Name.compareToAscii( "open" ) )
381     {
382         OpenCommandArgument2 aOpenArgument;
383         if( ! ( aCommand.Argument >>= aOpenArgument ) )
384             m_pMyShell->installError( CommandId,
385                                       TASKHANDLING_WRONG_OPEN_ARGUMENT );
386         else
387         {
388             Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
389             if( result.is() )
390                 aAny <<= result;
391         }
392     }
393     else if( ! aCommand.Name.compareToAscii( "delete" ) )
394     {
395         if( ! aCommand.Argument.has< sal_Bool >() )
396             m_pMyShell->installError( CommandId,
397                                       TASKHANDLING_WRONG_DELETE_ARGUMENT );
398         else
399             deleteContent( CommandId );
400     }
401     else if( ! aCommand.Name.compareToAscii( "transfer" ) )
402     {
403         TransferInfo aTransferInfo;
404         if( ! ( aCommand.Argument >>= aTransferInfo ) )
405             m_pMyShell->installError( CommandId,
406                                       TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
407         else
408             transfer( CommandId, aTransferInfo );
409     }
410     else if( ! aCommand.Name.compareToAscii( "insert" ) )
411     {
412         InsertCommandArgument aInsertArgument;
413         if( ! ( aCommand.Argument >>= aInsertArgument ) )
414             m_pMyShell->installError( CommandId,
415                                       TASKHANDLING_WRONG_INSERT_ARGUMENT );
416         else
417             insert( CommandId,aInsertArgument );
418     }
419     else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) )
420     {
421         Sequence< beans::Property > seq(1);
422         seq[0] = beans::Property(
423             rtl::OUString::createFromAscii("CasePreservingURL"),
424             -1,
425             getCppuType( static_cast< sal_Bool* >(0) ),
426             0 );
427         Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
428         rtl::OUString CasePreservingURL = xRow->getString(1);
429         if(!xRow->wasNull())
430             aAny <<= CasePreservingURL;
431     }
432     else if( ! aCommand.Name.compareToAscii( "createNewContent" ) )
433     {
434         ucb::ContentInfo aArg;
435         if ( !( aCommand.Argument >>= aArg ) )
436             m_pMyShell->installError( CommandId,
437                                       TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
438         else
439             aAny <<= createNewContent( aArg );
440     }
441     else
442         m_pMyShell->installError( CommandId,
443                                   TASKHANDLER_UNSUPPORTED_COMMAND );
444 
445 
446     // This is the only function allowed to throw an exception
447     endTask( CommandId );
448 
449     return aAny;
450 }
451 
452 
453 
454 void SAL_CALL
455 BaseContent::addPropertiesChangeListener(
456     const Sequence< rtl::OUString >& PropertyNames,
457     const Reference< beans::XPropertiesChangeListener >& Listener )
458     throw( RuntimeException )
459 {
460     if( ! Listener.is() )
461         return;
462 
463     osl::MutexGuard aGuard( m_aMutex );
464 
465     if( ! m_pPropertyListener )
466         m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex );
467 
468 
469     if( PropertyNames.getLength() == 0 )
470         m_pPropertyListener->addInterface( rtl::OUString(),Listener );
471     else
472     {
473         Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
474         for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
475             if( xProp->hasPropertyByName( PropertyNames[i] ) )
476                 m_pPropertyListener->addInterface( PropertyNames[i],Listener );
477     }
478 }
479 
480 
481 void SAL_CALL
482 BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames,
483                                              const Reference< beans::XPropertiesChangeListener >& Listener )
484     throw( RuntimeException )
485 {
486     if( ! Listener.is() )
487         return;
488 
489     osl::MutexGuard aGuard( m_aMutex );
490 
491     if( ! m_pPropertyListener )
492         return;
493 
494     for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
495         m_pPropertyListener->removeInterface( PropertyNames[i],Listener );
496 
497     m_pPropertyListener->removeInterface( rtl::OUString(), Listener );
498 }
499 
500 
501 /////////////////////////////////////////////////////////////////////////////////////////
502 // XContent
503 /////////////////////////////////////////////////////////////////////////////////////////
504 
505 Reference< ucb::XContentIdentifier > SAL_CALL
506 BaseContent::getIdentifier()
507     throw( RuntimeException )
508 {
509     return m_xContentIdentifier;
510 }
511 
512 
513 rtl::OUString SAL_CALL
514 BaseContent::getContentType()
515     throw( RuntimeException )
516 {
517     if( !( m_nState & Deleted ) )
518     {
519         if( m_nState & JustInserted )
520         {
521             if ( m_bFolder )
522                 return m_pMyShell->FolderContentType;
523             else
524                 return m_pMyShell->FileContentType;
525         }
526         else
527         {
528             try
529             {
530                 // Who am I ?
531                 Sequence< beans::Property > seq(1);
532                 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
533                                           -1,
534                                           getCppuType( static_cast< sal_Bool* >(0) ),
535                                           0 );
536                 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
537                 sal_Bool IsDocument = xRow->getBoolean( 1 );
538 
539                 if ( !xRow->wasNull() )
540                 {
541                     if ( IsDocument )
542                         return m_pMyShell->FileContentType;
543                     else
544                         return m_pMyShell->FolderContentType;
545                 }
546                 else
547                 {
548                     OSL_ENSURE( false,
549                                 "BaseContent::getContentType - Property value was null!" );
550                 }
551             }
552             catch ( sdbc::SQLException const & )
553             {
554                 OSL_ENSURE( false,
555                             "BaseContent::getContentType - Caught SQLException!" );
556             }
557         }
558     }
559 
560     return rtl::OUString();
561 }
562 
563 
564 
565 void SAL_CALL
566 BaseContent::addContentEventListener(
567     const Reference< XContentEventListener >& Listener )
568     throw( RuntimeException )
569 {
570     osl::MutexGuard aGuard( m_aMutex );
571 
572     if ( ! m_pContentEventListeners )
573         m_pContentEventListeners =
574             new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
575 
576 
577     m_pContentEventListeners->addInterface( Listener );
578 }
579 
580 
581 void SAL_CALL
582 BaseContent::removeContentEventListener(
583     const Reference< XContentEventListener >& Listener )
584     throw( RuntimeException )
585 {
586     osl::MutexGuard aGuard( m_aMutex );
587 
588     if ( m_pContentEventListeners )
589         m_pContentEventListeners->removeInterface( Listener );
590 }
591 
592 
593 
594 ////////////////////////////////////////////////////////////////////////////////
595 // XPropertyContainer
596 ////////////////////////////////////////////////////////////////////////////////
597 
598 
599 void SAL_CALL
600 BaseContent::addProperty(
601     const rtl::OUString& Name,
602     sal_Int16 Attributes,
603     const Any& DefaultValue )
604     throw( beans::PropertyExistException,
605            beans::IllegalTypeException,
606            lang::IllegalArgumentException,
607            RuntimeException)
608 {
609     if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() )
610     {
611         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
612     }
613 
614     m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
615 }
616 
617 
618 void SAL_CALL
619 BaseContent::removeProperty(
620     const rtl::OUString& Name )
621     throw( beans::UnknownPropertyException,
622            beans::NotRemoveableException,
623            RuntimeException)
624 {
625 
626     if( m_nState & Deleted )
627         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
628 
629     m_pMyShell->deassociate( m_aUncPath, Name );
630 }
631 
632 ////////////////////////////////////////////////////////////////////////////////
633 // XContentCreator
634 ////////////////////////////////////////////////////////////////////////////////
635 
636 Sequence< ContentInfo > SAL_CALL
637 BaseContent::queryCreatableContentsInfo(
638     void )
639     throw( RuntimeException )
640 {
641     return m_pMyShell->queryCreatableContentsInfo();
642 }
643 
644 
645 Reference< XContent > SAL_CALL
646 BaseContent::createNewContent(
647     const ContentInfo& Info )
648     throw( RuntimeException )
649 {
650     // Check type.
651     if ( !Info.Type.getLength() )
652         return Reference< XContent >();
653 
654     sal_Bool bFolder
655         = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
656     if ( !bFolder )
657     {
658         if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
659         {
660             // Neither folder nor file to create!
661             return Reference< XContent >();
662         }
663     }
664 
665     // Who am I ?
666     sal_Bool IsDocument = false;
667 
668     try
669     {
670         Sequence< beans::Property > seq(1);
671         seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
672                                   -1,
673                                   getCppuType( static_cast< sal_Bool* >(0) ),
674                                   0 );
675         Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
676         IsDocument = xRow->getBoolean( 1 );
677 
678         if ( xRow->wasNull() )
679         {
680             IsDocument = false;
681 //              OSL_ENSURE( false,
682 //                          "BaseContent::createNewContent - Property value was null!" );
683 //              return Reference< XContent >();
684         }
685     }
686     catch ( sdbc::SQLException const & )
687     {
688         OSL_ENSURE( false,
689                     "BaseContent::createNewContent - Caught SQLException!" );
690         return Reference< XContent >();
691     }
692 
693     rtl::OUString dstUncPath;
694 
695     if( IsDocument )
696     {
697         // KSO: Why is a document a XContentCreator? This is quite unusual.
698         dstUncPath = getParentName( m_aUncPath );
699     }
700     else
701         dstUncPath = m_aUncPath;
702 
703     BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
704     return Reference< XContent >( p );
705 }
706 
707 
708 ////////////////////////////////////////////////////////////////////////////////
709 // XPropertySetInfoChangeNotifier
710 ////////////////////////////////////////////////////////////////////////////////
711 
712 
713 void SAL_CALL
714 BaseContent::addPropertySetInfoChangeListener(
715     const Reference< beans::XPropertySetInfoChangeListener >& Listener )
716     throw( RuntimeException )
717 {
718     osl::MutexGuard aGuard( m_aMutex );
719     if( ! m_pPropertySetInfoChangeListeners )
720         m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
721 
722     m_pPropertySetInfoChangeListeners->addInterface( Listener );
723 }
724 
725 
726 void SAL_CALL
727 BaseContent::removePropertySetInfoChangeListener(
728     const Reference< beans::XPropertySetInfoChangeListener >& Listener )
729     throw( RuntimeException )
730 {
731     osl::MutexGuard aGuard( m_aMutex );
732 
733     if( m_pPropertySetInfoChangeListeners )
734         m_pPropertySetInfoChangeListeners->removeInterface( Listener );
735 }
736 
737 
738 ////////////////////////////////////////////////////////////////////////////////
739 // XChild
740 ////////////////////////////////////////////////////////////////////////////////
741 
742 Reference< XInterface > SAL_CALL
743 BaseContent::getParent(
744     void )
745     throw( RuntimeException )
746 {
747     rtl::OUString ParentUnq = getParentName( m_aUncPath );
748     rtl::OUString ParentUrl;
749 
750 
751     sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
752     if( err )
753         return Reference< XInterface >( 0 );
754 
755     FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
756     Reference< XContentIdentifier > Identifier( p );
757 
758     try
759     {
760         Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
761         return Reference<XInterface>(content,UNO_QUERY);
762     }
763     catch( IllegalIdentifierException )
764     {
765         return Reference< XInterface >();
766     }
767 }
768 
769 
770 void SAL_CALL
771 BaseContent::setParent(
772     const Reference< XInterface >& )
773     throw( lang::NoSupportException,
774            RuntimeException)
775 {
776     throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
777 }
778 
779 
780 //////////////////////////////////////////////////////////////////////////////////////////
781 // Private Methods
782 //////////////////////////////////////////////////////////////////////////////////////////
783 
784 
785 Reference< XCommandInfo > SAL_CALL
786 BaseContent::getCommandInfo()
787     throw( RuntimeException )
788 {
789     if( m_nState & Deleted )
790         return Reference< XCommandInfo >();
791 
792     return m_pMyShell->info_c();
793 }
794 
795 
796 Reference< beans::XPropertySetInfo > SAL_CALL
797 BaseContent::getPropertySetInfo(
798     sal_Int32 )
799     throw( RuntimeException )
800 {
801     if( m_nState & Deleted )
802         return Reference< beans::XPropertySetInfo >();
803 
804     return m_pMyShell->info_p( m_aUncPath );
805 }
806 
807 
808 
809 
810 Reference< sdbc::XRow > SAL_CALL
811 BaseContent::getPropertyValues(
812     sal_Int32 nMyCommandIdentifier,
813     const Sequence< beans::Property >& PropertySet )
814     throw( RuntimeException )
815 {
816     sal_Int32 nProps = PropertySet.getLength();
817     if ( !nProps )
818         return Reference< sdbc::XRow >();
819 
820     if( m_nState & Deleted )
821     {
822         Sequence< Any > aValues( nProps );
823         return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
824     }
825 
826     if( m_nState & JustInserted )
827     {
828         Sequence< Any > aValues( nProps );
829         Any* pValues = aValues.getArray();
830 
831         const beans::Property* pProps = PropertySet.getConstArray();
832 
833         for ( sal_Int32 n = 0; n < nProps; ++n )
834         {
835             const beans::Property& rProp = pProps[ n ];
836             Any& rValue = pValues[ n ];
837 
838             if( rProp.Name.compareToAscii( "ContentType" ) == 0 )
839             {
840                 rValue <<= m_bFolder ? m_pMyShell->FolderContentType
841                     : m_pMyShell->FileContentType;
842             }
843             else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 )
844             {
845                 rValue <<= m_bFolder;
846             }
847             else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 )
848             {
849                 rValue <<= sal_Bool( !m_bFolder );
850             }
851         }
852 
853         return Reference< sdbc::XRow >(
854             new XRow_impl( m_pMyShell, aValues ) );
855     }
856 
857     return m_pMyShell->getv( nMyCommandIdentifier,
858                              m_aUncPath,
859                              PropertySet );
860 }
861 
862 
863 Sequence< Any > SAL_CALL
864 BaseContent::setPropertyValues(
865     sal_Int32 nMyCommandIdentifier,
866     const Sequence< beans::PropertyValue >& Values )
867     throw()
868 {
869     if( m_nState & Deleted )
870     {   //  To do
871         return Sequence< Any >( Values.getLength() );
872     }
873 
874     const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" );
875 
876     // Special handling for files which have to be inserted
877     if( m_nState & JustInserted )
878     {
879         for( sal_Int32 i = 0; i < Values.getLength(); ++i )
880         {
881             if( Values[i].Name == Title )
882             {
883                 rtl::OUString NewTitle;
884                 if( Values[i].Value >>= NewTitle )
885                 {
886                     if ( m_nState & NameForInsertionSet )
887                     {
888                         // User wants to set another Title before "insert".
889                         // m_aUncPath contains previous own URI.
890 
891                         sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
892                         bool bTrailingSlash = false;
893                         if ( nLastSlash == m_aUncPath.getLength() - 1 )
894                         {
895                             bTrailingSlash = true;
896                             nLastSlash
897                                 = m_aUncPath.lastIndexOf( '/', nLastSlash );
898                         }
899 
900                         OSL_ENSURE( nLastSlash != -1,
901                                     "BaseContent::setPropertyValues: "
902                                     "Invalid URL!" );
903 
904                         rtl::OUStringBuffer aBuf(
905                             m_aUncPath.copy( 0, nLastSlash + 1 ) );
906 
907                         if ( NewTitle.getLength() > 0 )
908                         {
909                             aBuf.append( NewTitle );
910                             if ( bTrailingSlash )
911                                 aBuf.append( sal_Unicode( '/' ) );
912                         }
913                         else
914                         {
915                             m_nState &= ~NameForInsertionSet;
916                         }
917 
918                         m_aUncPath = aBuf.makeStringAndClear();
919                     }
920                     else
921                     {
922                         if ( NewTitle.getLength() > 0 )
923                         {
924                             // Initial Title before "insert".
925                             // m_aUncPath contains parent's URI.
926 
927                             if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
928                                 m_aUncPath += rtl::OUString::createFromAscii("/");
929 
930                             m_aUncPath += rtl::Uri::encode( NewTitle,
931                                                             rtl_UriCharClassPchar,
932                                                             rtl_UriEncodeIgnoreEscapes,
933                                                             RTL_TEXTENCODING_UTF8 );
934                             m_nState |= NameForInsertionSet;
935                         }
936                     }
937                 }
938             }
939         }
940 
941         return Sequence< Any >( Values.getLength() );
942     }
943     else
944     {
945         Sequence< Any > ret = m_pMyShell->setv( m_aUncPath,  // Does not handle Title
946                                                 Values );
947 
948         // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
949         for( sal_Int32 i = 0; i < Values.getLength(); ++i )
950         {
951             if( Values[i].Name != Title )
952                 continue;                  // handled by setv
953 
954             rtl::OUString NewTitle;
955             if( !( Values[i].Value >>= NewTitle ) )
956             {
957                 ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
958                 break;
959             }
960             else if( ! NewTitle.getLength() )
961             {
962                 ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
963                 break;
964             }
965 
966 
967             rtl::OUString aDstName = getParentName( m_aUncPath );
968             if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
969                 aDstName += rtl::OUString::createFromAscii("/");
970 
971             aDstName += rtl::Uri::encode( NewTitle,
972                                           rtl_UriCharClassPchar,
973                                           rtl_UriEncodeIgnoreEscapes,
974                                           RTL_TEXTENCODING_UTF8 );
975 
976             m_pMyShell->move( nMyCommandIdentifier,     // move notifies the childs also;
977                               m_aUncPath,
978                               aDstName,
979                               NameClash::KEEP );
980 
981             try
982             {
983                 endTask( nMyCommandIdentifier );
984             }
985             catch( const Exception& e )
986             {
987                 ret[i] <<= e;
988             }
989 
990             // NameChanges come back trough a ContentEvent
991             break; // only handling Title
992         } // end for
993 
994         return ret;
995     }
996 }
997 
998 
999 
1000 Reference< XDynamicResultSet > SAL_CALL
1001 BaseContent::open(
1002     sal_Int32 nMyCommandIdentifier,
1003     const OpenCommandArgument2& aCommandArgument )
1004     throw()
1005 {
1006     Reference< XDynamicResultSet > retValue( 0 );
1007 
1008     if( ( m_nState & Deleted ) )
1009     {
1010         m_pMyShell->installError( nMyCommandIdentifier,
1011                                   TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
1012     }
1013     else if( m_nState & JustInserted )
1014     {
1015         m_pMyShell->installError( nMyCommandIdentifier,
1016                                   TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
1017     }
1018     else
1019     {
1020         if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
1021             aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
1022 
1023         {
1024             Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
1025             if( outputStream.is() )
1026             {
1027                 m_pMyShell->page( nMyCommandIdentifier,
1028                                   m_aUncPath,
1029                                   outputStream );
1030             }
1031 
1032             sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
1033 
1034             Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
1035             if( activeDataSink.is() )
1036             {
1037                 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
1038                                                                   m_aUncPath,
1039                                                                   bLock ) );
1040             }
1041 
1042             Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
1043             if( activeDataStreamer.is() )
1044             {
1045                 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
1046                                                                     m_aUncPath,
1047                                                                     bLock ) );
1048             }
1049         }
1050         else if ( aCommandArgument.Mode == OpenMode::ALL        ||
1051                   aCommandArgument.Mode == OpenMode::FOLDERS    ||
1052                   aCommandArgument.Mode == OpenMode::DOCUMENTS )
1053         {
1054             retValue = m_pMyShell->ls( nMyCommandIdentifier,
1055                                        m_aUncPath,
1056                                        aCommandArgument.Mode,
1057                                        aCommandArgument.Properties,
1058                                        aCommandArgument.SortingInfo );
1059         }
1060 //          else if(  aCommandArgument.Mode ==
1061 //                    OpenMode::DOCUMENT_SHARE_DENY_NONE  ||
1062 //                    aCommandArgument.Mode ==
1063 //                    OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1064 //              m_pMyShell->installError( nMyCommandIdentifier,
1065 //                                        TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1066 //                                        aCommandArgument.Mode);
1067         else
1068             m_pMyShell->installError( nMyCommandIdentifier,
1069                                       TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1070                                       aCommandArgument.Mode);
1071     }
1072 
1073     return retValue;
1074 }
1075 
1076 
1077 
1078 void SAL_CALL
1079 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
1080     throw()
1081 {
1082     if( m_nState & Deleted )
1083         return;
1084 
1085     if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
1086     {
1087         osl::MutexGuard aGuard( m_aMutex );
1088         m_nState |= Deleted;
1089     }
1090 }
1091 
1092 
1093 
1094 void SAL_CALL
1095 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
1096                        const TransferInfo& aTransferInfo )
1097     throw()
1098 {
1099     if( m_nState & Deleted )
1100         return;
1101 
1102     if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
1103     {
1104         m_pMyShell->installError( nMyCommandIdentifier,
1105                                   TASKHANDLING_TRANSFER_INVALIDSCHEME );
1106         return;
1107     }
1108 
1109     rtl::OUString srcUnc;
1110     if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
1111     {
1112         m_pMyShell->installError( nMyCommandIdentifier,
1113                                   TASKHANDLING_TRANSFER_INVALIDURL );
1114         return;
1115     }
1116 
1117     rtl::OUString srcUncPath = srcUnc;
1118 
1119     // Determine the new title !
1120     rtl::OUString NewTitle;
1121     if( aTransferInfo.NewTitle.getLength() )
1122         NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
1123                                      rtl_UriCharClassPchar,
1124                                      rtl_UriEncodeIgnoreEscapes,
1125                                      RTL_TEXTENCODING_UTF8 );
1126     else
1127         NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
1128 
1129     // Is destination a document or a folder ?
1130     Sequence< beans::Property > seq(1);
1131     seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1132                               -1,
1133                               getCppuType( static_cast< sal_Bool* >(0) ),
1134                               0 );
1135     Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
1136     sal_Bool IsDocument = xRow->getBoolean( 1 );
1137     if( xRow->wasNull() )
1138     {   // Destination file type could not be determined
1139         m_pMyShell->installError( nMyCommandIdentifier,
1140                                   TASKHANDLING_TRANSFER_DESTFILETYPE );
1141         return;
1142     }
1143 
1144     rtl::OUString dstUncPath;
1145     if( IsDocument )
1146     {   // as sibling
1147         sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
1148         dstUncPath = m_aUncPath.copy(0,lastSlash );
1149     }
1150     else
1151         // as child
1152         dstUncPath = m_aUncPath;
1153 
1154     dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle );
1155 
1156     sal_Int32 NameClash = aTransferInfo.NameClash;
1157 
1158     if( aTransferInfo.MoveData )
1159         m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1160     else
1161         m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1162 }
1163 
1164 
1165 
1166 
1167 void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
1168                                    const InsertCommandArgument& aInsertArgument )
1169     throw()
1170 {
1171     if( m_nState & FullFeatured )
1172     {
1173         m_pMyShell->write( nMyCommandIdentifier,
1174                            m_aUncPath,
1175                            aInsertArgument.ReplaceExisting,
1176                            aInsertArgument.Data );
1177         return;
1178     }
1179 
1180     if( ! ( m_nState & JustInserted ) )
1181     {
1182         m_pMyShell->installError( nMyCommandIdentifier,
1183                                   TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
1184         return;
1185     }
1186 
1187     // Inserts the content, which has the flag m_bIsFresh
1188 
1189     if ( !m_nState | !NameForInsertionSet )
1190     {
1191         m_pMyShell->installError( nMyCommandIdentifier,
1192                                   TASKHANDLING_NONAMESET_INSERT_COMMAND );
1193         return;
1194     }
1195 
1196     // Inserting a document or a file?
1197     sal_Bool bDocument = false;
1198 
1199     Sequence< beans::Property > seq(1);
1200     seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1201                               -1,
1202                               getCppuType( static_cast< sal_Bool* >(0) ),
1203                               0 );
1204 
1205     Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
1206 
1207     bool contentTypeSet = true;  // is set to false, if contentType not set
1208     try
1209     {
1210         bDocument = xRow->getBoolean( 1 );
1211         if( xRow->wasNull() )
1212             contentTypeSet = false;
1213 
1214     }
1215     catch ( sdbc::SQLException const & )
1216     {
1217         OSL_ENSURE( false,
1218                     "BaseContent::insert - Caught SQLException!" );
1219         contentTypeSet = false;
1220     }
1221 
1222     if( ! contentTypeSet )
1223     {
1224         m_pMyShell->installError( nMyCommandIdentifier,
1225                                   TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1226         return;
1227     }
1228 
1229 
1230     sal_Bool success = false;
1231     if( bDocument )
1232         success = m_pMyShell->mkfil( nMyCommandIdentifier,
1233                                      m_aUncPath,
1234                                      aInsertArgument.ReplaceExisting,
1235                                      aInsertArgument.Data );
1236     else
1237     {
1238         while( ! success )
1239         {
1240             success = m_pMyShell->mkdir( nMyCommandIdentifier,
1241                                          m_aUncPath,
1242                                          aInsertArgument.ReplaceExisting );
1243             if( success )
1244                 break;
1245 
1246             XInteractionRequestImpl *aRequestImpl =
1247                 new XInteractionRequestImpl(
1248                     rtl::Uri::decode(
1249                         getTitle(m_aUncPath),
1250                         rtl_UriDecodeWithCharset,
1251                         RTL_TEXTENCODING_UTF8),
1252                     (cppu::OWeakObject*)this,
1253                     m_pMyShell,nMyCommandIdentifier);
1254             uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
1255 
1256             m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
1257             if(  aRequestImpl->aborted() ||
1258                  !aRequestImpl->newName().getLength() )
1259                 // means aborting
1260                 break;
1261 
1262             // determine new uncpath
1263             m_pMyShell->clearError( nMyCommandIdentifier );
1264             m_aUncPath = getParentName( m_aUncPath );
1265             if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
1266                 m_aUncPath += rtl::OUString::createFromAscii("/");
1267 
1268             m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
1269                                             rtl_UriCharClassPchar,
1270                                             rtl_UriEncodeIgnoreEscapes,
1271                                             RTL_TEXTENCODING_UTF8 );
1272         }
1273     }
1274 
1275     if ( ! success )
1276         return;
1277 
1278     FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
1279     m_xContentIdentifier = Reference< XContentIdentifier >( p );
1280 
1281     m_pMyShell->registerNotifier( m_aUncPath,this );
1282     m_pMyShell->insertDefaultProperties( m_aUncPath );
1283 
1284     osl::MutexGuard aGuard( m_aMutex );
1285     m_nState = FullFeatured;
1286 }
1287 
1288 
1289 
1290 void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
1291 {
1292     // This is the only function allowed to throw an exception
1293     m_pMyShell->endTask( CommandId,m_aUncPath,this );
1294 }
1295 
1296 
1297 
1298 ContentEventNotifier*
1299 BaseContent::cDEL( void )
1300 {
1301     osl::MutexGuard aGuard( m_aMutex );
1302 
1303     m_nState |= Deleted;
1304 
1305     ContentEventNotifier* p;
1306     if( m_pContentEventListeners )
1307         p = new ContentEventNotifier( m_pMyShell,
1308                                       this,
1309                                       m_xContentIdentifier,
1310                                       m_pContentEventListeners->getElements() );
1311     else
1312         p = 0;
1313 
1314     return p;
1315 }
1316 
1317 
1318 ContentEventNotifier*
1319 BaseContent::cEXC( const rtl::OUString aNewName )
1320 {
1321     osl::MutexGuard aGuard( m_aMutex );
1322 
1323     Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1324     m_aUncPath = aNewName;
1325     FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
1326     m_xContentIdentifier = Reference< XContentIdentifier >( pp );
1327 
1328     ContentEventNotifier* p = 0;
1329     if( m_pContentEventListeners )
1330         p = new ContentEventNotifier( m_pMyShell,
1331                                       this,
1332                                       m_xContentIdentifier,
1333                                       xOldRef,
1334                                       m_pContentEventListeners->getElements() );
1335 
1336     return p;
1337 }
1338 
1339 
1340 ContentEventNotifier*
1341 BaseContent::cCEL( void )
1342 {
1343     osl::MutexGuard aGuard( m_aMutex );
1344     ContentEventNotifier* p = 0;
1345     if( m_pContentEventListeners )
1346         p = new ContentEventNotifier( m_pMyShell,
1347                                       this,
1348                                       m_xContentIdentifier,
1349                                       m_pContentEventListeners->getElements() );
1350 
1351     return p;
1352 }
1353 
1354 PropertySetInfoChangeNotifier*
1355 BaseContent::cPSL( void )
1356 {
1357     osl::MutexGuard aGuard( m_aMutex );
1358     PropertySetInfoChangeNotifier* p = 0;
1359     if( m_pPropertySetInfoChangeListeners  )
1360         p = new PropertySetInfoChangeNotifier( m_pMyShell,
1361                                                this,
1362                                                m_xContentIdentifier,
1363                                                m_pPropertySetInfoChangeListeners->getElements() );
1364 
1365     return p;
1366 }
1367 
1368 
1369 
1370 PropertyChangeNotifier*
1371 BaseContent::cPCL( void )
1372 {
1373     osl::MutexGuard aGuard( m_aMutex );
1374 
1375     Sequence< rtl::OUString > seqNames;
1376 
1377     if( m_pPropertyListener )
1378         seqNames = m_pPropertyListener->getContainedTypes();
1379 
1380     PropertyChangeNotifier* p = 0;
1381 
1382     sal_Int32 length = seqNames.getLength();
1383 
1384     if( length )
1385     {
1386         ListenerMap* listener = new ListenerMap();
1387         for( sal_Int32 i = 0; i < length; ++i )
1388         {
1389             (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
1390         }
1391 
1392         p = new PropertyChangeNotifier( m_pMyShell,
1393                                         this,
1394                                         m_xContentIdentifier,
1395                                         listener );
1396     }
1397 
1398     return p;
1399 }
1400 
1401 
1402 rtl::OUString BaseContent::getKey( void )
1403 {
1404     return m_aUncPath;
1405 }
1406