Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <osl/mutex.hxx>
21 : #include <osl/diagnose.h>
22 :
23 : #include <uno/mapping.hxx>
24 : #include <comphelper/processfactory.hxx>
25 : #include <cppuhelper/factory.hxx>
26 : #include <cppuhelper/implbase1.hxx>
27 :
28 : #include <tools/urlobj.hxx>
29 : #include <ucbhelper/content.hxx>
30 : #include <unotools/streamwrap.hxx>
31 : #include <tools/stream.hxx>
32 :
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/XMacroExpander.hpp>
53 :
54 : #include <vector>
55 :
56 : #define IMPLEMENTATION_NAME "com.sun.star.comp.ucb.SimpleFileAccess"
57 : #define SERVICE_NAME "com.sun.star.ucb.SimpleFileAccess"
58 :
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;
69 :
70 : using ::std::vector;
71 :
72 : namespace
73 : {
74 :
75 :
76 : //===========================================================================
77 : // Implementation XSimpleFileAccess
78 :
79 : typedef cppu::WeakImplHelper1< XSimpleFileAccess3 > FileAccessHelper;
80 : class OCommandEnvironment;
81 :
82 992 : class OFileAccess : public FileAccessHelper
83 : {
84 : Reference< XMultiServiceFactory > mxSMgr;
85 : Reference< XCommandEnvironment > mxEnvironment;
86 : OCommandEnvironment* mpEnvironment;
87 :
88 : void transferImpl( const rtl::OUString& rSource, const rtl::OUString& rDest, sal_Bool bMoveData )
89 : throw(CommandAbortedException, Exception, RuntimeException);
90 : bool createNewFile( const rtl::OUString & rParentURL,
91 : const rtl::OUString & rTitle,
92 : const Reference< XInputStream >& data )
93 : throw ( Exception );
94 :
95 : public:
96 846 : OFileAccess( const Reference< XMultiServiceFactory > & xSMgr )
97 846 : : mxSMgr( xSMgr), mpEnvironment( NULL ) {}
98 :
99 : // Methods
100 : 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);
101 : 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);
102 : 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);
103 : 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);
104 : 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);
105 : 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);
106 : 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);
107 : 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);
108 : 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);
109 : 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);
110 : 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);
111 : 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);
112 : 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);
113 : 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);
114 : 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);
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 ::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);
117 : 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);
118 : 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);
119 : };
120 :
121 :
122 : //===========================================================================
123 : // Implementation XActiveDataSink
124 :
125 : typedef cppu::WeakImplHelper1< XActiveDataSink > ActiveDataSinkHelper;
126 :
127 216 : class OActiveDataSink : public ActiveDataSinkHelper
128 : {
129 : Reference< XInputStream > mxStream;
130 :
131 : public:
132 :
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);
138 : };
139 :
140 6 : void OActiveDataSink::setInputStream( const Reference< XInputStream >& aStream )
141 : throw(RuntimeException)
142 : {
143 6 : mxStream = aStream;
144 6 : }
145 :
146 6 : Reference< XInputStream > OActiveDataSink::getInputStream()
147 : throw(RuntimeException)
148 : {
149 6 : return mxStream;
150 : }
151 :
152 :
153 : //===========================================================================
154 : // Implementation XActiveDataStreamer
155 :
156 : typedef cppu::WeakImplHelper1< XActiveDataStreamer > ActiveDataStreamerHelper;
157 :
158 27 : class OActiveDataStreamer : public ActiveDataStreamerHelper
159 : {
160 : Reference< XStream > mxStream;
161 :
162 : public:
163 :
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);
169 : };
170 :
171 9 : void OActiveDataStreamer::setStream( const Reference< XStream >& aStream )
172 : throw(RuntimeException)
173 : {
174 9 : mxStream = aStream;
175 9 : }
176 :
177 9 : Reference< XStream > OActiveDataStreamer::getStream()
178 : throw(RuntimeException)
179 : {
180 9 : return mxStream;
181 : }
182 :
183 :
184 :
185 : //===========================================================================
186 : // Implementation XCommandEnvironment
187 :
188 : typedef cppu::WeakImplHelper1< XCommandEnvironment > CommandEnvironmentHelper;
189 :
190 0 : class OCommandEnvironment : public CommandEnvironmentHelper
191 : {
192 : Reference< XInteractionHandler > mxInteraction;
193 :
194 : public:
195 0 : void setHandler( Reference< XInteractionHandler > xInteraction_ )
196 : {
197 0 : mxInteraction = xInteraction_;
198 0 : }
199 :
200 : // Methods
201 : virtual Reference< XInteractionHandler > SAL_CALL getInteractionHandler()
202 : throw(RuntimeException);
203 : virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
204 : throw(RuntimeException);
205 : };
206 :
207 0 : Reference< XInteractionHandler > OCommandEnvironment::getInteractionHandler()
208 : throw(RuntimeException)
209 : {
210 0 : return mxInteraction;
211 : }
212 :
213 0 : Reference< XProgressHandler > OCommandEnvironment::getProgressHandler()
214 : throw(RuntimeException)
215 : {
216 0 : Reference< XProgressHandler > xRet;
217 0 : return xRet;
218 : }
219 :
220 : //===========================================================================
221 :
222 0 : void OFileAccess::transferImpl( const rtl::OUString& rSource,
223 : const rtl::OUString& rDest,
224 : sal_Bool bMoveData )
225 : throw(CommandAbortedException, Exception, RuntimeException)
226 : {
227 : // SfxContentHelper::Transfer_Impl
228 0 : INetURLObject aSourceObj( rSource, INET_PROT_FILE );
229 0 : INetURLObject aDestObj( rDest, INET_PROT_FILE );
230 : String aName = aDestObj.getName(
231 0 : INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
232 0 : String aDestURL;
233 0 : String aSourceURL = aSourceObj.GetMainURL( INetURLObject::NO_DECODE );
234 0 : if ( aDestObj.removeSegment() )
235 : {
236 : // hierarchical URL.
237 :
238 0 : aDestObj.setFinalSlash();
239 0 : aDestURL = aDestObj.GetMainURL( INetURLObject::NO_DECODE );
240 : }
241 : else
242 : {
243 : // non-hierachical URL
244 :
245 : // #i29648#
246 : //
247 :
248 0 : if ( aDestObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
249 : {
250 : // Hack: Expand destination URL using Macro Expander and try again
251 : // with the hopefully hierarchical expanded URL...
252 :
253 : try
254 : {
255 : Reference< XComponentContext > xCtx(
256 0 : comphelper::getComponentContext( mxSMgr ) );
257 :
258 0 : Reference< XMacroExpander > xExpander;
259 :
260 0 : xCtx->getValueByName(
261 0 : rtl::OUString( "/singletons/com.sun.star.util.theMacroExpander" ) )
262 0 : >>= xExpander;
263 :
264 : OSL_ENSURE( xExpander.is(),
265 : "Unable to obtain macro expander singleton!" );
266 :
267 0 : aDestURL = xExpander->expandMacros(
268 0 : aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
269 : }
270 0 : catch ( Exception const & )
271 : {
272 : throw RuntimeException(
273 : rtl::OUString( "OFileAccess::transferrImpl - Unable to obtain "
274 : "destination folder URL!" ),
275 0 : static_cast< cppu::OWeakObject * >( this ) );
276 : }
277 :
278 0 : transferImpl( rSource, aDestURL, bMoveData );
279 0 : return;
280 : }
281 :
282 : throw RuntimeException(
283 : rtl::OUString( "OFileAccess::transferrImpl - Unable to obtain "
284 : "destination folder URL!" ),
285 0 : static_cast< cppu::OWeakObject * >( this ) );
286 :
287 : }
288 :
289 0 : ucbhelper::Content aDestPath( aDestURL, mxEnvironment, comphelper::getProcessComponentContext() );
290 0 : ucbhelper::Content aSrc ( aSourceURL, mxEnvironment, comphelper::getProcessComponentContext() );
291 :
292 : try
293 : {
294 : aDestPath.transferContent( aSrc,
295 : bMoveData
296 : ? ucbhelper::InsertOperation_MOVE
297 : : ucbhelper::InsertOperation_COPY,
298 : aName,
299 0 : ::com::sun::star::ucb::NameClash::OVERWRITE );
300 : }
301 0 : catch ( ::com::sun::star::ucb::CommandFailedException const & )
302 : {
303 : // Interaction Handler already handled the error that has occurred...
304 0 : }
305 : }
306 :
307 0 : void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
308 : throw(CommandAbortedException, Exception, RuntimeException)
309 : {
310 0 : transferImpl( SourceURL, DestURL, sal_False );
311 0 : }
312 :
313 0 : void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
314 : throw(CommandAbortedException, Exception, RuntimeException)
315 : {
316 0 : transferImpl( SourceURL, DestURL, sal_True );
317 0 : }
318 :
319 8 : void OFileAccess::kill( const rtl::OUString& FileURL )
320 : throw(CommandAbortedException, Exception, RuntimeException)
321 : {
322 : // SfxContentHelper::Kill
323 8 : INetURLObject aDeleteObj( FileURL, INET_PROT_FILE );
324 8 : ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
325 : try
326 : {
327 10 : aCnt.executeCommand( rtl::OUString("delete" ), makeAny( sal_Bool( sal_True ) ) );
328 : }
329 0 : catch ( ::com::sun::star::ucb::CommandFailedException const & )
330 : {
331 : // Interaction Handler already handled the error that has occurred...
332 8 : }
333 6 : }
334 :
335 1417 : sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL )
336 : throw(CommandAbortedException, Exception, RuntimeException)
337 : {
338 1417 : sal_Bool bRet = sal_False;
339 : try
340 : {
341 1417 : INetURLObject aURLObj( FileURL, INET_PROT_FILE );
342 1417 : ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
343 2834 : bRet = aCnt.isFolder();
344 : }
345 1417 : catch (const Exception &) {}
346 1417 : return bRet;
347 : }
348 :
349 0 : sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL )
350 : throw(CommandAbortedException, Exception, RuntimeException)
351 : {
352 0 : INetURLObject aURLObj( FileURL, INET_PROT_FILE );
353 0 : ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
354 0 : Any aRetAny = aCnt.getPropertyValue( rtl::OUString( "IsReadOnly" ) );
355 0 : sal_Bool bRet = sal_False;
356 0 : aRetAny >>= bRet;
357 0 : return bRet;
358 : }
359 :
360 0 : void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly )
361 : throw(CommandAbortedException, Exception, RuntimeException)
362 : {
363 0 : INetURLObject aURLObj( FileURL, INET_PROT_FILE );
364 0 : ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
365 0 : Any aAny;
366 0 : aAny <<= bReadOnly;
367 0 : aCnt.setPropertyValue( rtl::OUString( "IsReadOnly" ), aAny );
368 0 : }
369 :
370 0 : void OFileAccess::createFolder( const rtl::OUString& NewFolderURL )
371 : throw(CommandAbortedException, Exception, RuntimeException)
372 : {
373 : // Does the folder already exist?
374 0 : if( NewFolderURL.isEmpty() || isFolder( NewFolderURL ) )
375 : return;
376 :
377 : // SfxContentHelper::MakeFolder
378 0 : INetURLObject aURL( NewFolderURL, INET_PROT_FILE );
379 0 : String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
380 0 : String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
381 0 : if ( aTitle.Len() )
382 : {
383 0 : aURL.removeSegment();
384 :
385 : // Does the base folder exist? Otherwise create it first
386 0 : String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
387 0 : if( !isFolder( aBaseFolderURLStr ) )
388 : {
389 0 : createFolder( aBaseFolderURLStr );
390 0 : }
391 : }
392 :
393 0 : ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
394 :
395 0 : Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
396 0 : sal_Int32 nCount = aInfo.getLength();
397 0 : if ( nCount == 0 )
398 : return;
399 :
400 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
401 : {
402 : // Simply look for the first KIND_FOLDER...
403 0 : const ContentInfo & rCurr = aInfo[i];
404 0 : if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
405 : {
406 : // Make sure the only required bootstrap property is "Title",
407 0 : const Sequence< Property > & rProps = rCurr.Properties;
408 0 : if ( rProps.getLength() != 1 )
409 0 : continue;
410 :
411 0 : if ( rProps[ 0 ].Name != "Title" )
412 0 : continue;
413 :
414 0 : Sequence<rtl::OUString> aNames(1);
415 0 : rtl::OUString* pNames = aNames.getArray();
416 0 : pNames[0] = rtl::OUString( "Title" );
417 0 : Sequence< Any > aValues(1);
418 0 : Any* pValues = aValues.getArray();
419 0 : pValues[0] = makeAny( rtl::OUString( aTitle ) );
420 :
421 0 : ucbhelper::Content aNew;
422 : try
423 : {
424 0 : if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) )
425 0 : continue;
426 :
427 : // Success. We're done.
428 : return;
429 : }
430 0 : catch ( ::com::sun::star::ucb::CommandFailedException const & )
431 : {
432 : // Interaction Handler already handled the error that has occurred...
433 0 : continue;
434 0 : }
435 : }
436 0 : }
437 : }
438 :
439 0 : sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL )
440 : throw(CommandAbortedException, Exception, RuntimeException)
441 : {
442 : // SfxContentHelper::GetSize
443 0 : sal_Int32 nSize = 0;
444 0 : sal_Int64 nTemp = 0;
445 0 : INetURLObject aObj( FileURL, INET_PROT_FILE );
446 0 : ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
447 0 : aCnt.getPropertyValue( "Size" ) >>= nTemp;
448 0 : nSize = (sal_Int32)nTemp;
449 0 : return nSize;
450 : }
451 :
452 0 : rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL )
453 : throw(CommandAbortedException, Exception, RuntimeException)
454 : {
455 0 : INetURLObject aObj( FileURL, INET_PROT_FILE );
456 0 : ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
457 :
458 0 : Reference< XContent > xContent = aCnt.get();
459 0 : rtl::OUString aTypeStr = xContent->getContentType();
460 0 : return aTypeStr;
461 : }
462 :
463 0 : DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL )
464 : throw(CommandAbortedException, Exception, RuntimeException)
465 : {
466 0 : INetURLObject aFileObj( FileURL, INET_PROT_FILE );
467 0 : DateTime aDateTime;
468 :
469 0 : Reference< XCommandEnvironment > aCmdEnv;
470 0 : ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext() );
471 0 : aYoung.getPropertyValue( rtl::OUString("DateModified" ) ) >>= aDateTime;
472 0 : return aDateTime;
473 : }
474 :
475 : typedef vector< rtl::OUString* > StringList_Impl;
476 :
477 0 : Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders )
478 : throw(CommandAbortedException, Exception, RuntimeException)
479 : {
480 : // SfxContentHelper::GetFolderContents
481 :
482 0 : StringList_Impl* pFiles = NULL;
483 0 : INetURLObject aFolderObj( FolderURL, INET_PROT_FILE );
484 :
485 0 : ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
486 0 : Reference< XResultSet > xResultSet;
487 0 : Sequence< rtl::OUString > aProps(0);
488 :
489 0 : ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY;
490 :
491 : try
492 : {
493 0 : xResultSet = aCnt.createCursor( aProps, eInclude );
494 : }
495 0 : catch ( ::com::sun::star::ucb::CommandFailedException const & )
496 : {
497 : // Interaction Handler already handled the error that has occurred...
498 : }
499 :
500 0 : if ( xResultSet.is() )
501 : {
502 0 : pFiles = new StringList_Impl();
503 0 : Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
504 :
505 0 : while ( xResultSet->next() )
506 : {
507 0 : rtl::OUString aId = xContentAccess->queryContentIdentifierString();
508 0 : INetURLObject aURL( aId, INET_PROT_FILE );
509 0 : rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
510 0 : pFiles->push_back( pFile );
511 0 : }
512 : }
513 :
514 0 : if ( pFiles )
515 : {
516 0 : size_t nCount = pFiles->size();
517 0 : Sequence < rtl::OUString > aRet( nCount );
518 0 : rtl::OUString* pRet = aRet.getArray();
519 0 : for ( size_t i = 0; i < nCount; ++i )
520 : {
521 0 : rtl::OUString* pFile = pFiles->at( i );
522 0 : pRet[i] = *( pFile );
523 0 : delete pFile;
524 : }
525 0 : pFiles->clear();
526 0 : delete pFiles;
527 0 : return aRet;
528 : }
529 : else
530 0 : return Sequence < rtl::OUString > ();
531 : }
532 :
533 0 : sal_Bool OFileAccess::exists( const rtl::OUString& FileURL )
534 : throw(CommandAbortedException, Exception, RuntimeException)
535 : {
536 0 : sal_Bool bRet = sal_False;
537 : try
538 : {
539 0 : bRet = isFolder( FileURL );
540 0 : if( !bRet )
541 : {
542 0 : Reference< XInputStream > xStream = openFileRead( FileURL );
543 0 : bRet = xStream.is();
544 0 : if( bRet )
545 0 : xStream->closeInput();
546 : }
547 : }
548 0 : catch (const Exception &) {}
549 0 : return bRet;
550 : }
551 :
552 72 : Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL )
553 : throw(CommandAbortedException, Exception, RuntimeException)
554 : {
555 72 : Reference< XInputStream > xRet;
556 72 : INetURLObject aObj( FileURL, INET_PROT_FILE );
557 72 : ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
558 :
559 72 : Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink());
560 :
561 : try
562 : {
563 72 : sal_Bool bRet = aCnt.openStream( xSink );
564 6 : if( bRet )
565 6 : xRet = xSink->getInputStream();
566 : }
567 0 : catch ( ::com::sun::star::ucb::CommandFailedException const & )
568 : {
569 : // Interaction Handler already handled the error that has occurred...
570 : }
571 :
572 72 : return xRet;
573 : }
574 :
575 6 : Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL )
576 : throw(CommandAbortedException, Exception, RuntimeException)
577 : {
578 6 : Reference< XOutputStream > xRet;
579 6 : Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL );
580 6 : if( xStream.is() )
581 6 : xRet = xStream->getOutputStream();
582 6 : return xRet;
583 : }
584 :
585 9 : Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL )
586 : throw(CommandAbortedException, Exception, RuntimeException)
587 : {
588 9 : Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer();
589 9 : Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink );
590 :
591 9 : OpenCommandArgument2 aArg;
592 9 : aArg.Mode = OpenMode::DOCUMENT;
593 9 : aArg.Priority = 0; // unused
594 9 : aArg.Sink = xSink;
595 9 : aArg.Properties = Sequence< Property >( 0 ); // unused
596 :
597 9 : Any aCmdArg;
598 9 : aCmdArg <<= aArg;
599 :
600 9 : INetURLObject aFileObj( FileURL, INET_PROT_FILE );
601 9 : ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
602 :
603 : // Be silent...
604 9 : Reference< XInteractionHandler > xIH;
605 9 : if ( mpEnvironment )
606 : {
607 0 : xIH = mpEnvironment->getInteractionHandler();
608 0 : mpEnvironment->setHandler( 0 );
609 : }
610 :
611 : try
612 : {
613 9 : aCnt.executeCommand( rtl::OUString("open" ), aCmdArg );
614 : }
615 0 : catch ( InteractiveIOException const & e )
616 : {
617 0 : if ( xIH.is() )
618 0 : mpEnvironment->setHandler( xIH );
619 :
620 0 : if ( e.Code == IOErrorCode_NOT_EXISTING )
621 : {
622 : // Create file...
623 0 : SvMemoryStream aStream(0,0);
624 0 : ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
625 0 : Reference< XInputStream > xInput( pInput );
626 0 : InsertCommandArgument aInsertArg;
627 0 : aInsertArg.Data = xInput;
628 0 : aInsertArg.ReplaceExisting = sal_False;
629 :
630 0 : aCmdArg <<= aInsertArg;
631 0 : aCnt.executeCommand( rtl::OUString("insert" ), aCmdArg );
632 :
633 : // Retry...
634 0 : return openFileReadWrite( FileURL );
635 : }
636 :
637 0 : throw;
638 : }
639 :
640 9 : if ( xIH.is() )
641 0 : mpEnvironment->setHandler( xIH );
642 :
643 9 : Reference< XStream > xRet = xSink->getStream();
644 9 : return xRet;
645 : }
646 :
647 0 : void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler )
648 : throw(RuntimeException)
649 : {
650 0 : if( !mpEnvironment )
651 : {
652 0 : mpEnvironment = new OCommandEnvironment();
653 0 : mxEnvironment = (XCommandEnvironment*)mpEnvironment;
654 : }
655 0 : mpEnvironment->setHandler( Handler );
656 0 : }
657 :
658 0 : bool OFileAccess::createNewFile( const rtl::OUString & rParentURL,
659 : const rtl::OUString & rTitle,
660 : const Reference< XInputStream >& data )
661 : throw ( Exception )
662 : {
663 0 : ucbhelper::Content aParentCnt( rParentURL, mxEnvironment, comphelper::getProcessComponentContext() );
664 :
665 0 : Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo();
666 0 : sal_Int32 nCount = aInfo.getLength();
667 0 : if ( nCount == 0 )
668 0 : return false;
669 :
670 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
671 : {
672 0 : const ContentInfo & rCurr = aInfo[i];
673 0 : if ( ( rCurr.Attributes
674 : & ContentInfoAttribute::KIND_DOCUMENT ) &&
675 : ( rCurr.Attributes
676 : & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) )
677 : {
678 : // Make sure the only required bootstrap property is
679 : // "Title",
680 0 : const Sequence< Property > & rProps = rCurr.Properties;
681 0 : if ( rProps.getLength() != 1 )
682 0 : continue;
683 :
684 0 : if ( rProps[ 0 ].Name != "Title" )
685 0 : continue;
686 :
687 0 : Sequence<rtl::OUString> aNames(1);
688 0 : rtl::OUString* pNames = aNames.getArray();
689 : pNames[0] = rtl::OUString(
690 0 : "Title" );
691 0 : Sequence< Any > aValues(1);
692 0 : Any* pValues = aValues.getArray();
693 0 : pValues[0] = makeAny( rtl::OUString( rTitle ) );
694 :
695 : try
696 : {
697 0 : ucbhelper::Content aNew;
698 0 : if ( aParentCnt.insertNewContent(
699 0 : rCurr.Type, aNames, aValues, data, aNew ) )
700 0 : return true; // success.
701 : else
702 0 : continue;
703 : }
704 0 : catch ( CommandFailedException const & )
705 : {
706 : // Interaction Handler already handled the
707 : // error that has occurred...
708 0 : continue;
709 0 : }
710 : }
711 : }
712 :
713 0 : return false;
714 : }
715 :
716 0 : void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL,
717 : const Reference< XInputStream >& data )
718 : throw ( Exception, RuntimeException )
719 : {
720 0 : INetURLObject aURL( FileURL, INET_PROT_FILE );
721 : try
722 : {
723 : ucbhelper::Content aCnt(
724 : aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment,
725 0 : comphelper::getProcessComponentContext() );
726 :
727 : try
728 : {
729 0 : aCnt.writeStream( data, sal_True /* bReplaceExisting */ );
730 : }
731 0 : catch ( CommandFailedException const & )
732 : {
733 : // Interaction Handler already handled the error that has occurred...
734 0 : }
735 : }
736 0 : catch ( ContentCreationException const & e )
737 : {
738 : // Most probably file does not exist. Try to create.
739 0 : if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED )
740 : {
741 0 : INetURLObject aParentURLObj( aURL );
742 0 : if ( aParentURLObj.removeSegment() )
743 : {
744 : String aParentURL
745 0 : = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE );
746 :
747 : // ensure all parent folders exist.
748 0 : createFolder( aParentURL );
749 :
750 : // create the new file...
751 : String aTitle
752 : = aURL.getName( INetURLObject::LAST_SEGMENT,
753 : true,
754 0 : INetURLObject::DECODE_WITH_CHARSET );
755 0 : if ( createNewFile( aParentURL, aTitle, data ) )
756 : {
757 : // success
758 0 : return;
759 0 : }
760 0 : }
761 : }
762 :
763 0 : throw;
764 0 : }
765 : }
766 :
767 0 : sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL )
768 : throw(CommandAbortedException, Exception, RuntimeException)
769 : {
770 0 : INetURLObject aURLObj( FileURL, INET_PROT_FILE );
771 0 : ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
772 0 : Any aRetAny = aCnt.getPropertyValue( rtl::OUString( "IsHidden" ) );
773 0 : sal_Bool bRet = sal_False;
774 0 : aRetAny >>= bRet;
775 0 : return bRet;
776 : }
777 :
778 0 : void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden )
779 : throw(CommandAbortedException, Exception, RuntimeException)
780 : {
781 0 : INetURLObject aURLObj( FileURL, INET_PROT_FILE );
782 0 : ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment, comphelper::getProcessComponentContext() );
783 0 : Any aAny;
784 0 : aAny <<= bHidden;
785 0 : aCnt.setPropertyValue( rtl::OUString( "IsHidden" ), aAny );
786 0 : }
787 :
788 : //==================================================================================================
789 : //==================================================================================================
790 : //==================================================================================================
791 :
792 846 : Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XMultiServiceFactory > & xSMgr )
793 : {
794 846 : return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xSMgr ) );
795 : }
796 :
797 :
798 14 : Sequence< rtl::OUString > FileAccess_getSupportedServiceNames()
799 : {
800 14 : Sequence< rtl::OUString > seqNames(1);
801 14 : seqNames.getArray()[0] = rtl::OUString(SERVICE_NAME );
802 14 : return seqNames;
803 : }
804 :
805 :
806 : }
807 :
808 : //==================================================================================================
809 : // Component exports
810 :
811 : extern "C"
812 : {
813 14 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL fileacc_component_getFactory(
814 : const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
815 : {
816 14 : void * pRet = 0;
817 :
818 14 : if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
819 : {
820 : Reference< XSingleServiceFactory > xFactory( cppu::createSingleFactory(
821 : reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
822 : rtl::OUString::createFromAscii( pImplName ),
823 : FileAccess_CreateInstance,
824 14 : FileAccess_getSupportedServiceNames() ) );
825 :
826 14 : if (xFactory.is())
827 : {
828 14 : xFactory->acquire();
829 14 : pRet = xFactory.get();
830 14 : }
831 : }
832 :
833 14 : return pRet;
834 : }
835 : }
836 :
837 :
838 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|