bump product version to 4.1.6.2
[LibreOffice.git] / ucbhelper / source / client / content.cxx
blobb5f710e0cc1456d11a515f2cc3fbd750d6b7326c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <cassert>
24 #include <osl/diagnose.h>
25 #include <osl/mutex.hxx>
26 #include <salhelper/simplereferenceobject.hxx>
27 #include <cppuhelper/weak.hxx>
29 #include <cppuhelper/implbase1.hxx>
30 #include <com/sun/star/ucb/CheckinArgument.hpp>
31 #include <com/sun/star/ucb/ContentCreationError.hpp>
32 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
33 #include <com/sun/star/ucb/XCommandInfo.hpp>
34 #include <com/sun/star/ucb/XCommandProcessor.hpp>
35 #include <com/sun/star/ucb/Command.hpp>
36 #include <com/sun/star/ucb/CommandInfo.hpp>
37 #include <com/sun/star/ucb/ContentAction.hpp>
38 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
39 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
40 #include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
41 #include <com/sun/star/ucb/NameClash.hpp>
42 #include <com/sun/star/ucb/OpenMode.hpp>
43 #include <com/sun/star/ucb/XContentCreator.hpp>
44 #include <com/sun/star/ucb/XContentEventListener.hpp>
45 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
46 #include <com/sun/star/ucb/XContentProvider.hpp>
47 #include <com/sun/star/ucb/XContentProviderManager.hpp>
48 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
49 #include <com/sun/star/ucb/SortedDynamicResultSetFactory.hpp>
50 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
51 #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
52 #include <com/sun/star/beans/XPropertySetInfo.hpp>
53 #include <com/sun/star/beans/Property.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/sdbc/XResultSet.hpp>
56 #include <com/sun/star/sdbc/XRow.hpp>
57 #include <com/sun/star/lang/IllegalArgumentException.hpp>
58 #include <com/sun/star/beans/UnknownPropertyException.hpp>
59 #include <ucbhelper/macros.hxx>
60 #include <ucbhelper/content.hxx>
61 #include <ucbhelper/activedatasink.hxx>
62 #include <ucbhelper/activedatastreamer.hxx>
63 #include <ucbhelper/interactionrequest.hxx>
64 #include <ucbhelper/cancelcommandexecution.hxx>
66 using namespace com::sun::star::container;
67 using namespace com::sun::star::beans;
68 using namespace com::sun::star::io;
69 using namespace com::sun::star::lang;
70 using namespace com::sun::star::sdbc;
71 using namespace com::sun::star::task;
72 using namespace com::sun::star::ucb;
73 using namespace com::sun::star::uno;
75 namespace ucbhelper
78 class EmptyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
80 public:
81 virtual sal_Int32 SAL_CALL readBytes(
82 Sequence< sal_Int8 > & data, sal_Int32 nBytesToRead )
83 throw (IOException, RuntimeException);
84 virtual sal_Int32 SAL_CALL readSomeBytes(
85 Sequence< sal_Int8 > & data, sal_Int32 nMaxBytesToRead )
86 throw (IOException, RuntimeException);
87 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
88 throw (IOException, RuntimeException);
89 virtual sal_Int32 SAL_CALL available()
90 throw (IOException, RuntimeException);
91 virtual void SAL_CALL closeInput()
92 throw (IOException, RuntimeException);
95 sal_Int32 EmptyInputStream::readBytes(
96 Sequence< sal_Int8 > & data, sal_Int32 )
97 throw (IOException, RuntimeException)
99 data.realloc( 0 );
100 return 0;
103 sal_Int32 EmptyInputStream::readSomeBytes(
104 Sequence< sal_Int8 > & data, sal_Int32 )
105 throw (IOException, RuntimeException)
107 data.realloc( 0 );
108 return 0;
111 void EmptyInputStream::skipBytes( sal_Int32 )
112 throw (IOException, RuntimeException)
116 sal_Int32 EmptyInputStream::available()
117 throw (IOException, RuntimeException)
119 return 0;
122 void EmptyInputStream::closeInput()
123 throw (IOException, RuntimeException)
128 //=========================================================================
129 //=========================================================================
131 // class ContentEventListener_Impl.
133 //=========================================================================
134 //=========================================================================
136 class ContentEventListener_Impl : public cppu::OWeakObject,
137 public XContentEventListener
139 Content_Impl& m_rContent;
141 public:
142 ContentEventListener_Impl( Content_Impl& rContent )
143 : m_rContent( rContent ) {}
145 // XInterface
146 XINTERFACE_DECL()
148 // XContentEventListener
149 virtual void SAL_CALL contentEvent( const ContentEvent& evt )
150 throw( RuntimeException );
152 // XEventListener ( base of XContentEventListener )
153 virtual void SAL_CALL disposing( const EventObject& Source )
154 throw( RuntimeException );
157 //=========================================================================
158 //=========================================================================
160 // class Content_Impl.
162 //=========================================================================
163 //=========================================================================
165 class Content_Impl : public salhelper::SimpleReferenceObject
167 friend class ContentEventListener_Impl;
169 mutable OUString m_aURL;
170 Reference< XComponentContext > m_xCtx;
171 Reference< XContent > m_xContent;
172 Reference< XCommandProcessor > m_xCommandProcessor;
173 Reference< XCommandEnvironment > m_xEnv;
174 Reference< XContentEventListener > m_xContentEventListener;
175 mutable osl::Mutex m_aMutex;
177 private:
178 void reinit( const Reference< XContent >& xContent );
179 void disposing(const EventObject& Source);
181 public:
182 Content_Impl() {};
183 Content_Impl( const Reference< XComponentContext >& rCtx,
184 const Reference< XContent >& rContent,
185 const Reference< XCommandEnvironment >& rEnv );
187 virtual ~Content_Impl();
189 const OUString& getURL() const;
190 Reference< XContent > getContent();
191 Reference< XCommandProcessor > getCommandProcessor();
192 Reference< XComponentContext > getComponentContext()
193 { assert(m_xCtx.is()); return m_xCtx; }
195 Any executeCommand( const Command& rCommand );
197 inline const Reference< XCommandEnvironment >& getEnvironment() const;
198 inline void setEnvironment(
199 const Reference< XCommandEnvironment >& xNewEnv );
201 void inserted();
204 //=========================================================================
205 // Helpers.
206 //=========================================================================
208 static void ensureContentProviderForURL( const Reference< XUniversalContentBroker >& rBroker,
209 const OUString & rURL )
210 throw ( ContentCreationException, RuntimeException )
212 Reference< XContentProvider > xProv
213 = rBroker->queryContentProvider( rURL );
214 if ( !xProv.is() )
216 throw ContentCreationException(
217 "No Content Provider available for URL: " + rURL,
218 Reference< XInterface >(),
219 ContentCreationError_NO_CONTENT_PROVIDER );
223 //=========================================================================
224 static Reference< XContentIdentifier > getContentIdentifier(
225 const Reference< XUniversalContentBroker > & rBroker,
226 const OUString & rURL,
227 bool bThrow )
228 throw ( ContentCreationException, RuntimeException )
230 Reference< XContentIdentifier > xId
231 = rBroker->createContentIdentifier( rURL );
233 if ( xId.is() )
234 return xId;
236 if ( bThrow )
238 ensureContentProviderForURL( rBroker, rURL );
240 throw ContentCreationException(
241 "Unable to create Content Identifier!",
242 Reference< XInterface >(),
243 ContentCreationError_IDENTIFIER_CREATION_FAILED );
246 return Reference< XContentIdentifier >();
249 //=========================================================================
250 static Reference< XContent > getContent(
251 const Reference< XUniversalContentBroker > & rBroker,
252 const Reference< XContentIdentifier > & xId,
253 bool bThrow )
254 throw ( ContentCreationException, RuntimeException )
256 Reference< XContent > xContent;
257 OUString msg;
260 xContent = rBroker->queryContent( xId );
262 catch ( IllegalIdentifierException const & e )
264 msg = e.Message;
265 // handled below.
268 if ( xContent.is() )
269 return xContent;
271 if ( bThrow )
273 ensureContentProviderForURL( rBroker, xId->getContentIdentifier() );
275 throw ContentCreationException(
276 "Unable to create Content! " + msg,
277 Reference< XInterface >(),
278 ContentCreationError_CONTENT_CREATION_FAILED );
281 return Reference< XContent >();
284 //=========================================================================
285 //=========================================================================
287 // Content Implementation.
289 //=========================================================================
290 //=========================================================================
292 Content::Content()
293 : m_xImpl( new Content_Impl )
297 //=========================================================================
298 Content::Content( const OUString& rURL,
299 const Reference< XCommandEnvironment >& rEnv,
300 const Reference< XComponentContext >& rCtx )
301 throw ( ContentCreationException, RuntimeException )
303 Reference< XUniversalContentBroker > pBroker(
304 UniversalContentBroker::create( rCtx ) );
306 Reference< XContentIdentifier > xId
307 = getContentIdentifier( pBroker, rURL, true );
309 Reference< XContent > xContent = getContent( pBroker, xId, true );
311 m_xImpl = new Content_Impl( rCtx, xContent, rEnv );
314 //=========================================================================
315 Content::Content( const Reference< XContent >& rContent,
316 const Reference< XCommandEnvironment >& rEnv,
317 const Reference< XComponentContext >& rCtx )
318 throw ( ContentCreationException, RuntimeException )
320 m_xImpl = new Content_Impl( rCtx, rContent, rEnv );
323 //=========================================================================
324 Content::Content( const Content& rOther )
326 m_xImpl = rOther.m_xImpl;
329 //=========================================================================
330 // static
331 sal_Bool Content::create( const OUString& rURL,
332 const Reference< XCommandEnvironment >& rEnv,
333 const Reference< XComponentContext >& rCtx,
334 Content& rContent )
336 Reference< XUniversalContentBroker > pBroker(
337 UniversalContentBroker::create( rCtx ) );
339 Reference< XContentIdentifier > xId
340 = getContentIdentifier( pBroker, rURL, false );
341 if ( !xId.is() )
342 return sal_False;
344 Reference< XContent > xContent = getContent( pBroker, xId, false );
345 if ( !xContent.is() )
346 return sal_False;
348 rContent.m_xImpl
349 = new Content_Impl( rCtx, xContent, rEnv );
351 return sal_True;
354 //=========================================================================
355 Content::~Content()
359 //=========================================================================
360 Content& Content::operator=( const Content& rOther )
362 m_xImpl = rOther.m_xImpl;
363 return *this;
366 //=========================================================================
367 Reference< XContent > Content::get() const
369 return m_xImpl->getContent();
372 //=========================================================================
373 const OUString& Content::getURL() const
375 return m_xImpl->getURL();
378 //=========================================================================
379 const Reference< XCommandEnvironment >& Content::getCommandEnvironment() const
381 return m_xImpl->getEnvironment();
384 //=========================================================================
385 void Content::setCommandEnvironment(
386 const Reference< XCommandEnvironment >& xNewEnv )
388 m_xImpl->setEnvironment( xNewEnv );
391 //=========================================================================
392 Reference< XCommandInfo > Content::getCommands()
393 throw( CommandAbortedException, RuntimeException, Exception )
395 Command aCommand;
396 aCommand.Name = OUString("getCommandInfo");
397 aCommand.Handle = -1; // n/a
398 aCommand.Argument = Any();
400 Any aResult = m_xImpl->executeCommand( aCommand );
402 Reference< XCommandInfo > xInfo;
403 aResult >>= xInfo;
404 return xInfo;
407 //=========================================================================
408 Reference< XPropertySetInfo > Content::getProperties()
409 throw( CommandAbortedException, RuntimeException, Exception )
411 Command aCommand;
412 aCommand.Name = OUString("getPropertySetInfo");
413 aCommand.Handle = -1; // n/a
414 aCommand.Argument = Any();
416 Any aResult = m_xImpl->executeCommand( aCommand );
418 Reference< XPropertySetInfo > xInfo;
419 aResult >>= xInfo;
420 return xInfo;
423 //=========================================================================
424 Any Content::getPropertyValue( const OUString& rPropertyName )
425 throw( CommandAbortedException, RuntimeException, Exception )
427 Sequence< OUString > aNames( 1 );
428 aNames.getArray()[ 0 ] = rPropertyName;
430 Sequence< Any > aRet = getPropertyValues( aNames );
431 return aRet.getConstArray()[ 0 ];
434 //=========================================================================
435 Any Content::setPropertyValue( const OUString& rName,
436 const Any& rValue )
437 throw( CommandAbortedException, RuntimeException, Exception )
439 Sequence< OUString > aNames( 1 );
440 aNames.getArray()[ 0 ] = rName;
442 Sequence< Any > aValues( 1 );
443 aValues.getArray()[ 0 ] = rValue;
445 Sequence< Any > aErrors = setPropertyValues( aNames, aValues );
446 return aErrors.getConstArray()[ 0 ];
449 //=========================================================================
450 Sequence< Any > Content::getPropertyValues(
451 const Sequence< OUString >& rPropertyNames )
452 throw( CommandAbortedException, RuntimeException, Exception )
454 Reference< XRow > xRow = getPropertyValuesInterface( rPropertyNames );
456 sal_Int32 nCount = rPropertyNames.getLength();
457 Sequence< Any > aValues( nCount );
459 if ( xRow.is() )
461 Any* pValues = aValues.getArray();
463 for ( sal_Int32 n = 0; n < nCount; ++n )
464 pValues[ n ] = xRow->getObject( n + 1, Reference< XNameAccess >() );
467 return aValues;
470 //=========================================================================
471 Reference< XRow > Content::getPropertyValuesInterface(
472 const Sequence< OUString >& rPropertyNames )
473 throw( CommandAbortedException, RuntimeException, Exception )
475 sal_Int32 nCount = rPropertyNames.getLength();
476 Sequence< Property > aProps( nCount );
477 Property* pProps = aProps.getArray();
479 const OUString* pNames = rPropertyNames.getConstArray();
481 for ( sal_Int32 n = 0; n< nCount; ++n )
483 Property& rProp = pProps[ n ];
485 rProp.Name = pNames[ n ];
486 rProp.Handle = -1; // n/a
487 // rProp.Type =
488 // rProp.Attributes = ;
491 Command aCommand;
492 aCommand.Name = OUString("getPropertyValues");
493 aCommand.Handle = -1; // n/a
494 aCommand.Argument <<= aProps;
496 Any aResult = m_xImpl->executeCommand( aCommand );
498 Reference< XRow > xRow;
499 aResult >>= xRow;
500 return xRow;
503 //=========================================================================
504 Sequence< Any > Content::setPropertyValues(
505 const Sequence< OUString >& rPropertyNames,
506 const Sequence< Any >& rValues )
507 throw( CommandAbortedException, RuntimeException, Exception )
509 if ( rPropertyNames.getLength() != rValues.getLength() )
511 ucbhelper::cancelCommandExecution(
512 makeAny( IllegalArgumentException(
513 OUString(
514 "Length of property names sequence and value "
515 "sequence are unequal!" ),
516 get(),
517 -1 ) ),
518 m_xImpl->getEnvironment() );
519 // Unreachable
522 sal_Int32 nCount = rValues.getLength();
523 Sequence< PropertyValue > aProps( nCount );
524 PropertyValue* pProps = aProps.getArray();
526 const OUString* pNames = rPropertyNames.getConstArray();
527 const Any* pValues = rValues.getConstArray();
529 for ( sal_Int32 n = 0; n< nCount; ++n )
531 PropertyValue& rProp = pProps[ n ];
533 rProp.Name = pNames[ n ];
534 rProp.Handle = -1; // n/a
535 rProp.Value = pValues[ n ];
536 // rProp.State = ;
539 Command aCommand;
540 aCommand.Name = OUString("setPropertyValues");
541 aCommand.Handle = -1; // n/a
542 aCommand.Argument <<= aProps;
544 Any aResult = m_xImpl->executeCommand( aCommand );
546 Sequence< Any > aErrors;
547 aResult >>= aErrors;
548 return aErrors;
551 //=========================================================================
552 Any Content::executeCommand( const OUString& rCommandName,
553 const Any& rCommandArgument )
554 throw( CommandAbortedException, RuntimeException, Exception )
556 Command aCommand;
557 aCommand.Name = rCommandName;
558 aCommand.Handle = -1; // n/a
559 aCommand.Argument = rCommandArgument;
561 return m_xImpl->executeCommand( aCommand );
564 //=========================================================================
565 Any Content::createCursorAny( const Sequence< OUString >& rPropertyNames,
566 ResultSetInclude eMode )
567 throw( CommandAbortedException, RuntimeException, Exception )
569 sal_Int32 nCount = rPropertyNames.getLength();
570 Sequence< Property > aProps( nCount );
571 Property* pProps = aProps.getArray();
572 const OUString* pNames = rPropertyNames.getConstArray();
573 for ( sal_Int32 n = 0; n < nCount; ++n )
575 Property& rProp = pProps[ n ];
576 rProp.Name = pNames[ n ];
577 rProp.Handle = -1; // n/a
580 OpenCommandArgument2 aArg;
581 aArg.Mode = ( eMode == INCLUDE_FOLDERS_ONLY )
582 ? OpenMode::FOLDERS
583 : ( eMode == INCLUDE_DOCUMENTS_ONLY )
584 ? OpenMode::DOCUMENTS : OpenMode::ALL;
585 aArg.Priority = 0; // unused
586 aArg.Sink = Reference< XInterface >(); // unused
587 aArg.Properties = aProps;
589 Command aCommand;
590 aCommand.Name = OUString("open");
591 aCommand.Handle = -1; // n/a
592 aCommand.Argument <<= aArg;
594 return m_xImpl->executeCommand( aCommand );
597 //=========================================================================
598 Reference< XResultSet > Content::createCursor(
599 const Sequence< OUString >& rPropertyNames,
600 ResultSetInclude eMode )
601 throw( CommandAbortedException, RuntimeException, Exception )
603 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
605 Reference< XDynamicResultSet > xDynSet;
606 Reference< XResultSet > aResult;
608 aCursorAny >>= xDynSet;
609 if ( xDynSet.is() )
610 aResult = xDynSet->getStaticResultSet();
612 OSL_ENSURE( aResult.is(), "Content::createCursor - no cursor!" );
614 if ( !aResult.is() )
616 // Former, the open command directly returned a XResultSet.
617 aCursorAny >>= aResult;
619 OSL_ENSURE( !aResult.is(),
620 "Content::createCursor - open-Command must "
621 "return a Reference< XDynnamicResultSet >!" );
624 return aResult;
627 //=========================================================================
628 Reference< XDynamicResultSet > Content::createDynamicCursor(
629 const Sequence< OUString >& rPropertyNames,
630 ResultSetInclude eMode )
631 throw( CommandAbortedException, RuntimeException, Exception )
633 Reference< XDynamicResultSet > aResult;
634 createCursorAny( rPropertyNames, eMode ) >>= aResult;
636 OSL_ENSURE( aResult.is(), "Content::createDynamicCursor - no cursor!" );
638 return aResult;
641 //=========================================================================
642 Reference< XResultSet > Content::createSortedCursor(
643 const Sequence< OUString >& rPropertyNames,
644 const Sequence< NumberedSortingInfo >& rSortInfo,
645 Reference< XAnyCompareFactory > rAnyCompareFactory,
646 ResultSetInclude eMode )
647 throw( CommandAbortedException, RuntimeException, Exception )
649 Reference< XResultSet > aResult;
650 Reference< XDynamicResultSet > aDynSet;
652 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
654 aCursorAny >>= aDynSet;
656 if( aDynSet.is() )
658 Reference< XDynamicResultSet > aDynResult;
660 if( m_xImpl->getComponentContext().is() )
662 Reference< XSortedDynamicResultSetFactory > aSortFactory =
663 SortedDynamicResultSetFactory::create( m_xImpl->getComponentContext());
665 aDynResult = aSortFactory->createSortedDynamicResultSet( aDynSet,
666 rSortInfo,
667 rAnyCompareFactory );
670 OSL_ENSURE( aDynResult.is(), "Content::createSortedCursor - no sorted cursor!\n" );
672 if( aDynResult.is() )
673 aResult = aDynResult->getStaticResultSet();
674 else
675 aResult = aDynSet->getStaticResultSet();
678 OSL_ENSURE( aResult.is(), "Content::createSortedCursor - no cursor!" );
680 if ( !aResult.is() )
682 // Former, the open command directly returned a XResultSet.
683 aCursorAny >>= aResult;
685 OSL_ENSURE( !aResult.is(),
686 "Content::createCursor - open-Command must "
687 "return a Reference< XDynnamicResultSet >!" );
690 return aResult;
693 //=========================================================================
694 Reference< XInputStream > Content::openStream()
695 throw( CommandAbortedException, RuntimeException, Exception )
697 if ( !isDocument() )
698 return Reference< XInputStream >();
700 Reference< XActiveDataSink > xSink = new ActiveDataSink;
702 OpenCommandArgument2 aArg;
703 aArg.Mode = OpenMode::DOCUMENT;
704 aArg.Priority = 0; // unused
705 aArg.Sink = xSink;
706 aArg.Properties = Sequence< Property >( 0 ); // unused
708 Command aCommand;
709 aCommand.Name = OUString("open");
710 aCommand.Handle = -1; // n/a
711 aCommand.Argument <<= aArg;
713 m_xImpl->executeCommand( aCommand );
715 return xSink->getInputStream();
718 //=========================================================================
719 Reference< XInputStream > Content::openStreamNoLock()
720 throw( CommandAbortedException, RuntimeException, Exception )
722 if ( !isDocument() )
723 return Reference< XInputStream >();
725 Reference< XActiveDataSink > xSink = new ActiveDataSink;
727 OpenCommandArgument2 aArg;
728 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
729 aArg.Priority = 0; // unused
730 aArg.Sink = xSink;
731 aArg.Properties = Sequence< Property >( 0 ); // unused
733 Command aCommand;
734 aCommand.Name = OUString("open");
735 aCommand.Handle = -1; // n/a
736 aCommand.Argument <<= aArg;
738 m_xImpl->executeCommand( aCommand );
740 return xSink->getInputStream();
743 //=========================================================================
744 Reference< XStream > Content::openWriteableStream()
745 throw( CommandAbortedException, RuntimeException, Exception )
747 if ( !isDocument() )
748 return Reference< XStream >();
750 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
752 OpenCommandArgument2 aArg;
753 aArg.Mode = OpenMode::DOCUMENT;
754 aArg.Priority = 0; // unused
755 aArg.Sink = xStreamer;
756 aArg.Properties = Sequence< Property >( 0 ); // unused
758 Command aCommand;
759 aCommand.Name = OUString("open");
760 aCommand.Handle = -1; // n/a
761 aCommand.Argument <<= aArg;
763 m_xImpl->executeCommand( aCommand );
765 return xStreamer->getStream();
768 //=========================================================================
769 Reference< XStream > Content::openWriteableStreamNoLock()
770 throw( CommandAbortedException, RuntimeException, Exception )
772 if ( !isDocument() )
773 return Reference< XStream >();
775 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
777 OpenCommandArgument2 aArg;
778 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
779 aArg.Priority = 0; // unused
780 aArg.Sink = xStreamer;
781 aArg.Properties = Sequence< Property >( 0 ); // unused
783 Command aCommand;
784 aCommand.Name = OUString("open");
785 aCommand.Handle = -1; // n/a
786 aCommand.Argument <<= aArg;
788 m_xImpl->executeCommand( aCommand );
790 return xStreamer->getStream();
793 //=========================================================================
794 sal_Bool Content::openStream( const Reference< XActiveDataSink >& rSink )
795 throw( CommandAbortedException, RuntimeException, Exception )
797 if ( !isDocument() )
798 return sal_False;
800 OpenCommandArgument2 aArg;
801 aArg.Mode = OpenMode::DOCUMENT;
802 aArg.Priority = 0; // unused
803 aArg.Sink = rSink;
804 aArg.Properties = Sequence< Property >( 0 ); // unused
806 Command aCommand;
807 aCommand.Name = OUString("open");
808 aCommand.Handle = -1; // n/a
809 aCommand.Argument <<= aArg;
811 m_xImpl->executeCommand( aCommand );
813 return sal_True;
816 //=========================================================================
817 sal_Bool Content::openStream( const Reference< XOutputStream >& rStream )
818 throw( CommandAbortedException, RuntimeException, Exception )
820 if ( !isDocument() )
821 return sal_False;
823 OpenCommandArgument2 aArg;
824 aArg.Mode = OpenMode::DOCUMENT;
825 aArg.Priority = 0; // unused
826 aArg.Sink = rStream;
827 aArg.Properties = Sequence< Property >( 0 ); // unused
829 Command aCommand;
830 aCommand.Name = OUString("open");
831 aCommand.Handle = -1; // n/a
832 aCommand.Argument <<= aArg;
834 m_xImpl->executeCommand( aCommand );
836 return sal_True;
839 //=========================================================================
840 void Content::writeStream( const Reference< XInputStream >& rStream,
841 sal_Bool bReplaceExisting )
842 throw( CommandAbortedException, RuntimeException, Exception )
844 InsertCommandArgument aArg;
845 aArg.Data = rStream.is() ? rStream : new EmptyInputStream;
846 aArg.ReplaceExisting = bReplaceExisting;
848 Command aCommand;
849 aCommand.Name = OUString("insert");
850 aCommand.Handle = -1; // n/a
851 aCommand.Argument <<= aArg;
853 m_xImpl->executeCommand( aCommand );
855 m_xImpl->inserted();
858 //=========================================================================
859 Sequence< ContentInfo > Content::queryCreatableContentsInfo()
860 throw( CommandAbortedException, RuntimeException, Exception )
862 // First, try it using "CreatableContentsInfo" property -> the "new" way.
863 Sequence< ContentInfo > aInfo;
864 if ( getPropertyValue(
865 OUString("CreatableContentsInfo") )
866 >>= aInfo )
867 return aInfo;
869 // Second, try it using XContentCreator interface -> the "old" way (not
870 // providing the chance to supply an XCommandEnvironment.
871 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
872 if ( xCreator.is() )
873 aInfo = xCreator->queryCreatableContentsInfo();
875 return aInfo;
878 //=========================================================================
879 sal_Bool Content::insertNewContent( const OUString& rContentType,
880 const Sequence< OUString >&
881 rPropertyNames,
882 const Sequence< Any >& rPropertyValues,
883 Content& rNewContent )
884 throw( CommandAbortedException, RuntimeException, Exception )
886 return insertNewContent( rContentType,
887 rPropertyNames,
888 rPropertyValues,
889 new EmptyInputStream,
890 rNewContent );
893 //=========================================================================
894 sal_Bool Content::insertNewContent( const OUString& rContentType,
895 const Sequence< OUString >&
896 rPropertyNames,
897 const Sequence< Any >& rPropertyValues,
898 const Reference< XInputStream >& rData,
899 Content& rNewContent )
900 throw( CommandAbortedException, RuntimeException, Exception )
902 if ( rContentType.isEmpty() )
903 return sal_False;
905 // First, try it using "createNewContent" command -> the "new" way.
906 ContentInfo aInfo;
907 aInfo.Type = rContentType;
908 aInfo.Attributes = 0;
910 Command aCommand;
911 aCommand.Name = OUString("createNewContent");
912 aCommand.Handle = -1; // n/a
913 aCommand.Argument <<= aInfo;
915 Reference< XContent > xNew;
918 m_xImpl->executeCommand( aCommand ) >>= xNew;
920 catch ( RuntimeException const & )
922 throw;
924 catch ( Exception const & )
928 if ( !xNew.is() )
930 // Second, try it using XContentCreator interface -> the "old"
931 // way (not providing the chance to supply an XCommandEnvironment.
932 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
934 if ( !xCreator.is() )
935 return sal_False;
937 xNew = xCreator->createNewContent( aInfo );
939 if ( !xNew.is() )
940 return sal_False;
943 Content aNewContent(
944 xNew, m_xImpl->getEnvironment(), m_xImpl->getComponentContext() );
945 aNewContent.setPropertyValues( rPropertyNames, rPropertyValues );
946 aNewContent.executeCommand( OUString("insert"),
947 makeAny(
948 InsertCommandArgument(
949 rData.is() ? rData : new EmptyInputStream,
950 sal_False /* ReplaceExisting */ ) ) );
951 aNewContent.m_xImpl->inserted();
953 rNewContent = aNewContent;
954 return sal_True;
957 //=========================================================================
958 sal_Bool Content::transferContent( const Content& rSourceContent,
959 InsertOperation eOperation,
960 const OUString & rTitle,
961 const sal_Int32 nNameClashAction,
962 const OUString & rMimeType,
963 bool bMajorVersion,
964 const OUString & rVersionComment,
965 OUString* pResultURL )
966 throw( CommandAbortedException, RuntimeException, Exception )
968 Reference< XUniversalContentBroker > pBroker(
969 UniversalContentBroker::create( m_xImpl->getComponentContext() ) );
971 // Execute command "globalTransfer" at UCB.
973 TransferCommandOperation eTransOp = TransferCommandOperation();
974 OUString sCommand( "globalTransfer" );
975 bool bCheckIn = false;
976 switch ( eOperation )
978 case InsertOperation_COPY:
979 eTransOp = TransferCommandOperation_COPY;
980 break;
982 case InsertOperation_MOVE:
983 eTransOp = TransferCommandOperation_MOVE;
984 break;
986 case InsertOperation_LINK:
987 eTransOp = TransferCommandOperation_LINK;
988 break;
990 case InsertOperation_CHECKIN:
991 eTransOp = TransferCommandOperation_COPY;
992 sCommand = OUString( "checkin" );
993 bCheckIn = true;
994 break;
996 default:
997 ucbhelper::cancelCommandExecution(
998 makeAny( IllegalArgumentException(
999 OUString(
1000 "Unknown transfer operation!" ),
1001 get(),
1002 -1 ) ),
1003 m_xImpl->getEnvironment() );
1004 // Unreachable
1006 Command aCommand;
1007 aCommand.Name = sCommand;
1008 aCommand.Handle = -1; // n/a
1010 if ( !bCheckIn )
1012 GlobalTransferCommandArgument2 aTransferArg(
1013 eTransOp,
1014 rSourceContent.getURL(), // SourceURL
1015 getURL(), // TargetFolderURL,
1016 rTitle,
1017 nNameClashAction,
1018 rMimeType );
1019 aCommand.Argument <<= aTransferArg;
1021 else
1023 CheckinArgument aCheckinArg( bMajorVersion, rVersionComment,
1024 rSourceContent.getURL(), getURL(), rTitle, rMimeType );
1025 aCommand.Argument <<= aCheckinArg;
1028 Any aRet = pBroker->execute( aCommand, 0, m_xImpl->getEnvironment() );
1029 if ( pResultURL != NULL )
1030 aRet >>= *pResultURL;
1031 return sal_True;
1034 //=========================================================================
1035 sal_Bool Content::isFolder()
1036 throw( CommandAbortedException, RuntimeException, Exception )
1038 sal_Bool bFolder = sal_False;
1039 if ( getPropertyValue( OUString("IsFolder") )
1040 >>= bFolder )
1041 return bFolder;
1043 ucbhelper::cancelCommandExecution(
1044 makeAny( UnknownPropertyException(
1045 OUString(
1046 "Unable to retrieve value of property 'IsFolder'!" ),
1047 get() ) ),
1048 m_xImpl->getEnvironment() );
1050 // Unreachable - cancelCommandExecution always throws an exception.
1051 // But some compilers complain...
1052 return sal_False;
1055 //=========================================================================
1056 sal_Bool Content::isDocument()
1057 throw( CommandAbortedException, RuntimeException, Exception )
1059 sal_Bool bDoc = sal_False;
1060 if ( getPropertyValue( OUString("IsDocument") )
1061 >>= bDoc )
1062 return bDoc;
1064 ucbhelper::cancelCommandExecution(
1065 makeAny( UnknownPropertyException(
1066 OUString(
1067 "Unable to retrieve value of property 'IsDocument'!" ),
1068 get() ) ),
1069 m_xImpl->getEnvironment() );
1071 // Unreachable - cancelCommandExecution always throws an exception,
1072 // But some compilers complain...
1073 return sal_False;
1076 //=========================================================================
1077 //=========================================================================
1079 // Content_Impl Implementation.
1081 //=========================================================================
1082 //=========================================================================
1084 Content_Impl::Content_Impl( const Reference< XComponentContext >& rCtx,
1085 const Reference< XContent >& rContent,
1086 const Reference< XCommandEnvironment >& rEnv )
1087 : m_xCtx( rCtx ),
1088 m_xContent( rContent ),
1089 m_xEnv( rEnv )
1091 assert(rCtx.is());
1092 if ( m_xContent.is() )
1094 m_xContentEventListener = new ContentEventListener_Impl( *this );
1095 m_xContent->addContentEventListener( m_xContentEventListener );
1097 #if OSL_DEBUG_LEVEL > 1
1098 // Only done on demand in product version for performance reasons,
1099 // but a nice debug helper.
1100 getURL();
1101 #endif
1105 //=========================================================================
1106 void Content_Impl::reinit( const Reference< XContent >& xContent )
1108 osl::MutexGuard aGuard( m_aMutex );
1110 m_xCommandProcessor = 0;
1112 // #92581# - Don't reset m_aURL!!!
1114 if ( m_xContent.is() )
1118 m_xContent->removeContentEventListener( m_xContentEventListener );
1120 catch ( RuntimeException const & )
1125 if ( xContent.is() )
1127 m_xContent = xContent;
1128 m_xContent->addContentEventListener( m_xContentEventListener );
1130 #if OSL_DEBUG_LEVEL > 1
1131 // Only done on demand in product version for performance reasons,
1132 // but a nice debug helper.
1133 getURL();
1134 #endif
1136 else
1138 // We need m_xContent's URL in order to be able to create the
1139 // content object again if demanded ( --> Content_Impl::getContent() )
1140 getURL();
1142 m_xContent = 0;
1146 //=========================================================================
1147 // virtual
1148 Content_Impl::~Content_Impl()
1150 if ( m_xContent.is() )
1154 m_xContent->removeContentEventListener( m_xContentEventListener );
1156 catch ( RuntimeException const & )
1162 //=========================================================================
1163 void Content_Impl::disposing( const EventObject& Source )
1165 Reference<XContent> xContent;
1168 osl::MutexGuard aGuard( m_aMutex );
1169 if(Source.Source != m_xContent)
1170 return;
1172 xContent = m_xContent;
1174 m_aURL = OUString();
1175 m_xCommandProcessor = 0;
1176 m_xContent = 0;
1179 if ( xContent.is() )
1183 xContent->removeContentEventListener( m_xContentEventListener );
1185 catch ( RuntimeException const & )
1191 //=========================================================================
1192 const OUString& Content_Impl::getURL() const
1194 if ( m_aURL.isEmpty() && m_xContent.is() )
1196 osl::MutexGuard aGuard( m_aMutex );
1198 if ( m_aURL.isEmpty() && m_xContent.is() )
1200 Reference< XContentIdentifier > xId = m_xContent->getIdentifier();
1201 if ( xId.is() )
1202 m_aURL = xId->getContentIdentifier();
1206 return m_aURL;
1209 //=========================================================================
1210 Reference< XContent > Content_Impl::getContent()
1212 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1214 osl::MutexGuard aGuard( m_aMutex );
1216 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1218 Reference< XUniversalContentBroker > pBroker(
1219 UniversalContentBroker::create( getComponentContext() ) );
1221 OSL_ENSURE( pBroker->queryContentProviders().getLength(),
1222 "Content Broker not configured (no providers)!" );
1224 Reference< XContentIdentifier > xId
1225 = pBroker->createContentIdentifier( m_aURL );
1227 OSL_ENSURE( xId.is(), "No Content Identifier!" );
1229 if ( xId.is() )
1233 m_xContent = pBroker->queryContent( xId );
1235 catch ( IllegalIdentifierException const & )
1239 if ( m_xContent.is() )
1240 m_xContent->addContentEventListener(
1241 m_xContentEventListener );
1246 return m_xContent;
1249 //=========================================================================
1250 Reference< XCommandProcessor > Content_Impl::getCommandProcessor()
1252 if ( !m_xCommandProcessor.is() )
1254 osl::MutexGuard aGuard( m_aMutex );
1256 if ( !m_xCommandProcessor.is() )
1257 m_xCommandProcessor
1258 = Reference< XCommandProcessor >( getContent(), UNO_QUERY );
1261 return m_xCommandProcessor;
1264 //=========================================================================
1265 Any Content_Impl::executeCommand( const Command& rCommand )
1267 Reference< XCommandProcessor > xProc = getCommandProcessor();
1268 if ( !xProc.is() )
1269 return Any();
1271 // Execute command
1272 return xProc->execute( rCommand, 0, m_xEnv );
1275 //=========================================================================
1276 inline const Reference< XCommandEnvironment >&
1277 Content_Impl::getEnvironment() const
1279 return m_xEnv;
1282 //=========================================================================
1283 inline void Content_Impl::setEnvironment(
1284 const Reference< XCommandEnvironment >& xNewEnv )
1286 osl::MutexGuard aGuard( m_aMutex );
1287 m_xEnv = xNewEnv;
1290 //=========================================================================
1291 void Content_Impl::inserted()
1293 // URL might have changed during 'insert' => recalculate in next getURL()
1294 osl::MutexGuard aGuard( m_aMutex );
1295 m_aURL = OUString();
1298 //=========================================================================
1299 //=========================================================================
1301 // ContentEventListener_Impl Implementation.
1303 //=========================================================================
1304 //=========================================================================
1306 //=========================================================================
1308 // XInterface methods.
1310 //=========================================================================
1312 XINTERFACE_IMPL_2( ContentEventListener_Impl,
1313 XContentEventListener,
1314 XEventListener ); /* base of XContentEventListener */
1316 //=========================================================================
1318 // XContentEventListener methods.
1320 //=========================================================================
1322 // virtual
1323 void SAL_CALL ContentEventListener_Impl::contentEvent( const ContentEvent& evt )
1324 throw( RuntimeException )
1326 if ( evt.Source == m_rContent.m_xContent )
1328 switch ( evt.Action )
1330 case ContentAction::DELETED:
1331 m_rContent.reinit( Reference< XContent >() );
1332 break;
1334 case ContentAction::EXCHANGED:
1335 m_rContent.reinit( evt.Content );
1336 break;
1338 default:
1339 break;
1344 //=========================================================================
1346 // XEventListenr methods.
1348 //=========================================================================
1350 // virtual
1351 void SAL_CALL ContentEventListener_Impl::disposing( const EventObject& Source )
1352 throw( RuntimeException )
1354 m_rContent.disposing(Source);
1357 } /* namespace ucbhelper */
1359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */