Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / file / bc.cxx
blob8ea4a928b78713d07f8f121e4df3aea48e48f575
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <rtl/uri.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #include <osl/file.hxx>
33 #include "osl/diagnose.h"
34 #include <com/sun/star/ucb/OpenMode.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/ucb/XProgressHandler.hpp>
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #include <com/sun/star/io/XActiveDataStreamer.hpp>
39 #include <com/sun/star/io/XOutputStream.hpp>
40 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
41 #include <com/sun/star/io/XActiveDataSink.hpp>
42 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
43 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
44 #include <com/sun/star/ucb/ContentAction.hpp>
45 #include <com/sun/star/ucb/NameClash.hpp>
46 #include "filglob.hxx"
47 #include "filid.hxx"
48 #include "filrow.hxx"
49 #include "bc.hxx"
50 #include "prov.hxx"
51 #include "filerror.hxx"
52 #include "filinsreq.hxx"
55 using namespace fileaccess;
56 using namespace com::sun::star;
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::ucb;
60 // PropertyListeners
63 typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
64 PropertyListeners_impl;
66 class fileaccess::PropertyListeners
67 : public PropertyListeners_impl
69 public:
70 PropertyListeners( ::osl::Mutex& aMutex )
71 : PropertyListeners_impl( aMutex )
77 /****************************************************************************************/
78 /* */
79 /* BaseContent */
80 /* */
81 /****************************************************************************************/
83 ////////////////////////////////////////////////////////////////////////////////
84 // Private Constructor for just inserted Contents
86 BaseContent::BaseContent( shell* pMyShell,
87 const rtl::OUString& parentName,
88 sal_Bool bFolder )
89 : m_pMyShell( pMyShell ),
90 m_xContentIdentifier( 0 ),
91 m_aUncPath( parentName ),
92 m_bFolder( bFolder ),
93 m_nState( JustInserted ),
94 m_pDisposeEventListeners( 0 ),
95 m_pContentEventListeners( 0 ),
96 m_pPropertySetInfoChangeListeners( 0 ),
97 m_pPropertyListener( 0 )
99 m_pMyShell->m_pProvider->acquire();
100 // No registering, since we have no name
104 ////////////////////////////////////////////////////////////////////////////////
105 // Constructor for full featured Contents
107 BaseContent::BaseContent( shell* pMyShell,
108 const Reference< XContentIdentifier >& xContentIdentifier,
109 const rtl::OUString& aUncPath )
110 : m_pMyShell( pMyShell ),
111 m_xContentIdentifier( xContentIdentifier ),
112 m_aUncPath( aUncPath ),
113 m_bFolder( false ),
114 m_nState( FullFeatured ),
115 m_pDisposeEventListeners( 0 ),
116 m_pContentEventListeners( 0 ),
117 m_pPropertySetInfoChangeListeners( 0 ),
118 m_pPropertyListener( 0 )
120 m_pMyShell->m_pProvider->acquire();
121 m_pMyShell->registerNotifier( m_aUncPath,this );
122 m_pMyShell->insertDefaultProperties( m_aUncPath );
126 BaseContent::~BaseContent( )
128 if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
130 m_pMyShell->deregisterNotifier( m_aUncPath,this );
132 m_pMyShell->m_pProvider->release();
134 delete m_pDisposeEventListeners;
135 delete m_pContentEventListeners;
136 delete m_pPropertyListener;
137 delete m_pPropertySetInfoChangeListeners;
141 //////////////////////////////////////////////////////////////////////////
142 // XInterface
143 //////////////////////////////////////////////////////////////////////////
145 void SAL_CALL
146 BaseContent::acquire( void )
147 throw()
149 OWeakObject::acquire();
153 void SAL_CALL
154 BaseContent::release( void )
155 throw()
157 OWeakObject::release();
161 Any SAL_CALL
162 BaseContent::queryInterface( const Type& rType )
163 throw( RuntimeException )
165 Any aRet = cppu::queryInterface( rType,
166 (static_cast< lang::XComponent* >(this)),
167 (static_cast< lang::XTypeProvider* >(this)),
168 (static_cast< lang::XServiceInfo* >(this)),
169 (static_cast< XCommandProcessor* >(this)),
170 (static_cast< container::XChild* >(this)),
171 (static_cast< beans::XPropertiesChangeNotifier* >(this)),
172 (static_cast< beans::XPropertyContainer* >(this)),
173 (static_cast< XContentCreator* >(this)),
174 (static_cast< beans::XPropertySetInfoChangeNotifier* >(this)),
175 (static_cast< XContent* >(this)) );
176 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
182 //////////////////////////////////////////////////////////////////////////////////////////
183 // XComponent
184 ////////////////////////////////////////////////////////////////////////////////////////
186 void SAL_CALL
187 BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
188 throw( RuntimeException )
190 osl::MutexGuard aGuard( m_aMutex );
192 if ( ! m_pDisposeEventListeners )
193 m_pDisposeEventListeners =
194 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
196 m_pDisposeEventListeners->addInterface( Listener );
200 void SAL_CALL
201 BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
202 throw( RuntimeException )
204 osl::MutexGuard aGuard( m_aMutex );
206 if ( m_pDisposeEventListeners )
207 m_pDisposeEventListeners->removeInterface( Listener );
211 void SAL_CALL
212 BaseContent::dispose()
213 throw( RuntimeException )
215 lang::EventObject aEvt;
216 cppu::OInterfaceContainerHelper* pDisposeEventListeners;
217 cppu::OInterfaceContainerHelper* pContentEventListeners;
218 cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
219 PropertyListeners* pPropertyListener;
222 osl::MutexGuard aGuard( m_aMutex );
223 aEvt.Source = static_cast< XContent* >( this );
226 pDisposeEventListeners =
227 m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
229 pContentEventListeners =
230 m_pContentEventListeners, m_pContentEventListeners = 0;
232 pPropertySetInfoChangeListeners =
233 m_pPropertySetInfoChangeListeners,
234 m_pPropertySetInfoChangeListeners = 0;
236 pPropertyListener =
237 m_pPropertyListener, m_pPropertyListener = 0;
240 if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
241 pDisposeEventListeners->disposeAndClear( aEvt );
243 if ( pContentEventListeners && pContentEventListeners->getLength() )
244 pContentEventListeners->disposeAndClear( aEvt );
246 if( pPropertyListener )
247 pPropertyListener->disposeAndClear( aEvt );
249 if( pPropertySetInfoChangeListeners )
250 pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
252 delete pDisposeEventListeners;
253 delete pContentEventListeners;
254 delete pPropertyListener;
255 delete pPropertySetInfoChangeListeners;
260 //////////////////////////////////////////////////////////////////////////////////////////
261 // XServiceInfo
262 //////////////////////////////////////////////////////////////////////////////////////////
264 rtl::OUString SAL_CALL
265 BaseContent::getImplementationName()
266 throw( RuntimeException)
268 return rtl::OUString("com.sun.star.comp.ucb.FileContent");
273 sal_Bool SAL_CALL
274 BaseContent::supportsService( const rtl::OUString& ServiceName )
275 throw( RuntimeException)
277 if ( ServiceName == "com.sun.star.ucb.FileContent" )
278 return true;
279 else
280 return false;
285 Sequence< rtl::OUString > SAL_CALL
286 BaseContent::getSupportedServiceNames()
287 throw( RuntimeException )
289 Sequence< rtl::OUString > ret( 1 );
290 ret[0] = rtl::OUString("com.sun.star.ucb.FileContent");
291 return ret;
296 //////////////////////////////////////////////////////////////////////////////////////////
297 // XTypeProvider
298 //////////////////////////////////////////////////////////////////////////////////////////
300 XTYPEPROVIDER_IMPL_10( BaseContent,
301 lang::XComponent,
302 lang::XTypeProvider,
303 lang::XServiceInfo,
304 XCommandProcessor,
305 XContentCreator,
306 XContent,
307 container::XChild,
308 beans::XPropertiesChangeNotifier,
309 beans::XPropertyContainer,
310 beans::XPropertySetInfoChangeNotifier )
313 //////////////////////////////////////////////////////////////////////////////////////////
314 // XCommandProcessor
315 //////////////////////////////////////////////////////////////////////////////////////////
317 sal_Int32 SAL_CALL
318 BaseContent::createCommandIdentifier( void )
319 throw( RuntimeException )
321 return m_pMyShell->getCommandId();
325 void SAL_CALL
326 BaseContent::abort( sal_Int32 CommandId )
327 throw( RuntimeException )
329 m_pMyShell->abort( CommandId );
333 Any SAL_CALL
334 BaseContent::execute( const Command& aCommand,
335 sal_Int32 CommandId,
336 const Reference< XCommandEnvironment >& Environment )
337 throw( Exception,
338 CommandAbortedException,
339 RuntimeException )
341 if( ! CommandId )
342 // A Command with commandid zero cannot be aborted
343 CommandId = createCommandIdentifier();
345 m_pMyShell->startTask( CommandId,
346 Environment );
348 Any aAny;
350 if (aCommand.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("getPropertySetInfo"))) // No exceptions
352 aAny <<= getPropertySetInfo( CommandId );
354 else if (aCommand.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("getCommandInfo"))) // no exceptions
356 aAny <<= getCommandInfo();
358 else if ( aCommand.Name == "setPropertyValues" )
360 Sequence< beans::PropertyValue > sPropertyValues;
362 if( ! ( aCommand.Argument >>= sPropertyValues ) )
363 m_pMyShell->installError( CommandId,
364 TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
365 else
366 aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
368 else if ( aCommand.Name == "getPropertyValues" )
370 Sequence< beans::Property > ListOfRequestedProperties;
372 if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
373 m_pMyShell->installError( CommandId,
374 TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
375 else
376 aAny <<= getPropertyValues( CommandId,
377 ListOfRequestedProperties );
379 else if ( aCommand.Name == "open" )
381 OpenCommandArgument2 aOpenArgument;
382 if( ! ( aCommand.Argument >>= aOpenArgument ) )
383 m_pMyShell->installError( CommandId,
384 TASKHANDLING_WRONG_OPEN_ARGUMENT );
385 else
387 Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
388 if( result.is() )
389 aAny <<= result;
392 else if ( aCommand.Name == "delete" )
394 if( ! aCommand.Argument.has< sal_Bool >() )
395 m_pMyShell->installError( CommandId,
396 TASKHANDLING_WRONG_DELETE_ARGUMENT );
397 else
398 deleteContent( CommandId );
400 else if ( aCommand.Name == "transfer" )
402 TransferInfo aTransferInfo;
403 if( ! ( aCommand.Argument >>= aTransferInfo ) )
404 m_pMyShell->installError( CommandId,
405 TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
406 else
407 transfer( CommandId, aTransferInfo );
409 else if ( aCommand.Name == "insert" )
411 InsertCommandArgument aInsertArgument;
412 if( ! ( aCommand.Argument >>= aInsertArgument ) )
413 m_pMyShell->installError( CommandId,
414 TASKHANDLING_WRONG_INSERT_ARGUMENT );
415 else
416 insert( CommandId,aInsertArgument );
418 else if ( aCommand.Name == "getCasePreservingURL" )
420 Sequence< beans::Property > seq(1);
421 seq[0] = beans::Property(
422 rtl::OUString("CasePreservingURL"),
424 getCppuType( static_cast< sal_Bool* >(0) ),
425 0 );
426 Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
427 rtl::OUString CasePreservingURL = xRow->getString(1);
428 if(!xRow->wasNull())
429 aAny <<= CasePreservingURL;
431 else if ( aCommand.Name == "createNewContent" )
433 ucb::ContentInfo aArg;
434 if ( !( aCommand.Argument >>= aArg ) )
435 m_pMyShell->installError( CommandId,
436 TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
437 else
438 aAny <<= createNewContent( aArg );
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("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_FAIL( "BaseContent::getContentType - Property value was null!" );
550 catch (const sdbc::SQLException&)
552 OSL_FAIL( "BaseContent::getContentType - Caught SQLException!" );
557 return rtl::OUString();
562 void SAL_CALL
563 BaseContent::addContentEventListener(
564 const Reference< XContentEventListener >& Listener )
565 throw( RuntimeException )
567 osl::MutexGuard aGuard( m_aMutex );
569 if ( ! m_pContentEventListeners )
570 m_pContentEventListeners =
571 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
574 m_pContentEventListeners->addInterface( Listener );
578 void SAL_CALL
579 BaseContent::removeContentEventListener(
580 const Reference< XContentEventListener >& Listener )
581 throw( RuntimeException )
583 osl::MutexGuard aGuard( m_aMutex );
585 if ( m_pContentEventListeners )
586 m_pContentEventListeners->removeInterface( Listener );
591 ////////////////////////////////////////////////////////////////////////////////
592 // XPropertyContainer
593 ////////////////////////////////////////////////////////////////////////////////
596 void SAL_CALL
597 BaseContent::addProperty(
598 const rtl::OUString& Name,
599 sal_Int16 Attributes,
600 const Any& DefaultValue )
601 throw( beans::PropertyExistException,
602 beans::IllegalTypeException,
603 lang::IllegalArgumentException,
604 RuntimeException)
606 if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name.isEmpty() )
608 throw lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >(), 0 );
611 m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
615 void SAL_CALL
616 BaseContent::removeProperty(
617 const rtl::OUString& Name )
618 throw( beans::UnknownPropertyException,
619 beans::NotRemoveableException,
620 RuntimeException)
623 if( m_nState & Deleted )
624 throw beans::UnknownPropertyException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
626 m_pMyShell->deassociate( m_aUncPath, Name );
629 ////////////////////////////////////////////////////////////////////////////////
630 // XContentCreator
631 ////////////////////////////////////////////////////////////////////////////////
633 Sequence< ContentInfo > SAL_CALL
634 BaseContent::queryCreatableContentsInfo(
635 void )
636 throw( RuntimeException )
638 return m_pMyShell->queryCreatableContentsInfo();
642 Reference< XContent > SAL_CALL
643 BaseContent::createNewContent(
644 const ContentInfo& Info )
645 throw( RuntimeException )
647 // Check type.
648 if ( Info.Type.isEmpty() )
649 return Reference< XContent >();
651 sal_Bool bFolder
652 = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
653 if ( !bFolder )
655 if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
657 // Neither folder nor file to create!
658 return Reference< XContent >();
662 // Who am I ?
663 sal_Bool IsDocument = false;
667 Sequence< beans::Property > seq(1);
668 seq[0] = beans::Property( rtl::OUString("IsDocument"),
670 getCppuType( static_cast< sal_Bool* >(0) ),
671 0 );
672 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
673 IsDocument = xRow->getBoolean( 1 );
675 if ( xRow->wasNull() )
677 IsDocument = false;
678 // OSL_FAIL( // "BaseContent::createNewContent - Property value was null!" );
679 // return Reference< XContent >();
682 catch (const sdbc::SQLException&)
684 OSL_FAIL( "BaseContent::createNewContent - Caught SQLException!" );
685 return Reference< XContent >();
688 rtl::OUString dstUncPath;
690 if( IsDocument )
692 // KSO: Why is a document a XContentCreator? This is quite unusual.
693 dstUncPath = getParentName( m_aUncPath );
695 else
696 dstUncPath = m_aUncPath;
698 BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
699 return Reference< XContent >( p );
703 ////////////////////////////////////////////////////////////////////////////////
704 // XPropertySetInfoChangeNotifier
705 ////////////////////////////////////////////////////////////////////////////////
708 void SAL_CALL
709 BaseContent::addPropertySetInfoChangeListener(
710 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
711 throw( RuntimeException )
713 osl::MutexGuard aGuard( m_aMutex );
714 if( ! m_pPropertySetInfoChangeListeners )
715 m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
717 m_pPropertySetInfoChangeListeners->addInterface( Listener );
721 void SAL_CALL
722 BaseContent::removePropertySetInfoChangeListener(
723 const Reference< beans::XPropertySetInfoChangeListener >& Listener )
724 throw( RuntimeException )
726 osl::MutexGuard aGuard( m_aMutex );
728 if( m_pPropertySetInfoChangeListeners )
729 m_pPropertySetInfoChangeListeners->removeInterface( Listener );
733 ////////////////////////////////////////////////////////////////////////////////
734 // XChild
735 ////////////////////////////////////////////////////////////////////////////////
737 Reference< XInterface > SAL_CALL
738 BaseContent::getParent(
739 void )
740 throw( RuntimeException )
742 rtl::OUString ParentUnq = getParentName( m_aUncPath );
743 rtl::OUString ParentUrl;
746 sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
747 if( err )
748 return Reference< XInterface >( 0 );
750 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
751 Reference< XContentIdentifier > Identifier( p );
755 Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
756 return Reference<XInterface>(content,UNO_QUERY);
758 catch (const IllegalIdentifierException&)
760 return Reference< XInterface >();
765 void SAL_CALL
766 BaseContent::setParent(
767 const Reference< XInterface >& )
768 throw( lang::NoSupportException,
769 RuntimeException)
771 throw lang::NoSupportException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
775 //////////////////////////////////////////////////////////////////////////////////////////
776 // Private Methods
777 //////////////////////////////////////////////////////////////////////////////////////////
780 Reference< XCommandInfo > SAL_CALL
781 BaseContent::getCommandInfo()
782 throw( RuntimeException )
784 if( m_nState & Deleted )
785 return Reference< XCommandInfo >();
787 return m_pMyShell->info_c();
791 Reference< beans::XPropertySetInfo > SAL_CALL
792 BaseContent::getPropertySetInfo(
793 sal_Int32 )
794 throw( RuntimeException )
796 if( m_nState & Deleted )
797 return Reference< beans::XPropertySetInfo >();
799 return m_pMyShell->info_p( m_aUncPath );
805 Reference< sdbc::XRow > SAL_CALL
806 BaseContent::getPropertyValues(
807 sal_Int32 nMyCommandIdentifier,
808 const Sequence< beans::Property >& PropertySet )
809 throw( RuntimeException )
811 sal_Int32 nProps = PropertySet.getLength();
812 if ( !nProps )
813 return Reference< sdbc::XRow >();
815 if( m_nState & Deleted )
817 Sequence< Any > aValues( nProps );
818 return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
821 if( m_nState & JustInserted )
823 Sequence< Any > aValues( nProps );
824 Any* pValues = aValues.getArray();
826 const beans::Property* pProps = PropertySet.getConstArray();
828 for ( sal_Int32 n = 0; n < nProps; ++n )
830 const beans::Property& rProp = pProps[ n ];
831 Any& rValue = pValues[ n ];
833 if ( rProp.Name == "ContentType" )
835 rValue <<= m_bFolder ? m_pMyShell->FolderContentType
836 : m_pMyShell->FileContentType;
838 else if ( rProp.Name == "IsFolder" )
840 rValue <<= m_bFolder;
842 else if ( rProp.Name == "IsDocument" )
844 rValue <<= sal_Bool( !m_bFolder );
848 return Reference< sdbc::XRow >(
849 new XRow_impl( m_pMyShell, aValues ) );
852 return m_pMyShell->getv( nMyCommandIdentifier,
853 m_aUncPath,
854 PropertySet );
858 Sequence< Any > SAL_CALL
859 BaseContent::setPropertyValues(
860 sal_Int32 nMyCommandIdentifier,
861 const Sequence< beans::PropertyValue >& Values )
862 throw()
864 if( m_nState & Deleted )
865 { // To do
866 return Sequence< Any >( Values.getLength() );
869 const rtl::OUString Title("Title");
871 // Special handling for files which have to be inserted
872 if( m_nState & JustInserted )
874 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
876 if( Values[i].Name == Title )
878 rtl::OUString NewTitle;
879 if( Values[i].Value >>= NewTitle )
881 if ( m_nState & NameForInsertionSet )
883 // User wants to set another Title before "insert".
884 // m_aUncPath contains previous own URI.
886 sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
887 bool bTrailingSlash = false;
888 if ( nLastSlash == m_aUncPath.getLength() - 1 )
890 bTrailingSlash = true;
891 nLastSlash
892 = m_aUncPath.lastIndexOf( '/', nLastSlash );
895 OSL_ENSURE( nLastSlash != -1,
896 "BaseContent::setPropertyValues: "
897 "Invalid URL!" );
899 rtl::OUStringBuffer aBuf(
900 m_aUncPath.copy( 0, nLastSlash + 1 ) );
902 if ( !NewTitle.isEmpty() )
904 aBuf.append( NewTitle );
905 if ( bTrailingSlash )
906 aBuf.append( sal_Unicode( '/' ) );
908 else
910 m_nState &= ~NameForInsertionSet;
913 m_aUncPath = aBuf.makeStringAndClear();
915 else
917 if ( !NewTitle.isEmpty() )
919 // Initial Title before "insert".
920 // m_aUncPath contains parent's URI.
922 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
923 m_aUncPath += rtl::OUString("/");
925 m_aUncPath += rtl::Uri::encode( NewTitle,
926 rtl_UriCharClassPchar,
927 rtl_UriEncodeIgnoreEscapes,
928 RTL_TEXTENCODING_UTF8 );
929 m_nState |= NameForInsertionSet;
936 return Sequence< Any >( Values.getLength() );
938 else
940 Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
941 Values );
943 // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
944 for( sal_Int32 i = 0; i < Values.getLength(); ++i )
946 if( Values[i].Name != Title )
947 continue; // handled by setv
949 rtl::OUString NewTitle;
950 if( !( Values[i].Value >>= NewTitle ) )
952 ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >() );
953 break;
955 else if( NewTitle.isEmpty() )
957 ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( OSL_LOG_PREFIX ), uno::Reference< uno::XInterface >(), 0 );
958 break;
962 rtl::OUString aDstName = getParentName( m_aUncPath );
963 if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
964 aDstName += rtl::OUString("/");
966 aDstName += rtl::Uri::encode( NewTitle,
967 rtl_UriCharClassPchar,
968 rtl_UriEncodeIgnoreEscapes,
969 RTL_TEXTENCODING_UTF8 );
971 m_pMyShell->move( nMyCommandIdentifier, // move notifies the children also;
972 m_aUncPath,
973 aDstName,
974 NameClash::KEEP );
978 endTask( nMyCommandIdentifier );
980 catch(const Exception& e)
982 ret[i] <<= e;
985 // NameChanges come back trough a ContentEvent
986 break; // only handling Title
987 } // end for
989 return ret;
995 Reference< XDynamicResultSet > SAL_CALL
996 BaseContent::open(
997 sal_Int32 nMyCommandIdentifier,
998 const OpenCommandArgument2& aCommandArgument )
999 throw()
1001 Reference< XDynamicResultSet > retValue( 0 );
1003 if( ( m_nState & Deleted ) )
1005 m_pMyShell->installError( nMyCommandIdentifier,
1006 TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
1008 else if( m_nState & JustInserted )
1010 m_pMyShell->installError( nMyCommandIdentifier,
1011 TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
1013 else
1015 if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
1016 aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
1019 Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
1020 if( outputStream.is() )
1022 m_pMyShell->page( nMyCommandIdentifier,
1023 m_aUncPath,
1024 outputStream );
1027 sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
1029 Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
1030 if( activeDataSink.is() )
1032 activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
1033 m_aUncPath,
1034 bLock ) );
1037 Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
1038 if( activeDataStreamer.is() )
1040 activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
1041 m_aUncPath,
1042 bLock ) );
1045 else if ( aCommandArgument.Mode == OpenMode::ALL ||
1046 aCommandArgument.Mode == OpenMode::FOLDERS ||
1047 aCommandArgument.Mode == OpenMode::DOCUMENTS )
1049 retValue = m_pMyShell->ls( nMyCommandIdentifier,
1050 m_aUncPath,
1051 aCommandArgument.Mode,
1052 aCommandArgument.Properties,
1053 aCommandArgument.SortingInfo );
1055 // else if( aCommandArgument.Mode ==
1056 // OpenMode::DOCUMENT_SHARE_DENY_NONE ||
1057 // aCommandArgument.Mode ==
1058 // OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1059 // m_pMyShell->installError( nMyCommandIdentifier,
1060 // TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1061 // aCommandArgument.Mode);
1062 else
1063 m_pMyShell->installError( nMyCommandIdentifier,
1064 TASKHANDLING_UNSUPPORTED_OPEN_MODE,
1065 aCommandArgument.Mode);
1068 return retValue;
1073 void SAL_CALL
1074 BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
1075 throw()
1077 if( m_nState & Deleted )
1078 return;
1080 if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
1082 osl::MutexGuard aGuard( m_aMutex );
1083 m_nState |= Deleted;
1089 void SAL_CALL
1090 BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
1091 const TransferInfo& aTransferInfo )
1092 throw()
1094 if( m_nState & Deleted )
1095 return;
1097 if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
1099 m_pMyShell->installError( nMyCommandIdentifier,
1100 TASKHANDLING_TRANSFER_INVALIDSCHEME );
1101 return;
1104 rtl::OUString srcUnc;
1105 if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
1107 m_pMyShell->installError( nMyCommandIdentifier,
1108 TASKHANDLING_TRANSFER_INVALIDURL );
1109 return;
1112 rtl::OUString srcUncPath = srcUnc;
1114 // Determine the new title !
1115 rtl::OUString NewTitle;
1116 if( !aTransferInfo.NewTitle.isEmpty() )
1117 NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
1118 rtl_UriCharClassPchar,
1119 rtl_UriEncodeIgnoreEscapes,
1120 RTL_TEXTENCODING_UTF8 );
1121 else
1122 NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
1124 // Is destination a document or a folder ?
1125 Sequence< beans::Property > seq(1);
1126 seq[0] = beans::Property( rtl::OUString("IsDocument"),
1128 getCppuType( static_cast< sal_Bool* >(0) ),
1129 0 );
1130 Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
1131 sal_Bool IsDocument = xRow->getBoolean( 1 );
1132 if( xRow->wasNull() )
1133 { // Destination file type could not be determined
1134 m_pMyShell->installError( nMyCommandIdentifier,
1135 TASKHANDLING_TRANSFER_DESTFILETYPE );
1136 return;
1139 rtl::OUString dstUncPath;
1140 if( IsDocument )
1141 { // as sibling
1142 sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
1143 dstUncPath = m_aUncPath.copy(0,lastSlash );
1145 else
1146 // as child
1147 dstUncPath = m_aUncPath;
1149 dstUncPath += ( rtl::OUString("/") + NewTitle );
1151 sal_Int32 NameClash = aTransferInfo.NameClash;
1153 if( aTransferInfo.MoveData )
1154 m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1155 else
1156 m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
1162 void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
1163 const InsertCommandArgument& aInsertArgument )
1164 throw()
1166 if( m_nState & FullFeatured )
1168 m_pMyShell->write( nMyCommandIdentifier,
1169 m_aUncPath,
1170 aInsertArgument.ReplaceExisting,
1171 aInsertArgument.Data );
1172 return;
1175 if( ! ( m_nState & JustInserted ) )
1177 m_pMyShell->installError( nMyCommandIdentifier,
1178 TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
1179 return;
1182 // Inserts the content, which has the flag m_bIsFresh
1184 if( ! (m_nState & NameForInsertionSet) )
1186 m_pMyShell->installError( nMyCommandIdentifier,
1187 TASKHANDLING_NONAMESET_INSERT_COMMAND );
1188 return;
1191 // Inserting a document or a file?
1192 sal_Bool bDocument = false;
1194 Sequence< beans::Property > seq(1);
1195 seq[0] = beans::Property( rtl::OUString("IsDocument"),
1197 getCppuType( static_cast< sal_Bool* >(0) ),
1198 0 );
1200 Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
1202 bool contentTypeSet = true; // is set to false, if contentType not set
1205 bDocument = xRow->getBoolean( 1 );
1206 if( xRow->wasNull() )
1207 contentTypeSet = false;
1210 catch (const sdbc::SQLException&)
1212 OSL_FAIL( "BaseContent::insert - Caught SQLException!" );
1213 contentTypeSet = false;
1216 if( ! contentTypeSet )
1218 m_pMyShell->installError( nMyCommandIdentifier,
1219 TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
1220 return;
1224 sal_Bool success = false;
1225 if( bDocument )
1226 success = m_pMyShell->mkfil( nMyCommandIdentifier,
1227 m_aUncPath,
1228 aInsertArgument.ReplaceExisting,
1229 aInsertArgument.Data );
1230 else
1232 while( ! success )
1234 success = m_pMyShell->mkdir( nMyCommandIdentifier,
1235 m_aUncPath,
1236 aInsertArgument.ReplaceExisting );
1237 if( success )
1238 break;
1240 XInteractionRequestImpl *aRequestImpl =
1241 new XInteractionRequestImpl(
1242 rtl::Uri::decode(
1243 getTitle(m_aUncPath),
1244 rtl_UriDecodeWithCharset,
1245 RTL_TEXTENCODING_UTF8),
1246 (cppu::OWeakObject*)this,
1247 m_pMyShell,nMyCommandIdentifier);
1248 uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
1250 m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
1251 if( aRequestImpl->aborted() ||
1252 aRequestImpl->newName().isEmpty() )
1253 // means aborting
1254 break;
1256 // determine new uncpath
1257 m_pMyShell->clearError( nMyCommandIdentifier );
1258 m_aUncPath = getParentName( m_aUncPath );
1259 if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
1260 m_aUncPath += rtl::OUString("/");
1262 m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
1263 rtl_UriCharClassPchar,
1264 rtl_UriEncodeIgnoreEscapes,
1265 RTL_TEXTENCODING_UTF8 );
1269 if ( ! success )
1270 return;
1272 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
1273 m_xContentIdentifier = Reference< XContentIdentifier >( p );
1275 m_pMyShell->registerNotifier( m_aUncPath,this );
1276 m_pMyShell->insertDefaultProperties( m_aUncPath );
1278 osl::MutexGuard aGuard( m_aMutex );
1279 m_nState = FullFeatured;
1284 void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
1286 // This is the only function allowed to throw an exception
1287 m_pMyShell->endTask( CommandId,m_aUncPath,this );
1292 ContentEventNotifier*
1293 BaseContent::cDEL( void )
1295 osl::MutexGuard aGuard( m_aMutex );
1297 m_nState |= Deleted;
1299 ContentEventNotifier* p;
1300 if( m_pContentEventListeners )
1301 p = new ContentEventNotifier( m_pMyShell,
1302 this,
1303 m_xContentIdentifier,
1304 m_pContentEventListeners->getElements() );
1305 else
1306 p = 0;
1308 return p;
1312 ContentEventNotifier*
1313 BaseContent::cEXC( const rtl::OUString aNewName )
1315 osl::MutexGuard aGuard( m_aMutex );
1317 Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
1318 m_aUncPath = aNewName;
1319 FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
1320 m_xContentIdentifier = Reference< XContentIdentifier >( pp );
1322 ContentEventNotifier* p = 0;
1323 if( m_pContentEventListeners )
1324 p = new ContentEventNotifier( m_pMyShell,
1325 this,
1326 m_xContentIdentifier,
1327 xOldRef,
1328 m_pContentEventListeners->getElements() );
1330 return p;
1334 ContentEventNotifier*
1335 BaseContent::cCEL( void )
1337 osl::MutexGuard aGuard( m_aMutex );
1338 ContentEventNotifier* p = 0;
1339 if( m_pContentEventListeners )
1340 p = new ContentEventNotifier( m_pMyShell,
1341 this,
1342 m_xContentIdentifier,
1343 m_pContentEventListeners->getElements() );
1345 return p;
1348 PropertySetInfoChangeNotifier*
1349 BaseContent::cPSL( void )
1351 osl::MutexGuard aGuard( m_aMutex );
1352 PropertySetInfoChangeNotifier* p = 0;
1353 if( m_pPropertySetInfoChangeListeners )
1354 p = new PropertySetInfoChangeNotifier( m_pMyShell,
1355 this,
1356 m_xContentIdentifier,
1357 m_pPropertySetInfoChangeListeners->getElements() );
1359 return p;
1364 PropertyChangeNotifier*
1365 BaseContent::cPCL( void )
1367 osl::MutexGuard aGuard( m_aMutex );
1369 Sequence< rtl::OUString > seqNames;
1371 if( m_pPropertyListener )
1372 seqNames = m_pPropertyListener->getContainedTypes();
1374 PropertyChangeNotifier* p = 0;
1376 sal_Int32 length = seqNames.getLength();
1378 if( length )
1380 ListenerMap* listener = new ListenerMap();
1381 for( sal_Int32 i = 0; i < length; ++i )
1383 (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
1386 p = new PropertyChangeNotifier( m_pMyShell,
1387 this,
1388 m_xContentIdentifier,
1389 listener );
1392 return p;
1396 rtl::OUString BaseContent::getKey( void )
1398 return m_aUncPath;
1401 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */