merge the formfield patch from ooo-build
[ooovba.git] / ucb / source / ucp / file / bc.cxx
blobab279417b88005b80cb1ffa1fe2a7bc74f126f1d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bc.cxx,v $
10 * $Revision: 1.40 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
33 #include <rtl/uri.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <osl/file.hxx>
37 #include "osl/diagnose.h"
38 #include <com/sun/star/ucb/OpenMode.hpp>
39 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #endif
42 #include <com/sun/star/ucb/XProgressHandler.hpp>
43 #include <com/sun/star/task/XInteractionHandler.hpp>
44 #include <com/sun/star/io/XActiveDataStreamer.hpp>
45 #include <com/sun/star/io/XOutputStream.hpp>
46 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
47 #include <com/sun/star/io/XActiveDataSink.hpp>
48 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
49 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
50 #include <com/sun/star/ucb/ContentAction.hpp>
51 #include <com/sun/star/ucb/NameClash.hpp>
52 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
53 #include "filglob.hxx"
54 #include "filid.hxx"
55 #include "filrow.hxx"
56 #include "bc.hxx"
57 #include "prov.hxx"
58 #ifndef _FILERROR_HXX_
59 #include "filerror.hxx"
60 #endif
61 #include "filinsreq.hxx"
64 using namespace fileaccess;
65 using namespace com::sun::star;
66 using namespace com::sun::star::uno;
67 using namespace com::sun::star::ucb;
69 // PropertyListeners
72 typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
73 PropertyListeners_impl;
75 class fileaccess::PropertyListeners
76 : public PropertyListeners_impl
78 public:
79 PropertyListeners( ::osl::Mutex& aMutex )
80 : PropertyListeners_impl( aMutex )
86 /****************************************************************************************/
87 /* */
88 /* BaseContent */
89 /* */
90 /****************************************************************************************/
92 ////////////////////////////////////////////////////////////////////////////////
93 // Private Constructor for just inserted Contents
95 BaseContent::BaseContent( shell* pMyShell,
96 const rtl::OUString& parentName,
97 sal_Bool bFolder )
98 : m_pMyShell( pMyShell ),
99 m_xContentIdentifier( 0 ),
100 m_aUncPath( parentName ),
101 m_bFolder( bFolder ),
102 m_nState( JustInserted ),
103 m_pDisposeEventListeners( 0 ),
104 m_pContentEventListeners( 0 ),
105 m_pPropertySetInfoChangeListeners( 0 ),
106 m_pPropertyListener( 0 )
108 m_pMyShell->m_pProvider->acquire();
109 // No registering, since we have no name
113 ////////////////////////////////////////////////////////////////////////////////
114 // Constructor for full featured Contents
116 BaseContent::BaseContent( shell* pMyShell,
117 const Reference< XContentIdentifier >& xContentIdentifier,
118 const rtl::OUString& aUncPath )
119 : m_pMyShell( pMyShell ),
120 m_xContentIdentifier( xContentIdentifier ),
121 m_aUncPath( aUncPath ),
122 m_bFolder( false ),
123 m_nState( FullFeatured ),
124 m_pDisposeEventListeners( 0 ),
125 m_pContentEventListeners( 0 ),
126 m_pPropertySetInfoChangeListeners( 0 ),
127 m_pPropertyListener( 0 )
129 m_pMyShell->m_pProvider->acquire();
130 m_pMyShell->registerNotifier( m_aUncPath,this );
131 m_pMyShell->insertDefaultProperties( m_aUncPath );
135 BaseContent::~BaseContent( )
137 if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
139 m_pMyShell->deregisterNotifier( m_aUncPath,this );
141 m_pMyShell->m_pProvider->release();
143 delete m_pDisposeEventListeners;
144 delete m_pContentEventListeners;
145 delete m_pPropertyListener;
146 delete m_pPropertySetInfoChangeListeners;
150 //////////////////////////////////////////////////////////////////////////
151 // XInterface
152 //////////////////////////////////////////////////////////////////////////
154 void SAL_CALL
155 BaseContent::acquire( void )
156 throw()
158 OWeakObject::acquire();
162 void SAL_CALL
163 BaseContent::release( void )
164 throw()
166 OWeakObject::release();
170 Any SAL_CALL
171 BaseContent::queryInterface( const Type& rType )
172 throw( RuntimeException )
174 Any aRet = cppu::queryInterface( rType,
175 SAL_STATIC_CAST( lang::XComponent*, this ),
176 SAL_STATIC_CAST( lang::XTypeProvider*, this ),
177 SAL_STATIC_CAST( lang::XServiceInfo*, this ),
178 SAL_STATIC_CAST( XCommandProcessor*, this ),
179 SAL_STATIC_CAST( container::XChild*, this ),
180 SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ),
181 SAL_STATIC_CAST( beans::XPropertyContainer*, this ),
182 SAL_STATIC_CAST( XContentCreator*,this ),
183 SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ),
184 SAL_STATIC_CAST( XContent*,this) );
185 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
191 //////////////////////////////////////////////////////////////////////////////////////////
192 // XComponent
193 ////////////////////////////////////////////////////////////////////////////////////////
195 void SAL_CALL
196 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
197 throw( RuntimeException )
199 osl::MutexGuard aGuard( m_aMutex );
201 if ( ! m_pDisposeEventListeners )
202 m_pDisposeEventListeners =
203 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
205 m_pDisposeEventListeners->addInterface( Listener );
209 void SAL_CALL
210 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
211 throw( RuntimeException )
213 osl::MutexGuard aGuard( m_aMutex );
215 if ( m_pDisposeEventListeners )
216 m_pDisposeEventListeners->removeInterface( Listener );
220 void SAL_CALL
221 BaseContent::dispose()
222 throw( RuntimeException )
224 lang::EventObject aEvt;
225 cppu::OInterfaceContainerHelper* pDisposeEventListeners;
226 cppu::OInterfaceContainerHelper* pContentEventListeners;
227 cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
228 PropertyListeners* pPropertyListener;
231 osl::MutexGuard aGuard( m_aMutex );
232 aEvt.Source = static_cast< XContent* >( this );
235 pDisposeEventListeners =
236 m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
238 pContentEventListeners =
239 m_pContentEventListeners, m_pContentEventListeners = 0;
241 pPropertySetInfoChangeListeners =
242 m_pPropertySetInfoChangeListeners,
243 m_pPropertySetInfoChangeListeners = 0;
245 pPropertyListener =
246 m_pPropertyListener, m_pPropertyListener = 0;
249 if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
250 pDisposeEventListeners->disposeAndClear( aEvt );
252 if ( pContentEventListeners && pContentEventListeners->getLength() )
253 pContentEventListeners->disposeAndClear( aEvt );
255 if( pPropertyListener )
256 pPropertyListener->disposeAndClear( aEvt );
258 if( pPropertySetInfoChangeListeners )
259 pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
261 delete pDisposeEventListeners;
262 delete pContentEventListeners;
263 delete pPropertyListener;
264 delete pPropertySetInfoChangeListeners;
269 //////////////////////////////////////////////////////////////////////////////////////////
270 // XServiceInfo
271 //////////////////////////////////////////////////////////////////////////////////////////
273 rtl::OUString SAL_CALL
274 BaseContent::getImplementationName()
275 throw( RuntimeException)
277 return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" );
282 sal_Bool SAL_CALL
283 BaseContent::supportsService( const rtl::OUString& ServiceName )
284 throw( RuntimeException)
286 if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 )
287 return true;
288 else
289 return false;
294 Sequence< rtl::OUString > SAL_CALL
295 BaseContent::getSupportedServiceNames()
296 throw( RuntimeException )
298 Sequence< rtl::OUString > ret( 1 );
299 ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" );
300 return ret;
305 //////////////////////////////////////////////////////////////////////////////////////////
306 // XTypeProvider
307 //////////////////////////////////////////////////////////////////////////////////////////
309 XTYPEPROVIDER_IMPL_10( BaseContent,
310 lang::XComponent,
311 lang::XTypeProvider,
312 lang::XServiceInfo,
313 XCommandProcessor,
314 XContentCreator,
315 XContent,
316 container::XChild,
317 beans::XPropertiesChangeNotifier,
318 beans::XPropertyContainer,
319 beans::XPropertySetInfoChangeNotifier )
322 //////////////////////////////////////////////////////////////////////////////////////////
323 // XCommandProcessor
324 //////////////////////////////////////////////////////////////////////////////////////////
326 sal_Int32 SAL_CALL
327 BaseContent::createCommandIdentifier( void )
328 throw( RuntimeException )
330 return m_pMyShell->getCommandId();
334 void SAL_CALL
335 BaseContent::abort( sal_Int32 CommandId )
336 throw( RuntimeException )
338 m_pMyShell->abort( CommandId );
342 Any SAL_CALL
343 BaseContent::execute( const Command& aCommand,
344 sal_Int32 CommandId,
345 const Reference< XCommandEnvironment >& Environment )
346 throw( Exception,
347 CommandAbortedException,
348 RuntimeException )
350 if( ! CommandId )
351 // A Command with commandid zero cannot be aborted
352 CommandId = createCommandIdentifier();
354 m_pMyShell->startTask( CommandId,
355 Environment );
357 Any aAny;
359 if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) ) // No exceptions
361 aAny <<= getPropertySetInfo( CommandId );
363 else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) ) // no exceptions
365 aAny <<= getCommandInfo();
367 else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) )
369 Sequence< beans::PropertyValue > sPropertyValues;
371 if( ! ( aCommand.Argument >>= sPropertyValues ) )
372 m_pMyShell->installError( CommandId,
373 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
374 else
375 aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
377 else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) )
379 Sequence< beans::Property > ListOfRequestedProperties;
381 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
382 m_pMyShell->installError( CommandId,
383 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
384 else
385 aAny <<= getPropertyValues( CommandId,
386 ListOfRequestedProperties );
388 else if( ! aCommand.Name.compareToAscii( "open" ) )
390 OpenCommandArgument2 aOpenArgument;
391 if( ! ( aCommand.Argument >>= aOpenArgument ) )
392 m_pMyShell->installError( CommandId,
393 TASKHANDLING_WRONG_OPEN_ARGUMENT );
394 else
396 Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
397 if( result.is() )
398 aAny <<= result;
401 else if( ! aCommand.Name.compareToAscii( "delete" ) )
403 if( ! aCommand.Argument.has< sal_Bool >() )
404 m_pMyShell->installError( CommandId,
405 TASKHANDLING_WRONG_DELETE_ARGUMENT );
406 else
407 deleteContent( CommandId );
409 else if( ! aCommand.Name.compareToAscii( "transfer" ) )
411 TransferInfo aTransferInfo;
412 if( ! ( aCommand.Argument >>= aTransferInfo ) )
413 m_pMyShell->installError( CommandId,
414 TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
415 else
416 transfer( CommandId, aTransferInfo );
418 else if( ! aCommand.Name.compareToAscii( "insert" ) )
420 InsertCommandArgument aInsertArgument;
421 if( ! ( aCommand.Argument >>= aInsertArgument ) )
422 m_pMyShell->installError( CommandId,
423 TASKHANDLING_WRONG_INSERT_ARGUMENT );
424 else
425 insert( CommandId,aInsertArgument );
427 else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) )
429 Sequence< beans::Property > seq(1);
430 seq[0] = beans::Property(
431 rtl::OUString::createFromAscii("CasePreservingURL"),
433 getCppuType( static_cast< sal_Bool* >(0) ),
434 0 );
435 Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
436 rtl::OUString CasePreservingURL = xRow->getString(1);
437 if(!xRow->wasNull())
438 aAny <<= CasePreservingURL;
440 else
441 m_pMyShell->installError( CommandId,
442 TASKHANDLER_UNSUPPORTED_COMMAND );
445 // This is the only function allowed to throw an exception
446 endTask( CommandId );
448 return aAny;
453 void SAL_CALL
454 BaseContent::addPropertiesChangeListener(
455 const Sequence< rtl::OUString >& PropertyNames,
456 const Reference< beans::XPropertiesChangeListener >& Listener )
457 throw( RuntimeException )
459 if( ! Listener.is() )
460 return;
462 osl::MutexGuard aGuard( m_aMutex );
464 if( ! m_pPropertyListener )
465 m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex );
468 if( PropertyNames.getLength() == 0 )
469 m_pPropertyListener->addInterface( rtl::OUString(),Listener );
470 else
472 Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
473 for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
474 if( xProp->hasPropertyByName( PropertyNames[i] ) )
475 m_pPropertyListener->addInterface( PropertyNames[i],Listener );
480 void SAL_CALL
481 BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames,
482 const Reference< beans::XPropertiesChangeListener >& Listener )
483 throw( RuntimeException )
485 if( ! Listener.is() )
486 return;
488 osl::MutexGuard aGuard( m_aMutex );
490 if( ! m_pPropertyListener )
491 return;
493 for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
494 m_pPropertyListener->removeInterface( PropertyNames[i],Listener );
496 m_pPropertyListener->removeInterface( rtl::OUString(), Listener );
500 /////////////////////////////////////////////////////////////////////////////////////////
501 // XContent
502 /////////////////////////////////////////////////////////////////////////////////////////
504 Reference< ucb::XContentIdentifier > SAL_CALL
505 BaseContent::getIdentifier()
506 throw( RuntimeException )
508 return m_xContentIdentifier;
512 rtl::OUString SAL_CALL
513 BaseContent::getContentType()
514 throw( RuntimeException )
516 if( !( m_nState & Deleted ) )
518 if( m_nState & JustInserted )
520 if ( m_bFolder )
521 return m_pMyShell->FolderContentType;
522 else
523 return m_pMyShell->FileContentType;
525 else
529 // Who am I ?
530 Sequence< beans::Property > seq(1);
531 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
533 getCppuType( static_cast< sal_Bool* >(0) ),
534 0 );
535 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
536 sal_Bool IsDocument = xRow->getBoolean( 1 );
538 if ( !xRow->wasNull() )
540 if ( IsDocument )
541 return m_pMyShell->FileContentType;
542 else
543 return m_pMyShell->FolderContentType;
545 else
547 OSL_ENSURE( false,
548 "BaseContent::getContentType - Property value was null!" );
551 catch ( sdbc::SQLException const & )
553 OSL_ENSURE( false,
554 "BaseContent::getContentType - Caught SQLException!" );
559 return rtl::OUString();
564 void SAL_CALL
565 BaseContent::addContentEventListener(
566 const Reference< XContentEventListener >& Listener )
567 throw( RuntimeException )
569 osl::MutexGuard aGuard( m_aMutex );
571 if ( ! m_pContentEventListeners )
572 m_pContentEventListeners =
573 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
576 m_pContentEventListeners->addInterface( Listener );
580 void SAL_CALL
581 BaseContent::removeContentEventListener(
582 const Reference< XContentEventListener >& Listener )
583 throw( RuntimeException )
585 osl::MutexGuard aGuard( m_aMutex );
587 if ( m_pContentEventListeners )
588 m_pContentEventListeners->removeInterface( Listener );
593 ////////////////////////////////////////////////////////////////////////////////
594 // XPropertyContainer
595 ////////////////////////////////////////////////////////////////////////////////
598 void SAL_CALL
599 BaseContent::addProperty(
600 const rtl::OUString& Name,
601 sal_Int16 Attributes,
602 const Any& DefaultValue )
603 throw( beans::PropertyExistException,
604 beans::IllegalTypeException,
605 lang::IllegalArgumentException,
606 RuntimeException)
608 if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() )
610 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
613 m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
617 void SAL_CALL
618 BaseContent::removeProperty(
619 const rtl::OUString& Name )
620 throw( beans::UnknownPropertyException,
621 beans::NotRemoveableException,
622 RuntimeException)
625 if( m_nState & Deleted )
626 throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
628 m_pMyShell->deassociate( m_aUncPath, Name );
631 ////////////////////////////////////////////////////////////////////////////////
632 // XContentCreator
633 ////////////////////////////////////////////////////////////////////////////////
635 Sequence< ContentInfo > SAL_CALL
636 BaseContent::queryCreatableContentsInfo(
637 void )
638 throw( RuntimeException )
640 Sequence< ContentInfo > seq(2);
642 // file
643 seq[0].Type = m_pMyShell->FileContentType;
644 seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
645 | ContentInfoAttribute::KIND_DOCUMENT;
647 Sequence< beans::Property > props( 1 );
648 props[0] = beans::Property(
649 rtl::OUString::createFromAscii( "Title" ),
651 getCppuType( static_cast< rtl::OUString* >( 0 ) ),
652 beans::PropertyAttribute::MAYBEVOID
653 | beans::PropertyAttribute::BOUND );
654 seq[0].Properties = props;
656 // folder
657 seq[1].Type = m_pMyShell->FolderContentType;
658 seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
659 seq[1].Properties = props;
660 return seq;
664 Reference< XContent > SAL_CALL
665 BaseContent::createNewContent(
666 const ContentInfo& Info )
667 throw( RuntimeException )
669 // Check type.
670 if ( !Info.Type.getLength() )
671 return Reference< XContent >();
673 sal_Bool bFolder
674 = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
675 if ( !bFolder )
677 if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
679 // Neither folder nor file to create!
680 return Reference< XContent >();
684 // Who am I ?
685 sal_Bool IsDocument = false;
689 Sequence< beans::Property > seq(1);
690 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
692 getCppuType( static_cast< sal_Bool* >(0) ),
693 0 );
694 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
695 IsDocument = xRow->getBoolean( 1 );
697 if ( xRow->wasNull() )
699 IsDocument = false;
700 // OSL_ENSURE( false,
701 // "BaseContent::createNewContent - Property value was null!" );
702 // return Reference< XContent >();
705 catch ( sdbc::SQLException const & )
707 OSL_ENSURE( false,
708 "BaseContent::createNewContent - Caught SQLException!" );
709 return Reference< XContent >();
712 rtl::OUString dstUncPath;
714 if( IsDocument )
716 // KSO: Why is a document a XContentCreator? This is quite unusual.
717 dstUncPath = getParentName( m_aUncPath );
719 else
720 dstUncPath = m_aUncPath;
722 BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
723 return Reference< XContent >( p );
727 ////////////////////////////////////////////////////////////////////////////////
728 // XPropertySetInfoChangeNotifier
729 ////////////////////////////////////////////////////////////////////////////////
732 void SAL_CALL
733 BaseContent::addPropertySetInfoChangeListener(
734 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
735 throw( RuntimeException )
737 osl::MutexGuard aGuard( m_aMutex );
738 if( ! m_pPropertySetInfoChangeListeners )
739 m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
741 m_pPropertySetInfoChangeListeners->addInterface( Listener );
745 void SAL_CALL
746 BaseContent::removePropertySetInfoChangeListener(
747 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
748 throw( RuntimeException )
750 osl::MutexGuard aGuard( m_aMutex );
752 if( m_pPropertySetInfoChangeListeners )
753 m_pPropertySetInfoChangeListeners->removeInterface( Listener );
757 ////////////////////////////////////////////////////////////////////////////////
758 // XChild
759 ////////////////////////////////////////////////////////////////////////////////
761 Reference< XInterface > SAL_CALL
762 BaseContent::getParent(
763 void )
764 throw( RuntimeException )
766 rtl::OUString ParentUnq = getParentName( m_aUncPath );
767 rtl::OUString ParentUrl;
770 sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
771 if( err )
772 return Reference< XInterface >( 0 );
774 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
775 Reference< XContentIdentifier > Identifier( p );
779 Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
780 return Reference<XInterface>(content,UNO_QUERY);
782 catch( IllegalIdentifierException )
784 return Reference< XInterface >();
789 void SAL_CALL
790 BaseContent::setParent(
791 const Reference< XInterface >& )
792 throw( lang::NoSupportException,
793 RuntimeException)
795 throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
799 //////////////////////////////////////////////////////////////////////////////////////////
800 // Private Methods
801 //////////////////////////////////////////////////////////////////////////////////////////
804 Reference< XCommandInfo > SAL_CALL
805 BaseContent::getCommandInfo()
806 throw( RuntimeException )
808 if( m_nState & Deleted )
809 return Reference< XCommandInfo >();
811 return m_pMyShell->info_c();
815 Reference< beans::XPropertySetInfo > SAL_CALL
816 BaseContent::getPropertySetInfo(
817 sal_Int32 )
818 throw( RuntimeException )
820 if( m_nState & Deleted )
821 return Reference< beans::XPropertySetInfo >();
823 return m_pMyShell->info_p( m_aUncPath );
829 Reference< sdbc::XRow > SAL_CALL
830 BaseContent::getPropertyValues(
831 sal_Int32 nMyCommandIdentifier,
832 const Sequence< beans::Property >& PropertySet )
833 throw( RuntimeException )
835 sal_Int32 nProps = PropertySet.getLength();
836 if ( !nProps )
837 return Reference< sdbc::XRow >();
839 if( m_nState & Deleted )
841 Sequence< Any > aValues( nProps );
842 return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
845 if( m_nState & JustInserted )
847 Sequence< Any > aValues( nProps );
848 Any* pValues = aValues.getArray();
850 const beans::Property* pProps = PropertySet.getConstArray();
852 for ( sal_Int32 n = 0; n < nProps; ++n )
854 const beans::Property& rProp = pProps[ n ];
855 Any& rValue = pValues[ n ];
857 if( rProp.Name.compareToAscii( "ContentType" ) == 0 )
859 rValue <<= m_bFolder ? m_pMyShell->FolderContentType
860 : m_pMyShell->FileContentType;
862 else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 )
864 rValue <<= m_bFolder;
866 else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 )
868 rValue <<= sal_Bool( !m_bFolder );
872 return Reference< sdbc::XRow >(
873 new XRow_impl( m_pMyShell, aValues ) );
876 return m_pMyShell->getv( nMyCommandIdentifier,
877 m_aUncPath,
878 PropertySet );
882 Sequence< Any > SAL_CALL
883 BaseContent::setPropertyValues(
884 sal_Int32 nMyCommandIdentifier,
885 const Sequence< beans::PropertyValue >& Values )
886 throw()
888 if( m_nState & Deleted )
889 { // To do
890 return Sequence< Any >( Values.getLength() );
893 const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" );
895 // Special handling for files which have to be inserted
896 if( m_nState & JustInserted )
898 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
900 if( Values[i].Name == Title )
902 rtl::OUString NewTitle;
903 if( Values[i].Value >>= NewTitle )
905 if ( m_nState & NameForInsertionSet )
907 // User wants to set another Title before "insert".
908 // m_aUncPath contains previous own URI.
910 sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
911 bool bTrailingSlash = false;
912 if ( nLastSlash == m_aUncPath.getLength() - 1 )
914 bTrailingSlash = true;
915 nLastSlash
916 = m_aUncPath.lastIndexOf( '/', nLastSlash );
919 OSL_ENSURE( nLastSlash != -1,
920 "BaseContent::setPropertyValues: "
921 "Invalid URL!" );
923 rtl::OUStringBuffer aBuf(
924 m_aUncPath.copy( 0, nLastSlash + 1 ) );
926 if ( NewTitle.getLength() > 0 )
928 aBuf.append( NewTitle );
929 if ( bTrailingSlash )
930 aBuf.append( sal_Unicode( '/' ) );
932 else
934 m_nState &= ~NameForInsertionSet;
937 m_aUncPath = aBuf.makeStringAndClear();
939 else
941 if ( NewTitle.getLength() > 0 )
943 // Initial Title before "insert".
944 // m_aUncPath contains parent's URI.
946 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
947 m_aUncPath += rtl::OUString::createFromAscii("/");
949 m_aUncPath += rtl::Uri::encode( NewTitle,
950 rtl_UriCharClassPchar,
951 rtl_UriEncodeIgnoreEscapes,
952 RTL_TEXTENCODING_UTF8 );
953 m_nState |= NameForInsertionSet;
960 return Sequence< Any >( Values.getLength() );
962 else
964 Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
965 Values );
967 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
968 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
970 if( Values[i].Name != Title )
971 continue; // handled by setv
973 rtl::OUString NewTitle;
974 if( !( Values[i].Value >>= NewTitle ) )
976 ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
977 break;
979 else if( ! NewTitle.getLength() )
981 ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
982 break;
986 rtl::OUString aDstName = getParentName( m_aUncPath );
987 if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
988 aDstName += rtl::OUString::createFromAscii("/");
990 aDstName += rtl::Uri::encode( NewTitle,
991 rtl_UriCharClassPchar,
992 rtl_UriEncodeIgnoreEscapes,
993 RTL_TEXTENCODING_UTF8 );
995 m_pMyShell->move( nMyCommandIdentifier, // move notifies the childs also;
996 m_aUncPath,
997 aDstName,
998 NameClash::KEEP );
1002 endTask( nMyCommandIdentifier );
1004 catch( const Exception& e )
1006 ret[i] <<= e;
1009 // NameChanges come back trough a ContentEvent
1010 break; // only handling Title
1011 } // end for
1013 return ret;
1019 Reference< XDynamicResultSet > SAL_CALL
1020 BaseContent::open(
1021 sal_Int32 nMyCommandIdentifier,
1022 const OpenCommandArgument2& aCommandArgument )
1023 throw()
1025 Reference< XDynamicResultSet > retValue( 0 );
1027 if( ( m_nState & Deleted ) )
1029 m_pMyShell->installError( nMyCommandIdentifier,
1030 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
1032 else if( m_nState & JustInserted )
1034 m_pMyShell->installError( nMyCommandIdentifier,
1035 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
1037 else
1039 if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
1040 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
1043 Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
1044 if( outputStream.is() )
1046 m_pMyShell->page( nMyCommandIdentifier,
1047 m_aUncPath,
1048 outputStream );
1051 sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
1053 Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
1054 if( activeDataSink.is() )
1056 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
1057 m_aUncPath,
1058 bLock ) );
1061 Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
1062 if( activeDataStreamer.is() )
1064 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
1065 m_aUncPath,
1066 bLock ) );
1069 else if ( aCommandArgument.Mode == OpenMode::ALL ||
1070 aCommandArgument.Mode == OpenMode::FOLDERS ||
1071 aCommandArgument.Mode == OpenMode::DOCUMENTS )
1073 retValue = m_pMyShell->ls( nMyCommandIdentifier,
1074 m_aUncPath,
1075 aCommandArgument.Mode,
1076 aCommandArgument.Properties,
1077 aCommandArgument.SortingInfo );
1079 // else if( aCommandArgument.Mode ==
1080 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
1081 // aCommandArgument.Mode ==
1082 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1083 // m_pMyShell->installError( nMyCommandIdentifier,
1084 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1085 // aCommandArgument.Mode);
1086 else
1087 m_pMyShell->installError( nMyCommandIdentifier,
1088 TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1089 aCommandArgument.Mode);
1092 return retValue;
1097 void SAL_CALL
1098 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
1099 throw()
1101 if( m_nState & Deleted )
1102 return;
1104 if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
1106 osl::MutexGuard aGuard( m_aMutex );
1107 m_nState |= Deleted;
1113 void SAL_CALL
1114 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
1115 const TransferInfo& aTransferInfo )
1116 throw()
1118 if( m_nState & Deleted )
1119 return;
1121 if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
1123 m_pMyShell->installError( nMyCommandIdentifier,
1124 TASKHANDLING_TRANSFER_INVALIDSCHEME );
1125 return;
1128 rtl::OUString srcUnc;
1129 if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
1131 m_pMyShell->installError( nMyCommandIdentifier,
1132 TASKHANDLING_TRANSFER_INVALIDURL );
1133 return;
1136 rtl::OUString srcUncPath = srcUnc;
1138 // Determine the new title !
1139 rtl::OUString NewTitle;
1140 if( aTransferInfo.NewTitle.getLength() )
1141 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
1142 rtl_UriCharClassPchar,
1143 rtl_UriEncodeIgnoreEscapes,
1144 RTL_TEXTENCODING_UTF8 );
1145 else
1146 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
1148 // Is destination a document or a folder ?
1149 Sequence< beans::Property > seq(1);
1150 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1152 getCppuType( static_cast< sal_Bool* >(0) ),
1153 0 );
1154 Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
1155 sal_Bool IsDocument = xRow->getBoolean( 1 );
1156 if( xRow->wasNull() )
1157 { // Destination file type could not be determined
1158 m_pMyShell->installError( nMyCommandIdentifier,
1159 TASKHANDLING_TRANSFER_DESTFILETYPE );
1160 return;
1163 rtl::OUString dstUncPath;
1164 if( IsDocument )
1165 { // as sibling
1166 sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
1167 dstUncPath = m_aUncPath.copy(0,lastSlash );
1169 else
1170 // as child
1171 dstUncPath = m_aUncPath;
1173 dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle );
1175 sal_Int32 NameClash = aTransferInfo.NameClash;
1177 if( aTransferInfo.MoveData )
1178 m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1179 else
1180 m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1186 void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
1187 const InsertCommandArgument& aInsertArgument )
1188 throw()
1190 if( m_nState & FullFeatured )
1192 m_pMyShell->write( nMyCommandIdentifier,
1193 m_aUncPath,
1194 aInsertArgument.ReplaceExisting,
1195 aInsertArgument.Data );
1196 return;
1199 if( ! ( m_nState & JustInserted ) )
1201 m_pMyShell->installError( nMyCommandIdentifier,
1202 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
1203 return;
1206 // Inserts the content, which has the flag m_bIsFresh
1208 if( ! m_nState & NameForInsertionSet )
1210 m_pMyShell->installError( nMyCommandIdentifier,
1211 TASKHANDLING_NONAMESET_INSERT_COMMAND );
1212 return;
1215 // Inserting a document or a file?
1216 sal_Bool bDocument = false;
1218 Sequence< beans::Property > seq(1);
1219 seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
1221 getCppuType( static_cast< sal_Bool* >(0) ),
1222 0 );
1224 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
1226 bool contentTypeSet = true; // is set to false, if contentType not set
1229 bDocument = xRow->getBoolean( 1 );
1230 if( xRow->wasNull() )
1231 contentTypeSet = false;
1234 catch ( sdbc::SQLException const & )
1236 OSL_ENSURE( false,
1237 "BaseContent::insert - Caught SQLException!" );
1238 contentTypeSet = false;
1241 if( ! contentTypeSet )
1243 m_pMyShell->installError( nMyCommandIdentifier,
1244 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1245 return;
1249 sal_Bool success = false;
1250 if( bDocument )
1251 success = m_pMyShell->mkfil( nMyCommandIdentifier,
1252 m_aUncPath,
1253 aInsertArgument.ReplaceExisting,
1254 aInsertArgument.Data );
1255 else
1257 while( ! success )
1259 success = m_pMyShell->mkdir( nMyCommandIdentifier,
1260 m_aUncPath,
1261 aInsertArgument.ReplaceExisting );
1262 if( success )
1263 break;
1265 XInteractionRequestImpl *aRequestImpl =
1266 new XInteractionRequestImpl(
1267 rtl::Uri::decode(
1268 getTitle(m_aUncPath),
1269 rtl_UriDecodeWithCharset,
1270 RTL_TEXTENCODING_UTF8),
1271 (cppu::OWeakObject*)this,
1272 m_pMyShell,nMyCommandIdentifier);
1273 uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
1275 m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
1276 if( aRequestImpl->aborted() ||
1277 !aRequestImpl->newName().getLength() )
1278 // means aborting
1279 break;
1281 // determine new uncpath
1282 m_pMyShell->clearError( nMyCommandIdentifier );
1283 m_aUncPath = getParentName( m_aUncPath );
1284 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
1285 m_aUncPath += rtl::OUString::createFromAscii("/");
1287 m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
1288 rtl_UriCharClassPchar,
1289 rtl_UriEncodeIgnoreEscapes,
1290 RTL_TEXTENCODING_UTF8 );
1294 if ( ! success )
1295 return;
1297 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
1298 m_xContentIdentifier = Reference< XContentIdentifier >( p );
1300 m_pMyShell->registerNotifier( m_aUncPath,this );
1301 m_pMyShell->insertDefaultProperties( m_aUncPath );
1303 osl::MutexGuard aGuard( m_aMutex );
1304 m_nState = FullFeatured;
1309 void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
1311 // This is the only function allowed to throw an exception
1312 m_pMyShell->endTask( CommandId,m_aUncPath,this );
1317 ContentEventNotifier*
1318 BaseContent::cDEL( void )
1320 osl::MutexGuard aGuard( m_aMutex );
1322 m_nState |= Deleted;
1324 ContentEventNotifier* p;
1325 if( m_pContentEventListeners )
1326 p = new ContentEventNotifier( m_pMyShell,
1327 this,
1328 m_xContentIdentifier,
1329 m_pContentEventListeners->getElements() );
1330 else
1331 p = 0;
1333 return p;
1337 ContentEventNotifier*
1338 BaseContent::cEXC( const rtl::OUString aNewName )
1340 osl::MutexGuard aGuard( m_aMutex );
1342 Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1343 m_aUncPath = aNewName;
1344 FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
1345 m_xContentIdentifier = Reference< XContentIdentifier >( pp );
1347 ContentEventNotifier* p = 0;
1348 if( m_pContentEventListeners )
1349 p = new ContentEventNotifier( m_pMyShell,
1350 this,
1351 m_xContentIdentifier,
1352 xOldRef,
1353 m_pContentEventListeners->getElements() );
1355 return p;
1359 ContentEventNotifier*
1360 BaseContent::cCEL( void )
1362 osl::MutexGuard aGuard( m_aMutex );
1363 ContentEventNotifier* p = 0;
1364 if( m_pContentEventListeners )
1365 p = new ContentEventNotifier( m_pMyShell,
1366 this,
1367 m_xContentIdentifier,
1368 m_pContentEventListeners->getElements() );
1370 return p;
1373 PropertySetInfoChangeNotifier*
1374 BaseContent::cPSL( void )
1376 osl::MutexGuard aGuard( m_aMutex );
1377 PropertySetInfoChangeNotifier* p = 0;
1378 if( m_pPropertySetInfoChangeListeners )
1379 p = new PropertySetInfoChangeNotifier( m_pMyShell,
1380 this,
1381 m_xContentIdentifier,
1382 m_pPropertySetInfoChangeListeners->getElements() );
1384 return p;
1389 PropertyChangeNotifier*
1390 BaseContent::cPCL( void )
1392 osl::MutexGuard aGuard( m_aMutex );
1394 Sequence< rtl::OUString > seqNames;
1396 if( m_pPropertyListener )
1397 seqNames = m_pPropertyListener->getContainedTypes();
1399 PropertyChangeNotifier* p = 0;
1401 sal_Int32 length = seqNames.getLength();
1403 if( length )
1405 ListenerMap* listener = new ListenerMap();
1406 for( sal_Int32 i = 0; i < length; ++i )
1408 (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
1411 p = new PropertyChangeNotifier( m_pMyShell,
1412 this,
1413 m_xContentIdentifier,
1414 listener );
1417 return p;
1421 rtl::OUString BaseContent::getKey( void )
1423 return m_aUncPath;