update dev300-m58
[ooovba.git] / fileaccess / source / FileAccess.cxx
blobfbbcc31e04086e0246f3504ea0c065f1d602cb5c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FileAccess.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <osl/mutex.hxx>
32 #include <osl/diagnose.h>
34 #include <uno/mapping.hxx>
36 #include <cppuhelper/factory.hxx>
37 #include <cppuhelper/implbase1.hxx>
39 #include <tools/ref.hxx>
40 #include <tools/urlobj.hxx>
41 #include <ucbhelper/content.hxx>
42 #include <unotools/streamwrap.hxx>
43 #include <tools/stream.hxx>
45 #include <com/sun/star/beans/Property.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/container/XChild.hpp>
48 #include <com/sun/star/io/XActiveDataSink.hpp>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <com/sun/star/io/XActiveDataStreamer.hpp>
51 #include <com/sun/star/sdbc/XResultSet.hpp>
52 #include <com/sun/star/ucb/CommandFailedException.hpp>
53 #include <com/sun/star/ucb/ContentInfo.hpp>
54 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
55 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
56 #include <com/sun/star/ucb/InteractiveIOException.hpp>
57 #include <com/sun/star/ucb/NameClash.hpp>
58 #include <com/sun/star/ucb/NameClashException.hpp>
59 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
60 #include <com/sun/star/ucb/OpenMode.hpp>
61 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
62 #include <com/sun/star/ucb/XContent.hpp>
63 #include <com/sun/star/ucb/XContentAccess.hpp>
64 #include <com/sun/star/ucb/XContentCreator.hpp>
65 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
66 #include <com/sun/star/util/XMacroExpander.hpp>
68 #define IMPLEMENTATION_NAME "com.sun.star.comp.ucb.SimpleFileAccess"
69 #define SERVICE_NAME "com.sun.star.ucb.SimpleFileAccess"
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::io;
74 using namespace ::com::sun::star::ucb;
75 using namespace ::com::sun::star::sdbc;
76 using namespace ::com::sun::star::task;
77 using namespace ::com::sun::star::util;
78 using namespace ::com::sun::star::beans;
79 using namespace ::com::sun::star::registry;
80 using namespace ::com::sun::star::container;
82 namespace io_FileAccess
86 //===========================================================================
87 // Implementation XSimpleFileAccess
89 typedef cppu::WeakImplHelper1< XSimpleFileAccess3 > FileAccessHelper;
90 class OCommandEnvironment;
92 class OFileAccess : public FileAccessHelper
94 Reference< XMultiServiceFactory > mxSMgr;
95 Reference< XCommandEnvironment > mxEnvironment;
96 OCommandEnvironment* mpEnvironment;
98 void transferImpl( const rtl::OUString& rSource, const rtl::OUString& rDest, sal_Bool bMoveData )
99 throw(CommandAbortedException, Exception, RuntimeException);
100 bool createNewFile( const rtl::OUString & rParentURL,
101 const rtl::OUString & rTitle,
102 const Reference< XInputStream >& data )
103 throw ( Exception );
105 public:
106 OFileAccess( const Reference< XMultiServiceFactory > & xSMgr )
107 : mxSMgr( xSMgr), mpEnvironment( NULL ) {}
109 // Methods
110 virtual void SAL_CALL copy( const ::rtl::OUString& SourceURL, const ::rtl::OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
111 virtual void SAL_CALL move( const ::rtl::OUString& SourceURL, const ::rtl::OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
112 virtual void SAL_CALL kill( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
113 virtual sal_Bool SAL_CALL isFolder( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
114 virtual sal_Bool SAL_CALL isReadOnly( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
115 virtual void SAL_CALL setReadOnly( const ::rtl::OUString& FileURL, sal_Bool bReadOnly ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
116 virtual void SAL_CALL createFolder( const ::rtl::OUString& NewFolderURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
117 virtual sal_Int32 SAL_CALL getSize( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
118 virtual ::rtl::OUString SAL_CALL getContentType( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
119 virtual ::com::sun::star::util::DateTime SAL_CALL getDateTimeModified( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
120 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFolderContents( const ::rtl::OUString& FolderURL, sal_Bool bIncludeFolders ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
121 virtual sal_Bool SAL_CALL exists( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
122 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL openFileRead( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
123 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL openFileWrite( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
124 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openFileReadWrite( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
125 virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException);
126 virtual void SAL_CALL writeFile( const ::rtl::OUString& FileURL, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& data ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
127 virtual sal_Bool SAL_CALL isHidden( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
128 virtual void SAL_CALL setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
132 //===========================================================================
133 // Implementation XActiveDataSink
135 typedef cppu::WeakImplHelper1< XActiveDataSink > ActiveDataSinkHelper;
137 class OActiveDataSink : public ActiveDataSinkHelper
139 Reference< XInputStream > mxStream;
141 public:
143 // Methods
144 virtual void SAL_CALL setInputStream( const Reference< XInputStream >& aStream )
145 throw(RuntimeException);
146 virtual Reference< XInputStream > SAL_CALL getInputStream( )
147 throw(RuntimeException);
150 void OActiveDataSink::setInputStream( const Reference< XInputStream >& aStream )
151 throw(RuntimeException)
153 mxStream = aStream;
156 Reference< XInputStream > OActiveDataSink::getInputStream()
157 throw(RuntimeException)
159 return mxStream;
163 //===========================================================================
164 // Implementation XActiveDataSource
166 typedef cppu::WeakImplHelper1< XActiveDataSource > ActiveDataSourceHelper;
168 class OActiveDataSource : public ActiveDataSourceHelper
170 Reference< XOutputStream > mxStream;
172 public:
174 // Methods
175 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream )
176 throw(RuntimeException);
177 virtual Reference< XOutputStream > SAL_CALL getOutputStream()
178 throw(RuntimeException);
181 void OActiveDataSource::setOutputStream( const Reference< XOutputStream >& aStream )
182 throw(RuntimeException)
184 mxStream = aStream;
187 Reference< XOutputStream > OActiveDataSource::getOutputStream()
188 throw(RuntimeException)
190 return mxStream;
194 //===========================================================================
195 // Implementation XActiveDataStreamer
197 typedef cppu::WeakImplHelper1< XActiveDataStreamer > ActiveDataStreamerHelper;
199 class OActiveDataStreamer : public ActiveDataStreamerHelper
201 Reference< XStream > mxStream;
203 public:
205 // Methods
206 virtual void SAL_CALL setStream( const Reference< XStream >& aStream )
207 throw(RuntimeException);
208 virtual Reference< XStream > SAL_CALL getStream()
209 throw(RuntimeException);
212 void OActiveDataStreamer::setStream( const Reference< XStream >& aStream )
213 throw(RuntimeException)
215 mxStream = aStream;
218 Reference< XStream > OActiveDataStreamer::getStream()
219 throw(RuntimeException)
221 return mxStream;
226 //===========================================================================
227 // Implementation XCommandEnvironment
229 typedef cppu::WeakImplHelper1< XCommandEnvironment > CommandEnvironmentHelper;
231 class OCommandEnvironment : public CommandEnvironmentHelper
233 Reference< XInteractionHandler > mxInteraction;
235 public:
236 void setHandler( Reference< XInteractionHandler > xInteraction_ )
238 mxInteraction = xInteraction_;
241 // Methods
242 virtual Reference< XInteractionHandler > SAL_CALL getInteractionHandler()
243 throw(RuntimeException);
244 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
245 throw(RuntimeException);
248 Reference< XInteractionHandler > OCommandEnvironment::getInteractionHandler()
249 throw(RuntimeException)
251 return mxInteraction;
254 Reference< XProgressHandler > OCommandEnvironment::getProgressHandler()
255 throw(RuntimeException)
257 Reference< XProgressHandler > xRet;
258 return xRet;
261 //===========================================================================
263 void OFileAccess::transferImpl( const rtl::OUString& rSource,
264 const rtl::OUString& rDest,
265 sal_Bool bMoveData )
266 throw(CommandAbortedException, Exception, RuntimeException)
268 // SfxContentHelper::Transfer_Impl
269 INetURLObject aSourceObj( rSource, INET_PROT_FILE );
270 INetURLObject aDestObj( rDest, INET_PROT_FILE );
271 String aName = aDestObj.getName(
272 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
273 String aDestURL;
274 String aSourceURL = aSourceObj.GetMainURL( INetURLObject::NO_DECODE );
275 if ( aDestObj.removeSegment() )
277 // hierarchical URL.
279 aDestObj.setFinalSlash();
280 aDestURL = aDestObj.GetMainURL( INetURLObject::NO_DECODE );
282 else
284 // non-hierachical URL
286 // #i29648#
288 #if 0
289 // Note: A hierachical UCB content implements interface XChild, which
290 // has a method getParent(). Unfortunately this does not always help
291 // here, because it is not guaranteed that a content object for a
292 // non-existing resource can be created. Thus, it will happen that an
293 // exception is thrown when trying to create a UCB content for the
294 // destination URL.
298 ucbhelper::Content aFullDest(
299 aDestObj.GetMainURL(
300 INetURLObject::NO_DECODE ), mxEnvironment );
302 Reference< XChild > xChild( aFullDest.get(), UNO_QUERY_THROW );
303 Reference< com::sun::star::ucb::XContent >
304 xParent( xChild->getParent(), UNO_QUERY_THROW );
305 ucbhelper::Content aParent( xParent, mxEnvironment );
307 aDestURL = aParent.getURL();
309 rtl::OUString aNameTmp;
310 aFullDest.getPropertyValue(
311 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) )
312 >>= aNameTmp;
313 aName = aNameTmp;
315 catch ( Exception const & )
317 throw RuntimeException(
318 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
319 "OFileAccess::transferrImpl - Unable to "
320 "obtain destination folder URL!" ) ),
321 static_cast< cppu::OWeakObject * >( this ) );
323 #else
324 if ( aDestObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
326 // Hack: Expand destination URL using Macro Expander and try again
327 // with the hopefully hierarchical expanded URL...
331 Reference< XComponentContext > xCtx;
332 Reference< XPropertySet > xPropSet( mxSMgr, UNO_QUERY_THROW );
333 if ( xPropSet.is() )
335 xPropSet->getPropertyValue(
336 rtl::OUString(
337 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
338 >>= xCtx;
341 Reference< XMacroExpander > xExpander;
343 xCtx->getValueByName(
344 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
345 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
346 >>= xExpander;
348 OSL_ENSURE( xExpander.is(),
349 "Unable to obtain macro expander singleton!" );
351 aDestURL = xExpander->expandMacros(
352 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
354 catch ( Exception const & )
356 throw RuntimeException(
357 rtl::OUString(
358 RTL_CONSTASCII_USTRINGPARAM(
359 "OFileAccess::transferrImpl - Unable to obtain "
360 "destination folder URL!" ) ),
361 static_cast< cppu::OWeakObject * >( this ) );
364 transferImpl( rSource, aDestURL, bMoveData );
365 return;
368 throw RuntimeException(
369 rtl::OUString(
370 RTL_CONSTASCII_USTRINGPARAM(
371 "OFileAccess::transferrImpl - Unable to obtain "
372 "destination folder URL!" ) ),
373 static_cast< cppu::OWeakObject * >( this ) );
374 #endif
377 ucbhelper::Content aDestPath( aDestURL, mxEnvironment );
378 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment );
382 aDestPath.transferContent( aSrc,
383 bMoveData
384 ? ucbhelper::InsertOperation_MOVE
385 : ucbhelper::InsertOperation_COPY,
386 aName,
387 ::com::sun::star::ucb::NameClash::OVERWRITE );
389 catch ( ::com::sun::star::ucb::CommandFailedException const & )
391 // Interaction Handler already handled the error that has occured...
395 void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
396 throw(CommandAbortedException, Exception, RuntimeException)
398 transferImpl( SourceURL, DestURL, sal_False );
401 void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
402 throw(CommandAbortedException, Exception, RuntimeException)
404 transferImpl( SourceURL, DestURL, sal_True );
407 void OFileAccess::kill( const rtl::OUString& FileURL )
408 throw(CommandAbortedException, Exception, RuntimeException)
410 // SfxContentHelper::Kill
411 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE );
412 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
415 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
417 catch ( ::com::sun::star::ucb::CommandFailedException const & )
419 // Interaction Handler already handled the error that has occured...
423 sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL )
424 throw(CommandAbortedException, Exception, RuntimeException)
426 sal_Bool bRet = sal_False;
429 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
430 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
431 bRet = aCnt.isFolder();
433 catch (Exception &) {}
434 return bRet;
437 sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL )
438 throw(CommandAbortedException, Exception, RuntimeException)
440 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
441 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
442 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) );
443 sal_Bool bRet = sal_False;
444 aRetAny >>= bRet;
445 return bRet;
448 void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly )
449 throw(CommandAbortedException, Exception, RuntimeException)
451 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
452 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
453 Any aAny;
454 aAny <<= bReadOnly;
455 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), aAny );
458 void OFileAccess::createFolder( const rtl::OUString& NewFolderURL )
459 throw(CommandAbortedException, Exception, RuntimeException)
461 // Does the folder already exist?
462 if( !NewFolderURL.getLength() || isFolder( NewFolderURL ) )
463 return;
465 // SfxContentHelper::MakeFolder
466 INetURLObject aURL( NewFolderURL, INET_PROT_FILE );
467 String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
468 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
469 if ( aTitle.Len() )
471 aURL.removeSegment();
473 // Does the base folder exist? Otherwise create it first
474 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
475 if( !isFolder( aBaseFolderURLStr ) )
477 createFolder( aBaseFolderURLStr );
481 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
483 Reference< XContentCreator > xCreator = Reference< XContentCreator >( aCnt.get(), UNO_QUERY );
484 if ( !xCreator.is() )
485 return;
487 Sequence< ContentInfo > aInfo = xCreator->queryCreatableContentsInfo();
488 sal_Int32 nCount = aInfo.getLength();
489 if ( nCount == 0 )
490 return;
492 for ( sal_Int32 i = 0; i < nCount; ++i )
494 // Simply look for the first KIND_FOLDER...
495 const ContentInfo & rCurr = aInfo[i];
496 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
498 // Make sure the only required bootstrap property is "Title",
499 const Sequence< Property > & rProps = rCurr.Properties;
500 if ( rProps.getLength() != 1 )
501 continue;
503 if ( !rProps[ 0 ].Name.equalsAsciiL(
504 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
505 continue;
507 Sequence<rtl::OUString> aNames(1);
508 rtl::OUString* pNames = aNames.getArray();
509 pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
510 Sequence< Any > aValues(1);
511 Any* pValues = aValues.getArray();
512 pValues[0] = makeAny( rtl::OUString( aTitle ) );
514 ucbhelper::Content aNew;
517 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) )
518 continue;
520 // Success. We're done.
521 return;
523 catch ( ::com::sun::star::ucb::CommandFailedException const & )
525 // Interaction Handler already handled the error that has occured...
526 continue;
532 sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL )
533 throw(CommandAbortedException, Exception, RuntimeException)
535 // SfxContentHelper::GetSize
536 sal_Int32 nSize = 0;
537 sal_Int64 nTemp = 0;
538 INetURLObject aObj( FileURL, INET_PROT_FILE );
539 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
540 aCnt.getPropertyValue( rtl::OUString::createFromAscii( "Size" ) ) >>= nTemp;
541 nSize = (sal_Int32)nTemp;
542 return nSize;
545 rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL )
546 throw(CommandAbortedException, Exception, RuntimeException)
548 INetURLObject aObj( FileURL, INET_PROT_FILE );
549 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
551 Reference< XContent > xContent = aCnt.get();
552 rtl::OUString aTypeStr = xContent->getContentType();
553 return aTypeStr;
556 DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL )
557 throw(CommandAbortedException, Exception, RuntimeException)
559 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
560 DateTime aDateTime;
562 Reference< XCommandEnvironment > aCmdEnv;
563 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
564 aYoung.getPropertyValue( rtl::OUString::createFromAscii( "DateModified" ) ) >>= aDateTime;
565 return aDateTime;
569 DECLARE_LIST( StringList_Impl, rtl::OUString* )
571 Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders )
572 throw(CommandAbortedException, Exception, RuntimeException)
574 // SfxContentHelper::GetFolderContents
576 StringList_Impl* pFiles = NULL;
577 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE );
579 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
580 Reference< XResultSet > xResultSet;
581 Sequence< rtl::OUString > aProps(0);
582 //Sequence< rtl::OUString > aProps(1);
583 //rtl::OUString* pProps = aProps.getArray();
584 //pProps[0] == rtl::OUString::createFromAscii( "Url" );
586 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY;
590 xResultSet = aCnt.createCursor( aProps, eInclude );
592 catch ( ::com::sun::star::ucb::CommandFailedException const & )
594 // Interaction Handler already handled the error that has occured...
597 if ( xResultSet.is() )
599 pFiles = new StringList_Impl;
600 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
602 while ( xResultSet->next() )
604 rtl::OUString aId = xContentAccess->queryContentIdentifierString();
605 INetURLObject aURL( aId, INET_PROT_FILE );
606 rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
607 pFiles->Insert( pFile, LIST_APPEND );
611 if ( pFiles )
613 ULONG nCount = pFiles->Count();
614 Sequence < rtl::OUString > aRet( nCount );
615 rtl::OUString* pRet = aRet.getArray();
616 for ( USHORT i = 0; i < nCount; ++i )
618 rtl::OUString* pFile = pFiles->GetObject(i);
619 pRet[i] = *( pFile );
620 delete pFile;
622 delete pFiles;
623 return aRet;
625 else
626 return Sequence < rtl::OUString > ();
629 sal_Bool OFileAccess::exists( const rtl::OUString& FileURL )
630 throw(CommandAbortedException, Exception, RuntimeException)
632 sal_Bool bRet = sal_False;
635 bRet = isFolder( FileURL );
636 if( !bRet )
638 Reference< XInputStream > xStream = openFileRead( FileURL );
639 bRet = xStream.is();
640 if( bRet )
641 xStream->closeInput();
644 catch (Exception &) {}
645 return bRet;
648 Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL )
649 throw(CommandAbortedException, Exception, RuntimeException)
651 Reference< XInputStream > xRet;
652 INetURLObject aObj( FileURL, INET_PROT_FILE );
653 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
655 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink());
659 sal_Bool bRet = aCnt.openStream( xSink );
660 if( bRet )
661 xRet = xSink->getInputStream();
663 catch ( ::com::sun::star::ucb::CommandFailedException const & )
665 // Interaction Handler already handled the error that has occured...
668 return xRet;
671 Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL )
672 throw(CommandAbortedException, Exception, RuntimeException)
674 Reference< XOutputStream > xRet;
675 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL );
676 if( xStream.is() )
677 xRet = xStream->getOutputStream();
678 return xRet;
681 Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL )
682 throw(CommandAbortedException, Exception, RuntimeException)
684 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer();
685 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink );
687 OpenCommandArgument2 aArg;
688 aArg.Mode = OpenMode::DOCUMENT;
689 aArg.Priority = 0; // unused
690 aArg.Sink = xSink;
691 aArg.Properties = Sequence< Property >( 0 ); // unused
693 Any aCmdArg;
694 aCmdArg <<= aArg;
696 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
697 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
699 // Be silent...
700 Reference< XInteractionHandler > xIH;
701 if ( mpEnvironment )
703 xIH = mpEnvironment->getInteractionHandler();
704 mpEnvironment->setHandler( 0 );
709 aCnt.executeCommand( rtl::OUString::createFromAscii( "open" ), aCmdArg );
711 catch ( InteractiveIOException const & e )
713 if ( xIH.is() )
714 mpEnvironment->setHandler( xIH );
716 if ( e.Code == IOErrorCode_NOT_EXISTING )
718 // Create file...
719 SvMemoryStream aStream(0,0);
720 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
721 Reference< XInputStream > xInput( pInput );
722 InsertCommandArgument aInsertArg;
723 aInsertArg.Data = xInput;
724 aInsertArg.ReplaceExisting = sal_False;
726 aCmdArg <<= aInsertArg;
727 aCnt.executeCommand( rtl::OUString::createFromAscii( "insert" ), aCmdArg );
729 // Retry...
730 return openFileReadWrite( FileURL );
733 throw;
736 if ( xIH.is() )
737 mpEnvironment->setHandler( xIH );
739 Reference< XStream > xRet = xSink->getStream();
740 return xRet;
743 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler )
744 throw(RuntimeException)
746 if( !mpEnvironment )
748 mpEnvironment = new OCommandEnvironment();
749 mxEnvironment = (XCommandEnvironment*)mpEnvironment;
751 mpEnvironment->setHandler( Handler );
754 bool OFileAccess::createNewFile( const rtl::OUString & rParentURL,
755 const rtl::OUString & rTitle,
756 const Reference< XInputStream >& data )
757 throw ( Exception )
759 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment );
761 Reference< XContentCreator > xCreator
762 = Reference< XContentCreator >( aParentCnt.get(), UNO_QUERY );
763 if ( xCreator.is() )
765 Sequence< ContentInfo > aInfo = xCreator->queryCreatableContentsInfo();
766 sal_Int32 nCount = aInfo.getLength();
767 if ( nCount == 0 )
768 return false;
770 for ( sal_Int32 i = 0; i < nCount; ++i )
772 const ContentInfo & rCurr = aInfo[i];
773 if ( ( rCurr.Attributes
774 & ContentInfoAttribute::KIND_DOCUMENT ) &&
775 ( rCurr.Attributes
776 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) )
778 // Make sure the only required bootstrap property is
779 // "Title",
780 const Sequence< Property > & rProps = rCurr.Properties;
781 if ( rProps.getLength() != 1 )
782 continue;
784 if ( !rProps[ 0 ].Name.equalsAsciiL(
785 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
786 continue;
788 Sequence<rtl::OUString> aNames(1);
789 rtl::OUString* pNames = aNames.getArray();
790 pNames[0] = rtl::OUString(
791 RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
792 Sequence< Any > aValues(1);
793 Any* pValues = aValues.getArray();
794 pValues[0] = makeAny( rtl::OUString( rTitle ) );
798 ucbhelper::Content aNew;
799 if ( aParentCnt.insertNewContent(
800 rCurr.Type, aNames, aValues, data, aNew ) )
801 return true; // success.
802 else
803 continue;
805 catch ( CommandFailedException const & )
807 // Interaction Handler already handled the
808 // error that has occured...
809 continue;
815 return false;
818 void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL,
819 const Reference< XInputStream >& data )
820 throw ( Exception, RuntimeException )
822 INetURLObject aURL( FileURL, INET_PROT_FILE );
825 ucbhelper::Content aCnt(
826 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
830 aCnt.writeStream( data, sal_True /* bReplaceExisting */ );
832 catch ( CommandFailedException const & )
834 // Interaction Handler already handled the error that has occured...
837 catch ( ContentCreationException const & e )
839 // Most probably file does not exist. Try to create.
840 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED )
842 INetURLObject aParentURLObj( aURL );
843 if ( aParentURLObj.removeSegment() )
845 String aParentURL
846 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE );
848 // ensure all parent folders exist.
849 createFolder( aParentURL );
851 // create the new file...
852 String aTitle
853 = aURL.getName( INetURLObject::LAST_SEGMENT,
854 true,
855 INetURLObject::DECODE_WITH_CHARSET );
856 if ( createNewFile( aParentURL, aTitle, data ) )
858 // success
859 return;
864 throw;
868 sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL )
869 throw(CommandAbortedException, Exception, RuntimeException)
871 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
872 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
873 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ) );
874 sal_Bool bRet = sal_False;
875 aRetAny >>= bRet;
876 return bRet;
879 void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden )
880 throw(CommandAbortedException, Exception, RuntimeException)
882 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
883 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
884 Any aAny;
885 aAny <<= bHidden;
886 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), aAny );
889 //==================================================================================================
890 //==================================================================================================
891 //==================================================================================================
893 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XMultiServiceFactory > & xSMgr )
895 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xSMgr ) );
899 Sequence< rtl::OUString > FileAccess_getSupportedServiceNames()
901 static Sequence < rtl::OUString > *pNames = 0;
902 if( ! pNames )
904 osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
905 if( !pNames )
907 static Sequence< rtl::OUString > seqNames(1);
908 seqNames.getArray()[0] = rtl::OUString::createFromAscii( SERVICE_NAME );
909 pNames = &seqNames;
912 return *pNames;
918 //==================================================================================================
919 // Component exports
921 extern "C"
923 //==================================================================================================
924 void SAL_CALL component_getImplementationEnvironment(
925 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
927 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
929 //==================================================================================================
930 sal_Bool SAL_CALL component_writeInfo(
931 void * /*pServiceManager*/, void * pRegistryKey )
933 if (pRegistryKey)
937 Reference< XRegistryKey > xNewKey(
938 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
939 rtl::OUString::createFromAscii("/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) );
941 const Sequence< rtl::OUString > & rSNL = io_FileAccess::FileAccess_getSupportedServiceNames();
942 const rtl::OUString * pArray = rSNL.getConstArray();
943 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
944 xNewKey->createKey( pArray[nPos] );
946 return sal_True;
948 catch (InvalidRegistryException &)
950 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
953 return sal_False;
955 //==================================================================================================
956 void * SAL_CALL component_getFactory(
957 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
959 void * pRet = 0;
961 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
963 Reference< XSingleServiceFactory > xFactory( cppu::createSingleFactory(
964 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
965 rtl::OUString::createFromAscii( pImplName ),
966 io_FileAccess::FileAccess_CreateInstance,
967 io_FileAccess::FileAccess_getSupportedServiceNames() ) );
969 if (xFactory.is())
971 xFactory->acquire();
972 pRet = xFactory.get();
976 return pRet;