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