xref: /AOO41X/main/ucb/source/ucp/webdav/webdavcontent.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_ucb.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir /**************************************************************************
32*cdf0e10cSrcweir                                   TODO
33*cdf0e10cSrcweir  **************************************************************************
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir  *************************************************************************/
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <osl/diagnose.h>
38*cdf0e10cSrcweir #include "osl/doublecheckedlocking.h"
39*cdf0e10cSrcweir #include <rtl/uri.hxx>
40*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
41*cdf0e10cSrcweir #include <ucbhelper/contentidentifier.hxx>
42*cdf0e10cSrcweir #include <ucbhelper/propertyvalueset.hxx>
43*cdf0e10cSrcweir #include <ucbhelper/simpleinteractionrequest.hxx>
44*cdf0e10cSrcweir #include <ucbhelper/cancelcommandexecution.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/beans/PropertySetInfoChange.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalAccessException.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/ucb/CommandEnvironment.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/ucb/CommandFailedException.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/ucb/InsertCommandArgument.hpp>
58*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
59*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
60*cdf0e10cSrcweir #include "com/sun/star/ucb/InteractiveLockingLockedException.hpp"
61*cdf0e10cSrcweir #include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp"
62*cdf0e10cSrcweir #include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp"
63*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
64*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
65*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
66*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
67*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
68*cdf0e10cSrcweir #include <com/sun/star/ucb/MissingInputStreamException.hpp>
69*cdf0e10cSrcweir #include <com/sun/star/ucb/MissingPropertiesException.hpp>
70*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClash.hpp>
71*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClashException.hpp>
72*cdf0e10cSrcweir #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
73*cdf0e10cSrcweir #include <com/sun/star/ucb/OpenMode.hpp>
74*cdf0e10cSrcweir #include <com/sun/star/ucb/PostCommandArgument2.hpp>
75*cdf0e10cSrcweir #include <com/sun/star/ucb/TransferInfo.hpp>
76*cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
77*cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
78*cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
79*cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
80*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandInfo.hpp>
81*cdf0e10cSrcweir #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
82*cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir #include "webdavcontent.hxx"
85*cdf0e10cSrcweir #include "webdavprovider.hxx"
86*cdf0e10cSrcweir #include "webdavresultset.hxx"
87*cdf0e10cSrcweir #include "ContentProperties.hxx"
88*cdf0e10cSrcweir #include "NeonUri.hxx"
89*cdf0e10cSrcweir #include "UCBDeadPropertyValue.hxx"
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir using namespace com::sun::star;
92*cdf0e10cSrcweir using namespace webdav_ucp;
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir //=========================================================================
95*cdf0e10cSrcweir //=========================================================================
96*cdf0e10cSrcweir //
97*cdf0e10cSrcweir // Content Implementation.
98*cdf0e10cSrcweir //
99*cdf0e10cSrcweir //=========================================================================
100*cdf0e10cSrcweir //=========================================================================
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir //=========================================================================
103*cdf0e10cSrcweir // ctr for content on an existing webdav resource
104*cdf0e10cSrcweir Content::Content(
105*cdf0e10cSrcweir           const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
106*cdf0e10cSrcweir           ContentProvider* pProvider,
107*cdf0e10cSrcweir           const uno::Reference< ucb::XContentIdentifier >& Identifier,
108*cdf0e10cSrcweir           rtl::Reference< DAVSessionFactory > const & rSessionFactory )
109*cdf0e10cSrcweir   throw ( ucb::ContentCreationException )
110*cdf0e10cSrcweir : ContentImplHelper( rxSMgr, pProvider, Identifier ),
111*cdf0e10cSrcweir   m_eResourceType( UNKNOWN ),
112*cdf0e10cSrcweir   m_pProvider( pProvider ),
113*cdf0e10cSrcweir   m_bTransient( false ),
114*cdf0e10cSrcweir   m_bCollection( false ),
115*cdf0e10cSrcweir   m_bDidGetOrHead( false )
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir     try
118*cdf0e10cSrcweir     {
119*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess(
120*cdf0e10cSrcweir                 rxSMgr,
121*cdf0e10cSrcweir                 rSessionFactory,
122*cdf0e10cSrcweir                 Identifier->getContentIdentifier() ) );
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir         NeonUri aURI( Identifier->getContentIdentifier() );
125*cdf0e10cSrcweir         m_aEscapedTitle = aURI.GetPathBaseName();
126*cdf0e10cSrcweir     }
127*cdf0e10cSrcweir     catch ( DAVException const & )
128*cdf0e10cSrcweir     {
129*cdf0e10cSrcweir         throw ucb::ContentCreationException();
130*cdf0e10cSrcweir     }
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir //=========================================================================
134*cdf0e10cSrcweir // ctr for content on an non-existing webdav resource
135*cdf0e10cSrcweir Content::Content(
136*cdf0e10cSrcweir             const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
137*cdf0e10cSrcweir             ContentProvider* pProvider,
138*cdf0e10cSrcweir             const uno::Reference< ucb::XContentIdentifier >& Identifier,
139*cdf0e10cSrcweir             rtl::Reference< DAVSessionFactory > const & rSessionFactory,
140*cdf0e10cSrcweir             sal_Bool isCollection )
141*cdf0e10cSrcweir   throw ( ucb::ContentCreationException )
142*cdf0e10cSrcweir : ContentImplHelper( rxSMgr, pProvider, Identifier ),
143*cdf0e10cSrcweir   m_eResourceType( UNKNOWN ),
144*cdf0e10cSrcweir   m_pProvider( pProvider ),
145*cdf0e10cSrcweir   m_bTransient( true ),
146*cdf0e10cSrcweir   m_bCollection( isCollection ),
147*cdf0e10cSrcweir   m_bDidGetOrHead( false )
148*cdf0e10cSrcweir {
149*cdf0e10cSrcweir     try
150*cdf0e10cSrcweir     {
151*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess(
152*cdf0e10cSrcweir             rxSMgr, rSessionFactory, Identifier->getContentIdentifier() ) );
153*cdf0e10cSrcweir     }
154*cdf0e10cSrcweir     catch ( DAVException const & )
155*cdf0e10cSrcweir     {
156*cdf0e10cSrcweir         throw ucb::ContentCreationException();
157*cdf0e10cSrcweir     }
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir     // Do not set m_aEscapedTitle here! Content::insert relays on this!!!
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir //=========================================================================
163*cdf0e10cSrcweir // virtual
164*cdf0e10cSrcweir Content::~Content()
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir //=========================================================================
169*cdf0e10cSrcweir //
170*cdf0e10cSrcweir // XInterface methods.
171*cdf0e10cSrcweir //
172*cdf0e10cSrcweir //=========================================================================
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir // virtual
175*cdf0e10cSrcweir void SAL_CALL Content::acquire()
176*cdf0e10cSrcweir     throw( )
177*cdf0e10cSrcweir {
178*cdf0e10cSrcweir     ContentImplHelper::acquire();
179*cdf0e10cSrcweir }
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir //=========================================================================
182*cdf0e10cSrcweir // virtual
183*cdf0e10cSrcweir void SAL_CALL Content::release()
184*cdf0e10cSrcweir     throw( )
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir     ContentImplHelper::release();
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir //=========================================================================
190*cdf0e10cSrcweir // virtual
191*cdf0e10cSrcweir uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
192*cdf0e10cSrcweir     throw ( uno::RuntimeException )
193*cdf0e10cSrcweir {
194*cdf0e10cSrcweir     // Note: isFolder may require network activities! So call it only
195*cdf0e10cSrcweir     //       if it is really necessary!!!
196*cdf0e10cSrcweir     uno::Any aRet = cppu::queryInterface(
197*cdf0e10cSrcweir         rType,
198*cdf0e10cSrcweir         static_cast< ucb::XContentCreator * >( this ) );
199*cdf0e10cSrcweir     if ( aRet.hasValue() )
200*cdf0e10cSrcweir     {
201*cdf0e10cSrcweir         try
202*cdf0e10cSrcweir         {
203*cdf0e10cSrcweir             uno::Reference< beans::XPropertySet > const xProps(
204*cdf0e10cSrcweir                 m_xSMgr, uno::UNO_QUERY_THROW );
205*cdf0e10cSrcweir             uno::Reference< uno::XComponentContext > xCtx;
206*cdf0e10cSrcweir             xCtx.set( xProps->getPropertyValue(
207*cdf0e10cSrcweir                 rtl::OUString(
208*cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
209*cdf0e10cSrcweir                 uno::UNO_QUERY_THROW );
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir             uno::Reference< task::XInteractionHandler > xIH(
212*cdf0e10cSrcweir                 task::PasswordContainerInteractionHandler::create( xCtx ) );
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir             // Supply a command env to isFolder() that contains an interaction
215*cdf0e10cSrcweir             // handler that uses the password container service to obtain
216*cdf0e10cSrcweir             // credentials without displaying a password gui.
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir             uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
219*cdf0e10cSrcweir                 ucb::CommandEnvironment::create(
220*cdf0e10cSrcweir                    xCtx,
221*cdf0e10cSrcweir                    xIH,
222*cdf0e10cSrcweir                    uno::Reference< ucb::XProgressHandler >() ) );
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir             return isFolder( xCmdEnv ) ? aRet : uno::Any();
225*cdf0e10cSrcweir         }
226*cdf0e10cSrcweir         catch ( uno::RuntimeException const & )
227*cdf0e10cSrcweir         {
228*cdf0e10cSrcweir             throw;
229*cdf0e10cSrcweir         }
230*cdf0e10cSrcweir         catch ( uno::Exception const & )
231*cdf0e10cSrcweir         {
232*cdf0e10cSrcweir             return uno::Any();
233*cdf0e10cSrcweir         }
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir     return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir //=========================================================================
239*cdf0e10cSrcweir //
240*cdf0e10cSrcweir // XTypeProvider methods.
241*cdf0e10cSrcweir //
242*cdf0e10cSrcweir //=========================================================================
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir XTYPEPROVIDER_COMMON_IMPL( Content );
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir //=========================================================================
247*cdf0e10cSrcweir // virtual
248*cdf0e10cSrcweir uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
249*cdf0e10cSrcweir     throw( uno::RuntimeException )
250*cdf0e10cSrcweir {
251*cdf0e10cSrcweir     sal_Bool bFolder = sal_False;
252*cdf0e10cSrcweir     try
253*cdf0e10cSrcweir     {
254*cdf0e10cSrcweir         bFolder
255*cdf0e10cSrcweir             = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
256*cdf0e10cSrcweir     }
257*cdf0e10cSrcweir     catch ( uno::RuntimeException const & )
258*cdf0e10cSrcweir     {
259*cdf0e10cSrcweir         throw;
260*cdf0e10cSrcweir     }
261*cdf0e10cSrcweir     catch ( uno::Exception const & )
262*cdf0e10cSrcweir     {
263*cdf0e10cSrcweir     }
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir     cppu::OTypeCollection * pCollection = 0;
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir     if ( bFolder )
268*cdf0e10cSrcweir     {
269*cdf0e10cSrcweir         static cppu::OTypeCollection* pFolderTypes = 0;
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir         pCollection = pFolderTypes;
272*cdf0e10cSrcweir         if ( !pCollection )
273*cdf0e10cSrcweir         {
274*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir             pCollection = pFolderTypes;
277*cdf0e10cSrcweir             if ( !pCollection )
278*cdf0e10cSrcweir             {
279*cdf0e10cSrcweir                 static cppu::OTypeCollection aCollection(
280*cdf0e10cSrcweir                     CPPU_TYPE_REF( lang::XTypeProvider ),
281*cdf0e10cSrcweir                         CPPU_TYPE_REF( lang::XServiceInfo ),
282*cdf0e10cSrcweir                         CPPU_TYPE_REF( lang::XComponent ),
283*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XContent ),
284*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XCommandProcessor ),
285*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
286*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
287*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertyContainer ),
288*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
289*cdf0e10cSrcweir                         CPPU_TYPE_REF( container::XChild ),
290*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
291*cdf0e10cSrcweir                 pCollection = &aCollection;
292*cdf0e10cSrcweir                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
293*cdf0e10cSrcweir                 pFolderTypes = pCollection;
294*cdf0e10cSrcweir             }
295*cdf0e10cSrcweir         }
296*cdf0e10cSrcweir         else {
297*cdf0e10cSrcweir             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
298*cdf0e10cSrcweir         }
299*cdf0e10cSrcweir     }
300*cdf0e10cSrcweir     else
301*cdf0e10cSrcweir     {
302*cdf0e10cSrcweir         static cppu::OTypeCollection* pDocumentTypes = 0;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir         pCollection = pDocumentTypes;
305*cdf0e10cSrcweir         if ( !pCollection )
306*cdf0e10cSrcweir         {
307*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir             pCollection = pDocumentTypes;
310*cdf0e10cSrcweir             if ( !pCollection )
311*cdf0e10cSrcweir             {
312*cdf0e10cSrcweir                 static cppu::OTypeCollection aCollection(
313*cdf0e10cSrcweir                         CPPU_TYPE_REF( lang::XTypeProvider ),
314*cdf0e10cSrcweir                         CPPU_TYPE_REF( lang::XServiceInfo ),
315*cdf0e10cSrcweir                         CPPU_TYPE_REF( lang::XComponent ),
316*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XContent ),
317*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XCommandProcessor ),
318*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
319*cdf0e10cSrcweir                         CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
320*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertyContainer ),
321*cdf0e10cSrcweir                         CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
322*cdf0e10cSrcweir                         CPPU_TYPE_REF( container::XChild ) );
323*cdf0e10cSrcweir                 pCollection = &aCollection;
324*cdf0e10cSrcweir                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
325*cdf0e10cSrcweir                 pDocumentTypes = pCollection;
326*cdf0e10cSrcweir             }
327*cdf0e10cSrcweir         }
328*cdf0e10cSrcweir         else {
329*cdf0e10cSrcweir             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
330*cdf0e10cSrcweir         }
331*cdf0e10cSrcweir     }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir     return (*pCollection).getTypes();
334*cdf0e10cSrcweir }
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir //=========================================================================
337*cdf0e10cSrcweir //
338*cdf0e10cSrcweir // XServiceInfo methods.
339*cdf0e10cSrcweir //
340*cdf0e10cSrcweir //=========================================================================
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir // virtual
343*cdf0e10cSrcweir rtl::OUString SAL_CALL Content::getImplementationName()
344*cdf0e10cSrcweir     throw( uno::RuntimeException )
345*cdf0e10cSrcweir {
346*cdf0e10cSrcweir     return rtl::OUString::createFromAscii(
347*cdf0e10cSrcweir                             "com.sun.star.comp.ucb.WebDAVContent" );
348*cdf0e10cSrcweir }
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir //=========================================================================
351*cdf0e10cSrcweir // virtual
352*cdf0e10cSrcweir uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
353*cdf0e10cSrcweir     throw( uno::RuntimeException )
354*cdf0e10cSrcweir {
355*cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aSNS( 1 );
356*cdf0e10cSrcweir     aSNS.getArray()[ 0 ]
357*cdf0e10cSrcweir         = rtl::OUString::createFromAscii( WEBDAV_CONTENT_SERVICE_NAME );
358*cdf0e10cSrcweir     return aSNS;
359*cdf0e10cSrcweir }
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir //=========================================================================
362*cdf0e10cSrcweir //
363*cdf0e10cSrcweir // XContent methods.
364*cdf0e10cSrcweir //
365*cdf0e10cSrcweir //=========================================================================
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir // virtual
368*cdf0e10cSrcweir rtl::OUString SAL_CALL Content::getContentType()
369*cdf0e10cSrcweir     throw( uno::RuntimeException )
370*cdf0e10cSrcweir {
371*cdf0e10cSrcweir     sal_Bool bFolder = sal_False;
372*cdf0e10cSrcweir     try
373*cdf0e10cSrcweir     {
374*cdf0e10cSrcweir         bFolder
375*cdf0e10cSrcweir             = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
376*cdf0e10cSrcweir     }
377*cdf0e10cSrcweir     catch ( uno::RuntimeException const & )
378*cdf0e10cSrcweir     {
379*cdf0e10cSrcweir         throw;
380*cdf0e10cSrcweir     }
381*cdf0e10cSrcweir     catch ( uno::Exception const & )
382*cdf0e10cSrcweir     {
383*cdf0e10cSrcweir     }
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir     if ( bFolder )
386*cdf0e10cSrcweir         return rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE );
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir     return rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE );
389*cdf0e10cSrcweir }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir //=========================================================================
392*cdf0e10cSrcweir //
393*cdf0e10cSrcweir // XCommandProcessor methods.
394*cdf0e10cSrcweir //
395*cdf0e10cSrcweir //=========================================================================
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir // virtual
398*cdf0e10cSrcweir uno::Any SAL_CALL Content::execute(
399*cdf0e10cSrcweir         const ucb::Command& aCommand,
400*cdf0e10cSrcweir         sal_Int32 /*CommandId*/,
401*cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment >& Environment )
402*cdf0e10cSrcweir     throw( uno::Exception,
403*cdf0e10cSrcweir            ucb::CommandAbortedException,
404*cdf0e10cSrcweir            uno::RuntimeException )
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir     OSL_TRACE( ">>>>> Content::execute: start: command: %s, env: %s",
407*cdf0e10cSrcweir                rtl::OUStringToOString( aCommand.Name,
408*cdf0e10cSrcweir                                        RTL_TEXTENCODING_UTF8 ).getStr(),
409*cdf0e10cSrcweir                Environment.is() ? "present" : "missing" );
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir     uno::Any aRet;
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir     if ( aCommand.Name.equalsAsciiL(
414*cdf0e10cSrcweir              RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
415*cdf0e10cSrcweir     {
416*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
417*cdf0e10cSrcweir         // getPropertyValues
418*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir         uno::Sequence< beans::Property > Properties;
421*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= Properties ) )
422*cdf0e10cSrcweir         {
423*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
424*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
425*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
426*cdf0e10cSrcweir                                         "Wrong argument type!" ),
427*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
428*cdf0e10cSrcweir                                     -1 ) ),
429*cdf0e10cSrcweir                 Environment );
430*cdf0e10cSrcweir             // Unreachable
431*cdf0e10cSrcweir         }
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir         aRet <<= getPropertyValues( Properties, Environment );
434*cdf0e10cSrcweir     }
435*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
436*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
437*cdf0e10cSrcweir     {
438*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
439*cdf0e10cSrcweir         // setPropertyValues
440*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aProperties;
443*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= aProperties ) )
444*cdf0e10cSrcweir         {
445*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
446*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
447*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
448*cdf0e10cSrcweir                                         "Wrong argument type!" ),
449*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
450*cdf0e10cSrcweir                                     -1 ) ),
451*cdf0e10cSrcweir                 Environment );
452*cdf0e10cSrcweir             // Unreachable
453*cdf0e10cSrcweir         }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir         if ( !aProperties.getLength() )
456*cdf0e10cSrcweir         {
457*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
458*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
459*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
460*cdf0e10cSrcweir                                         "No properties!" ),
461*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
462*cdf0e10cSrcweir                                     -1 ) ),
463*cdf0e10cSrcweir                 Environment );
464*cdf0e10cSrcweir             // Unreachable
465*cdf0e10cSrcweir         }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir         aRet <<= setPropertyValues( aProperties, Environment );
468*cdf0e10cSrcweir     }
469*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
470*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
471*cdf0e10cSrcweir     {
472*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
473*cdf0e10cSrcweir         // getPropertySetInfo
474*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir         // Note: Implemented by base class.
477*cdf0e10cSrcweir         aRet <<= getPropertySetInfo( Environment,
478*cdf0e10cSrcweir                                      sal_False /* don't cache data */ );
479*cdf0e10cSrcweir     }
480*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
481*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
482*cdf0e10cSrcweir     {
483*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
484*cdf0e10cSrcweir         // getCommandInfo
485*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir         // Note: Implemented by base class.
488*cdf0e10cSrcweir         aRet <<= getCommandInfo( Environment, sal_False );
489*cdf0e10cSrcweir     }
490*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
491*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
492*cdf0e10cSrcweir     {
493*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
494*cdf0e10cSrcweir         // open
495*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir         ucb::OpenCommandArgument2 aOpenCommand;
498*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= aOpenCommand ) )
499*cdf0e10cSrcweir         {
500*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
501*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
502*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
503*cdf0e10cSrcweir                                         "Wrong argument type!" ),
504*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
505*cdf0e10cSrcweir                                     -1 ) ),
506*cdf0e10cSrcweir                 Environment );
507*cdf0e10cSrcweir             // Unreachable
508*cdf0e10cSrcweir         }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir         aRet = open( aOpenCommand, Environment );
511*cdf0e10cSrcweir     }
512*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
513*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
514*cdf0e10cSrcweir     {
515*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
516*cdf0e10cSrcweir         // insert
517*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir         ucb::InsertCommandArgument arg;
520*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= arg ) )
521*cdf0e10cSrcweir         {
522*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
523*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
524*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
525*cdf0e10cSrcweir                                         "Wrong argument type!" ),
526*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
527*cdf0e10cSrcweir                                     -1 ) ),
528*cdf0e10cSrcweir                 Environment );
529*cdf0e10cSrcweir             // Unreachable
530*cdf0e10cSrcweir         }
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir         insert( arg.Data, arg.ReplaceExisting, Environment );
533*cdf0e10cSrcweir     }
534*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
535*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
536*cdf0e10cSrcweir     {
537*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
538*cdf0e10cSrcweir         // delete
539*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir         sal_Bool bDeletePhysical = sal_False;
542*cdf0e10cSrcweir         aCommand.Argument >>= bDeletePhysical;
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir //  KSO: Ignore parameter and destroy the content, if you don't support
545*cdf0e10cSrcweir //       putting objects into trashcan. ( Since we do not have a trash can
546*cdf0e10cSrcweir //       service yet (src603), you actually have no other choice. )
547*cdf0e10cSrcweir //      if ( bDeletePhysical )
548*cdf0e10cSrcweir //  {
549*cdf0e10cSrcweir         try
550*cdf0e10cSrcweir         {
551*cdf0e10cSrcweir             std::auto_ptr< DAVResourceAccess > xResAccess;
552*cdf0e10cSrcweir             {
553*cdf0e10cSrcweir                 osl::Guard< osl::Mutex > aGuard( m_aMutex );
554*cdf0e10cSrcweir                 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
555*cdf0e10cSrcweir             }
556*cdf0e10cSrcweir             xResAccess->DESTROY( Environment );
557*cdf0e10cSrcweir             {
558*cdf0e10cSrcweir                 osl::Guard< osl::Mutex > aGuard( m_aMutex );
559*cdf0e10cSrcweir                 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
560*cdf0e10cSrcweir             }
561*cdf0e10cSrcweir         }
562*cdf0e10cSrcweir         catch ( DAVException const & e )
563*cdf0e10cSrcweir         {
564*cdf0e10cSrcweir             cancelCommandExecution( e, Environment, sal_True );
565*cdf0e10cSrcweir             // Unreachable
566*cdf0e10cSrcweir         }
567*cdf0e10cSrcweir //      }
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir         // Propagate destruction.
570*cdf0e10cSrcweir         destroy( bDeletePhysical );
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir         // Remove own and all children's Additional Core Properties.
573*cdf0e10cSrcweir         removeAdditionalPropertySet( sal_True );
574*cdf0e10cSrcweir     }
575*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
576*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "transfer" ) )
577*cdf0e10cSrcweir               && isFolder( Environment ) )
578*cdf0e10cSrcweir     {
579*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
580*cdf0e10cSrcweir         // transfer
581*cdf0e10cSrcweir         //  ( Not available at documents )
582*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir         ucb::TransferInfo transferArgs;
585*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= transferArgs ) )
586*cdf0e10cSrcweir         {
587*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
588*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
589*cdf0e10cSrcweir                                   rtl::OUString::createFromAscii(
590*cdf0e10cSrcweir                                       "Wrong argument type!" ),
591*cdf0e10cSrcweir                                   static_cast< cppu::OWeakObject * >( this ),
592*cdf0e10cSrcweir                                   -1 ) ),
593*cdf0e10cSrcweir                 Environment );
594*cdf0e10cSrcweir             // Unreachable
595*cdf0e10cSrcweir         }
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir         transfer( transferArgs, Environment );
598*cdf0e10cSrcweir     }
599*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
600*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "post" ) ) )
601*cdf0e10cSrcweir     {
602*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
603*cdf0e10cSrcweir         // post
604*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir         ucb::PostCommandArgument2 aArg;
607*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= aArg ) )
608*cdf0e10cSrcweir         {
609*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
610*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
611*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
612*cdf0e10cSrcweir                                         "Wrong argument type!" ),
613*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
614*cdf0e10cSrcweir                                     -1 ) ),
615*cdf0e10cSrcweir                 Environment );
616*cdf0e10cSrcweir             // Unreachable
617*cdf0e10cSrcweir         }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir         post( aArg, Environment );
620*cdf0e10cSrcweir     }
621*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
622*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "lock" ) ) &&
623*cdf0e10cSrcweir               supportsExclusiveWriteLock( Environment ) )
624*cdf0e10cSrcweir     {
625*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
626*cdf0e10cSrcweir         // lock
627*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir         lock( Environment );
630*cdf0e10cSrcweir     }
631*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
632*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) &&
633*cdf0e10cSrcweir               supportsExclusiveWriteLock( Environment ) )
634*cdf0e10cSrcweir     {
635*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
636*cdf0e10cSrcweir         // unlock
637*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir         unlock( Environment );
640*cdf0e10cSrcweir     }
641*cdf0e10cSrcweir     else if ( aCommand.Name.equalsAsciiL(
642*cdf0e10cSrcweir                   RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) &&
643*cdf0e10cSrcweir               isFolder( Environment ) )
644*cdf0e10cSrcweir     {
645*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
646*cdf0e10cSrcweir         // createNewContent
647*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir         ucb::ContentInfo aArg;
650*cdf0e10cSrcweir         if ( !( aCommand.Argument >>= aArg ) )
651*cdf0e10cSrcweir         {
652*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
653*cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
654*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
655*cdf0e10cSrcweir                                         "Wrong argument type!" ),
656*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
657*cdf0e10cSrcweir                                     -1 ) ),
658*cdf0e10cSrcweir                 Environment );
659*cdf0e10cSrcweir             // Unreachable
660*cdf0e10cSrcweir         }
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir         aRet = uno::makeAny( createNewContent( aArg ) );
663*cdf0e10cSrcweir     }
664*cdf0e10cSrcweir     else
665*cdf0e10cSrcweir     {
666*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
667*cdf0e10cSrcweir         // Unsupported command
668*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
671*cdf0e10cSrcweir             uno::makeAny( ucb::UnsupportedCommandException(
672*cdf0e10cSrcweir                               aCommand.Name,
673*cdf0e10cSrcweir                               static_cast< cppu::OWeakObject * >( this ) ) ),
674*cdf0e10cSrcweir             Environment );
675*cdf0e10cSrcweir         // Unreachable
676*cdf0e10cSrcweir     }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir     OSL_TRACE( "<<<<< Content::execute: end: command: %s",
679*cdf0e10cSrcweir                rtl::OUStringToOString( aCommand.Name,
680*cdf0e10cSrcweir                                        RTL_TEXTENCODING_UTF8 ).getStr() );
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir     return aRet;
683*cdf0e10cSrcweir }
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir //=========================================================================
686*cdf0e10cSrcweir // virtual
687*cdf0e10cSrcweir void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
688*cdf0e10cSrcweir     throw( uno::RuntimeException )
689*cdf0e10cSrcweir {
690*cdf0e10cSrcweir     try
691*cdf0e10cSrcweir     {
692*cdf0e10cSrcweir         std::auto_ptr< DAVResourceAccess > xResAccess;
693*cdf0e10cSrcweir         {
694*cdf0e10cSrcweir             osl::MutexGuard aGuard( m_aMutex );
695*cdf0e10cSrcweir             xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
696*cdf0e10cSrcweir         }
697*cdf0e10cSrcweir         xResAccess->abort();
698*cdf0e10cSrcweir         {
699*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
700*cdf0e10cSrcweir             m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
701*cdf0e10cSrcweir         }
702*cdf0e10cSrcweir     }
703*cdf0e10cSrcweir     catch ( DAVException const & )
704*cdf0e10cSrcweir     {
705*cdf0e10cSrcweir         // abort failed!
706*cdf0e10cSrcweir     }
707*cdf0e10cSrcweir }
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir //=========================================================================
710*cdf0e10cSrcweir //
711*cdf0e10cSrcweir // XPropertyContainer methods.
712*cdf0e10cSrcweir //
713*cdf0e10cSrcweir //=========================================================================
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir // virtual
716*cdf0e10cSrcweir void SAL_CALL Content::addProperty( const rtl::OUString& Name,
717*cdf0e10cSrcweir                                     sal_Int16 Attributes,
718*cdf0e10cSrcweir                                     const uno::Any& DefaultValue )
719*cdf0e10cSrcweir     throw( beans::PropertyExistException,
720*cdf0e10cSrcweir            beans::IllegalTypeException,
721*cdf0e10cSrcweir            lang::IllegalArgumentException,
722*cdf0e10cSrcweir            uno::RuntimeException )
723*cdf0e10cSrcweir {
724*cdf0e10cSrcweir //    if ( m_bTransient )
725*cdf0e10cSrcweir //   @@@ ???
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir     if ( !Name.getLength() )
728*cdf0e10cSrcweir         throw lang::IllegalArgumentException();
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir     // Check property type.
731*cdf0e10cSrcweir     if ( !UCBDeadPropertyValue::supportsType( DefaultValue.getValueType() ) )
732*cdf0e10cSrcweir     {
733*cdf0e10cSrcweir         OSL_ENSURE( sal_False,
734*cdf0e10cSrcweir                     "Content::addProperty - Unsupported property type!" );
735*cdf0e10cSrcweir         throw beans::IllegalTypeException();
736*cdf0e10cSrcweir     }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
739*cdf0e10cSrcweir     // Make sure a property with the requested name does not already
740*cdf0e10cSrcweir     // exist in dynamic and static(!) properties.
741*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir     // @@@ Need real command environment here, but where to get it from?
744*cdf0e10cSrcweir     //     XPropertyContainer interface should be replaced by
745*cdf0e10cSrcweir     //     XCommandProcessor commands!
746*cdf0e10cSrcweir     uno::Reference< ucb::XCommandEnvironment > xEnv;
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir     // Note: This requires network access!
749*cdf0e10cSrcweir     if ( getPropertySetInfo( xEnv, sal_False /* don't cache data */ )
750*cdf0e10cSrcweir              ->hasPropertyByName( Name ) )
751*cdf0e10cSrcweir     {
752*cdf0e10cSrcweir         // Property does already exist.
753*cdf0e10cSrcweir         throw beans::PropertyExistException();
754*cdf0e10cSrcweir     }
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
757*cdf0e10cSrcweir     // Add a new dynamic property.
758*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir     ProppatchValue aValue( PROPSET, Name, DefaultValue );
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir     std::vector< ProppatchValue > aProppatchValues;
763*cdf0e10cSrcweir     aProppatchValues.push_back( aValue );
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir     try
766*cdf0e10cSrcweir     {
767*cdf0e10cSrcweir         // Set property value at server.
768*cdf0e10cSrcweir         std::auto_ptr< DAVResourceAccess > xResAccess;
769*cdf0e10cSrcweir         {
770*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
771*cdf0e10cSrcweir             xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
772*cdf0e10cSrcweir         }
773*cdf0e10cSrcweir         xResAccess->PROPPATCH( aProppatchValues, xEnv );
774*cdf0e10cSrcweir         {
775*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
776*cdf0e10cSrcweir             m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
777*cdf0e10cSrcweir         }
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir         // Notify propertyset info change listeners.
780*cdf0e10cSrcweir         beans::PropertySetInfoChangeEvent evt(
781*cdf0e10cSrcweir             static_cast< cppu::OWeakObject * >( this ),
782*cdf0e10cSrcweir             Name,
783*cdf0e10cSrcweir             -1, // No handle available
784*cdf0e10cSrcweir             beans::PropertySetInfoChange::PROPERTY_INSERTED );
785*cdf0e10cSrcweir         notifyPropertySetInfoChange( evt );
786*cdf0e10cSrcweir     }
787*cdf0e10cSrcweir     catch ( DAVException const & e )
788*cdf0e10cSrcweir     {
789*cdf0e10cSrcweir         if ( e.getStatus() == SC_FORBIDDEN )
790*cdf0e10cSrcweir         {
791*cdf0e10cSrcweir             // Support for setting arbitrary dead properties is optional!
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir             // Store property locally.
794*cdf0e10cSrcweir             ContentImplHelper::addProperty(
795*cdf0e10cSrcweir                 Name, Attributes, DefaultValue );
796*cdf0e10cSrcweir         }
797*cdf0e10cSrcweir         else
798*cdf0e10cSrcweir         {
799*cdf0e10cSrcweir             if ( shouldAccessNetworkAfterException( e ) )
800*cdf0e10cSrcweir             {
801*cdf0e10cSrcweir                 try
802*cdf0e10cSrcweir                 {
803*cdf0e10cSrcweir                     const ResourceType & rType = getResourceType( xEnv );
804*cdf0e10cSrcweir                     switch ( rType )
805*cdf0e10cSrcweir                     {
806*cdf0e10cSrcweir                     case UNKNOWN:
807*cdf0e10cSrcweir                     case DAV:
808*cdf0e10cSrcweir                         throw lang::IllegalArgumentException();
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir                     case FTP:
811*cdf0e10cSrcweir                     case NON_DAV:
812*cdf0e10cSrcweir                         // Store property locally.
813*cdf0e10cSrcweir                         ContentImplHelper::addProperty( Name,
814*cdf0e10cSrcweir                                                         Attributes,
815*cdf0e10cSrcweir                                                         DefaultValue );
816*cdf0e10cSrcweir                         break;
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir                     default:
819*cdf0e10cSrcweir                         OSL_ENSURE( sal_False,
820*cdf0e10cSrcweir                                     "Content::addProperty - "
821*cdf0e10cSrcweir                                     "Unsupported resource type!" );
822*cdf0e10cSrcweir                         break;
823*cdf0e10cSrcweir                     }
824*cdf0e10cSrcweir                 }
825*cdf0e10cSrcweir                 catch ( uno::Exception const & )
826*cdf0e10cSrcweir                 {
827*cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
828*cdf0e10cSrcweir                                 "Content::addProperty - "
829*cdf0e10cSrcweir                                 "Unable to determine resource type!" );
830*cdf0e10cSrcweir                 }
831*cdf0e10cSrcweir             }
832*cdf0e10cSrcweir             else
833*cdf0e10cSrcweir             {
834*cdf0e10cSrcweir                 OSL_ENSURE( sal_False,
835*cdf0e10cSrcweir                             "Content::addProperty - "
836*cdf0e10cSrcweir                             "Unable to determine resource type!" );
837*cdf0e10cSrcweir             }
838*cdf0e10cSrcweir         }
839*cdf0e10cSrcweir     }
840*cdf0e10cSrcweir }
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir //=========================================================================
843*cdf0e10cSrcweir // virtual
844*cdf0e10cSrcweir void SAL_CALL Content::removeProperty( const rtl::OUString& Name )
845*cdf0e10cSrcweir     throw( beans::UnknownPropertyException,
846*cdf0e10cSrcweir            beans::NotRemoveableException,
847*cdf0e10cSrcweir            uno::RuntimeException )
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir     // @@@ Need real command environment here, but where to get it from?
850*cdf0e10cSrcweir     //     XPropertyContainer interface should be replaced by
851*cdf0e10cSrcweir     //     XCommandProcessor commands!
852*cdf0e10cSrcweir     uno::Reference< ucb::XCommandEnvironment > xEnv;
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir #if 0
855*cdf0e10cSrcweir     // @@@ REMOVEABLE z.Z. nicht richtig an der PropSetInfo gesetzt!!!
856*cdf0e10cSrcweir     try
857*cdf0e10cSrcweir     {
858*cdf0e10cSrcweir         beans::Property aProp
859*cdf0e10cSrcweir             = getPropertySetInfo( xEnv, sal_False /* don't cache data */ )
860*cdf0e10cSrcweir                 ->getPropertyByName( Name );
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir         if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) )
863*cdf0e10cSrcweir         {
864*cdf0e10cSrcweir             // Not removeable!
865*cdf0e10cSrcweir             throw beans::NotRemoveableException();
866*cdf0e10cSrcweir         }
867*cdf0e10cSrcweir     }
868*cdf0e10cSrcweir     catch ( beans::UnknownPropertyException const & )
869*cdf0e10cSrcweir     {
870*cdf0e10cSrcweir         //OSL_ENSURE( sal_False, "removeProperty - Unknown property!" );
871*cdf0e10cSrcweir         throw;
872*cdf0e10cSrcweir     }
873*cdf0e10cSrcweir #endif
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
876*cdf0e10cSrcweir     // Try to remove property from server.
877*cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir     try
880*cdf0e10cSrcweir     {
881*cdf0e10cSrcweir         std::vector< ProppatchValue > aProppatchValues;
882*cdf0e10cSrcweir         ProppatchValue aValue( PROPREMOVE, Name, uno::Any() );
883*cdf0e10cSrcweir         aProppatchValues.push_back( aValue );
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir         // Remove property value from server.
886*cdf0e10cSrcweir         std::auto_ptr< DAVResourceAccess > xResAccess;
887*cdf0e10cSrcweir         {
888*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
889*cdf0e10cSrcweir             xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
890*cdf0e10cSrcweir         }
891*cdf0e10cSrcweir         xResAccess->PROPPATCH( aProppatchValues, xEnv );
892*cdf0e10cSrcweir         {
893*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
894*cdf0e10cSrcweir             m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
895*cdf0e10cSrcweir         }
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir         // Notify propertyset info change listeners.
898*cdf0e10cSrcweir         beans::PropertySetInfoChangeEvent evt(
899*cdf0e10cSrcweir             static_cast< cppu::OWeakObject * >( this ),
900*cdf0e10cSrcweir             Name,
901*cdf0e10cSrcweir             -1, // No handle available
902*cdf0e10cSrcweir             beans::PropertySetInfoChange::PROPERTY_REMOVED );
903*cdf0e10cSrcweir         notifyPropertySetInfoChange( evt );
904*cdf0e10cSrcweir     }
905*cdf0e10cSrcweir     catch ( DAVException const & e )
906*cdf0e10cSrcweir     {
907*cdf0e10cSrcweir         if ( e.getStatus() == SC_FORBIDDEN )
908*cdf0e10cSrcweir         {
909*cdf0e10cSrcweir             // Support for setting arbitrary dead properties is optional!
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir             // Try to remove property from local store.
912*cdf0e10cSrcweir             ContentImplHelper::removeProperty( Name );
913*cdf0e10cSrcweir         }
914*cdf0e10cSrcweir         else
915*cdf0e10cSrcweir         {
916*cdf0e10cSrcweir             if ( shouldAccessNetworkAfterException( e ) )
917*cdf0e10cSrcweir             {
918*cdf0e10cSrcweir                 try
919*cdf0e10cSrcweir                 {
920*cdf0e10cSrcweir                     const ResourceType & rType = getResourceType( xEnv );
921*cdf0e10cSrcweir                     switch ( rType )
922*cdf0e10cSrcweir                     {
923*cdf0e10cSrcweir                         case UNKNOWN:
924*cdf0e10cSrcweir                         case DAV:
925*cdf0e10cSrcweir                             throw beans::UnknownPropertyException();
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir                         case FTP:
928*cdf0e10cSrcweir                         case NON_DAV:
929*cdf0e10cSrcweir                             // Try to remove property from local store.
930*cdf0e10cSrcweir                             ContentImplHelper::removeProperty( Name );
931*cdf0e10cSrcweir                             break;
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir                         default:
934*cdf0e10cSrcweir                             OSL_ENSURE( sal_False,
935*cdf0e10cSrcweir                                         "Content::removeProperty - "
936*cdf0e10cSrcweir                                         "Unsupported resource type!" );
937*cdf0e10cSrcweir                             break;
938*cdf0e10cSrcweir                     }
939*cdf0e10cSrcweir                 }
940*cdf0e10cSrcweir                 catch ( uno::Exception const & )
941*cdf0e10cSrcweir                 {
942*cdf0e10cSrcweir                     OSL_ENSURE( sal_False,
943*cdf0e10cSrcweir                                 "Content::removeProperty - "
944*cdf0e10cSrcweir                                 "Unable to determine resource type!" );
945*cdf0e10cSrcweir                 }
946*cdf0e10cSrcweir             }
947*cdf0e10cSrcweir             else
948*cdf0e10cSrcweir             {
949*cdf0e10cSrcweir                 OSL_ENSURE( sal_False,
950*cdf0e10cSrcweir                             "Content::removeProperty - "
951*cdf0e10cSrcweir                             "Unable to determine resource type!" );
952*cdf0e10cSrcweir //                throw beans::UnknownPropertyException();
953*cdf0e10cSrcweir             }
954*cdf0e10cSrcweir         }
955*cdf0e10cSrcweir     }
956*cdf0e10cSrcweir }
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir //=========================================================================
959*cdf0e10cSrcweir //
960*cdf0e10cSrcweir // XContentCreator methods.
961*cdf0e10cSrcweir //
962*cdf0e10cSrcweir //=========================================================================
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir // virtual
965*cdf0e10cSrcweir uno::Sequence< ucb::ContentInfo > SAL_CALL
966*cdf0e10cSrcweir Content::queryCreatableContentsInfo()
967*cdf0e10cSrcweir     throw( uno::RuntimeException )
968*cdf0e10cSrcweir {
969*cdf0e10cSrcweir     osl::Guard< osl::Mutex > aGuard( m_aMutex );
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir     uno::Sequence< ucb::ContentInfo > aSeq( 2 );
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir     // document.
974*cdf0e10cSrcweir     aSeq.getArray()[ 0 ].Type
975*cdf0e10cSrcweir         = rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE );
976*cdf0e10cSrcweir     aSeq.getArray()[ 0 ].Attributes
977*cdf0e10cSrcweir         = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
978*cdf0e10cSrcweir           | ucb::ContentInfoAttribute::KIND_DOCUMENT;
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir     beans::Property aProp;
981*cdf0e10cSrcweir     m_pProvider->getProperty(
982*cdf0e10cSrcweir         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), aProp );
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir     uno::Sequence< beans::Property > aDocProps( 1 );
985*cdf0e10cSrcweir     aDocProps.getArray()[ 0 ] = aProp;
986*cdf0e10cSrcweir     aSeq.getArray()[ 0 ].Properties = aDocProps;
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir     // folder.
989*cdf0e10cSrcweir     aSeq.getArray()[ 1 ].Type
990*cdf0e10cSrcweir         = rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE );
991*cdf0e10cSrcweir     aSeq.getArray()[ 1 ].Attributes
992*cdf0e10cSrcweir         = ucb::ContentInfoAttribute::KIND_FOLDER;
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir     uno::Sequence< beans::Property > aFolderProps( 1 );
995*cdf0e10cSrcweir     aFolderProps.getArray()[ 0 ] = aProp;
996*cdf0e10cSrcweir     aSeq.getArray()[ 1 ].Properties = aFolderProps;
997*cdf0e10cSrcweir     return aSeq;
998*cdf0e10cSrcweir }
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir //=========================================================================
1001*cdf0e10cSrcweir // virtual
1002*cdf0e10cSrcweir uno::Reference< ucb::XContent > SAL_CALL
1003*cdf0e10cSrcweir Content::createNewContent( const ucb::ContentInfo& Info )
1004*cdf0e10cSrcweir     throw( uno::RuntimeException )
1005*cdf0e10cSrcweir {
1006*cdf0e10cSrcweir     osl::Guard< osl::Mutex > aGuard( m_aMutex );
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir     if ( !Info.Type.getLength() )
1009*cdf0e10cSrcweir         return uno::Reference< ucb::XContent >();
1010*cdf0e10cSrcweir 
1011*cdf0e10cSrcweir     if ( ( !Info.Type.equalsAsciiL(
1012*cdf0e10cSrcweir                RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) )
1013*cdf0e10cSrcweir          &&
1014*cdf0e10cSrcweir          ( !Info.Type.equalsAsciiL(
1015*cdf0e10cSrcweir              RTL_CONSTASCII_STRINGPARAM( WEBDAV_CONTENT_TYPE ) ) ) )
1016*cdf0e10cSrcweir         return uno::Reference< ucb::XContent >();
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir     rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir     OSL_ENSURE( aURL.getLength() > 0,
1021*cdf0e10cSrcweir                 "WebdavContent::createNewContent - empty identifier!" );
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir     if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
1024*cdf0e10cSrcweir         aURL += rtl::OUString::createFromAscii( "/" );
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir     sal_Bool isCollection;
1027*cdf0e10cSrcweir     if ( Info.Type.equalsAsciiL(
1028*cdf0e10cSrcweir              RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) )
1029*cdf0e10cSrcweir     {
1030*cdf0e10cSrcweir         aURL += rtl::OUString::createFromAscii( "New_Collection" );
1031*cdf0e10cSrcweir         isCollection = sal_True;
1032*cdf0e10cSrcweir     }
1033*cdf0e10cSrcweir     else
1034*cdf0e10cSrcweir     {
1035*cdf0e10cSrcweir         aURL += rtl::OUString::createFromAscii( "New_Content" );
1036*cdf0e10cSrcweir         isCollection = sal_False;
1037*cdf0e10cSrcweir     }
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir     uno::Reference< ucb::XContentIdentifier > xId(
1040*cdf0e10cSrcweir                     new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) );
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir     // create the local content
1043*cdf0e10cSrcweir     try
1044*cdf0e10cSrcweir     {
1045*cdf0e10cSrcweir         return new ::webdav_ucp::Content( m_xSMgr,
1046*cdf0e10cSrcweir                                           m_pProvider,
1047*cdf0e10cSrcweir                                           xId,
1048*cdf0e10cSrcweir                                           m_xResAccess->getSessionFactory(),
1049*cdf0e10cSrcweir                                           isCollection );
1050*cdf0e10cSrcweir     }
1051*cdf0e10cSrcweir     catch ( ucb::ContentCreationException & )
1052*cdf0e10cSrcweir     {
1053*cdf0e10cSrcweir         return uno::Reference< ucb::XContent >();
1054*cdf0e10cSrcweir     }
1055*cdf0e10cSrcweir }
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir //=========================================================================
1058*cdf0e10cSrcweir // virtual
1059*cdf0e10cSrcweir rtl::OUString Content::getParentURL()
1060*cdf0e10cSrcweir {
1061*cdf0e10cSrcweir     // <scheme>://              -> ""
1062*cdf0e10cSrcweir     // <scheme>://foo           -> ""
1063*cdf0e10cSrcweir     // <scheme>://foo/          -> ""
1064*cdf0e10cSrcweir     // <scheme>://foo/bar       -> <scheme>://foo/
1065*cdf0e10cSrcweir     // <scheme>://foo/bar/      -> <scheme>://foo/
1066*cdf0e10cSrcweir     // <scheme>://foo/bar/abc   -> <scheme>://foo/bar/
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir     rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir     sal_Int32 nPos = aURL.lastIndexOf( '/' );
1071*cdf0e10cSrcweir     if ( nPos == ( aURL.getLength() - 1 ) )
1072*cdf0e10cSrcweir     {
1073*cdf0e10cSrcweir         // Trailing slash found. Skip.
1074*cdf0e10cSrcweir         nPos = aURL.lastIndexOf( '/', nPos );
1075*cdf0e10cSrcweir     }
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir     sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
1078*cdf0e10cSrcweir     if ( nPos1 != -1 )
1079*cdf0e10cSrcweir         nPos1 = aURL.lastIndexOf( '/', nPos1 );
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir     if ( nPos1 == -1 )
1082*cdf0e10cSrcweir         return rtl::OUString();
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir     return rtl::OUString( aURL.copy( 0, nPos + 1 ) );
1085*cdf0e10cSrcweir }
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir //=========================================================================
1088*cdf0e10cSrcweir //
1089*cdf0e10cSrcweir // Non-interface methods.
1090*cdf0e10cSrcweir //
1091*cdf0e10cSrcweir //=========================================================================
1092*cdf0e10cSrcweir 
1093*cdf0e10cSrcweir // static
1094*cdf0e10cSrcweir uno::Reference< sdbc::XRow > Content::getPropertyValues(
1095*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
1096*cdf0e10cSrcweir     const uno::Sequence< beans::Property >& rProperties,
1097*cdf0e10cSrcweir     const ContentProperties& rData,
1098*cdf0e10cSrcweir     const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
1099*cdf0e10cSrcweir     const rtl::OUString& rContentId )
1100*cdf0e10cSrcweir {
1101*cdf0e10cSrcweir     // Note: Empty sequence means "get values of all supported properties".
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir     rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
1104*cdf0e10cSrcweir         = new ::ucbhelper::PropertyValueSet( rSMgr );
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir     sal_Int32 nCount = rProperties.getLength();
1107*cdf0e10cSrcweir     if ( nCount )
1108*cdf0e10cSrcweir     {
1109*cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > xAdditionalPropSet;
1110*cdf0e10cSrcweir         sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir         const beans::Property* pProps = rProperties.getConstArray();
1113*cdf0e10cSrcweir         for ( sal_Int32 n = 0; n < nCount; ++n )
1114*cdf0e10cSrcweir         {
1115*cdf0e10cSrcweir             const beans::Property& rProp = pProps[ n ];
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir             // Process standard UCB, DAV and HTTP properties.
1118*cdf0e10cSrcweir             const uno::Any & rValue = rData.getValue( rProp.Name );
1119*cdf0e10cSrcweir             if ( rValue.hasValue() )
1120*cdf0e10cSrcweir             {
1121*cdf0e10cSrcweir                 xRow->appendObject( rProp, rValue );
1122*cdf0e10cSrcweir             }
1123*cdf0e10cSrcweir             else
1124*cdf0e10cSrcweir             {
1125*cdf0e10cSrcweir                 // Process local Additional Properties.
1126*cdf0e10cSrcweir                 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
1127*cdf0e10cSrcweir                 {
1128*cdf0e10cSrcweir                     xAdditionalPropSet
1129*cdf0e10cSrcweir                         = uno::Reference< beans::XPropertySet >(
1130*cdf0e10cSrcweir                             rProvider->getAdditionalPropertySet( rContentId,
1131*cdf0e10cSrcweir                                                                  sal_False ),
1132*cdf0e10cSrcweir                             uno::UNO_QUERY );
1133*cdf0e10cSrcweir                     bTriedToGetAdditonalPropSet = sal_True;
1134*cdf0e10cSrcweir                 }
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir                 if ( !xAdditionalPropSet.is() ||
1137*cdf0e10cSrcweir                      !xRow->appendPropertySetValue(
1138*cdf0e10cSrcweir                                             xAdditionalPropSet, rProp ) )
1139*cdf0e10cSrcweir                 {
1140*cdf0e10cSrcweir                     // Append empty entry.
1141*cdf0e10cSrcweir                     xRow->appendVoid( rProp );
1142*cdf0e10cSrcweir                 }
1143*cdf0e10cSrcweir             }
1144*cdf0e10cSrcweir         }
1145*cdf0e10cSrcweir     }
1146*cdf0e10cSrcweir     else
1147*cdf0e10cSrcweir     {
1148*cdf0e10cSrcweir         // Append all standard UCB, DAV and HTTP properties.
1149*cdf0e10cSrcweir 
1150*cdf0e10cSrcweir         const std::auto_ptr< PropertyValueMap > & xProps = rData.getProperties();
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir         PropertyValueMap::const_iterator it  = xProps->begin();
1153*cdf0e10cSrcweir         PropertyValueMap::const_iterator end = xProps->end();
1154*cdf0e10cSrcweir 
1155*cdf0e10cSrcweir         ContentProvider * pProvider
1156*cdf0e10cSrcweir             = static_cast< ContentProvider * >( rProvider.get() );
1157*cdf0e10cSrcweir         beans::Property aProp;
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir         while ( it != end )
1160*cdf0e10cSrcweir         {
1161*cdf0e10cSrcweir             if ( pProvider->getProperty( (*it).first, aProp ) )
1162*cdf0e10cSrcweir                 xRow->appendObject( aProp, (*it).second.value() );
1163*cdf0e10cSrcweir 
1164*cdf0e10cSrcweir             ++it;
1165*cdf0e10cSrcweir         }
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir         // Append all local Additional Properties.
1168*cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > xSet(
1169*cdf0e10cSrcweir             rProvider->getAdditionalPropertySet( rContentId, sal_False ),
1170*cdf0e10cSrcweir             uno::UNO_QUERY );
1171*cdf0e10cSrcweir         xRow->appendPropertySet( xSet );
1172*cdf0e10cSrcweir     }
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir     return uno::Reference< sdbc::XRow >( xRow.get() );
1175*cdf0e10cSrcweir }
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir //=========================================================================
1178*cdf0e10cSrcweir uno::Reference< sdbc::XRow > Content::getPropertyValues(
1179*cdf0e10cSrcweir                 const uno::Sequence< beans::Property >& rProperties,
1180*cdf0e10cSrcweir                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1181*cdf0e10cSrcweir     throw ( uno::Exception )
1182*cdf0e10cSrcweir {
1183*cdf0e10cSrcweir     std::auto_ptr< ContentProperties > xProps;
1184*cdf0e10cSrcweir     std::auto_ptr< ContentProperties > xCachedProps;
1185*cdf0e10cSrcweir     std::auto_ptr< DAVResourceAccess > xResAccess;
1186*cdf0e10cSrcweir     rtl::OUString aUnescapedTitle;
1187*cdf0e10cSrcweir     bool bHasAll = false;
1188*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xSMgr;
1189*cdf0e10cSrcweir     uno::Reference< ucb::XContentIdentifier > xIdentifier;
1190*cdf0e10cSrcweir     rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir     {
1193*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir         aUnescapedTitle = NeonUri::unescape( m_aEscapedTitle );
1196*cdf0e10cSrcweir         xSMgr.set( m_xSMgr );
1197*cdf0e10cSrcweir         xIdentifier.set( m_xIdentifier );
1198*cdf0e10cSrcweir         xProvider.set( m_xProvider.get() );
1199*cdf0e10cSrcweir         xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1200*cdf0e10cSrcweir 
1201*cdf0e10cSrcweir         // First, ask cache...
1202*cdf0e10cSrcweir         if ( m_xCachedProps.get() )
1203*cdf0e10cSrcweir         {
1204*cdf0e10cSrcweir             xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
1205*cdf0e10cSrcweir 
1206*cdf0e10cSrcweir             std::vector< rtl::OUString > aMissingProps;
1207*cdf0e10cSrcweir             if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) )
1208*cdf0e10cSrcweir             {
1209*cdf0e10cSrcweir                 // All properties are already in cache! No server access needed.
1210*cdf0e10cSrcweir                 bHasAll = true;
1211*cdf0e10cSrcweir             }
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir             // use the cached ContentProperties instance
1214*cdf0e10cSrcweir             xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1215*cdf0e10cSrcweir         }
1216*cdf0e10cSrcweir     }
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir     if ( !m_bTransient && !bHasAll )
1219*cdf0e10cSrcweir     {
1220*cdf0e10cSrcweir         /////////////////////////////////////////////////////////////////////
1221*cdf0e10cSrcweir         // Obtain values from server...
1222*cdf0e10cSrcweir         /////////////////////////////////////////////////////////////////////
1223*cdf0e10cSrcweir 
1224*cdf0e10cSrcweir         // First, identify whether resource is DAV or not
1225*cdf0e10cSrcweir         const ResourceType & rType = getResourceType( xEnv, xResAccess );
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir         bool bNetworkAccessAllowed = true;
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir         if ( DAV == rType )
1230*cdf0e10cSrcweir         {
1231*cdf0e10cSrcweir             // cache lookup... getResourceType may fill the props cache via
1232*cdf0e10cSrcweir             // PROPFIND!
1233*cdf0e10cSrcweir             if ( m_xCachedProps.get() )
1234*cdf0e10cSrcweir             {
1235*cdf0e10cSrcweir                 xCachedProps.reset(
1236*cdf0e10cSrcweir                     new ContentProperties( *m_xCachedProps.get() ) );
1237*cdf0e10cSrcweir 
1238*cdf0e10cSrcweir                 std::vector< rtl::OUString > aMissingProps;
1239*cdf0e10cSrcweir                 if ( xCachedProps->containsAllNames(
1240*cdf0e10cSrcweir                          rProperties, aMissingProps ) )
1241*cdf0e10cSrcweir                 {
1242*cdf0e10cSrcweir                     // All properties are already in cache! No server access
1243*cdf0e10cSrcweir                     // needed.
1244*cdf0e10cSrcweir                     bHasAll = true;
1245*cdf0e10cSrcweir                 }
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir                 // use the cached ContentProperties instance
1248*cdf0e10cSrcweir                 xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1249*cdf0e10cSrcweir             }
1250*cdf0e10cSrcweir 
1251*cdf0e10cSrcweir             if ( !bHasAll )
1252*cdf0e10cSrcweir             {
1253*cdf0e10cSrcweir                 // Only DAV resources support PROPFIND
1254*cdf0e10cSrcweir                 std::vector< rtl::OUString > aPropNames;
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir                 uno::Sequence< beans::Property > aProperties(
1257*cdf0e10cSrcweir                     rProperties.getLength() );
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir                 if ( m_aFailedPropNames.size() > 0 )
1260*cdf0e10cSrcweir                 {
1261*cdf0e10cSrcweir                     sal_Int32 nProps = 0;
1262*cdf0e10cSrcweir                     sal_Int32 nCount = rProperties.getLength();
1263*cdf0e10cSrcweir                     for ( sal_Int32 n = 0; n < nCount; ++n )
1264*cdf0e10cSrcweir                     {
1265*cdf0e10cSrcweir                         const rtl::OUString & rName = rProperties[ n ].Name;
1266*cdf0e10cSrcweir 
1267*cdf0e10cSrcweir                         std::vector< rtl::OUString >::const_iterator it
1268*cdf0e10cSrcweir                             = m_aFailedPropNames.begin();
1269*cdf0e10cSrcweir                         std::vector< rtl::OUString >::const_iterator end
1270*cdf0e10cSrcweir                             = m_aFailedPropNames.end();
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir                         while ( it != end )
1273*cdf0e10cSrcweir                         {
1274*cdf0e10cSrcweir                             if ( *it == rName )
1275*cdf0e10cSrcweir                                 break;
1276*cdf0e10cSrcweir 
1277*cdf0e10cSrcweir                             ++it;
1278*cdf0e10cSrcweir                         }
1279*cdf0e10cSrcweir 
1280*cdf0e10cSrcweir                         if ( it == end )
1281*cdf0e10cSrcweir                         {
1282*cdf0e10cSrcweir                             aProperties[ nProps ] = rProperties[ n ];
1283*cdf0e10cSrcweir                             nProps++;
1284*cdf0e10cSrcweir                         }
1285*cdf0e10cSrcweir                     }
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir                     aProperties.realloc( nProps );
1288*cdf0e10cSrcweir                 }
1289*cdf0e10cSrcweir                 else
1290*cdf0e10cSrcweir                 {
1291*cdf0e10cSrcweir                     aProperties = rProperties;
1292*cdf0e10cSrcweir                 }
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir                 if ( aProperties.getLength() > 0 )
1295*cdf0e10cSrcweir                     ContentProperties::UCBNamesToDAVNames(
1296*cdf0e10cSrcweir                         aProperties, aPropNames );
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir                 if ( aPropNames.size() > 0 )
1299*cdf0e10cSrcweir                 {
1300*cdf0e10cSrcweir                     std::vector< DAVResource > resources;
1301*cdf0e10cSrcweir                     try
1302*cdf0e10cSrcweir                     {
1303*cdf0e10cSrcweir                         xResAccess->PROPFIND(
1304*cdf0e10cSrcweir                             DAVZERO, aPropNames, resources, xEnv );
1305*cdf0e10cSrcweir 
1306*cdf0e10cSrcweir                         if ( 1 == resources.size() )
1307*cdf0e10cSrcweir                         {
1308*cdf0e10cSrcweir                             if ( xProps.get())
1309*cdf0e10cSrcweir                                 xProps->addProperties(
1310*cdf0e10cSrcweir                                     aPropNames,
1311*cdf0e10cSrcweir                                     ContentProperties( resources[ 0 ] ));
1312*cdf0e10cSrcweir                             else
1313*cdf0e10cSrcweir                                 xProps.reset(
1314*cdf0e10cSrcweir                                     new ContentProperties( resources[ 0 ] ) );
1315*cdf0e10cSrcweir                         }
1316*cdf0e10cSrcweir                     }
1317*cdf0e10cSrcweir                     catch ( DAVException const & e )
1318*cdf0e10cSrcweir                     {
1319*cdf0e10cSrcweir                         bNetworkAccessAllowed
1320*cdf0e10cSrcweir                             = shouldAccessNetworkAfterException( e );
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir                         if ( !bNetworkAccessAllowed )
1323*cdf0e10cSrcweir                         {
1324*cdf0e10cSrcweir                             cancelCommandExecution( e, xEnv );
1325*cdf0e10cSrcweir                             // unreachable
1326*cdf0e10cSrcweir                         }
1327*cdf0e10cSrcweir                     }
1328*cdf0e10cSrcweir                 }
1329*cdf0e10cSrcweir             }
1330*cdf0e10cSrcweir         }
1331*cdf0e10cSrcweir 
1332*cdf0e10cSrcweir         if ( bNetworkAccessAllowed )
1333*cdf0e10cSrcweir         {
1334*cdf0e10cSrcweir             // All properties obtained already?
1335*cdf0e10cSrcweir             std::vector< rtl::OUString > aMissingProps;
1336*cdf0e10cSrcweir             if ( !( xProps.get()
1337*cdf0e10cSrcweir                     && xProps->containsAllNames(
1338*cdf0e10cSrcweir                         rProperties, aMissingProps ) )
1339*cdf0e10cSrcweir                  && !m_bDidGetOrHead )
1340*cdf0e10cSrcweir             {
1341*cdf0e10cSrcweir                 // Possibly the missing props can be obtained using a HEAD
1342*cdf0e10cSrcweir                 // request.
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir                 std::vector< rtl::OUString > aHeaderNames;
1345*cdf0e10cSrcweir                 ContentProperties::UCBNamesToHTTPNames(
1346*cdf0e10cSrcweir                     rProperties,
1347*cdf0e10cSrcweir                     aHeaderNames,
1348*cdf0e10cSrcweir                     true /* bIncludeUnmatched */ );
1349*cdf0e10cSrcweir 
1350*cdf0e10cSrcweir                 if ( aHeaderNames.size() > 0 )
1351*cdf0e10cSrcweir                 {
1352*cdf0e10cSrcweir                     try
1353*cdf0e10cSrcweir                     {
1354*cdf0e10cSrcweir                         DAVResource resource;
1355*cdf0e10cSrcweir                         xResAccess->HEAD( aHeaderNames, resource, xEnv );
1356*cdf0e10cSrcweir                         m_bDidGetOrHead = true;
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir                         if ( xProps.get() )
1359*cdf0e10cSrcweir                             xProps->addProperties(
1360*cdf0e10cSrcweir                                 aMissingProps,
1361*cdf0e10cSrcweir                                 ContentProperties( resource ) );
1362*cdf0e10cSrcweir                         else
1363*cdf0e10cSrcweir                             xProps.reset ( new ContentProperties( resource ) );
1364*cdf0e10cSrcweir 
1365*cdf0e10cSrcweir                         if ( m_eResourceType == NON_DAV )
1366*cdf0e10cSrcweir                             xProps->addProperties( aMissingProps,
1367*cdf0e10cSrcweir                                                    ContentProperties(
1368*cdf0e10cSrcweir                                                        aUnescapedTitle,
1369*cdf0e10cSrcweir                                                        false ) );
1370*cdf0e10cSrcweir                     }
1371*cdf0e10cSrcweir                     catch ( DAVException const & e )
1372*cdf0e10cSrcweir                     {
1373*cdf0e10cSrcweir                         bNetworkAccessAllowed
1374*cdf0e10cSrcweir                             = shouldAccessNetworkAfterException( e );
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir                         if ( !bNetworkAccessAllowed )
1377*cdf0e10cSrcweir                         {
1378*cdf0e10cSrcweir                             cancelCommandExecution( e, xEnv );
1379*cdf0e10cSrcweir                             // unreachable
1380*cdf0e10cSrcweir                         }
1381*cdf0e10cSrcweir                     }
1382*cdf0e10cSrcweir                 }
1383*cdf0e10cSrcweir             }
1384*cdf0e10cSrcweir         }
1385*cdf0e10cSrcweir 
1386*cdf0e10cSrcweir         // might trigger HTTP redirect.
1387*cdf0e10cSrcweir         // Therefore, title must be updated here.
1388*cdf0e10cSrcweir         NeonUri aUri( xResAccess->getURL() );
1389*cdf0e10cSrcweir         aUnescapedTitle = aUri.GetPathBaseNameUnescaped();
1390*cdf0e10cSrcweir 
1391*cdf0e10cSrcweir         if ( rType == UNKNOWN )
1392*cdf0e10cSrcweir         {
1393*cdf0e10cSrcweir             xProps.reset( new ContentProperties( aUnescapedTitle ) );
1394*cdf0e10cSrcweir         }
1395*cdf0e10cSrcweir 
1396*cdf0e10cSrcweir         // For DAV resources we only know the Title, for non-DAV
1397*cdf0e10cSrcweir         // resources we additionally know that it is a document.
1398*cdf0e10cSrcweir 
1399*cdf0e10cSrcweir         if ( rType == DAV )
1400*cdf0e10cSrcweir         {
1401*cdf0e10cSrcweir             //xProps.reset(
1402*cdf0e10cSrcweir             //    new ContentProperties( aUnescapedTitle ) );
1403*cdf0e10cSrcweir             xProps->addProperty(
1404*cdf0e10cSrcweir                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
1405*cdf0e10cSrcweir                 uno::makeAny( aUnescapedTitle ),
1406*cdf0e10cSrcweir                 true );
1407*cdf0e10cSrcweir         }
1408*cdf0e10cSrcweir         else
1409*cdf0e10cSrcweir         {
1410*cdf0e10cSrcweir             if ( !xProps.get() )
1411*cdf0e10cSrcweir                 xProps.reset( new ContentProperties( aUnescapedTitle, false ) );
1412*cdf0e10cSrcweir             else
1413*cdf0e10cSrcweir                 xProps->addProperty(
1414*cdf0e10cSrcweir                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
1415*cdf0e10cSrcweir                     uno::makeAny( aUnescapedTitle ),
1416*cdf0e10cSrcweir                     true );
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir             xProps->addProperty(
1419*cdf0e10cSrcweir                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
1420*cdf0e10cSrcweir                 uno::makeAny( false ),
1421*cdf0e10cSrcweir                 true );
1422*cdf0e10cSrcweir             xProps->addProperty(
1423*cdf0e10cSrcweir                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
1424*cdf0e10cSrcweir                 uno::makeAny( true ),
1425*cdf0e10cSrcweir                 true );
1426*cdf0e10cSrcweir         }
1427*cdf0e10cSrcweir     }
1428*cdf0e10cSrcweir     else
1429*cdf0e10cSrcweir     {
1430*cdf0e10cSrcweir         // No server access for just created (not yet committed) objects.
1431*cdf0e10cSrcweir         // Only a minimal set of properties supported at this stage.
1432*cdf0e10cSrcweir         if (m_bTransient)
1433*cdf0e10cSrcweir             xProps.reset( new ContentProperties( aUnescapedTitle,
1434*cdf0e10cSrcweir                                                  m_bCollection ) );
1435*cdf0e10cSrcweir     }
1436*cdf0e10cSrcweir 
1437*cdf0e10cSrcweir     sal_Int32 nCount = rProperties.getLength();
1438*cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < nCount; ++n )
1439*cdf0e10cSrcweir     {
1440*cdf0e10cSrcweir         const rtl::OUString rName = rProperties[ n ].Name;
1441*cdf0e10cSrcweir         if ( rName.equalsAsciiL(
1442*cdf0e10cSrcweir                       RTL_CONSTASCII_STRINGPARAM( "BaseURI" ) ) )
1443*cdf0e10cSrcweir         {
1444*cdf0e10cSrcweir             // Add BaseURI property, if requested.
1445*cdf0e10cSrcweir             xProps->addProperty(
1446*cdf0e10cSrcweir                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ),
1447*cdf0e10cSrcweir                  uno::makeAny( getBaseURI( xResAccess ) ),
1448*cdf0e10cSrcweir                  true );
1449*cdf0e10cSrcweir         }
1450*cdf0e10cSrcweir         else if ( rName.equalsAsciiL(
1451*cdf0e10cSrcweir                       RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
1452*cdf0e10cSrcweir         {
1453*cdf0e10cSrcweir             // Add CreatableContentsInfo property, if requested.
1454*cdf0e10cSrcweir             sal_Bool bFolder = sal_False;
1455*cdf0e10cSrcweir             xProps->getValue(
1456*cdf0e10cSrcweir                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ) )
1457*cdf0e10cSrcweir                     >>= bFolder;
1458*cdf0e10cSrcweir             xProps->addProperty(
1459*cdf0e10cSrcweir                 rtl::OUString(
1460*cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
1461*cdf0e10cSrcweir                 uno::makeAny( bFolder
1462*cdf0e10cSrcweir                                   ? queryCreatableContentsInfo()
1463*cdf0e10cSrcweir                                   : uno::Sequence< ucb::ContentInfo >() ),
1464*cdf0e10cSrcweir                 true );
1465*cdf0e10cSrcweir         }
1466*cdf0e10cSrcweir     }
1467*cdf0e10cSrcweir 
1468*cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xResultRow
1469*cdf0e10cSrcweir         = getPropertyValues( xSMgr,
1470*cdf0e10cSrcweir                              rProperties,
1471*cdf0e10cSrcweir                              *xProps,
1472*cdf0e10cSrcweir                              xProvider,
1473*cdf0e10cSrcweir                              xIdentifier->getContentIdentifier() );
1474*cdf0e10cSrcweir 
1475*cdf0e10cSrcweir     {
1476*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir         if ( !m_xCachedProps.get() )
1479*cdf0e10cSrcweir             m_xCachedProps.reset( new CachableContentProperties( *xProps.get() ) );
1480*cdf0e10cSrcweir         else
1481*cdf0e10cSrcweir             m_xCachedProps->addProperties( *xProps.get() );
1482*cdf0e10cSrcweir 
1483*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1484*cdf0e10cSrcweir         m_aEscapedTitle = NeonUri::escapeSegment( aUnescapedTitle );
1485*cdf0e10cSrcweir     }
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir     return xResultRow;
1488*cdf0e10cSrcweir }
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir //=========================================================================
1491*cdf0e10cSrcweir uno::Sequence< uno::Any > Content::setPropertyValues(
1492*cdf0e10cSrcweir                 const uno::Sequence< beans::PropertyValue >& rValues,
1493*cdf0e10cSrcweir                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1494*cdf0e10cSrcweir     throw ( uno::Exception )
1495*cdf0e10cSrcweir {
1496*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xSMgr;
1497*cdf0e10cSrcweir     uno::Reference< ucb::XContentIdentifier >    xIdentifier;
1498*cdf0e10cSrcweir     rtl::Reference< ContentProvider >            xProvider;
1499*cdf0e10cSrcweir     sal_Bool bTransient;
1500*cdf0e10cSrcweir     std::auto_ptr< DAVResourceAccess > xResAccess;
1501*cdf0e10cSrcweir 
1502*cdf0e10cSrcweir     {
1503*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir         xProvider.set( m_pProvider );
1506*cdf0e10cSrcweir         xIdentifier.set( m_xIdentifier );
1507*cdf0e10cSrcweir         bTransient = m_bTransient;
1508*cdf0e10cSrcweir         xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1509*cdf0e10cSrcweir         xSMgr.set( m_xSMgr );
1510*cdf0e10cSrcweir     }
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir     uno::Sequence< uno::Any > aRet( rValues.getLength() );
1513*cdf0e10cSrcweir     uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1514*cdf0e10cSrcweir     sal_Int32 nChanged = 0;
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir     beans::PropertyChangeEvent aEvent;
1517*cdf0e10cSrcweir     aEvent.Source         = static_cast< cppu::OWeakObject * >( this );
1518*cdf0e10cSrcweir     aEvent.Further        = sal_False;
1519*cdf0e10cSrcweir     // aEvent.PropertyName =
1520*cdf0e10cSrcweir     aEvent.PropertyHandle = -1;
1521*cdf0e10cSrcweir     // aEvent.OldValue   =
1522*cdf0e10cSrcweir     // aEvent.NewValue   =
1523*cdf0e10cSrcweir 
1524*cdf0e10cSrcweir     std::vector< ProppatchValue > aProppatchValues;
1525*cdf0e10cSrcweir     std::vector< sal_Int32 > aProppatchPropsPositions;
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir     uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1528*cdf0e10cSrcweir     sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1529*cdf0e10cSrcweir 
1530*cdf0e10cSrcweir     sal_Bool bExchange = sal_False;
1531*cdf0e10cSrcweir     rtl::OUString aNewTitle;
1532*cdf0e10cSrcweir     rtl::OUString aOldTitle;
1533*cdf0e10cSrcweir     sal_Int32 nTitlePos = -1;
1534*cdf0e10cSrcweir 
1535*cdf0e10cSrcweir     uno::Reference< beans::XPropertySetInfo > xInfo;
1536*cdf0e10cSrcweir 
1537*cdf0e10cSrcweir     const beans::PropertyValue* pValues = rValues.getConstArray();
1538*cdf0e10cSrcweir     sal_Int32 nCount = rValues.getLength();
1539*cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < nCount; ++n )
1540*cdf0e10cSrcweir     {
1541*cdf0e10cSrcweir         const beans::PropertyValue& rValue = pValues[ n ];
1542*cdf0e10cSrcweir         const rtl::OUString & rName = rValue.Name;
1543*cdf0e10cSrcweir 
1544*cdf0e10cSrcweir         beans::Property aTmpProp;
1545*cdf0e10cSrcweir         xProvider->getProperty( rName, aTmpProp );
1546*cdf0e10cSrcweir 
1547*cdf0e10cSrcweir         if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY )
1548*cdf0e10cSrcweir         {
1549*cdf0e10cSrcweir             // Read-only property!
1550*cdf0e10cSrcweir             aRet[ n ] <<= lang::IllegalAccessException(
1551*cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1552*cdf0e10cSrcweir                                 "Property is read-only!" ),
1553*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ) );
1554*cdf0e10cSrcweir             continue;
1555*cdf0e10cSrcweir         }
1556*cdf0e10cSrcweir 
1557*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
1558*cdf0e10cSrcweir         // Mandatory props.
1559*cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
1560*cdf0e10cSrcweir 
1561*cdf0e10cSrcweir         if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
1562*cdf0e10cSrcweir         {
1563*cdf0e10cSrcweir             // Read-only property!
1564*cdf0e10cSrcweir             aRet[ n ] <<= lang::IllegalAccessException(
1565*cdf0e10cSrcweir                 rtl::OUString::createFromAscii(
1566*cdf0e10cSrcweir                     "Property is read-only!" ),
1567*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ) );
1568*cdf0e10cSrcweir         }
1569*cdf0e10cSrcweir         else if ( rName.equalsAsciiL(
1570*cdf0e10cSrcweir                       RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
1571*cdf0e10cSrcweir         {
1572*cdf0e10cSrcweir             // Read-only property!
1573*cdf0e10cSrcweir             aRet[ n ] <<= lang::IllegalAccessException(
1574*cdf0e10cSrcweir                 rtl::OUString::createFromAscii(
1575*cdf0e10cSrcweir                     "Property is read-only!" ),
1576*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ) );
1577*cdf0e10cSrcweir         }
1578*cdf0e10cSrcweir         else if ( rName.equalsAsciiL(
1579*cdf0e10cSrcweir                       RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
1580*cdf0e10cSrcweir         {
1581*cdf0e10cSrcweir             // Read-only property!
1582*cdf0e10cSrcweir             aRet[ n ] <<= lang::IllegalAccessException(
1583*cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1584*cdf0e10cSrcweir                                 "Property is read-only!" ),
1585*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ) );
1586*cdf0e10cSrcweir         }
1587*cdf0e10cSrcweir         else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
1588*cdf0e10cSrcweir         {
1589*cdf0e10cSrcweir             rtl::OUString aNewValue;
1590*cdf0e10cSrcweir             if ( rValue.Value >>= aNewValue )
1591*cdf0e10cSrcweir             {
1592*cdf0e10cSrcweir                 // No empty titles!
1593*cdf0e10cSrcweir                 if ( aNewValue.getLength() > 0 )
1594*cdf0e10cSrcweir                 {
1595*cdf0e10cSrcweir                     try
1596*cdf0e10cSrcweir                     {
1597*cdf0e10cSrcweir                         NeonUri aURI( xIdentifier->getContentIdentifier() );
1598*cdf0e10cSrcweir                         aOldTitle = aURI.GetPathBaseNameUnescaped();
1599*cdf0e10cSrcweir 
1600*cdf0e10cSrcweir                         if ( aNewValue != aOldTitle )
1601*cdf0e10cSrcweir                         {
1602*cdf0e10cSrcweir                             // modified title -> modified URL -> exchange !
1603*cdf0e10cSrcweir                             if ( !bTransient )
1604*cdf0e10cSrcweir                                 bExchange = sal_True;
1605*cdf0e10cSrcweir 
1606*cdf0e10cSrcweir                             // new value will be set later...
1607*cdf0e10cSrcweir                             aNewTitle = aNewValue;
1608*cdf0e10cSrcweir 
1609*cdf0e10cSrcweir                             // remember position within sequence of values (for
1610*cdf0e10cSrcweir                             // error handling).
1611*cdf0e10cSrcweir                             nTitlePos = n;
1612*cdf0e10cSrcweir                         }
1613*cdf0e10cSrcweir                     }
1614*cdf0e10cSrcweir                     catch ( DAVException const & )
1615*cdf0e10cSrcweir                     {
1616*cdf0e10cSrcweir                         aRet[ n ] <<= lang::IllegalArgumentException(
1617*cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1618*cdf0e10cSrcweir                                 "Invalid content identifier!" ),
1619*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ),
1620*cdf0e10cSrcweir                             -1 );
1621*cdf0e10cSrcweir                     }
1622*cdf0e10cSrcweir                 }
1623*cdf0e10cSrcweir                 else
1624*cdf0e10cSrcweir                 {
1625*cdf0e10cSrcweir                     aRet[ n ] <<= lang::IllegalArgumentException(
1626*cdf0e10cSrcweir                         rtl::OUString::createFromAscii(
1627*cdf0e10cSrcweir                             "Empty title not allowed!" ),
1628*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ),
1629*cdf0e10cSrcweir                         -1 );
1630*cdf0e10cSrcweir                 }
1631*cdf0e10cSrcweir             }
1632*cdf0e10cSrcweir             else
1633*cdf0e10cSrcweir             {
1634*cdf0e10cSrcweir                 aRet[ n ] <<= beans::IllegalTypeException(
1635*cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
1636*cdf0e10cSrcweir                         "Property value has wrong type!" ),
1637*cdf0e10cSrcweir                     static_cast< cppu::OWeakObject * >( this ) );
1638*cdf0e10cSrcweir             }
1639*cdf0e10cSrcweir         }
1640*cdf0e10cSrcweir         else
1641*cdf0e10cSrcweir         {
1642*cdf0e10cSrcweir             //////////////////////////////////////////////////////////////
1643*cdf0e10cSrcweir             // Optional props.
1644*cdf0e10cSrcweir             //////////////////////////////////////////////////////////////
1645*cdf0e10cSrcweir 
1646*cdf0e10cSrcweir             if ( !xInfo.is() )
1647*cdf0e10cSrcweir                 xInfo = getPropertySetInfo( xEnv,
1648*cdf0e10cSrcweir                                             sal_False /* don't cache data */ );
1649*cdf0e10cSrcweir 
1650*cdf0e10cSrcweir             if ( !xInfo->hasPropertyByName( rName ) )
1651*cdf0e10cSrcweir             {
1652*cdf0e10cSrcweir                 // Check, whether property exists. Skip otherwise.
1653*cdf0e10cSrcweir                 // PROPPATCH::set would add the property automatically, which
1654*cdf0e10cSrcweir                 // is not allowed for "setPropertyValues" command!
1655*cdf0e10cSrcweir                 aRet[ n ] <<= beans::UnknownPropertyException(
1656*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1657*cdf0e10cSrcweir                                     "Property is unknown!" ),
1658*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1659*cdf0e10cSrcweir                 continue;
1660*cdf0e10cSrcweir             }
1661*cdf0e10cSrcweir 
1662*cdf0e10cSrcweir             if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
1663*cdf0e10cSrcweir             {
1664*cdf0e10cSrcweir                 // Read-only property!
1665*cdf0e10cSrcweir                 aRet[ n ] <<= lang::IllegalAccessException(
1666*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1667*cdf0e10cSrcweir                                     "Property is read-only!" ),
1668*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1669*cdf0e10cSrcweir             }
1670*cdf0e10cSrcweir             else if ( rName.equalsAsciiL(
1671*cdf0e10cSrcweir                         RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
1672*cdf0e10cSrcweir             {
1673*cdf0e10cSrcweir                 // Read-only property!
1674*cdf0e10cSrcweir                 aRet[ n ] <<= lang::IllegalAccessException(
1675*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1676*cdf0e10cSrcweir                                     "Property is read-only!" ),
1677*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1678*cdf0e10cSrcweir             }
1679*cdf0e10cSrcweir             else if ( rName.equalsAsciiL(
1680*cdf0e10cSrcweir                         RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
1681*cdf0e10cSrcweir             {
1682*cdf0e10cSrcweir                 // Read-only property!
1683*cdf0e10cSrcweir                 aRet[ n ] <<= lang::IllegalAccessException(
1684*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1685*cdf0e10cSrcweir                                     "Property is read-only!" ),
1686*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1687*cdf0e10cSrcweir             }
1688*cdf0e10cSrcweir             else if ( rName.equalsAsciiL(
1689*cdf0e10cSrcweir                         RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
1690*cdf0e10cSrcweir             {
1691*cdf0e10cSrcweir                 // Read-only property!
1692*cdf0e10cSrcweir                 // (but could be writable, if 'getcontenttype' would be)
1693*cdf0e10cSrcweir                 aRet[ n ] <<= lang::IllegalAccessException(
1694*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1695*cdf0e10cSrcweir                                     "Property is read-only!" ),
1696*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1697*cdf0e10cSrcweir             }
1698*cdf0e10cSrcweir             if ( rName.equalsAsciiL(
1699*cdf0e10cSrcweir                      RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
1700*cdf0e10cSrcweir             {
1701*cdf0e10cSrcweir                 // Read-only property!
1702*cdf0e10cSrcweir                 aRet[ n ] <<= lang::IllegalAccessException(
1703*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1704*cdf0e10cSrcweir                                     "Property is read-only!" ),
1705*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1706*cdf0e10cSrcweir             }
1707*cdf0e10cSrcweir             else
1708*cdf0e10cSrcweir             {
1709*cdf0e10cSrcweir                 if ( getResourceType( xEnv, xResAccess ) == DAV )
1710*cdf0e10cSrcweir                 {
1711*cdf0e10cSrcweir                     // Property value will be set on server.
1712*cdf0e10cSrcweir                     ProppatchValue aValue( PROPSET, rName, rValue.Value );
1713*cdf0e10cSrcweir                     aProppatchValues.push_back( aValue );
1714*cdf0e10cSrcweir 
1715*cdf0e10cSrcweir                     // remember position within sequence of values (for
1716*cdf0e10cSrcweir                     // error handling).
1717*cdf0e10cSrcweir                     aProppatchPropsPositions.push_back( n );
1718*cdf0e10cSrcweir                 }
1719*cdf0e10cSrcweir                 else
1720*cdf0e10cSrcweir                 {
1721*cdf0e10cSrcweir                     // Property value will be stored in local property store.
1722*cdf0e10cSrcweir                     if ( !bTriedToGetAdditonalPropSet &&
1723*cdf0e10cSrcweir                          !xAdditionalPropSet.is() )
1724*cdf0e10cSrcweir                     {
1725*cdf0e10cSrcweir                         xAdditionalPropSet
1726*cdf0e10cSrcweir                             = getAdditionalPropertySet( sal_False );
1727*cdf0e10cSrcweir                         bTriedToGetAdditonalPropSet = sal_True;
1728*cdf0e10cSrcweir                     }
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir                     if ( xAdditionalPropSet.is() )
1731*cdf0e10cSrcweir                     {
1732*cdf0e10cSrcweir                         try
1733*cdf0e10cSrcweir                         {
1734*cdf0e10cSrcweir                             uno::Any aOldValue
1735*cdf0e10cSrcweir                                 = xAdditionalPropSet->getPropertyValue( rName );
1736*cdf0e10cSrcweir                             if ( aOldValue != rValue.Value )
1737*cdf0e10cSrcweir                             {
1738*cdf0e10cSrcweir                                 xAdditionalPropSet->setPropertyValue(
1739*cdf0e10cSrcweir                                                         rName, rValue.Value );
1740*cdf0e10cSrcweir 
1741*cdf0e10cSrcweir                                 aEvent.PropertyName = rName;
1742*cdf0e10cSrcweir                                 aEvent.OldValue     = aOldValue;
1743*cdf0e10cSrcweir                                 aEvent.NewValue     = rValue.Value;
1744*cdf0e10cSrcweir 
1745*cdf0e10cSrcweir                                 aChanges.getArray()[ nChanged ] = aEvent;
1746*cdf0e10cSrcweir                                 nChanged++;
1747*cdf0e10cSrcweir                             }
1748*cdf0e10cSrcweir                         }
1749*cdf0e10cSrcweir                         catch ( beans::UnknownPropertyException const & e )
1750*cdf0e10cSrcweir                         {
1751*cdf0e10cSrcweir                             aRet[ n ] <<= e;
1752*cdf0e10cSrcweir                         }
1753*cdf0e10cSrcweir                         catch ( lang::WrappedTargetException const & e )
1754*cdf0e10cSrcweir                         {
1755*cdf0e10cSrcweir                             aRet[ n ] <<= e;
1756*cdf0e10cSrcweir                         }
1757*cdf0e10cSrcweir                         catch ( beans::PropertyVetoException const & e )
1758*cdf0e10cSrcweir                         {
1759*cdf0e10cSrcweir                             aRet[ n ] <<= e;
1760*cdf0e10cSrcweir                         }
1761*cdf0e10cSrcweir                         catch ( lang::IllegalArgumentException const & e )
1762*cdf0e10cSrcweir                         {
1763*cdf0e10cSrcweir                             aRet[ n ] <<= e;
1764*cdf0e10cSrcweir                         }
1765*cdf0e10cSrcweir                     }
1766*cdf0e10cSrcweir                     else
1767*cdf0e10cSrcweir                     {
1768*cdf0e10cSrcweir                         aRet[ n ] <<= uno::Exception(
1769*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1770*cdf0e10cSrcweir                                     "No property set for storing the value!" ),
1771*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) );
1772*cdf0e10cSrcweir                     }
1773*cdf0e10cSrcweir                 }
1774*cdf0e10cSrcweir             }
1775*cdf0e10cSrcweir         }
1776*cdf0e10cSrcweir     } // for
1777*cdf0e10cSrcweir 
1778*cdf0e10cSrcweir     if ( !bTransient && aProppatchValues.size() )
1779*cdf0e10cSrcweir     {
1780*cdf0e10cSrcweir         try
1781*cdf0e10cSrcweir         {
1782*cdf0e10cSrcweir             // Set property values at server.
1783*cdf0e10cSrcweir             xResAccess->PROPPATCH( aProppatchValues, xEnv );
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir             std::vector< ProppatchValue >::const_iterator it
1786*cdf0e10cSrcweir                 = aProppatchValues.begin();
1787*cdf0e10cSrcweir             std::vector< ProppatchValue >::const_iterator end
1788*cdf0e10cSrcweir                 = aProppatchValues.end();
1789*cdf0e10cSrcweir 
1790*cdf0e10cSrcweir             while ( it != end )
1791*cdf0e10cSrcweir             {
1792*cdf0e10cSrcweir                 aEvent.PropertyName = (*it).name;
1793*cdf0e10cSrcweir                 aEvent.OldValue     = uno::Any(); // @@@ to expensive to obtain!
1794*cdf0e10cSrcweir                 aEvent.NewValue     = (*it).value;
1795*cdf0e10cSrcweir 
1796*cdf0e10cSrcweir                 aChanges.getArray()[ nChanged ] = aEvent;
1797*cdf0e10cSrcweir                 nChanged++;
1798*cdf0e10cSrcweir 
1799*cdf0e10cSrcweir                 ++it;
1800*cdf0e10cSrcweir             }
1801*cdf0e10cSrcweir         }
1802*cdf0e10cSrcweir         catch ( DAVException const & e )
1803*cdf0e10cSrcweir         {
1804*cdf0e10cSrcweir //            OSL_ENSURE( sal_False,
1805*cdf0e10cSrcweir //                        "Content::setPropertyValues - PROPPATCH failed!" );
1806*cdf0e10cSrcweir 
1807*cdf0e10cSrcweir #if 1
1808*cdf0e10cSrcweir             cancelCommandExecution( e, xEnv );
1809*cdf0e10cSrcweir             // unreachable
1810*cdf0e10cSrcweir #else
1811*cdf0e10cSrcweir             // Note: PROPPATCH either sets ALL property values OR NOTHING.
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir             std::vector< sal_Int32 >::const_iterator it
1814*cdf0e10cSrcweir                 = aProppatchPropsPositions.begin();
1815*cdf0e10cSrcweir             std::vector< sal_Int32 >::const_iterator end
1816*cdf0e10cSrcweir                 = aProppatchPropsPositions.end();
1817*cdf0e10cSrcweir 
1818*cdf0e10cSrcweir             while ( it != end )
1819*cdf0e10cSrcweir             {
1820*cdf0e10cSrcweir                 // Set error.
1821*cdf0e10cSrcweir                 aRet[ (*it) ] <<= MapDAVException( e, sal_True );
1822*cdf0e10cSrcweir                 ++it;
1823*cdf0e10cSrcweir             }
1824*cdf0e10cSrcweir #endif
1825*cdf0e10cSrcweir         }
1826*cdf0e10cSrcweir     }
1827*cdf0e10cSrcweir 
1828*cdf0e10cSrcweir     if ( bExchange )
1829*cdf0e10cSrcweir     {
1830*cdf0e10cSrcweir         // Assemble new content identifier...
1831*cdf0e10cSrcweir 
1832*cdf0e10cSrcweir         rtl::OUString aNewURL = getParentURL();
1833*cdf0e10cSrcweir         if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
1834*cdf0e10cSrcweir             aNewURL += rtl::OUString::createFromAscii( "/" );
1835*cdf0e10cSrcweir 
1836*cdf0e10cSrcweir         aNewURL += NeonUri::escapeSegment( aNewTitle );
1837*cdf0e10cSrcweir 
1838*cdf0e10cSrcweir         uno::Reference< ucb::XContentIdentifier > xNewId
1839*cdf0e10cSrcweir             = new ::ucbhelper::ContentIdentifier( xSMgr, aNewURL );
1840*cdf0e10cSrcweir         uno::Reference< ucb::XContentIdentifier > xOldId = xIdentifier;
1841*cdf0e10cSrcweir 
1842*cdf0e10cSrcweir         try
1843*cdf0e10cSrcweir         {
1844*cdf0e10cSrcweir             NeonUri sourceURI( xOldId->getContentIdentifier() );
1845*cdf0e10cSrcweir             NeonUri targetURI( xNewId->getContentIdentifier() );
1846*cdf0e10cSrcweir             targetURI.SetScheme( sourceURI.GetScheme() );
1847*cdf0e10cSrcweir 
1848*cdf0e10cSrcweir             xResAccess->MOVE(
1849*cdf0e10cSrcweir                 sourceURI.GetPath(), targetURI.GetURI(), sal_False, xEnv );
1850*cdf0e10cSrcweir             // @@@ Should check for resources that could not be moved
1851*cdf0e10cSrcweir             //     (due to source access or target overwrite) and send
1852*cdf0e10cSrcweir             //     this information through the interaction handler.
1853*cdf0e10cSrcweir 
1854*cdf0e10cSrcweir             // @@@ Existing content should be checked to see if it needs
1855*cdf0e10cSrcweir             //     to be deleted at the source
1856*cdf0e10cSrcweir 
1857*cdf0e10cSrcweir             // @@@ Existing content should be checked to see if it has
1858*cdf0e10cSrcweir             //     been overwritten at the target
1859*cdf0e10cSrcweir 
1860*cdf0e10cSrcweir             if ( exchangeIdentity( xNewId ) )
1861*cdf0e10cSrcweir             {
1862*cdf0e10cSrcweir                 xResAccess->setURL( aNewURL );
1863*cdf0e10cSrcweir 
1864*cdf0e10cSrcweir // DAV resources store all additional props on server!
1865*cdf0e10cSrcweir //              // Adapt Additional Core Properties.
1866*cdf0e10cSrcweir //              renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1867*cdf0e10cSrcweir //                                           xNewId->getContentIdentifier(),
1868*cdf0e10cSrcweir //                                           sal_True );
1869*cdf0e10cSrcweir             }
1870*cdf0e10cSrcweir             else
1871*cdf0e10cSrcweir             {
1872*cdf0e10cSrcweir                 // Do not set new title!
1873*cdf0e10cSrcweir                 aNewTitle = rtl::OUString();
1874*cdf0e10cSrcweir 
1875*cdf0e10cSrcweir                 // Set error .
1876*cdf0e10cSrcweir                 aRet[ nTitlePos ] <<= uno::Exception(
1877*cdf0e10cSrcweir                     rtl::OUString::createFromAscii( "Exchange failed!" ),
1878*cdf0e10cSrcweir                     static_cast< cppu::OWeakObject * >( this ) );
1879*cdf0e10cSrcweir             }
1880*cdf0e10cSrcweir         }
1881*cdf0e10cSrcweir         catch ( DAVException const & e )
1882*cdf0e10cSrcweir         {
1883*cdf0e10cSrcweir             // Do not set new title!
1884*cdf0e10cSrcweir             aNewTitle = rtl::OUString();
1885*cdf0e10cSrcweir 
1886*cdf0e10cSrcweir             // Set error .
1887*cdf0e10cSrcweir             aRet[ nTitlePos ] <<= MapDAVException( e, sal_True );
1888*cdf0e10cSrcweir         }
1889*cdf0e10cSrcweir     }
1890*cdf0e10cSrcweir 
1891*cdf0e10cSrcweir     if ( aNewTitle.getLength() )
1892*cdf0e10cSrcweir     {
1893*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1894*cdf0e10cSrcweir 
1895*cdf0e10cSrcweir         aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
1896*cdf0e10cSrcweir         aEvent.OldValue     = uno::makeAny( aOldTitle );
1897*cdf0e10cSrcweir         aEvent.NewValue     = uno::makeAny( aNewTitle );
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir         m_aEscapedTitle     = NeonUri::escapeSegment( aNewTitle );
1900*cdf0e10cSrcweir 
1901*cdf0e10cSrcweir         aChanges.getArray()[ nChanged ] = aEvent;
1902*cdf0e10cSrcweir         nChanged++;
1903*cdf0e10cSrcweir     }
1904*cdf0e10cSrcweir 
1905*cdf0e10cSrcweir     if ( nChanged > 0 )
1906*cdf0e10cSrcweir     {
1907*cdf0e10cSrcweir         aChanges.realloc( nChanged );
1908*cdf0e10cSrcweir         notifyPropertiesChange( aChanges );
1909*cdf0e10cSrcweir     }
1910*cdf0e10cSrcweir 
1911*cdf0e10cSrcweir     {
1912*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
1913*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1914*cdf0e10cSrcweir     }
1915*cdf0e10cSrcweir 
1916*cdf0e10cSrcweir     return aRet;
1917*cdf0e10cSrcweir }
1918*cdf0e10cSrcweir 
1919*cdf0e10cSrcweir //=========================================================================
1920*cdf0e10cSrcweir uno::Any Content::open(
1921*cdf0e10cSrcweir                 const ucb::OpenCommandArgument2 & rArg,
1922*cdf0e10cSrcweir                 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1923*cdf0e10cSrcweir     throw( uno::Exception )
1924*cdf0e10cSrcweir {
1925*cdf0e10cSrcweir     uno::Any aRet;
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir     sal_Bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) ||
1928*cdf0e10cSrcweir                              ( rArg.Mode == ucb::OpenMode::FOLDERS ) ||
1929*cdf0e10cSrcweir                              ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) );
1930*cdf0e10cSrcweir     if ( bOpenFolder )
1931*cdf0e10cSrcweir     {
1932*cdf0e10cSrcweir         if ( isFolder( xEnv ) )
1933*cdf0e10cSrcweir         {
1934*cdf0e10cSrcweir             // Open collection.
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir             uno::Reference< ucb::XDynamicResultSet > xSet
1937*cdf0e10cSrcweir                 = new DynamicResultSet( m_xSMgr, this, rArg, xEnv );
1938*cdf0e10cSrcweir             aRet <<= xSet;
1939*cdf0e10cSrcweir         }
1940*cdf0e10cSrcweir         else
1941*cdf0e10cSrcweir         {
1942*cdf0e10cSrcweir             // Error: Not a folder!
1943*cdf0e10cSrcweir 
1944*cdf0e10cSrcweir             rtl::OUStringBuffer aMsg;
1945*cdf0e10cSrcweir             if ( getResourceType( xEnv ) == FTP )
1946*cdf0e10cSrcweir             {
1947*cdf0e10cSrcweir                 // #114653#
1948*cdf0e10cSrcweir                 aMsg.appendAscii( "FTP over HTTP proxy: resource cannot "
1949*cdf0e10cSrcweir                                   "be opened as folder! Wrong Open Mode!" );
1950*cdf0e10cSrcweir             }
1951*cdf0e10cSrcweir             else
1952*cdf0e10cSrcweir             {
1953*cdf0e10cSrcweir                 aMsg.appendAscii( "Non-folder resource cannot be "
1954*cdf0e10cSrcweir                                   "opened as folder! Wrong Open Mode!" );
1955*cdf0e10cSrcweir             }
1956*cdf0e10cSrcweir 
1957*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
1958*cdf0e10cSrcweir                 uno::makeAny(
1959*cdf0e10cSrcweir                     lang::IllegalArgumentException(
1960*cdf0e10cSrcweir                         aMsg.makeStringAndClear(),
1961*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ),
1962*cdf0e10cSrcweir                         -1 ) ),
1963*cdf0e10cSrcweir                 xEnv );
1964*cdf0e10cSrcweir             // Unreachable
1965*cdf0e10cSrcweir         }
1966*cdf0e10cSrcweir     }
1967*cdf0e10cSrcweir 
1968*cdf0e10cSrcweir     if ( rArg.Sink.is() )
1969*cdf0e10cSrcweir     {
1970*cdf0e10cSrcweir         // Open document.
1971*cdf0e10cSrcweir 
1972*cdf0e10cSrcweir         if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1973*cdf0e10cSrcweir              ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1974*cdf0e10cSrcweir         {
1975*cdf0e10cSrcweir             // Currently(?) unsupported.
1976*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
1977*cdf0e10cSrcweir                 uno::makeAny(
1978*cdf0e10cSrcweir                     ucb::UnsupportedOpenModeException(
1979*cdf0e10cSrcweir                             rtl::OUString(),
1980*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ),
1981*cdf0e10cSrcweir                             sal_Int16( rArg.Mode ) ) ),
1982*cdf0e10cSrcweir                 xEnv );
1983*cdf0e10cSrcweir             // Unreachable
1984*cdf0e10cSrcweir         }
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir         rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
1987*cdf0e10cSrcweir         uno::Reference< io::XOutputStream > xOut
1988*cdf0e10cSrcweir             = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
1989*cdf0e10cSrcweir         if ( xOut.is() )
1990*cdf0e10cSrcweir         {
1991*cdf0e10cSrcweir             // PUSH: write data
1992*cdf0e10cSrcweir             try
1993*cdf0e10cSrcweir             {
1994*cdf0e10cSrcweir                 std::auto_ptr< DAVResourceAccess > xResAccess;
1995*cdf0e10cSrcweir 
1996*cdf0e10cSrcweir                 {
1997*cdf0e10cSrcweir                     osl::MutexGuard aGuard( m_aMutex );
1998*cdf0e10cSrcweir 
1999*cdf0e10cSrcweir                     xResAccess.reset(
2000*cdf0e10cSrcweir                         new DAVResourceAccess( *m_xResAccess.get() ) );
2001*cdf0e10cSrcweir                 }
2002*cdf0e10cSrcweir 
2003*cdf0e10cSrcweir                 DAVResource aResource;
2004*cdf0e10cSrcweir                 std::vector< rtl::OUString > aHeaders;
2005*cdf0e10cSrcweir 
2006*cdf0e10cSrcweir                 xResAccess->GET( xOut, aHeaders, aResource, xEnv );
2007*cdf0e10cSrcweir                 m_bDidGetOrHead = true;
2008*cdf0e10cSrcweir 
2009*cdf0e10cSrcweir                 {
2010*cdf0e10cSrcweir                     osl::MutexGuard aGuard( m_aMutex );
2011*cdf0e10cSrcweir 
2012*cdf0e10cSrcweir                     // cache headers.
2013*cdf0e10cSrcweir                     if ( !m_xCachedProps.get())
2014*cdf0e10cSrcweir                         m_xCachedProps.reset(
2015*cdf0e10cSrcweir                             new CachableContentProperties( aResource ) );
2016*cdf0e10cSrcweir                     else
2017*cdf0e10cSrcweir                         m_xCachedProps->addProperties( aResource );
2018*cdf0e10cSrcweir 
2019*cdf0e10cSrcweir                     m_xResAccess.reset(
2020*cdf0e10cSrcweir                         new DAVResourceAccess( *xResAccess.get() ) );
2021*cdf0e10cSrcweir                 }
2022*cdf0e10cSrcweir             }
2023*cdf0e10cSrcweir             catch ( DAVException const & e )
2024*cdf0e10cSrcweir             {
2025*cdf0e10cSrcweir                 cancelCommandExecution( e, xEnv );
2026*cdf0e10cSrcweir                 // Unreachable
2027*cdf0e10cSrcweir             }
2028*cdf0e10cSrcweir         }
2029*cdf0e10cSrcweir         else
2030*cdf0e10cSrcweir         {
2031*cdf0e10cSrcweir             uno::Reference< io::XActiveDataSink > xDataSink
2032*cdf0e10cSrcweir                 = uno::Reference< io::XActiveDataSink >( rArg.Sink,
2033*cdf0e10cSrcweir                                                          uno::UNO_QUERY );
2034*cdf0e10cSrcweir             if ( xDataSink.is() )
2035*cdf0e10cSrcweir             {
2036*cdf0e10cSrcweir                 // PULL: wait for client read
2037*cdf0e10cSrcweir                 try
2038*cdf0e10cSrcweir                 {
2039*cdf0e10cSrcweir                     std::auto_ptr< DAVResourceAccess > xResAccess;
2040*cdf0e10cSrcweir                     {
2041*cdf0e10cSrcweir                         osl::MutexGuard aGuard( m_aMutex );
2042*cdf0e10cSrcweir 
2043*cdf0e10cSrcweir                         xResAccess.reset(
2044*cdf0e10cSrcweir                             new DAVResourceAccess( *m_xResAccess.get() ) );
2045*cdf0e10cSrcweir                     }
2046*cdf0e10cSrcweir 
2047*cdf0e10cSrcweir                     // fill inputsream sync; return if all data present
2048*cdf0e10cSrcweir                     DAVResource aResource;
2049*cdf0e10cSrcweir                     std::vector< rtl::OUString > aHeaders;
2050*cdf0e10cSrcweir 
2051*cdf0e10cSrcweir                     uno::Reference< io::XInputStream > xIn
2052*cdf0e10cSrcweir                         = xResAccess->GET( aHeaders, aResource, xEnv );
2053*cdf0e10cSrcweir                     m_bDidGetOrHead = true;
2054*cdf0e10cSrcweir 
2055*cdf0e10cSrcweir                     {
2056*cdf0e10cSrcweir                         osl::MutexGuard aGuard( m_aMutex );
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir                         // cache headers.
2059*cdf0e10cSrcweir                         if ( !m_xCachedProps.get())
2060*cdf0e10cSrcweir                             m_xCachedProps.reset(
2061*cdf0e10cSrcweir                                 new CachableContentProperties( aResource ) );
2062*cdf0e10cSrcweir                         else
2063*cdf0e10cSrcweir                             m_xCachedProps->addProperties(
2064*cdf0e10cSrcweir                                 aResource.properties );
2065*cdf0e10cSrcweir 
2066*cdf0e10cSrcweir                         m_xResAccess.reset(
2067*cdf0e10cSrcweir                             new DAVResourceAccess( *xResAccess.get() ) );
2068*cdf0e10cSrcweir                     }
2069*cdf0e10cSrcweir 
2070*cdf0e10cSrcweir                     xDataSink->setInputStream( xIn );
2071*cdf0e10cSrcweir                 }
2072*cdf0e10cSrcweir                 catch ( DAVException const & e )
2073*cdf0e10cSrcweir                 {
2074*cdf0e10cSrcweir                     cancelCommandExecution( e, xEnv );
2075*cdf0e10cSrcweir                     // Unreachable
2076*cdf0e10cSrcweir                 }
2077*cdf0e10cSrcweir             }
2078*cdf0e10cSrcweir             else
2079*cdf0e10cSrcweir             {
2080*cdf0e10cSrcweir                 // Note: aOpenCommand.Sink may contain an XStream
2081*cdf0e10cSrcweir                 //       implementation. Support for this type of
2082*cdf0e10cSrcweir                 //       sink is optional...
2083*cdf0e10cSrcweir                 ucbhelper::cancelCommandExecution(
2084*cdf0e10cSrcweir                     uno::makeAny(
2085*cdf0e10cSrcweir                         ucb::UnsupportedDataSinkException(
2086*cdf0e10cSrcweir                             rtl::OUString(),
2087*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ),
2088*cdf0e10cSrcweir                             rArg.Sink ) ),
2089*cdf0e10cSrcweir                     xEnv );
2090*cdf0e10cSrcweir                 // Unreachable
2091*cdf0e10cSrcweir             }
2092*cdf0e10cSrcweir         }
2093*cdf0e10cSrcweir     }
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir     return aRet;
2096*cdf0e10cSrcweir }
2097*cdf0e10cSrcweir 
2098*cdf0e10cSrcweir //=========================================================================
2099*cdf0e10cSrcweir void Content::post(
2100*cdf0e10cSrcweir                 const ucb::PostCommandArgument2 & rArg,
2101*cdf0e10cSrcweir                 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2102*cdf0e10cSrcweir     throw( uno::Exception )
2103*cdf0e10cSrcweir {
2104*cdf0e10cSrcweir     uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
2105*cdf0e10cSrcweir     if ( xSink.is() )
2106*cdf0e10cSrcweir     {
2107*cdf0e10cSrcweir         try
2108*cdf0e10cSrcweir         {
2109*cdf0e10cSrcweir             std::auto_ptr< DAVResourceAccess > xResAccess;
2110*cdf0e10cSrcweir             {
2111*cdf0e10cSrcweir                 osl::MutexGuard aGuard( m_aMutex );
2112*cdf0e10cSrcweir                 xResAccess.reset(
2113*cdf0e10cSrcweir                     new DAVResourceAccess( *m_xResAccess.get() ) );
2114*cdf0e10cSrcweir             }
2115*cdf0e10cSrcweir 
2116*cdf0e10cSrcweir             uno::Reference< io::XInputStream > xResult
2117*cdf0e10cSrcweir                 = xResAccess->POST( rArg.MediaType,
2118*cdf0e10cSrcweir                                     rArg.Referer,
2119*cdf0e10cSrcweir                                     rArg.Source,
2120*cdf0e10cSrcweir                                     xEnv );
2121*cdf0e10cSrcweir 
2122*cdf0e10cSrcweir             {
2123*cdf0e10cSrcweir                  osl::MutexGuard aGuard( m_aMutex );
2124*cdf0e10cSrcweir                  m_xResAccess.reset(
2125*cdf0e10cSrcweir                      new DAVResourceAccess( *xResAccess.get() ) );
2126*cdf0e10cSrcweir             }
2127*cdf0e10cSrcweir 
2128*cdf0e10cSrcweir             xSink->setInputStream( xResult );
2129*cdf0e10cSrcweir         }
2130*cdf0e10cSrcweir         catch ( DAVException const & e )
2131*cdf0e10cSrcweir         {
2132*cdf0e10cSrcweir             cancelCommandExecution( e, xEnv, sal_True );
2133*cdf0e10cSrcweir             // Unreachable
2134*cdf0e10cSrcweir         }
2135*cdf0e10cSrcweir     }
2136*cdf0e10cSrcweir     else
2137*cdf0e10cSrcweir     {
2138*cdf0e10cSrcweir         uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
2139*cdf0e10cSrcweir         if ( xResult.is() )
2140*cdf0e10cSrcweir         {
2141*cdf0e10cSrcweir             try
2142*cdf0e10cSrcweir             {
2143*cdf0e10cSrcweir                 std::auto_ptr< DAVResourceAccess > xResAccess;
2144*cdf0e10cSrcweir                 {
2145*cdf0e10cSrcweir                     osl::MutexGuard aGuard( m_aMutex );
2146*cdf0e10cSrcweir                     xResAccess.reset(
2147*cdf0e10cSrcweir                         new DAVResourceAccess( *m_xResAccess.get() ) );
2148*cdf0e10cSrcweir                 }
2149*cdf0e10cSrcweir 
2150*cdf0e10cSrcweir                 xResAccess->POST( rArg.MediaType,
2151*cdf0e10cSrcweir                                   rArg.Referer,
2152*cdf0e10cSrcweir                                   rArg.Source,
2153*cdf0e10cSrcweir                                   xResult,
2154*cdf0e10cSrcweir                                   xEnv );
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir                 {
2157*cdf0e10cSrcweir                     osl::MutexGuard aGuard( m_aMutex );
2158*cdf0e10cSrcweir                     m_xResAccess.reset(
2159*cdf0e10cSrcweir                         new DAVResourceAccess( *xResAccess.get() ) );
2160*cdf0e10cSrcweir                 }
2161*cdf0e10cSrcweir             }
2162*cdf0e10cSrcweir             catch ( DAVException const & e )
2163*cdf0e10cSrcweir             {
2164*cdf0e10cSrcweir                 cancelCommandExecution( e, xEnv, sal_True );
2165*cdf0e10cSrcweir                 // Unreachable
2166*cdf0e10cSrcweir             }
2167*cdf0e10cSrcweir         }
2168*cdf0e10cSrcweir         else
2169*cdf0e10cSrcweir         {
2170*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
2171*cdf0e10cSrcweir                 uno::makeAny(
2172*cdf0e10cSrcweir                     ucb::UnsupportedDataSinkException(
2173*cdf0e10cSrcweir                         rtl::OUString(),
2174*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ),
2175*cdf0e10cSrcweir                         rArg.Sink ) ),
2176*cdf0e10cSrcweir                 xEnv );
2177*cdf0e10cSrcweir             // Unreachable
2178*cdf0e10cSrcweir         }
2179*cdf0e10cSrcweir     }
2180*cdf0e10cSrcweir }
2181*cdf0e10cSrcweir 
2182*cdf0e10cSrcweir //=========================================================================
2183*cdf0e10cSrcweir void Content::queryChildren( ContentRefList& rChildren )
2184*cdf0e10cSrcweir {
2185*cdf0e10cSrcweir     // Obtain a list with a snapshot of all currently instanciated contents
2186*cdf0e10cSrcweir     // from provider and extract the contents which are direct children
2187*cdf0e10cSrcweir     // of this content.
2188*cdf0e10cSrcweir 
2189*cdf0e10cSrcweir     ::ucbhelper::ContentRefList aAllContents;
2190*cdf0e10cSrcweir     m_xProvider->queryExistingContents( aAllContents );
2191*cdf0e10cSrcweir 
2192*cdf0e10cSrcweir     rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
2193*cdf0e10cSrcweir     sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
2194*cdf0e10cSrcweir 
2195*cdf0e10cSrcweir     if ( nURLPos != ( aURL.getLength() - 1 ) )
2196*cdf0e10cSrcweir     {
2197*cdf0e10cSrcweir         // No trailing slash found. Append.
2198*cdf0e10cSrcweir         aURL += rtl::OUString::createFromAscii( "/" );
2199*cdf0e10cSrcweir     }
2200*cdf0e10cSrcweir 
2201*cdf0e10cSrcweir     sal_Int32 nLen = aURL.getLength();
2202*cdf0e10cSrcweir 
2203*cdf0e10cSrcweir     ::ucbhelper::ContentRefList::const_iterator it  = aAllContents.begin();
2204*cdf0e10cSrcweir     ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2205*cdf0e10cSrcweir 
2206*cdf0e10cSrcweir     while ( it != end )
2207*cdf0e10cSrcweir     {
2208*cdf0e10cSrcweir         ::ucbhelper::ContentImplHelperRef xChild = (*it);
2209*cdf0e10cSrcweir         rtl::OUString aChildURL
2210*cdf0e10cSrcweir             = xChild->getIdentifier()->getContentIdentifier();
2211*cdf0e10cSrcweir 
2212*cdf0e10cSrcweir         // Is aURL a prefix of aChildURL?
2213*cdf0e10cSrcweir         if ( ( aChildURL.getLength() > nLen ) &&
2214*cdf0e10cSrcweir              ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
2215*cdf0e10cSrcweir         {
2216*cdf0e10cSrcweir             sal_Int32 nPos = nLen;
2217*cdf0e10cSrcweir             nPos = aChildURL.indexOf( '/', nPos );
2218*cdf0e10cSrcweir 
2219*cdf0e10cSrcweir             if ( ( nPos == -1 ) ||
2220*cdf0e10cSrcweir                  ( nPos == ( aChildURL.getLength() - 1 ) ) )
2221*cdf0e10cSrcweir             {
2222*cdf0e10cSrcweir                 // No further slashes / only a final slash. It's a child!
2223*cdf0e10cSrcweir                 rChildren.push_back(
2224*cdf0e10cSrcweir                     ::webdav_ucp::Content::ContentRef(
2225*cdf0e10cSrcweir                         static_cast< ::webdav_ucp::Content * >(
2226*cdf0e10cSrcweir                             xChild.get() ) ) );
2227*cdf0e10cSrcweir             }
2228*cdf0e10cSrcweir         }
2229*cdf0e10cSrcweir         ++it;
2230*cdf0e10cSrcweir     }
2231*cdf0e10cSrcweir }
2232*cdf0e10cSrcweir 
2233*cdf0e10cSrcweir //=========================================================================
2234*cdf0e10cSrcweir void Content::insert(
2235*cdf0e10cSrcweir         const uno::Reference< io::XInputStream > & xInputStream,
2236*cdf0e10cSrcweir         sal_Bool bReplaceExisting,
2237*cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment >& Environment )
2238*cdf0e10cSrcweir     throw( uno::Exception )
2239*cdf0e10cSrcweir {
2240*cdf0e10cSrcweir     sal_Bool bTransient, bCollection;
2241*cdf0e10cSrcweir     rtl::OUString aEscapedTitle;
2242*cdf0e10cSrcweir     std::auto_ptr< DAVResourceAccess > xResAccess;
2243*cdf0e10cSrcweir 
2244*cdf0e10cSrcweir     {
2245*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
2246*cdf0e10cSrcweir 
2247*cdf0e10cSrcweir         bTransient    = m_bTransient;
2248*cdf0e10cSrcweir         bCollection   = m_bCollection;
2249*cdf0e10cSrcweir         aEscapedTitle = m_aEscapedTitle;
2250*cdf0e10cSrcweir         xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2251*cdf0e10cSrcweir     }
2252*cdf0e10cSrcweir 
2253*cdf0e10cSrcweir     // Check, if all required properties are present.
2254*cdf0e10cSrcweir 
2255*cdf0e10cSrcweir     if ( aEscapedTitle.getLength() == 0 )
2256*cdf0e10cSrcweir     {
2257*cdf0e10cSrcweir         OSL_ENSURE( sal_False, "Content::insert - Title missing!" );
2258*cdf0e10cSrcweir 
2259*cdf0e10cSrcweir         uno::Sequence< rtl::OUString > aProps( 1 );
2260*cdf0e10cSrcweir         aProps[ 0 ] = rtl::OUString::createFromAscii( "Title" );
2261*cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
2262*cdf0e10cSrcweir             uno::makeAny( ucb::MissingPropertiesException(
2263*cdf0e10cSrcweir                                 rtl::OUString(),
2264*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ),
2265*cdf0e10cSrcweir                                 aProps ) ),
2266*cdf0e10cSrcweir             Environment );
2267*cdf0e10cSrcweir         // Unreachable
2268*cdf0e10cSrcweir     }
2269*cdf0e10cSrcweir 
2270*cdf0e10cSrcweir     if ( !bReplaceExisting )
2271*cdf0e10cSrcweir     {
2272*cdf0e10cSrcweir         /* [RFC 2616] - HTTP
2273*cdf0e10cSrcweir 
2274*cdf0e10cSrcweir            The PUT method requests that the enclosed entity be stored under the
2275*cdf0e10cSrcweir            supplied Request-URI. If the Request-URI refers to an already
2276*cdf0e10cSrcweir            existing resource, the enclosed entity SHOULD be considered as a
2277*cdf0e10cSrcweir            modified version of the one residing on the origin server.
2278*cdf0e10cSrcweir         */
2279*cdf0e10cSrcweir 
2280*cdf0e10cSrcweir         /* [RFC 2518] - WebDAV
2281*cdf0e10cSrcweir 
2282*cdf0e10cSrcweir            MKCOL creates a new collection resource at the location specified by
2283*cdf0e10cSrcweir            the Request-URI.  If the resource identified by the Request-URI is
2284*cdf0e10cSrcweir            non-null then the MKCOL MUST fail.
2285*cdf0e10cSrcweir         */
2286*cdf0e10cSrcweir 
2287*cdf0e10cSrcweir         // ==> Complain on PUT, continue on MKCOL.
2288*cdf0e10cSrcweir         if ( !bTransient || ( bTransient && !bCollection  ) )
2289*cdf0e10cSrcweir         {
2290*cdf0e10cSrcweir             ucb::UnsupportedNameClashException aEx(
2291*cdf0e10cSrcweir                 rtl::OUString::createFromAscii(
2292*cdf0e10cSrcweir                     "Unable to write without overwrite!" ),
2293*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
2294*cdf0e10cSrcweir                 ucb::NameClash::ERROR );
2295*cdf0e10cSrcweir 
2296*cdf0e10cSrcweir             uno::Reference< task::XInteractionHandler > xIH;
2297*cdf0e10cSrcweir 
2298*cdf0e10cSrcweir             if ( Environment.is() )
2299*cdf0e10cSrcweir                 xIH = Environment->getInteractionHandler();
2300*cdf0e10cSrcweir 
2301*cdf0e10cSrcweir             if ( xIH.is() )
2302*cdf0e10cSrcweir             {
2303*cdf0e10cSrcweir                 uno::Any aExAsAny( uno::makeAny( aEx ) );
2304*cdf0e10cSrcweir 
2305*cdf0e10cSrcweir                 rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest
2306*cdf0e10cSrcweir                     = new ucbhelper::SimpleInteractionRequest(
2307*cdf0e10cSrcweir                         aExAsAny,
2308*cdf0e10cSrcweir                         ucbhelper::CONTINUATION_APPROVE
2309*cdf0e10cSrcweir                             | ucbhelper::CONTINUATION_DISAPPROVE );
2310*cdf0e10cSrcweir                 xIH->handle( xRequest.get() );
2311*cdf0e10cSrcweir 
2312*cdf0e10cSrcweir                 const sal_Int32 nResp = xRequest->getResponse();
2313*cdf0e10cSrcweir 
2314*cdf0e10cSrcweir                 switch ( nResp )
2315*cdf0e10cSrcweir                 {
2316*cdf0e10cSrcweir                     case ucbhelper::CONTINUATION_UNKNOWN:
2317*cdf0e10cSrcweir                         // Not handled; throw.
2318*cdf0e10cSrcweir                         throw aEx;
2319*cdf0e10cSrcweir //                            break;
2320*cdf0e10cSrcweir 
2321*cdf0e10cSrcweir                     case ucbhelper::CONTINUATION_APPROVE:
2322*cdf0e10cSrcweir                         // Continue -> Overwrite.
2323*cdf0e10cSrcweir                         bReplaceExisting = sal_True;
2324*cdf0e10cSrcweir                         break;
2325*cdf0e10cSrcweir 
2326*cdf0e10cSrcweir                     case ucbhelper::CONTINUATION_DISAPPROVE:
2327*cdf0e10cSrcweir                         // Abort.
2328*cdf0e10cSrcweir                         throw ucb::CommandFailedException(
2329*cdf0e10cSrcweir                                     rtl::OUString(),
2330*cdf0e10cSrcweir                                     uno::Reference< uno::XInterface >(),
2331*cdf0e10cSrcweir                                     aExAsAny );
2332*cdf0e10cSrcweir //                            break;
2333*cdf0e10cSrcweir 
2334*cdf0e10cSrcweir                     default:
2335*cdf0e10cSrcweir                         OSL_ENSURE( sal_False,
2336*cdf0e10cSrcweir                                     "Content::insert - "
2337*cdf0e10cSrcweir                                     "Unknown interaction selection!" );
2338*cdf0e10cSrcweir                         throw ucb::CommandFailedException(
2339*cdf0e10cSrcweir                                     rtl::OUString::createFromAscii(
2340*cdf0e10cSrcweir                                         "Unknown interaction selection!" ),
2341*cdf0e10cSrcweir                                     uno::Reference< uno::XInterface >(),
2342*cdf0e10cSrcweir                                     aExAsAny );
2343*cdf0e10cSrcweir //                            break;
2344*cdf0e10cSrcweir                 }
2345*cdf0e10cSrcweir             }
2346*cdf0e10cSrcweir             else
2347*cdf0e10cSrcweir             {
2348*cdf0e10cSrcweir                 // No IH; throw.
2349*cdf0e10cSrcweir                 throw aEx;
2350*cdf0e10cSrcweir             }
2351*cdf0e10cSrcweir         }
2352*cdf0e10cSrcweir     }
2353*cdf0e10cSrcweir 
2354*cdf0e10cSrcweir     if ( bTransient )
2355*cdf0e10cSrcweir     {
2356*cdf0e10cSrcweir         // Assemble new content identifier...
2357*cdf0e10cSrcweir         rtl::OUString aURL = getParentURL();
2358*cdf0e10cSrcweir         if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) )
2359*cdf0e10cSrcweir             aURL += rtl::OUString::createFromAscii( "/" );
2360*cdf0e10cSrcweir 
2361*cdf0e10cSrcweir         aURL += aEscapedTitle;
2362*cdf0e10cSrcweir 
2363*cdf0e10cSrcweir         try
2364*cdf0e10cSrcweir         {
2365*cdf0e10cSrcweir             xResAccess->setURL( aURL );
2366*cdf0e10cSrcweir 
2367*cdf0e10cSrcweir             if ( bCollection )
2368*cdf0e10cSrcweir                 xResAccess->MKCOL( Environment );
2369*cdf0e10cSrcweir             else
2370*cdf0e10cSrcweir                 xResAccess->PUT( xInputStream, Environment );
2371*cdf0e10cSrcweir         }
2372*cdf0e10cSrcweir         catch ( DAVException const & except )
2373*cdf0e10cSrcweir         {
2374*cdf0e10cSrcweir             if ( bCollection )
2375*cdf0e10cSrcweir             {
2376*cdf0e10cSrcweir                 if ( except.getStatus() == SC_METHOD_NOT_ALLOWED )
2377*cdf0e10cSrcweir                 {
2378*cdf0e10cSrcweir                     // [RFC 2518] - WebDAV
2379*cdf0e10cSrcweir                     // 405 (Method Not Allowed) - MKCOL can only be
2380*cdf0e10cSrcweir                     // executed on a deleted/non-existent resource.
2381*cdf0e10cSrcweir 
2382*cdf0e10cSrcweir                     if ( bReplaceExisting )
2383*cdf0e10cSrcweir                     {
2384*cdf0e10cSrcweir                         // Destroy old resource.
2385*cdf0e10cSrcweir                         try
2386*cdf0e10cSrcweir                         {
2387*cdf0e10cSrcweir                             xResAccess->DESTROY( Environment );
2388*cdf0e10cSrcweir                         }
2389*cdf0e10cSrcweir                         catch ( DAVException const & e )
2390*cdf0e10cSrcweir                         {
2391*cdf0e10cSrcweir                             cancelCommandExecution( e, Environment, sal_True );
2392*cdf0e10cSrcweir                             // Unreachable
2393*cdf0e10cSrcweir                         }
2394*cdf0e10cSrcweir 
2395*cdf0e10cSrcweir                         // Insert (recursion!).
2396*cdf0e10cSrcweir                         insert( xInputStream, bReplaceExisting, Environment );
2397*cdf0e10cSrcweir 
2398*cdf0e10cSrcweir                         {
2399*cdf0e10cSrcweir                             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2400*cdf0e10cSrcweir                             m_xResAccess.reset(
2401*cdf0e10cSrcweir                                 new DAVResourceAccess( *xResAccess.get() ) );
2402*cdf0e10cSrcweir                         }
2403*cdf0e10cSrcweir 
2404*cdf0e10cSrcweir                         // Success!
2405*cdf0e10cSrcweir                         return;
2406*cdf0e10cSrcweir                     }
2407*cdf0e10cSrcweir                     else
2408*cdf0e10cSrcweir                     {
2409*cdf0e10cSrcweir                         rtl::OUString aTitle;
2410*cdf0e10cSrcweir                         try
2411*cdf0e10cSrcweir                         {
2412*cdf0e10cSrcweir                             NeonUri aURI( aURL );
2413*cdf0e10cSrcweir                             aTitle = aURI.GetPathBaseNameUnescaped();
2414*cdf0e10cSrcweir                         }
2415*cdf0e10cSrcweir                         catch ( DAVException const & )
2416*cdf0e10cSrcweir                         {
2417*cdf0e10cSrcweir                         }
2418*cdf0e10cSrcweir 
2419*cdf0e10cSrcweir                         ucbhelper::cancelCommandExecution(
2420*cdf0e10cSrcweir                             uno::makeAny(
2421*cdf0e10cSrcweir                                 ucb::NameClashException(
2422*cdf0e10cSrcweir                                     rtl::OUString(),
2423*cdf0e10cSrcweir                                     static_cast< cppu::OWeakObject * >( this ),
2424*cdf0e10cSrcweir                                     task::InteractionClassification_ERROR,
2425*cdf0e10cSrcweir                                     aTitle ) ),
2426*cdf0e10cSrcweir                             Environment );
2427*cdf0e10cSrcweir                         // Unreachable
2428*cdf0e10cSrcweir                     }
2429*cdf0e10cSrcweir                 }
2430*cdf0e10cSrcweir             }
2431*cdf0e10cSrcweir 
2432*cdf0e10cSrcweir             cancelCommandExecution( except, Environment, sal_True );
2433*cdf0e10cSrcweir             // Unreachable
2434*cdf0e10cSrcweir         }
2435*cdf0e10cSrcweir 
2436*cdf0e10cSrcweir         {
2437*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2438*cdf0e10cSrcweir             m_xIdentifier
2439*cdf0e10cSrcweir                 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
2440*cdf0e10cSrcweir         }
2441*cdf0e10cSrcweir 
2442*cdf0e10cSrcweir         inserted();
2443*cdf0e10cSrcweir 
2444*cdf0e10cSrcweir         {
2445*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2446*cdf0e10cSrcweir             m_bTransient = sal_False;
2447*cdf0e10cSrcweir         }
2448*cdf0e10cSrcweir     }
2449*cdf0e10cSrcweir     else
2450*cdf0e10cSrcweir     {
2451*cdf0e10cSrcweir         if ( !xInputStream.is() )
2452*cdf0e10cSrcweir         {
2453*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
2454*cdf0e10cSrcweir                 uno::makeAny(
2455*cdf0e10cSrcweir                     ucb::MissingInputStreamException(
2456*cdf0e10cSrcweir                         rtl::OUString(),
2457*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ) ) ),
2458*cdf0e10cSrcweir                 Environment );
2459*cdf0e10cSrcweir             // Unreachable
2460*cdf0e10cSrcweir         }
2461*cdf0e10cSrcweir 
2462*cdf0e10cSrcweir         try
2463*cdf0e10cSrcweir         {
2464*cdf0e10cSrcweir             xResAccess->PUT( xInputStream, Environment );
2465*cdf0e10cSrcweir         }
2466*cdf0e10cSrcweir         catch ( DAVException const & e )
2467*cdf0e10cSrcweir         {
2468*cdf0e10cSrcweir             cancelCommandExecution( e, Environment, sal_True );
2469*cdf0e10cSrcweir             // Unreachable
2470*cdf0e10cSrcweir         }
2471*cdf0e10cSrcweir     }
2472*cdf0e10cSrcweir 
2473*cdf0e10cSrcweir     {
2474*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
2475*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2476*cdf0e10cSrcweir     }
2477*cdf0e10cSrcweir }
2478*cdf0e10cSrcweir 
2479*cdf0e10cSrcweir //=========================================================================
2480*cdf0e10cSrcweir void Content::transfer(
2481*cdf0e10cSrcweir         const ucb::TransferInfo & rArgs,
2482*cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment >& Environment )
2483*cdf0e10cSrcweir     throw( uno::Exception )
2484*cdf0e10cSrcweir {
2485*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xSMgr;
2486*cdf0e10cSrcweir     uno::Reference< ucb::XContentIdentifier >    xIdentifier;
2487*cdf0e10cSrcweir     uno::Reference< ucb::XContentProvider >      xProvider;
2488*cdf0e10cSrcweir     std::auto_ptr< DAVResourceAccess > xResAccess;
2489*cdf0e10cSrcweir 
2490*cdf0e10cSrcweir     {
2491*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
2492*cdf0e10cSrcweir 
2493*cdf0e10cSrcweir         xSMgr.set( m_xSMgr );
2494*cdf0e10cSrcweir         xIdentifier.set( m_xIdentifier );
2495*cdf0e10cSrcweir         xProvider.set( m_xProvider.get() );
2496*cdf0e10cSrcweir         xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2497*cdf0e10cSrcweir     }
2498*cdf0e10cSrcweir 
2499*cdf0e10cSrcweir     rtl::OUString aTargetURI;
2500*cdf0e10cSrcweir     try
2501*cdf0e10cSrcweir     {
2502*cdf0e10cSrcweir         NeonUri sourceURI( rArgs.SourceURL );
2503*cdf0e10cSrcweir         NeonUri targetURI( xIdentifier->getContentIdentifier() );
2504*cdf0e10cSrcweir         aTargetURI = targetURI.GetPathBaseNameUnescaped();
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir         // Check source's and target's URL scheme
2507*cdf0e10cSrcweir         //
2508*cdf0e10cSrcweir         const rtl::OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase();
2509*cdf0e10cSrcweir         if ( aScheme.equalsAsciiL(
2510*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
2511*cdf0e10cSrcweir         {
2512*cdf0e10cSrcweir             sourceURI.SetScheme(
2513*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2514*cdf0e10cSrcweir         }
2515*cdf0e10cSrcweir         else if ( aScheme.equalsAsciiL(
2516*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
2517*cdf0e10cSrcweir         {
2518*cdf0e10cSrcweir             sourceURI.SetScheme(
2519*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2520*cdf0e10cSrcweir         }
2521*cdf0e10cSrcweir         else if ( aScheme.equalsAsciiL(
2522*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
2523*cdf0e10cSrcweir         {
2524*cdf0e10cSrcweir             sourceURI.SetScheme(
2525*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
2526*cdf0e10cSrcweir         }
2527*cdf0e10cSrcweir         else
2528*cdf0e10cSrcweir         {
2529*cdf0e10cSrcweir             if ( !aScheme.equalsAsciiL(
2530*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) &&
2531*cdf0e10cSrcweir                  !aScheme.equalsAsciiL(
2532*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) )
2533*cdf0e10cSrcweir             {
2534*cdf0e10cSrcweir                 ucbhelper::cancelCommandExecution(
2535*cdf0e10cSrcweir                     uno::makeAny(
2536*cdf0e10cSrcweir                         ucb::InteractiveBadTransferURLException(
2537*cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
2538*cdf0e10cSrcweir                                 "Unsupported URL scheme!" ),
2539*cdf0e10cSrcweir                             static_cast< cppu::OWeakObject * >( this ) ) ),
2540*cdf0e10cSrcweir                     Environment );
2541*cdf0e10cSrcweir                 // Unreachable
2542*cdf0e10cSrcweir             }
2543*cdf0e10cSrcweir         }
2544*cdf0e10cSrcweir 
2545*cdf0e10cSrcweir         if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
2546*cdf0e10cSrcweir                  RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
2547*cdf0e10cSrcweir             targetURI.SetScheme(
2548*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2549*cdf0e10cSrcweir         else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
2550*cdf0e10cSrcweir                  RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
2551*cdf0e10cSrcweir             targetURI.SetScheme(
2552*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2553*cdf0e10cSrcweir 
2554*cdf0e10cSrcweir         // @@@ This implementation of 'transfer' only works
2555*cdf0e10cSrcweir         //     if the source and target are located at same host.
2556*cdf0e10cSrcweir         //     (Neon does not support cross-server copy/move)
2557*cdf0e10cSrcweir 
2558*cdf0e10cSrcweir         // Check for same host
2559*cdf0e10cSrcweir         //
2560*cdf0e10cSrcweir         if ( sourceURI.GetHost().getLength() &&
2561*cdf0e10cSrcweir              ( sourceURI.GetHost() != targetURI.GetHost() ) )
2562*cdf0e10cSrcweir         {
2563*cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
2564*cdf0e10cSrcweir                 uno::makeAny( ucb::InteractiveBadTransferURLException(
2565*cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
2566*cdf0e10cSrcweir                                     "Different hosts!" ),
2567*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ) ) ),
2568*cdf0e10cSrcweir                 Environment );
2569*cdf0e10cSrcweir             // Unreachable
2570*cdf0e10cSrcweir         }
2571*cdf0e10cSrcweir 
2572*cdf0e10cSrcweir         rtl::OUString aTitle = rArgs.NewTitle;
2573*cdf0e10cSrcweir 
2574*cdf0e10cSrcweir         if ( !aTitle.getLength() )
2575*cdf0e10cSrcweir             aTitle = sourceURI.GetPathBaseNameUnescaped();
2576*cdf0e10cSrcweir 
2577*cdf0e10cSrcweir         if ( aTitle.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "/" ) ) )
2578*cdf0e10cSrcweir         {
2579*cdf0e10cSrcweir             // kso: ???
2580*cdf0e10cSrcweir             aTitle = rtl::OUString();
2581*cdf0e10cSrcweir         }
2582*cdf0e10cSrcweir 
2583*cdf0e10cSrcweir         targetURI.AppendPath( aTitle );
2584*cdf0e10cSrcweir 
2585*cdf0e10cSrcweir         rtl::OUString aTargetURL = xIdentifier->getContentIdentifier();
2586*cdf0e10cSrcweir         if ( ( aTargetURL.lastIndexOf( '/' ) + 1 )
2587*cdf0e10cSrcweir                 != aTargetURL.getLength() )
2588*cdf0e10cSrcweir             aTargetURL += rtl::OUString::createFromAscii( "/" );
2589*cdf0e10cSrcweir 
2590*cdf0e10cSrcweir         aTargetURL += aTitle;
2591*cdf0e10cSrcweir 
2592*cdf0e10cSrcweir         uno::Reference< ucb::XContentIdentifier > xTargetId
2593*cdf0e10cSrcweir             = new ::ucbhelper::ContentIdentifier( xSMgr, aTargetURL );
2594*cdf0e10cSrcweir 
2595*cdf0e10cSrcweir         DAVResourceAccess aSourceAccess( xSMgr,
2596*cdf0e10cSrcweir                                          xResAccess->getSessionFactory(),
2597*cdf0e10cSrcweir                                          sourceURI.GetURI() );
2598*cdf0e10cSrcweir 
2599*cdf0e10cSrcweir         if ( rArgs.MoveData == sal_True )
2600*cdf0e10cSrcweir         {
2601*cdf0e10cSrcweir             uno::Reference< ucb::XContentIdentifier > xId
2602*cdf0e10cSrcweir                 = new ::ucbhelper::ContentIdentifier( xSMgr, rArgs.SourceURL );
2603*cdf0e10cSrcweir 
2604*cdf0e10cSrcweir             // Note: The static cast is okay here, because its sure that
2605*cdf0e10cSrcweir             //       xProvider is always the WebDAVContentProvider.
2606*cdf0e10cSrcweir             rtl::Reference< Content > xSource
2607*cdf0e10cSrcweir                 = static_cast< Content * >(
2608*cdf0e10cSrcweir                     xProvider->queryContent( xId ).get() );
2609*cdf0e10cSrcweir 
2610*cdf0e10cSrcweir             // [RFC 2518] - WebDAV
2611*cdf0e10cSrcweir             // If a resource exists at the destination and the Overwrite
2612*cdf0e10cSrcweir             // header is "T" then prior to performing the move the server
2613*cdf0e10cSrcweir             // MUST perform a DELETE with "Depth: infinity" on the
2614*cdf0e10cSrcweir             // destination resource.  If the Overwrite header is set to
2615*cdf0e10cSrcweir             // "F" then the operation will fail.
2616*cdf0e10cSrcweir 
2617*cdf0e10cSrcweir             aSourceAccess.MOVE( sourceURI.GetPath(),
2618*cdf0e10cSrcweir                                 targetURI.GetURI(),
2619*cdf0e10cSrcweir                                 rArgs.NameClash
2620*cdf0e10cSrcweir                                     == ucb::NameClash::OVERWRITE,
2621*cdf0e10cSrcweir                                 Environment );
2622*cdf0e10cSrcweir 
2623*cdf0e10cSrcweir             if ( xSource.is() )
2624*cdf0e10cSrcweir             {
2625*cdf0e10cSrcweir                 // Propagate destruction to listeners.
2626*cdf0e10cSrcweir                 xSource->destroy( sal_True );
2627*cdf0e10cSrcweir             }
2628*cdf0e10cSrcweir 
2629*cdf0e10cSrcweir // DAV resources store all additional props on server!
2630*cdf0e10cSrcweir //              // Rename own and all children's Additional Core Properties.
2631*cdf0e10cSrcweir //              renameAdditionalPropertySet( xId->getContentIdentifier(),
2632*cdf0e10cSrcweir //                                           xTargetId->getContentIdentifier(),
2633*cdf0e10cSrcweir //                                           sal_True );
2634*cdf0e10cSrcweir         }
2635*cdf0e10cSrcweir         else
2636*cdf0e10cSrcweir         {
2637*cdf0e10cSrcweir             // [RFC 2518] - WebDAV
2638*cdf0e10cSrcweir             // If a resource exists at the destination and the Overwrite
2639*cdf0e10cSrcweir             // header is "T" then prior to performing the copy the server
2640*cdf0e10cSrcweir             // MUST perform a DELETE with "Depth: infinity" on the
2641*cdf0e10cSrcweir             // destination resource.  If the Overwrite header is set to
2642*cdf0e10cSrcweir             // "F" then the operation will fail.
2643*cdf0e10cSrcweir 
2644*cdf0e10cSrcweir             aSourceAccess.COPY( sourceURI.GetPath(),
2645*cdf0e10cSrcweir                                 targetURI.GetURI(),
2646*cdf0e10cSrcweir                                 rArgs.NameClash
2647*cdf0e10cSrcweir                                     == ucb::NameClash::OVERWRITE,
2648*cdf0e10cSrcweir                                 Environment );
2649*cdf0e10cSrcweir 
2650*cdf0e10cSrcweir // DAV resources store all additional props on server!
2651*cdf0e10cSrcweir //              // Copy own and all children's Additional Core Properties.
2652*cdf0e10cSrcweir //              copyAdditionalPropertySet( xId->getContentIdentifier(),
2653*cdf0e10cSrcweir //                                         xTargetId->getContentIdentifier(),
2654*cdf0e10cSrcweir //                                         sal_True );
2655*cdf0e10cSrcweir         }
2656*cdf0e10cSrcweir 
2657*cdf0e10cSrcweir         // Note: The static cast is okay here, because its sure that
2658*cdf0e10cSrcweir         //       xProvider is always the WebDAVContentProvider.
2659*cdf0e10cSrcweir         rtl::Reference< Content > xTarget
2660*cdf0e10cSrcweir             = static_cast< Content * >(
2661*cdf0e10cSrcweir                     xProvider->queryContent( xTargetId ).get() );
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir         // Announce transfered content in its new folder.
2664*cdf0e10cSrcweir         xTarget->inserted();
2665*cdf0e10cSrcweir     }
2666*cdf0e10cSrcweir     catch ( ucb::IllegalIdentifierException const & )
2667*cdf0e10cSrcweir     {
2668*cdf0e10cSrcweir         // queryContent
2669*cdf0e10cSrcweir     }
2670*cdf0e10cSrcweir     catch ( DAVException const & e )
2671*cdf0e10cSrcweir     {
2672*cdf0e10cSrcweir         // [RFC 2518] - WebDAV
2673*cdf0e10cSrcweir         // 412 (Precondition Failed) - The server was unable to maintain
2674*cdf0e10cSrcweir         // the liveness of the properties listed in the propertybehavior
2675*cdf0e10cSrcweir         // XML element or the Overwrite header is "F" and the state of
2676*cdf0e10cSrcweir         // the destination resource is non-null.
2677*cdf0e10cSrcweir 
2678*cdf0e10cSrcweir         if ( e.getStatus() == SC_PRECONDITION_FAILED )
2679*cdf0e10cSrcweir         {
2680*cdf0e10cSrcweir             switch ( rArgs.NameClash )
2681*cdf0e10cSrcweir             {
2682*cdf0e10cSrcweir                 case ucb::NameClash::ERROR:
2683*cdf0e10cSrcweir                 {
2684*cdf0e10cSrcweir                     ucbhelper::cancelCommandExecution(
2685*cdf0e10cSrcweir                         uno::makeAny(
2686*cdf0e10cSrcweir                             ucb::NameClashException(
2687*cdf0e10cSrcweir                                 rtl::OUString(),
2688*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ),
2689*cdf0e10cSrcweir                                 task::InteractionClassification_ERROR,
2690*cdf0e10cSrcweir                                 aTargetURI ) ),
2691*cdf0e10cSrcweir                         Environment );
2692*cdf0e10cSrcweir                     // Unreachable
2693*cdf0e10cSrcweir                 }
2694*cdf0e10cSrcweir 
2695*cdf0e10cSrcweir                 case ucb::NameClash::OVERWRITE:
2696*cdf0e10cSrcweir                     break;
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir                 case ucb::NameClash::KEEP: // deprecated
2699*cdf0e10cSrcweir                 case ucb::NameClash::RENAME:
2700*cdf0e10cSrcweir                 case ucb::NameClash::ASK:
2701*cdf0e10cSrcweir                 default:
2702*cdf0e10cSrcweir                 {
2703*cdf0e10cSrcweir                     ucbhelper::cancelCommandExecution(
2704*cdf0e10cSrcweir                         uno::makeAny(
2705*cdf0e10cSrcweir                             ucb::UnsupportedNameClashException(
2706*cdf0e10cSrcweir                                 rtl::OUString(),
2707*cdf0e10cSrcweir                                 static_cast< cppu::OWeakObject * >( this ),
2708*cdf0e10cSrcweir                                 rArgs.NameClash ) ),
2709*cdf0e10cSrcweir                         Environment );
2710*cdf0e10cSrcweir                     // Unreachable
2711*cdf0e10cSrcweir                 }
2712*cdf0e10cSrcweir             }
2713*cdf0e10cSrcweir         }
2714*cdf0e10cSrcweir 
2715*cdf0e10cSrcweir         cancelCommandExecution( e, Environment, sal_True );
2716*cdf0e10cSrcweir         // Unreachable
2717*cdf0e10cSrcweir     }
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir     {
2720*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
2721*cdf0e10cSrcweir         m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2722*cdf0e10cSrcweir     }
2723*cdf0e10cSrcweir }
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir //=========================================================================
2726*cdf0e10cSrcweir void Content::destroy( sal_Bool bDeletePhysical )
2727*cdf0e10cSrcweir     throw( uno::Exception )
2728*cdf0e10cSrcweir {
2729*cdf0e10cSrcweir     // @@@ take care about bDeletePhysical -> trashcan support
2730*cdf0e10cSrcweir     rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
2731*cdf0e10cSrcweir 
2732*cdf0e10cSrcweir     uno::Reference< ucb::XContent > xThis = this;
2733*cdf0e10cSrcweir 
2734*cdf0e10cSrcweir     deleted();
2735*cdf0e10cSrcweir 
2736*cdf0e10cSrcweir     osl::Guard< osl::Mutex > aGuard( m_aMutex );
2737*cdf0e10cSrcweir 
2738*cdf0e10cSrcweir     // Process instanciated children...
2739*cdf0e10cSrcweir 
2740*cdf0e10cSrcweir     ::webdav_ucp::Content::ContentRefList aChildren;
2741*cdf0e10cSrcweir     queryChildren( aChildren );
2742*cdf0e10cSrcweir 
2743*cdf0e10cSrcweir     ContentRefList::const_iterator it  = aChildren.begin();
2744*cdf0e10cSrcweir     ContentRefList::const_iterator end = aChildren.end();
2745*cdf0e10cSrcweir 
2746*cdf0e10cSrcweir     while ( it != end )
2747*cdf0e10cSrcweir     {
2748*cdf0e10cSrcweir         (*it)->destroy( bDeletePhysical );
2749*cdf0e10cSrcweir         ++it;
2750*cdf0e10cSrcweir     }
2751*cdf0e10cSrcweir }
2752*cdf0e10cSrcweir 
2753*cdf0e10cSrcweir //=========================================================================
2754*cdf0e10cSrcweir bool Content::supportsExclusiveWriteLock(
2755*cdf0e10cSrcweir   const uno::Reference< ucb::XCommandEnvironment >& Environment )
2756*cdf0e10cSrcweir {
2757*cdf0e10cSrcweir     if ( getResourceType( Environment ) == DAV )
2758*cdf0e10cSrcweir     {
2759*cdf0e10cSrcweir         if ( m_xCachedProps.get() )
2760*cdf0e10cSrcweir         {
2761*cdf0e10cSrcweir             uno::Sequence< ucb::LockEntry > aSupportedLocks;
2762*cdf0e10cSrcweir             if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK )
2763*cdf0e10cSrcweir                 >>= aSupportedLocks )
2764*cdf0e10cSrcweir             {
2765*cdf0e10cSrcweir                 for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
2766*cdf0e10cSrcweir                 {
2767*cdf0e10cSrcweir                     if ( aSupportedLocks[ n ].Scope
2768*cdf0e10cSrcweir                             == ucb::LockScope_EXCLUSIVE &&
2769*cdf0e10cSrcweir                          aSupportedLocks[ n ].Type
2770*cdf0e10cSrcweir                             == ucb::LockType_WRITE )
2771*cdf0e10cSrcweir                         return true;
2772*cdf0e10cSrcweir                 }
2773*cdf0e10cSrcweir             }
2774*cdf0e10cSrcweir         }
2775*cdf0e10cSrcweir     }
2776*cdf0e10cSrcweir     return false;
2777*cdf0e10cSrcweir }
2778*cdf0e10cSrcweir 
2779*cdf0e10cSrcweir //=========================================================================
2780*cdf0e10cSrcweir void Content::lock(
2781*cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment >& Environment )
2782*cdf0e10cSrcweir     throw( uno::Exception )
2783*cdf0e10cSrcweir {
2784*cdf0e10cSrcweir     try
2785*cdf0e10cSrcweir     {
2786*cdf0e10cSrcweir         std::auto_ptr< DAVResourceAccess > xResAccess;
2787*cdf0e10cSrcweir         {
2788*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2789*cdf0e10cSrcweir             xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2790*cdf0e10cSrcweir         }
2791*cdf0e10cSrcweir 
2792*cdf0e10cSrcweir         uno::Any aOwnerAny;
2793*cdf0e10cSrcweir         aOwnerAny
2794*cdf0e10cSrcweir             <<= rtl::OUString::createFromAscii( "http://ucb.openoffice.org" );
2795*cdf0e10cSrcweir 
2796*cdf0e10cSrcweir         ucb::Lock aLock(
2797*cdf0e10cSrcweir             ucb::LockScope_EXCLUSIVE,
2798*cdf0e10cSrcweir             ucb::LockType_WRITE,
2799*cdf0e10cSrcweir             ucb::LockDepth_ZERO,
2800*cdf0e10cSrcweir             aOwnerAny,
2801*cdf0e10cSrcweir             180, // lock timeout in secs
2802*cdf0e10cSrcweir             //-1, // infinite lock
2803*cdf0e10cSrcweir             uno::Sequence< ::rtl::OUString >() );
2804*cdf0e10cSrcweir 
2805*cdf0e10cSrcweir         xResAccess->LOCK( aLock, Environment );
2806*cdf0e10cSrcweir 
2807*cdf0e10cSrcweir         {
2808*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2809*cdf0e10cSrcweir             m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2810*cdf0e10cSrcweir         }
2811*cdf0e10cSrcweir     }
2812*cdf0e10cSrcweir     catch ( DAVException const & e )
2813*cdf0e10cSrcweir     {
2814*cdf0e10cSrcweir         cancelCommandExecution( e, Environment, sal_False );
2815*cdf0e10cSrcweir         // Unreachable
2816*cdf0e10cSrcweir     }
2817*cdf0e10cSrcweir }
2818*cdf0e10cSrcweir 
2819*cdf0e10cSrcweir //=========================================================================
2820*cdf0e10cSrcweir void Content::unlock(
2821*cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment >& Environment )
2822*cdf0e10cSrcweir     throw( uno::Exception )
2823*cdf0e10cSrcweir {
2824*cdf0e10cSrcweir     try
2825*cdf0e10cSrcweir     {
2826*cdf0e10cSrcweir         std::auto_ptr< DAVResourceAccess > xResAccess;
2827*cdf0e10cSrcweir         {
2828*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2829*cdf0e10cSrcweir             xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2830*cdf0e10cSrcweir         }
2831*cdf0e10cSrcweir 
2832*cdf0e10cSrcweir         xResAccess->UNLOCK( Environment );
2833*cdf0e10cSrcweir 
2834*cdf0e10cSrcweir         {
2835*cdf0e10cSrcweir             osl::Guard< osl::Mutex > aGuard( m_aMutex );
2836*cdf0e10cSrcweir             m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2837*cdf0e10cSrcweir         }
2838*cdf0e10cSrcweir     }
2839*cdf0e10cSrcweir     catch ( DAVException const & e )
2840*cdf0e10cSrcweir     {
2841*cdf0e10cSrcweir         cancelCommandExecution( e, Environment, sal_False );
2842*cdf0e10cSrcweir         // Unreachable
2843*cdf0e10cSrcweir     }
2844*cdf0e10cSrcweir }
2845*cdf0e10cSrcweir 
2846*cdf0e10cSrcweir //=========================================================================
2847*cdf0e10cSrcweir sal_Bool Content::exchangeIdentity(
2848*cdf0e10cSrcweir     const uno::Reference< ucb::XContentIdentifier >& xNewId )
2849*cdf0e10cSrcweir {
2850*cdf0e10cSrcweir     if ( !xNewId.is() )
2851*cdf0e10cSrcweir         return sal_False;
2852*cdf0e10cSrcweir 
2853*cdf0e10cSrcweir     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2854*cdf0e10cSrcweir 
2855*cdf0e10cSrcweir     uno::Reference< ucb::XContent > xThis = this;
2856*cdf0e10cSrcweir 
2857*cdf0e10cSrcweir     // Already persistent?
2858*cdf0e10cSrcweir     if ( m_bTransient )
2859*cdf0e10cSrcweir     {
2860*cdf0e10cSrcweir         OSL_ENSURE( sal_False, "Content::exchangeIdentity - Not persistent!" );
2861*cdf0e10cSrcweir         return sal_False;
2862*cdf0e10cSrcweir     }
2863*cdf0e10cSrcweir 
2864*cdf0e10cSrcweir     // Exchange own identitity.
2865*cdf0e10cSrcweir 
2866*cdf0e10cSrcweir     // Fail, if a content with given id already exists.
2867*cdf0e10cSrcweir //  if ( !hasData( xNewId ) )
2868*cdf0e10cSrcweir     {
2869*cdf0e10cSrcweir         rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
2870*cdf0e10cSrcweir 
2871*cdf0e10cSrcweir         aGuard.clear();
2872*cdf0e10cSrcweir         if ( exchange( xNewId ) )
2873*cdf0e10cSrcweir         {
2874*cdf0e10cSrcweir             // Process instanciated children...
2875*cdf0e10cSrcweir 
2876*cdf0e10cSrcweir             ContentRefList aChildren;
2877*cdf0e10cSrcweir             queryChildren( aChildren );
2878*cdf0e10cSrcweir 
2879*cdf0e10cSrcweir             ContentRefList::const_iterator it  = aChildren.begin();
2880*cdf0e10cSrcweir             ContentRefList::const_iterator end = aChildren.end();
2881*cdf0e10cSrcweir 
2882*cdf0e10cSrcweir             while ( it != end )
2883*cdf0e10cSrcweir             {
2884*cdf0e10cSrcweir                 ContentRef xChild = (*it);
2885*cdf0e10cSrcweir 
2886*cdf0e10cSrcweir                 // Create new content identifier for the child...
2887*cdf0e10cSrcweir                 uno::Reference< ucb::XContentIdentifier >
2888*cdf0e10cSrcweir                     xOldChildId = xChild->getIdentifier();
2889*cdf0e10cSrcweir                 rtl::OUString aOldChildURL
2890*cdf0e10cSrcweir                     = xOldChildId->getContentIdentifier();
2891*cdf0e10cSrcweir                 rtl::OUString aNewChildURL
2892*cdf0e10cSrcweir                     = aOldChildURL.replaceAt(
2893*cdf0e10cSrcweir                         0,
2894*cdf0e10cSrcweir                         aOldURL.getLength(),
2895*cdf0e10cSrcweir                         xNewId->getContentIdentifier() );
2896*cdf0e10cSrcweir                 uno::Reference< ucb::XContentIdentifier > xNewChildId
2897*cdf0e10cSrcweir                     = new ::ucbhelper::ContentIdentifier(
2898*cdf0e10cSrcweir                         m_xSMgr, aNewChildURL );
2899*cdf0e10cSrcweir 
2900*cdf0e10cSrcweir                 if ( !xChild->exchangeIdentity( xNewChildId ) )
2901*cdf0e10cSrcweir                     return sal_False;
2902*cdf0e10cSrcweir 
2903*cdf0e10cSrcweir                 ++it;
2904*cdf0e10cSrcweir             }
2905*cdf0e10cSrcweir             return sal_True;
2906*cdf0e10cSrcweir         }
2907*cdf0e10cSrcweir     }
2908*cdf0e10cSrcweir 
2909*cdf0e10cSrcweir     OSL_ENSURE( sal_False,
2910*cdf0e10cSrcweir                 "Content::exchangeIdentity - "
2911*cdf0e10cSrcweir                 "Panic! Cannot exchange identity!" );
2912*cdf0e10cSrcweir     return sal_False;
2913*cdf0e10cSrcweir }
2914*cdf0e10cSrcweir 
2915*cdf0e10cSrcweir //=========================================================================
2916*cdf0e10cSrcweir sal_Bool Content::isFolder(
2917*cdf0e10cSrcweir             const uno::Reference< ucb::XCommandEnvironment >& xEnv )
2918*cdf0e10cSrcweir     throw( uno::Exception )
2919*cdf0e10cSrcweir {
2920*cdf0e10cSrcweir     {
2921*cdf0e10cSrcweir         osl::MutexGuard aGuard( m_aMutex );
2922*cdf0e10cSrcweir 
2923*cdf0e10cSrcweir         if ( m_bTransient )
2924*cdf0e10cSrcweir             return m_bCollection;
2925*cdf0e10cSrcweir     }
2926*cdf0e10cSrcweir 
2927*cdf0e10cSrcweir     uno::Sequence< beans::Property > aProperties( 1 );
2928*cdf0e10cSrcweir     aProperties[ 0 ].Name   = rtl::OUString::createFromAscii( "IsFolder" );
2929*cdf0e10cSrcweir     aProperties[ 0 ].Handle = -1;
2930*cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) );
2931*cdf0e10cSrcweir     if ( xRow.is() )
2932*cdf0e10cSrcweir     {
2933*cdf0e10cSrcweir         try
2934*cdf0e10cSrcweir         {
2935*cdf0e10cSrcweir             return xRow->getBoolean( 1 );
2936*cdf0e10cSrcweir         }
2937*cdf0e10cSrcweir         catch ( sdbc::SQLException const & )
2938*cdf0e10cSrcweir         {
2939*cdf0e10cSrcweir         }
2940*cdf0e10cSrcweir     }
2941*cdf0e10cSrcweir 
2942*cdf0e10cSrcweir     return sal_False;
2943*cdf0e10cSrcweir }
2944*cdf0e10cSrcweir 
2945*cdf0e10cSrcweir //=========================================================================
2946*cdf0e10cSrcweir uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite )
2947*cdf0e10cSrcweir {
2948*cdf0e10cSrcweir     // Map DAVException...
2949*cdf0e10cSrcweir     uno::Any aException;
2950*cdf0e10cSrcweir 
2951*cdf0e10cSrcweir     rtl::OUString aURL;
2952*cdf0e10cSrcweir     if ( m_bTransient )
2953*cdf0e10cSrcweir     {
2954*cdf0e10cSrcweir         aURL = getParentURL();
2955*cdf0e10cSrcweir         if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) )
2956*cdf0e10cSrcweir             aURL += rtl::OUString::createFromAscii( "/" );
2957*cdf0e10cSrcweir 
2958*cdf0e10cSrcweir         aURL += m_aEscapedTitle;
2959*cdf0e10cSrcweir     }
2960*cdf0e10cSrcweir     else
2961*cdf0e10cSrcweir     {
2962*cdf0e10cSrcweir         aURL = m_xIdentifier->getContentIdentifier();
2963*cdf0e10cSrcweir     }
2964*cdf0e10cSrcweir 
2965*cdf0e10cSrcweir     switch ( e.getStatus() )
2966*cdf0e10cSrcweir     {
2967*cdf0e10cSrcweir         case SC_NOT_FOUND:
2968*cdf0e10cSrcweir         {
2969*cdf0e10cSrcweir             uno::Sequence< uno::Any > aArgs( 1 );
2970*cdf0e10cSrcweir             aArgs[ 0 ] <<= beans::PropertyValue(
2971*cdf0e10cSrcweir                 rtl::OUString::createFromAscii("Uri"), -1,
2972*cdf0e10cSrcweir                 uno::makeAny(aURL),
2973*cdf0e10cSrcweir                 beans::PropertyState_DIRECT_VALUE);
2974*cdf0e10cSrcweir 
2975*cdf0e10cSrcweir             aException <<=
2976*cdf0e10cSrcweir                 ucb::InteractiveAugmentedIOException(
2977*cdf0e10cSrcweir                     rtl::OUString::createFromAscii( "Not found!" ),
2978*cdf0e10cSrcweir                     static_cast< cppu::OWeakObject * >( this ),
2979*cdf0e10cSrcweir                     task::InteractionClassification_ERROR,
2980*cdf0e10cSrcweir                     ucb::IOErrorCode_NOT_EXISTING,
2981*cdf0e10cSrcweir                     aArgs );
2982*cdf0e10cSrcweir             return aException;
2983*cdf0e10cSrcweir         }
2984*cdf0e10cSrcweir         default:
2985*cdf0e10cSrcweir             break;
2986*cdf0e10cSrcweir     }
2987*cdf0e10cSrcweir 
2988*cdf0e10cSrcweir     switch ( e.getError() )
2989*cdf0e10cSrcweir     {
2990*cdf0e10cSrcweir     case DAVException::DAV_HTTP_ERROR:
2991*cdf0e10cSrcweir         {
2992*cdf0e10cSrcweir             if ( bWrite )
2993*cdf0e10cSrcweir                 aException <<=
2994*cdf0e10cSrcweir                     ucb::InteractiveNetworkWriteException(
2995*cdf0e10cSrcweir                         e.getData(),
2996*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ),
2997*cdf0e10cSrcweir                         task::InteractionClassification_ERROR,
2998*cdf0e10cSrcweir                         e.getData() );
2999*cdf0e10cSrcweir             else
3000*cdf0e10cSrcweir                 aException <<=
3001*cdf0e10cSrcweir                     ucb::InteractiveNetworkReadException(
3002*cdf0e10cSrcweir                         e.getData(),
3003*cdf0e10cSrcweir                         static_cast< cppu::OWeakObject * >( this ),
3004*cdf0e10cSrcweir                         task::InteractionClassification_ERROR,
3005*cdf0e10cSrcweir                         e.getData() );
3006*cdf0e10cSrcweir             break;
3007*cdf0e10cSrcweir         }
3008*cdf0e10cSrcweir 
3009*cdf0e10cSrcweir     case DAVException::DAV_HTTP_LOOKUP:
3010*cdf0e10cSrcweir         aException <<=
3011*cdf0e10cSrcweir             ucb::InteractiveNetworkResolveNameException(
3012*cdf0e10cSrcweir                 rtl::OUString(),
3013*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3014*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3015*cdf0e10cSrcweir                 e.getData() );
3016*cdf0e10cSrcweir         break;
3017*cdf0e10cSrcweir 
3018*cdf0e10cSrcweir // @@@ No matching InteractiveNetwork*Exception
3019*cdf0e10cSrcweir //    case DAVException::DAV_HTTP_AUTH:
3020*cdf0e10cSrcweir //        break;
3021*cdf0e10cSrcweir 
3022*cdf0e10cSrcweir // @@@ No matching InteractiveNetwork*Exception
3023*cdf0e10cSrcweir //    case DAVException::DAV_HTTP_AUTHPROXY:
3024*cdf0e10cSrcweir //        break;
3025*cdf0e10cSrcweir 
3026*cdf0e10cSrcweir     case DAVException::DAV_HTTP_CONNECT:
3027*cdf0e10cSrcweir         aException <<=
3028*cdf0e10cSrcweir             ucb::InteractiveNetworkConnectException(
3029*cdf0e10cSrcweir                 rtl::OUString(),
3030*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3031*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3032*cdf0e10cSrcweir                 e.getData() );
3033*cdf0e10cSrcweir         break;
3034*cdf0e10cSrcweir 
3035*cdf0e10cSrcweir // @@@ No matching InteractiveNetwork*Exception
3036*cdf0e10cSrcweir //    case DAVException::DAV_HTTP_TIMEOUT:
3037*cdf0e10cSrcweir //        break;
3038*cdf0e10cSrcweir 
3039*cdf0e10cSrcweir // @@@ No matching InteractiveNetwork*Exception
3040*cdf0e10cSrcweir //     case DAVException::DAV_HTTP_REDIRECT:
3041*cdf0e10cSrcweir //         break;
3042*cdf0e10cSrcweir 
3043*cdf0e10cSrcweir // @@@ No matching InteractiveNetwork*Exception
3044*cdf0e10cSrcweir //     case DAVException::DAV_SESSION_CREATE:
3045*cdf0e10cSrcweir //         break;
3046*cdf0e10cSrcweir 
3047*cdf0e10cSrcweir     case DAVException::DAV_INVALID_ARG:
3048*cdf0e10cSrcweir         aException <<=
3049*cdf0e10cSrcweir             lang::IllegalArgumentException(
3050*cdf0e10cSrcweir                 rtl::OUString(),
3051*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3052*cdf0e10cSrcweir                 -1 );
3053*cdf0e10cSrcweir         break;
3054*cdf0e10cSrcweir 
3055*cdf0e10cSrcweir     case DAVException::DAV_LOCKED:
3056*cdf0e10cSrcweir #if 1
3057*cdf0e10cSrcweir         aException <<=
3058*cdf0e10cSrcweir             ucb::InteractiveLockingLockedException(
3059*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "Locked!" ),
3060*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3061*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3062*cdf0e10cSrcweir                 aURL,
3063*cdf0e10cSrcweir                 sal_False ); // not SelfOwned
3064*cdf0e10cSrcweir #else
3065*cdf0e10cSrcweir         {
3066*cdf0e10cSrcweir             uno::Sequence< uno::Any > aArgs( 1 );
3067*cdf0e10cSrcweir             aArgs[ 0 ] <<= beans::PropertyValue(
3068*cdf0e10cSrcweir                 rtl::OUString::createFromAscii("Uri"), -1,
3069*cdf0e10cSrcweir                 uno::makeAny(aURL),
3070*cdf0e10cSrcweir                 beans::PropertyState_DIRECT_VALUE);
3071*cdf0e10cSrcweir 
3072*cdf0e10cSrcweir             aException <<=
3073*cdf0e10cSrcweir                 ucb::InteractiveAugmentedIOException(
3074*cdf0e10cSrcweir                     rtl::OUString::createFromAscii( "Locked!" ),
3075*cdf0e10cSrcweir                     static_cast< cppu::OWeakObject * >( this ),
3076*cdf0e10cSrcweir                     task::InteractionClassification_ERROR,
3077*cdf0e10cSrcweir                     ucb::IOErrorCode_LOCKING_VIOLATION,
3078*cdf0e10cSrcweir                     aArgs );
3079*cdf0e10cSrcweir         }
3080*cdf0e10cSrcweir #endif
3081*cdf0e10cSrcweir         break;
3082*cdf0e10cSrcweir 
3083*cdf0e10cSrcweir     case DAVException::DAV_LOCKED_SELF:
3084*cdf0e10cSrcweir         aException <<=
3085*cdf0e10cSrcweir             ucb::InteractiveLockingLockedException(
3086*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "Locked (self)!" ),
3087*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3088*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3089*cdf0e10cSrcweir                 aURL,
3090*cdf0e10cSrcweir                 sal_True ); // SelfOwned
3091*cdf0e10cSrcweir         break;
3092*cdf0e10cSrcweir 
3093*cdf0e10cSrcweir     case DAVException::DAV_NOT_LOCKED:
3094*cdf0e10cSrcweir         aException <<=
3095*cdf0e10cSrcweir             ucb::InteractiveLockingNotLockedException(
3096*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "Not locked!" ),
3097*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3098*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3099*cdf0e10cSrcweir                 aURL );
3100*cdf0e10cSrcweir         break;
3101*cdf0e10cSrcweir 
3102*cdf0e10cSrcweir     case DAVException::DAV_LOCK_EXPIRED:
3103*cdf0e10cSrcweir         aException <<=
3104*cdf0e10cSrcweir             ucb::InteractiveLockingLockExpiredException(
3105*cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "Lock expired!" ),
3106*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3107*cdf0e10cSrcweir                 task::InteractionClassification_ERROR,
3108*cdf0e10cSrcweir                 aURL );
3109*cdf0e10cSrcweir         break;
3110*cdf0e10cSrcweir 
3111*cdf0e10cSrcweir     default:
3112*cdf0e10cSrcweir         aException <<=
3113*cdf0e10cSrcweir             ucb::InteractiveNetworkGeneralException(
3114*cdf0e10cSrcweir                 rtl::OUString(),
3115*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >( this ),
3116*cdf0e10cSrcweir                 task::InteractionClassification_ERROR );
3117*cdf0e10cSrcweir         break;
3118*cdf0e10cSrcweir     }
3119*cdf0e10cSrcweir 
3120*cdf0e10cSrcweir     return aException;
3121*cdf0e10cSrcweir }
3122*cdf0e10cSrcweir 
3123*cdf0e10cSrcweir //=========================================================================
3124*cdf0e10cSrcweir // static
3125*cdf0e10cSrcweir bool Content::shouldAccessNetworkAfterException( const DAVException & e )
3126*cdf0e10cSrcweir {
3127*cdf0e10cSrcweir     if ( ( e.getStatus() == SC_NOT_FOUND ) ||
3128*cdf0e10cSrcweir          ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) ||
3129*cdf0e10cSrcweir          ( e.getError() == DAVException::DAV_HTTP_CONNECT ) ||
3130*cdf0e10cSrcweir          ( e.getError() == DAVException::DAV_HTTP_AUTH ) ||
3131*cdf0e10cSrcweir          ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY ) )
3132*cdf0e10cSrcweir         return false;
3133*cdf0e10cSrcweir 
3134*cdf0e10cSrcweir     return true;
3135*cdf0e10cSrcweir }
3136*cdf0e10cSrcweir 
3137*cdf0e10cSrcweir //=========================================================================
3138*cdf0e10cSrcweir void Content::cancelCommandExecution(
3139*cdf0e10cSrcweir                 const DAVException & e,
3140*cdf0e10cSrcweir                 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
3141*cdf0e10cSrcweir                 sal_Bool bWrite /* = sal_False */ )
3142*cdf0e10cSrcweir     throw ( uno::Exception )
3143*cdf0e10cSrcweir {
3144*cdf0e10cSrcweir     ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv );
3145*cdf0e10cSrcweir     // Unreachable
3146*cdf0e10cSrcweir }
3147*cdf0e10cSrcweir 
3148*cdf0e10cSrcweir //=========================================================================
3149*cdf0e10cSrcweir const rtl::OUString
3150*cdf0e10cSrcweir Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess )
3151*cdf0e10cSrcweir {
3152*cdf0e10cSrcweir     osl::Guard< osl::Mutex > aGuard( m_aMutex );
3153*cdf0e10cSrcweir 
3154*cdf0e10cSrcweir     // First, try to obtain value of response header "Content-Location".
3155*cdf0e10cSrcweir     if ( m_xCachedProps.get() )
3156*cdf0e10cSrcweir     {
3157*cdf0e10cSrcweir         rtl::OUString aLocation;
3158*cdf0e10cSrcweir         m_xCachedProps->getValue( rtl::OUString(
3159*cdf0e10cSrcweir                                     RTL_CONSTASCII_USTRINGPARAM(
3160*cdf0e10cSrcweir                                         "Content-Location" ) ) ) >>= aLocation;
3161*cdf0e10cSrcweir         if ( aLocation.getLength() )
3162*cdf0e10cSrcweir         {
3163*cdf0e10cSrcweir             try
3164*cdf0e10cSrcweir             {
3165*cdf0e10cSrcweir                 // Do not use m_xIdentifier->getContentIdentifier() because it
3166*cdf0e10cSrcweir                 // for example does not reflect redirects applied to requests
3167*cdf0e10cSrcweir                 // done using the original URI but m_xResAccess' URI does.
3168*cdf0e10cSrcweir                 return rtl::Uri::convertRelToAbs( rResAccess->getURL(),
3169*cdf0e10cSrcweir                                                   aLocation );
3170*cdf0e10cSrcweir             }
3171*cdf0e10cSrcweir             catch ( rtl::MalformedUriException const & )
3172*cdf0e10cSrcweir             {
3173*cdf0e10cSrcweir             }
3174*cdf0e10cSrcweir         }
3175*cdf0e10cSrcweir     }
3176*cdf0e10cSrcweir 
3177*cdf0e10cSrcweir     return rtl::OUString( rResAccess->getURL() );
3178*cdf0e10cSrcweir }
3179*cdf0e10cSrcweir 
3180*cdf0e10cSrcweir //=========================================================================
3181*cdf0e10cSrcweir const Content::ResourceType & Content::getResourceType(
3182*cdf0e10cSrcweir                     const uno::Reference< ucb::XCommandEnvironment >& xEnv,
3183*cdf0e10cSrcweir                     const std::auto_ptr< DAVResourceAccess > & rResAccess )
3184*cdf0e10cSrcweir     throw ( uno::Exception )
3185*cdf0e10cSrcweir {
3186*cdf0e10cSrcweir     if ( m_eResourceType == UNKNOWN )
3187*cdf0e10cSrcweir     {
3188*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( m_aMutex );
3189*cdf0e10cSrcweir 
3190*cdf0e10cSrcweir         ResourceType eResourceType;
3191*cdf0e10cSrcweir         eResourceType = m_eResourceType;
3192*cdf0e10cSrcweir 
3193*cdf0e10cSrcweir         const rtl::OUString & rURL = rResAccess->getURL();
3194*cdf0e10cSrcweir         const rtl::OUString aScheme(
3195*cdf0e10cSrcweir             rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() );
3196*cdf0e10cSrcweir 
3197*cdf0e10cSrcweir         if ( aScheme.equalsAsciiL(
3198*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) )
3199*cdf0e10cSrcweir         {
3200*cdf0e10cSrcweir             eResourceType = FTP;
3201*cdf0e10cSrcweir         }
3202*cdf0e10cSrcweir         else
3203*cdf0e10cSrcweir         {
3204*cdf0e10cSrcweir             try
3205*cdf0e10cSrcweir             {
3206*cdf0e10cSrcweir                 // Try to fetch some frequently used property value, e.g. those
3207*cdf0e10cSrcweir                 // used when loading documents... along with identifying whether
3208*cdf0e10cSrcweir                 // this is a DAV resource.
3209*cdf0e10cSrcweir                 std::vector< DAVResource > resources;
3210*cdf0e10cSrcweir                 std::vector< rtl::OUString > aPropNames;
3211*cdf0e10cSrcweir                 uno::Sequence< beans::Property > aProperties( 5 );
3212*cdf0e10cSrcweir                 aProperties[ 0 ].Name
3213*cdf0e10cSrcweir                     = rtl::OUString::createFromAscii( "IsFolder" );
3214*cdf0e10cSrcweir                 aProperties[ 1 ].Name
3215*cdf0e10cSrcweir                     = rtl::OUString::createFromAscii( "IsDocument" );
3216*cdf0e10cSrcweir                 aProperties[ 2 ].Name
3217*cdf0e10cSrcweir                     = rtl::OUString::createFromAscii( "IsReadOnly" );
3218*cdf0e10cSrcweir                 aProperties[ 3 ].Name
3219*cdf0e10cSrcweir                     = rtl::OUString::createFromAscii( "MediaType" );
3220*cdf0e10cSrcweir                 aProperties[ 4 ].Name
3221*cdf0e10cSrcweir                     = DAVProperties::SUPPORTEDLOCK;
3222*cdf0e10cSrcweir 
3223*cdf0e10cSrcweir                 ContentProperties::UCBNamesToDAVNames(
3224*cdf0e10cSrcweir                     aProperties, aPropNames );
3225*cdf0e10cSrcweir 
3226*cdf0e10cSrcweir                 rResAccess->PROPFIND(
3227*cdf0e10cSrcweir                     DAVZERO, aPropNames, resources, xEnv );
3228*cdf0e10cSrcweir 
3229*cdf0e10cSrcweir                 if ( resources.size() == 1 )
3230*cdf0e10cSrcweir                 {
3231*cdf0e10cSrcweir                     m_xCachedProps.reset(
3232*cdf0e10cSrcweir                         new CachableContentProperties( resources[ 0 ] ) );
3233*cdf0e10cSrcweir                     m_xCachedProps->containsAllNames(
3234*cdf0e10cSrcweir                         aProperties, m_aFailedPropNames );
3235*cdf0e10cSrcweir                 }
3236*cdf0e10cSrcweir 
3237*cdf0e10cSrcweir                 eResourceType = DAV;
3238*cdf0e10cSrcweir             }
3239*cdf0e10cSrcweir             catch ( DAVException const & e )
3240*cdf0e10cSrcweir             {
3241*cdf0e10cSrcweir                 rResAccess->resetUri();
3242*cdf0e10cSrcweir 
3243*cdf0e10cSrcweir                 if ( e.getStatus() == SC_METHOD_NOT_ALLOWED )
3244*cdf0e10cSrcweir                 {
3245*cdf0e10cSrcweir                     // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the
3246*cdf0e10cSrcweir                     // resource is NON_DAV
3247*cdf0e10cSrcweir                     eResourceType = NON_DAV;
3248*cdf0e10cSrcweir                 }
3249*cdf0e10cSrcweir             }
3250*cdf0e10cSrcweir         }
3251*cdf0e10cSrcweir         m_eResourceType = eResourceType;
3252*cdf0e10cSrcweir     }
3253*cdf0e10cSrcweir     return m_eResourceType;
3254*cdf0e10cSrcweir }
3255*cdf0e10cSrcweir 
3256*cdf0e10cSrcweir //=========================================================================
3257*cdf0e10cSrcweir const Content::ResourceType & Content::getResourceType(
3258*cdf0e10cSrcweir                     const uno::Reference< ucb::XCommandEnvironment >& xEnv )
3259*cdf0e10cSrcweir     throw ( uno::Exception )
3260*cdf0e10cSrcweir {
3261*cdf0e10cSrcweir     return getResourceType( xEnv, m_xResAccess );
3262*cdf0e10cSrcweir }
3263