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