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