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 <uno/mapping.hxx>
28
29 #include <cppuhelper/factory.hxx>
30 #include <cppuhelper/implbase1.hxx>
31
32 #include <tools/ref.hxx>
33 #include <tools/urlobj.hxx>
34 #include <ucbhelper/content.hxx>
35 #include <unotools/streamwrap.hxx>
36 #include <tools/stream.hxx>
37
38 #include <com/sun/star/beans/Property.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/container/XChild.hpp>
41 #include <com/sun/star/io/XActiveDataSink.hpp>
42 #include <com/sun/star/io/XActiveDataSource.hpp>
43 #include <com/sun/star/io/XActiveDataStreamer.hpp>
44 #include <com/sun/star/sdbc/XResultSet.hpp>
45 #include <com/sun/star/ucb/CommandFailedException.hpp>
46 #include <com/sun/star/ucb/ContentInfo.hpp>
47 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
48 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
49 #include <com/sun/star/ucb/InteractiveIOException.hpp>
50 #include <com/sun/star/ucb/NameClash.hpp>
51 #include <com/sun/star/ucb/NameClashException.hpp>
52 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
53 #include <com/sun/star/ucb/OpenMode.hpp>
54 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
55 #include <com/sun/star/ucb/XContent.hpp>
56 #include <com/sun/star/ucb/XContentAccess.hpp>
57 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
58 #include <com/sun/star/util/XMacroExpander.hpp>
59
60 #define IMPLEMENTATION_NAME "com.sun.star.comp.ucb.SimpleFileAccess"
61 #define SERVICE_NAME "com.sun.star.ucb.SimpleFileAccess"
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< XMultiServiceFactory > mxSMgr;
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<XMultiServiceFactory> & xSMgr)98 OFileAccess( const Reference< XMultiServiceFactory > & xSMgr )
99 : mxSMgr( xSMgr), 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 hierachical 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< XComponentContext > xCtx;
324 Reference< XPropertySet > xPropSet( mxSMgr, UNO_QUERY_THROW );
325 if ( xPropSet.is() )
326 {
327 xPropSet->getPropertyValue(
328 rtl::OUString(
329 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
330 >>= xCtx;
331 }
332
333 Reference< XMacroExpander > xExpander;
334
335 xCtx->getValueByName(
336 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
337 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
338 >>= xExpander;
339
340 OSL_ENSURE( xExpander.is(),
341 "Unable to obtain macro expander singleton!" );
342
343 aDestURL = xExpander->expandMacros(
344 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
345 }
346 catch ( Exception const & )
347 {
348 throw RuntimeException(
349 rtl::OUString(
350 RTL_CONSTASCII_USTRINGPARAM(
351 "OFileAccess::transferrImpl - Unable to obtain "
352 "destination folder URL!" ) ),
353 static_cast< cppu::OWeakObject * >( this ) );
354 }
355
356 transferImpl( rSource, aDestURL, bMoveData );
357 return;
358 }
359
360 throw RuntimeException(
361 rtl::OUString(
362 RTL_CONSTASCII_USTRINGPARAM(
363 "OFileAccess::transferrImpl - Unable to obtain "
364 "destination folder URL!" ) ),
365 static_cast< cppu::OWeakObject * >( this ) );
366 #endif
367 }
368
369 ucbhelper::Content aDestPath( aDestURL, mxEnvironment );
370 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment );
371
372 try
373 {
374 aDestPath.transferContent( aSrc,
375 bMoveData
376 ? ucbhelper::InsertOperation_MOVE
377 : ucbhelper::InsertOperation_COPY,
378 aName,
379 ::com::sun::star::ucb::NameClash::OVERWRITE );
380 }
381 catch ( ::com::sun::star::ucb::CommandFailedException const & )
382 {
383 // Interaction Handler already handled the error that has occured...
384 }
385 }
386
copy(const rtl::OUString & SourceURL,const rtl::OUString & DestURL)387 void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
388 throw(CommandAbortedException, Exception, RuntimeException)
389 {
390 transferImpl( SourceURL, DestURL, sal_False );
391 }
392
move(const rtl::OUString & SourceURL,const rtl::OUString & DestURL)393 void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL )
394 throw(CommandAbortedException, Exception, RuntimeException)
395 {
396 transferImpl( SourceURL, DestURL, sal_True );
397 }
398
kill(const rtl::OUString & FileURL)399 void OFileAccess::kill( const rtl::OUString& FileURL )
400 throw(CommandAbortedException, Exception, RuntimeException)
401 {
402 // SfxContentHelper::Kill
403 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE );
404 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
405 try
406 {
407 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
408 }
409 catch ( ::com::sun::star::ucb::CommandFailedException const & )
410 {
411 // Interaction Handler already handled the error that has occured...
412 }
413 }
414
isFolder(const rtl::OUString & FileURL)415 sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL )
416 throw(CommandAbortedException, Exception, RuntimeException)
417 {
418 sal_Bool bRet = sal_False;
419 try
420 {
421 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
422 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
423 bRet = aCnt.isFolder();
424 }
425 catch (Exception &) {}
426 return bRet;
427 }
428
isReadOnly(const rtl::OUString & FileURL)429 sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL )
430 throw(CommandAbortedException, Exception, RuntimeException)
431 {
432 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
433 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
434 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) );
435 sal_Bool bRet = sal_False;
436 aRetAny >>= bRet;
437 return bRet;
438 }
439
setReadOnly(const rtl::OUString & FileURL,sal_Bool bReadOnly)440 void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly )
441 throw(CommandAbortedException, Exception, RuntimeException)
442 {
443 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
444 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
445 Any aAny;
446 aAny <<= bReadOnly;
447 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), aAny );
448 }
449
createFolder(const rtl::OUString & NewFolderURL)450 void OFileAccess::createFolder( const rtl::OUString& NewFolderURL )
451 throw(CommandAbortedException, Exception, RuntimeException)
452 {
453 // Does the folder already exist?
454 if( !NewFolderURL.getLength() || isFolder( NewFolderURL ) )
455 return;
456
457 // SfxContentHelper::MakeFolder
458 INetURLObject aURL( NewFolderURL, INET_PROT_FILE );
459 String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
460 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
461 if ( aTitle.Len() )
462 {
463 aURL.removeSegment();
464
465 // Does the base folder exist? Otherwise create it first
466 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
467 if( !isFolder( aBaseFolderURLStr ) )
468 {
469 createFolder( aBaseFolderURLStr );
470 }
471 }
472
473 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
474
475 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo();
476 sal_Int32 nCount = aInfo.getLength();
477 if ( nCount == 0 )
478 return;
479
480 for ( sal_Int32 i = 0; i < nCount; ++i )
481 {
482 // Simply look for the first KIND_FOLDER...
483 const ContentInfo & rCurr = aInfo[i];
484 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
485 {
486 // Make sure the only required bootstrap property is "Title",
487 const Sequence< Property > & rProps = rCurr.Properties;
488 if ( rProps.getLength() != 1 )
489 continue;
490
491 if ( !rProps[ 0 ].Name.equalsAsciiL(
492 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
493 continue;
494
495 Sequence<rtl::OUString> aNames(1);
496 rtl::OUString* pNames = aNames.getArray();
497 pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
498 Sequence< Any > aValues(1);
499 Any* pValues = aValues.getArray();
500 pValues[0] = makeAny( rtl::OUString( aTitle ) );
501
502 ucbhelper::Content aNew;
503 try
504 {
505 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) )
506 continue;
507
508 // Success. We're done.
509 return;
510 }
511 catch ( ::com::sun::star::ucb::CommandFailedException const & )
512 {
513 // Interaction Handler already handled the error that has occured...
514 continue;
515 }
516 }
517 }
518 }
519
getSize(const rtl::OUString & FileURL)520 sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL )
521 throw(CommandAbortedException, Exception, RuntimeException)
522 {
523 // SfxContentHelper::GetSize
524 sal_Int32 nSize = 0;
525 sal_Int64 nTemp = 0;
526 INetURLObject aObj( FileURL, INET_PROT_FILE );
527 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
528 aCnt.getPropertyValue( rtl::OUString::createFromAscii( "Size" ) ) >>= nTemp;
529 nSize = (sal_Int32)nTemp;
530 return nSize;
531 }
532
getContentType(const rtl::OUString & FileURL)533 rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL )
534 throw(CommandAbortedException, Exception, RuntimeException)
535 {
536 INetURLObject aObj( FileURL, INET_PROT_FILE );
537 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
538
539 Reference< XContent > xContent = aCnt.get();
540 rtl::OUString aTypeStr = xContent->getContentType();
541 return aTypeStr;
542 }
543
getDateTimeModified(const rtl::OUString & FileURL)544 DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL )
545 throw(CommandAbortedException, Exception, RuntimeException)
546 {
547 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
548 DateTime aDateTime;
549
550 Reference< XCommandEnvironment > aCmdEnv;
551 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv );
552 aYoung.getPropertyValue( rtl::OUString::createFromAscii( "DateModified" ) ) >>= aDateTime;
553 return aDateTime;
554 }
555
556
DECLARE_LIST(StringList_Impl,rtl::OUString *)557 DECLARE_LIST( StringList_Impl, rtl::OUString* )
558
559 Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders )
560 throw(CommandAbortedException, Exception, RuntimeException)
561 {
562 // SfxContentHelper::GetFolderContents
563
564 StringList_Impl* pFiles = NULL;
565 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE );
566
567 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
568 Reference< XResultSet > xResultSet;
569 Sequence< rtl::OUString > aProps(0);
570 //Sequence< rtl::OUString > aProps(1);
571 //rtl::OUString* pProps = aProps.getArray();
572 //pProps[0] == rtl::OUString::createFromAscii( "Url" );
573
574 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY;
575
576 try
577 {
578 xResultSet = aCnt.createCursor( aProps, eInclude );
579 }
580 catch ( ::com::sun::star::ucb::CommandFailedException const & )
581 {
582 // Interaction Handler already handled the error that has occured...
583 }
584
585 if ( xResultSet.is() )
586 {
587 pFiles = new StringList_Impl;
588 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
589
590 while ( xResultSet->next() )
591 {
592 rtl::OUString aId = xContentAccess->queryContentIdentifierString();
593 INetURLObject aURL( aId, INET_PROT_FILE );
594 rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
595 pFiles->Insert( pFile, LIST_APPEND );
596 }
597 }
598
599 if ( pFiles )
600 {
601 sal_uIntPtr nCount = pFiles->Count();
602 Sequence < rtl::OUString > aRet( nCount );
603 rtl::OUString* pRet = aRet.getArray();
604 for ( sal_uInt16 i = 0; i < nCount; ++i )
605 {
606 rtl::OUString* pFile = pFiles->GetObject(i);
607 pRet[i] = *( pFile );
608 delete pFile;
609 }
610 delete pFiles;
611 return aRet;
612 }
613 else
614 return Sequence < rtl::OUString > ();
615 }
616
exists(const rtl::OUString & FileURL)617 sal_Bool OFileAccess::exists( const rtl::OUString& FileURL )
618 throw(CommandAbortedException, Exception, RuntimeException)
619 {
620 sal_Bool bRet = sal_False;
621 try
622 {
623 bRet = isFolder( FileURL );
624 if( !bRet )
625 {
626 Reference< XInputStream > xStream = openFileRead( FileURL );
627 bRet = xStream.is();
628 if( bRet )
629 xStream->closeInput();
630 }
631 }
632 catch (Exception &) {}
633 return bRet;
634 }
635
openFileRead(const rtl::OUString & FileURL)636 Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL )
637 throw(CommandAbortedException, Exception, RuntimeException)
638 {
639 Reference< XInputStream > xRet;
640 INetURLObject aObj( FileURL, INET_PROT_FILE );
641 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
642
643 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink());
644
645 try
646 {
647 sal_Bool bRet = aCnt.openStream( xSink );
648 if( bRet )
649 xRet = xSink->getInputStream();
650 }
651 catch ( ::com::sun::star::ucb::CommandFailedException const & )
652 {
653 // Interaction Handler already handled the error that has occured...
654 }
655
656 return xRet;
657 }
658
openFileWrite(const rtl::OUString & FileURL)659 Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL )
660 throw(CommandAbortedException, Exception, RuntimeException)
661 {
662 Reference< XOutputStream > xRet;
663 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL );
664 if( xStream.is() )
665 xRet = xStream->getOutputStream();
666 return xRet;
667 }
668
openFileReadWrite(const rtl::OUString & FileURL)669 Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL )
670 throw(CommandAbortedException, Exception, RuntimeException)
671 {
672 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer();
673 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink );
674
675 OpenCommandArgument2 aArg;
676 aArg.Mode = OpenMode::DOCUMENT;
677 aArg.Priority = 0; // unused
678 aArg.Sink = xSink;
679 aArg.Properties = Sequence< Property >( 0 ); // unused
680
681 Any aCmdArg;
682 aCmdArg <<= aArg;
683
684 INetURLObject aFileObj( FileURL, INET_PROT_FILE );
685 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
686
687 // Be silent...
688 Reference< XInteractionHandler > xIH;
689 if ( mpEnvironment )
690 {
691 xIH = mpEnvironment->getInteractionHandler();
692 mpEnvironment->setHandler( 0 );
693 }
694
695 try
696 {
697 aCnt.executeCommand( rtl::OUString::createFromAscii( "open" ), aCmdArg );
698 }
699 catch ( InteractiveIOException const & e )
700 {
701 if ( xIH.is() )
702 mpEnvironment->setHandler( xIH );
703
704 if ( e.Code == IOErrorCode_NOT_EXISTING )
705 {
706 // Create file...
707 SvMemoryStream aStream(0,0);
708 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
709 Reference< XInputStream > xInput( pInput );
710 InsertCommandArgument aInsertArg;
711 aInsertArg.Data = xInput;
712 aInsertArg.ReplaceExisting = sal_False;
713
714 aCmdArg <<= aInsertArg;
715 aCnt.executeCommand( rtl::OUString::createFromAscii( "insert" ), aCmdArg );
716
717 // Retry...
718 return openFileReadWrite( FileURL );
719 }
720
721 throw;
722 }
723
724 if ( xIH.is() )
725 mpEnvironment->setHandler( xIH );
726
727 Reference< XStream > xRet = xSink->getStream();
728 return xRet;
729 }
730
setInteractionHandler(const Reference<XInteractionHandler> & Handler)731 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler )
732 throw(RuntimeException)
733 {
734 if( !mpEnvironment )
735 {
736 mpEnvironment = new OCommandEnvironment();
737 mxEnvironment = (XCommandEnvironment*)mpEnvironment;
738 }
739 mpEnvironment->setHandler( Handler );
740 }
741
createNewFile(const rtl::OUString & rParentURL,const rtl::OUString & rTitle,const Reference<XInputStream> & data)742 bool OFileAccess::createNewFile( const rtl::OUString & rParentURL,
743 const rtl::OUString & rTitle,
744 const Reference< XInputStream >& data )
745 throw ( Exception )
746 {
747 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment );
748
749 Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo();
750 sal_Int32 nCount = aInfo.getLength();
751 if ( nCount == 0 )
752 return false;
753
754 for ( sal_Int32 i = 0; i < nCount; ++i )
755 {
756 const ContentInfo & rCurr = aInfo[i];
757 if ( ( rCurr.Attributes
758 & ContentInfoAttribute::KIND_DOCUMENT ) &&
759 ( rCurr.Attributes
760 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) )
761 {
762 // Make sure the only required bootstrap property is
763 // "Title",
764 const Sequence< Property > & rProps = rCurr.Properties;
765 if ( rProps.getLength() != 1 )
766 continue;
767
768 if ( !rProps[ 0 ].Name.equalsAsciiL(
769 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
770 continue;
771
772 Sequence<rtl::OUString> aNames(1);
773 rtl::OUString* pNames = aNames.getArray();
774 pNames[0] = rtl::OUString(
775 RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
776 Sequence< Any > aValues(1);
777 Any* pValues = aValues.getArray();
778 pValues[0] = makeAny( rtl::OUString( rTitle ) );
779
780 try
781 {
782 ucbhelper::Content aNew;
783 if ( aParentCnt.insertNewContent(
784 rCurr.Type, aNames, aValues, data, aNew ) )
785 return true; // success.
786 else
787 continue;
788 }
789 catch ( CommandFailedException const & )
790 {
791 // Interaction Handler already handled the
792 // error that has occured...
793 continue;
794 }
795 }
796 }
797
798 return false;
799 }
800
writeFile(const rtl::OUString & FileURL,const Reference<XInputStream> & data)801 void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL,
802 const Reference< XInputStream >& data )
803 throw ( Exception, RuntimeException )
804 {
805 INetURLObject aURL( FileURL, INET_PROT_FILE );
806 try
807 {
808 ucbhelper::Content aCnt(
809 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
810
811 try
812 {
813 aCnt.writeStream( data, sal_True /* bReplaceExisting */ );
814 }
815 catch ( CommandFailedException const & )
816 {
817 // Interaction Handler already handled the error that has occured...
818 }
819 }
820 catch ( ContentCreationException const & e )
821 {
822 // Most probably file does not exist. Try to create.
823 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED )
824 {
825 INetURLObject aParentURLObj( aURL );
826 if ( aParentURLObj.removeSegment() )
827 {
828 String aParentURL
829 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE );
830
831 // ensure all parent folders exist.
832 createFolder( aParentURL );
833
834 // create the new file...
835 String aTitle
836 = aURL.getName( INetURLObject::LAST_SEGMENT,
837 true,
838 INetURLObject::DECODE_WITH_CHARSET );
839 if ( createNewFile( aParentURL, aTitle, data ) )
840 {
841 // success
842 return;
843 }
844 }
845 }
846
847 throw;
848 }
849 }
850
isHidden(const::rtl::OUString & FileURL)851 sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL )
852 throw(CommandAbortedException, Exception, RuntimeException)
853 {
854 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
855 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
856 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ) );
857 sal_Bool bRet = sal_False;
858 aRetAny >>= bRet;
859 return bRet;
860 }
861
setHidden(const::rtl::OUString & FileURL,sal_Bool bHidden)862 void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden )
863 throw(CommandAbortedException, Exception, RuntimeException)
864 {
865 INetURLObject aURLObj( FileURL, INET_PROT_FILE );
866 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment );
867 Any aAny;
868 aAny <<= bHidden;
869 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), aAny );
870 }
871
872 //==================================================================================================
873 //==================================================================================================
874 //==================================================================================================
875
FileAccess_CreateInstance(const Reference<XMultiServiceFactory> & xSMgr)876 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XMultiServiceFactory > & xSMgr )
877 {
878 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xSMgr ) );
879 }
880
881
FileAccess_getSupportedServiceNames()882 Sequence< rtl::OUString > FileAccess_getSupportedServiceNames()
883 {
884 static Sequence < rtl::OUString > *pNames = 0;
885 if( ! pNames )
886 {
887 osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
888 if( !pNames )
889 {
890 static Sequence< rtl::OUString > seqNames(1);
891 seqNames.getArray()[0] = rtl::OUString::createFromAscii( SERVICE_NAME );
892 pNames = &seqNames;
893 }
894 }
895 return *pNames;
896 }
897
898
899 }
900
901 //==================================================================================================
902 // Component exports
903
904 extern "C"
905 {
906 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)907 void SAL_CALL component_getImplementationEnvironment(
908 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
909 {
910 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
911 }
912 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void *)913 void * SAL_CALL component_getFactory(
914 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
915 {
916 void * pRet = 0;
917
918 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
919 {
920 Reference< XSingleServiceFactory > xFactory( cppu::createSingleFactory(
921 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
922 rtl::OUString::createFromAscii( pImplName ),
923 io_FileAccess::FileAccess_CreateInstance,
924 io_FileAccess::FileAccess_getSupportedServiceNames() ) );
925
926 if (xFactory.is())
927 {
928 xFactory->acquire();
929 pRet = xFactory.get();
930 }
931 }
932
933 return pRet;
934 }
935 }
936
937
938