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