bump product version to 4.1.6.2
[LibreOffice.git] / fileaccess / source / FileAccess.cxx
blob00327b4047a40321d886a6d125c67007cdd2d13b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/mutex.hxx>
21 #include <osl/diagnose.h>
23 #include <uno/mapping.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/implbase1.hxx>
28 #include <tools/urlobj.hxx>
29 #include <ucbhelper/content.hxx>
30 #include <unotools/streamwrap.hxx>
31 #include <tools/stream.hxx>
33 #include <com/sun/star/beans/Property.hpp>
34 #include <com/sun/star/container/XChild.hpp>
35 #include <com/sun/star/io/XActiveDataSink.hpp>
36 #include <com/sun/star/io/XActiveDataSource.hpp>
37 #include <com/sun/star/io/XActiveDataStreamer.hpp>
38 #include <com/sun/star/sdbc/XResultSet.hpp>
39 #include <com/sun/star/ucb/CommandFailedException.hpp>
40 #include <com/sun/star/ucb/ContentInfo.hpp>
41 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
42 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
43 #include <com/sun/star/ucb/InteractiveIOException.hpp>
44 #include <com/sun/star/ucb/NameClash.hpp>
45 #include <com/sun/star/ucb/NameClashException.hpp>
46 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
47 #include <com/sun/star/ucb/OpenMode.hpp>
48 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
49 #include <com/sun/star/ucb/XContent.hpp>
50 #include <com/sun/star/ucb/XContentAccess.hpp>
51 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
52 #include <com/sun/star/util/theMacroExpander.hpp>
54 #include <vector>
56 #define IMPLEMENTATION_NAME "com.sun.star.comp.ucb.SimpleFileAccess"
57 #define SERVICE_NAME "com.sun.star.ucb.SimpleFileAccess"
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::lang;
61 using namespace ::com::sun::star::io;
62 using namespace ::com::sun::star::ucb;
63 using namespace ::com::sun::star::sdbc;
64 using namespace ::com::sun::star::task;
65 using namespace ::com::sun::star::util;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::registry;
68 using namespace ::com::sun::star::container;
70 using ::std::vector;
72 namespace
76 //===========================================================================
77 // Implementation XSimpleFileAccess
79 typedef cppu::WeakImplHelper1< XSimpleFileAccess3 > FileAccessHelper;
80 class OCommandEnvironment;
82 class OFileAccess : public FileAccessHelper
84 Reference< XComponentContext > m_xContext;
85 Reference< XCommandEnvironment > mxEnvironment;
86 OCommandEnvironment* mpEnvironment;
88 void transferImpl( const OUString& rSource, const OUString& rDest, sal_Bool bMoveData )
89 throw(CommandAbortedException, Exception, RuntimeException);
90 bool createNewFile( const OUString & rParentURL,
91 const OUString & rTitle,
92 const Reference< XInputStream >& data )
93 throw ( Exception );
95 public:
96 OFileAccess( const Reference< XComponentContext > & xContext )
97 : m_xContext( xContext), mpEnvironment( NULL ) {}
99 // Methods
100 virtual void SAL_CALL copy( const OUString& SourceURL, const OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
101 virtual void SAL_CALL move( const OUString& SourceURL, const OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
102 virtual void SAL_CALL kill( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
103 virtual sal_Bool SAL_CALL isFolder( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
104 virtual sal_Bool SAL_CALL isReadOnly( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
105 virtual void SAL_CALL setReadOnly( const OUString& FileURL, sal_Bool bReadOnly ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
106 virtual void SAL_CALL createFolder( const OUString& NewFolderURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
107 virtual sal_Int32 SAL_CALL getSize( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
108 virtual OUString SAL_CALL getContentType( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
109 virtual ::com::sun::star::util::DateTime SAL_CALL getDateTimeModified( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
110 virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getFolderContents( const OUString& FolderURL, sal_Bool bIncludeFolders ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
111 virtual sal_Bool SAL_CALL exists( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
112 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL openFileRead( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
113 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL openFileWrite( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
114 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openFileReadWrite( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
115 virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException);
116 virtual void SAL_CALL writeFile( const 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);
117 virtual sal_Bool SAL_CALL isHidden( const OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
118 virtual void SAL_CALL setHidden( const OUString& FileURL, sal_Bool bHidden ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
122 //===========================================================================
123 // Implementation XActiveDataSink
125 typedef cppu::WeakImplHelper1< XActiveDataSink > ActiveDataSinkHelper;
127 class OActiveDataSink : public ActiveDataSinkHelper
129 Reference< XInputStream > mxStream;
131 public:
133 // Methods
134 virtual void SAL_CALL setInputStream( const Reference< XInputStream >& aStream )
135 throw(RuntimeException);
136 virtual Reference< XInputStream > SAL_CALL getInputStream( )
137 throw(RuntimeException);
140 void OActiveDataSink::setInputStream( const Reference< XInputStream >& aStream )
141 throw(RuntimeException)
143 mxStream = aStream;
146 Reference< XInputStream > OActiveDataSink::getInputStream()
147 throw(RuntimeException)
149 return mxStream;
153 //===========================================================================
154 // Implementation XActiveDataStreamer
156 typedef cppu::WeakImplHelper1< XActiveDataStreamer > ActiveDataStreamerHelper;
158 class OActiveDataStreamer : public ActiveDataStreamerHelper
160 Reference< XStream > mxStream;
162 public:
164 // Methods
165 virtual void SAL_CALL setStream( const Reference< XStream >& aStream )
166 throw(RuntimeException);
167 virtual Reference< XStream > SAL_CALL getStream()
168 throw(RuntimeException);
171 void OActiveDataStreamer::setStream( const Reference< XStream >& aStream )
172 throw(RuntimeException)
174 mxStream = aStream;
177 Reference< XStream > OActiveDataStreamer::getStream()
178 throw(RuntimeException)
180 return mxStream;
185 //===========================================================================
186 // Implementation XCommandEnvironment
188 typedef cppu::WeakImplHelper1< XCommandEnvironment > CommandEnvironmentHelper;
190 class OCommandEnvironment : public CommandEnvironmentHelper
192 Reference< XInteractionHandler > mxInteraction;
194 public:
195 void setHandler( Reference< XInteractionHandler > xInteraction_ )
197 mxInteraction = xInteraction_;
200 // Methods
201 virtual Reference< XInteractionHandler > SAL_CALL getInteractionHandler()
202 throw(RuntimeException);
203 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
204 throw(RuntimeException);
207 Reference< XInteractionHandler > OCommandEnvironment::getInteractionHandler()
208 throw(RuntimeException)
210 return mxInteraction;
213 Reference< XProgressHandler > OCommandEnvironment::getProgressHandler()
214 throw(RuntimeException)
216 Reference< XProgressHandler > xRet;
217 return xRet;
220 //===========================================================================
222 void OFileAccess::transferImpl( const OUString& rSource,
223 const OUString& rDest,
224 sal_Bool bMoveData )
225 throw(CommandAbortedException, Exception, RuntimeException)
227 // SfxContentHelper::Transfer_Impl
228 INetURLObject aSourceObj( rSource, INET_PROT_FILE );
229 INetURLObject aDestObj( rDest, INET_PROT_FILE );
230 String aName = aDestObj.getName(
231 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
232 String aDestURL;
233 String aSourceURL = aSourceObj.GetMainURL( INetURLObject::NO_DECODE );
234 if ( aDestObj.removeSegment() )
236 // hierarchical URL.
238 aDestObj.setFinalSlash();
239 aDestURL = aDestObj.GetMainURL( INetURLObject::NO_DECODE );
241 else
243 // non-hierachical URL
245 // #i29648#
248 if ( aDestObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
250 // Hack: Expand destination URL using Macro Expander and try again
251 // with the hopefully hierarchical expanded URL...
255 Reference< XMacroExpander > xExpander = theMacroExpander::get(m_xContext);
257 aDestURL = xExpander->expandMacros(
258 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
260 catch ( Exception const & )
262 throw RuntimeException(
263 OUString( "OFileAccess::transferrImpl - Unable to obtain "
264 "destination folder URL!" ),
265 static_cast< cppu::OWeakObject * >( this ) );
268 transferImpl( rSource, aDestURL, bMoveData );
269 return;
272 throw RuntimeException(
273 OUString( "OFileAccess::transferrImpl - Unable to obtain "
274 "destination folder URL!" ),
275 static_cast< cppu::OWeakObject * >( this ) );
279 ucbhelper::Content aDestPath( aDestURL, mxEnvironment, comphelper::getProcessComponentContext() );
280 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment, comphelper::getProcessComponentContext() );
284 aDestPath.transferContent( aSrc,
285 bMoveData
286 ? ucbhelper::InsertOperation_MOVE
287 : ucbhelper::InsertOperation_COPY,
288 aName,
289 ::com::sun::star::ucb::NameClash::OVERWRITE );
291 catch ( ::com::sun::star::ucb::CommandFailedException const & )
293 // Interaction Handler already handled the error that has occurred...
297 void OFileAccess::copy( const OUString& SourceURL, const OUString& DestURL )
298 throw(CommandAbortedException, Exception, RuntimeException)
300 transferImpl( SourceURL, DestURL, sal_False );
303 void OFileAccess::move( const OUString& SourceURL, const OUString& DestURL )
304 throw(CommandAbortedException, Exception, RuntimeException)
306 transferImpl( SourceURL, DestURL, sal_True );
309 void OFileAccess::kill( const OUString& FileURL )
310 throw(CommandAbortedException, Exception, RuntimeException)
312 // SfxContentHelper::Kill
313 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE );
314 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
317 aCnt.executeCommand( OUString("delete" ), makeAny( sal_Bool( sal_True ) ) );
319 catch ( ::com::sun::star::ucb::CommandFailedException const & )
321 // Interaction Handler already handled the error that has occurred...
325 sal_Bool OFileAccess::isFolder( const OUString& FileURL )
326 throw(CommandAbortedException, Exception, RuntimeException)
328 sal_Bool bRet = sal_False;
331 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
332 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
333 bRet = aCnt.isFolder();
335 catch (const Exception &) {}
336 return bRet;
339 sal_Bool OFileAccess::isReadOnly( const OUString& FileURL )
340 throw(CommandAbortedException, Exception, RuntimeException)
342 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
343 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
344 Any aRetAny = aCnt.getPropertyValue( OUString( "IsReadOnly" ) );
345 sal_Bool bRet = sal_False;
346 aRetAny >>= bRet;
347 return bRet;
350 void OFileAccess::setReadOnly( const OUString& FileURL, sal_Bool bReadOnly )
351 throw(CommandAbortedException, Exception, RuntimeException)
353 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
354 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
355 Any aAny;
356 aAny <<= bReadOnly;
357 aCnt.setPropertyValue( OUString( "IsReadOnly" ), aAny );
360 void OFileAccess::createFolder( const OUString& NewFolderURL )
361 throw(CommandAbortedException, Exception, RuntimeException)
363 // Does the folder already exist?
364 if( NewFolderURL.isEmpty() || isFolder( NewFolderURL ) )
365 return;
367 // SfxContentHelper::MakeFolder
368 INetURLObject aURL( NewFolderURL, INET_PROT_FILE );
369 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
370 if ( aTitle.Len() )
372 aURL.removeSegment();
374 // Does the base folder exist? Otherwise create it first
375 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
376 if( !isFolder( aBaseFolderURLStr ) )
378 createFolder( aBaseFolderURLStr );
382 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
384 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
385 sal_Int32 nCount = aInfo.getLength();
386 if ( nCount == 0 )
387 return;
389 for ( sal_Int32 i = 0; i < nCount; ++i )
391 // Simply look for the first KIND_FOLDER...
392 const ContentInfo & rCurr = aInfo[i];
393 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
395 // Make sure the only required bootstrap property is "Title",
396 const Sequence< Property > & rProps = rCurr.Properties;
397 if ( rProps.getLength() != 1 )
398 continue;
400 if ( rProps[ 0 ].Name != "Title" )
401 continue;
403 Sequence<OUString> aNames(1);
404 OUString* pNames = aNames.getArray();
405 pNames[0] = OUString( "Title" );
406 Sequence< Any > aValues(1);
407 Any* pValues = aValues.getArray();
408 pValues[0] = makeAny( OUString( aTitle ) );
410 ucbhelper::Content aNew;
413 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) )
414 continue;
416 // Success. We're done.
417 return;
419 catch ( ::com::sun::star::ucb::CommandFailedException const & )
421 // Interaction Handler already handled the error that has occurred...
422 continue;
428 sal_Int32 OFileAccess::getSize( const OUString& FileURL )
429 throw(CommandAbortedException, Exception, RuntimeException)
431 // SfxContentHelper::GetSize
432 sal_Int32 nSize = 0;
433 sal_Int64 nTemp = 0;
434 INetURLObject aObj( FileURL, INET_PROT_FILE );
435 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
436 aCnt.getPropertyValue( "Size" ) >>= nTemp;
437 nSize = (sal_Int32)nTemp;
438 return nSize;
441 OUString OFileAccess::getContentType( const OUString& FileURL )
442 throw(CommandAbortedException, Exception, RuntimeException)
444 INetURLObject aObj( FileURL, INET_PROT_FILE );
445 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
447 Reference< XContent > xContent = aCnt.get();
448 OUString aTypeStr = xContent->getContentType();
449 return aTypeStr;
452 DateTime OFileAccess::getDateTimeModified( const OUString& FileURL )
453 throw(CommandAbortedException, Exception, RuntimeException)
455 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
456 DateTime aDateTime;
458 Reference< XCommandEnvironment > aCmdEnv;
459 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext() );
460 aYoung.getPropertyValue( OUString("DateModified" ) ) >>= aDateTime;
461 return aDateTime;
464 typedef vector< OUString* > StringList_Impl;
466 Sequence< OUString > OFileAccess::getFolderContents( const OUString& FolderURL, sal_Bool bIncludeFolders )
467 throw(CommandAbortedException, Exception, RuntimeException)
469 // SfxContentHelper::GetFolderContents
471 StringList_Impl* pFiles = NULL;
472 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE );
474 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
475 Reference< XResultSet > xResultSet;
476 Sequence< OUString > aProps(0);
478 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY;
482 xResultSet = aCnt.createCursor( aProps, eInclude );
484 catch ( ::com::sun::star::ucb::CommandFailedException const & )
486 // Interaction Handler already handled the error that has occurred...
489 if ( xResultSet.is() )
491 pFiles = new StringList_Impl();
492 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
494 while ( xResultSet->next() )
496 OUString aId = xContentAccess->queryContentIdentifierString();
497 INetURLObject aURL( aId, INET_PROT_FILE );
498 OUString* pFile = new OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
499 pFiles->push_back( pFile );
503 if ( pFiles )
505 size_t nCount = pFiles->size();
506 Sequence < OUString > aRet( nCount );
507 OUString* pRet = aRet.getArray();
508 for ( size_t i = 0; i < nCount; ++i )
510 OUString* pFile = pFiles->at( i );
511 pRet[i] = *( pFile );
512 delete pFile;
514 pFiles->clear();
515 delete pFiles;
516 return aRet;
518 else
519 return Sequence < OUString > ();
522 sal_Bool OFileAccess::exists( const OUString& FileURL )
523 throw(CommandAbortedException, Exception, RuntimeException)
525 sal_Bool bRet = sal_False;
528 bRet = isFolder( FileURL );
529 if( !bRet )
531 Reference< XInputStream > xStream = openFileRead( FileURL );
532 bRet = xStream.is();
533 if( bRet )
534 xStream->closeInput();
537 catch (const Exception &) {}
538 return bRet;
541 Reference< XInputStream > OFileAccess::openFileRead( const OUString& FileURL )
542 throw(CommandAbortedException, Exception, RuntimeException)
544 Reference< XInputStream > xRet;
545 INetURLObject aObj( FileURL, INET_PROT_FILE );
546 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
548 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink());
552 sal_Bool bRet = aCnt.openStream( xSink );
553 if( bRet )
554 xRet = xSink->getInputStream();
556 catch ( ::com::sun::star::ucb::CommandFailedException const & )
558 // Interaction Handler already handled the error that has occurred...
561 return xRet;
564 Reference< XOutputStream > OFileAccess::openFileWrite( const OUString& FileURL )
565 throw(CommandAbortedException, Exception, RuntimeException)
567 Reference< XOutputStream > xRet;
568 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL );
569 if( xStream.is() )
570 xRet = xStream->getOutputStream();
571 return xRet;
574 Reference< XStream > OFileAccess::openFileReadWrite( const OUString& FileURL )
575 throw(CommandAbortedException, Exception, RuntimeException)
577 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer();
578 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink );
580 OpenCommandArgument2 aArg;
581 aArg.Mode = OpenMode::DOCUMENT;
582 aArg.Priority = 0; // unused
583 aArg.Sink = xSink;
584 aArg.Properties = Sequence< Property >( 0 ); // unused
586 Any aCmdArg;
587 aCmdArg <<= aArg;
589 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
590 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
592 // Be silent...
593 Reference< XInteractionHandler > xIH;
594 if ( mpEnvironment )
596 xIH = mpEnvironment->getInteractionHandler();
597 mpEnvironment->setHandler( 0 );
602 aCnt.executeCommand( OUString("open" ), aCmdArg );
604 catch ( InteractiveIOException const & e )
606 if ( xIH.is() )
607 mpEnvironment->setHandler( xIH );
609 if ( e.Code == IOErrorCode_NOT_EXISTING )
611 // Create file...
612 SvMemoryStream aStream(0,0);
613 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
614 Reference< XInputStream > xInput( pInput );
615 InsertCommandArgument aInsertArg;
616 aInsertArg.Data = xInput;
617 aInsertArg.ReplaceExisting = sal_False;
619 aCmdArg <<= aInsertArg;
620 aCnt.executeCommand( OUString("insert" ), aCmdArg );
622 // Retry...
623 return openFileReadWrite( FileURL );
626 throw;
629 if ( xIH.is() )
630 mpEnvironment->setHandler( xIH );
632 Reference< XStream > xRet = xSink->getStream();
633 return xRet;
636 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler )
637 throw(RuntimeException)
639 if( !mpEnvironment )
641 mpEnvironment = new OCommandEnvironment();
642 mxEnvironment = (XCommandEnvironment*)mpEnvironment;
644 mpEnvironment->setHandler( Handler );
647 bool OFileAccess::createNewFile( const OUString & rParentURL,
648 const OUString & rTitle,
649 const Reference< XInputStream >& data )
650 throw ( Exception )
652 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment, comphelper::getProcessComponentContext() );
654 Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo();
655 sal_Int32 nCount = aInfo.getLength();
656 if ( nCount == 0 )
657 return false;
659 for ( sal_Int32 i = 0; i < nCount; ++i )
661 const ContentInfo & rCurr = aInfo[i];
662 if ( ( rCurr.Attributes
663 & ContentInfoAttribute::KIND_DOCUMENT ) &&
664 ( rCurr.Attributes
665 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) )
667 // Make sure the only required bootstrap property is
668 // "Title",
669 const Sequence< Property > & rProps = rCurr.Properties;
670 if ( rProps.getLength() != 1 )
671 continue;
673 if ( rProps[ 0 ].Name != "Title" )
674 continue;
676 Sequence<OUString> aNames(1);
677 OUString* pNames = aNames.getArray();
678 pNames[0] = OUString(
679 "Title" );
680 Sequence< Any > aValues(1);
681 Any* pValues = aValues.getArray();
682 pValues[0] = makeAny( OUString( rTitle ) );
686 ucbhelper::Content aNew;
687 if ( aParentCnt.insertNewContent(
688 rCurr.Type, aNames, aValues, data, aNew ) )
689 return true; // success.
690 else
691 continue;
693 catch ( CommandFailedException const & )
695 // Interaction Handler already handled the
696 // error that has occurred...
697 continue;
702 return false;
705 void SAL_CALL OFileAccess::writeFile( const OUString& FileURL,
706 const Reference< XInputStream >& data )
707 throw ( Exception, RuntimeException )
709 INetURLObject aURL( FileURL, INET_PROT_FILE );
712 ucbhelper::Content aCnt(
713 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment,
714 comphelper::getProcessComponentContext() );
718 aCnt.writeStream( data, sal_True /* bReplaceExisting */ );
720 catch ( CommandFailedException const & )
722 // Interaction Handler already handled the error that has occurred...
725 catch ( ContentCreationException const & e )
727 // Most probably file does not exist. Try to create.
728 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED )
730 INetURLObject aParentURLObj( aURL );
731 if ( aParentURLObj.removeSegment() )
733 String aParentURL
734 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE );
736 // ensure all parent folders exist.
737 createFolder( aParentURL );
739 // create the new file...
740 String aTitle
741 = aURL.getName( INetURLObject::LAST_SEGMENT,
742 true,
743 INetURLObject::DECODE_WITH_CHARSET );
744 if ( createNewFile( aParentURL, aTitle, data ) )
746 // success
747 return;
752 throw;
756 sal_Bool OFileAccess::isHidden( const OUString& FileURL )
757 throw(CommandAbortedException, Exception, RuntimeException)
759 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
760 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
761 Any aRetAny = aCnt.getPropertyValue( OUString( "IsHidden" ) );
762 sal_Bool bRet = sal_False;
763 aRetAny >>= bRet;
764 return bRet;
767 void OFileAccess::setHidden( const OUString& FileURL, sal_Bool bHidden )
768 throw(CommandAbortedException, Exception, RuntimeException)
770 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
771 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
772 Any aAny;
773 aAny <<= bHidden;
774 aCnt.setPropertyValue( OUString( "IsHidden" ), aAny );
777 //==================================================================================================
778 //==================================================================================================
779 //==================================================================================================
781 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XMultiServiceFactory > & xSMgr )
783 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( comphelper::getComponentContext(xSMgr) ) );
787 Sequence< OUString > FileAccess_getSupportedServiceNames()
789 Sequence< OUString > seqNames(1);
790 seqNames.getArray()[0] = OUString(SERVICE_NAME );
791 return seqNames;
797 //==================================================================================================
798 // Component exports
800 extern "C"
802 SAL_DLLPUBLIC_EXPORT void * SAL_CALL fileacc_component_getFactory(
803 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
805 void * pRet = 0;
807 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
809 Reference< XSingleServiceFactory > xFactory( cppu::createSingleFactory(
810 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
811 OUString::createFromAscii( pImplName ),
812 FileAccess_CreateInstance,
813 FileAccess_getSupportedServiceNames() ) );
815 if (xFactory.is())
817 xFactory->acquire();
818 pRet = xFactory.get();
822 return pRet;
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */