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