Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
36 : :
37 : : #include "ftpdynresultset.hxx"
38 : : #include "ftpresultsetfactory.hxx"
39 : : #include "ftpresultsetI.hxx"
40 : : #include "ftpcontent.hxx"
41 : : #include "ftpcontentprovider.hxx"
42 : : #include "ftpdirp.hxx"
43 : : #include "ftpcontentidentifier.hxx"
44 : : #include "ftpcfunc.hxx"
45 : : #include "ftpstrcont.hxx"
46 : : #include "ftpintreq.hxx"
47 : :
48 : : #include <memory>
49 : : #include <vector>
50 : : #include <rtl/memory.h>
51 : : #include "curl.hxx"
52 : : #include <curl/easy.h>
53 : : #include <ucbhelper/cancelcommandexecution.hxx>
54 : : #include <ucbhelper/contentidentifier.hxx>
55 : : #include <ucbhelper/fd_inputstream.hxx>
56 : : #include <ucbhelper/propertyvalueset.hxx>
57 : : #include <ucbhelper/contentidentifier.hxx>
58 : : #include <ucbhelper/cancelcommandexecution.hxx>
59 : : #include <ucbhelper/simpleauthenticationrequest.hxx>
60 : : #include <com/sun/star/lang/IllegalAccessException.hpp>
61 : : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
62 : : #include <com/sun/star/beans/UnknownPropertyException.hpp>
63 : : #include <com/sun/star/beans/Property.hpp>
64 : : #include <com/sun/star/beans/PropertyValue.hpp>
65 : : #include <com/sun/star/ucb/XCommandInfo.hpp>
66 : : #include <com/sun/star/io/XActiveDataSink.hpp>
67 : : #include <com/sun/star/io/XOutputStream.hpp>
68 : : #include <com/sun/star/io/XActiveDataStreamer.hpp>
69 : : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
70 : : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
71 : : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
72 : : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
73 : : #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
74 : : #include <com/sun/star/ucb/InteractiveIOException.hpp>
75 : : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
76 : : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
77 : : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
78 : : #include <com/sun/star/ucb/NameClashException.hpp>
79 : : #include <com/sun/star/ucb/OpenMode.hpp>
80 : : #include <com/sun/star/ucb/IOErrorCode.hpp>
81 : :
82 : : using namespace ftp;
83 : : using namespace com::sun::star::task;
84 : : using namespace com::sun::star::container;
85 : : using namespace com::sun::star::lang;
86 : : using namespace com::sun::star::uno;
87 : : using namespace com::sun::star::ucb;
88 : : using namespace com::sun::star::beans;
89 : : using namespace com::sun::star::io;
90 : : using namespace com::sun::star::sdbc;
91 : :
92 : :
93 : :
94 : : //=========================================================================
95 : : //=========================================================================
96 : : //
97 : : // Content Implementation.
98 : : //
99 : : //=========================================================================
100 : : //=========================================================================
101 : :
102 : 4 : FTPContent::FTPContent( const Reference< XMultiServiceFactory >& rxSMgr,
103 : : FTPContentProvider* pProvider,
104 : : const Reference< XContentIdentifier >& Identifier,
105 : : const FTPURL& aFTPURL)
106 : : : ContentImplHelper(rxSMgr,pProvider,Identifier),
107 : : m_pFCP(pProvider),
108 : : m_aFTPURL(aFTPURL),
109 : : m_bInserted(false),
110 [ + - ][ + - ]: 4 : m_bTitleSet(false)
[ + - ]
111 : : {
112 : 4 : }
113 : :
114 : :
115 : :
116 : 0 : FTPContent::FTPContent( const Reference< XMultiServiceFactory >& rxSMgr,
117 : : FTPContentProvider* pProvider,
118 : : const Reference< XContentIdentifier >& Identifier,
119 : : const ContentInfo& Info)
120 : : : ContentImplHelper(rxSMgr,pProvider,Identifier),
121 : : m_pFCP(pProvider),
122 [ # # ]: 0 : m_aFTPURL(Identifier->getContentIdentifier(),
123 : : pProvider),
124 : : m_bInserted(true),
125 : : m_bTitleSet(false),
126 [ # # ][ # # ]: 0 : m_aInfo(Info)
[ # # ][ # # ]
[ # # ]
127 : : {
128 : 0 : }
129 : :
130 : :
131 : :
132 : : //=========================================================================
133 : :
134 [ + - ][ + - ]: 4 : FTPContent::~FTPContent()
135 : : {
136 [ - + ]: 8 : }
137 : :
138 : :
139 : : //=========================================================================
140 : : //
141 : : // XInterface methods.
142 : : //
143 : : //=========================================================================
144 : :
145 [ + - ][ + + ]: 80 : XINTERFACE_IMPL_6( FTPContent,
[ + - ]
146 : : XTypeProvider,
147 : : XServiceInfo,
148 : : XContent,
149 : : XCommandProcessor,
150 : : XContentCreator,
151 : : XChild);
152 : :
153 : : //=========================================================================
154 : : //
155 : : // XTypeProvider methods.
156 : : //
157 : : //=========================================================================
158 : :
159 [ # # ][ # # ]: 0 : XTYPEPROVIDER_IMPL_6( FTPContent,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
160 : : XTypeProvider,
161 : : XServiceInfo,
162 : : XContent,
163 : : XCommandProcessor,
164 : : XContentCreator,
165 : : XChild);
166 : :
167 : : //=========================================================================
168 : : //
169 : : // XServiceInfo methods.
170 : : //
171 : : //=========================================================================
172 : :
173 : : // needed, because the service shall not be creatable!!
174 : : #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
175 : : #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
176 : :
177 [ # # ][ # # ]: 0 : XSERVICEINFO_IMPL_1( FTPContent,
[ # # ][ # # ]
[ # # ][ # # ]
178 : : rtl::OUString( "com.sun.star.comp.FTPContent"),
179 : : rtl::OUString( "com.sun.star.ucb.FTPContent"));
180 : :
181 : :
182 : :
183 : : //=========================================================================
184 : : //
185 : : // XContent methods.
186 : : //
187 : : //=========================================================================
188 : :
189 : : // virtual
190 : 0 : rtl::OUString SAL_CALL FTPContent::getContentType()
191 : : throw( RuntimeException )
192 : : {
193 : 0 : return rtl::OUString(FTP_CONTENT_TYPE);
194 : : }
195 : :
196 : :
197 : : //=========================================================================
198 : : //
199 : : // XCommandProcessor methods.
200 : : //
201 : : //=========================================================================
202 : :
203 : :
204 : : //virtual
205 : 0 : void SAL_CALL FTPContent::abort( sal_Int32 /*CommandId*/ )
206 : : throw( RuntimeException )
207 : : {
208 : 0 : }
209 : :
210 : :
211 : :
212 : : /***************************************************************************/
213 : : /* */
214 : : /* Internal implementation class. */
215 : : /* */
216 : : /***************************************************************************/
217 : :
218 : :
219 [ # # ][ # # ]: 0 : class ResultSetFactoryI
[ # # ]
220 : : : public ResultSetFactory
221 : : {
222 : : public:
223 : :
224 : 0 : ResultSetFactoryI(const Reference<XMultiServiceFactory >& xSMgr,
225 : : const Reference<XContentProvider >& xProvider,
226 : : sal_Int32 nOpenMode,
227 : : const Sequence<Property>& seq,
228 : : const Sequence<NumberedSortingInfo>& seqSort,
229 : : const std::vector<FTPDirentry>& dirvec)
230 : : : m_xSMgr(xSMgr),
231 : : m_xProvider(xProvider),
232 : : m_nOpenMode(nOpenMode),
233 : : m_seq(seq),
234 : : m_seqSort(seqSort),
235 [ # # ][ # # ]: 0 : m_dirvec(dirvec)
[ # # ]
236 : : {
237 : 0 : }
238 : :
239 : 0 : virtual ResultSetBase* createResultSet()
240 : : {
241 : : return new ResultSetI(m_xSMgr,
242 : : m_xProvider,
243 : : m_nOpenMode,
244 : : m_seq,
245 : : m_seqSort,
246 [ # # ]: 0 : m_dirvec);
247 : : }
248 : :
249 : : public:
250 : :
251 : : Reference< XMultiServiceFactory > m_xSMgr;
252 : : Reference< XContentProvider > m_xProvider;
253 : : sal_Int32 m_nOpenMode;
254 : : Sequence< Property > m_seq;
255 : : Sequence< NumberedSortingInfo > m_seqSort;
256 : : std::vector<FTPDirentry> m_dirvec;
257 : : };
258 : :
259 : :
260 : :
261 : : //=========================================================================
262 : : //
263 : : // XCommandProcessor methods.
264 : : //
265 : : //=========================================================================
266 : :
267 : : enum ACTION { NOACTION,
268 : : THROWAUTHENTICATIONREQUEST,
269 : : THROWACCESSDENIED,
270 : : THROWINTERACTIVECONNECT,
271 : : THROWRESOLVENAME,
272 : : THROWQUOTE,
273 : : THROWNOFILE,
274 : : THROWGENERAL };
275 : :
276 : :
277 : : // virtual
278 : 2 : Any SAL_CALL FTPContent::execute(
279 : : const Command& aCommand,
280 : : sal_Int32 /*CommandId*/,
281 : : const Reference<
282 : : XCommandEnvironment >& Environment
283 : : )
284 : : throw(
285 : : Exception,
286 : : CommandAbortedException,
287 : : RuntimeException
288 : : )
289 : : {
290 : 2 : ACTION action(NOACTION);
291 : 2 : Any aRet;
292 : :
293 : 2 : while(true)
294 : : try {
295 [ - + ]: 4 : if(action == THROWAUTHENTICATIONREQUEST) {
296 : : // try to get a continuation first
297 : 0 : rtl::OUString aRealm,aPassword,aAccount;
298 : : m_pFCP->forHost(m_aFTPURL.host(),
299 : : m_aFTPURL.port(),
300 : : m_aFTPURL.username(),
301 : : aPassword,
302 [ # # ]: 0 : aAccount);
303 : : rtl::Reference<ucbhelper::SimpleAuthenticationRequest>
304 : : p( new ucbhelper::SimpleAuthenticationRequest(
305 : : m_aFTPURL.ident(false, false),
306 : : m_aFTPURL.host(), // ServerName
307 : : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA,
308 : : aRealm,
309 : : ucbhelper::SimpleAuthenticationRequest
310 : : ::ENTITY_FIXED,
311 : : m_aFTPURL.username(),
312 : : ucbhelper::SimpleAuthenticationRequest
313 : : ::ENTITY_MODIFY,
314 [ # # ][ # # ]: 0 : aPassword));
315 : :
316 : 0 : Reference<XInteractionHandler> xInteractionHandler;
317 [ # # ]: 0 : if(Environment.is())
318 : : xInteractionHandler =
319 [ # # ][ # # ]: 0 : Environment->getInteractionHandler();
[ # # ]
320 : :
321 [ # # ]: 0 : if( xInteractionHandler.is()) {
322 [ # # ][ # # ]: 0 : xInteractionHandler->handle(p.get());
[ # # ][ # # ]
323 : :
324 : : Reference<XInterface> xSelection(
325 [ # # ][ # # ]: 0 : p->getSelection().get());
326 : :
327 [ # # ]: 0 : if(Reference<XInteractionRetry>(
328 [ # # ]: 0 : xSelection,UNO_QUERY).is())
329 : 0 : action = NOACTION;
330 [ # # ]: 0 : else if(Reference<XInteractionSupplyAuthentication>(
331 [ # # ]: 0 : xSelection,UNO_QUERY).is()) {
332 : : m_pFCP->setHost(
333 : : m_aFTPURL.host(),
334 : : m_aFTPURL.port(),
335 : : m_aFTPURL.username(),
336 : 0 : p->getAuthenticationSupplier()->getPassword(),
337 [ # # ]: 0 : aAccount);
338 : 0 : action = NOACTION;
339 : 0 : }
340 : : }
341 [ # # ]: 0 : aRet = p->getRequest();
342 : : }
343 : :
344 : : // if(aCommand.Name.compareToAscii(
345 : : // "getPropertyValues") == 0 &&
346 : : // action != NOACTION) {
347 : : // // It is not allowed to throw if
348 : : // // command is getPropertyValues
349 : : // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
350 : : // new ucbhelper::PropertyValueSet(m_xSMgr);
351 : : // Sequence<Property> Properties;
352 : : // aCommand.Argument >>= Properties;
353 : : // for(int i = 0; i < Properties.getLength(); ++i)
354 : : // xRow->appendVoid(Properties[i]);
355 : : // aRet <<= Reference<XRow>(xRow.get());
356 : : // return aRet;
357 : : // }
358 : :
359 [ + - - - : 4 : switch (action)
+ - - - ]
360 : : {
361 : : case NOACTION:
362 : 2 : break;
363 : :
364 : : case THROWAUTHENTICATIONREQUEST:
365 : : ucbhelper::cancelCommandExecution(
366 : : aRet,
367 [ # # ][ # # ]: 0 : Reference<XCommandEnvironment>(0));
368 : 0 : break;
369 : :
370 : : case THROWACCESSDENIED:
371 : : {
372 [ # # ]: 0 : Sequence<Any> seq(1);
373 : 0 : PropertyValue value;
374 : 0 : value.Name = rtl::OUString("Uri");
375 : 0 : value.Handle = -1;
376 [ # # ][ # # ]: 0 : value.Value <<= m_aFTPURL.ident(false,false);
377 : 0 : value.State = PropertyState_DIRECT_VALUE;
378 [ # # ][ # # ]: 0 : seq[0] <<= value;
379 : : ucbhelper::cancelCommandExecution(
380 : : IOErrorCode_ACCESS_DENIED,
381 : : seq,
382 [ # # ][ # # ]: 0 : Environment);
383 [ # # ]: 0 : break;
384 : : }
385 : : case THROWINTERACTIVECONNECT:
386 : : {
387 [ # # ]: 0 : InteractiveNetworkConnectException excep;
388 : 0 : excep.Server = m_aFTPURL.host();
389 [ # # ]: 0 : aRet <<= excep;
390 : : ucbhelper::cancelCommandExecution(
391 : : aRet,
392 [ # # ]: 0 : Environment);
393 [ # # ]: 0 : break;
394 : : }
395 : : case THROWRESOLVENAME:
396 : : {
397 [ + - ]: 2 : InteractiveNetworkResolveNameException excep;
398 : 2 : excep.Server = m_aFTPURL.host();
399 [ + - ]: 2 : aRet <<= excep;
400 : : ucbhelper::cancelCommandExecution(
401 : : aRet,
402 [ - + ]: 2 : Environment);
403 [ # # ]: 2 : break;
404 : : }
405 : : case THROWNOFILE:
406 : : {
407 [ # # ]: 0 : Sequence<Any> seq(1);
408 : 0 : PropertyValue value;
409 : 0 : value.Name = rtl::OUString("Uri");
410 : 0 : value.Handle = -1;
411 [ # # ][ # # ]: 0 : value.Value <<= m_aFTPURL.ident(false,false);
412 : 0 : value.State = PropertyState_DIRECT_VALUE;
413 [ # # ][ # # ]: 0 : seq[0] <<= value;
414 : : ucbhelper::cancelCommandExecution(
415 : : IOErrorCode_NO_FILE,
416 : : seq,
417 [ # # ][ # # ]: 0 : Environment);
418 [ # # ]: 0 : break;
419 : : }
420 : : case THROWQUOTE:
421 : : case THROWGENERAL:
422 : : ucbhelper::cancelCommandExecution(
423 : : IOErrorCode_GENERAL,
424 : : Sequence<Any>(0),
425 [ # # ][ # # ]: 0 : Environment);
[ # # ][ # # ]
426 : 0 : break;
427 : : }
428 : :
429 [ - + ]: 2 : if(aCommand.Name.compareToAscii("getPropertyValues") == 0) {
430 [ # # ]: 0 : Sequence<Property> Properties;
431 [ # # ][ # # ]: 0 : if(!(aCommand.Argument >>= Properties))
432 : : {
433 : : aRet <<= IllegalArgumentException(
434 : : rtl::OUString( "Wrong argument type!" ),
435 : : static_cast< cppu::OWeakObject * >(this),
436 [ # # ][ # # ]: 0 : -1);
[ # # ][ # # ]
437 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
438 : : }
439 : :
440 [ # # ][ # # ]: 0 : aRet <<= getPropertyValues(Properties,Environment);
[ # # ]
441 : : }
442 [ - + ]: 2 : else if(aCommand.Name.compareToAscii("setPropertyValues") == 0)
443 : : {
444 [ # # ]: 0 : Sequence<PropertyValue> propertyValues;
445 : :
446 [ # # ][ # # ]: 0 : if( ! ( aCommand.Argument >>= propertyValues ) ) {
447 : : aRet <<= IllegalArgumentException(
448 : : rtl::OUString( "Wrong argument type!" ),
449 : : static_cast< cppu::OWeakObject * >(this),
450 [ # # ][ # # ]: 0 : -1);
[ # # ][ # # ]
451 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
452 : : }
453 : :
454 [ # # ][ # # ]: 0 : aRet <<= setPropertyValues(propertyValues);
[ # # ][ # # ]
455 : : }
456 [ - + ]: 2 : else if(aCommand.Name.compareToAscii("getCommandInfo") == 0) {
457 : : // Note: Implemented by base class.
458 [ # # ][ # # ]: 0 : aRet <<= getCommandInfo(Environment);
459 : : }
460 [ - + ]: 2 : else if(aCommand.Name.compareToAscii("getPropertySetInfo") == 0) {
461 : : // Note: Implemented by base class.
462 [ # # ][ # # ]: 0 : aRet <<= getPropertySetInfo(Environment);
463 : : }
464 [ - + ]: 2 : else if(aCommand.Name.compareToAscii( "insert" ) == 0)
465 : : {
466 [ # # ]: 0 : InsertCommandArgument aInsertArgument;
467 [ # # ][ # # ]: 0 : if ( ! ( aCommand.Argument >>= aInsertArgument ) ) {
468 : : aRet <<= IllegalArgumentException(
469 : : rtl::OUString( "Wrong argument type!" ),
470 : : static_cast< cppu::OWeakObject * >(this),
471 [ # # ][ # # ]: 0 : -1);
[ # # ][ # # ]
472 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
473 : : }
474 [ # # ][ # # ]: 0 : insert(aInsertArgument,Environment);
475 : : }
476 [ - + ]: 2 : else if(aCommand.Name.compareToAscii("delete") == 0) {
477 [ # # ]: 0 : m_aFTPURL.del();
478 [ # # ]: 0 : deleted();
479 : : }
480 [ + - ]: 2 : else if(aCommand.Name.compareToAscii( "open" ) == 0) {
481 [ + - ]: 2 : OpenCommandArgument2 aOpenCommand;
482 [ + - ][ - + ]: 2 : if ( !( aCommand.Argument >>= aOpenCommand ) ) {
483 : : aRet <<= IllegalArgumentException(
484 : : rtl::OUString( "Wrong argument type!" ),
485 : : static_cast< cppu::OWeakObject * >(this),
486 [ # # ][ # # ]: 0 : -1);
[ # # ][ # # ]
487 : :
488 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
489 : : }
490 : :
491 [ - + ]: 2 : if(aOpenCommand.Mode == OpenMode::DOCUMENT) {
492 : : // Open as a document
493 : : Reference<XActiveDataSink>
494 [ # # ]: 0 : xActiveDataSink(aOpenCommand.Sink,UNO_QUERY);
495 : : Reference< XOutputStream >
496 [ # # ]: 0 : xOutputStream(aOpenCommand.Sink,UNO_QUERY);
497 : :
498 [ # # ]: 0 : if(xActiveDataSink.is()) {
499 [ # # ]: 0 : xActiveDataSink->setInputStream(
500 [ # # ][ # # ]: 0 : new ucbhelper::FdInputStream(m_aFTPURL.open()));
[ # # ][ # # ]
[ # # ]
501 : : }
502 [ # # ]: 0 : else if(xOutputStream.is()) {
503 : : Reference<XInputStream> xStream(
504 [ # # ][ # # ]: 0 : new ucbhelper::FdInputStream(m_aFTPURL.open()));
[ # # ][ # #
# # # # ]
505 [ # # ]: 0 : Sequence<sal_Int8> byte_seq(4096);
506 : 0 : sal_Int32 n = 1000; // value does not matter here
507 : 0 : for (;;) {
508 [ # # ][ # # ]: 0 : n = xStream->readBytes(byte_seq,4096);
509 [ # # ]: 0 : if (n == 0) {
510 : 0 : break;
511 : : }
512 : : try {
513 [ # # ]: 0 : if(byte_seq.getLength() != n)
514 [ # # ]: 0 : byte_seq.realloc(n);
515 [ # # ][ # # ]: 0 : xOutputStream->writeBytes(byte_seq);
516 [ # # ]: 0 : } catch(const NotConnectedException&) {
517 : :
518 [ # # ]: 0 : } catch(const BufferSizeExceededException&) {
519 : :
520 [ # # ]: 0 : } catch(const IOException&) {
521 : :
522 : : }
523 : : }
524 [ # # ]: 0 : if(n) {
525 [ # # ]: 0 : Sequence<Any> seq(1);
526 : 0 : PropertyValue value;
527 : 0 : value.Name = rtl::OUString("Uri");
528 : 0 : value.Handle = -1;
529 [ # # ][ # # ]: 0 : value.Value <<= m_aFTPURL.ident(false,false);
530 : 0 : value.State = PropertyState_DIRECT_VALUE;
531 [ # # ][ # # ]: 0 : seq[0] <<= value;
532 : : ucbhelper::cancelCommandExecution(
533 : : IOErrorCode_UNKNOWN,
534 : : seq,
535 [ # # ][ # # ]: 0 : Environment);
[ # # ]
536 [ # # ]: 0 : }
537 : : }
538 : : else {
539 : : aRet <<= UnsupportedDataSinkException(
540 : : rtl::OUString(),
541 : : static_cast< cppu::OWeakObject * >(this),
542 [ # # ][ # # ]: 0 : aOpenCommand.Sink);
[ # # ][ # # ]
543 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
544 : 0 : }
545 : : }
546 [ - + ][ # # ]: 2 : else if(aOpenCommand.Mode == OpenMode::ALL ||
[ # # ]
547 : : aOpenCommand.Mode == OpenMode::DOCUMENTS ||
548 : : aOpenCommand.Mode == OpenMode::FOLDERS ) {
549 : : std::vector<FTPDirentry> resvec =
550 [ - + ]: 2 : m_aFTPURL.list(sal_Int16(aOpenCommand.Mode));
551 : : Reference< XDynamicResultSet > xSet
552 : : = new DynamicResultSet(
553 : : m_xSMgr,
554 : : this,
555 : : aOpenCommand,
556 : : Environment,
557 : : new ResultSetFactoryI(m_xSMgr,
558 : 0 : m_xProvider.get(),
559 : : aOpenCommand.Mode,
560 : : aOpenCommand.Properties,
561 : : aOpenCommand.SortingInfo,
562 [ # # ][ # # ]: 0 : resvec));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
563 [ # # ]: 2 : aRet <<= xSet;
564 : : }
565 [ # # ][ # # ]: 0 : else if(aOpenCommand.Mode ==
566 : : OpenMode::DOCUMENT_SHARE_DENY_NONE ||
567 : : aOpenCommand.Mode ==
568 : : OpenMode::DOCUMENT_SHARE_DENY_WRITE) {
569 : : // Unsupported OpenMode
570 : : aRet <<= UnsupportedOpenModeException(
571 : : rtl::OUString(),
572 : : static_cast< cppu::OWeakObject * >(this),
573 [ # # ][ # # ]: 0 : static_cast< sal_Int16 >(aOpenCommand.Mode));
[ # # ][ # # ]
574 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
575 : : }
576 : : else {
577 : : aRet <<= IllegalArgumentException(
578 : : rtl::OUString( "Unexpected OpenMode!" ),
579 : : static_cast< cppu::OWeakObject * >(this),
580 [ # # ][ # # ]: 0 : -1);
[ # # ][ # # ]
581 : :
582 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
583 [ # # ]: 2 : }
584 [ # # ]: 0 : } else if(aCommand.Name.compareToAscii("createNewContent") == 0) {
585 [ # # ]: 0 : ContentInfo aArg;
586 [ # # ][ # # ]: 0 : if (!(aCommand.Argument >>= aArg)) {
587 : : ucbhelper::cancelCommandExecution(
588 : : makeAny(
589 : : IllegalArgumentException(
590 : : rtl::OUString( "Wrong argument type!" ),
591 : : static_cast< cppu::OWeakObject * >(this),
592 : : -1)),
593 [ # # ][ # # ]: 0 : Environment);
[ # # ][ # # ]
[ # # ]
594 : : // Unreachable
595 : : }
596 [ # # ][ # # ]: 0 : aRet <<= createNewContent(aArg);
[ # # ]
597 : : } else {
598 : : aRet <<= UnsupportedCommandException(
599 : : aCommand.Name,
600 [ # # ][ # # ]: 4 : static_cast< cppu::OWeakObject * >(this));
[ # # ][ # # ]
[ + + ]
601 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
602 : : }
603 : :
604 : 0 : return aRet;
605 : 4 : } catch(const curl_exception& e) {
606 [ - + ]: 2 : if(e.code() == CURLE_COULDNT_CONNECT)
607 : 0 : action = THROWINTERACTIVECONNECT;
608 [ + - ]: 2 : else if(e.code() == CURLE_COULDNT_RESOLVE_HOST )
609 : 2 : action = THROWRESOLVENAME;
610 [ # # # # : 0 : else if(e.code() == CURLE_FTP_USER_PASSWORD_INCORRECT ||
# # # # #
# ]
611 : 0 : e.code() == CURLE_LOGIN_DENIED ||
612 : 0 : e.code() == CURLE_BAD_PASSWORD_ENTERED ||
613 : 0 : e.code() == CURLE_FTP_WEIRD_PASS_REPLY)
614 : 0 : action = THROWAUTHENTICATIONREQUEST;
615 [ # # ]: 0 : else if(e.code() == CURLE_FTP_ACCESS_DENIED)
616 : 0 : action = THROWACCESSDENIED;
617 [ # # ]: 0 : else if(e.code() == CURLE_FTP_QUOTE_ERROR)
618 : 0 : action = THROWQUOTE;
619 [ # # ]: 0 : else if(e.code() == CURLE_FTP_COULDNT_RETR_FILE)
620 : 0 : action = THROWNOFILE;
621 : : else
622 : : // nothing known about the cause of the error
623 : 0 : action = THROWGENERAL;
624 : 2 : }
625 : : }
626 : :
627 : : #define FTP_FILE rtl::OUString( "application/vnd.sun.staroffice.ftp-file")
628 : :
629 : : #define FTP_FOLDER rtl::OUString( "application/vnd.sun.staroffice.ftp-folder")
630 : :
631 : : Sequence<ContentInfo > SAL_CALL
632 : 0 : FTPContent::queryCreatableContentsInfo( )
633 : : throw (RuntimeException)
634 : : {
635 : 0 : return queryCreatableContentsInfo_Static();
636 : : }
637 : :
638 : : // static
639 : : Sequence<ContentInfo >
640 : 0 : FTPContent::queryCreatableContentsInfo_Static( )
641 : : throw (RuntimeException)
642 : : {
643 [ # # ]: 0 : Sequence< ContentInfo > seq(2);
644 : :
645 [ # # ]: 0 : seq[0].Type = FTP_FILE;
646 [ # # ]: 0 : seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
647 : 0 : | ContentInfoAttribute::KIND_DOCUMENT;
648 [ # # ]: 0 : Sequence< Property > props( 1 );
649 [ # # ]: 0 : props[0] = Property(
650 : : rtl::OUString("Title"),
651 : : -1,
652 [ # # ]: 0 : getCppuType( static_cast< rtl::OUString* >( 0 ) ),
653 : : PropertyAttribute::MAYBEVOID
654 : 0 : | PropertyAttribute::BOUND );
655 [ # # ][ # # ]: 0 : seq[0].Properties = props;
656 : :
657 : : // folder
658 [ # # ]: 0 : seq[1].Type = FTP_FOLDER;
659 [ # # ]: 0 : seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
660 [ # # ][ # # ]: 0 : seq[1].Properties = props;
661 : :
662 [ # # ]: 0 : return seq;
663 : : }
664 : :
665 : : Reference<XContent > SAL_CALL
666 : 0 : FTPContent::createNewContent( const ContentInfo& Info )
667 : : throw (RuntimeException)
668 : : {
669 [ # # ][ # # ]: 0 : if( Info.Type =="application/vnd.sun.staroffice.ftp-file" || Info.Type == "application/vnd.sun.staroffice.ftp-folder" )
[ # # ]
670 : : return new FTPContent(m_xSMgr,
671 : : m_pFCP,
672 [ # # ][ # # ]: 0 : m_xIdentifier,Info);
673 : : else
674 : 0 : return Reference<XContent>(0);
675 : : }
676 : :
677 : :
678 : :
679 : :
680 : : Reference<XInterface > SAL_CALL
681 : 0 : FTPContent::getParent( )
682 : : throw (RuntimeException)
683 : : {
684 : : Reference<XContentIdentifier>
685 [ # # ][ # # ]: 0 : xIdent(new FTPContentIdentifier(m_aFTPURL.parent(false)));
[ # # ][ # # ]
686 [ # # ]: 0 : Reference<XContent> xContent(m_xProvider->queryContent(xIdent));
687 [ # # ]: 0 : return Reference<XInterface>(xContent,UNO_QUERY);
688 : : }
689 : :
690 : :
691 : : void SAL_CALL
692 : 0 : FTPContent::setParent(const Reference<XInterface >& /*Parent*/ )
693 : : throw (NoSupportException,
694 : : RuntimeException)
695 : : {
696 [ # # ]: 0 : throw NoSupportException();
697 : : }
698 : :
699 : :
700 : :
701 : 0 : rtl::OUString FTPContent::getParentURL()
702 : : {
703 : 0 : return m_aFTPURL.parent();
704 : : }
705 : :
706 : :
707 : : class InsertData
708 : : : public CurlInput {
709 : :
710 : : public:
711 : :
712 : 0 : InsertData(const Reference<XInputStream>& xInputStream)
713 : 0 : : m_xInputStream(xInputStream) { }
714 [ # # ]: 0 : virtual ~InsertData() {}
715 : :
716 : : // returns the number of bytes actually read
717 : : virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested);
718 : :
719 : : private:
720 : :
721 : : Reference<XInputStream> m_xInputStream;
722 : : };
723 : :
724 : :
725 : :
726 : 0 : sal_Int32 InsertData::read(sal_Int8 *dest,sal_Int32 nBytesRequested)
727 : : {
728 : 0 : sal_Int32 m = 0;
729 : :
730 [ # # ]: 0 : if(m_xInputStream.is()) {
731 [ # # ]: 0 : Sequence<sal_Int8> seq(nBytesRequested);
732 [ # # ][ # # ]: 0 : m = m_xInputStream->readBytes(seq,nBytesRequested);
733 [ # # ][ # # ]: 0 : rtl_copyMemory(dest,seq.getConstArray(),m);
734 : : }
735 : 0 : return m;
736 : : }
737 : :
738 : :
739 : 0 : void FTPContent::insert(const InsertCommandArgument& aInsertCommand,
740 : : const Reference<XCommandEnvironment>& Env)
741 : : {
742 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
743 : :
744 [ # # ][ # # ]: 0 : if(m_bInserted && !m_bTitleSet) {
745 [ # # ]: 0 : MissingPropertiesException excep;
746 [ # # ]: 0 : excep.Properties.realloc(1);
747 [ # # ]: 0 : excep.Properties[0] = rtl::OUString("Title");
748 [ # # ]: 0 : Any aAny; aAny <<= excep;
749 [ # # ][ # # ]: 0 : ucbhelper::cancelCommandExecution(aAny,Env);
750 : : }
751 : :
752 [ # # # # : 0 : if(m_bInserted &&
# # ][ # # ]
753 [ # # ][ # # ]: 0 : m_aInfo.Type == FTP_FILE &&
754 : 0 : !aInsertCommand.Data.is())
755 : : {
756 [ # # ]: 0 : MissingInputStreamException excep;
757 [ # # ]: 0 : Any aAny; aAny <<= excep;
758 [ # # ][ # # ]: 0 : ucbhelper::cancelCommandExecution(aAny,Env);
759 : : }
760 : :
761 : 0 : bool bReplace(aInsertCommand.ReplaceExisting);
762 : :
763 : : retry:
764 : : try {
765 [ # # ]: 0 : if(m_aInfo.Type == FTP_FILE) {
766 [ # # ]: 0 : InsertData data(aInsertCommand.Data);
767 [ # # ][ # # ]: 0 : m_aFTPURL.insert(bReplace,&data);
768 [ # # ]: 0 : } else if(m_aInfo.Type == FTP_FOLDER)
769 [ # # ]: 0 : m_aFTPURL.mkdir(bReplace);
770 [ # # # # ]: 0 : } catch(const curl_exception& e) {
771 [ # # # # : 0 : if(e.code() == FILE_EXIST_DURING_INSERT ||
# # ]
772 : 0 : e.code() == FOLDER_EXIST_DURING_INSERT) {
773 : : // Deprecated, not used anymore:
774 [ # # ]: 0 : NameClashException excep;
775 [ # # ]: 0 : excep.Name = m_aFTPURL.child();
776 : 0 : Any aAny;
777 [ # # ]: 0 : aAny <<= excep;
778 [ # # # # ]: 0 : ucbhelper::cancelCommandExecution(aAny,Env);
779 [ # # # # : 0 : } else if(e.code() == FOLDER_MIGHT_EXIST_DURING_INSERT ||
# # ]
780 : 0 : e.code() == FILE_MIGHT_EXIST_DURING_INSERT) {
781 : : // Interact
782 : 0 : Reference<XInteractionHandler> xInt;
783 [ # # ]: 0 : if(Env.is())
784 [ # # # # : 0 : xInt = Env->getInteractionHandler();
# # ]
785 : :
786 [ # # ]: 0 : UnsupportedNameClashException excep;
787 : 0 : excep.NameClash = 0; //NameClash::ERROR;
788 : :
789 [ # # ]: 0 : if(!xInt.is()) {
790 : 0 : Any aAny;
791 [ # # ]: 0 : aAny <<= excep;
792 [ # # ]: 0 : ucbhelper::cancelCommandExecution(aAny,Env);
793 : : }
794 : :
795 : : XInteractionRequestImpl* p =
796 [ # # # # ]: 0 : new XInteractionRequestImpl(m_aFTPURL.child());
797 [ # # # # ]: 0 : Reference<XInteractionRequest> req(p);
798 [ # # # # ]: 0 : xInt->handle(req);
799 [ # # # # ]: 0 : if(p->approved()) {
800 : 0 : bReplace = true;
801 : : goto retry;
802 : : }
803 : : else
804 [ # # # # ]: 0 : throw excep;
805 : : }
806 : : else
807 : 0 : throw;
808 : : }
809 : :
810 : : // May not be reached, because both mkdir and insert can throw curl-
811 : : // exceptions
812 : 0 : m_bInserted = false;
813 [ # # ][ # # ]: 0 : inserted();
814 : 0 : }
815 : :
816 : :
817 : :
818 : 0 : Reference< XRow > FTPContent::getPropertyValues(
819 : : const Sequence< Property >& seqProp,
820 : : const Reference<XCommandEnvironment>& /*environment*/
821 : : )
822 : : {
823 : : rtl::Reference<ucbhelper::PropertyValueSet> xRow =
824 [ # # ]: 0 : new ucbhelper::PropertyValueSet(m_xSMgr);
825 : :
826 [ # # ]: 0 : FTPDirentry aDirEntry = m_aFTPURL.direntry();
827 : :
828 [ # # ]: 0 : for(sal_Int32 i = 0; i < seqProp.getLength(); ++i) {
829 : 0 : const rtl::OUString& Name = seqProp[i].Name;
830 [ # # ]: 0 : if(Name.compareToAscii("Title") == 0)
831 [ # # ]: 0 : xRow->appendString(seqProp[i],aDirEntry.m_aName);
832 [ # # ]: 0 : else if(Name.compareToAscii("CreatableContentsInfo") == 0)
833 : 0 : xRow->appendObject(seqProp[i],
834 [ # # ]: 0 : makeAny(queryCreatableContentsInfo()));
[ # # # # ]
[ # # ]
835 [ # # ]: 0 : else if(aDirEntry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN) {
836 [ # # ]: 0 : if(Name.compareToAscii("ContentType") == 0)
837 : 0 : xRow->appendString(seqProp[i],
838 : : aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR
839 : : ? FTP_FOLDER
840 [ # # ][ # # ]: 0 : : FTP_FILE );
[ # # ][ # # ]
[ # # # # ]
841 [ # # ]: 0 : else if(Name.compareToAscii("IsReadOnly") == 0)
842 : 0 : xRow->appendBoolean(seqProp[i],
843 : : aDirEntry.m_nMode
844 : : & INETCOREFTP_FILEMODE_WRITE
845 : : ? 0
846 [ # # ]: 0 : : 1 );
847 [ # # ]: 0 : else if(Name.compareToAscii("IsDocument") == 0)
848 : 0 : xRow->appendBoolean(seqProp[i],
849 : : ! sal_Bool(aDirEntry.m_nMode &
850 [ # # ]: 0 : INETCOREFTP_FILEMODE_ISDIR));
851 [ # # ]: 0 : else if(Name.compareToAscii("IsFolder") == 0)
852 : 0 : xRow->appendBoolean(seqProp[i],
853 : : sal_Bool(aDirEntry.m_nMode &
854 [ # # ]: 0 : INETCOREFTP_FILEMODE_ISDIR));
855 [ # # ]: 0 : else if(Name.compareToAscii("Size") == 0)
856 : 0 : xRow->appendLong(seqProp[i],
857 [ # # ]: 0 : aDirEntry.m_nSize);
858 [ # # ]: 0 : else if(Name.compareToAscii("DateCreated") == 0)
859 : 0 : xRow->appendTimestamp(seqProp[i],
860 [ # # ]: 0 : aDirEntry.m_aDate);
861 : : else
862 [ # # ]: 0 : xRow->appendVoid(seqProp[i]);
863 : : } else
864 [ # # ]: 0 : xRow->appendVoid(seqProp[i]);
865 : : }
866 : :
867 [ # # ][ # # ]: 0 : return Reference<XRow>(xRow.get());
868 : : }
869 : :
870 : :
871 : :
872 : 0 : Sequence<Any> FTPContent::setPropertyValues(
873 : : const Sequence<PropertyValue>& seqPropVal)
874 : : {
875 [ # # ]: 0 : Sequence<Any> ret(seqPropVal.getLength());
876 [ # # ]: 0 : Sequence<PropertyChangeEvent > evt;
877 : :
878 [ # # ]: 0 : osl::MutexGuard aGuard(m_aMutex);
879 [ # # ]: 0 : for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
880 [ # # ]: 0 : if ( seqPropVal[i].Name == "Title" ) {
881 : 0 : rtl::OUString Title;
882 [ # # ]: 0 : if(!(seqPropVal[i].Value >>= Title)) {
883 [ # # ][ # # ]: 0 : ret[i] <<= IllegalTypeException();
[ # # ][ # # ]
884 : 0 : continue;
885 [ # # ]: 0 : } else if(Title.isEmpty()) {
886 [ # # ][ # # ]: 0 : ret[i] <<= IllegalArgumentException();
[ # # ][ # # ]
887 : 0 : continue;
888 : : }
889 : :
890 [ # # ]: 0 : if(m_bInserted) {
891 [ # # ]: 0 : m_aFTPURL.child(Title);
892 : : m_xIdentifier =
893 [ # # ][ # # ]: 0 : new FTPContentIdentifier(m_aFTPURL.ident(false,false));
[ # # ][ # # ]
894 : 0 : m_bTitleSet = true;
895 : : } else
896 : : try {
897 [ # # ]: 0 : rtl::OUString OldTitle = m_aFTPURL.ren(Title);
898 [ # # ]: 0 : evt.realloc(1);
899 [ # # ]: 0 : evt[0].PropertyName =
900 : 0 : rtl::OUString("Title");
901 [ # # ]: 0 : evt[0].Further = false;
902 [ # # ]: 0 : evt[0].PropertyHandle = -1;
903 [ # # ][ # # ]: 0 : evt[0].OldValue <<= OldTitle;
904 [ # # ][ # # ]: 0 : evt[0].NewValue <<= Title;
905 [ # # ]: 0 : } catch(const curl_exception&) {
906 [ # # ]: 0 : InteractiveIOException excep;
907 : : // any better possibility here?
908 : : // ( the error code is always CURLE_FTP_QUOTE_ERROR )
909 : 0 : excep.Code = IOErrorCode_ACCESS_DENIED;
910 [ # # # # : 0 : ret[i] <<= excep;
# # ]
911 [ # # ]: 0 : }
912 : : } else {
913 : : Sequence<Property> props =
914 [ # # ][ # # ]: 0 : getProperties(Reference<XCommandEnvironment>(0));
915 : :
916 : : // either unknown or read-only
917 [ # # ][ # # ]: 0 : ret[i] <<= UnknownPropertyException();
[ # # ][ # # ]
918 [ # # ]: 0 : for(sal_Int32 j = 0; j < props.getLength(); ++j)
919 [ # # ][ # # ]: 0 : if(props[j].Name == seqPropVal[i].Name) {
920 [ # # ]: 0 : ret[i] <<= IllegalAccessException(
921 : : rtl::OUString( "Property is read-only!"),
922 : : //props[j].Attributes & PropertyAttribute::READONLY
923 : : // ? "Property is read-only!"
924 : : // : "Access denied!"),
925 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >( this ));
[ # # ][ # # ]
926 : 0 : break;
927 [ # # ]: 0 : }
928 : : }
929 : : }
930 : :
931 [ # # ]: 0 : if(evt.getLength()) {
932 : : // title has changed
933 [ # # ]: 0 : notifyPropertiesChange(evt);
934 [ # # ][ # # ]: 0 : exchange(new FTPContentIdentifier(m_aFTPURL.ident(false,false)));
[ # # ][ # # ]
[ # # ]
935 : : }
936 : :
937 [ # # ][ # # ]: 0 : return ret;
938 : : }
939 : :
940 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|