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 #include <string.h>
27*b1cdbd2cSJim Jagielski #include <unistd.h>
28*b1cdbd2cSJim Jagielski #include <sys/types.h>
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski #include "osl/time.h"
31*b1cdbd2cSJim Jagielski #include <osl/diagnose.h>
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski #include "osl/doublecheckedlocking.h"
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyValue.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyAttribute.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertySetInfoChange.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/io/XActiveDataSink.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/io/XOutputStream.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/IllegalAccessException.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InsertCommandArgument.hpp>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
45*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
46*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
47*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
48*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
49*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
50*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
51*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/NameClash.hpp>
52*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/NameClashException.hpp>
53*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
54*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/OpenMode.hpp>
55*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/PostCommandArgument2.hpp>
56*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/TransferInfo.hpp>
57*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/XCommandInfo.hpp>
58*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
59*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/MissingInputStreamException.hpp>
60*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/MissingPropertiesException.hpp>
61*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
62*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
63*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
64*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
65*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
66*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/NameClashException.hpp>
67*b1cdbd2cSJim Jagielski #include <ucbhelper/contentidentifier.hxx>
68*b1cdbd2cSJim Jagielski #include <ucbhelper/propertyvalueset.hxx>
69*b1cdbd2cSJim Jagielski #include <ucbhelper/interactionrequest.hxx>
70*b1cdbd2cSJim Jagielski #include <ucbhelper/cancelcommandexecution.hxx>
71*b1cdbd2cSJim Jagielski #include <ucbhelper/simpleauthenticationrequest.hxx>
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski const int TRANSFER_BUFFER_SIZE = 65536;
74*b1cdbd2cSJim Jagielski 
75*b1cdbd2cSJim Jagielski /*
76*b1cdbd2cSJim Jagielski  * NB. Name escaping is done only for URIs
77*b1cdbd2cSJim Jagielski  * the 'Title' property is unescaped on set/get
78*b1cdbd2cSJim Jagielski  */
79*b1cdbd2cSJim Jagielski #include <libgnomevfs/gnome-vfs-utils.h>
80*b1cdbd2cSJim Jagielski #include <libgnomevfs/gnome-vfs-result.h>
81*b1cdbd2cSJim Jagielski #include <libgnomevfs/gnome-vfs-standard-callbacks.h>
82*b1cdbd2cSJim Jagielski extern "C" { // missing in the header: doh.
83*b1cdbd2cSJim Jagielski #  include <libgnomevfs/gnome-vfs-module-callback.h>
84*b1cdbd2cSJim Jagielski }
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski #include "gvfs_content.hxx"
87*b1cdbd2cSJim Jagielski #include "gvfs_provider.hxx"
88*b1cdbd2cSJim Jagielski #include "gvfs_directory.hxx"
89*b1cdbd2cSJim Jagielski #include "gvfs_stream.hxx"
90*b1cdbd2cSJim Jagielski 
91*b1cdbd2cSJim Jagielski using namespace gvfs;
92*b1cdbd2cSJim Jagielski using namespace com::sun::star;
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski #define CLEAR_INFO(info) memset((info), 0, sizeof ((info)[0]))
95*b1cdbd2cSJim Jagielski 
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski static char *
OUStringToGnome(const rtl::OUString & str)98*b1cdbd2cSJim Jagielski OUStringToGnome( const rtl::OUString &str )
99*b1cdbd2cSJim Jagielski {
100*b1cdbd2cSJim Jagielski     rtl::OString aTempStr = rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 );
101*b1cdbd2cSJim Jagielski     return g_strdup( aTempStr.getStr() );
102*b1cdbd2cSJim Jagielski }
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski static rtl::OUString
GnomeToOUString(const char * utf8_str)105*b1cdbd2cSJim Jagielski GnomeToOUString( const char *utf8_str)
106*b1cdbd2cSJim Jagielski {
107*b1cdbd2cSJim Jagielski     if (!utf8_str)
108*b1cdbd2cSJim Jagielski         return rtl::OUString();
109*b1cdbd2cSJim Jagielski     else
110*b1cdbd2cSJim Jagielski         return rtl::OUString( utf8_str, strlen( utf8_str ), RTL_TEXTENCODING_UTF8 );
111*b1cdbd2cSJim Jagielski }
112*b1cdbd2cSJim Jagielski 
113*b1cdbd2cSJim Jagielski 
Content(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,ContentProvider * pProvider,const uno::Reference<ucb::XContentIdentifier> & Identifier)114*b1cdbd2cSJim Jagielski Content::Content(
115*b1cdbd2cSJim Jagielski           const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
116*b1cdbd2cSJim Jagielski           ContentProvider* pProvider,
117*b1cdbd2cSJim Jagielski           const uno::Reference< ucb::XContentIdentifier >& Identifier)
118*b1cdbd2cSJim Jagielski   throw ( ucb::ContentCreationException )
119*b1cdbd2cSJim Jagielski     : ContentImplHelper( rxSMgr, pProvider, Identifier ),
120*b1cdbd2cSJim Jagielski       m_pProvider( pProvider ),
121*b1cdbd2cSJim Jagielski       m_bTransient( sal_False )
122*b1cdbd2cSJim Jagielski {
123*b1cdbd2cSJim Jagielski     CLEAR_INFO (&m_info);
124*b1cdbd2cSJim Jagielski #ifdef DEBUG
125*b1cdbd2cSJim Jagielski     g_warning ("New Content ('%s')", getURI());
126*b1cdbd2cSJim Jagielski #endif
127*b1cdbd2cSJim Jagielski }
128*b1cdbd2cSJim Jagielski 
Content(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,ContentProvider * pProvider,const uno::Reference<ucb::XContentIdentifier> & Identifier,sal_Bool IsFolder)129*b1cdbd2cSJim Jagielski Content::Content(
130*b1cdbd2cSJim Jagielski     const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
131*b1cdbd2cSJim Jagielski     ContentProvider                                   * pProvider,
132*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XContentIdentifier >&    Identifier,
133*b1cdbd2cSJim Jagielski     sal_Bool                                            IsFolder)
134*b1cdbd2cSJim Jagielski         throw ( ucb::ContentCreationException )
135*b1cdbd2cSJim Jagielski     : ContentImplHelper( rxSMgr, pProvider, Identifier ),
136*b1cdbd2cSJim Jagielski       m_pProvider( pProvider ),
137*b1cdbd2cSJim Jagielski       m_bTransient( sal_True )
138*b1cdbd2cSJim Jagielski {
139*b1cdbd2cSJim Jagielski     CLEAR_INFO (&m_info);
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski #ifdef DEBUG
142*b1cdbd2cSJim Jagielski     g_warning ("New Transient content ('%s') (%d)", getURI(), IsFolder);
143*b1cdbd2cSJim Jagielski #endif
144*b1cdbd2cSJim Jagielski //	m_info.name = FIXME: set name ?
145*b1cdbd2cSJim Jagielski     m_info.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE;
146*b1cdbd2cSJim Jagielski     m_info.type = IsFolder ? GNOME_VFS_FILE_TYPE_DIRECTORY :
147*b1cdbd2cSJim Jagielski                          GNOME_VFS_FILE_TYPE_REGULAR;
148*b1cdbd2cSJim Jagielski }
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski // virtual
~Content()151*b1cdbd2cSJim Jagielski Content::~Content()
152*b1cdbd2cSJim Jagielski {
153*b1cdbd2cSJim Jagielski     gnome_vfs_file_info_clear( &m_info );
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski //
157*b1cdbd2cSJim Jagielski // XInterface methods.
158*b1cdbd2cSJim Jagielski //
159*b1cdbd2cSJim Jagielski 
acquire()160*b1cdbd2cSJim Jagielski void SAL_CALL Content::acquire()
161*b1cdbd2cSJim Jagielski     throw( )
162*b1cdbd2cSJim Jagielski {
163*b1cdbd2cSJim Jagielski     ContentImplHelper::acquire();
164*b1cdbd2cSJim Jagielski }
release()165*b1cdbd2cSJim Jagielski void SAL_CALL Content::release()
166*b1cdbd2cSJim Jagielski     throw( )
167*b1cdbd2cSJim Jagielski {
168*b1cdbd2cSJim Jagielski     ContentImplHelper::release();
169*b1cdbd2cSJim Jagielski }
queryInterface(const uno::Type & rType)170*b1cdbd2cSJim Jagielski uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
171*b1cdbd2cSJim Jagielski     throw ( uno::RuntimeException )
172*b1cdbd2cSJim Jagielski {
173*b1cdbd2cSJim Jagielski     // Note: isFolder may require network activities! So call it only
174*b1cdbd2cSJim Jagielski     //       if it is really necessary!!!
175*b1cdbd2cSJim Jagielski     uno::Any aRet = cppu::queryInterface( rType,
176*b1cdbd2cSJim Jagielski                         static_cast< ucb::XContentCreator * >( this ) );
177*b1cdbd2cSJim Jagielski     if ( aRet.hasValue() )
178*b1cdbd2cSJim Jagielski             return isFolder( uno::Reference< ucb::XCommandEnvironment >() )
179*b1cdbd2cSJim Jagielski             ? aRet : uno::Any();
180*b1cdbd2cSJim Jagielski     else
181*b1cdbd2cSJim Jagielski         return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
182*b1cdbd2cSJim Jagielski }
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski //
185*b1cdbd2cSJim Jagielski // XTypeProvider methods.
186*b1cdbd2cSJim Jagielski //
187*b1cdbd2cSJim Jagielski 
188*b1cdbd2cSJim Jagielski XTYPEPROVIDER_COMMON_IMPL( Content );
189*b1cdbd2cSJim Jagielski 
getTypes()190*b1cdbd2cSJim Jagielski uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
191*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
192*b1cdbd2cSJim Jagielski {
193*b1cdbd2cSJim Jagielski     static cppu::OTypeCollection *pFolderCollection = NULL;
194*b1cdbd2cSJim Jagielski     static cppu::OTypeCollection *pFileCollection = NULL;
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski     if (!pFolderCollection) {
197*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
198*b1cdbd2cSJim Jagielski 
199*b1cdbd2cSJim Jagielski         if (!pFolderCollection) {
200*b1cdbd2cSJim Jagielski             static cppu::OTypeCollection aFolderCollection
201*b1cdbd2cSJim Jagielski                 (CPPU_TYPE_REF( lang::XTypeProvider ),
202*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( lang::XServiceInfo ),
203*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( lang::XComponent ),
204*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XContent ),
205*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
206*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
207*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
208*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertyContainer ),
209*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
210*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( container::XChild ),
211*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
212*b1cdbd2cSJim Jagielski             static cppu::OTypeCollection aFileCollection
213*b1cdbd2cSJim Jagielski                 (CPPU_TYPE_REF( lang::XTypeProvider ),
214*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( lang::XServiceInfo ),
215*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( lang::XComponent ),
216*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XContent ),
217*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
218*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
219*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
220*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertyContainer ),
221*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
222*b1cdbd2cSJim Jagielski                  CPPU_TYPE_REF( container::XChild ) );
223*b1cdbd2cSJim Jagielski 
224*b1cdbd2cSJim Jagielski             pFolderCollection = &aFolderCollection;
225*b1cdbd2cSJim Jagielski             pFileCollection = &aFileCollection;
226*b1cdbd2cSJim Jagielski             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
227*b1cdbd2cSJim Jagielski         }
228*b1cdbd2cSJim Jagielski     }
229*b1cdbd2cSJim Jagielski     else {
230*b1cdbd2cSJim Jagielski         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
231*b1cdbd2cSJim Jagielski     }
232*b1cdbd2cSJim Jagielski 
233*b1cdbd2cSJim Jagielski     if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
234*b1cdbd2cSJim Jagielski         return pFolderCollection->getTypes();
235*b1cdbd2cSJim Jagielski     else
236*b1cdbd2cSJim Jagielski         return pFileCollection->getTypes();
237*b1cdbd2cSJim Jagielski }
238*b1cdbd2cSJim Jagielski 
239*b1cdbd2cSJim Jagielski //
240*b1cdbd2cSJim Jagielski // XServiceInfo methods.
241*b1cdbd2cSJim Jagielski //
242*b1cdbd2cSJim Jagielski 
getImplementationName()243*b1cdbd2cSJim Jagielski rtl::OUString SAL_CALL Content::getImplementationName()
244*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
245*b1cdbd2cSJim Jagielski {
246*b1cdbd2cSJim Jagielski     return rtl::OUString::createFromAscii("com.sun.star.comp.GnomeVFSContent" );
247*b1cdbd2cSJim Jagielski }
248*b1cdbd2cSJim Jagielski 
getSupportedServiceNames()249*b1cdbd2cSJim Jagielski uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
250*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
251*b1cdbd2cSJim Jagielski {
252*b1cdbd2cSJim Jagielski     uno::Sequence< rtl::OUString > aSNS( 1 );
253*b1cdbd2cSJim Jagielski     aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
254*b1cdbd2cSJim Jagielski         "com.sun.star.ucb.GnomeVFSContent" );
255*b1cdbd2cSJim Jagielski     return aSNS;
256*b1cdbd2cSJim Jagielski }
257*b1cdbd2cSJim Jagielski 
258*b1cdbd2cSJim Jagielski //
259*b1cdbd2cSJim Jagielski // XContent methods.
260*b1cdbd2cSJim Jagielski //
261*b1cdbd2cSJim Jagielski 
getContentType()262*b1cdbd2cSJim Jagielski rtl::OUString SAL_CALL Content::getContentType()
263*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski     if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
266*b1cdbd2cSJim Jagielski         return rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
267*b1cdbd2cSJim Jagielski     else
268*b1cdbd2cSJim Jagielski         return rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
269*b1cdbd2cSJim Jagielski }
270*b1cdbd2cSJim Jagielski 
271*b1cdbd2cSJim Jagielski //
272*b1cdbd2cSJim Jagielski // XCommandProcessor methods.
273*b1cdbd2cSJim Jagielski //
274*b1cdbd2cSJim Jagielski 
getBadArgExcept()275*b1cdbd2cSJim Jagielski uno::Any Content::getBadArgExcept()
276*b1cdbd2cSJim Jagielski {
277*b1cdbd2cSJim Jagielski     return uno::makeAny( lang::IllegalArgumentException
278*b1cdbd2cSJim Jagielski                  ( rtl::OUString::createFromAscii( "Wrong argument type!" ),
279*b1cdbd2cSJim Jagielski                    static_cast< cppu::OWeakObject * >( this ),
280*b1cdbd2cSJim Jagielski                    -1 ) );
281*b1cdbd2cSJim Jagielski }
282*b1cdbd2cSJim Jagielski 
283*b1cdbd2cSJim Jagielski #include <stdio.h>
284*b1cdbd2cSJim Jagielski 
execute(const ucb::Command & aCommand,sal_Int32,const uno::Reference<ucb::XCommandEnvironment> & xEnv)285*b1cdbd2cSJim Jagielski uno::Any SAL_CALL Content::execute(
286*b1cdbd2cSJim Jagielski         const ucb::Command& aCommand,
287*b1cdbd2cSJim Jagielski         sal_Int32 /*CommandId*/,
288*b1cdbd2cSJim Jagielski         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
289*b1cdbd2cSJim Jagielski     throw( uno::Exception,
290*b1cdbd2cSJim Jagielski            ucb::CommandAbortedException,
291*b1cdbd2cSJim Jagielski            uno::RuntimeException )
292*b1cdbd2cSJim Jagielski {
293*b1cdbd2cSJim Jagielski     uno::Any aRet;
294*b1cdbd2cSJim Jagielski 
295*b1cdbd2cSJim Jagielski #ifdef DEBUG
296*b1cdbd2cSJim Jagielski     {
297*b1cdbd2cSJim Jagielski         uno::Reference< task::XInteractionHandler > xIH;
298*b1cdbd2cSJim Jagielski 
299*b1cdbd2cSJim Jagielski         if ( xEnv.is() )
300*b1cdbd2cSJim Jagielski             xIH = xEnv->getInteractionHandler();
301*b1cdbd2cSJim Jagielski         g_warning( "Execute command: '%s' with %s interaction env",
302*b1cdbd2cSJim Jagielski                OUStringToGnome( aCommand.Name ),
303*b1cdbd2cSJim Jagielski                xIH.is() ? "" : "NO" );
304*b1cdbd2cSJim Jagielski     }
305*b1cdbd2cSJim Jagielski #endif
306*b1cdbd2cSJim Jagielski 
307*b1cdbd2cSJim Jagielski #define COMMAND_IS(cmd,name) ( (cmd).Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( name ) ) )
308*b1cdbd2cSJim Jagielski 
309*b1cdbd2cSJim Jagielski     if ( COMMAND_IS( aCommand, "getPropertyValues" ) ) {
310*b1cdbd2cSJim Jagielski         uno::Sequence< beans::Property > Properties;
311*b1cdbd2cSJim Jagielski 
312*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= Properties ) )
313*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski         aRet <<= getPropertyValues( Properties, xEnv );
316*b1cdbd2cSJim Jagielski 
317*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "setPropertyValues" ) ) {
318*b1cdbd2cSJim Jagielski         uno::Sequence< beans::PropertyValue > aProperties;
319*b1cdbd2cSJim Jagielski 
320*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= aProperties ) ||
321*b1cdbd2cSJim Jagielski              !aProperties.getLength() )
322*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
323*b1cdbd2cSJim Jagielski 
324*b1cdbd2cSJim Jagielski         aRet <<= setPropertyValues( aProperties, xEnv );
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "getPropertySetInfo" ) ) {
327*b1cdbd2cSJim Jagielski         aRet <<= getPropertySetInfo( xEnv, sal_False );
328*b1cdbd2cSJim Jagielski 
329*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "getCommandInfo" ) ) {
330*b1cdbd2cSJim Jagielski         aRet <<= getCommandInfo( xEnv, sal_False );
331*b1cdbd2cSJim Jagielski 
332*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "open" ) ) {
333*b1cdbd2cSJim Jagielski         rtl::OUString str = m_xIdentifier->getContentIdentifier();
334*b1cdbd2cSJim Jagielski         rtl::OString stra(
335*b1cdbd2cSJim Jagielski             str.getStr(),
336*b1cdbd2cSJim Jagielski             str.getLength(),
337*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_UTF8);
338*b1cdbd2cSJim Jagielski 
339*b1cdbd2cSJim Jagielski         ucb::OpenCommandArgument2 aOpenCommand;
340*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= aOpenCommand ) )
341*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
342*b1cdbd2cSJim Jagielski 
343*b1cdbd2cSJim Jagielski         sal_Bool bOpenFolder =
344*b1cdbd2cSJim Jagielski             ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) ||
345*b1cdbd2cSJim Jagielski               ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
346*b1cdbd2cSJim Jagielski               ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) );
347*b1cdbd2cSJim Jagielski 
348*b1cdbd2cSJim Jagielski         if ( bOpenFolder && isFolder( xEnv ) ) {
349*b1cdbd2cSJim Jagielski             uno::Reference< ucb::XDynamicResultSet > xSet
350*b1cdbd2cSJim Jagielski                 = new DynamicResultSet(m_xSMgr, this, aOpenCommand, xEnv );
351*b1cdbd2cSJim Jagielski             aRet <<= xSet;
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski         } else if ( aOpenCommand.Sink.is() ) {
354*b1cdbd2cSJim Jagielski 
355*b1cdbd2cSJim Jagielski             if ( ( aOpenCommand.Mode
356*b1cdbd2cSJim Jagielski                    == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
357*b1cdbd2cSJim Jagielski                  ( aOpenCommand.Mode
358*b1cdbd2cSJim Jagielski                    == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) {
359*b1cdbd2cSJim Jagielski                 ucbhelper::cancelCommandExecution
360*b1cdbd2cSJim Jagielski                     ( uno::makeAny ( ucb::UnsupportedOpenModeException
361*b1cdbd2cSJim Jagielski                              ( rtl::OUString(),
362*b1cdbd2cSJim Jagielski                                static_cast< cppu::OWeakObject * >( this ),
363*b1cdbd2cSJim Jagielski                                sal_Int16( aOpenCommand.Mode ) ) ),
364*b1cdbd2cSJim Jagielski                       xEnv );
365*b1cdbd2cSJim Jagielski             }
366*b1cdbd2cSJim Jagielski             if ( !feedSink( aOpenCommand.Sink, xEnv ) ) {
367*b1cdbd2cSJim Jagielski                 // Note: aOpenCommand.Sink may contain an XStream
368*b1cdbd2cSJim Jagielski                 //       implementation. Support for this type of
369*b1cdbd2cSJim Jagielski                 //       sink is optional...
370*b1cdbd2cSJim Jagielski #ifdef DEBUG
371*b1cdbd2cSJim Jagielski                 g_warning ("Failed to load data from '%s'", getURI());
372*b1cdbd2cSJim Jagielski #endif
373*b1cdbd2cSJim Jagielski                 ucbhelper::cancelCommandExecution
374*b1cdbd2cSJim Jagielski                     ( uno::makeAny (ucb::UnsupportedDataSinkException
375*b1cdbd2cSJim Jagielski                             ( rtl::OUString(),
376*b1cdbd2cSJim Jagielski                               static_cast< cppu::OWeakObject * >( this ),
377*b1cdbd2cSJim Jagielski                               aOpenCommand.Sink ) ),
378*b1cdbd2cSJim Jagielski                       xEnv );
379*b1cdbd2cSJim Jagielski             }
380*b1cdbd2cSJim Jagielski         }
381*b1cdbd2cSJim Jagielski #ifdef DEBUG
382*b1cdbd2cSJim Jagielski         else
383*b1cdbd2cSJim Jagielski             g_warning ("Open falling through ...");
384*b1cdbd2cSJim Jagielski #endif
385*b1cdbd2cSJim Jagielski 
386*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "createNewContent" ) && isFolder( xEnv ) ) {
387*b1cdbd2cSJim Jagielski         ucb::ContentInfo arg;
388*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= arg ) )
389*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
390*b1cdbd2cSJim Jagielski 
391*b1cdbd2cSJim Jagielski         aRet <<= createNewContent( arg );
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "insert" ) ) {
394*b1cdbd2cSJim Jagielski         ucb::InsertCommandArgument arg;
395*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= arg ) )
396*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
397*b1cdbd2cSJim Jagielski 
398*b1cdbd2cSJim Jagielski         insert( arg.Data, arg.ReplaceExisting, xEnv );
399*b1cdbd2cSJim Jagielski 
400*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "delete" ) ) {
401*b1cdbd2cSJim Jagielski 
402*b1cdbd2cSJim Jagielski         sal_Bool bDeletePhysical = sal_False;
403*b1cdbd2cSJim Jagielski         aCommand.Argument >>= bDeletePhysical;
404*b1cdbd2cSJim Jagielski 
405*b1cdbd2cSJim Jagielski         ::rtl::OString aURI = getOURI();
406*b1cdbd2cSJim Jagielski         GnomeVFSResult result = gnome_vfs_unlink( aURI.getStr());
407*b1cdbd2cSJim Jagielski 
408*b1cdbd2cSJim Jagielski         if (result != GNOME_VFS_OK)
409*b1cdbd2cSJim Jagielski             cancelCommandExecution( result, xEnv, sal_True );
410*b1cdbd2cSJim Jagielski 
411*b1cdbd2cSJim Jagielski         destroy( bDeletePhysical );
412*b1cdbd2cSJim Jagielski 
413*b1cdbd2cSJim Jagielski     } else if ( COMMAND_IS( aCommand, "transfer" ) && isFolder( xEnv ) ) {
414*b1cdbd2cSJim Jagielski         ucb::TransferInfo transferArgs;
415*b1cdbd2cSJim Jagielski 
416*b1cdbd2cSJim Jagielski         if ( !( aCommand.Argument >>= transferArgs ) )
417*b1cdbd2cSJim Jagielski             ucbhelper::cancelCommandExecution( getBadArgExcept(), xEnv );
418*b1cdbd2cSJim Jagielski 
419*b1cdbd2cSJim Jagielski         transfer( transferArgs, xEnv );
420*b1cdbd2cSJim Jagielski 
421*b1cdbd2cSJim Jagielski     } else { // Unsuported
422*b1cdbd2cSJim Jagielski #ifdef DEBUG
423*b1cdbd2cSJim Jagielski         g_warning( "Unsupported command: '%s'",
424*b1cdbd2cSJim Jagielski                OUStringToGnome( aCommand.Name ) );
425*b1cdbd2cSJim Jagielski #endif
426*b1cdbd2cSJim Jagielski         ucbhelper::cancelCommandExecution
427*b1cdbd2cSJim Jagielski             ( uno::makeAny( ucb::UnsupportedCommandException
428*b1cdbd2cSJim Jagielski                     ( rtl::OUString(),
429*b1cdbd2cSJim Jagielski                       static_cast< cppu::OWeakObject * >( this ) ) ),
430*b1cdbd2cSJim Jagielski               xEnv );
431*b1cdbd2cSJim Jagielski     }
432*b1cdbd2cSJim Jagielski #undef COMMAND_IS
433*b1cdbd2cSJim Jagielski 
434*b1cdbd2cSJim Jagielski     return aRet;
435*b1cdbd2cSJim Jagielski }
436*b1cdbd2cSJim Jagielski 
abort(sal_Int32)437*b1cdbd2cSJim Jagielski void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
438*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
439*b1cdbd2cSJim Jagielski {
440*b1cdbd2cSJim Jagielski     // FIXME: we should use the GnomeVFSCancellation APIs here ...
441*b1cdbd2cSJim Jagielski }
442*b1cdbd2cSJim Jagielski 
443*b1cdbd2cSJim Jagielski //
444*b1cdbd2cSJim Jagielski // XContentCreator methods.
445*b1cdbd2cSJim Jagielski //
446*b1cdbd2cSJim Jagielski 
queryCreatableContentsInfo(const uno::Reference<ucb::XCommandEnvironment> & xEnv)447*b1cdbd2cSJim Jagielski uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
448*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment >& xEnv)
449*b1cdbd2cSJim Jagielski             throw( uno::RuntimeException )
450*b1cdbd2cSJim Jagielski {
451*b1cdbd2cSJim Jagielski     if ( isFolder( xEnv ) )
452*b1cdbd2cSJim Jagielski     {
453*b1cdbd2cSJim Jagielski         uno::Sequence< ucb::ContentInfo > seq(2);
454*b1cdbd2cSJim Jagielski 
455*b1cdbd2cSJim Jagielski         // Minimum set of props we really need
456*b1cdbd2cSJim Jagielski         uno::Sequence< beans::Property > props( 1 );
457*b1cdbd2cSJim Jagielski         props[0] = beans::Property(
458*b1cdbd2cSJim Jagielski             rtl::OUString::createFromAscii( "Title" ),
459*b1cdbd2cSJim Jagielski             -1,
460*b1cdbd2cSJim Jagielski             getCppuType( static_cast< rtl::OUString* >( 0 ) ),
461*b1cdbd2cSJim Jagielski             beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
462*b1cdbd2cSJim Jagielski 
463*b1cdbd2cSJim Jagielski         // file
464*b1cdbd2cSJim Jagielski         seq[0].Type       = rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
465*b1cdbd2cSJim Jagielski         seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
466*b1cdbd2cSJim Jagielski                               ucb::ContentInfoAttribute::KIND_DOCUMENT );
467*b1cdbd2cSJim Jagielski         seq[0].Properties = props;
468*b1cdbd2cSJim Jagielski 
469*b1cdbd2cSJim Jagielski         // folder
470*b1cdbd2cSJim Jagielski         seq[1].Type       = rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
471*b1cdbd2cSJim Jagielski         seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
472*b1cdbd2cSJim Jagielski         seq[1].Properties = props;
473*b1cdbd2cSJim Jagielski 
474*b1cdbd2cSJim Jagielski         return seq;
475*b1cdbd2cSJim Jagielski     }
476*b1cdbd2cSJim Jagielski     else
477*b1cdbd2cSJim Jagielski     {
478*b1cdbd2cSJim Jagielski         return uno::Sequence< ucb::ContentInfo >();
479*b1cdbd2cSJim Jagielski     }
480*b1cdbd2cSJim Jagielski }
481*b1cdbd2cSJim Jagielski 
queryCreatableContentsInfo()482*b1cdbd2cSJim Jagielski uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
483*b1cdbd2cSJim Jagielski             throw( uno::RuntimeException )
484*b1cdbd2cSJim Jagielski {
485*b1cdbd2cSJim Jagielski     return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
486*b1cdbd2cSJim Jagielski }
487*b1cdbd2cSJim Jagielski 
488*b1cdbd2cSJim Jagielski uno::Reference< ucb::XContent > SAL_CALL
createNewContent(const ucb::ContentInfo & Info)489*b1cdbd2cSJim Jagielski Content::createNewContent( const ucb::ContentInfo& Info )
490*b1cdbd2cSJim Jagielski     throw( uno::RuntimeException )
491*b1cdbd2cSJim Jagielski {
492*b1cdbd2cSJim Jagielski     bool create_document;
493*b1cdbd2cSJim Jagielski     const char *name;
494*b1cdbd2cSJim Jagielski 
495*b1cdbd2cSJim Jagielski         if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FILE_TYPE ) ) )
496*b1cdbd2cSJim Jagielski         create_document = true;
497*b1cdbd2cSJim Jagielski     else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FOLDER_TYPE ) ) )
498*b1cdbd2cSJim Jagielski         create_document = false;
499*b1cdbd2cSJim Jagielski     else {
500*b1cdbd2cSJim Jagielski #ifdef DEBUG
501*b1cdbd2cSJim Jagielski         g_warning( "Failed to create new content '%s'",
502*b1cdbd2cSJim Jagielski                OUStringToGnome( Info.Type ) );
503*b1cdbd2cSJim Jagielski #endif
504*b1cdbd2cSJim Jagielski         return uno::Reference< ucb::XContent >();
505*b1cdbd2cSJim Jagielski     }
506*b1cdbd2cSJim Jagielski 
507*b1cdbd2cSJim Jagielski #ifdef DEBUG
508*b1cdbd2cSJim Jagielski     g_warning( "createNewContent (%d)", (int) create_document );
509*b1cdbd2cSJim Jagielski #endif
510*b1cdbd2cSJim Jagielski 
511*b1cdbd2cSJim Jagielski         rtl::OUString aURL = getOUURI();
512*b1cdbd2cSJim Jagielski 
513*b1cdbd2cSJim Jagielski     if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
514*b1cdbd2cSJim Jagielski         aURL += rtl::OUString::createFromAscii( "/" );
515*b1cdbd2cSJim Jagielski 
516*b1cdbd2cSJim Jagielski     name = create_document ? "[New_Content]" : "[New_Collection]";
517*b1cdbd2cSJim Jagielski     // This looks problematic to me cf. webdav
518*b1cdbd2cSJim Jagielski     aURL += rtl::OUString::createFromAscii( name );
519*b1cdbd2cSJim Jagielski 
520*b1cdbd2cSJim Jagielski         uno::Reference< ucb::XContentIdentifier > xId
521*b1cdbd2cSJim Jagielski         ( new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) );
522*b1cdbd2cSJim Jagielski 
523*b1cdbd2cSJim Jagielski         try {
524*b1cdbd2cSJim Jagielski         return new ::gvfs::Content( m_xSMgr, m_pProvider, xId, !create_document );
525*b1cdbd2cSJim Jagielski     } catch ( ucb::ContentCreationException & ) {
526*b1cdbd2cSJim Jagielski         return uno::Reference< ucb::XContent >();
527*b1cdbd2cSJim Jagielski         }
528*b1cdbd2cSJim Jagielski }
529*b1cdbd2cSJim Jagielski 
getParentURL()530*b1cdbd2cSJim Jagielski rtl::OUString Content::getParentURL()
531*b1cdbd2cSJim Jagielski {
532*b1cdbd2cSJim Jagielski     rtl::OUString aParentURL;
533*b1cdbd2cSJim Jagielski     // <scheme>://              -> ""
534*b1cdbd2cSJim Jagielski     // <scheme>://foo           -> ""
535*b1cdbd2cSJim Jagielski     // <scheme>://foo/          -> ""
536*b1cdbd2cSJim Jagielski     // <scheme>://foo/bar       -> <scheme>://foo/
537*b1cdbd2cSJim Jagielski     // <scheme>://foo/bar/      -> <scheme>://foo/
538*b1cdbd2cSJim Jagielski     // <scheme>://foo/bar/abc   -> <scheme>://foo/bar/
539*b1cdbd2cSJim Jagielski 
540*b1cdbd2cSJim Jagielski     rtl::OUString aURL = getOUURI();
541*b1cdbd2cSJim Jagielski 
542*b1cdbd2cSJim Jagielski     sal_Int32 nPos = aURL.lastIndexOf( '/' );
543*b1cdbd2cSJim Jagielski     if ( nPos == ( aURL.getLength() - 1 ) ) {
544*b1cdbd2cSJim Jagielski         // Trailing slash found. Skip.
545*b1cdbd2cSJim Jagielski         nPos = aURL.lastIndexOf( '/', nPos );
546*b1cdbd2cSJim Jagielski     }
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski     sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
549*b1cdbd2cSJim Jagielski     if ( nPos1 != -1 )
550*b1cdbd2cSJim Jagielski         nPos1 = aURL.lastIndexOf( '/', nPos1 );
551*b1cdbd2cSJim Jagielski 
552*b1cdbd2cSJim Jagielski     if ( nPos1 != -1 )
553*b1cdbd2cSJim Jagielski         aParentURL = rtl::OUString( aURL.copy( 0, nPos + 1 ) );
554*b1cdbd2cSJim Jagielski 
555*b1cdbd2cSJim Jagielski #ifdef DEBUG
556*b1cdbd2cSJim Jagielski     g_warning ("getParentURL '%s' -> '%s'",
557*b1cdbd2cSJim Jagielski            getURI(), rtl::OUStringToOString( aParentURL, RTL_TEXTENCODING_UTF8).getStr() );
558*b1cdbd2cSJim Jagielski #endif
559*b1cdbd2cSJim Jagielski 
560*b1cdbd2cSJim Jagielski     return aParentURL;
561*b1cdbd2cSJim Jagielski }
562*b1cdbd2cSJim Jagielski 
563*b1cdbd2cSJim Jagielski static util::DateTime
getDateFromUnix(time_t t)564*b1cdbd2cSJim Jagielski getDateFromUnix (time_t t)
565*b1cdbd2cSJim Jagielski {
566*b1cdbd2cSJim Jagielski     TimeValue tv;
567*b1cdbd2cSJim Jagielski     tv.Nanosec = 0;
568*b1cdbd2cSJim Jagielski     tv.Seconds = t;
569*b1cdbd2cSJim Jagielski     oslDateTime dt;
570*b1cdbd2cSJim Jagielski 
571*b1cdbd2cSJim Jagielski     if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
572*b1cdbd2cSJim Jagielski         return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
573*b1cdbd2cSJim Jagielski                                dt.Day, dt.Month, dt.Year);
574*b1cdbd2cSJim Jagielski     else
575*b1cdbd2cSJim Jagielski         return util::DateTime();
576*b1cdbd2cSJim Jagielski }
577*b1cdbd2cSJim Jagielski 
getPropertyValues(const uno::Sequence<beans::Property> & rProperties,const uno::Reference<ucb::XCommandEnvironment> & xEnv)578*b1cdbd2cSJim Jagielski uno::Reference< sdbc::XRow > Content::getPropertyValues(
579*b1cdbd2cSJim Jagielski                 const uno::Sequence< beans::Property >& rProperties,
580*b1cdbd2cSJim Jagielski                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
581*b1cdbd2cSJim Jagielski {
582*b1cdbd2cSJim Jagielski     int nProps;
583*b1cdbd2cSJim Jagielski     GnomeVFSResult result;
584*b1cdbd2cSJim Jagielski     uno::Sequence< beans::Property > allProperties;
585*b1cdbd2cSJim Jagielski 
586*b1cdbd2cSJim Jagielski     if( ( result = getInfo( xEnv ) ) != GNOME_VFS_OK )
587*b1cdbd2cSJim Jagielski         cancelCommandExecution( result, xEnv, sal_False );
588*b1cdbd2cSJim Jagielski 
589*b1cdbd2cSJim Jagielski     const beans::Property* pProps;
590*b1cdbd2cSJim Jagielski 
591*b1cdbd2cSJim Jagielski     if( rProperties.getLength() ) {
592*b1cdbd2cSJim Jagielski         nProps = rProperties.getLength();
593*b1cdbd2cSJim Jagielski         pProps = rProperties.getConstArray();
594*b1cdbd2cSJim Jagielski     } else {
595*b1cdbd2cSJim Jagielski         allProperties = getPropertySetInfo( xEnv )->getProperties();
596*b1cdbd2cSJim Jagielski         nProps = allProperties.getLength();
597*b1cdbd2cSJim Jagielski         pProps = allProperties.getConstArray();
598*b1cdbd2cSJim Jagielski     }
599*b1cdbd2cSJim Jagielski 
600*b1cdbd2cSJim Jagielski     rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
601*b1cdbd2cSJim Jagielski         = new ::ucbhelper::PropertyValueSet( m_xSMgr );
602*b1cdbd2cSJim Jagielski 
603*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
604*b1cdbd2cSJim Jagielski     for( sal_Int32 n = 0; n < nProps; ++n ) {
605*b1cdbd2cSJim Jagielski         const beans::Property& rProp = pProps[ n ];
606*b1cdbd2cSJim Jagielski 
607*b1cdbd2cSJim Jagielski         if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
608*b1cdbd2cSJim Jagielski             if (m_info.name && m_info.name[0] == '/')
609*b1cdbd2cSJim Jagielski                 g_warning ("Odd NFS title on item '%s' == '%s'",
610*b1cdbd2cSJim Jagielski                        getURI(), m_info.name);
611*b1cdbd2cSJim Jagielski             xRow->appendString( rProp, GnomeToOUString( m_info.name ) );
612*b1cdbd2cSJim Jagielski         }
613*b1cdbd2cSJim Jagielski 
614*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
615*b1cdbd2cSJim Jagielski             xRow->appendString( rProp, getContentType () );
616*b1cdbd2cSJim Jagielski 
617*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) {
618*b1cdbd2cSJim Jagielski             if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
619*b1cdbd2cSJim Jagielski                 xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_REGULAR ||
620*b1cdbd2cSJim Jagielski                                   m_info.type == GNOME_VFS_FILE_TYPE_UNKNOWN ) );
621*b1cdbd2cSJim Jagielski             else
622*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
623*b1cdbd2cSJim Jagielski         }
624*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) {
625*b1cdbd2cSJim Jagielski             if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
626*b1cdbd2cSJim Jagielski                 xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) );
627*b1cdbd2cSJim Jagielski             else
628*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
629*b1cdbd2cSJim Jagielski         }
630*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) ) {
631*b1cdbd2cSJim Jagielski 
632*b1cdbd2cSJim Jagielski             GnomeVFSFileInfo* fileInfo = gnome_vfs_file_info_new ();
633*b1cdbd2cSJim Jagielski 
634*b1cdbd2cSJim Jagielski             ::rtl::OString aURI = getOURI();
635*b1cdbd2cSJim Jagielski             gnome_vfs_get_file_info( aURI.getStr(), fileInfo,
636*b1cdbd2cSJim Jagielski                         GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS );
637*b1cdbd2cSJim Jagielski 
638*b1cdbd2cSJim Jagielski             if (fileInfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_ACCESS) {
639*b1cdbd2cSJim Jagielski                 bool read_only = true;
640*b1cdbd2cSJim Jagielski 
641*b1cdbd2cSJim Jagielski                 if (fileInfo->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE)
642*b1cdbd2cSJim Jagielski                                         read_only = false;
643*b1cdbd2cSJim Jagielski 
644*b1cdbd2cSJim Jagielski                 xRow->appendBoolean( rProp, read_only );
645*b1cdbd2cSJim Jagielski             } else
646*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
647*b1cdbd2cSJim Jagielski             gnome_vfs_file_info_unref (fileInfo);
648*b1cdbd2cSJim Jagielski         }
649*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) {
650*b1cdbd2cSJim Jagielski             if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
651*b1cdbd2cSJim Jagielski                 xRow->appendLong( rProp, m_info.size );
652*b1cdbd2cSJim Jagielski             else
653*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
654*b1cdbd2cSJim Jagielski         }
655*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
656*b1cdbd2cSJim Jagielski             xRow->appendBoolean( rProp, ( m_info.name && m_info.name[0] == '.' ) );
657*b1cdbd2cSJim Jagielski 
658*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) ||
659*b1cdbd2cSJim Jagielski              rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisk" ) ) )
660*b1cdbd2cSJim Jagielski             xRow->appendBoolean( rProp, sal_False );
661*b1cdbd2cSJim Jagielski 
662*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ) {
663*b1cdbd2cSJim Jagielski             if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_CTIME)
664*b1cdbd2cSJim Jagielski                 xRow->appendTimestamp( rProp, getDateFromUnix( m_info.ctime ) );
665*b1cdbd2cSJim Jagielski             else
666*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
667*b1cdbd2cSJim Jagielski         }
668*b1cdbd2cSJim Jagielski 
669*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
670*b1cdbd2cSJim Jagielski             if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME)
671*b1cdbd2cSJim Jagielski                 xRow->appendTimestamp( rProp, getDateFromUnix( m_info.mtime ) );
672*b1cdbd2cSJim Jagielski             else
673*b1cdbd2cSJim Jagielski                 xRow->appendVoid( rProp );
674*b1cdbd2cSJim Jagielski         }
675*b1cdbd2cSJim Jagielski 
676*b1cdbd2cSJim Jagielski         else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) {
677*b1cdbd2cSJim Jagielski             // We do this by sniffing in gnome-vfs; rather expensively.
678*b1cdbd2cSJim Jagielski #ifdef DEBUG
679*b1cdbd2cSJim Jagielski             g_warning ("FIXME: Requested mime-type - an expensive op. indeed!");
680*b1cdbd2cSJim Jagielski #endif
681*b1cdbd2cSJim Jagielski             xRow->appendVoid( rProp );
682*b1cdbd2cSJim Jagielski         } else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
683*b1cdbd2cSJim Jagielski             xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
684*b1cdbd2cSJim Jagielski 
685*b1cdbd2cSJim Jagielski         else {
686*b1cdbd2cSJim Jagielski             xRow->appendVoid( rProp );
687*b1cdbd2cSJim Jagielski         }
688*b1cdbd2cSJim Jagielski     }
689*b1cdbd2cSJim Jagielski #ifdef DEBUG
690*b1cdbd2cSJim Jagielski     g_warning ("getPropertyValues on '%s' %d properties returned (of %d)",
691*b1cdbd2cSJim Jagielski            getURI(), (int)xRow->getLength(), (int)nProps);
692*b1cdbd2cSJim Jagielski #endif
693*b1cdbd2cSJim Jagielski 
694*b1cdbd2cSJim Jagielski     return uno::Reference< sdbc::XRow >( xRow.get() );
695*b1cdbd2cSJim Jagielski }
696*b1cdbd2cSJim Jagielski 
697*b1cdbd2cSJim Jagielski static lang::IllegalAccessException
getReadOnlyException(Content * ctnt)698*b1cdbd2cSJim Jagielski getReadOnlyException( Content *ctnt )
699*b1cdbd2cSJim Jagielski {
700*b1cdbd2cSJim Jagielski     return lang::IllegalAccessException
701*b1cdbd2cSJim Jagielski         ( rtl::OUString::createFromAscii( "Property is read-only!" ),
702*b1cdbd2cSJim Jagielski           static_cast< cppu::OWeakObject * >( ctnt ) );
703*b1cdbd2cSJim Jagielski }
704*b1cdbd2cSJim Jagielski 
705*b1cdbd2cSJim Jagielski rtl::OUString
makeNewURL(const char *)706*b1cdbd2cSJim Jagielski Content::makeNewURL( const char */*newName*/ )
707*b1cdbd2cSJim Jagielski {
708*b1cdbd2cSJim Jagielski     rtl::OUString aNewURL = getParentURL();
709*b1cdbd2cSJim Jagielski     if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
710*b1cdbd2cSJim Jagielski         aNewURL += rtl::OUString::createFromAscii( "/" );
711*b1cdbd2cSJim Jagielski 
712*b1cdbd2cSJim Jagielski     char *name = gnome_vfs_escape_string( m_info.name );
713*b1cdbd2cSJim Jagielski     aNewURL += GnomeToOUString( name );
714*b1cdbd2cSJim Jagielski     g_free( name );
715*b1cdbd2cSJim Jagielski 
716*b1cdbd2cSJim Jagielski     return aNewURL;
717*b1cdbd2cSJim Jagielski }
718*b1cdbd2cSJim Jagielski 
719*b1cdbd2cSJim Jagielski // This is slightly complicated by needing to support either 'move' or 'setname'
720*b1cdbd2cSJim Jagielski GnomeVFSResult
doSetFileInfo(const GnomeVFSFileInfo * newInfo,GnomeVFSSetFileInfoMask setMask,const uno::Reference<ucb::XCommandEnvironment> &)721*b1cdbd2cSJim Jagielski Content::doSetFileInfo( const GnomeVFSFileInfo *newInfo,
722*b1cdbd2cSJim Jagielski             GnomeVFSSetFileInfoMask setMask,
723*b1cdbd2cSJim Jagielski             const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
724*b1cdbd2cSJim Jagielski {
725*b1cdbd2cSJim Jagielski     GnomeVFSResult result = GNOME_VFS_OK;
726*b1cdbd2cSJim Jagielski 
727*b1cdbd2cSJim Jagielski     g_assert (!m_bTransient);
728*b1cdbd2cSJim Jagielski 
729*b1cdbd2cSJim Jagielski     ::rtl::OString aURI = getOURI();
730*b1cdbd2cSJim Jagielski 
731*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
732*b1cdbd2cSJim Jagielski 
733*b1cdbd2cSJim Jagielski     // The simple approach:
734*b1cdbd2cSJim Jagielski     if( setMask != GNOME_VFS_SET_FILE_INFO_NONE )
735*b1cdbd2cSJim Jagielski         result = gnome_vfs_set_file_info // missed a const in the API there
736*b1cdbd2cSJim Jagielski             ( aURI.getStr(), (GnomeVFSFileInfo *)newInfo, setMask );
737*b1cdbd2cSJim Jagielski 
738*b1cdbd2cSJim Jagielski     if ( result == GNOME_VFS_ERROR_NOT_SUPPORTED &&
739*b1cdbd2cSJim Jagielski          ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) ) {
740*b1cdbd2cSJim Jagielski         // Try a move instead
741*b1cdbd2cSJim Jagielski #ifdef DEBUG
742*b1cdbd2cSJim Jagielski         g_warning( "SetFileInfo not supported on '%s'", getURI() );
743*b1cdbd2cSJim Jagielski #endif
744*b1cdbd2cSJim Jagielski 
745*b1cdbd2cSJim Jagielski         char *newURI = OUStringToGnome( makeNewURL( newInfo->name ) );
746*b1cdbd2cSJim Jagielski 
747*b1cdbd2cSJim Jagielski         result = gnome_vfs_move( aURI.getStr(), newURI, FALSE);
748*b1cdbd2cSJim Jagielski 
749*b1cdbd2cSJim Jagielski         g_free (newURI);
750*b1cdbd2cSJim Jagielski     }
751*b1cdbd2cSJim Jagielski 
752*b1cdbd2cSJim Jagielski     return result;
753*b1cdbd2cSJim Jagielski }
754*b1cdbd2cSJim Jagielski 
755*b1cdbd2cSJim Jagielski 
setPropertyValues(const uno::Sequence<beans::PropertyValue> & rValues,const uno::Reference<ucb::XCommandEnvironment> & xEnv)756*b1cdbd2cSJim Jagielski uno::Sequence< uno::Any > Content::setPropertyValues(
757*b1cdbd2cSJim Jagielski                 const uno::Sequence< beans::PropertyValue >& rValues,
758*b1cdbd2cSJim Jagielski                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
759*b1cdbd2cSJim Jagielski {
760*b1cdbd2cSJim Jagielski     rtl::OUString    aNewTitle;
761*b1cdbd2cSJim Jagielski     GnomeVFSFileInfo newInfo;
762*b1cdbd2cSJim Jagielski     int              setMask = GNOME_VFS_SET_FILE_INFO_NONE;
763*b1cdbd2cSJim Jagielski 
764*b1cdbd2cSJim Jagielski     getInfo( xEnv );
765*b1cdbd2cSJim Jagielski 
766*b1cdbd2cSJim Jagielski     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
767*b1cdbd2cSJim Jagielski 
768*b1cdbd2cSJim Jagielski     gnome_vfs_file_info_copy( &newInfo, &m_info );
769*b1cdbd2cSJim Jagielski 
770*b1cdbd2cSJim Jagielski     Authentication aAuth( xEnv );
771*b1cdbd2cSJim Jagielski 
772*b1cdbd2cSJim Jagielski     int nChanged = 0, nTitlePos = 0;
773*b1cdbd2cSJim Jagielski     uno::Sequence< uno::Any > aRet( rValues.getLength() );
774*b1cdbd2cSJim Jagielski     uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
775*b1cdbd2cSJim Jagielski 
776*b1cdbd2cSJim Jagielski     beans::PropertyChangeEvent aEvent;
777*b1cdbd2cSJim Jagielski     aEvent.Source         = static_cast< cppu::OWeakObject * >( this );
778*b1cdbd2cSJim Jagielski     aEvent.Further        = sal_False;
779*b1cdbd2cSJim Jagielski     aEvent.PropertyHandle = -1;
780*b1cdbd2cSJim Jagielski     // aEvent.PropertyName = fill in later ...
781*b1cdbd2cSJim Jagielski     // aEvent.OldValue     =
782*b1cdbd2cSJim Jagielski     // aEvent.NewValue     =
783*b1cdbd2cSJim Jagielski 
784*b1cdbd2cSJim Jagielski     int nCount = rValues.getLength();
785*b1cdbd2cSJim Jagielski     const beans::PropertyValue* pValues = rValues.getConstArray();
786*b1cdbd2cSJim Jagielski 
787*b1cdbd2cSJim Jagielski     for ( sal_Int32 n = 0; n < nCount; ++n ) {
788*b1cdbd2cSJim Jagielski         const beans::PropertyValue& rValue = pValues[ n ];
789*b1cdbd2cSJim Jagielski 
790*b1cdbd2cSJim Jagielski #ifdef DEBUG
791*b1cdbd2cSJim Jagielski         g_warning( "Set prop '%s'", OUStringToGnome( rValue.Name ) );
792*b1cdbd2cSJim Jagielski #endif
793*b1cdbd2cSJim Jagielski         if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
794*b1cdbd2cSJim Jagielski              rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
795*b1cdbd2cSJim Jagielski              rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
796*b1cdbd2cSJim Jagielski              rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
797*b1cdbd2cSJim Jagielski              rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
798*b1cdbd2cSJim Jagielski              rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
799*b1cdbd2cSJim Jagielski             aRet[ n ] <<= getReadOnlyException( this );
800*b1cdbd2cSJim Jagielski 
801*b1cdbd2cSJim Jagielski         else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
802*b1cdbd2cSJim Jagielski             if ( rValue.Value >>= aNewTitle ) {
803*b1cdbd2cSJim Jagielski                 if ( aNewTitle.getLength() <= 0 )
804*b1cdbd2cSJim Jagielski                     aRet[ n ] <<= lang::IllegalArgumentException
805*b1cdbd2cSJim Jagielski                         ( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
806*b1cdbd2cSJim Jagielski                           static_cast< cppu::OWeakObject * >( this ), -1 );
807*b1cdbd2cSJim Jagielski                 else {
808*b1cdbd2cSJim Jagielski                     char *newName = OUStringToGnome( aNewTitle );
809*b1cdbd2cSJim Jagielski 
810*b1cdbd2cSJim Jagielski                     if( !newName || !m_info.name || strcmp( newName, m_info.name ) ) {
811*b1cdbd2cSJim Jagielski #ifdef DEBUG
812*b1cdbd2cSJim Jagielski                         g_warning ("Set new name to '%s'", newName);
813*b1cdbd2cSJim Jagielski #endif
814*b1cdbd2cSJim Jagielski 
815*b1cdbd2cSJim Jagielski                         aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
816*b1cdbd2cSJim Jagielski                         aEvent.OldValue     = uno::makeAny( GnomeToOUString( newInfo.name ) );
817*b1cdbd2cSJim Jagielski                         aEvent.NewValue     = uno::makeAny( aNewTitle );
818*b1cdbd2cSJim Jagielski                         aChanges.getArray()[ nChanged ] = aEvent;
819*b1cdbd2cSJim Jagielski                         nTitlePos = nChanged++;
820*b1cdbd2cSJim Jagielski 
821*b1cdbd2cSJim Jagielski                         newInfo.name = newName;
822*b1cdbd2cSJim Jagielski                         setMask |= GNOME_VFS_SET_FILE_INFO_NAME;
823*b1cdbd2cSJim Jagielski                     } else // same name
824*b1cdbd2cSJim Jagielski                         g_free (newName);
825*b1cdbd2cSJim Jagielski                 }
826*b1cdbd2cSJim Jagielski             } else
827*b1cdbd2cSJim Jagielski                 aRet[ n ] <<= beans::IllegalTypeException
828*b1cdbd2cSJim Jagielski                     ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
829*b1cdbd2cSJim Jagielski                       static_cast< cppu::OWeakObject * >( this ) );
830*b1cdbd2cSJim Jagielski 
831*b1cdbd2cSJim Jagielski         } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ||
832*b1cdbd2cSJim Jagielski                 rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
833*b1cdbd2cSJim Jagielski             // FIXME: should be able to set the timestamps
834*b1cdbd2cSJim Jagielski             aRet[ n ] <<= getReadOnlyException( this );
835*b1cdbd2cSJim Jagielski         } else {
836*b1cdbd2cSJim Jagielski #ifdef DEBUG
837*b1cdbd2cSJim Jagielski             g_warning( "Unhandled property '%s'", OUStringToGnome( rValue.Name ) );
838*b1cdbd2cSJim Jagielski #endif
839*b1cdbd2cSJim Jagielski             aRet[ n ] <<= getReadOnlyException( this );
840*b1cdbd2cSJim Jagielski         }
841*b1cdbd2cSJim Jagielski     }
842*b1cdbd2cSJim Jagielski 
843*b1cdbd2cSJim Jagielski     GnomeVFSResult result = GNOME_VFS_OK;
844*b1cdbd2cSJim Jagielski 
845*b1cdbd2cSJim Jagielski     if ( !m_bTransient &&
846*b1cdbd2cSJim Jagielski          ( result = doSetFileInfo( &newInfo,
847*b1cdbd2cSJim Jagielski                        (GnomeVFSSetFileInfoMask) setMask,
848*b1cdbd2cSJim Jagielski                        xEnv ) ) != GNOME_VFS_OK ) {
849*b1cdbd2cSJim Jagielski         for (int i = 0; i < nChanged; i++)
850*b1cdbd2cSJim Jagielski             aRet[ i ] <<= mapVFSException( result, sal_True );
851*b1cdbd2cSJim Jagielski 
852*b1cdbd2cSJim Jagielski     }
853*b1cdbd2cSJim Jagielski 
854*b1cdbd2cSJim Jagielski     if ( result == GNOME_VFS_OK) {
855*b1cdbd2cSJim Jagielski         gnome_vfs_file_info_copy( &m_info, &newInfo );
856*b1cdbd2cSJim Jagielski 
857*b1cdbd2cSJim Jagielski         if ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) {
858*b1cdbd2cSJim Jagielski             uno::Reference< ucb::XContentIdentifier > xNewId
859*b1cdbd2cSJim Jagielski                 = new ::ucbhelper::ContentIdentifier(
860*b1cdbd2cSJim Jagielski                     m_xSMgr, makeNewURL( newInfo.name ) );
861*b1cdbd2cSJim Jagielski 
862*b1cdbd2cSJim Jagielski             aGuard.clear();
863*b1cdbd2cSJim Jagielski             if (!exchangeIdentity( xNewId ) )
864*b1cdbd2cSJim Jagielski                 aRet[ nTitlePos ] <<= uno::Exception
865*b1cdbd2cSJim Jagielski                     ( rtl::OUString::createFromAscii( "Exchange failed!" ),
866*b1cdbd2cSJim Jagielski                       static_cast< cppu::OWeakObject * >( this ) );
867*b1cdbd2cSJim Jagielski         }
868*b1cdbd2cSJim Jagielski     }
869*b1cdbd2cSJim Jagielski 
870*b1cdbd2cSJim Jagielski     gnome_vfs_file_info_clear( &newInfo );
871*b1cdbd2cSJim Jagielski 
872*b1cdbd2cSJim Jagielski     if ( nChanged > 0 ) {
873*b1cdbd2cSJim Jagielski             aGuard.clear();
874*b1cdbd2cSJim Jagielski         aChanges.realloc( nChanged );
875*b1cdbd2cSJim Jagielski         notifyPropertiesChange( aChanges );
876*b1cdbd2cSJim Jagielski     }
877*b1cdbd2cSJim Jagielski 
878*b1cdbd2cSJim Jagielski     return aRet;
879*b1cdbd2cSJim Jagielski }
880*b1cdbd2cSJim Jagielski 
queryChildren(ContentRefList & rChildren)881*b1cdbd2cSJim Jagielski void Content::queryChildren( ContentRefList& rChildren )
882*b1cdbd2cSJim Jagielski {
883*b1cdbd2cSJim Jagielski     // Obtain a list with a snapshot of all currently instanciated contents
884*b1cdbd2cSJim Jagielski     // from provider and extract the contents which are direct children
885*b1cdbd2cSJim Jagielski     // of this content.
886*b1cdbd2cSJim Jagielski 
887*b1cdbd2cSJim Jagielski     ::ucbhelper::ContentRefList aAllContents;
888*b1cdbd2cSJim Jagielski     m_xProvider->queryExistingContents( aAllContents );
889*b1cdbd2cSJim Jagielski 
890*b1cdbd2cSJim Jagielski     rtl::OUString aURL = getOUURI();
891*b1cdbd2cSJim Jagielski     sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
892*b1cdbd2cSJim Jagielski 
893*b1cdbd2cSJim Jagielski     if ( nURLPos != ( aURL.getLength() - 1 ) )
894*b1cdbd2cSJim Jagielski         aURL += rtl::OUString::createFromAscii( "/" );
895*b1cdbd2cSJim Jagielski 
896*b1cdbd2cSJim Jagielski     sal_Int32 nLen = aURL.getLength();
897*b1cdbd2cSJim Jagielski 
898*b1cdbd2cSJim Jagielski     ::ucbhelper::ContentRefList::const_iterator it  = aAllContents.begin();
899*b1cdbd2cSJim Jagielski     ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
900*b1cdbd2cSJim Jagielski 
901*b1cdbd2cSJim Jagielski     while ( it != end ) {
902*b1cdbd2cSJim Jagielski         ::ucbhelper::ContentImplHelperRef xChild = (*it);
903*b1cdbd2cSJim Jagielski         rtl::OUString aChildURL
904*b1cdbd2cSJim Jagielski             = xChild->getIdentifier()->getContentIdentifier();
905*b1cdbd2cSJim Jagielski 
906*b1cdbd2cSJim Jagielski         // Is aURL a prefix of aChildURL?
907*b1cdbd2cSJim Jagielski         if ( ( aChildURL.getLength() > nLen ) &&
908*b1cdbd2cSJim Jagielski              ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) {
909*b1cdbd2cSJim Jagielski             sal_Int32 nPos = nLen;
910*b1cdbd2cSJim Jagielski             nPos = aChildURL.indexOf( '/', nPos );
911*b1cdbd2cSJim Jagielski 
912*b1cdbd2cSJim Jagielski             if ( ( nPos == -1 ) ||
913*b1cdbd2cSJim Jagielski                  ( nPos == ( aChildURL.getLength() - 1 ) ) ) {
914*b1cdbd2cSJim Jagielski                 // No further slashes / only a final slash. It's a child!
915*b1cdbd2cSJim Jagielski                 rChildren.push_back( ::gvfs::Content::ContentRef
916*b1cdbd2cSJim Jagielski                              (static_cast< ::gvfs::Content * >(xChild.get() ) ) );
917*b1cdbd2cSJim Jagielski             }
918*b1cdbd2cSJim Jagielski         }
919*b1cdbd2cSJim Jagielski         ++it;
920*b1cdbd2cSJim Jagielski     }
921*b1cdbd2cSJim Jagielski }
922*b1cdbd2cSJim Jagielski 
insert(const uno::Reference<io::XInputStream> & xInputStream,sal_Bool bReplaceExisting,const uno::Reference<ucb::XCommandEnvironment> & xEnv)923*b1cdbd2cSJim Jagielski void Content::insert(
924*b1cdbd2cSJim Jagielski         const uno::Reference< io::XInputStream >               &xInputStream,
925*b1cdbd2cSJim Jagielski         sal_Bool                                                bReplaceExisting,
926*b1cdbd2cSJim Jagielski         const uno::Reference< ucb::XCommandEnvironment > &xEnv )
927*b1cdbd2cSJim Jagielski         throw( uno::Exception )
928*b1cdbd2cSJim Jagielski {
929*b1cdbd2cSJim Jagielski     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
930*b1cdbd2cSJim Jagielski 
931*b1cdbd2cSJim Jagielski #ifdef DEBUG
932*b1cdbd2cSJim Jagielski     g_warning( "Insert '%s' (%d) (0x%x:%d)", getURI(), bReplaceExisting,
933*b1cdbd2cSJim Jagielski            m_info.valid_fields, m_info.type );
934*b1cdbd2cSJim Jagielski #endif
935*b1cdbd2cSJim Jagielski 
936*b1cdbd2cSJim Jagielski     GnomeVFSResult result = getInfo( xEnv );
937*b1cdbd2cSJim Jagielski     // a racy design indeed.
938*b1cdbd2cSJim Jagielski     if( !bReplaceExisting && !m_bTransient &&
939*b1cdbd2cSJim Jagielski         result != GNOME_VFS_ERROR_NOT_FOUND) {
940*b1cdbd2cSJim Jagielski #ifdef DEBUG
941*b1cdbd2cSJim Jagielski         g_warning ("Nasty error inserting to '%s' ('%s')",
942*b1cdbd2cSJim Jagielski                getURI(), gnome_vfs_result_to_string( result ));
943*b1cdbd2cSJim Jagielski #endif
944*b1cdbd2cSJim Jagielski         cancelCommandExecution( GNOME_VFS_ERROR_FILE_EXISTS, xEnv, sal_True );
945*b1cdbd2cSJim Jagielski     }
946*b1cdbd2cSJim Jagielski 
947*b1cdbd2cSJim Jagielski     if ( m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
948*b1cdbd2cSJim Jagielski          m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) {
949*b1cdbd2cSJim Jagielski         ::rtl::OString aURI = getOURI();
950*b1cdbd2cSJim Jagielski         int perm;
951*b1cdbd2cSJim Jagielski 
952*b1cdbd2cSJim Jagielski         perm = ( GNOME_VFS_PERM_USER_ALL |
953*b1cdbd2cSJim Jagielski              GNOME_VFS_PERM_GROUP_READ |
954*b1cdbd2cSJim Jagielski              GNOME_VFS_PERM_OTHER_READ );
955*b1cdbd2cSJim Jagielski 
956*b1cdbd2cSJim Jagielski #ifdef DEBUG
957*b1cdbd2cSJim Jagielski         g_warning ("Make directory");
958*b1cdbd2cSJim Jagielski #endif
959*b1cdbd2cSJim Jagielski         result = gnome_vfs_make_directory( aURI.getStr(), perm );
960*b1cdbd2cSJim Jagielski 
961*b1cdbd2cSJim Jagielski         if( result != GNOME_VFS_OK )
962*b1cdbd2cSJim Jagielski             cancelCommandExecution( result, xEnv, sal_True );
963*b1cdbd2cSJim Jagielski 
964*b1cdbd2cSJim Jagielski         return;
965*b1cdbd2cSJim Jagielski     }
966*b1cdbd2cSJim Jagielski 
967*b1cdbd2cSJim Jagielski     if ( !xInputStream.is() ) {
968*b1cdbd2cSJim Jagielski         // FIXME: slightly unclear whether to accept this and create an empty file
969*b1cdbd2cSJim Jagielski         ucbhelper::cancelCommandExecution
970*b1cdbd2cSJim Jagielski             ( uno::makeAny
971*b1cdbd2cSJim Jagielski               ( ucb::MissingInputStreamException
972*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
973*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ) ) ),
974*b1cdbd2cSJim Jagielski               xEnv );
975*b1cdbd2cSJim Jagielski     }
976*b1cdbd2cSJim Jagielski 
977*b1cdbd2cSJim Jagielski     GnomeVFSHandle *handle = NULL;
978*b1cdbd2cSJim Jagielski     ::rtl::OString aURI = getOURI();
979*b1cdbd2cSJim Jagielski 
980*b1cdbd2cSJim Jagielski     result = GNOME_VFS_OK;
981*b1cdbd2cSJim Jagielski     if ( bReplaceExisting ) {
982*b1cdbd2cSJim Jagielski         Authentication aAuth( xEnv );
983*b1cdbd2cSJim Jagielski         result = gnome_vfs_open( &handle, aURI.getStr(),
984*b1cdbd2cSJim Jagielski                      GNOME_VFS_OPEN_WRITE );
985*b1cdbd2cSJim Jagielski     }
986*b1cdbd2cSJim Jagielski 
987*b1cdbd2cSJim Jagielski     if ( result != GNOME_VFS_OK ) {
988*b1cdbd2cSJim Jagielski         int perm;
989*b1cdbd2cSJim Jagielski         Authentication aAuth( xEnv );
990*b1cdbd2cSJim Jagielski 
991*b1cdbd2cSJim Jagielski         perm = ( ( GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ ) |
992*b1cdbd2cSJim Jagielski              ( GNOME_VFS_PERM_GROUP_WRITE | GNOME_VFS_PERM_GROUP_READ ) );
993*b1cdbd2cSJim Jagielski 
994*b1cdbd2cSJim Jagielski         result = gnome_vfs_create
995*b1cdbd2cSJim Jagielski             ( &handle, aURI.getStr(), GNOME_VFS_OPEN_WRITE, TRUE, perm );
996*b1cdbd2cSJim Jagielski     }
997*b1cdbd2cSJim Jagielski 
998*b1cdbd2cSJim Jagielski     if( result != GNOME_VFS_OK )
999*b1cdbd2cSJim Jagielski         cancelCommandExecution( result, xEnv, sal_True );
1000*b1cdbd2cSJim Jagielski 
1001*b1cdbd2cSJim Jagielski     if ( !xInputStream.is() ) {
1002*b1cdbd2cSJim Jagielski         result = gnome_vfs_close( handle );
1003*b1cdbd2cSJim Jagielski         if (result != GNOME_VFS_OK)
1004*b1cdbd2cSJim Jagielski             cancelCommandExecution( result, xEnv, sal_True );
1005*b1cdbd2cSJim Jagielski 
1006*b1cdbd2cSJim Jagielski     } else { // copy it over
1007*b1cdbd2cSJim Jagielski         uno::Reference < io::XOutputStream > xOutput =
1008*b1cdbd2cSJim Jagielski             new gvfs::Stream( handle, &m_info );
1009*b1cdbd2cSJim Jagielski 
1010*b1cdbd2cSJim Jagielski         copyData( xInputStream, xOutput );
1011*b1cdbd2cSJim Jagielski     }
1012*b1cdbd2cSJim Jagielski 
1013*b1cdbd2cSJim Jagielski     if (m_bTransient) {
1014*b1cdbd2cSJim Jagielski         m_bTransient = sal_False;
1015*b1cdbd2cSJim Jagielski         aGuard.clear();
1016*b1cdbd2cSJim Jagielski         inserted();
1017*b1cdbd2cSJim Jagielski     }
1018*b1cdbd2cSJim Jagielski }
1019*b1cdbd2cSJim Jagielski 
transfer(const ucb::TransferInfo &,const uno::Reference<ucb::XCommandEnvironment> & xEnv)1020*b1cdbd2cSJim Jagielski void Content::transfer(const ucb::TransferInfo & /*rArgs*/,
1021*b1cdbd2cSJim Jagielski                const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1022*b1cdbd2cSJim Jagielski     throw( uno::Exception )
1023*b1cdbd2cSJim Jagielski {
1024*b1cdbd2cSJim Jagielski     // FIXME: see gnome-vfs-xfer.h - but we need to be able to easily
1025*b1cdbd2cSJim Jagielski     // detect which are gnome-vfs owned URI types ...
1026*b1cdbd2cSJim Jagielski     ucbhelper::cancelCommandExecution
1027*b1cdbd2cSJim Jagielski         ( uno::makeAny
1028*b1cdbd2cSJim Jagielski             ( ucb::InteractiveBadTransferURLException
1029*b1cdbd2cSJim Jagielski                 ( rtl::OUString::createFromAscii( "Unsupported URL scheme!" ),
1030*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ) ) ),
1031*b1cdbd2cSJim Jagielski           xEnv );
1032*b1cdbd2cSJim Jagielski }
1033*b1cdbd2cSJim Jagielski 
destroy(sal_Bool bDeletePhysical)1034*b1cdbd2cSJim Jagielski void Content::destroy( sal_Bool bDeletePhysical )
1035*b1cdbd2cSJim Jagielski     throw( uno::Exception )
1036*b1cdbd2cSJim Jagielski {
1037*b1cdbd2cSJim Jagielski     // @@@ take care about bDeletePhysical -> trashcan support
1038*b1cdbd2cSJim Jagielski     rtl::OUString aURL = getOUURI();
1039*b1cdbd2cSJim Jagielski 
1040*b1cdbd2cSJim Jagielski     uno::Reference< ucb::XContent > xThis = this;
1041*b1cdbd2cSJim Jagielski 
1042*b1cdbd2cSJim Jagielski     deleted();
1043*b1cdbd2cSJim Jagielski 
1044*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > aGuard( m_aMutex );
1045*b1cdbd2cSJim Jagielski 
1046*b1cdbd2cSJim Jagielski     // Process instanciated children...
1047*b1cdbd2cSJim Jagielski     ::gvfs::Content::ContentRefList aChildren;
1048*b1cdbd2cSJim Jagielski     queryChildren( aChildren );
1049*b1cdbd2cSJim Jagielski 
1050*b1cdbd2cSJim Jagielski     ContentRefList::const_iterator it  = aChildren.begin();
1051*b1cdbd2cSJim Jagielski     ContentRefList::const_iterator end = aChildren.end();
1052*b1cdbd2cSJim Jagielski 
1053*b1cdbd2cSJim Jagielski     while ( it != end ) {
1054*b1cdbd2cSJim Jagielski         (*it)->destroy( bDeletePhysical );
1055*b1cdbd2cSJim Jagielski         ++it;
1056*b1cdbd2cSJim Jagielski     }
1057*b1cdbd2cSJim Jagielski }
1058*b1cdbd2cSJim Jagielski 
1059*b1cdbd2cSJim Jagielski // Used by the 'setPropertyValues' method for
1060*b1cdbd2cSJim Jagielski // propagating the renaming of a Content.
exchangeIdentity(const uno::Reference<ucb::XContentIdentifier> & xNewId)1061*b1cdbd2cSJim Jagielski sal_Bool Content::exchangeIdentity(
1062*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XContentIdentifier >& xNewId )
1063*b1cdbd2cSJim Jagielski {
1064*b1cdbd2cSJim Jagielski     if ( !xNewId.is() )
1065*b1cdbd2cSJim Jagielski         return sal_False;
1066*b1cdbd2cSJim Jagielski 
1067*b1cdbd2cSJim Jagielski     uno::Reference< ucb::XContent > xThis = this;
1068*b1cdbd2cSJim Jagielski 
1069*b1cdbd2cSJim Jagielski #ifdef DEBUG
1070*b1cdbd2cSJim Jagielski     g_warning( "exchangeIdentity from '%s' to '%s'",
1071*b1cdbd2cSJim Jagielski            getURI(), OUStringToGnome( xNewId->getContentIdentifier() ) );
1072*b1cdbd2cSJim Jagielski #endif
1073*b1cdbd2cSJim Jagielski 
1074*b1cdbd2cSJim Jagielski     if ( m_bTransient ) {
1075*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1076*b1cdbd2cSJim Jagielski         /* FIXME: can we not screw up an identically named
1077*b1cdbd2cSJim Jagielski          * Content pointing to ourself here ? */
1078*b1cdbd2cSJim Jagielski         m_xIdentifier = xNewId;
1079*b1cdbd2cSJim Jagielski         return sal_False;
1080*b1cdbd2cSJim Jagielski     }
1081*b1cdbd2cSJim Jagielski 
1082*b1cdbd2cSJim Jagielski     rtl::OUString aOldURL = getOUURI();
1083*b1cdbd2cSJim Jagielski 
1084*b1cdbd2cSJim Jagielski     // Exchange own identitity.
1085*b1cdbd2cSJim Jagielski     if ( exchange( xNewId ) ) {
1086*b1cdbd2cSJim Jagielski 
1087*b1cdbd2cSJim Jagielski         // Process instanciated children...
1088*b1cdbd2cSJim Jagielski         ContentRefList aChildren;
1089*b1cdbd2cSJim Jagielski         queryChildren( aChildren );
1090*b1cdbd2cSJim Jagielski 
1091*b1cdbd2cSJim Jagielski         ContentRefList::const_iterator it  = aChildren.begin();
1092*b1cdbd2cSJim Jagielski         ContentRefList::const_iterator end = aChildren.end();
1093*b1cdbd2cSJim Jagielski 
1094*b1cdbd2cSJim Jagielski         while ( it != end ) {
1095*b1cdbd2cSJim Jagielski             ContentRef xChild = (*it);
1096*b1cdbd2cSJim Jagielski 
1097*b1cdbd2cSJim Jagielski             // Create new content identifier for the child...
1098*b1cdbd2cSJim Jagielski             uno::Reference< ucb::XContentIdentifier >
1099*b1cdbd2cSJim Jagielski                 xOldChildId = xChild->getIdentifier();
1100*b1cdbd2cSJim Jagielski             rtl::OUString aOldChildURL
1101*b1cdbd2cSJim Jagielski                 = xOldChildId->getContentIdentifier();
1102*b1cdbd2cSJim Jagielski             rtl::OUString aNewChildURL
1103*b1cdbd2cSJim Jagielski                 = aOldChildURL.replaceAt(
1104*b1cdbd2cSJim Jagielski                              0,
1105*b1cdbd2cSJim Jagielski                              aOldURL.getLength(),
1106*b1cdbd2cSJim Jagielski                              xNewId->getContentIdentifier() );
1107*b1cdbd2cSJim Jagielski             uno::Reference< ucb::XContentIdentifier >
1108*b1cdbd2cSJim Jagielski                 xNewChildId
1109*b1cdbd2cSJim Jagielski                 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL );
1110*b1cdbd2cSJim Jagielski 
1111*b1cdbd2cSJim Jagielski             if ( !xChild->exchangeIdentity( xNewChildId ) )
1112*b1cdbd2cSJim Jagielski                 return sal_False;
1113*b1cdbd2cSJim Jagielski 
1114*b1cdbd2cSJim Jagielski             ++it;
1115*b1cdbd2cSJim Jagielski         }
1116*b1cdbd2cSJim Jagielski         return sal_True;
1117*b1cdbd2cSJim Jagielski     }
1118*b1cdbd2cSJim Jagielski 
1119*b1cdbd2cSJim Jagielski     return sal_False;
1120*b1cdbd2cSJim Jagielski }
1121*b1cdbd2cSJim Jagielski 
1122*b1cdbd2cSJim Jagielski GnomeVFSResult
getInfo(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1123*b1cdbd2cSJim Jagielski Content::getInfo( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1124*b1cdbd2cSJim Jagielski {
1125*b1cdbd2cSJim Jagielski     GnomeVFSResult result;
1126*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1127*b1cdbd2cSJim Jagielski 
1128*b1cdbd2cSJim Jagielski     if (m_bTransient)
1129*b1cdbd2cSJim Jagielski         result = GNOME_VFS_OK;
1130*b1cdbd2cSJim Jagielski 
1131*b1cdbd2cSJim Jagielski     else if ( !m_info.valid_fields ) {
1132*b1cdbd2cSJim Jagielski         ::rtl::OString aURI = getOURI();
1133*b1cdbd2cSJim Jagielski         Authentication aAuth( xEnv );
1134*b1cdbd2cSJim Jagielski         result = gnome_vfs_get_file_info
1135*b1cdbd2cSJim Jagielski             ( aURI.getStr(), &m_info, GNOME_VFS_FILE_INFO_DEFAULT );
1136*b1cdbd2cSJim Jagielski         if (result != GNOME_VFS_OK)
1137*b1cdbd2cSJim Jagielski             gnome_vfs_file_info_clear( &m_info );
1138*b1cdbd2cSJim Jagielski     } else
1139*b1cdbd2cSJim Jagielski         result = GNOME_VFS_OK;
1140*b1cdbd2cSJim Jagielski #ifdef DEBUG
1141*b1cdbd2cSJim Jagielski     g_warning( "getInfo on '%s' returns '%s' (%d) (0x%x)",
1142*b1cdbd2cSJim Jagielski            getURI(), gnome_vfs_result_to_string( result ),
1143*b1cdbd2cSJim Jagielski            result, m_info.valid_fields );
1144*b1cdbd2cSJim Jagielski #endif
1145*b1cdbd2cSJim Jagielski     return result;
1146*b1cdbd2cSJim Jagielski }
1147*b1cdbd2cSJim Jagielski 
1148*b1cdbd2cSJim Jagielski sal_Bool
isFolder(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1149*b1cdbd2cSJim Jagielski Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1150*b1cdbd2cSJim Jagielski {
1151*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1152*b1cdbd2cSJim Jagielski     getInfo( xEnv );
1153*b1cdbd2cSJim Jagielski     return (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
1154*b1cdbd2cSJim Jagielski         m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY);
1155*b1cdbd2cSJim Jagielski }
1156*b1cdbd2cSJim Jagielski 
mapVFSException(const GnomeVFSResult result,sal_Bool bWrite)1157*b1cdbd2cSJim Jagielski uno::Any Content::mapVFSException( const GnomeVFSResult result, sal_Bool bWrite )
1158*b1cdbd2cSJim Jagielski {
1159*b1cdbd2cSJim Jagielski     uno::Any aException;
1160*b1cdbd2cSJim Jagielski     const char *gvfs_message;
1161*b1cdbd2cSJim Jagielski     rtl::OUString message;
1162*b1cdbd2cSJim Jagielski     uno::Sequence< uno::Any > aArgs( 1 );
1163*b1cdbd2cSJim Jagielski 
1164*b1cdbd2cSJim Jagielski #ifdef DEBUG
1165*b1cdbd2cSJim Jagielski     g_warning ("Map VFS exception '%s' (%d)",
1166*b1cdbd2cSJim Jagielski            gnome_vfs_result_to_string( result ), result );
1167*b1cdbd2cSJim Jagielski #endif
1168*b1cdbd2cSJim Jagielski 
1169*b1cdbd2cSJim Jagielski     if ((gvfs_message = gnome_vfs_result_to_string (result)))
1170*b1cdbd2cSJim Jagielski         message = GnomeToOUString( gvfs_message );
1171*b1cdbd2cSJim Jagielski 
1172*b1cdbd2cSJim Jagielski     switch (result) {
1173*b1cdbd2cSJim Jagielski     case GNOME_VFS_OK:
1174*b1cdbd2cSJim Jagielski         g_warning("VFS_OK mapped to exception.");
1175*b1cdbd2cSJim Jagielski         break;
1176*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_EOF:
1177*b1cdbd2cSJim Jagielski         g_warning ("VFS_EOF not handled somewhere.");
1178*b1cdbd2cSJim Jagielski         break;
1179*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_FOUND:
1180*b1cdbd2cSJim Jagielski         aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
1181*b1cdbd2cSJim Jagielski         aException <<=
1182*b1cdbd2cSJim Jagielski             ucb::InteractiveAugmentedIOException
1183*b1cdbd2cSJim Jagielski             ( rtl::OUString::createFromAscii( "Not found!" ),
1184*b1cdbd2cSJim Jagielski               static_cast< cppu::OWeakObject * >( this ),
1185*b1cdbd2cSJim Jagielski               task::InteractionClassification_ERROR,
1186*b1cdbd2cSJim Jagielski               ucb::IOErrorCode_NOT_EXISTING,
1187*b1cdbd2cSJim Jagielski               aArgs );
1188*b1cdbd2cSJim Jagielski         break;
1189*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_BAD_PARAMETERS:
1190*b1cdbd2cSJim Jagielski         aException <<=
1191*b1cdbd2cSJim Jagielski             lang::IllegalArgumentException
1192*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
1193*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ),
1194*b1cdbd2cSJim Jagielski                   -1 );
1195*b1cdbd2cSJim Jagielski         break;
1196*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_GENERIC:
1197*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_INTERNAL:
1198*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_SUPPORTED:
1199*b1cdbd2cSJim Jagielski #ifdef DEBUG
1200*b1cdbd2cSJim Jagielski         g_warning ("Internal - un-mapped error");
1201*b1cdbd2cSJim Jagielski #endif
1202*b1cdbd2cSJim Jagielski         aException <<= io::IOException();
1203*b1cdbd2cSJim Jagielski         break;
1204*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_IO:
1205*b1cdbd2cSJim Jagielski         if ( bWrite )
1206*b1cdbd2cSJim Jagielski             aException <<=
1207*b1cdbd2cSJim Jagielski                 ucb::InteractiveNetworkWriteException
1208*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
1209*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ),
1210*b1cdbd2cSJim Jagielski                   task::InteractionClassification_ERROR,
1211*b1cdbd2cSJim Jagielski                   message );
1212*b1cdbd2cSJim Jagielski         else
1213*b1cdbd2cSJim Jagielski             aException <<=
1214*b1cdbd2cSJim Jagielski                 ucb::InteractiveNetworkReadException
1215*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
1216*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ),
1217*b1cdbd2cSJim Jagielski                   task::InteractionClassification_ERROR,
1218*b1cdbd2cSJim Jagielski                   message );
1219*b1cdbd2cSJim Jagielski         break;
1220*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_HOST_NOT_FOUND:
1221*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_INVALID_HOST_NAME:
1222*b1cdbd2cSJim Jagielski         aException <<=
1223*b1cdbd2cSJim Jagielski             ucb::InteractiveNetworkResolveNameException
1224*b1cdbd2cSJim Jagielski             ( rtl::OUString(),
1225*b1cdbd2cSJim Jagielski               static_cast< cppu::OWeakObject * >( this ),
1226*b1cdbd2cSJim Jagielski               task::InteractionClassification_ERROR,
1227*b1cdbd2cSJim Jagielski               message );
1228*b1cdbd2cSJim Jagielski         break;
1229*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
1230*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_SERVICE_OBSOLETE:
1231*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_PROTOCOL_ERROR:
1232*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NO_MASTER_BROWSER:
1233*b1cdbd2cSJim Jagielski         aException <<=
1234*b1cdbd2cSJim Jagielski             ucb::InteractiveNetworkConnectException
1235*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
1236*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ),
1237*b1cdbd2cSJim Jagielski                   task::InteractionClassification_ERROR,
1238*b1cdbd2cSJim Jagielski                   message );
1239*b1cdbd2cSJim Jagielski         break;
1240*b1cdbd2cSJim Jagielski 
1241*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_FILE_EXISTS:
1242*b1cdbd2cSJim Jagielski         aException <<= ucb::NameClashException
1243*b1cdbd2cSJim Jagielski                 ( rtl::OUString(),
1244*b1cdbd2cSJim Jagielski                   static_cast< cppu::OWeakObject * >( this ),
1245*b1cdbd2cSJim Jagielski                   task::InteractionClassification_ERROR,
1246*b1cdbd2cSJim Jagielski                   message );
1247*b1cdbd2cSJim Jagielski         break;
1248*b1cdbd2cSJim Jagielski 
1249*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
1250*b1cdbd2cSJim Jagielski         aException <<= ucb::UnsupportedOpenModeException();
1251*b1cdbd2cSJim Jagielski         break;
1252*b1cdbd2cSJim Jagielski 
1253*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_CORRUPTED_DATA:
1254*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_WRONG_FORMAT:
1255*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_BAD_FILE:
1256*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_TOO_BIG:
1257*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NO_SPACE:
1258*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_READ_ONLY:
1259*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_INVALID_URI:
1260*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_OPEN:
1261*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_ACCESS_DENIED:
1262*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
1263*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
1264*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_IN_PROGRESS:
1265*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_INTERRUPTED:
1266*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_LOOP:
1267*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_PERMITTED:
1268*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_IS_DIRECTORY:
1269*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NO_MEMORY:
1270*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
1271*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_LOGIN_FAILED:
1272*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_CANCELLED:
1273*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_DIRECTORY_BUSY:
1274*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
1275*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_TOO_MANY_LINKS:
1276*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:
1277*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
1278*b1cdbd2cSJim Jagielski     case GNOME_VFS_ERROR_NAME_TOO_LONG:
1279*b1cdbd2cSJim Jagielski #ifdef DEBUG
1280*b1cdbd2cSJim Jagielski         g_warning( "FIXME: Un-mapped VFS exception '%s' (%d)",
1281*b1cdbd2cSJim Jagielski                gnome_vfs_result_to_string( result ), result );
1282*b1cdbd2cSJim Jagielski #endif
1283*b1cdbd2cSJim Jagielski     default:
1284*b1cdbd2cSJim Jagielski         aException <<= ucb::InteractiveNetworkGeneralException
1285*b1cdbd2cSJim Jagielski             ( rtl::OUString(),
1286*b1cdbd2cSJim Jagielski               static_cast< cppu::OWeakObject * >( this ),
1287*b1cdbd2cSJim Jagielski               task::InteractionClassification_ERROR );
1288*b1cdbd2cSJim Jagielski         break;
1289*b1cdbd2cSJim Jagielski     }
1290*b1cdbd2cSJim Jagielski 
1291*b1cdbd2cSJim Jagielski     return aException;
1292*b1cdbd2cSJim Jagielski }
1293*b1cdbd2cSJim Jagielski 
cancelCommandExecution(GnomeVFSResult result,const uno::Reference<ucb::XCommandEnvironment> & xEnv,sal_Bool bWrite)1294*b1cdbd2cSJim Jagielski void Content::cancelCommandExecution(
1295*b1cdbd2cSJim Jagielski     GnomeVFSResult result,
1296*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment > & xEnv,
1297*b1cdbd2cSJim Jagielski     sal_Bool bWrite /* = sal_False */ )
1298*b1cdbd2cSJim Jagielski     throw ( uno::Exception )
1299*b1cdbd2cSJim Jagielski {
1300*b1cdbd2cSJim Jagielski     ucbhelper::cancelCommandExecution( mapVFSException( result, bWrite ), xEnv );
1301*b1cdbd2cSJim Jagielski     // Unreachable
1302*b1cdbd2cSJim Jagielski }
1303*b1cdbd2cSJim Jagielski 
getProperties(const uno::Reference<ucb::XCommandEnvironment> &)1304*b1cdbd2cSJim Jagielski uno::Sequence< beans::Property > Content::getProperties(
1305*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
1306*b1cdbd2cSJim Jagielski {
1307*b1cdbd2cSJim Jagielski     static const beans::Property aGenericProperties[] = {
1308*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
1309*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1310*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1311*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
1312*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1313*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1314*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
1315*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1316*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1317*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
1318*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1319*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND ),
1320*b1cdbd2cSJim Jagielski         // Optional ...
1321*b1cdbd2cSJim Jagielski         beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
1322*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1323*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1324*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
1325*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1326*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1327*b1cdbd2cSJim Jagielski // FIXME: Too expensive for now (?)
1328*b1cdbd2cSJim Jagielski //                beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1329*b1cdbd2cSJim Jagielski //                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1330*b1cdbd2cSJim Jagielski //                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1331*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
1332*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
1333*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1334*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
1335*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1336*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1337*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
1338*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1339*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1340*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisk" ) ),
1341*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1342*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1343*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
1344*b1cdbd2cSJim Jagielski                  -1, getCppuBooleanType(),
1345*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1346*b1cdbd2cSJim Jagielski                 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
1347*b1cdbd2cSJim Jagielski                  -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
1348*b1cdbd2cSJim Jagielski                  beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
1349*b1cdbd2cSJim Jagielski     };
1350*b1cdbd2cSJim Jagielski 
1351*b1cdbd2cSJim Jagielski     const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
1352*b1cdbd2cSJim Jagielski 
1353*b1cdbd2cSJim Jagielski     return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
1354*b1cdbd2cSJim Jagielski 
1355*b1cdbd2cSJim Jagielski }
1356*b1cdbd2cSJim Jagielski 
getCommands(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1357*b1cdbd2cSJim Jagielski uno::Sequence< ucb::CommandInfo > Content::getCommands(
1358*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1359*b1cdbd2cSJim Jagielski {
1360*b1cdbd2cSJim Jagielski     static ucb::CommandInfo aCommandInfoTable[] = {
1361*b1cdbd2cSJim Jagielski         // Required commands
1362*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1363*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
1364*b1cdbd2cSJim Jagielski           -1, getCppuVoidType() ),
1365*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1366*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
1367*b1cdbd2cSJim Jagielski           -1, getCppuVoidType() ),
1368*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1369*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
1370*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
1371*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1372*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
1373*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
1374*b1cdbd2cSJim Jagielski 
1375*b1cdbd2cSJim Jagielski         // Optional standard commands
1376*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1377*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
1378*b1cdbd2cSJim Jagielski           -1, getCppuBooleanType() ),
1379*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1380*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
1381*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
1382*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1383*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
1384*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
1385*b1cdbd2cSJim Jagielski 
1386*b1cdbd2cSJim Jagielski         // Folder Only, omitted if not a folder
1387*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1388*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
1389*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
1390*b1cdbd2cSJim Jagielski         ucb::CommandInfo
1391*b1cdbd2cSJim Jagielski         ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
1392*b1cdbd2cSJim Jagielski           -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
1393*b1cdbd2cSJim Jagielski     };
1394*b1cdbd2cSJim Jagielski 
1395*b1cdbd2cSJim Jagielski     const int nProps
1396*b1cdbd2cSJim Jagielski         = sizeof( aCommandInfoTable ) / sizeof( aCommandInfoTable[ 0 ] );
1397*b1cdbd2cSJim Jagielski     return uno::Sequence< ucb::CommandInfo >(
1398*b1cdbd2cSJim Jagielski         aCommandInfoTable, isFolder( xEnv ) ? nProps : nProps - 2 );
1399*b1cdbd2cSJim Jagielski }
1400*b1cdbd2cSJim Jagielski 
1401*b1cdbd2cSJim Jagielski rtl::OUString
getOUURI()1402*b1cdbd2cSJim Jagielski Content::getOUURI ()
1403*b1cdbd2cSJim Jagielski {
1404*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1405*b1cdbd2cSJim Jagielski     return m_xIdentifier->getContentIdentifier();
1406*b1cdbd2cSJim Jagielski }
1407*b1cdbd2cSJim Jagielski 
1408*b1cdbd2cSJim Jagielski rtl::OString
getOURI()1409*b1cdbd2cSJim Jagielski Content::getOURI ()
1410*b1cdbd2cSJim Jagielski {
1411*b1cdbd2cSJim Jagielski     return rtl::OUStringToOString( getOUURI(), RTL_TEXTENCODING_UTF8 );
1412*b1cdbd2cSJim Jagielski }
1413*b1cdbd2cSJim Jagielski 
1414*b1cdbd2cSJim Jagielski char *
getURI()1415*b1cdbd2cSJim Jagielski Content::getURI ()
1416*b1cdbd2cSJim Jagielski {
1417*b1cdbd2cSJim Jagielski     return OUStringToGnome( getOUURI() );
1418*b1cdbd2cSJim Jagielski }
1419*b1cdbd2cSJim Jagielski 
1420*b1cdbd2cSJim Jagielski void
copyData(uno::Reference<io::XInputStream> xIn,uno::Reference<io::XOutputStream> xOut)1421*b1cdbd2cSJim Jagielski Content::copyData( uno::Reference< io::XInputStream > xIn,
1422*b1cdbd2cSJim Jagielski                    uno::Reference< io::XOutputStream > xOut )
1423*b1cdbd2cSJim Jagielski {
1424*b1cdbd2cSJim Jagielski     uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
1425*b1cdbd2cSJim Jagielski 
1426*b1cdbd2cSJim Jagielski     g_return_if_fail( xIn.is() && xOut.is() );
1427*b1cdbd2cSJim Jagielski 
1428*b1cdbd2cSJim Jagielski     while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
1429*b1cdbd2cSJim Jagielski         xOut->writeBytes( theData );
1430*b1cdbd2cSJim Jagielski 
1431*b1cdbd2cSJim Jagielski     xOut->closeOutput();
1432*b1cdbd2cSJim Jagielski }
1433*b1cdbd2cSJim Jagielski 
1434*b1cdbd2cSJim Jagielski // Inherits an authentication context
1435*b1cdbd2cSJim Jagielski uno::Reference< io::XInputStream >
createTempStream(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1436*b1cdbd2cSJim Jagielski Content::createTempStream(
1437*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1438*b1cdbd2cSJim Jagielski         throw( uno::Exception )
1439*b1cdbd2cSJim Jagielski {
1440*b1cdbd2cSJim Jagielski     GnomeVFSResult result;
1441*b1cdbd2cSJim Jagielski     GnomeVFSHandle *handle = NULL;
1442*b1cdbd2cSJim Jagielski     ::rtl::OString aURI = getOURI();
1443*b1cdbd2cSJim Jagielski 
1444*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1445*b1cdbd2cSJim Jagielski     // Something badly wrong happened - can't seek => stream to a temporary file
1446*b1cdbd2cSJim Jagielski     const rtl::OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
1447*b1cdbd2cSJim Jagielski     uno::Reference < io::XOutputStream > xTempOut =
1448*b1cdbd2cSJim Jagielski         uno::Reference < io::XOutputStream >
1449*b1cdbd2cSJim Jagielski             ( m_xSMgr->createInstance( sServiceName ), uno::UNO_QUERY );
1450*b1cdbd2cSJim Jagielski 
1451*b1cdbd2cSJim Jagielski     if ( !xTempOut.is() )
1452*b1cdbd2cSJim Jagielski         cancelCommandExecution( GNOME_VFS_ERROR_IO, xEnv );
1453*b1cdbd2cSJim Jagielski 
1454*b1cdbd2cSJim Jagielski     result = gnome_vfs_open( &handle, aURI.getStr(), GNOME_VFS_OPEN_READ );
1455*b1cdbd2cSJim Jagielski     if (result != GNOME_VFS_OK)
1456*b1cdbd2cSJim Jagielski         cancelCommandExecution( result, xEnv );
1457*b1cdbd2cSJim Jagielski 
1458*b1cdbd2cSJim Jagielski     uno::Reference < io::XInputStream > pStream = new ::gvfs::Stream( handle, &m_info );
1459*b1cdbd2cSJim Jagielski     copyData( pStream, xTempOut );
1460*b1cdbd2cSJim Jagielski 
1461*b1cdbd2cSJim Jagielski     return uno::Reference < io::XInputStream > ( xTempOut, uno::UNO_QUERY );
1462*b1cdbd2cSJim Jagielski }
1463*b1cdbd2cSJim Jagielski 
1464*b1cdbd2cSJim Jagielski uno::Reference< io::XInputStream >
createInputStream(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1465*b1cdbd2cSJim Jagielski Content::createInputStream(
1466*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1467*b1cdbd2cSJim Jagielski         throw( uno::Exception )
1468*b1cdbd2cSJim Jagielski {
1469*b1cdbd2cSJim Jagielski     GnomeVFSHandle *handle = NULL;
1470*b1cdbd2cSJim Jagielski     GnomeVFSResult  result;
1471*b1cdbd2cSJim Jagielski     uno::Reference<io::XInputStream > xIn;
1472*b1cdbd2cSJim Jagielski 
1473*b1cdbd2cSJim Jagielski     Authentication aAuth( xEnv );
1474*b1cdbd2cSJim Jagielski         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1475*b1cdbd2cSJim Jagielski 
1476*b1cdbd2cSJim Jagielski     getInfo( xEnv );
1477*b1cdbd2cSJim Jagielski     ::rtl::OString aURI = getOURI();
1478*b1cdbd2cSJim Jagielski 
1479*b1cdbd2cSJim Jagielski     if ( !(m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) )
1480*b1cdbd2cSJim Jagielski         return createTempStream( xEnv );
1481*b1cdbd2cSJim Jagielski 
1482*b1cdbd2cSJim Jagielski     result = gnome_vfs_open( &handle, aURI.getStr(),
1483*b1cdbd2cSJim Jagielski           (GnomeVFSOpenMode) (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM ) );
1484*b1cdbd2cSJim Jagielski 
1485*b1cdbd2cSJim Jagielski     if (result == GNOME_VFS_ERROR_INVALID_OPEN_MODE ||
1486*b1cdbd2cSJim Jagielski         result == GNOME_VFS_ERROR_NOT_SUPPORTED)
1487*b1cdbd2cSJim Jagielski         return createTempStream( xEnv );
1488*b1cdbd2cSJim Jagielski 
1489*b1cdbd2cSJim Jagielski     if (result != GNOME_VFS_OK)
1490*b1cdbd2cSJim Jagielski         cancelCommandExecution( result, xEnv );
1491*b1cdbd2cSJim Jagielski 
1492*b1cdbd2cSJim Jagielski     // Try a seek just to make sure it's Random access: some lie.
1493*b1cdbd2cSJim Jagielski     result = gnome_vfs_seek( handle, GNOME_VFS_SEEK_START, 0);
1494*b1cdbd2cSJim Jagielski     if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) {
1495*b1cdbd2cSJim Jagielski         gnome_vfs_close( handle );
1496*b1cdbd2cSJim Jagielski         return createTempStream( xEnv );
1497*b1cdbd2cSJim Jagielski     }
1498*b1cdbd2cSJim Jagielski 
1499*b1cdbd2cSJim Jagielski     if (result != GNOME_VFS_OK)
1500*b1cdbd2cSJim Jagielski         cancelCommandExecution( result, xEnv );
1501*b1cdbd2cSJim Jagielski 
1502*b1cdbd2cSJim Jagielski     if (handle != NULL)
1503*b1cdbd2cSJim Jagielski         xIn = new ::gvfs::Stream( handle, &m_info );
1504*b1cdbd2cSJim Jagielski 
1505*b1cdbd2cSJim Jagielski     return xIn;
1506*b1cdbd2cSJim Jagielski }
1507*b1cdbd2cSJim Jagielski 
1508*b1cdbd2cSJim Jagielski sal_Bool
feedSink(uno::Reference<uno::XInterface> aSink,const uno::Reference<ucb::XCommandEnvironment> & xEnv)1509*b1cdbd2cSJim Jagielski Content::feedSink( uno::Reference< uno::XInterface > aSink,
1510*b1cdbd2cSJim Jagielski                    const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1511*b1cdbd2cSJim Jagielski {
1512*b1cdbd2cSJim Jagielski     if ( !aSink.is() )
1513*b1cdbd2cSJim Jagielski         return sal_False;
1514*b1cdbd2cSJim Jagielski 
1515*b1cdbd2cSJim Jagielski     uno::Reference< io::XOutputStream > xOut
1516*b1cdbd2cSJim Jagielski         = uno::Reference< io::XOutputStream >(aSink, uno::UNO_QUERY );
1517*b1cdbd2cSJim Jagielski     uno::Reference< io::XActiveDataSink > xDataSink
1518*b1cdbd2cSJim Jagielski         = uno::Reference< io::XActiveDataSink >(aSink, uno::UNO_QUERY );
1519*b1cdbd2cSJim Jagielski 
1520*b1cdbd2cSJim Jagielski     if ( !xOut.is() && !xDataSink.is() )
1521*b1cdbd2cSJim Jagielski         return sal_False;
1522*b1cdbd2cSJim Jagielski 
1523*b1cdbd2cSJim Jagielski     uno::Reference< io::XInputStream > xIn = createInputStream( xEnv );
1524*b1cdbd2cSJim Jagielski     if ( !xIn.is() )
1525*b1cdbd2cSJim Jagielski         return sal_False;
1526*b1cdbd2cSJim Jagielski 
1527*b1cdbd2cSJim Jagielski     if ( xOut.is() )
1528*b1cdbd2cSJim Jagielski         copyData( xIn, xOut );
1529*b1cdbd2cSJim Jagielski 
1530*b1cdbd2cSJim Jagielski     if ( xDataSink.is() )
1531*b1cdbd2cSJim Jagielski         xDataSink->setInputStream( xIn );
1532*b1cdbd2cSJim Jagielski 
1533*b1cdbd2cSJim Jagielski     return sal_True;
1534*b1cdbd2cSJim Jagielski }
1535*b1cdbd2cSJim Jagielski 
1536*b1cdbd2cSJim Jagielski extern "C" {
1537*b1cdbd2cSJim Jagielski 
1538*b1cdbd2cSJim Jagielski #ifndef GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION
1539*b1cdbd2cSJim Jagielski #  error "We require Gnome VFS 2.6.x to compile (will run fine with < 2.6)"
1540*b1cdbd2cSJim Jagielski #endif
1541*b1cdbd2cSJim Jagielski 
1542*b1cdbd2cSJim Jagielski     static void
vfs_authentication_callback(gconstpointer in_void,gsize in_size,gpointer out_void,gsize out_size,gpointer callback_data)1543*b1cdbd2cSJim Jagielski     vfs_authentication_callback (gconstpointer in_void,
1544*b1cdbd2cSJim Jagielski                      gsize         in_size,
1545*b1cdbd2cSJim Jagielski                      gpointer      out_void,
1546*b1cdbd2cSJim Jagielski                      gsize         out_size,
1547*b1cdbd2cSJim Jagielski                      gpointer      callback_data)
1548*b1cdbd2cSJim Jagielski     {
1549*b1cdbd2cSJim Jagielski         task::XInteractionHandler *xIH;
1550*b1cdbd2cSJim Jagielski 
1551*b1cdbd2cSJim Jagielski #ifdef DEBUG
1552*b1cdbd2cSJim Jagielski         g_warning ("Full authentication callback (%p) ...", callback_data);
1553*b1cdbd2cSJim Jagielski #endif
1554*b1cdbd2cSJim Jagielski 
1555*b1cdbd2cSJim Jagielski         if( !( xIH = (task::XInteractionHandler *) callback_data ) )
1556*b1cdbd2cSJim Jagielski             return;
1557*b1cdbd2cSJim Jagielski 
1558*b1cdbd2cSJim Jagielski         const GnomeVFSModuleCallbackFullAuthenticationIn *in =
1559*b1cdbd2cSJim Jagielski             (const GnomeVFSModuleCallbackFullAuthenticationIn *) in_void;
1560*b1cdbd2cSJim Jagielski         GnomeVFSModuleCallbackFullAuthenticationOut *out =
1561*b1cdbd2cSJim Jagielski             (GnomeVFSModuleCallbackFullAuthenticationOut *) out_void;
1562*b1cdbd2cSJim Jagielski 
1563*b1cdbd2cSJim Jagielski         g_return_if_fail (in != NULL && out != NULL);
1564*b1cdbd2cSJim Jagielski         g_return_if_fail (sizeof (GnomeVFSModuleCallbackFullAuthenticationIn) == in_size &&
1565*b1cdbd2cSJim Jagielski                   sizeof (GnomeVFSModuleCallbackFullAuthenticationOut) == out_size);
1566*b1cdbd2cSJim Jagielski 
1567*b1cdbd2cSJim Jagielski #ifdef DEBUG
1568*b1cdbd2cSJim Jagielski #  define NNIL(x) (x?x:"<Null>")
1569*b1cdbd2cSJim Jagielski         g_warning (" InComing data 0x%x uri '%s' prot '%s' server '%s' object '%s' "
1570*b1cdbd2cSJim Jagielski                    "port %d auth_t '%s' user '%s' domain '%s' "
1571*b1cdbd2cSJim Jagielski                    "def user '%s', def domain '%s'",
1572*b1cdbd2cSJim Jagielski                    (int) in->flags, NNIL(in->uri), NNIL(in->protocol),
1573*b1cdbd2cSJim Jagielski                    NNIL(in->server), NNIL(in->object),
1574*b1cdbd2cSJim Jagielski                    (int) in->port, NNIL(in->authtype), NNIL(in->username), NNIL(in->domain),
1575*b1cdbd2cSJim Jagielski                    NNIL(in->default_user), NNIL(in->default_domain));
1576*b1cdbd2cSJim Jagielski #  undef NNIL
1577*b1cdbd2cSJim Jagielski #endif
1578*b1cdbd2cSJim Jagielski 
1579*b1cdbd2cSJim Jagielski         ucbhelper::SimpleAuthenticationRequest::EntityType
1580*b1cdbd2cSJim Jagielski                                    eDomain, eUserName, ePassword;
1581*b1cdbd2cSJim Jagielski         ::rtl::OUString aHostName, aDomain, aUserName, aPassword;
1582*b1cdbd2cSJim Jagielski 
1583*b1cdbd2cSJim Jagielski         aHostName = GnomeToOUString( in->server );
1584*b1cdbd2cSJim Jagielski 
1585*b1cdbd2cSJim Jagielski         if (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN)
1586*b1cdbd2cSJim Jagielski         {
1587*b1cdbd2cSJim Jagielski             aDomain = GnomeToOUString( in->domain );
1588*b1cdbd2cSJim Jagielski             eDomain = ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY;
1589*b1cdbd2cSJim Jagielski             if (!aDomain.getLength())
1590*b1cdbd2cSJim Jagielski                 aDomain = GnomeToOUString( in->default_domain );
1591*b1cdbd2cSJim Jagielski         }
1592*b1cdbd2cSJim Jagielski         else // no underlying capability to display realm otherwise
1593*b1cdbd2cSJim Jagielski             eDomain = ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
1594*b1cdbd2cSJim Jagielski 
1595*b1cdbd2cSJim Jagielski         aUserName = GnomeToOUString( in->username );
1596*b1cdbd2cSJim Jagielski         if (!aUserName.getLength())
1597*b1cdbd2cSJim Jagielski             aUserName = GnomeToOUString( in->default_user );
1598*b1cdbd2cSJim Jagielski         eUserName = (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME) ?
1599*b1cdbd2cSJim Jagielski             ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY :
1600*b1cdbd2cSJim Jagielski                 (aUserName.getLength() ?
1601*b1cdbd2cSJim Jagielski                     ucbhelper::SimpleAuthenticationRequest::ENTITY_FIXED :
1602*b1cdbd2cSJim Jagielski                     ucbhelper::SimpleAuthenticationRequest::ENTITY_NA);
1603*b1cdbd2cSJim Jagielski 
1604*b1cdbd2cSJim Jagielski         // No suggested password.
1605*b1cdbd2cSJim Jagielski         ePassword = (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_PASSWORD) ?
1606*b1cdbd2cSJim Jagielski             ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY :
1607*b1cdbd2cSJim Jagielski             ucbhelper::SimpleAuthenticationRequest::ENTITY_FIXED;
1608*b1cdbd2cSJim Jagielski 
1609*b1cdbd2cSJim Jagielski         // Really, really bad things happen if we don't provide
1610*b1cdbd2cSJim Jagielski         // the same user/password as was entered last time if
1611*b1cdbd2cSJim Jagielski         // we failed to authenticate - infinite looping / flickering
1612*b1cdbd2cSJim Jagielski         // madness etc. [ nice infrastructure ! ]
1613*b1cdbd2cSJim Jagielski         static rtl::OUString aLastUserName, aLastPassword;
1614*b1cdbd2cSJim Jagielski         if (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED)
1615*b1cdbd2cSJim Jagielski         {
1616*b1cdbd2cSJim Jagielski             osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
1617*b1cdbd2cSJim Jagielski             aUserName = aLastUserName;
1618*b1cdbd2cSJim Jagielski             aPassword = aLastPassword;
1619*b1cdbd2cSJim Jagielski         }
1620*b1cdbd2cSJim Jagielski 
1621*b1cdbd2cSJim Jagielski         rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
1622*b1cdbd2cSJim Jagielski             = new ucbhelper::SimpleAuthenticationRequest (GnomeToOUString(in->uri),
1623*b1cdbd2cSJim Jagielski                                                           aHostName, eDomain, aDomain,
1624*b1cdbd2cSJim Jagielski                                                           eUserName, aUserName,
1625*b1cdbd2cSJim Jagielski                                                           ePassword, aPassword);
1626*b1cdbd2cSJim Jagielski 
1627*b1cdbd2cSJim Jagielski         xIH->handle( xRequest.get() );
1628*b1cdbd2cSJim Jagielski 
1629*b1cdbd2cSJim Jagielski         rtl::Reference< ucbhelper::InteractionContinuation > xSelection
1630*b1cdbd2cSJim Jagielski             = xRequest->getSelection();
1631*b1cdbd2cSJim Jagielski 
1632*b1cdbd2cSJim Jagielski         if ( xSelection.is() ) {
1633*b1cdbd2cSJim Jagielski             // Handler handled the request.
1634*b1cdbd2cSJim Jagielski             uno::Reference< task::XInteractionAbort > xAbort(xSelection.get(), uno::UNO_QUERY );
1635*b1cdbd2cSJim Jagielski             if ( !xAbort.is() ) {
1636*b1cdbd2cSJim Jagielski                 const rtl::Reference<
1637*b1cdbd2cSJim Jagielski                     ucbhelper::InteractionSupplyAuthentication > & xSupp
1638*b1cdbd2cSJim Jagielski                     = xRequest->getAuthenticationSupplier();
1639*b1cdbd2cSJim Jagielski 
1640*b1cdbd2cSJim Jagielski                 aUserName = xSupp->getUserName();
1641*b1cdbd2cSJim Jagielski                 aDomain   = xSupp->getRealm();
1642*b1cdbd2cSJim Jagielski                 aPassword = xSupp->getPassword();
1643*b1cdbd2cSJim Jagielski 
1644*b1cdbd2cSJim Jagielski                 {
1645*b1cdbd2cSJim Jagielski                     osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
1646*b1cdbd2cSJim Jagielski                     aLastUserName = aUserName;
1647*b1cdbd2cSJim Jagielski                     aLastPassword = aPassword;
1648*b1cdbd2cSJim Jagielski                 }
1649*b1cdbd2cSJim Jagielski 
1650*b1cdbd2cSJim Jagielski                 out->username = OUStringToGnome( aUserName );
1651*b1cdbd2cSJim Jagielski                 out->domain   = OUStringToGnome( aDomain );
1652*b1cdbd2cSJim Jagielski                 out->password = OUStringToGnome( aPassword );
1653*b1cdbd2cSJim Jagielski                 out->save_password = xSupp->getRememberPasswordMode();
1654*b1cdbd2cSJim Jagielski 
1655*b1cdbd2cSJim Jagielski #ifdef DEBUG
1656*b1cdbd2cSJim Jagielski                 g_warning ("Got valid user/domain/password '%s' '%s' '%s', %s password",
1657*b1cdbd2cSJim Jagielski                            out->username, out->domain, out->password,
1658*b1cdbd2cSJim Jagielski                            out->save_password ? "save" : "don't save");
1659*b1cdbd2cSJim Jagielski #endif
1660*b1cdbd2cSJim Jagielski             }
1661*b1cdbd2cSJim Jagielski             else
1662*b1cdbd2cSJim Jagielski                 out->abort_auth = TRUE;
1663*b1cdbd2cSJim Jagielski         }
1664*b1cdbd2cSJim Jagielski         else
1665*b1cdbd2cSJim Jagielski             out->abort_auth = TRUE;
1666*b1cdbd2cSJim Jagielski     }
1667*b1cdbd2cSJim Jagielski 
1668*b1cdbd2cSJim Jagielski     static void
vfs_authentication_old_callback(gconstpointer in_void,gsize in_size,gpointer out_void,gsize out_size,gpointer callback_data)1669*b1cdbd2cSJim Jagielski     vfs_authentication_old_callback (gconstpointer in_void,
1670*b1cdbd2cSJim Jagielski                                      gsize         in_size,
1671*b1cdbd2cSJim Jagielski                                      gpointer      out_void,
1672*b1cdbd2cSJim Jagielski                                      gsize         out_size,
1673*b1cdbd2cSJim Jagielski                                      gpointer      callback_data)
1674*b1cdbd2cSJim Jagielski     {
1675*b1cdbd2cSJim Jagielski #ifdef DEBUG
1676*b1cdbd2cSJim Jagielski         g_warning ("Old authentication callback (%p) [ UNTESTED ] ...", callback_data);
1677*b1cdbd2cSJim Jagielski #endif
1678*b1cdbd2cSJim Jagielski         const GnomeVFSModuleCallbackAuthenticationIn *in =
1679*b1cdbd2cSJim Jagielski             (const GnomeVFSModuleCallbackAuthenticationIn *) in_void;
1680*b1cdbd2cSJim Jagielski         GnomeVFSModuleCallbackAuthenticationOut *out =
1681*b1cdbd2cSJim Jagielski             (GnomeVFSModuleCallbackAuthenticationOut *) out_void;
1682*b1cdbd2cSJim Jagielski 
1683*b1cdbd2cSJim Jagielski         g_return_if_fail (in != NULL && out != NULL);
1684*b1cdbd2cSJim Jagielski         g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size &&
1685*b1cdbd2cSJim Jagielski                   sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
1686*b1cdbd2cSJim Jagielski 
1687*b1cdbd2cSJim Jagielski         GnomeVFSModuleCallbackFullAuthenticationIn mapped_in = {
1688*b1cdbd2cSJim Jagielski                 (GnomeVFSModuleCallbackFullAuthenticationFlags)
1689*b1cdbd2cSJim Jagielski                 (GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_PASSWORD |
1690*b1cdbd2cSJim Jagielski                  GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME |
1691*b1cdbd2cSJim Jagielski                  GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN),
1692*b1cdbd2cSJim Jagielski                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1693*b1cdbd2cSJim Jagielski         GnomeVFSModuleCallbackFullAuthenticationOut mapped_out = { 0, 0, 0, 0, 0, 0, 0, 0 };
1694*b1cdbd2cSJim Jagielski 
1695*b1cdbd2cSJim Jagielski         // Map the old style input auth. data to the new style structure.
1696*b1cdbd2cSJim Jagielski         if (in->previous_attempt_failed)
1697*b1cdbd2cSJim Jagielski             mapped_in.flags = (GnomeVFSModuleCallbackFullAuthenticationFlags)
1698*b1cdbd2cSJim Jagielski                 (mapped_in.flags |
1699*b1cdbd2cSJim Jagielski                  GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED);
1700*b1cdbd2cSJim Jagielski 
1701*b1cdbd2cSJim Jagielski         GnomeVFSURI *pURI = NULL;
1702*b1cdbd2cSJim Jagielski         // Urk - parse all this from the URL ...
1703*b1cdbd2cSJim Jagielski         mapped_in.uri = in->uri;
1704*b1cdbd2cSJim Jagielski         if (in->uri)
1705*b1cdbd2cSJim Jagielski         {
1706*b1cdbd2cSJim Jagielski             pURI = gnome_vfs_uri_new( in->uri );
1707*b1cdbd2cSJim Jagielski             mapped_in.protocol = (char *) gnome_vfs_uri_get_scheme (pURI);
1708*b1cdbd2cSJim Jagielski             mapped_in.server   = (char *) gnome_vfs_uri_get_host_name (pURI);
1709*b1cdbd2cSJim Jagielski             mapped_in.port     = gnome_vfs_uri_get_host_port (pURI);
1710*b1cdbd2cSJim Jagielski             mapped_in.username = (char *) gnome_vfs_uri_get_user_name (pURI);
1711*b1cdbd2cSJim Jagielski         }
1712*b1cdbd2cSJim Jagielski         mapped_in.domain = in->realm;
1713*b1cdbd2cSJim Jagielski         mapped_in.default_user = mapped_in.username;
1714*b1cdbd2cSJim Jagielski         mapped_in.default_domain = mapped_in.domain;
1715*b1cdbd2cSJim Jagielski 
1716*b1cdbd2cSJim Jagielski         vfs_authentication_callback ((gconstpointer) &mapped_in,
1717*b1cdbd2cSJim Jagielski                                      sizeof (mapped_in),
1718*b1cdbd2cSJim Jagielski                                      (gpointer) &mapped_out,
1719*b1cdbd2cSJim Jagielski                                      sizeof (mapped_out),
1720*b1cdbd2cSJim Jagielski                                      callback_data);
1721*b1cdbd2cSJim Jagielski 
1722*b1cdbd2cSJim Jagielski         if (pURI)
1723*b1cdbd2cSJim Jagielski             gnome_vfs_uri_unref (pURI);
1724*b1cdbd2cSJim Jagielski 
1725*b1cdbd2cSJim Jagielski         // Map the new style auth. out data to the old style out structure.
1726*b1cdbd2cSJim Jagielski         out->username = mapped_out.username;
1727*b1cdbd2cSJim Jagielski         out->password = mapped_out.password;
1728*b1cdbd2cSJim Jagielski         g_free (mapped_out.domain);
1729*b1cdbd2cSJim Jagielski         g_free (mapped_out.keyring);
1730*b1cdbd2cSJim Jagielski     }
1731*b1cdbd2cSJim Jagielski 
1732*b1cdbd2cSJim Jagielski 
1733*b1cdbd2cSJim Jagielski     static void
auth_destroy(gpointer data)1734*b1cdbd2cSJim Jagielski     auth_destroy (gpointer data)
1735*b1cdbd2cSJim Jagielski     {
1736*b1cdbd2cSJim Jagielski         task::XInteractionHandler *xIH;
1737*b1cdbd2cSJim Jagielski         if( ( xIH = ( task::XInteractionHandler * )data ) )
1738*b1cdbd2cSJim Jagielski             xIH->release();
1739*b1cdbd2cSJim Jagielski     }
1740*b1cdbd2cSJim Jagielski 
1741*b1cdbd2cSJim Jagielski     // This sucks, but gnome-vfs doesn't much like
1742*b1cdbd2cSJim Jagielski     // repeated set / unsets - so we have to compensate.
1743*b1cdbd2cSJim Jagielski     GPrivate *auth_queue = NULL;
1744*b1cdbd2cSJim Jagielski 
auth_queue_destroy(gpointer data)1745*b1cdbd2cSJim Jagielski     void auth_queue_destroy( gpointer data )
1746*b1cdbd2cSJim Jagielski     {
1747*b1cdbd2cSJim Jagielski         GList  *l;
1748*b1cdbd2cSJim Jagielski         GQueue *vq = (GQueue *) data;
1749*b1cdbd2cSJim Jagielski 
1750*b1cdbd2cSJim Jagielski         for (l = vq->head; l; l = l->next)
1751*b1cdbd2cSJim Jagielski             auth_destroy (l->data);
1752*b1cdbd2cSJim Jagielski         g_queue_free (vq);
1753*b1cdbd2cSJim Jagielski     }
1754*b1cdbd2cSJim Jagielski }
1755*b1cdbd2cSJim Jagielski 
1756*b1cdbd2cSJim Jagielski static void
refresh_auth(GQueue * vq)1757*b1cdbd2cSJim Jagielski refresh_auth( GQueue *vq )
1758*b1cdbd2cSJim Jagielski {
1759*b1cdbd2cSJim Jagielski     GList *l;
1760*b1cdbd2cSJim Jagielski 
1761*b1cdbd2cSJim Jagielski     gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION );
1762*b1cdbd2cSJim Jagielski     gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION );
1763*b1cdbd2cSJim Jagielski 
1764*b1cdbd2cSJim Jagielski     for (l = vq->head; l; l = l->next) {
1765*b1cdbd2cSJim Jagielski         if (l->data) {
1766*b1cdbd2cSJim Jagielski             gnome_vfs_module_callback_push
1767*b1cdbd2cSJim Jagielski                 ( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
1768*b1cdbd2cSJim Jagielski                   vfs_authentication_old_callback, l->data, NULL );
1769*b1cdbd2cSJim Jagielski             gnome_vfs_module_callback_push
1770*b1cdbd2cSJim Jagielski                 ( GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION,
1771*b1cdbd2cSJim Jagielski                   vfs_authentication_callback, l->data, NULL );
1772*b1cdbd2cSJim Jagielski             break;
1773*b1cdbd2cSJim Jagielski         }
1774*b1cdbd2cSJim Jagielski     }
1775*b1cdbd2cSJim Jagielski }
1776*b1cdbd2cSJim Jagielski 
Authentication(const uno::Reference<ucb::XCommandEnvironment> & xEnv)1777*b1cdbd2cSJim Jagielski gvfs::Authentication::Authentication(
1778*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1779*b1cdbd2cSJim Jagielski {
1780*b1cdbd2cSJim Jagielski     GQueue *vq;
1781*b1cdbd2cSJim Jagielski     uno::Reference< task::XInteractionHandler > xIH;
1782*b1cdbd2cSJim Jagielski 
1783*b1cdbd2cSJim Jagielski     if ( xEnv.is() )
1784*b1cdbd2cSJim Jagielski         xIH = xEnv->getInteractionHandler();
1785*b1cdbd2cSJim Jagielski 
1786*b1cdbd2cSJim Jagielski     if ( xIH.is() )
1787*b1cdbd2cSJim Jagielski         xIH->acquire();
1788*b1cdbd2cSJim Jagielski 
1789*b1cdbd2cSJim Jagielski     if( !(vq = (GQueue *)g_private_get( auth_queue ) ) ) {
1790*b1cdbd2cSJim Jagielski         vq = g_queue_new();
1791*b1cdbd2cSJim Jagielski         g_private_set( auth_queue, vq );
1792*b1cdbd2cSJim Jagielski     }
1793*b1cdbd2cSJim Jagielski 
1794*b1cdbd2cSJim Jagielski     g_queue_push_head( vq, (gpointer) xIH.get() );
1795*b1cdbd2cSJim Jagielski     refresh_auth( vq );
1796*b1cdbd2cSJim Jagielski }
1797*b1cdbd2cSJim Jagielski 
~Authentication()1798*b1cdbd2cSJim Jagielski gvfs::Authentication::~Authentication()
1799*b1cdbd2cSJim Jagielski {
1800*b1cdbd2cSJim Jagielski     GQueue *vq;
1801*b1cdbd2cSJim Jagielski     gpointer data;
1802*b1cdbd2cSJim Jagielski 
1803*b1cdbd2cSJim Jagielski     vq = (GQueue *)g_private_get( auth_queue );
1804*b1cdbd2cSJim Jagielski 
1805*b1cdbd2cSJim Jagielski     data = g_queue_pop_head( vq );
1806*b1cdbd2cSJim Jagielski     auth_destroy (data);
1807*b1cdbd2cSJim Jagielski 
1808*b1cdbd2cSJim Jagielski     refresh_auth( vq );
1809*b1cdbd2cSJim Jagielski }
1810