summaryrefslogtreecommitdiff
path: root/unotools/source/ucbhelper
diff options
context:
space:
mode:
Diffstat (limited to 'unotools/source/ucbhelper')
-rw-r--r--unotools/source/ucbhelper/XTempFile.hxx153
-rw-r--r--unotools/source/ucbhelper/localfilehelper.cxx242
-rw-r--r--unotools/source/ucbhelper/makefile.mk54
-rw-r--r--unotools/source/ucbhelper/progresshandlerwrap.cxx98
-rw-r--r--unotools/source/ucbhelper/tempfile.cxx493
-rw-r--r--unotools/source/ucbhelper/ucbhelper.cxx925
-rw-r--r--unotools/source/ucbhelper/ucblockbytes.cxx1746
-rw-r--r--unotools/source/ucbhelper/ucbstreamhelper.cxx248
-rw-r--r--unotools/source/ucbhelper/xtempfile.cxx576
9 files changed, 4535 insertions, 0 deletions
diff --git a/unotools/source/ucbhelper/XTempFile.hxx b/unotools/source/ucbhelper/XTempFile.hxx
new file mode 100644
index 000000000000..115f6cf823a7
--- /dev/null
+++ b/unotools/source/ucbhelper/XTempFile.hxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _XTEMPFILE_HXX_
+#define _XTEMPFILE_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XTempFile.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase5.hxx>
+#ifndef _CPPUHELPER_PROPERTYSETMIXIN_HXX_
+#include <cppuhelper/propertysetmixin.hxx>
+#endif
+#include <osl/mutex.hxx>
+
+class SvStream;
+namespace utl { class TempFile; }
+
+typedef ::cppu::WeakImplHelper5< ::com::sun::star::io::XTempFile
+ , ::com::sun::star::io::XInputStream
+ , ::com::sun::star::io::XOutputStream
+ , ::com::sun::star::io::XTruncate
+ , ::com::sun::star::lang::XServiceInfo
+ >
+ OTempFileBase;
+
+class OTempFileService :
+ public OTempFileBase,
+ public ::cppu::PropertySetMixin< ::com::sun::star::io::XTempFile >
+{
+protected:
+ ::utl::TempFile* mpTempFile;
+ ::osl::Mutex maMutex;
+ SvStream* mpStream;
+ sal_Bool mbRemoveFile;
+ sal_Bool mbInClosed;
+ sal_Bool mbOutClosed;
+
+ sal_Int64 mnCachedPos;
+ sal_Bool mbHasCachedPos;
+
+ void checkError () const;
+ void checkConnected ();
+
+public:
+ OTempFileService (::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context);
+
+ //Methods
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( )
+ throw ();
+ virtual void SAL_CALL release( )
+ throw ();
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XTempFile
+ virtual ::sal_Bool SAL_CALL getRemoveFile()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setRemoveFile( ::sal_Bool _removefile )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getUri()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getResourceName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInputStream
+ virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL available( )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeInput( )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL flush( )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeOutput( )
+ throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( )
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( )
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XStream
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( )
+ throw (::com::sun::star::uno::RuntimeException);
+ // XTruncate
+ virtual void SAL_CALL truncate()
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > SAL_CALL XTempFile_createInstance( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context);
+ static ::rtl::OUString getImplementationName_Static ();
+ static ::com::sun::star::uno::Sequence < ::rtl::OUString > getSupportedServiceNames_Static();
+
+ static ::com::sun::star::uno::Reference < com::sun::star::lang::XSingleComponentFactory > createServiceFactory_Static( com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > const & rServiceFactory );
+
+private:
+ OTempFileService( OTempFileService & );
+ virtual ~OTempFileService ();
+
+};
+#endif
diff --git a/unotools/source/ucbhelper/localfilehelper.cxx b/unotools/source/ucbhelper/localfilehelper.cxx
new file mode 100644
index 000000000000..5ddd1f811923
--- /dev/null
+++ b/unotools/source/ucbhelper/localfilehelper.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+
+#include <unotools/localfilehelper.hxx>
+#include <ucbhelper/fileidentifierconverter.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <tools/debug.hxx>
+#include <tools/list.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/content.hxx>
+
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+
+namespace utl
+{
+
+sal_Bool LocalFileHelper::ConvertSystemPathToURL( const String& rName, const String& rBaseURL, String& rReturn )
+{
+ rReturn = ::rtl::OUString();
+
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ {
+ rtl::OUString aRet;
+ if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
+ rReturn = aRet;
+ }
+ else
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+ try
+ {
+ rReturn = ::ucbhelper::getFileURLFromSystemPath( xManager, rBaseURL, rName );
+ }
+ catch ( ::com::sun::star::uno::RuntimeException& )
+ {
+ return sal_False;
+ }
+ }
+
+ return ( rReturn.Len() != 0 );
+}
+
+sal_Bool LocalFileHelper::ConvertURLToSystemPath( const String& rName, String& rReturn )
+{
+ rReturn = ::rtl::OUString();
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ {
+ rtl::OUString aRet;
+ if( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
+ rReturn = aRet;
+ }
+ else
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+ try
+ {
+ rReturn = ::ucbhelper::getSystemPathFromFileURL( xManager, rName );
+ }
+ catch ( ::com::sun::star::uno::RuntimeException& )
+ {
+ }
+ }
+
+ return ( rReturn.Len() != 0 );
+}
+
+sal_Bool LocalFileHelper::ConvertPhysicalNameToURL( const String& rName, String& rReturn )
+{
+ rReturn = ::rtl::OUString();
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ {
+ rtl::OUString aRet;
+ if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
+ rReturn = aRet;
+ }
+ else
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+
+ try
+ {
+ rtl::OUString aBase( ::ucbhelper::getLocalFileURL( xManager ) );
+ rReturn = ::ucbhelper::getFileURLFromSystemPath( xManager, aBase, rName );
+ }
+ catch ( ::com::sun::star::uno::RuntimeException& )
+ {
+ }
+ }
+
+ return ( rReturn.Len() != 0 );
+}
+
+sal_Bool LocalFileHelper::ConvertURLToPhysicalName( const String& rName, String& rReturn )
+{
+ rReturn = ::rtl::OUString();
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ {
+ ::rtl::OUString aRet;
+ if ( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
+ rReturn = aRet;
+ }
+ else
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+ try
+ {
+ INetURLObject aObj( rName );
+ INetURLObject aLocal( ::ucbhelper::getLocalFileURL( xManager ) );
+ if ( aObj.GetProtocol() == aLocal.GetProtocol() )
+ rReturn = ::ucbhelper::getSystemPathFromFileURL( xManager, rName );
+ }
+ catch ( ::com::sun::star::uno::RuntimeException& )
+ {
+ }
+ }
+
+ return ( rReturn.Len() != 0 );
+}
+
+sal_Bool LocalFileHelper::IsLocalFile( const String& rName )
+{
+ String aTmp;
+ return ConvertURLToPhysicalName( rName, aTmp );
+}
+
+sal_Bool LocalFileHelper::IsFileContent( const String& rName )
+{
+ String aTmp;
+ return ConvertURLToSystemPath( rName, aTmp );
+}
+
+DECLARE_LIST( StringList_Impl, ::rtl::OUString* )
+
+::com::sun::star::uno::Sequence < ::rtl::OUString > LocalFileHelper::GetFolderContents( const ::rtl::OUString& rFolder, sal_Bool bFolder )
+{
+ StringList_Impl* pFiles = NULL;
+ try
+ {
+ ::ucbhelper::Content aCnt( rFolder, Reference< XCommandEnvironment > () );
+ Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aProps(1);
+ ::rtl::OUString* pProps = aProps.getArray();
+ pProps[0] = ::rtl::OUString::createFromAscii( "Url" );
+
+ try
+ {
+ ::ucbhelper::ResultSetInclude eInclude = bFolder ? ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ::ucbhelper::INCLUDE_DOCUMENTS_ONLY;
+ xResultSet = aCnt.createCursor( aProps, eInclude );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( xResultSet.is() )
+ {
+ pFiles = new StringList_Impl;
+ Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ ::rtl::OUString aId = xContentAccess->queryContentIdentifierString();
+ ::rtl::OUString* pFile = new ::rtl::OUString( aId );
+ pFiles->Insert( pFile, LIST_APPEND );
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( pFiles )
+ {
+ ULONG nCount = pFiles->Count();
+ Sequence < ::rtl::OUString > aRet( nCount );
+ ::rtl::OUString* pRet = aRet.getArray();
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ ::rtl::OUString* pFile = pFiles->GetObject(i);
+ pRet[i] = *( pFile );
+ delete pFile;
+ }
+ delete pFiles;
+ return aRet;
+ }
+ else
+ return Sequence < ::rtl::OUString > ();
+}
+
+}
diff --git a/unotools/source/ucbhelper/makefile.mk b/unotools/source/ucbhelper/makefile.mk
new file mode 100644
index 000000000000..57088c69ca5c
--- /dev/null
+++ b/unotools/source/ucbhelper/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=..$/..$/inc
+PRJNAME=unotools
+TARGET=ucbhelp
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES=\
+ $(SLO)$/ucblockbytes.obj \
+ $(SLO)$/localfilehelper.obj \
+ $(SLO)$/ucbhelper.obj \
+ $(SLO)$/ucbstreamhelper.obj \
+ $(SLO)$/tempfile.obj \
+ $(SLO)$/xtempfile.obj \
+ $(SLO)$/progresshandlerwrap.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/unotools/source/ucbhelper/progresshandlerwrap.cxx b/unotools/source/ucbhelper/progresshandlerwrap.cxx
new file mode 100644
index 000000000000..7fdbdacabc4b
--- /dev/null
+++ b/unotools/source/ucbhelper/progresshandlerwrap.cxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+#include <unotools/progresshandlerwrap.hxx>
+
+namespace utl
+{
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+
+ProgressHandlerWrap::ProgressHandlerWrap( ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > xSI )
+: m_xStatusIndicator( xSI )
+{
+}
+
+sal_Bool getStatusFromAny_Impl( const Any& aAny, ::rtl::OUString& aText, sal_Int32& nNum )
+{
+ sal_Bool bNumIsSet = sal_False;
+
+ Sequence< Any > aSetList;
+ if( ( aAny >>= aSetList ) && aSetList.getLength() )
+ for( int ind = 0; ind < aSetList.getLength(); ind++ )
+ {
+ if( !bNumIsSet && ( aSetList[ind] >>= nNum ) )
+ bNumIsSet = sal_True;
+ else
+ !aText.getLength() && ( aSetList[ind] >>= aText );
+ }
+
+ return bNumIsSet;
+}
+
+void SAL_CALL ProgressHandlerWrap::push( const Any& Status )
+ throw( RuntimeException )
+{
+ if( !m_xStatusIndicator.is() )
+ return;
+
+ ::rtl::OUString aText;
+ sal_Int32 nRange;
+
+ if( getStatusFromAny_Impl( Status, aText, nRange ) )
+ m_xStatusIndicator->start( aText, nRange );
+}
+
+void SAL_CALL ProgressHandlerWrap::update( const Any& Status )
+ throw( RuntimeException )
+{
+ if( !m_xStatusIndicator.is() )
+ return;
+
+ ::rtl::OUString aText;
+ sal_Int32 nValue;
+
+ if( getStatusFromAny_Impl( Status, aText, nValue ) )
+ {
+ if( aText.getLength() ) m_xStatusIndicator->setText( aText );
+ m_xStatusIndicator->setValue( nValue );
+ }
+}
+
+void SAL_CALL ProgressHandlerWrap::pop()
+ throw( RuntimeException )
+{
+ if( m_xStatusIndicator.is() )
+ m_xStatusIndicator->end();
+}
+
+} // namespace utl
+
diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx
new file mode 100644
index 000000000000..e77dc529e410
--- /dev/null
+++ b/unotools/source/ucbhelper/tempfile.cxx
@@ -0,0 +1,493 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+
+#include <unotools/tempfile.hxx>
+#include <tools/tempfile.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <ucbhelper/fileidentifierconverter.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/instance.hxx>
+#include <osl/file.hxx>
+#include <tools/time.hxx>
+#include <tools/debug.hxx>
+#include <stdio.h>
+
+#ifdef UNX
+#include <sys/stat.h>
+#endif
+
+using namespace osl;
+
+namespace
+{
+ struct TempNameBase_Impl
+ : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {};
+}
+
+namespace utl
+{
+
+struct TempFile_Impl
+{
+ String aName;
+ String aURL;
+ SvStream* pStream;
+ sal_Bool bIsDirectory;
+
+ TempFile_Impl()
+ : pStream(0)
+ {}
+};
+
+rtl::OUString getParentName( const rtl::OUString& aFileName )
+{
+ sal_Int32 lastIndex = aFileName.lastIndexOf( sal_Unicode('/') );
+ rtl::OUString aParent = aFileName.copy( 0,lastIndex );
+
+ if( aParent[ aParent.getLength()-1] == sal_Unicode(':') && aParent.getLength() == 6 )
+ aParent += rtl::OUString::createFromAscii( "/" );
+
+ if( 0 == aParent.compareToAscii( "file://" ) )
+ aParent = rtl::OUString::createFromAscii( "file:///" );
+
+ return aParent;
+}
+
+sal_Bool ensuredir( const rtl::OUString& rUnqPath )
+{
+ rtl::OUString aPath;
+ if ( rUnqPath.getLength() < 1 )
+ return sal_False;
+
+ // remove trailing slash
+ if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
+ aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
+ else
+ aPath = rUnqPath;
+
+ // HACK: create directory on a mount point with nobrowse option
+ // returns ENOSYS in any case !!
+ osl::Directory aDirectory( aPath );
+#ifdef UNX
+/* RW permission for the user only! */
+ mode_t old_mode = umask(077);
+#endif
+ osl::FileBase::RC nError = aDirectory.open();
+#ifdef UNX
+umask(old_mode);
+#endif
+ aDirectory.close();
+ if( nError == osl::File::E_None )
+ return sal_True;
+
+ // try to create the directory
+ nError = osl::Directory::create( aPath );
+ sal_Bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+ if( !bSuccess )
+ {
+ // perhaps parent(s) don't exist
+ rtl::OUString aParentDir = getParentName( aPath );
+ if ( aParentDir != aPath )
+ {
+ bSuccess = ensuredir( getParentName( aPath ) );
+
+ // After parent directory structure exists try it one's more
+ if ( bSuccess )
+ {
+ // Parent directory exists, retry creation of directory
+ nError = osl::Directory::create( aPath );
+ bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+ }
+ }
+ }
+
+ return bSuccess;
+}
+
+#define TMPNAME_SIZE ( 1 + 5 + 5 + 4 + 1 )
+String ConstructTempDir_Impl( const String* pParent )
+{
+ String aName;
+ if ( pParent && pParent->Len() )
+ {
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( pBroker )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
+ pBroker->getContentProviderManagerInterface();
+
+ // if parent given try to use it
+ rtl::OUString aTmp( *pParent );
+
+ // test for valid filename
+ rtl::OUString aRet;
+ ::osl::FileBase::getFileURLFromSystemPath(
+ ::ucbhelper::getSystemPathFromFileURL( xManager, aTmp ),
+ aRet );
+ if ( aRet.getLength() )
+ {
+ ::osl::DirectoryItem aItem;
+ sal_Int32 i = aRet.getLength();
+ if ( aRet[i-1] == '/' )
+ i--;
+
+ if ( DirectoryItem::get( ::rtl::OUString( aRet, i ), aItem ) == FileBase::E_None )
+ aName = aRet;
+ }
+ }
+ else
+ {
+ DBG_WARNING( "::unotools::TempFile : UCB not present or not initialized!" );
+ }
+ }
+
+ if ( !aName.Len() )
+ {
+ ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get();
+ if (rTempNameBase_Impl.getLength() == 0)
+ {
+ ::rtl::OUString ustrTempDirURL;
+ ::osl::FileBase::RC rc = ::osl::File::getTempDirURL(
+ ustrTempDirURL );
+ if (rc == ::osl::FileBase::E_None)
+ rTempNameBase_Impl = ustrTempDirURL;
+ }
+ // if no parent or invalid parent : use default directory
+ DBG_ASSERT( rTempNameBase_Impl.getLength(), "No TempDir!" );
+ aName = rTempNameBase_Impl;
+ ensuredir( aName );
+ }
+
+ // Make sure that directory ends with a separator
+ xub_StrLen i = aName.Len();
+ if( i>0 && aName.GetChar(i-1) != '/' )
+ aName += '/';
+
+ return aName;
+}
+
+void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True )
+{
+ // add a suitable tempname
+ // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
+ // ER 13.07.00 why not radix 36 [0-9A-Z] ?!?
+ const unsigned nRadix = 26;
+ String aName( rName );
+ aName += String::CreateFromAscii( "sv" );
+
+ rName.Erase();
+ static unsigned long u = Time::GetSystemTicks();
+ for ( unsigned long nOld = u; ++u != nOld; )
+ {
+ u %= (nRadix*nRadix*nRadix);
+ String aTmp( aName );
+ aTmp += String::CreateFromInt32( (sal_Int32) (unsigned) u, nRadix );
+ aTmp += String::CreateFromAscii( ".tmp" );
+
+ if ( bDir )
+ {
+ FileBase::RC err = Directory::create( aTmp );
+ if ( err == FileBase::E_None )
+ {
+ // !bKeep: only for creating a name, not a file or directory
+ if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
+ rName = aTmp;
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ {
+ // if f.e. name contains invalid chars stop trying to create dirs
+ break;
+ }
+ }
+ else
+ {
+ DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
+ File aFile( aTmp );
+#ifdef UNX
+/* RW permission for the user only! */
+ mode_t old_mode = umask(077);
+#endif
+ FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
+#ifdef UNX
+umask(old_mode);
+#endif
+ if ( err == FileBase::E_None )
+ {
+ rName = aTmp;
+ aFile.close();
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ {
+ // if f.e. name contains invalid chars stop trying to create files
+ // but if there is a folder with such name proceed further
+
+ DirectoryItem aTmpItem;
+ FileStatus aTmpStatus( FileStatusMask_Type );
+ if ( DirectoryItem::get( aTmp, aTmpItem ) != FileBase::E_None
+ || aTmpItem.getFileStatus( aTmpStatus ) != FileBase::E_None
+ || aTmpStatus.getFileType() != FileStatus::Directory )
+ break;
+ }
+ }
+ }
+}
+
+void lcl_createName(TempFile_Impl& _rImpl,const String& rLeadingChars,sal_Bool _bStartWithZero, const String* pExtension, const String* pParent, sal_Bool bDirectory)
+{
+ _rImpl.bIsDirectory = bDirectory;
+
+ // get correct directory
+ String aName = ConstructTempDir_Impl( pParent );
+
+ sal_Bool bUseNumber = _bStartWithZero;
+ // now use special naming scheme ( name takes leading chars and an index counting up from zero
+ aName += rLeadingChars;
+ for ( sal_Int32 i=0;; i++ )
+ {
+ String aTmp( aName );
+ if ( bUseNumber )
+ aTmp += String::CreateFromInt32( i );
+ bUseNumber = sal_True;
+ if ( pExtension )
+ aTmp += *pExtension;
+ else
+ aTmp += String::CreateFromAscii( ".tmp" );
+ if ( bDirectory )
+ {
+ FileBase::RC err = Directory::create( aTmp );
+ if ( err == FileBase::E_None )
+ {
+ _rImpl.aName = aTmp;
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ // if f.e. name contains invalid chars stop trying to create dirs
+ break;
+ }
+ else
+ {
+ File aFile( aTmp );
+#ifdef UNX
+/* RW permission for the user only! */
+ mode_t old_mode = umask(077);
+#endif
+ FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
+#ifdef UNX
+umask(old_mode);
+#endif
+ if ( err == FileBase::E_None )
+ {
+ _rImpl.aName = aTmp;
+ aFile.close();
+ break;
+ }
+ else if ( err != FileBase::E_EXIST )
+ {
+ // if f.e. name contains invalid chars stop trying to create dirs
+ // but if there is a folder with such name proceed further
+
+ DirectoryItem aTmpItem;
+ FileStatus aTmpStatus( FileStatusMask_Type );
+ if ( DirectoryItem::get( aTmp, aTmpItem ) != FileBase::E_None
+ || aTmpItem.getFileStatus( aTmpStatus ) != FileBase::E_None
+ || aTmpStatus.getFileType() != FileStatus::Directory )
+ break;
+ }
+ }
+ if ( !_bStartWithZero )
+ aTmp += String::CreateFromInt32( i );
+ }
+}
+
+
+String TempFile::CreateTempName( const String* pParent )
+{
+ // get correct directory
+ String aName = ConstructTempDir_Impl( pParent );
+
+ // get TempFile name with default naming scheme
+ CreateTempName_Impl( aName, sal_False );
+
+ // convert to file URL
+ rtl::OUString aTmp;
+ if ( aName.Len() )
+ FileBase::getSystemPathFromFileURL( aName, aTmp );
+ return aTmp;
+}
+
+TempFile::TempFile( const String* pParent, sal_Bool bDirectory )
+ : pImp( new TempFile_Impl )
+ , bKillingFileEnabled( sal_False )
+{
+ pImp->bIsDirectory = bDirectory;
+
+ // get correct directory
+ pImp->aName = ConstructTempDir_Impl( pParent );
+
+ // get TempFile with default naming scheme
+ CreateTempName_Impl( pImp->aName, sal_True, bDirectory );
+}
+
+TempFile::TempFile( const String& rLeadingChars, const String* pExtension, const String* pParent, sal_Bool bDirectory)
+ : pImp( new TempFile_Impl )
+ , bKillingFileEnabled( sal_False )
+{
+ lcl_createName(*pImp,rLeadingChars,sal_True, pExtension, pParent, bDirectory);
+}
+TempFile::TempFile( const String& rLeadingChars,sal_Bool _bStartWithZero, const String* pExtension, const String* pParent, sal_Bool bDirectory)
+ : pImp( new TempFile_Impl )
+ , bKillingFileEnabled( sal_False )
+{
+ lcl_createName(*pImp,rLeadingChars,_bStartWithZero, pExtension, pParent, bDirectory);
+}
+
+TempFile::~TempFile()
+{
+ delete pImp->pStream;
+ if ( bKillingFileEnabled )
+ {
+ if ( pImp->bIsDirectory )
+ {
+ // at the moment no recursiv algorithm present
+ Directory::remove( pImp->aName );
+ }
+ else
+ {
+ File::remove( pImp->aName );
+ }
+ }
+
+ delete pImp;
+}
+
+sal_Bool TempFile::IsValid() const
+{
+ return pImp->aName.Len() != 0;
+}
+
+String TempFile::GetFileName() const
+{
+ rtl::OUString aTmp;
+ FileBase::getSystemPathFromFileURL( pImp->aName, aTmp );
+ return aTmp;
+}
+
+String TempFile::GetURL() const
+{
+ if ( !pImp->aURL.Len() )
+ {
+ String aTmp;
+ LocalFileHelper::ConvertPhysicalNameToURL( GetFileName(), aTmp );
+ pImp->aURL = aTmp;
+ }
+
+ return pImp->aURL;
+}
+
+SvStream* TempFile::GetStream( StreamMode eMode )
+{
+ if ( !pImp->pStream )
+ {
+ if ( GetURL().Len() )
+ pImp->pStream = UcbStreamHelper::CreateStream( pImp->aURL, eMode, sal_True /* bFileExists */ );
+ else
+ pImp->pStream = new SvMemoryStream( eMode );
+ }
+
+ return pImp->pStream;
+}
+
+void TempFile::CloseStream()
+{
+ if ( pImp->pStream )
+ {
+ delete pImp->pStream;
+ pImp->pStream = NULL;
+ }
+}
+
+String TempFile::SetTempNameBaseDirectory( const String &rBaseName )
+{
+ if( !rBaseName.Len() )
+ return String();
+
+ rtl::OUString aUnqPath( rBaseName );
+
+ // remove trailing slash
+ if ( rBaseName.GetChar( rBaseName.Len() - 1 ) == sal_Unicode( '/' ) )
+ aUnqPath = rBaseName.Copy( 0, rBaseName.Len() - 1 );
+
+ // try to create the directory
+ sal_Bool bRet = sal_False;
+ osl::FileBase::RC err = osl::Directory::create( aUnqPath );
+ if ( err != FileBase::E_None && err != FileBase::E_EXIST )
+ // perhaps parent(s) don't exist
+ bRet = ensuredir( aUnqPath );
+ else
+ bRet = sal_True;
+
+ // failure to create base directory means returning an empty string
+ rtl::OUString aTmp;
+ if ( bRet )
+ {
+ // append own internal directory
+ bRet = sal_True;
+ ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get();
+ rTempNameBase_Impl = rBaseName;
+ rTempNameBase_Impl += String( '/' );
+
+ TempFile aBase( NULL, sal_True );
+ if ( aBase.IsValid() )
+ // use it in case of success
+ rTempNameBase_Impl = aBase.pImp->aName;
+
+ // return system path of used directory
+ FileBase::getSystemPathFromFileURL( rTempNameBase_Impl, aTmp );
+ }
+
+ return aTmp;
+}
+
+String TempFile::GetTempNameBaseDirectory()
+{
+ const ::rtl::OUString &rTempNameBase_Impl = TempNameBase_Impl::get();
+ if ( !rTempNameBase_Impl.getLength() )
+ return String();
+
+ rtl::OUString aTmp;
+ FileBase::getSystemPathFromFileURL( rTempNameBase_Impl, aTmp );
+ return aTmp;
+}
+
+}
diff --git a/unotools/source/ucbhelper/ucbhelper.cxx b/unotools/source/ucbhelper/ucbhelper.cxx
new file mode 100644
index 000000000000..8befb8a0f209
--- /dev/null
+++ b/unotools/source/ucbhelper/ucbhelper.cxx
@@ -0,0 +1,925 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+
+#include "unotools/ucbhelper.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/IllegalIdentifierException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <ucbhelper/commandenvironment.hxx>
+#include <ucbhelper/content.hxx>
+#include <comphelper/processfactory.hxx>
+#include <osl/file.hxx>
+
+#include <tools/wldcrd.hxx>
+#include <tools/ref.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/datetime.hxx>
+#include <ucbhelper/contentbroker.hxx>
+
+#include "unotools/localfilehelper.hxx"
+
+using namespace ucbhelper;
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::task;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace rtl;
+using namespace comphelper;
+using namespace osl;
+
+DECLARE_LIST( StringList_Impl, OUString* )
+
+#define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
+ aToolsDT = DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
+ Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
+
+namespace utl
+{
+
+sal_Bool UCBContentHelper::Transfer_Impl( const String& rSource, const String& rDest, sal_Bool bMoveData, sal_Int32 nNameClash )
+{
+ sal_Bool bRet = sal_True, bKillSource = sal_False;
+ INetURLObject aSourceObj( rSource );
+ DBG_ASSERT( aSourceObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+
+ INetURLObject aDestObj( rDest );
+ DBG_ASSERT( aDestObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ if ( bMoveData && aSourceObj.GetProtocol() != aDestObj.GetProtocol() )
+ {
+ bMoveData = sal_False;
+ bKillSource = sal_True;
+ }
+ String aName = aDestObj.getName();
+ aDestObj.removeSegment();
+ aDestObj.setFinalSlash();
+
+ try
+ {
+ Content aDestPath( aDestObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
+ OUString aTransferName = OUString::createFromAscii( "transfer" );
+ if ( xInfo->hasCommandByName( aTransferName ) )
+ {
+ aDestPath.executeCommand( aTransferName, makeAny(
+ ::com::sun::star::ucb::TransferInfo( bMoveData, aSourceObj.GetMainURL( INetURLObject::NO_DECODE ), aName, nNameClash ) ) );
+ }
+ else
+ {
+ DBG_ERRORFILE( "transfer command not available" );
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ bRet = sal_False;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRet = sal_False;
+ }
+
+ if ( bKillSource )
+ UCBContentHelper::Kill( rSource );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::IsDocument( const String& rContent )
+{
+ sal_Bool bRet = sal_False;
+ INetURLObject aObj( rContent );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+
+ try
+ {
+ Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ bRet = aCnt.isDocument();
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_WARNING( "CommandAbortedException" );
+ }
+ catch( ::com::sun::star::ucb::IllegalIdentifierException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ContentCreationException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ DBG_WARNING( "Any other exception" );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+Any UCBContentHelper::GetProperty( const String& rContent, const ::rtl::OUString& rName )
+{
+ INetURLObject aObj( rContent );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ return aCnt.getPropertyValue( rName );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_WARNING( "CommandAbortedException" );
+ }
+ catch( ::com::sun::star::ucb::IllegalIdentifierException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ContentCreationException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ DBG_WARNING( "Any other exception" );
+ }
+
+ return Any();
+}
+
+sal_Bool UCBContentHelper::IsFolder( const String& rContent )
+{
+ sal_Bool bRet = sal_False;
+ INetURLObject aObj( rContent );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ bRet = aCnt.isFolder();
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_WARNING( "CommandAbortedException" );
+ }
+ catch( ::com::sun::star::ucb::IllegalIdentifierException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ContentCreationException& )
+ {
+ DBG_WARNING( "IllegalIdentifierException" );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ DBG_WARNING( "Any other exception" );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::GetTitle( const String& rContent, String& rTitle )
+{
+ sal_Bool bRet = sal_False;
+ INetURLObject aObj( rContent );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ OUString aTemp;
+ if ( aCnt.getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTemp )
+ {
+ rTitle = String( aTemp );
+ bRet = sal_True;
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::Kill( const String& rContent )
+{
+ sal_Bool bRet = sal_True;
+ INetURLObject aDeleteObj( rContent );
+ DBG_ASSERT( aDeleteObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+
+ try
+ {
+ Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_WARNING( "CommandAbortedException" );
+ bRet = sal_False;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ DBG_WARNING( "Any other exception" );
+ bRet = sal_False;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+Sequence < OUString > UCBContentHelper::GetFolderContents( const String& rFolder, sal_Bool bFolder, sal_Bool bSorted )
+{
+ StringList_Impl* pFiles = NULL;
+ INetURLObject aFolderObj( rFolder );
+ DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps( bSorted ? 2 : 1 );
+ OUString* pProps = aProps.getArray();
+ pProps[0] = OUString::createFromAscii( "Title" );
+ if ( bSorted )
+ pProps[1] = OUString::createFromAscii( "IsFolder" );
+
+ try
+ {
+ ResultSetInclude eInclude = bFolder ? INCLUDE_FOLDERS_AND_DOCUMENTS : INCLUDE_DOCUMENTS_ONLY;
+ if ( !bSorted )
+ {
+ xResultSet = aCnt.createCursor( aProps, eInclude );
+ }
+ else
+ {
+ uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet;
+ xDynResultSet = aCnt.createDynamicCursor( aProps, eInclude );
+
+ uno::Reference < com::sun::star::ucb::XAnyCompareFactory > xFactory;
+ uno::Reference < XMultiServiceFactory > xMgr = getProcessServiceFactory();
+ uno::Reference < com::sun::star::ucb::XSortedDynamicResultSetFactory > xSRSFac(
+ xMgr->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SortedDynamicResultSetFactory") ), UNO_QUERY );
+
+ Sequence< com::sun::star::ucb::NumberedSortingInfo > aSortInfo( 2 );
+ com::sun::star::ucb::NumberedSortingInfo* pInfo = aSortInfo.getArray();
+ pInfo[ 0 ].ColumnIndex = 2;
+ pInfo[ 0 ].Ascending = sal_False;
+ pInfo[ 1 ].ColumnIndex = 1;
+ pInfo[ 1 ].Ascending = sal_True;
+
+ uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynamicResultSet;
+ xDynamicResultSet =
+ xSRSFac->createSortedDynamicResultSet( xDynResultSet, aSortInfo, xFactory );
+ if ( xDynamicResultSet.is() )
+ {
+ xResultSet = xDynamicResultSet->getStaticResultSet();
+ }
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ // folder not exists?
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if ( xResultSet.is() )
+ {
+ pFiles = new StringList_Impl;
+ uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aId = xContentAccess->queryContentIdentifierString();
+ OUString* pFile = new OUString( aId );
+ pFiles->Insert( pFile, LIST_APPEND );
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if ( pFiles )
+ {
+ ULONG nCount = pFiles->Count();
+ Sequence < OUString > aRet( nCount );
+ OUString* pRet = aRet.getArray();
+ for ( ULONG i = 0; i < nCount; ++i )
+ {
+ OUString* pFile = pFiles->GetObject(i);
+ pRet[i] = *( pFile );
+ delete pFile;
+ }
+ delete pFiles;
+ return aRet;
+ }
+ else
+ return Sequence < OUString > ();
+}
+
+// -----------------------------------------------------------------------
+
+Sequence < OUString > UCBContentHelper::GetResultSet( const String& rURL )
+{
+ StringList_Impl* pList = NULL;
+ try
+ {
+ Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+ uno::Reference< XResultSet > xResultSet;
+ uno::Reference< com::sun::star::ucb::XDynamicResultSet > xDynResultSet;
+ Sequence< OUString > aProps(3);
+ OUString* pProps = aProps.getArray();
+ pProps[0] = OUString::createFromAscii( "Title" );
+ pProps[1] = OUString::createFromAscii( "ContentType" );
+ // TODO: can be optimized, property never used:
+ pProps[2] = OUString::createFromAscii( "IsFolder" );
+
+ try
+ {
+ xDynResultSet = aCnt.createDynamicCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS );
+ if ( xDynResultSet.is() )
+ xResultSet = xDynResultSet->getStaticResultSet();
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if ( xResultSet.is() )
+ {
+ pList = new StringList_Impl;
+ uno::Reference< com::sun::star::sdbc::XRow > xRow( xResultSet, UNO_QUERY );
+ uno::Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ String aTitle( xRow->getString(1) );
+ String aType( xRow->getString(2) );
+ String aRow = aTitle;
+ aRow += '\t';
+ aRow += aType;
+ aRow += '\t';
+ aRow += String( xContentAccess->queryContentIdentifierString() );
+ OUString* pRow = new OUString( aRow );
+ pList->Insert( pRow, LIST_APPEND );
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if ( pList )
+ {
+ ULONG nCount = pList->Count();
+ Sequence < OUString > aRet( nCount );
+ OUString* pRet = aRet.getArray();
+ for ( ULONG i = 0; i < nCount; ++i )
+ {
+ OUString* pEntry = pList->GetObject(i);
+ pRet[i] = *( pEntry );
+ delete pEntry;
+ }
+ delete pList;
+ return aRet;
+ }
+ else
+ return Sequence < OUString > ();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::CopyTo( const String& rSource, const String& rDest )
+{
+ return Transfer_Impl( rSource, rDest, sal_False, NameClash::ERROR );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::MoveTo( const String& rSource, const String& rDest, sal_Int32 nNameClash )
+{
+ return Transfer_Impl( rSource, rDest, sal_True, nNameClash );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::CanMakeFolder( const String& rFolder )
+{
+ try
+ {
+ Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () );
+ Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
+ sal_Int32 nCount = aInfo.getLength();
+ if ( nCount == 0 )
+ return sal_False;
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ // Simply look for the first KIND_FOLDER...
+ const ContentInfo & rCurr = aInfo[i];
+ if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
+ return sal_True;
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& ) {}
+ catch( RuntimeException& ) {}
+ catch( Exception& ) {}
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::MakeFolder( const String& rFolder, sal_Bool bNewOnly )
+{
+ INetURLObject aURL( rFolder );
+ DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ aURL.removeSegment();
+ Content aCnt;
+ Content aNew;
+ uno::Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference< XInteractionHandler > xInteractionHandler = uno::Reference< XInteractionHandler > (
+ xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY );
+ if ( Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ), new CommandEnvironment( xInteractionHandler, uno::Reference< XProgressHandler >() ), aCnt ) )
+ return MakeFolder( aCnt, aTitle, aNew, bNewOnly );
+ else
+ return sal_False;
+}
+
+sal_Bool UCBContentHelper::MakeFolder( Content& aCnt, const String& aTitle, Content& rNew, sal_Bool bNewOnly )
+{
+ sal_Bool bAlreadyExists = sal_False;
+
+ try
+ {
+ Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
+ sal_Int32 nCount = aInfo.getLength();
+ if ( nCount == 0 )
+ return sal_False;
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ // Simply look for the first KIND_FOLDER...
+ const ContentInfo & rCurr = aInfo[i];
+ if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
+ {
+ // Make sure the only required bootstrap property is "Title",
+ const Sequence< Property > & rProps = rCurr.Properties;
+ if ( rProps.getLength() != 1 )
+ continue;
+
+ if ( !rProps[ 0 ].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ continue;
+
+ Sequence<OUString> aNames(1);
+ OUString* pNames = aNames.getArray();
+ pNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
+ Sequence<Any> aValues(1);
+ Any* pValues = aValues.getArray();
+ pValues[0] = makeAny( OUString( aTitle ) );
+
+ if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, rNew ) )
+ continue;
+
+ return sal_True;
+ }
+ }
+ }
+ catch ( InteractiveIOException& r )
+ {
+ if ( r.Code == IOErrorCode_ALREADY_EXISTING )
+ {
+ bAlreadyExists = sal_True;
+ }
+ }
+ catch ( NameClashException& )
+ {
+ bAlreadyExists = sal_True;
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( RuntimeException& )
+ {
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( bAlreadyExists && !bNewOnly )
+ {
+ INetURLObject aObj( aCnt.getURL() );
+ aObj.Append( aTitle );
+ rNew = Content( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < XCommandEnvironment >() );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::HasParentFolder( const String& rFolder )
+{
+ sal_Bool bRet = sal_False;
+ try
+ {
+ Content aCnt( rFolder, uno::Reference< XCommandEnvironment > () );
+ uno::Reference< XChild > xChild( aCnt.get(), UNO_QUERY );
+ if ( xChild.is() )
+ {
+ uno::Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
+ if ( xParent.is() )
+ {
+ String aParentURL = String( xParent->getIdentifier()->getContentIdentifier() );
+ bRet = ( aParentURL.Len() > 0 && aParentURL != rFolder );
+ }
+ }
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG UCBContentHelper::GetSize( const String& rContent )
+{
+ ULONG nSize = 0;
+ sal_Int64 nTemp = 0;
+ INetURLObject aObj( rContent );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= nTemp;
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ nSize = (UINT32)nTemp;
+ return nSize;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool UCBContentHelper::IsYounger( const String& rIsYoung, const String& rIsOlder )
+{
+ DateTime aYoungDate, aOlderDate;
+ INetURLObject aYoungObj( rIsYoung );
+ DBG_ASSERT( aYoungObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ INetURLObject aOlderObj( rIsOlder );
+ DBG_ASSERT( aOlderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ try
+ {
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > aCmdEnv;
+ Content aYoung( aYoungObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
+ ::com::sun::star::util::DateTime aTempYoungDate;
+ aYoung.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempYoungDate;
+ CONVERT_DATETIME( aTempYoungDate, aYoungDate );
+ Content aOlder( aOlderObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
+ ::com::sun::star::util::DateTime aTempOlderDate;
+ aOlder.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempOlderDate;
+ CONVERT_DATETIME( aTempOlderDate, aOlderDate );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return ( aYoungDate > aOlderDate );
+}
+
+// -----------------------------------------------------------------------
+sal_Bool UCBContentHelper::Find( const String& rFolder, const String& rName, String& rFile, BOOL bAllowWildCards )
+{
+ BOOL bWild = bAllowWildCards && ( rName.Search( '*' ) != STRING_NOTFOUND || rName.Search( '?' ) != STRING_NOTFOUND );
+
+ sal_Bool bRet = sal_False;
+
+ // get a list of URLs for all children of rFolder
+ Sequence< ::rtl::OUString > aFiles = GetFolderContents( rFolder, sal_False );
+
+ const ::rtl::OUString* pFiles = aFiles.getConstArray();
+ UINT32 i, nCount = aFiles.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ // get the last name of the URLs and compare it with rName
+ INetURLObject aFileObject( pFiles[i] );
+ String aFile = aFileObject.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
+ if ( (bWild && WildCard( rName ).Matches( aFile )) || aFile == rName )
+ {
+ // names match
+ rFile = aFileObject.GetMainURL( INetURLObject::NO_DECODE );
+ bRet = sal_True;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool UCBContentHelper::Exists( const String& rURL )
+{
+
+ String sObjectPhysicalName;
+ sal_Bool bIsLocalFile = ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, sObjectPhysicalName );
+ // try to create a directory entry for the URL given
+ if ( bIsLocalFile )
+ {
+ ::rtl::OUString sIn( sObjectPhysicalName ), sOut;
+ if ( osl_File_E_None == osl_getFileURLFromSystemPath( sIn.pData, &sOut.pData ) )
+ {
+ // #106526 osl_getDirectoryItem is an existence check
+ // no further osl_getFileStatus call necessary
+ DirectoryItem aItem;
+ return (FileBase::E_None == DirectoryItem::get(sOut, aItem));
+ }
+ return sal_False;
+ }
+
+ // divide URL into folder and name part
+ sal_Bool bRet = sal_False;
+ INetURLObject aObj( rURL );
+ ::rtl::OUString aFileName = aObj.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
+ aObj.removeSegment();
+ aObj.removeFinalSlash();
+
+ // get a list of URLs for all children of rFolder
+ Sequence< ::rtl::OUString > aFiles = GetFolderContents( aObj.GetMainURL( INetURLObject::NO_DECODE ), sal_True, sal_False );
+
+ const ::rtl::OUString* pFiles = aFiles.getConstArray();
+ UINT32 i, nCount = aFiles.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ // get the last name of the URLs and compare it with rName
+ INetURLObject aFileObject( pFiles[i] );
+ ::rtl::OUString aFile = aFileObject.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).toAsciiLowerCase();
+ if ( aFile == aFileName )
+ {
+ // names match
+ bRet = sal_True;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool UCBContentHelper::FindInPath( const String& rPath, const String& rName, String& rFile, char cDelim, BOOL bAllowWildCards )
+{
+ // extract the single folder names from the path variable and try to find the file in one of these folders
+ USHORT nTokenCount = rPath.GetTokenCount( cDelim );
+ for ( USHORT nToken = 0; nToken < nTokenCount; ++nToken )
+ {
+ String aPath = rPath.GetToken( nToken, cDelim );
+ if ( Find( aPath, rName, rFile, bAllowWildCards ) )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool UCBContentHelper::IsSubPath( const ::rtl::OUString& rPath, const ::rtl::OUString& rSubfolderCandidate, const uno::Reference< ::com::sun::star::ucb::XContentProvider >& xProv )
+{
+ sal_Bool bResult = sal_False;
+
+ uno::Reference< ::com::sun::star::ucb::XContentProvider > xContentProvider = xProv;
+
+ // the comparing is done in the following way:
+ // - first compare in case sensitive way
+ // - if name are different try a fallback comparing inf case insensitive way
+ // - if the last comparing succeeded get casepreserving normalized names for the files and compare them
+ // ( the second step is required because retrieving of the normalized names might be very expensive in some cases )
+
+ INetURLObject aCandidate( rSubfolderCandidate );
+ INetURLObject aCandidateLowCase( rSubfolderCandidate.toAsciiLowerCase() ); // will be used for case insensitive comparing
+ INetURLObject aParentFolder( rPath );
+ INetURLObject aParentFolderLowCase( rPath.toAsciiLowerCase() ); // will be used for case insensitive comparing
+
+ if ( aCandidate.GetProtocol() == aParentFolder.GetProtocol() )
+ {
+ if ( !xContentProvider.is() )
+ {
+ ::ucbhelper::ContentBroker* pBroker = NULL;
+ if ( aCandidate.GetProtocol() == INET_PROT_FILE )
+ {
+ pBroker = ::ucbhelper::ContentBroker::get();
+ if ( pBroker )
+ xContentProvider = pBroker->getContentProviderInterface();
+ }
+ }
+
+ INetURLObject aLastTmpObj;
+ do
+ {
+ if ( aParentFolder == aCandidate )
+ {
+ // if case sensitive comparing succeeded there is no need for additional checks
+ bResult = sal_True;
+ }
+ else if ( xContentProvider.is() && aParentFolderLowCase == aCandidateLowCase )
+ {
+ // the comparing was done using caseinsensitive way
+ // the case sensitive comparing have failed already
+ // the normalized urls must be retrieved
+ try
+ {
+ uno::Reference< ::com::sun::star::ucb::XContent > xSecCont =
+ xContentProvider->queryContent(
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >(
+ xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier(
+ aParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) );
+
+ uno::Reference< ::com::sun::star::ucb::XContent > xLocCont =
+ xContentProvider->queryContent(
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory >(
+ xContentProvider, ::com::sun::star::uno::UNO_QUERY_THROW )->createContentIdentifier(
+ aCandidate.GetMainURL( INetURLObject::NO_DECODE ) ) );
+
+ if ( !xSecCont.is() || !xLocCont.is() )
+ throw ::com::sun::star::uno::RuntimeException();
+
+ ::rtl::OUString aSecNormStr;
+ ::rtl::OUString aLocNormStr;
+
+ bResult =
+ ( ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >(
+ xSecCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute(
+ ::com::sun::star::ucb::Command(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ),
+ -1,
+ ::com::sun::star::uno::Any() ),
+ 0,
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() )
+ >>= aSecNormStr )
+ && ( uno::Reference< ::com::sun::star::ucb::XCommandProcessor >(
+ xLocCont, ::com::sun::star::uno::UNO_QUERY_THROW )->execute(
+ ::com::sun::star::ucb::Command(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCasePreservingURL" ) ),
+ -1,
+ ::com::sun::star::uno::Any() ),
+ 0,
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() )
+ >>= aLocNormStr )
+ && aLocNormStr.equals( aSecNormStr ) );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {}
+ }
+
+ // INetURLObject::removeSegment sometimes return true without exchanging URL,
+ // for example in case of "file:///"
+ aLastTmpObj = aCandidate;
+
+ } while( aCandidate.removeSegment() && aCandidateLowCase.removeSegment() && aCandidate != aLastTmpObj && !bResult );
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool UCBContentHelper::EqualURLs( const ::rtl::OUString& aFirstURL, const ::rtl::OUString& aSecondURL )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( aFirstURL.getLength() && aSecondURL.getLength() )
+ {
+ INetURLObject aFirst( aFirstURL );
+ INetURLObject aSecond( aSecondURL );
+
+ if ( aFirst.GetProtocol() != INET_PROT_NOT_VALID && aSecond.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ try
+ {
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ throw uno::RuntimeException();
+
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory > xIdFac
+ = pBroker->getContentIdentifierFactoryInterface();
+ if ( !xIdFac.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdFirst
+ = xIdFac->createContentIdentifier( aFirst.GetMainURL( INetURLObject::NO_DECODE ) );
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdSecond
+ = xIdFac->createContentIdentifier( aSecond.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ if ( xIdFirst.is() && xIdSecond.is() )
+ {
+ uno::Reference< ::com::sun::star::ucb::XContentProvider > xProvider =
+ pBroker->getContentProviderInterface();
+ if ( !xProvider.is() )
+ throw uno::RuntimeException();
+ bResult = !xProvider->compareContentIds( xIdFirst, xIdSecond );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't compare URL's, treat as different!\n" );
+ }
+ }
+ }
+
+ return bResult;
+}
+
+
+
+} // namespace utl
+
diff --git a/unotools/source/ucbhelper/ucblockbytes.cxx b/unotools/source/ucbhelper/ucblockbytes.cxx
new file mode 100644
index 000000000000..f21855d20aed
--- /dev/null
+++ b/unotools/source/ucbhelper/ucblockbytes.cxx
@@ -0,0 +1,1746 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+
+#include <unotools/ucblockbytes.hxx>
+#include <comphelper/processfactory.hxx>
+#include <salhelper/condition.hxx>
+#ifndef _OSL_THREAD_HXX_
+#include <osl/thread.hxx>
+#endif
+#include <tools/urlobj.hxx>
+#include <ucbhelper/interactionrequest.hxx>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#endif
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/ucb/DocumentHeaderField.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <tools/inetmsg.hxx>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <comphelper/storagehelper.hxx>
+
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/content.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+
+namespace utl
+{
+
+/**
+ Helper class for getting a XInputStream when opening a content
+ */
+class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
+{
+ UcbLockBytesRef m_xLockBytes;
+
+public:
+ UcbDataSink_Impl( UcbLockBytes* pLockBytes )
+ : m_xLockBytes( pLockBytes )
+ {}
+
+ SvLockBytes* getLockBytes (void)
+ { return m_xLockBytes; }
+
+ // XActiveDataControl.
+ virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
+ virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
+ virtual void SAL_CALL start (void) throw(RuntimeException) {}
+ virtual void SAL_CALL terminate (void) throw(RuntimeException)
+ { m_xLockBytes->terminate_Impl(); }
+
+ // XActiveDataSink.
+ virtual void SAL_CALL setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException)
+ { m_xLockBytes->setInputStream_Impl (rxInputStream); }
+ virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException)
+ { return m_xLockBytes->getInputStream_Impl(); }
+};
+
+/**
+ Helper class for getting a XStream when opening a content
+ */
+class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
+{
+ Reference < XStream > m_xStream;
+ UcbLockBytesRef m_xLockBytes;
+
+public:
+
+ UcbStreamer_Impl( UcbLockBytes* pLockBytes )
+ : m_xLockBytes( pLockBytes )
+ {}
+
+ // XActiveDataControl.
+ virtual void SAL_CALL addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
+ virtual void SAL_CALL removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
+ virtual void SAL_CALL start (void) throw(RuntimeException) {}
+ virtual void SAL_CALL terminate (void) throw(RuntimeException)
+ { m_xLockBytes->terminate_Impl(); }
+
+ // XActiveDataStreamer
+ virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) throw(RuntimeException)
+ { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
+ virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException)
+ { return m_xStream; }
+};
+
+/**
+ Helper class for progress handling while executing UCB commands
+ */
+class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler >
+{
+ Link m_aProgress;
+
+public:
+ ProgressHandler_Impl( const Link& rLink )
+ : m_aProgress( rLink )
+ {}
+ // XProgressHandler
+ virtual void SAL_CALL push(const Any & /*rStatus*/) throw (RuntimeException) {}
+ virtual void SAL_CALL pop() throw (RuntimeException) {}
+ virtual void SAL_CALL update(const Any & /*rStatus*/) throw (RuntimeException)
+ { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); }
+};
+
+/**
+ Helper class for managing interactions and progress when executing UCB commands
+ */
+class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
+{
+ Reference< XInteractionHandler > m_xInteractionHandler;
+ Reference< XProgressHandler > m_xProgressHandler;
+
+public:
+ UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
+ const Reference< XProgressHandler>& rxProgressHandler )
+ : m_xInteractionHandler( rxInteractionHandler )
+ , m_xProgressHandler( rxProgressHandler )
+ {}
+
+
+ virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException)
+ { return m_xInteractionHandler; }
+
+ virtual Reference<XProgressHandler> SAL_CALL getProgressHandler() throw (RuntimeException)
+ { return m_xProgressHandler; }
+};
+
+
+/**
+ Helper class for property change notifies when executing UCB commands
+*/
+class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
+{
+public:
+ UcbLockBytesRef m_xLockBytes;
+
+ UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
+ : m_xLockBytes( rRef )
+ {}
+
+ virtual void SAL_CALL disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {}
+ virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException);
+};
+
+void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException)
+{
+ sal_Int32 i, n = rEvent.getLength();
+ for (i = 0; i < n; i++)
+ {
+ PropertyChangeEvent evt (rEvent[i]);
+ if (evt.PropertyName == ::rtl::OUString::createFromAscii ("DocumentHeader"))
+ {
+ Sequence<DocumentHeaderField> aHead;
+ if (evt.NewValue >>= aHead)
+ {
+ sal_Int32 k, m = aHead.getLength();
+ for (k = 0; k < m; k++)
+ {
+ String aName( aHead[k].Name );
+ String aValue( aHead[k].Value );
+
+ if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL)
+ {
+ DateTime aExpires (0, 0);
+ if (INetRFC822Message::ParseDateField (aValue, aExpires))
+ {
+ aExpires.ConvertToLocalTime();
+ m_xLockBytes->SetExpireDate_Impl( aExpires );
+ }
+ }
+ }
+ }
+
+ m_xLockBytes->SetStreamValid_Impl();
+ }
+ else if (evt.PropertyName == rtl::OUString::createFromAscii ("PresentationURL"))
+ {
+ ::rtl::OUString aUrl;
+ if (evt.NewValue >>= aUrl)
+ {
+ ::rtl::OUString aBad (::rtl::OUString::createFromAscii ("private:"));
+ if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0))
+ {
+ // URL changed (Redirection).
+ m_xLockBytes->SetRealURL_Impl( aUrl );
+ }
+ }
+ }
+ else if (evt.PropertyName == ::rtl::OUString::createFromAscii ("MediaType"))
+ {
+ ::rtl::OUString aContentType;
+ if (evt.NewValue >>= aContentType)
+ m_xLockBytes->SetContentType_Impl( aContentType );
+ }
+ }
+}
+
+
+
+class Moderator
+ : public osl::Thread
+{
+ // usage restriction:
+ // It might be possible, that the call to the interactionhandler and/or
+ // progresshandler is done asynchrounsly, while the 'execute' simply
+ // returns. This would imply that these class must be refcounted !!!
+
+public:
+
+ Moderator(
+ Reference < XContent >& xContent,
+ Reference < XInteractionHandler >& xInteract,
+ Reference < XProgressHandler >& xProgress,
+ const Command& rArg
+ )
+ throw(
+ ContentCreationException,
+ RuntimeException
+ );
+
+ ~Moderator();
+
+
+ enum ResultType {
+ NORESULT,
+
+ INTERACTIONREQUEST, // reply expected
+
+ PROGRESSPUSH,
+ PROGRESSUPDATE,
+ PROGRESSPOP,
+
+ INPUTSTREAM,
+ STREAM,
+
+ RESULT,
+ TIMEDOUT,
+ COMMANDABORTED,
+ COMMANDFAILED,
+ INTERACTIVEIO,
+ UNSUPPORTED,
+ GENERAL
+ };
+
+
+ class ConditionRes
+ : public salhelper::Condition
+ {
+ public:
+
+ ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
+ : salhelper::Condition(aMutex),
+ m_aModerator(aModerator)
+ {
+ }
+
+ protected:
+
+ bool applies() const {
+ return m_aModerator.m_aResultType != NORESULT;
+ }
+
+ private:
+
+ Moderator& m_aModerator;
+ };
+
+
+ struct Result {
+ ResultType type;
+ Any result;
+ sal_Int32 ioErrorCode;
+ };
+
+
+ Result getResult(const sal_uInt32 milliSec);
+
+
+ enum ReplyType {
+ NOREPLY,
+ EXIT,
+ RETRY,
+ REQUESTHANDLED
+ };
+
+
+ class ConditionRep
+ : public salhelper::Condition
+ {
+ public:
+
+ ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
+ : salhelper::Condition(aMutex),
+ m_aModerator(aModerator)
+ {
+ }
+
+ protected:
+
+ bool applies() const {
+ return m_aModerator.m_aReplyType != NOREPLY;
+ }
+
+ private:
+
+ Moderator& m_aModerator;
+ };
+
+ void setReply(ReplyType);
+
+
+ void handle( const Reference<XInteractionRequest >& Request );
+
+ void push( const Any& Status );
+
+ void update( const Any& Status );
+
+ void pop( );
+
+ void setStream(const Reference< XStream >& aStream);
+
+ void setInputStream(const Reference<XInputStream> &rxInputStream);
+
+
+protected:
+
+ virtual void SAL_CALL run();
+
+ virtual void SAL_CALL onTerminated();
+
+private:
+
+ osl::Mutex m_aMutex;
+
+ friend class ConditionRes;
+
+ ConditionRes m_aRes;
+ ResultType m_aResultType;
+ sal_Int32 m_nIOErrorCode;
+ Any m_aResult;
+
+ friend class ConditionRep;
+
+ ConditionRep m_aRep;
+ ReplyType m_aReplyType;
+
+ Command m_aArg;
+ ::ucbhelper::Content m_aContent;
+};
+
+
+class ModeratorsActiveDataStreamer
+ : public ::cppu::WeakImplHelper1<XActiveDataStreamer>
+{
+public:
+
+ ModeratorsActiveDataStreamer(Moderator &theModerator);
+
+ ~ModeratorsActiveDataStreamer();
+
+ // XActiveDataStreamer
+ virtual void SAL_CALL
+ setStream(
+ const Reference< XStream >& aStream
+ )
+ throw(
+ RuntimeException
+ );
+
+ virtual Reference<XStream> SAL_CALL
+ getStream (
+ void
+ ) throw(
+ RuntimeException
+ )
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ return m_xStream;
+ }
+
+
+private:
+
+ Moderator& m_aModerator;
+
+ osl::Mutex m_aMutex;
+ Reference<XStream> m_xStream;
+};
+
+
+
+class ModeratorsActiveDataSink
+ : public ::cppu::WeakImplHelper1<XActiveDataSink>
+{
+public:
+
+ ModeratorsActiveDataSink(Moderator &theModerator);
+
+ ~ModeratorsActiveDataSink();
+
+ // XActiveDataSink.
+ virtual void SAL_CALL
+ setInputStream (
+ const Reference<XInputStream> &rxInputStream
+ )
+ throw(
+ RuntimeException
+ );
+
+ virtual Reference<XInputStream> SAL_CALL
+ getInputStream (
+ void
+ ) throw(
+ RuntimeException
+ )
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ return m_xStream;
+ }
+
+
+private:
+
+ Moderator& m_aModerator;
+ osl::Mutex m_aMutex;
+ Reference<XInputStream> m_xStream;
+};
+
+
+
+ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
+ : m_aModerator(theModerator)
+{
+}
+
+
+ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
+{
+}
+
+// XActiveDataSink.
+void SAL_CALL
+ModeratorsActiveDataSink::setInputStream (
+ const Reference<XInputStream> &rxInputStream
+)
+ throw(
+ RuntimeException
+ )
+{
+ m_aModerator.setInputStream(rxInputStream);
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xStream = rxInputStream;
+}
+
+
+ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
+ Moderator &theModerator
+)
+ : m_aModerator(theModerator)
+{
+}
+
+
+ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
+{
+}
+
+// XActiveDataStreamer.
+void SAL_CALL
+ModeratorsActiveDataStreamer::setStream (
+ const Reference<XStream> &rxStream
+)
+ throw(
+ RuntimeException
+ )
+{
+ m_aModerator.setStream(rxStream);
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xStream = rxStream;
+}
+
+
+
+class ModeratorsInteractionHandler
+ : public ::cppu::WeakImplHelper1<XInteractionHandler>
+{
+public:
+
+ ModeratorsInteractionHandler(Moderator &theModerator);
+
+ ~ModeratorsInteractionHandler();
+
+ virtual void SAL_CALL
+ handle( const Reference<XInteractionRequest >& Request )
+ throw (RuntimeException);
+
+private:
+
+ Moderator& m_aModerator;
+};
+
+
+class ModeratorsProgressHandler
+ : public ::cppu::WeakImplHelper1<XProgressHandler>
+{
+public:
+
+ ModeratorsProgressHandler(Moderator &theModerator);
+
+ ~ModeratorsProgressHandler();
+
+ virtual void SAL_CALL push( const Any& Status )
+ throw (
+ RuntimeException);
+
+ virtual void SAL_CALL update( const Any& Status )
+ throw (RuntimeException);
+
+ virtual void SAL_CALL pop( )
+ throw (RuntimeException);
+
+
+private:
+
+ Moderator& m_aModerator;
+};
+
+
+ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator)
+ : m_aModerator(theModerator)
+{
+}
+
+ModeratorsProgressHandler::~ModeratorsProgressHandler()
+{
+}
+
+
+void SAL_CALL ModeratorsProgressHandler::push( const Any& Status )
+ throw (
+ RuntimeException)
+{
+ m_aModerator.push(Status);
+}
+
+
+void SAL_CALL ModeratorsProgressHandler::update( const Any& Status )
+ throw (RuntimeException)
+{
+ m_aModerator.update(Status);
+}
+
+
+void SAL_CALL ModeratorsProgressHandler::pop( )
+ throw (RuntimeException)
+{
+ m_aModerator.pop();
+}
+
+
+
+
+ModeratorsInteractionHandler::ModeratorsInteractionHandler(
+ Moderator &aModerator)
+ : m_aModerator(aModerator)
+{
+}
+
+
+ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
+{
+}
+
+
+void SAL_CALL
+ModeratorsInteractionHandler::handle(
+ const Reference<XInteractionRequest >& Request
+)
+ throw (
+ RuntimeException
+ )
+{
+ // wakes up the mainthread
+ m_aModerator.handle(Request);
+}
+
+
+
+
+Moderator::Moderator(
+ Reference < XContent >& xContent,
+ Reference < XInteractionHandler >& xInteract,
+ Reference < XProgressHandler >& xProgress,
+ const Command& rArg
+)
+ throw(
+ ::com::sun::star::ucb::ContentCreationException,
+ ::com::sun::star::uno::RuntimeException
+ )
+ : m_aMutex(),
+
+ m_aRes(m_aMutex,*this),
+ m_aResultType(NORESULT),
+ m_nIOErrorCode(0),
+ m_aResult(),
+
+ m_aRep(m_aMutex,*this),
+ m_aReplyType(NOREPLY),
+
+ m_aArg(rArg),
+ m_aContent(
+ xContent,
+ new UcbTaskEnvironment(
+ xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
+ xProgress.is() ? new ModeratorsProgressHandler(*this) : 0
+ ))
+{
+ // now exchange the whole data sink stuff
+ // with a thread safe version
+
+ Reference<XInterface> *pxSink = NULL;
+
+ PostCommandArgument2 aPostArg;
+ OpenCommandArgument2 aOpenArg;
+
+ int dec(2);
+ if(m_aArg.Argument >>= aPostArg) {
+ pxSink = &aPostArg.Sink;
+ dec = 0;
+ }
+ else if(m_aArg.Argument >>= aOpenArg) {
+ pxSink = &aOpenArg.Sink;
+ dec = 1;
+ }
+
+ if(dec ==2)
+ throw ContentCreationException();
+
+ Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
+ if(xActiveSink.is())
+ *pxSink = Reference<XInterface>(
+ (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this));
+
+ Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
+ if ( xStreamer.is() )
+ *pxSink = Reference<XInterface>(
+ (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this));
+
+ if(dec == 0)
+ m_aArg.Argument <<= aPostArg;
+ else if(dec == 1)
+ m_aArg.Argument <<= aOpenArg;
+}
+
+
+Moderator::~Moderator()
+{
+}
+
+
+Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
+{
+ Result ret;
+ try {
+ salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
+ ret.type = m_aResultType;
+ ret.result = m_aResult;
+ ret.ioErrorCode = m_nIOErrorCode;
+
+ // reset
+ m_aResultType = NORESULT;
+ }
+ catch(const salhelper::ConditionWaiter::timedout&)
+ {
+ ret.type = TIMEDOUT;
+ }
+
+ return ret;
+}
+
+
+void Moderator::setReply(ReplyType aReplyType )
+{
+ salhelper::ConditionModifier aMod(m_aRep);
+ m_aReplyType = aReplyType;
+}
+
+
+void Moderator::handle( const Reference<XInteractionRequest >& Request )
+{
+ ReplyType aReplyType;
+
+ do {
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = INTERACTIONREQUEST;
+ m_aResult <<= Request;
+ }
+
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+
+ // reset
+ m_aReplyType = NOREPLY;
+ }
+
+ if(aReplyType == EXIT) {
+ Sequence<Reference<XInteractionContinuation> > aSeq(
+ Request->getContinuations());
+ for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
+ Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
+ if(aRef.is()) {
+ aRef->select();
+ }
+ }
+
+ // resignal the exitcondition
+ setReply(EXIT);
+ break;
+ }
+ } while(aReplyType != REQUESTHANDLED);
+}
+
+
+
+void Moderator::push( const Any& Status )
+{
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = PROGRESSPUSH;
+ m_aResult = Status;
+ }
+ ReplyType aReplyType;
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+ m_aReplyType = NOREPLY;
+ }
+ if(aReplyType == EXIT)
+ setReply(EXIT);
+}
+
+
+void Moderator::update( const Any& Status )
+{
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = PROGRESSUPDATE;
+ m_aResult = Status;
+ }
+ ReplyType aReplyType;
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+ m_aReplyType = NOREPLY;
+ }
+ if(aReplyType == EXIT)
+ setReply(EXIT);
+}
+
+
+void Moderator::pop( )
+{
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = PROGRESSPOP;
+ }
+ ReplyType aReplyType;
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+ m_aReplyType = NOREPLY;
+ }
+ if(aReplyType == EXIT)
+ setReply(EXIT);
+}
+
+
+void Moderator::setStream(const Reference< XStream >& aStream)
+{
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = STREAM;
+ m_aResult <<= aStream;
+ }
+ ReplyType aReplyType;
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+ m_aReplyType = NOREPLY;
+ }
+ if(aReplyType == EXIT)
+ setReply(EXIT);
+}
+
+
+void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
+{
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = INPUTSTREAM;
+ m_aResult <<= rxInputStream;
+ }
+ ReplyType aReplyType;
+ {
+ salhelper::ConditionWaiter aWait(m_aRep);
+ aReplyType = m_aReplyType;
+ m_aReplyType = NOREPLY;
+ }
+ if(aReplyType == EXIT)
+ setReply(EXIT);
+}
+
+
+
+void SAL_CALL Moderator::run()
+{
+ ResultType aResultType;
+ Any aResult;
+ sal_Int32 nIOErrorCode = 0;
+
+ try
+ {
+ aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
+ aResultType = RESULT;
+ }
+ catch ( CommandAbortedException )
+ {
+ aResultType = COMMANDABORTED;
+ }
+ catch ( CommandFailedException )
+ {
+ aResultType = COMMANDFAILED;
+ }
+ catch ( InteractiveIOException& r )
+ {
+ nIOErrorCode = r.Code;
+ aResultType = INTERACTIVEIO;
+ }
+ catch ( UnsupportedDataSinkException& )
+ {
+ aResultType = UNSUPPORTED;
+ }
+ catch ( Exception )
+ {
+ aResultType = GENERAL;
+ }
+
+ {
+ salhelper::ConditionModifier aMod(m_aRes);
+ m_aResultType = aResultType;
+ m_aResult = aResult;
+ m_nIOErrorCode = nIOErrorCode;
+ }
+}
+
+
+
+void SAL_CALL Moderator::onTerminated()
+{
+ {
+ salhelper::ConditionWaiter aWaiter(m_aRep);
+ }
+ delete this;
+}
+
+
+/**
+ Function for opening UCB contents synchronously,
+ but with handled timeout;
+*/
+
+static sal_Bool _UCBOpenContentSync(
+ UcbLockBytesRef xLockBytes,
+ Reference < XContent > xContent,
+ const Command& rArg,
+ Reference < XInterface > xSink,
+ Reference < XInteractionHandler > xInteract,
+ Reference < XProgressHandler > xProgress,
+ UcbLockBytesHandlerRef xHandler );
+
+
+static sal_Bool UCBOpenContentSync(
+ UcbLockBytesRef xLockBytes,
+ Reference < XContent > xContent,
+ const Command& rArg,
+ Reference < XInterface > xSink,
+ Reference < XInteractionHandler > xInteract,
+ Reference < XProgressHandler > xProgress,
+ UcbLockBytesHandlerRef xHandler )
+{
+ // http protocol must be handled in a special way:
+ // during the opening process the input stream may change
+ // only the last inputstream after notifying the document
+ // headers is valid
+
+ Reference<XContentIdentifier> xContId(
+ xContent.is() ? xContent->getIdentifier() : 0 );
+
+ rtl::OUString aScheme;
+ if(xContId.is())
+ aScheme = xContId->getContentProviderScheme();
+
+ // now determine wether we use a timeout or not;
+ if( ! aScheme.equalsIgnoreAsciiCaseAscii("http") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("https") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("ftp"))
+ return _UCBOpenContentSync(
+ xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
+
+ if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) ||
+ (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) )
+ xLockBytes->SetStreamValid_Impl();
+
+ Reference< XPropertiesChangeListener > xListener;
+ Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
+ if(xProps.is()) {
+ xListener =
+ new UcbPropertiesChangeListener_Impl(xLockBytes);
+ xProps->addPropertiesChangeListener(
+ Sequence< ::rtl::OUString >(),
+ xListener);
+ }
+
+ Any aResult;
+ bool bException(false);
+ bool bAborted(false);
+ bool bResultAchieved(false);
+
+ Moderator* pMod = 0;
+ try {
+ pMod = new Moderator(xContent,xInteract,xProgress,rArg);
+ pMod->create();
+ } catch(const ContentCreationException&) {
+ bResultAchieved = bException = true;
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ }
+
+ sal_uInt32 nTimeout(5000); // initially 5000 milliSec
+ while(!bResultAchieved) {
+
+ Moderator::Result res;
+ // try to get the result for with timeout
+ res = pMod->getResult(nTimeout);
+
+ switch(res.type) {
+ case Moderator::PROGRESSPUSH:
+ {
+ if(xProgress.is())
+ xProgress->push(res.result);
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::PROGRESSUPDATE:
+ {
+ if(xProgress.is())
+ xProgress->update(res.result);
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::PROGRESSPOP:
+ {
+ if(xProgress.is())
+ xProgress->pop();
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::STREAM:
+ {
+ Reference<XStream> result;
+ if(res.result >>= result) {
+ Reference < XActiveDataStreamer > xStreamer(
+ xSink, UNO_QUERY
+ );
+
+ if(xStreamer.is())
+ xStreamer->setStream(result);
+ }
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::INPUTSTREAM:
+ {
+ Reference<XInputStream> result;
+ res.result >>= result;
+ Reference < XActiveDataSink > xActiveSink(
+ xSink, UNO_QUERY
+ );
+
+ if(xActiveSink.is())
+ xActiveSink->setInputStream(result);
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::TIMEDOUT:
+ {
+ Reference<XInteractionRetry> xRet;
+ if(xInteract.is()) {
+ InteractiveNetworkConnectException aExcep;
+ INetURLObject aURL(
+ xContId.is() ?
+ xContId->getContentIdentifier() :
+ rtl::OUString() );
+ aExcep.Server = aURL.GetHost();
+ aExcep.Classification = InteractionClassification_ERROR;
+ aExcep.Message =
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "server not responding after five seconds"));
+ Any request;
+ request <<= aExcep;
+ ucbhelper::InteractionRequest *ir =
+ new ucbhelper::InteractionRequest(request);
+ Reference<XInteractionRequest> xIR(ir);
+ Sequence<Reference<XInteractionContinuation> > aSeq(2);
+ ucbhelper::InteractionRetry *retryP =
+ new ucbhelper::InteractionRetry(ir);
+ aSeq[0] = retryP;
+ ucbhelper::InteractionAbort *abortP =
+ new ucbhelper::InteractionAbort(ir);
+ aSeq[1] = abortP;
+
+ ir->setContinuations(aSeq);
+ xInteract->handle(xIR);
+ rtl::Reference< ucbhelper::InteractionContinuation > ref
+ = ir->getSelection();
+ if(ref.is()) {
+ Reference<XInterface> xInt(ref.get());
+ xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
+ }
+ }
+
+ if(!xRet.is()) {
+ bAborted = true;
+ xLockBytes->SetError(ERRCODE_ABORT);
+ }
+
+ break;
+ }
+ case Moderator::INTERACTIONREQUEST:
+ {
+ Reference<XInteractionRequest> Request;
+ res.result >>= Request;
+ xInteract->handle(Request);
+ pMod->setReply(Moderator::REQUESTHANDLED);
+ break;
+ }
+ case Moderator::RESULT:
+ {
+ bResultAchieved = true;
+ aResult = res.result;
+ break;
+ }
+ case Moderator::COMMANDABORTED:
+ {
+ bAborted = true;
+ xLockBytes->SetError( ERRCODE_ABORT );
+ break;
+ }
+ case Moderator::COMMANDFAILED:
+ {
+ bAborted = true;
+ xLockBytes->SetError( ERRCODE_ABORT );
+ break;
+ }
+ case Moderator::INTERACTIVEIO:
+ {
+ bException = true;
+ if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
+ res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
+ xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
+ else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
+ xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
+ else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
+ xLockBytes->SetError( ERRCODE_IO_CANTREAD );
+ else
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ break;
+ }
+ case Moderator::UNSUPPORTED:
+ {
+ bException = true;
+ xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
+ break;
+ }
+ default:
+ {
+ bException = true;
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ break;
+ }
+ }
+
+ bResultAchieved |= bException;
+ bResultAchieved |= bAborted;
+ if(nTimeout == 5000) nTimeout *= 2;
+ }
+
+ if(pMod) pMod->setReply(Moderator::EXIT);
+
+ if ( bAborted || bException )
+ {
+ if( xHandler.Is() )
+ xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
+
+ Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
+ if ( xActiveSink.is() )
+ xActiveSink->setInputStream( Reference < XInputStream >() );
+
+ Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
+ if ( xStreamer.is() )
+ xStreamer->setStream( Reference < XStream >() );
+ }
+
+ Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
+ if ( xControl.is() )
+ xControl->terminate();
+
+ if ( xProps.is() )
+ xProps->removePropertiesChangeListener(
+ Sequence< ::rtl::OUString >(),
+ xListener );
+
+ return ( bAborted || bException );
+}
+
+/**
+ Function for opening UCB contents synchronously
+ */
+static sal_Bool _UCBOpenContentSync(
+ UcbLockBytesRef xLockBytes,
+ Reference < XContent > xContent,
+ const Command& rArg,
+ Reference < XInterface > xSink,
+ Reference < XInteractionHandler > xInteract,
+ Reference < XProgressHandler > xProgress,
+ UcbLockBytesHandlerRef xHandler )
+{
+ ::ucbhelper::Content aContent( xContent, new UcbTaskEnvironment( xInteract, xProgress ) );
+ Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
+ ::rtl::OUString aScheme = xIdent->getContentProviderScheme();
+
+ // http protocol must be handled in a special way: during the opening process the input stream may change
+ // only the last inputstream after notifying the document headers is valid
+ if ( aScheme.compareToAscii("http") != COMPARE_EQUAL )
+ xLockBytes->SetStreamValid_Impl();
+
+ Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
+ Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
+ if ( xProps.is() )
+ xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
+
+ Any aResult;
+ bool bException = false;
+ bool bAborted = false;
+
+ try
+ {
+ aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
+ }
+ catch ( CommandAbortedException )
+ {
+ bAborted = true;
+ xLockBytes->SetError( ERRCODE_ABORT );
+ }
+ catch ( CommandFailedException )
+ {
+ bAborted = true;
+ xLockBytes->SetError( ERRCODE_ABORT );
+ }
+ catch ( InteractiveIOException& r )
+ {
+ bException = true;
+ if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
+ xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
+ else if ( r.Code == IOErrorCode_NOT_EXISTING )
+ xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
+ else if ( r.Code == IOErrorCode_CANT_READ )
+ xLockBytes->SetError( ERRCODE_IO_CANTREAD );
+ else
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( UnsupportedDataSinkException& )
+ {
+ bException = true;
+ xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
+ }
+ catch ( Exception )
+ {
+ bException = true;
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ }
+
+ if ( bAborted || bException )
+ {
+ if( xHandler.Is() )
+ xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );
+
+ Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
+ if ( xActiveSink.is() )
+ xActiveSink->setInputStream( Reference < XInputStream >() );
+
+ Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
+ if ( xStreamer.is() )
+ xStreamer->setStream( Reference < XStream >() );
+ }
+
+ Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
+ if ( xControl.is() )
+ xControl->terminate();
+
+
+ if ( xProps.is() )
+ xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );
+
+ return ( bAborted || bException );
+}
+
+
+//----------------------------------------------------------------------------
+UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
+ : m_xInputStream (NULL)
+ , m_pCommandThread( NULL )
+ , m_xHandler( pHandler )
+ , m_nError( ERRCODE_NONE )
+ , m_bTerminated (sal_False)
+ , m_bDontClose( sal_False )
+ , m_bStreamValid (sal_False)
+{
+ SetSynchronMode( TRUE );
+}
+
+//----------------------------------------------------------------------------
+UcbLockBytes::~UcbLockBytes()
+{
+ if ( !m_bDontClose )
+ {
+ if ( m_xInputStream.is() )
+ {
+ try
+ {
+ m_xInputStream->closeInput();
+ }
+ catch ( RuntimeException const & )
+ {}
+ catch ( IOException const & )
+ {}
+ }
+ }
+
+ if ( !m_xInputStream.is() && m_xOutputStream.is() )
+ {
+ try
+ {
+ m_xOutputStream->closeOutput();
+ }
+ catch ( RuntimeException const & )
+ {}
+ catch ( IOException const & )
+ {}
+ }
+}
+
+Reference < XInputStream > UcbLockBytes::getInputStream()
+{
+ vos::OClearableGuard aGuard( m_aMutex );
+ m_bDontClose = sal_True;
+ return m_xInputStream;
+}
+
+Reference < XStream > UcbLockBytes::getStream()
+{
+ vos::OClearableGuard aGuard( m_aMutex );
+ Reference < XStream > xStream( m_xSeekable, UNO_QUERY );
+ if ( xStream.is() )
+ m_bDontClose = sal_True;
+ return xStream;
+}
+
+//----------------------------------------------------------------------------
+
+sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
+{
+ vos::OClearableGuard aGuard( m_aMutex );
+ if ( aStream.is() )
+ {
+ m_xOutputStream = aStream->getOutputStream();
+ setInputStream_Impl( aStream->getInputStream(), sal_False );
+ m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
+ }
+ else
+ {
+ m_xOutputStream = Reference < XOutputStream >();
+ setInputStream_Impl( Reference < XInputStream >() );
+ }
+
+ return m_xInputStream.is();
+}
+
+sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable )
+{
+ sal_Bool bRet = sal_False;
+
+ try
+ {
+ vos::OClearableGuard aGuard( m_aMutex );
+
+ if ( !m_bDontClose && m_xInputStream.is() )
+ m_xInputStream->closeInput();
+
+ m_xInputStream = rxInputStream;
+
+ if( bSetXSeekable )
+ {
+ m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
+ if( !m_xSeekable.is() && rxInputStream.is() )
+ {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XOutputStream > rxTempOut = Reference < XOutputStream > (
+ xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ UNO_QUERY );
+
+ if( rxTempOut.is() )
+ {
+ ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
+ m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
+ m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
+ }
+ }
+ }
+
+ bRet = m_xInputStream.is();
+ // aGuard.clear();
+ }
+ catch( Exception& )
+ {}
+
+ if ( m_bStreamValid && m_xInputStream.is() )
+ m_aInitialized.set();
+
+ return bRet;
+}
+
+void UcbLockBytes::SetStreamValid_Impl()
+{
+ m_bStreamValid = sal_True;
+ if ( m_xInputStream.is() )
+ m_aInitialized.set();
+}
+
+//----------------------------------------------------------------------------
+void UcbLockBytes::terminate_Impl()
+{
+ m_bTerminated = sal_True;
+ m_aInitialized.set();
+ m_aTerminated.set();
+
+ if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
+ {
+ DBG_ERROR("No InputStream, but no error set!" );
+ SetError( ERRCODE_IO_NOTEXISTS );
+ }
+
+ if ( m_xHandler.Is() )
+ m_xHandler->Handle( UcbLockBytesHandler::DONE, this );
+}
+
+//----------------------------------------------------------------------------
+void UcbLockBytes::SetSynchronMode (BOOL bSynchron)
+{
+ SvLockBytes::SetSynchronMode (bSynchron);
+}
+
+//----------------------------------------------------------------------------
+ErrCode UcbLockBytes::ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const
+{
+ if ( IsSynchronMode() )
+ {
+ UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
+ pThis->m_aInitialized.wait();
+ }
+
+ Reference <XInputStream> xStream = getInputStream_Impl();
+ if ( !xStream.is() )
+ {
+ if ( m_bTerminated )
+ return ERRCODE_IO_CANTREAD;
+ else
+ return ERRCODE_IO_PENDING;
+ }
+
+ if ( pRead )
+ *pRead = 0;
+
+ Reference <XSeekable> xSeekable = getSeekable_Impl();
+ if ( !xSeekable.is() )
+ return ERRCODE_IO_CANTREAD;
+
+ try
+ {
+ xSeekable->seek( nPos );
+ }
+ catch ( IOException )
+ {
+ return ERRCODE_IO_CANTSEEK;
+ }
+ catch (com::sun::star::lang::IllegalArgumentException)
+ {
+ return ERRCODE_IO_CANTSEEK;
+ }
+
+ Sequence<sal_Int8> aData;
+ sal_Int32 nSize;
+
+ nCount = VOS_MIN(nCount, 0x7FFFFFFF);
+ try
+ {
+ if ( !m_bTerminated && !IsSynchronMode() )
+ {
+ sal_uInt64 nLen = xSeekable->getLength();
+ if ( nPos + nCount > nLen )
+ return ERRCODE_IO_PENDING;
+ }
+
+ nSize = xStream->readBytes( aData, sal_Int32(nCount) );
+ }
+ catch (IOException)
+ {
+ return ERRCODE_IO_CANTREAD;
+ }
+
+ rtl_copyMemory (pBuffer, aData.getConstArray(), nSize);
+ if (pRead)
+ *pRead = ULONG(nSize);
+
+ return ERRCODE_NONE;
+}
+
+//----------------------------------------------------------------------------
+ErrCode UcbLockBytes::WriteAt ( ULONG nPos, const void *pBuffer, ULONG nCount, ULONG *pWritten)
+{
+ if ( pWritten )
+ *pWritten = 0;
+
+ DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
+ DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );
+
+ Reference <XSeekable> xSeekable = getSeekable_Impl();
+ Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
+ if ( !xOutputStream.is() || !xSeekable.is() )
+ return ERRCODE_IO_CANTWRITE;
+
+ try
+ {
+ xSeekable->seek( nPos );
+ }
+ catch ( IOException )
+ {
+ return ERRCODE_IO_CANTSEEK;
+ }
+
+ sal_Int8* pData = (sal_Int8*) pBuffer;
+ Sequence<sal_Int8> aData( pData, nCount );
+ try
+ {
+ xOutputStream->writeBytes( aData );
+ if ( pWritten )
+ *pWritten = nCount;
+ }
+ catch ( Exception )
+ {
+ return ERRCODE_IO_CANTWRITE;
+ }
+
+ return ERRCODE_NONE;
+}
+
+//----------------------------------------------------------------------------
+ErrCode UcbLockBytes::Flush() const
+{
+ Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
+ if ( !xOutputStream.is() )
+ return ERRCODE_IO_CANTWRITE;
+ xOutputStream->flush();
+ return ERRCODE_NONE;
+}
+
+//----------------------------------------------------------------------------
+ErrCode UcbLockBytes::SetSize (ULONG nNewSize)
+{
+ SvLockBytesStat aStat;
+ Stat( &aStat, (SvLockBytesStatFlag) 0 );
+ ULONG nSize = aStat.nSize;
+
+ if ( nSize > nNewSize )
+ {
+ Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
+ if ( xTrunc.is() )
+ {
+ xTrunc->truncate();
+ nSize = 0;
+ }
+ else {
+ DBG_WARNING("Not truncatable!");
+ }
+ }
+
+ if ( nSize < nNewSize )
+ {
+ ULONG nDiff = nNewSize-nSize, nCount=0;
+ BYTE* pBuffer = new BYTE[ nDiff ];
+ memset(pBuffer, 0, nDiff); // initialize for enhanced security
+ WriteAt( nSize, pBuffer, nDiff, &nCount );
+ delete[] pBuffer;
+ if ( nCount != nDiff )
+ return ERRCODE_IO_CANTWRITE;
+ }
+
+ return ERRCODE_NONE;
+}
+
+//----------------------------------------------------------------------------
+ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
+{
+ if ( IsSynchronMode() )
+ {
+ UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
+ pThis->m_aInitialized.wait();
+ }
+
+ if (!pStat)
+ return ERRCODE_IO_INVALIDPARAMETER;
+
+ Reference <XInputStream> xStream = getInputStream_Impl();
+ Reference <XSeekable> xSeekable = getSeekable_Impl();
+
+ if ( !xStream.is() )
+ {
+ if ( m_bTerminated )
+ return ERRCODE_IO_INVALIDACCESS;
+ else
+ return ERRCODE_IO_PENDING;
+ }
+ else if( !xSeekable.is() )
+ return ERRCODE_IO_CANTTELL;
+
+ try
+ {
+ pStat->nSize = ULONG(xSeekable->getLength());
+ }
+ catch (IOException)
+ {
+ return ERRCODE_IO_CANTTELL;
+ }
+
+ return ERRCODE_NONE;
+}
+
+//----------------------------------------------------------------------------
+void UcbLockBytes::Cancel()
+{
+ // is alive only for compatibility reasons
+ OSL_ENSURE( m_bTerminated, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" );
+}
+
+//----------------------------------------------------------------------------
+IMPL_LINK( UcbLockBytes, DataAvailHdl, void*, EMPTYARG )
+{
+ if ( hasInputStream_Impl() && m_xHandler.Is() )
+ m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this );
+
+ return 0;
+}
+
+UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
+{
+ if( !xInputStream.is() )
+ return NULL;;
+
+ UcbLockBytesRef xLockBytes = new UcbLockBytes();
+ xLockBytes->setDontClose_Impl();
+ xLockBytes->setInputStream_Impl( xInputStream );
+ xLockBytes->terminate_Impl();
+ return xLockBytes;
+}
+
+UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
+{
+ if( !xStream.is() )
+ return NULL;;
+
+ UcbLockBytesRef xLockBytes = new UcbLockBytes();
+ xLockBytes->setDontClose_Impl();
+ xLockBytes->setStream_Impl( xStream );
+ xLockBytes->terminate_Impl();
+ return xLockBytes;
+}
+
+UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const ::rtl::OUString& rReferer, const ::rtl::OUString& rMediaType,
+ const Reference < XInputStream >& xPostData, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
+{
+ if( !xContent.is() )
+ return NULL;;
+
+ UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
+ xLockBytes->SetSynchronMode( !pHandler );
+ Reference< XActiveDataControl > xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
+
+ PostCommandArgument2 aArgument;
+ aArgument.Source = xPostData;
+ aArgument.Sink = xSink;
+ aArgument.MediaType = rMediaType;
+ aArgument.Referer = rReferer;
+
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString::createFromAscii ("post");
+ aCommand.Argument <<= aArgument;
+
+ Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
+
+ sal_Bool bError = UCBOpenContentSync( xLockBytes,
+ xContent,
+ aCommand,
+ xSink,
+ xInteractionHandler,
+ xProgressHdl,
+ pHandler );
+
+ if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
+ {
+ DBG_ERROR("No InputStream, but no error set!" );
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ }
+
+ return xLockBytes;
+}
+
+UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
+ StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
+{
+ if( !xContent.is() )
+ return NULL;;
+
+ UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
+ xLockBytes->SetSynchronMode( !pHandler );
+ Reference< XActiveDataControl > xSink;
+ if ( eOpenMode & STREAM_WRITE )
+ xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes );
+ else
+ xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );
+
+ if ( rProps.getLength() )
+ {
+ Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString::createFromAscii("setPropertyValues");
+ aCommand.Handle = -1; /* unknown */
+ aCommand.Argument <<= rProps;
+ xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
+ }
+
+ OpenCommandArgument2 aArgument;
+ aArgument.Sink = xSink;
+ aArgument.Mode = OpenMode::DOCUMENT;
+
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") );
+ aCommand.Argument <<= aArgument;
+
+ Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );
+
+ sal_Bool bError = UCBOpenContentSync( xLockBytes,
+ xContent,
+ aCommand,
+ xSink,
+ xInteractionHandler,
+ xProgressHdl,
+ pHandler );
+
+ if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
+ {
+ DBG_ERROR("No InputStream, but no error set!" );
+ xLockBytes->SetError( ERRCODE_IO_GENERAL );
+ }
+
+ return xLockBytes;
+}
+
+}
diff --git a/unotools/source/ucbhelper/ucbstreamhelper.cxx b/unotools/source/ucbhelper/ucbstreamhelper.cxx
new file mode 100644
index 000000000000..f27f663b3698
--- /dev/null
+++ b/unotools/source/ucbhelper/ucbstreamhelper.cxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+
+#include <unotools/ucblockbytes.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+
+#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HDL_
+#include <com/sun/star/ucb/XCommandEnvironment.hdl>
+#endif
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/content.hxx>
+#include <tools/debug.hxx>
+#include <unotools/streamwrap.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+namespace utl
+{
+
+static SvStream* lcl_CreateStream( const String& rFileName, StreamMode eOpenMode,
+ Reference < XInteractionHandler > xInteractionHandler,
+ UcbLockBytesHandler* pHandler, sal_Bool /*bForceSynchron*/, sal_Bool bEnsureFileExists )
+{
+ SvStream* pStream = NULL;
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( pBroker )
+ {
+ UcbLockBytesRef xLockBytes;
+ if ( eOpenMode & STREAM_WRITE )
+ {
+ sal_Bool bTruncate = ( eOpenMode & STREAM_TRUNC ) != 0;
+ if ( bTruncate )
+ {
+ try
+ {
+ // truncate is implemented with deleting the original file
+ ::ucbhelper::Content aCnt( rFileName, Reference < XCommandEnvironment >() );
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
+ }
+
+ catch ( CommandAbortedException& )
+ {
+ // couldn't truncate/delete
+ }
+ catch ( ContentCreationException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( bEnsureFileExists || bTruncate )
+ {
+ try
+ {
+ // make sure that the desired file exists before trying to open
+ SvMemoryStream aStream(0,0);
+ ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
+ Reference< XInputStream > xInput( pInput );
+
+ ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() );
+ InsertCommandArgument aInsertArg;
+ aInsertArg.Data = xInput;
+
+ aInsertArg.ReplaceExisting = sal_False;
+ Any aCmdArg;
+ aCmdArg <<= aInsertArg;
+ aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg );
+ }
+
+ // it is NOT an error when the stream already exists and no truncation was desired
+ catch ( CommandAbortedException& )
+ {
+ // currently never an error is detected !
+ }
+ catch ( ContentCreationException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+
+ try
+ {
+ // create LockBytes using UCB
+ ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() );
+ xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(),
+ eOpenMode, xInteractionHandler, pHandler );
+ if ( xLockBytes.Is() )
+ {
+ pStream = new SvStream( xLockBytes );
+ pStream->SetBufferSize( 4096 );
+ pStream->SetError( xLockBytes->GetError() );
+ }
+ }
+ catch ( CommandAbortedException& )
+ {
+ }
+ catch ( ContentCreationException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ // if no UCB is present at least conventional file io is supported
+ pStream = new SvFileStream( rFileName, eOpenMode );
+
+ return pStream;
+}
+
+//============================================================================
+
+SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
+ UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
+{
+ return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ );
+}
+
+SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
+ Reference < XInteractionHandler > xInteractionHandler,
+ UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
+{
+ return lcl_CreateStream( rFileName, eOpenMode, xInteractionHandler, pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ );
+}
+
+SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode,
+ sal_Bool bFileExists,
+ UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron )
+{
+ return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, !bFileExists );
+}
+
+SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream )
+{
+ SvStream* pStream = NULL;
+ UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
+ if ( xLockBytes.Is() )
+ {
+ pStream = new SvStream( xLockBytes );
+ pStream->SetBufferSize( 4096 );
+ pStream->SetError( xLockBytes->GetError() );
+ }
+
+ return pStream;
+}
+
+SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream )
+{
+ SvStream* pStream = NULL;
+ if ( xStream->getOutputStream().is() )
+ {
+ UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream );
+ if ( xLockBytes.Is() )
+ {
+ pStream = new SvStream( xLockBytes );
+ pStream->SetBufferSize( 4096 );
+ pStream->SetError( xLockBytes->GetError() );
+ }
+ }
+ else
+ return CreateStream( xStream->getInputStream() );
+
+ return pStream;
+}
+
+SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream, sal_Bool bCloseStream )
+{
+ SvStream* pStream = NULL;
+ UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream );
+ if ( xLockBytes.Is() )
+ {
+ if ( !bCloseStream )
+ xLockBytes->setDontClose_Impl();
+
+ pStream = new SvStream( xLockBytes );
+ pStream->SetBufferSize( 4096 );
+ pStream->SetError( xLockBytes->GetError() );
+ }
+
+ return pStream;
+};
+
+SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream, sal_Bool bCloseStream )
+{
+ SvStream* pStream = NULL;
+ if ( xStream->getOutputStream().is() )
+ {
+ UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream );
+ if ( xLockBytes.Is() )
+ {
+ if ( !bCloseStream )
+ xLockBytes->setDontClose_Impl();
+
+ pStream = new SvStream( xLockBytes );
+ pStream->SetBufferSize( 4096 );
+ pStream->SetError( xLockBytes->GetError() );
+ }
+ }
+ else
+ return CreateStream( xStream->getInputStream(), bCloseStream );
+
+ return pStream;
+};
+
+}
diff --git a/unotools/source/ucbhelper/xtempfile.cxx b/unotools/source/ucbhelper/xtempfile.cxx
new file mode 100644
index 000000000000..023211dc3527
--- /dev/null
+++ b/unotools/source/ucbhelper/xtempfile.cxx
@@ -0,0 +1,576 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "precompiled_unotools.hxx"
+#include <XTempFile.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#include <unotools/tempfile.hxx>
+#include <osl/file.hxx>
+#include <unotools/configmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+
+namespace css = com::sun::star;
+
+// copy define from desktop\source\app\appinit.cxx
+
+#define DESKTOP_TEMPNAMEBASE_DIR "/temp/soffice.tmp"
+
+OTempFileService::OTempFileService(::css::uno::Reference< ::css::uno::XComponentContext > const & context)
+: ::cppu::PropertySetMixin< ::css::io::XTempFile >(
+ context
+ , static_cast< Implements >( IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET | IMPLEMENTS_PROPERTY_ACCESS )
+ , com::sun::star::uno::Sequence< rtl::OUString >() )
+, mpStream( NULL )
+, mbRemoveFile( sal_True )
+, mbInClosed( sal_False )
+, mbOutClosed( sal_False )
+, mnCachedPos( 0 )
+, mbHasCachedPos( sal_False )
+
+{
+ mpTempFile = new ::utl::TempFile;
+ mpTempFile->EnableKillingFile ( sal_True );
+}
+
+OTempFileService::~OTempFileService ()
+{
+ if ( mpTempFile )
+ delete mpTempFile;
+}
+
+
+// XInterface
+
+::css::uno::Any SAL_CALL OTempFileService::queryInterface( ::css::uno::Type const & aType )
+throw ( ::css::uno::RuntimeException )
+{
+ ::css::uno::Any aResult( OTempFileBase::queryInterface( aType ) );
+ if (!aResult.hasValue())
+ aResult = cppu::PropertySetMixin< ::css::io::XTempFile >::queryInterface( aType ) ;
+ return aResult;
+};
+void SAL_CALL OTempFileService::acquire( )
+throw ()
+{
+ OTempFileBase::acquire();
+}
+void SAL_CALL OTempFileService::release( )
+throw ()
+{
+ OTempFileBase::release();
+}
+
+// XTypeProvider
+
+::css::uno::Sequence< ::css::uno::Type > SAL_CALL OTempFileService::getTypes( )
+throw ( ::css::uno::RuntimeException )
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL;
+ if ( pTypeCollection == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
+
+ if ( pTypeCollection == NULL )
+ {
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType( ( const ::css::uno::Reference< ::css::beans::XPropertySet >*)NULL )
+ ,OTempFileBase::getTypes() );
+ pTypeCollection = &aTypeCollection;
+ }
+ }
+ return pTypeCollection->getTypes();
+};
+::css::uno::Sequence< sal_Int8 > SAL_CALL OTempFileService::getImplementationId( )
+throw ( ::css::uno::RuntimeException )
+{
+ return OTempFileBase::getImplementationId();
+}
+
+// XTempFile
+
+sal_Bool SAL_CALL OTempFileService::getRemoveFile()
+throw ( ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( !mpTempFile )
+ {
+ // the stream is already disconnected
+ throw ::css::uno::RuntimeException();
+ }
+
+ return mbRemoveFile;
+};
+void SAL_CALL OTempFileService::setRemoveFile( sal_Bool _removefile )
+throw ( ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( !mpTempFile )
+ {
+ // the stream is already disconnected
+ throw ::css::uno::RuntimeException();
+ }
+
+ mbRemoveFile = _removefile;
+ mpTempFile->EnableKillingFile( mbRemoveFile );
+};
+::rtl::OUString SAL_CALL OTempFileService::getUri()
+throw ( ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( !mpTempFile )
+ {
+ throw ::css::uno::RuntimeException();
+ }
+
+ return ::rtl::OUString( mpTempFile->GetURL() );
+
+};
+::rtl::OUString SAL_CALL OTempFileService::getResourceName()
+throw ( ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( !mpTempFile )
+ {
+ throw ::css::uno::RuntimeException();
+}
+
+ return ::rtl::OUString( mpTempFile->GetFileName() );
+};
+
+
+
+// XInputStream
+
+sal_Int32 SAL_CALL OTempFileService::readBytes( ::css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+throw (::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbInClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+ if (nBytesToRead < 0)
+ throw ::css::io::BufferSizeExceededException( ::rtl::OUString(), static_cast< ::css::uno::XWeak * >(this));
+
+ aData.realloc(nBytesToRead);
+
+ sal_uInt32 nRead = mpStream->Read(static_cast < void* > ( aData.getArray() ), nBytesToRead);
+ checkError();
+
+ if (nRead < static_cast < sal_uInt32 > ( nBytesToRead ) )
+ aData.realloc( nRead );
+
+ if ( sal::static_int_cast<sal_uInt32>(nBytesToRead) > nRead )
+ {
+ // usually that means that the stream was read till the end
+ // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? )
+ mnCachedPos = mpStream->Tell();
+ mbHasCachedPos = sal_True;
+
+ mpStream = NULL;
+ if ( mpTempFile )
+ mpTempFile->CloseStream();
+ }
+
+ return nRead;
+}
+sal_Int32 SAL_CALL OTempFileService::readSomeBytes( ::css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbInClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+ checkError();
+
+ if (nMaxBytesToRead < 0)
+ throw ::css::io::BufferSizeExceededException( ::rtl::OUString(), static_cast < ::css::uno::XWeak * >( this ) );
+
+ if (mpStream->IsEof())
+ {
+ aData.realloc(0);
+ return 0;
+ }
+ else
+ return readBytes(aData, nMaxBytesToRead);
+}
+void SAL_CALL OTempFileService::skipBytes( sal_Int32 nBytesToSkip )
+throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbInClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+ checkError();
+ mpStream->SeekRel(nBytesToSkip);
+ checkError();
+}
+sal_Int32 SAL_CALL OTempFileService::available( )
+throw ( ::css::io::NotConnectedException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbInClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+
+ sal_uInt32 nPos = mpStream->Tell();
+ checkError();
+
+ mpStream->Seek(STREAM_SEEK_TO_END);
+ checkError();
+
+ sal_Int32 nAvailable = (sal_Int32)mpStream->Tell() - nPos;
+ mpStream->Seek(nPos);
+ checkError();
+
+ return nAvailable;
+}
+void SAL_CALL OTempFileService::closeInput( )
+throw ( ::css::io::NotConnectedException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbInClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ mbInClosed = sal_True;
+
+ if ( mbOutClosed )
+ {
+ // stream will be deleted by TempFile implementation
+ mpStream = NULL;
+
+ if ( mpTempFile )
+ {
+ delete mpTempFile;
+ mpTempFile = NULL;
+ }
+ }
+}
+
+// XOutputStream
+
+void SAL_CALL OTempFileService::writeBytes( const ::css::uno::Sequence< sal_Int8 >& aData )
+throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbOutClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+ sal_uInt32 nWritten = mpStream->Write(aData.getConstArray(),aData.getLength());
+ checkError();
+ if ( nWritten != (sal_uInt32)aData.getLength())
+ throw ::css::io::BufferSizeExceededException( ::rtl::OUString(),static_cast < ::css::uno::XWeak * > ( this ) );
+}
+void SAL_CALL OTempFileService::flush( )
+throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbOutClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ checkConnected();
+ mpStream->Flush();
+ checkError();
+}
+void SAL_CALL OTempFileService::closeOutput( )
+throw ( ::css::io::NotConnectedException, ::css::io::BufferSizeExceededException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mbOutClosed )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+
+ mbOutClosed = sal_True;
+
+ // TODO/LATER: it is better to get rid of this optimization by avoiding using of multiple temporary files ( there should be only one temporary file? )
+ if ( mpStream )
+ {
+ mnCachedPos = mpStream->Tell();
+ mbHasCachedPos = sal_True;
+
+ mpStream = NULL;
+ if ( mpTempFile )
+ mpTempFile->CloseStream();
+ }
+
+ if ( mbInClosed )
+ {
+ // stream will be deleted by TempFile implementation
+ mpStream = NULL;
+
+ if ( mpTempFile )
+ {
+ delete mpTempFile;
+ mpTempFile = NULL;
+ }
+ }
+}
+
+
+void OTempFileService::checkError () const
+{
+ if (!mpStream || mpStream->SvStream::GetError () != ERRCODE_NONE )
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+}
+void OTempFileService::checkConnected ()
+{
+ if (!mpStream && mpTempFile)
+ {
+ mpStream = mpTempFile->GetStream( STREAM_STD_READWRITE );
+ if ( mpStream && mbHasCachedPos )
+ {
+ mpStream->Seek( sal::static_int_cast<sal_Size>(mnCachedPos) );
+ if ( mpStream->SvStream::GetError () == ERRCODE_NONE )
+ {
+ mbHasCachedPos = sal_False;
+ mnCachedPos = 0;
+ }
+ else
+ {
+ mpStream = NULL;
+ mpTempFile->CloseStream();
+ }
+ }
+ }
+
+ if (!mpStream)
+ throw ::css::io::NotConnectedException ( ::rtl::OUString(), const_cast < ::css::uno::XWeak * > ( static_cast < const ::css::uno::XWeak * > (this ) ) );
+}
+
+// XSeekable
+
+void SAL_CALL OTempFileService::seek( sal_Int64 nLocation )
+throw ( ::css::lang::IllegalArgumentException, ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ checkConnected();
+ if ( nLocation < 0 || nLocation > getLength() )
+ throw ::css::lang::IllegalArgumentException();
+
+ mpStream->Seek((sal_uInt32) nLocation );
+ checkError();
+}
+sal_Int64 SAL_CALL OTempFileService::getPosition( )
+throw ( ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ checkConnected();
+
+ sal_uInt32 nPos = mpStream->Tell();
+ checkError();
+ return (sal_Int64)nPos;
+}
+sal_Int64 SAL_CALL OTempFileService::getLength( )
+throw ( ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ checkConnected();
+
+ sal_uInt32 nCurrentPos = mpStream->Tell();
+ checkError();
+
+ mpStream->Seek(STREAM_SEEK_TO_END);
+ sal_uInt32 nEndPos = mpStream->Tell();
+ mpStream->Seek(nCurrentPos);
+
+ checkError();
+
+ return (sal_Int64)nEndPos;
+}
+
+
+// XStream
+
+::css::uno::Reference< ::css::io::XInputStream > SAL_CALL OTempFileService::getInputStream()
+throw ( ::css::uno::RuntimeException )
+ {
+ return ::css::uno::Reference< ::css::io::XInputStream >( *this, ::css::uno::UNO_QUERY );
+}
+
+::css::uno::Reference< ::css::io::XOutputStream > SAL_CALL OTempFileService::getOutputStream()
+throw ( ::css::uno::RuntimeException )
+ {
+ return ::css::uno::Reference< ::css::io::XOutputStream >( *this, ::css::uno::UNO_QUERY );
+ }
+
+// XTruncate
+
+void SAL_CALL OTempFileService::truncate()
+throw ( ::css::io::IOException, ::css::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ checkConnected();
+ // SetStreamSize() call does not change the position
+ mpStream->Seek( 0 );
+ mpStream->SetStreamSize( 0 );
+ checkError();
+}
+
+// XServiceInfo
+
+::rtl::OUString SAL_CALL OTempFileService::getImplementationName()
+throw ( ::css::uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+sal_Bool SAL_CALL OTempFileService::supportsService( ::rtl::OUString const & rServiceName )
+throw ( ::css::uno::RuntimeException )
+{
+ ::css::uno::Sequence< ::rtl::OUString > aServices(getSupportedServiceNames_Static());
+ return rServiceName == aServices[0];
+}
+
+::css::uno::Sequence < ::rtl::OUString > SAL_CALL OTempFileService::getSupportedServiceNames()
+throw ( ::css::uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+
+
+::rtl::OUString OTempFileService::getImplementationName_Static ()
+{
+ return ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.comp.TempFile" ) );
+}
+::css::uno::Sequence < ::rtl::OUString > OTempFileService::getSupportedServiceNames_Static()
+{
+ ::css::uno::Sequence < ::rtl::OUString > aNames ( 1 );
+ aNames[0] = ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
+ return aNames;
+}
+::css::uno::Reference < ::css::uno::XInterface >SAL_CALL XTempFile_createInstance(
+ css::uno::Reference< ::css::uno::XComponentContext > const & context)
+ SAL_THROW( ( css::uno::Exception ) )
+{
+ return static_cast< ::cppu::OWeakObject * >( new OTempFileService(context) );
+}
+
+::css::uno::Reference < ::css::lang::XSingleComponentFactory > OTempFileService::createServiceFactory_Static( ::css::uno::Reference < ::css::lang::XMultiServiceFactory > const & )
+{
+ return ::cppu::createSingleComponentFactory( XTempFile_createInstance, getImplementationName_Static(), getSupportedServiceNames_Static() );
+}
+
+static sal_Bool writeInfo( void * pRegistryKey,
+ const ::rtl::OUString & rImplementationName,
+ ::css::uno::Sequence< ::rtl::OUString > const & rServiceNames )
+{
+ ::rtl::OUString aKeyName( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/UNO/SERVICES" ) );
+
+ ::css::uno::Reference< ::css::registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< ::css::registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( ::css::registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( ::css::registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+// C functions to implement this as a component
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+/**
+ * This function creates an implementation section in the registry and another subkey
+ * for each supported service.
+ * @param pServiceManager generic uno interface providing a service manager
+ * @param pRegistryKey generic uno interface providing registry key to write
+ */
+extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey )
+{
+ return pRegistryKey &&
+ writeInfo (pRegistryKey,
+ OTempFileService::getImplementationName_Static(),
+ OTempFileService::getSupportedServiceNames_Static() );
+}
+
+
+/**
+ * This function is called to get service factories for an implementation.
+ * @param pImplName name of implementation
+ * @param pServiceManager generic uno interface providing a service manager to instantiate components
+ * @param pRegistryKey registry data key to read and write component persistent data
+ * @return a component factory (generic uno interface)
+ */
+extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+ ::css::uno::Reference< ::css::lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< ::css::lang::XMultiServiceFactory * >( pServiceManager ) );
+ ::css::uno::Reference< ::css::lang::XSingleComponentFactory > xFactory;
+
+ if (OTempFileService::getImplementationName_Static().compareToAscii( pImplName ) == 0)
+ xFactory = OTempFileService::createServiceFactory_Static ( xSMgr );
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}