1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <osl/mutex.hxx>
25 #include <osl/diagnose.h>
26
27 #include "fileaccess/dllapi.h"
28
29 #include <uno/mapping.hxx>
30
31 #include <cppuhelper/factory.hxx>
32 #include <cppuhelper/implbase1.hxx>
33 #include <cppuhelper/implementationentry.hxx>
34
35 #include <tools/ref.hxx>
36 #include <tools/urlobj.hxx>
37 #include <ucbhelper/content.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <tools/stream.hxx>
40
41 #include <com/sun/star/beans/Property.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/container/XChild.hpp>
44 #include <com/sun/star/io/XActiveDataSink.hpp>
45 #include <com/sun/star/io/XActiveDataSource.hpp>
46 #include <com/sun/star/io/XActiveDataStreamer.hpp>
47 #include <com/sun/star/sdbc/XResultSet.hpp>
48 #include <com/sun/star/ucb/CommandFailedException.hpp>
49 #include <com/sun/star/ucb/ContentInfo.hpp>
50 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
51 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
52 #include <com/sun/star/ucb/InteractiveIOException.hpp>
53 #include <com/sun/star/ucb/NameClash.hpp>
54 #include <com/sun/star/ucb/NameClashException.hpp>
55 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
56 #include <com/sun/star/ucb/OpenMode.hpp>
57 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
58 #include <com/sun/star/ucb/XContent.hpp>
59 #include <com/sun/star/ucb/XContentAccess.hpp>
60 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
61 #include <com/sun/star/util/XMacroExpander.hpp>
62
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::lang;
65 using namespace ::com::sun::star::io;
66 using namespace ::com::sun::star::ucb;
67 using namespace ::com::sun::star::sdbc;
68 using namespace ::com::sun::star::task;
69 using namespace ::com::sun::star::util;
70 using namespace ::com::sun::star::beans;
71 using namespace ::com::sun::star::registry;
72 using namespace ::com::sun::star::container;
73
74 namespace io_FileAccess
75 {
76
77
78 //===========================================================================
79 // Implementation XSimpleFileAccess
80
81 typedef cppu::WeakImplHelper1< XSimpleFileAccess3 > FileAccessHelper;
82 class OCommandEnvironment;
83
84 class OFileAccess : public FileAccessHelper
85 {
86 Reference< XComponentContext > mxCtx;
87 Reference< XCommandEnvironment > mxEnvironment;
88 OCommandEnvironment* mpEnvironment;
89
90 void transferImpl( const rtl::OUString& rSource, const rtl::OUString& rDest, sal_Bool bMoveData )
91 throw(CommandAbortedException, Exception, RuntimeException);
92 bool createNewFile( const rtl::OUString & rParentURL,
93 const rtl::OUString & rTitle,
94 const Reference< XInputStream >& data )
95 throw ( Exception );
96
97 public:
OFileAccess(const Reference<XComponentContext> & xCtx)98 OFileAccess( const Reference< XComponentContext > & xCtx )
99 : mxCtx( xCtx ), mpEnvironment( NULL ) {}
100
101 // Methods
102 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);
103 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);
104 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);
105 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);
106 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);
107 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);
108 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);
109 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);
110 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);
111 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);
112 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);
113 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);
114 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);
115 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);
116 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);
117 virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException);
118 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);
119 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);
120 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);
121 };
122
123
124 //===========================================================================
125 // Implementation XActiveDataSink
126
127 typedef cppu::WeakImplHelper1< XActiveDataSink > ActiveDataSinkHelper;
128
129 class OActiveDataSink : public ActiveDataSinkHelper
130 {
131 Reference< XInputStream > mxStream;
132
133 public:
134
135 // Methods
136 virtual void SAL_CALL setInputStream( const Reference< XInputStream >& aStream )
137 throw(RuntimeException);
138 virtual Reference< XInputStream > SAL_CALL getInputStream( )
139 throw(RuntimeException);
140 };
141
setInputStream(const Reference<XInputStream> & aStream)142 void OActiveDataSink::setInputStream( const Reference< XInputStream >& aStream )
143 throw(RuntimeException)
144 {
145 mxStream = aStream;
146 }
147
getInputStream()148 Reference< XInputStream > OActiveDataSink::getInputStream()
149 throw(RuntimeException)
150 {
151 return mxStream;
152 }
153
154
155 //===========================================================================
156 // Implementation XActiveDataSource
157
158 typedef cppu::WeakImplHelper1< XActiveDataSource > ActiveDataSourceHelper;
159
160 class OActiveDataSource : public ActiveDataSourceHelper
161 {
162 Reference< XOutputStream > mxStream;
163
164 public:
165
166 // Methods
167 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream )
168 throw(RuntimeException);
169 virtual Reference< XOutputStream > SAL_CALL getOutputStream()
170 throw(RuntimeException);
171 };
172
setOutputStream(const Reference<XOutputStream> & aStream)173 void OActiveDataSource::setOutputStream( const Reference< XOutputStream >& aStream )
174 throw(RuntimeException)
175 {
176 mxStream = aStream;
177 }
178
getOutputStream()179 Reference< XOutputStream > OActiveDataSource::getOutputStream()
180 throw(RuntimeException)
181 {
182 return mxStream;
183 }
184
185
186 //===========================================================================
187 // Implementation XActiveDataStreamer
188
189 typedef cppu::WeakImplHelper1< XActiveDataStreamer > ActiveDataStreamerHelper;
190
191 class OActiveDataStreamer : public ActiveDataStreamerHelper
192 {
193 Reference< XStream > mxStream;
194
195 public:
196
197 // Methods
198 virtual void SAL_CALL setStream( const Reference< XStream >& aStream )
199 throw(RuntimeException);
200 virtual Reference< XStream > SAL_CALL getStream()
201 throw(RuntimeException);
202 };
203
setStream(const Reference<XStream> & aStream)204 void OActiveDataStreamer::setStream( const Reference< XStream >& aStream )
205 throw(RuntimeException)
206 {
207 mxStream = aStream;
208 }
209
getStream()210 Reference< XStream > OActiveDataStreamer::getStream()
211 throw(RuntimeException)
212 {
213 return mxStream;
214 }
215
216
217
218 //===========================================================================
219 // Implementation XCommandEnvironment
220
221 typedef cppu::WeakImplHelper1< XCommandEnvironment > CommandEnvironmentHelper;
222
223 class OCommandEnvironment : public CommandEnvironmentHelper
224 {
225 Reference< XInteractionHandler > mxInteraction;
226
227 public:
setHandler(Reference<XInteractionHandler> xInteraction_)228 void setHandler( Reference< XInteractionHandler > xInteraction_ )
229 {
230 mxInteraction = xInteraction_;
231 }
232
233 // Methods
234 virtual Reference< XInteractionHandler > SAL_CALL getInteractionHandler()
235 throw(RuntimeException);
236 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
237 throw(RuntimeException);
238 };
239
getInteractionHandler()240 Reference< XInteractionHandler > OCommandEnvironment::getInteractionHandler()
241 throw(RuntimeException)
242 {
243 return mxInteraction;
244 }
245
getProgressHandler()246 Reference< XProgressHandler > OCommandEnvironment::getProgressHandler()
247 throw(RuntimeException)
248 {
249 Reference< XProgressHandler > xRet;
250 return xRet;
251 }
252
253 //===========================================================================
254
transferImpl(const rtl::OUString & rSource,const rtl::OUString & rDest,sal_Bool bMoveData)255 void OFileAccess::transferImpl( const rtl::OUString& rSource,
256 const rtl::OUString& rDest,
257 sal_Bool bMoveData )
258 throw(CommandAbortedException, Exception, RuntimeException)
259 {
260 // SfxContentHelper::Transfer_Impl
261 INetURLObject aSourceObj( rSource, INET_PROT_FILE );
262 INetURLObject aDestObj( rDest, INET_PROT_FILE );
263 String aName = aDestObj.getName(
264 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
265 String aDestURL;
266 String aSourceURL = aSourceObj.GetMainURL( INetURLObject::NO_DECODE );
267 if ( aDestObj.removeSegment() )
268 {
269 // hierarchical URL.
270
271 aDestObj.setFinalSlash();
272 aDestURL = aDestObj.GetMainURL( INetURLObject::NO_DECODE );
273 }
274 else
275 {
276 // non-hierachical URL
277
278 // #i29648#
279 //
280 #if 0
281 // Note: A hierarchical UCB content implements interface XChild, which
282 // has a method getParent(). Unfortunately this does not always help
283 // here, because it is not guaranteed that a content object for a
284 // non-existing resource can be created. Thus, it will happen that an
285 // exception is thrown when trying to create a UCB content for the
286 // destination URL.
287
288 try
289 {
290 ucbhelper::Content aFullDest(
291 aDestObj.GetMainURL(
292 INetURLObject::NO_DECODE ), mxEnvironment );
293
294 Reference< XChild > xChild( aFullDest.get(), UNO_QUERY_THROW );
295 Reference< com::sun::star::ucb::XContent >
296 xParent( xChild->getParent(), UNO_QUERY_THROW );
297 ucbhelper::Content aParent( xParent, mxEnvironment );
298
299 aDestURL = aParent.getURL();
300
301 rtl::OUString aNameTmp;
302 aFullDest.getPropertyValue(
303 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) )
304 >>= aNameTmp;
305 aName = aNameTmp;
306 }
307 catch ( Exception const & )
308 {
309 throw RuntimeException(
310 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
311 "OFileAccess::transferrImpl - Unable to "
312 "obtain destination folder URL!" ) ),
313 static_cast< cppu::OWeakObject * >( this ) );
314 }
315 #else
316 if ( aDestObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
317 {
318 // Hack: Expand destination URL using Macro Expander and try again
319 // with the hopefully hierarchical expanded URL...
320
321 try
322 {
323 Reference< XMacroExpander > xExpander;
324
325 mxCtx->getValueByName(
326 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
327 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
328 >>= xExpander;
329
330 OSL_ENSURE( xExpander.is(),
331 "Unable to obtain macro expander singleton!" );
332
333 aDestURL = xExpander->expandMacros(
334 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
335 }
336 catch ( Exception const & )
337 {
338 throw RuntimeException(
339 rtl::OUString(
340 RTL_CONSTASCII_USTRINGPARAM(
341 "OFileAccess::transferrImpl - Unable to obtain "
342 "destination folder URL!" ) ),
343 static_cast< cppu::OWeakObject * >( this ) );
344 }
345
346 transferImpl( rSource, aDestURL, bMoveData );
347 return;
348 }
349
350 throw RuntimeException(
351 rtl::OUString(
352 RTL_CONSTASCII_USTRINGPARAM(
353 "OFileAccess::transferrImpl - Unable to obtain "
354 "destination folder URL!" ) ),
355 static_cast< cppu::OWeakObject * >( this ) );
356 #endif
357 }
358
359 ucbhelper::Content aDestPath( aDestURL, mxEnvironment );
360 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment );
361
362 try
363 {
364 aDestPath.transferContent( aSrc,
365 bMoveData
366 ? ucbhelper::InsertOperation_MOVE
367 : ucbhelper::InsertOperation_COPY,
368 aName,
369 ::com::sun::star::ucb::NameClash::OVERWRITE );
370 }
371 catch ( ::com::sun::star::ucb::CommandFailedException const & )
372 {
373 // Interaction Handler already handled the error that has occurred...
374 }
375 }
376
copy(const rtl::OUString & SourceURL,const rtl::OUString & DestURL)377 void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
378 throw(CommandAbortedException, Exception, RuntimeException)
379 {
380 transferImpl( SourceURL, DestURL, sal_False );
381 }
382
move(const rtl::OUString & SourceURL,const rtl::OUString & DestURL)383 void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
384 throw(CommandAbortedException, Exception, RuntimeException)
385 {
386 transferImpl( SourceURL, DestURL, sal_True );
387 }
388
kill(const rtl::OUString & FileURL)389 void OFileAccess::kill( const rtl::OUString& FileURL )
390 throw(CommandAbortedException, Exception, RuntimeException)
391 {
392 // SfxContentHelper::Kill
393 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE );
394 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
395 try
396 {
397 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
398 }
399 catch ( ::com::sun::star::ucb::CommandFailedException const & )
400 {
401 // Interaction Handler already handled the error that has occurred...
402 }
403 }
404
isFolder(const rtl::OUString & FileURL)405 sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL )
406 throw(CommandAbortedException, Exception, RuntimeException)
407 {
408 sal_Bool bRet = sal_False;
409 try
410 {
411 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
412 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
413 bRet = aCnt.isFolder();
414 }
415 catch (Exception &) {}
416 return bRet;
417 }
418
isReadOnly(const rtl::OUString & FileURL)419 sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL )
420 throw(CommandAbortedException, Exception, RuntimeException)
421 {
422 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
423 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
424 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) );
425 sal_Bool bRet = sal_False;
426 aRetAny >>= bRet;
427 return bRet;
428 }
429
setReadOnly(const rtl::OUString & FileURL,sal_Bool bReadOnly)430 void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly )
431 throw(CommandAbortedException, Exception, RuntimeException)
432 {
433 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
434 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
435 Any aAny;
436 aAny <<= bReadOnly;
437 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), aAny );
438 }
439
createFolder(const rtl::OUString & NewFolderURL)440 void OFileAccess::createFolder( const rtl::OUString& NewFolderURL )
441 throw(CommandAbortedException, Exception, RuntimeException)
442 {
443 // Does the folder already exist?
444 if( !NewFolderURL.getLength() || isFolder( NewFolderURL ) )
445 return;
446
447 // SfxContentHelper::MakeFolder
448 INetURLObject aURL( NewFolderURL, INET_PROT_FILE );
449 String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
450 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
451 if ( aTitle.Len() )
452 {
453 aURL.removeSegment();
454
455 // Does the base folder exist? Otherwise create it first
456 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
457 if( !isFolder( aBaseFolderURLStr ) )
458 {
459 createFolder( aBaseFolderURLStr );
460 }
461 }
462
463 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
464
465 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
466 sal_Int32 nCount = aInfo.getLength();
467 if ( nCount == 0 )
468 return;
469
470 for ( sal_Int32 i = 0; i < nCount; ++i )
471 {
472 // Simply look for the first KIND_FOLDER...
473 const ContentInfo & rCurr = aInfo[i];
474 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
475 {
476 // Make sure the only required bootstrap property is "Title",
477 const Sequence< Property > & rProps = rCurr.Properties;
478 if ( rProps.getLength() != 1 )
479 continue;
480
481 if ( !rProps[ 0 ].Name.equalsAsciiL(
482 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
483 continue;
484
485 Sequence<rtl::OUString> aNames(1);
486 rtl::OUString* pNames = aNames.getArray();
487 pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
488 Sequence< Any > aValues(1);
489 Any* pValues = aValues.getArray();
490 pValues[0] = makeAny( rtl::OUString( aTitle ) );
491
492 ucbhelper::Content aNew;
493 try
494 {
495 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) )
496 continue;
497
498 // Success. We're done.
499 return;
500 }
501 catch ( ::com::sun::star::ucb::CommandFailedException const & )
502 {
503 // Interaction Handler already handled the error that has occurred...
504 continue;
505 }
506 }
507 }
508 }
509
getSize(const rtl::OUString & FileURL)510 sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL )
511 throw(CommandAbortedException, Exception, RuntimeException)
512 {
513 // SfxContentHelper::GetSize
514 sal_Int32 nSize = 0;
515 sal_Int64 nTemp = 0;
516 INetURLObject aObj( FileURL, INET_PROT_FILE );
517 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
518 aCnt.getPropertyValue( rtl::OUString::createFromAscii( "Size" ) ) >>= nTemp;
519 nSize = (sal_Int32)nTemp;
520 return nSize;
521 }
522
getContentType(const rtl::OUString & FileURL)523 rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL )
524 throw(CommandAbortedException, Exception, RuntimeException)
525 {
526 INetURLObject aObj( FileURL, INET_PROT_FILE );
527 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
528
529 Reference< XContent > xContent = aCnt.get();
530 rtl::OUString aTypeStr = xContent->getContentType();
531 return aTypeStr;
532 }
533
getDateTimeModified(const rtl::OUString & FileURL)534 DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL )
535 throw(CommandAbortedException, Exception, RuntimeException)
536 {
537 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
538 DateTime aDateTime;
539
540 Reference< XCommandEnvironment > aCmdEnv;
541 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
542 aYoung.getPropertyValue( rtl::OUString::createFromAscii( "DateModified" ) ) >>= aDateTime;
543 return aDateTime;
544 }
545
546
DECLARE_LIST(StringList_Impl,rtl::OUString *)547 DECLARE_LIST( StringList_Impl, rtl::OUString* )
548
549 Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders )
550 throw(CommandAbortedException, Exception, RuntimeException)
551 {
552 // SfxContentHelper::GetFolderContents
553
554 StringList_Impl* pFiles = NULL;
555 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE );
556
557 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
558 Reference< XResultSet > xResultSet;
559 Sequence< rtl::OUString > aProps(0);
560 //Sequence< rtl::OUString > aProps(1);
561 //rtl::OUString* pProps = aProps.getArray();
562 //pProps[0] == rtl::OUString::createFromAscii( "Url" );
563
564 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY;
565
566 try
567 {
568 xResultSet = aCnt.createCursor( aProps, eInclude );
569 }
570 catch ( ::com::sun::star::ucb::CommandFailedException const & )
571 {
572 // Interaction Handler already handled the error that has occurred...
573 }
574
575 if ( xResultSet.is() )
576 {
577 pFiles = new StringList_Impl;
578 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
579
580 while ( xResultSet->next() )
581 {
582 rtl::OUString aId = xContentAccess->queryContentIdentifierString();
583 INetURLObject aURL( aId, INET_PROT_FILE );
584 rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
585 pFiles->Insert( pFile, LIST_APPEND );
586 }
587 }
588
589 if ( pFiles )
590 {
591 sal_uIntPtr nCount = pFiles->Count();
592 Sequence < rtl::OUString > aRet( nCount );
593 rtl::OUString* pRet = aRet.getArray();
594 for ( sal_uInt16 i = 0; i < nCount; ++i )
595 {
596 rtl::OUString* pFile = pFiles->GetObject(i);
597 pRet[i] = *( pFile );
598 delete pFile;
599 }
600 delete pFiles;
601 return aRet;
602 }
603 else
604 return Sequence < rtl::OUString > ();
605 }
606
exists(const rtl::OUString & FileURL)607 sal_Bool OFileAccess::exists( const rtl::OUString& FileURL )
608 throw(CommandAbortedException, Exception, RuntimeException)
609 {
610 sal_Bool bRet = sal_False;
611 try
612 {
613 bRet = isFolder( FileURL );
614 if( !bRet )
615 {
616 Reference< XInputStream > xStream = openFileRead( FileURL );
617 bRet = xStream.is();
618 if( bRet )
619 xStream->closeInput();
620 }
621 }
622 catch (Exception &) {}
623 return bRet;
624 }
625
openFileRead(const rtl::OUString & FileURL)626 Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL )
627 throw(CommandAbortedException, Exception, RuntimeException)
628 {
629 Reference< XInputStream > xRet;
630 INetURLObject aObj( FileURL, INET_PROT_FILE );
631 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
632
633 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink());
634
635 try
636 {
637 sal_Bool bRet = aCnt.openStream( xSink );
638 if( bRet )
639 xRet = xSink->getInputStream();
640 }
641 catch ( ::com::sun::star::ucb::CommandFailedException const & )
642 {
643 // Interaction Handler already handled the error that has occurred...
644 }
645
646 return xRet;
647 }
648
openFileWrite(const rtl::OUString & FileURL)649 Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL )
650 throw(CommandAbortedException, Exception, RuntimeException)
651 {
652 Reference< XOutputStream > xRet;
653 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL );
654 if( xStream.is() )
655 xRet = xStream->getOutputStream();
656 return xRet;
657 }
658
openFileReadWrite(const rtl::OUString & FileURL)659 Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL )
660 throw(CommandAbortedException, Exception, RuntimeException)
661 {
662 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer();
663 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink );
664
665 OpenCommandArgument2 aArg;
666 aArg.Mode = OpenMode::DOCUMENT;
667 aArg.Priority = 0; // unused
668 aArg.Sink = xSink;
669 aArg.Properties = Sequence< Property >( 0 ); // unused
670
671 Any aCmdArg;
672 aCmdArg <<= aArg;
673
674 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
675 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
676
677 // Be silent...
678 Reference< XInteractionHandler > xIH;
679 if ( mpEnvironment )
680 {
681 xIH = mpEnvironment->getInteractionHandler();
682 mpEnvironment->setHandler( 0 );
683 }
684
685 try
686 {
687 aCnt.executeCommand( rtl::OUString::createFromAscii( "open" ), aCmdArg );
688 }
689 catch ( InteractiveIOException const & e )
690 {
691 if ( xIH.is() )
692 mpEnvironment->setHandler( xIH );
693
694 if ( e.Code == IOErrorCode_NOT_EXISTING )
695 {
696 // Create file...
697 SvMemoryStream aStream(0,0);
698 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
699 Reference< XInputStream > xInput( pInput );
700 InsertCommandArgument aInsertArg;
701 aInsertArg.Data = xInput;
702 aInsertArg.ReplaceExisting = sal_False;
703
704 aCmdArg <<= aInsertArg;
705 aCnt.executeCommand( rtl::OUString::createFromAscii( "insert" ), aCmdArg );
706
707 // Retry...
708 return openFileReadWrite( FileURL );
709 }
710
711 throw;
712 }
713
714 if ( xIH.is() )
715 mpEnvironment->setHandler( xIH );
716
717 Reference< XStream > xRet = xSink->getStream();
718 return xRet;
719 }
720
setInteractionHandler(const Reference<XInteractionHandler> & Handler)721 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler )
722 throw(RuntimeException)
723 {
724 if( !mpEnvironment )
725 {
726 mpEnvironment = new OCommandEnvironment();
727 mxEnvironment = (XCommandEnvironment*)mpEnvironment;
728 }
729 mpEnvironment->setHandler( Handler );
730 }
731
createNewFile(const rtl::OUString & rParentURL,const rtl::OUString & rTitle,const Reference<XInputStream> & data)732 bool OFileAccess::createNewFile( const rtl::OUString & rParentURL,
733 const rtl::OUString & rTitle,
734 const Reference< XInputStream >& data )
735 throw ( Exception )
736 {
737 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment );
738
739 Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo();
740 sal_Int32 nCount = aInfo.getLength();
741 if ( nCount == 0 )
742 return false;
743
744 for ( sal_Int32 i = 0; i < nCount; ++i )
745 {
746 const ContentInfo & rCurr = aInfo[i];
747 if ( ( rCurr.Attributes
748 & ContentInfoAttribute::KIND_DOCUMENT ) &&
749 ( rCurr.Attributes
750 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) )
751 {
752 // Make sure the only required bootstrap property is
753 // "Title",
754 const Sequence< Property > & rProps = rCurr.Properties;
755 if ( rProps.getLength() != 1 )
756 continue;
757
758 if ( !rProps[ 0 ].Name.equalsAsciiL(
759 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
760 continue;
761
762 Sequence<rtl::OUString> aNames(1);
763 rtl::OUString* pNames = aNames.getArray();
764 pNames[0] = rtl::OUString(
765 RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
766 Sequence< Any > aValues(1);
767 Any* pValues = aValues.getArray();
768 pValues[0] = makeAny( rtl::OUString( rTitle ) );
769
770 try
771 {
772 ucbhelper::Content aNew;
773 if ( aParentCnt.insertNewContent(
774 rCurr.Type, aNames, aValues, data, aNew ) )
775 return true; // success.
776 else
777 continue;
778 }
779 catch ( CommandFailedException const & )
780 {
781 // Interaction Handler already handled the
782 // error that has occurred...
783 continue;
784 }
785 }
786 }
787
788 return false;
789 }
790
writeFile(const rtl::OUString & FileURL,const Reference<XInputStream> & data)791 void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL,
792 const Reference< XInputStream >& data )
793 throw ( Exception, RuntimeException )
794 {
795 INetURLObject aURL( FileURL, INET_PROT_FILE );
796 try
797 {
798 ucbhelper::Content aCnt(
799 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
800
801 try
802 {
803 aCnt.writeStream( data, sal_True /* bReplaceExisting */ );
804 }
805 catch ( CommandFailedException const & )
806 {
807 // Interaction Handler already handled the error that has occurred...
808 }
809 }
810 catch ( ContentCreationException const & e )
811 {
812 // Most probably file does not exist. Try to create.
813 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED )
814 {
815 INetURLObject aParentURLObj( aURL );
816 if ( aParentURLObj.removeSegment() )
817 {
818 String aParentURL
819 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE );
820
821 // ensure all parent folders exist.
822 createFolder( aParentURL );
823
824 // create the new file...
825 String aTitle
826 = aURL.getName( INetURLObject::LAST_SEGMENT,
827 true,
828 INetURLObject::DECODE_WITH_CHARSET );
829 if ( createNewFile( aParentURL, aTitle, data ) )
830 {
831 // success
832 return;
833 }
834 }
835 }
836
837 throw;
838 }
839 }
840
isHidden(const::rtl::OUString & FileURL)841 sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL )
842 throw(CommandAbortedException, Exception, RuntimeException)
843 {
844 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
845 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
846 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ) );
847 sal_Bool bRet = sal_False;
848 aRetAny >>= bRet;
849 return bRet;
850 }
851
setHidden(const::rtl::OUString & FileURL,sal_Bool bHidden)852 void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden )
853 throw(CommandAbortedException, Exception, RuntimeException)
854 {
855 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
856 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
857 Any aAny;
858 aAny <<= bHidden;
859 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), aAny );
860 }
861
862 //==================================================================================================
863 //==================================================================================================
864 //==================================================================================================
865
FileAccess_CreateInstance(const Reference<XComponentContext> & xCtx)866 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XComponentContext > & xCtx )
867 {
868 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xCtx ) );
869 }
870
FileAccess_getImplementationName()871 rtl::OUString FileAccess_getImplementationName()
872 {
873 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ucb.SimpleFileAccess" ) );
874 }
875
FileAccess_getSupportedServiceNames()876 Sequence< rtl::OUString > FileAccess_getSupportedServiceNames()
877 {
878 static Sequence < rtl::OUString > *pNames = 0;
879 if( ! pNames )
880 {
881 osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
882 if( !pNames )
883 {
884 static Sequence< rtl::OUString > seqNames(1);
885 seqNames.getArray()[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" );
886 pNames = &seqNames;
887 }
888 }
889 return *pNames;
890 }
891
892 struct ::cppu::ImplementationEntry g_component_entries [] =
893 {
894 {
895 FileAccess_CreateInstance,
896 FileAccess_getImplementationName,
897 FileAccess_getSupportedServiceNames,
898 ::cppu::createSingleComponentFactory,
899 0,
900 0
901 },
902 { 0, 0, 0, 0, 0, 0 }
903 };
904
905 }
906
907 //==================================================================================================
908 // Component exports
909
910 extern "C"
911 {
912 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)913 FILEACCESS_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment(
914 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
915 {
916 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
917 }
918 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void * pRegistryKey)919 FILEACCESS_DLLPUBLIC void * SAL_CALL component_getFactory(
920 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
921 {
922 return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, ::io_FileAccess::g_component_entries );
923 }
924 }
925