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