Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / ucbhelper / source / client / content.cxx
bloba32f3bbade32f56dcf263408be63de9c6aed173d
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 rtl::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;
176 sal_Int32 m_nCommandId;
178 private:
179 void reinit( const Reference< XContent >& xContent );
180 void disposing(const EventObject& Source);
182 public:
183 Content_Impl() : m_nCommandId( 0 ) {};
184 Content_Impl( const Reference< XComponentContext >& rCtx,
185 const Reference< XContent >& rContent,
186 const Reference< XCommandEnvironment >& rEnv );
188 virtual ~Content_Impl();
190 const rtl::OUString& getURL() const;
191 Reference< XContent > getContent();
192 Reference< XCommandProcessor > getCommandProcessor();
193 sal_Int32 getCommandId();
194 Reference< XComponentContext > getComponentContext()
195 { assert(m_xCtx.is()); return m_xCtx; }
197 Any executeCommand( const Command& rCommand );
199 inline const Reference< XCommandEnvironment >& getEnvironment() const;
200 inline void setEnvironment(
201 const Reference< XCommandEnvironment >& xNewEnv );
203 void inserted();
206 //=========================================================================
207 // Helpers.
208 //=========================================================================
210 static void ensureContentProviderForURL( const Reference< XUniversalContentBroker >& rBroker,
211 const rtl::OUString & rURL )
212 throw ( ContentCreationException, RuntimeException )
214 Reference< XContentProvider > xProv
215 = rBroker->queryContentProvider( rURL );
216 if ( !xProv.is() )
218 throw ContentCreationException(
219 "No Content Provider available for URL: " + rURL,
220 Reference< XInterface >(),
221 ContentCreationError_NO_CONTENT_PROVIDER );
225 //=========================================================================
226 static Reference< XContentIdentifier > getContentIdentifier(
227 const Reference< XUniversalContentBroker > & rBroker,
228 const rtl::OUString & rURL,
229 bool bThrow )
230 throw ( ContentCreationException, RuntimeException )
232 Reference< XContentIdentifier > xId
233 = rBroker->createContentIdentifier( rURL );
235 if ( xId.is() )
236 return xId;
238 if ( bThrow )
240 ensureContentProviderForURL( rBroker, rURL );
242 throw ContentCreationException(
243 "Unable to create Content Identifier!",
244 Reference< XInterface >(),
245 ContentCreationError_IDENTIFIER_CREATION_FAILED );
248 return Reference< XContentIdentifier >();
251 //=========================================================================
252 static Reference< XContent > getContent(
253 const Reference< XUniversalContentBroker > & rBroker,
254 const Reference< XContentIdentifier > & xId,
255 bool bThrow )
256 throw ( ContentCreationException, RuntimeException )
258 Reference< XContent > xContent;
259 rtl::OUString msg;
262 xContent = rBroker->queryContent( xId );
264 catch ( IllegalIdentifierException const & e )
266 msg = e.Message;
267 // handled below.
270 if ( xContent.is() )
271 return xContent;
273 if ( bThrow )
275 ensureContentProviderForURL( rBroker, xId->getContentIdentifier() );
277 throw ContentCreationException(
278 "Unable to create Content! " + msg,
279 Reference< XInterface >(),
280 ContentCreationError_CONTENT_CREATION_FAILED );
283 return Reference< XContent >();
286 //=========================================================================
287 //=========================================================================
289 // Content Implementation.
291 //=========================================================================
292 //=========================================================================
294 Content::Content()
295 : m_xImpl( new Content_Impl )
299 //=========================================================================
300 Content::Content( const rtl::OUString& rURL,
301 const Reference< XCommandEnvironment >& rEnv,
302 const Reference< XComponentContext >& rCtx )
303 throw ( ContentCreationException, RuntimeException )
305 Reference< XUniversalContentBroker > pBroker(
306 UniversalContentBroker::create( rCtx ) );
308 Reference< XContentIdentifier > xId
309 = getContentIdentifier( pBroker, rURL, true );
311 Reference< XContent > xContent = getContent( pBroker, xId, true );
313 m_xImpl = new Content_Impl( rCtx, xContent, rEnv );
316 //=========================================================================
317 Content::Content( const Reference< XContent >& rContent,
318 const Reference< XCommandEnvironment >& rEnv,
319 const Reference< XComponentContext >& rCtx )
320 throw ( ContentCreationException, RuntimeException )
322 m_xImpl = new Content_Impl( rCtx, rContent, rEnv );
325 //=========================================================================
326 Content::Content( const Content& rOther )
328 m_xImpl = rOther.m_xImpl;
331 //=========================================================================
332 // static
333 sal_Bool Content::create( const rtl::OUString& rURL,
334 const Reference< XCommandEnvironment >& rEnv,
335 const Reference< XComponentContext >& rCtx,
336 Content& rContent )
338 Reference< XUniversalContentBroker > pBroker(
339 UniversalContentBroker::create( rCtx ) );
341 Reference< XContentIdentifier > xId
342 = getContentIdentifier( pBroker, rURL, false );
343 if ( !xId.is() )
344 return sal_False;
346 Reference< XContent > xContent = getContent( pBroker, xId, false );
347 if ( !xContent.is() )
348 return sal_False;
350 rContent.m_xImpl
351 = new Content_Impl( rCtx, xContent, rEnv );
353 return sal_True;
356 //=========================================================================
357 Content::~Content()
361 //=========================================================================
362 Content& Content::operator=( const Content& rOther )
364 m_xImpl = rOther.m_xImpl;
365 return *this;
368 //=========================================================================
369 Reference< XContent > Content::get() const
371 return m_xImpl->getContent();
374 //=========================================================================
375 const rtl::OUString& Content::getURL() const
377 return m_xImpl->getURL();
380 //=========================================================================
381 const Reference< XCommandEnvironment >& Content::getCommandEnvironment() const
383 return m_xImpl->getEnvironment();
386 //=========================================================================
387 void Content::setCommandEnvironment(
388 const Reference< XCommandEnvironment >& xNewEnv )
390 m_xImpl->setEnvironment( xNewEnv );
393 //=========================================================================
394 Reference< XCommandInfo > Content::getCommands()
395 throw( CommandAbortedException, RuntimeException, Exception )
397 Command aCommand;
398 aCommand.Name = rtl::OUString("getCommandInfo");
399 aCommand.Handle = -1; // n/a
400 aCommand.Argument = Any();
402 Any aResult = m_xImpl->executeCommand( aCommand );
404 Reference< XCommandInfo > xInfo;
405 aResult >>= xInfo;
406 return xInfo;
409 //=========================================================================
410 Reference< XPropertySetInfo > Content::getProperties()
411 throw( CommandAbortedException, RuntimeException, Exception )
413 Command aCommand;
414 aCommand.Name = rtl::OUString("getPropertySetInfo");
415 aCommand.Handle = -1; // n/a
416 aCommand.Argument = Any();
418 Any aResult = m_xImpl->executeCommand( aCommand );
420 Reference< XPropertySetInfo > xInfo;
421 aResult >>= xInfo;
422 return xInfo;
425 //=========================================================================
426 Any Content::getPropertyValue( const rtl::OUString& rPropertyName )
427 throw( CommandAbortedException, RuntimeException, Exception )
429 Sequence< rtl::OUString > aNames( 1 );
430 aNames.getArray()[ 0 ] = rPropertyName;
432 Sequence< Any > aRet = getPropertyValues( aNames );
433 return aRet.getConstArray()[ 0 ];
436 //=========================================================================
437 Any Content::setPropertyValue( const rtl::OUString& rName,
438 const Any& rValue )
439 throw( CommandAbortedException, RuntimeException, Exception )
441 Sequence< rtl::OUString > aNames( 1 );
442 aNames.getArray()[ 0 ] = rName;
444 Sequence< Any > aValues( 1 );
445 aValues.getArray()[ 0 ] = rValue;
447 Sequence< Any > aErrors = setPropertyValues( aNames, aValues );
448 return aErrors.getConstArray()[ 0 ];
451 //=========================================================================
452 Sequence< Any > Content::getPropertyValues(
453 const Sequence< rtl::OUString >& rPropertyNames )
454 throw( CommandAbortedException, RuntimeException, Exception )
456 Reference< XRow > xRow = getPropertyValuesInterface( rPropertyNames );
458 sal_Int32 nCount = rPropertyNames.getLength();
459 Sequence< Any > aValues( nCount );
461 if ( xRow.is() )
463 Any* pValues = aValues.getArray();
465 for ( sal_Int32 n = 0; n < nCount; ++n )
466 pValues[ n ] = xRow->getObject( n + 1, Reference< XNameAccess >() );
469 return aValues;
472 //=========================================================================
473 Reference< XRow > Content::getPropertyValuesInterface(
474 const Sequence< rtl::OUString >& rPropertyNames )
475 throw( CommandAbortedException, RuntimeException, Exception )
477 sal_Int32 nCount = rPropertyNames.getLength();
478 Sequence< Property > aProps( nCount );
479 Property* pProps = aProps.getArray();
481 const rtl::OUString* pNames = rPropertyNames.getConstArray();
483 for ( sal_Int32 n = 0; n< nCount; ++n )
485 Property& rProp = pProps[ n ];
487 rProp.Name = pNames[ n ];
488 rProp.Handle = -1; // n/a
489 // rProp.Type =
490 // rProp.Attributes = ;
493 Command aCommand;
494 aCommand.Name = rtl::OUString("getPropertyValues");
495 aCommand.Handle = -1; // n/a
496 aCommand.Argument <<= aProps;
498 Any aResult = m_xImpl->executeCommand( aCommand );
500 Reference< XRow > xRow;
501 aResult >>= xRow;
502 return xRow;
505 //=========================================================================
506 Sequence< Any > Content::setPropertyValues(
507 const Sequence< rtl::OUString >& rPropertyNames,
508 const Sequence< Any >& rValues )
509 throw( CommandAbortedException, RuntimeException, Exception )
511 if ( rPropertyNames.getLength() != rValues.getLength() )
513 ucbhelper::cancelCommandExecution(
514 makeAny( IllegalArgumentException(
515 rtl::OUString(
516 "Length of property names sequence and value "
517 "sequence are unequal!" ),
518 get(),
519 -1 ) ),
520 m_xImpl->getEnvironment() );
521 // Unreachable
524 sal_Int32 nCount = rValues.getLength();
525 Sequence< PropertyValue > aProps( nCount );
526 PropertyValue* pProps = aProps.getArray();
528 const rtl::OUString* pNames = rPropertyNames.getConstArray();
529 const Any* pValues = rValues.getConstArray();
531 for ( sal_Int32 n = 0; n< nCount; ++n )
533 PropertyValue& rProp = pProps[ n ];
535 rProp.Name = pNames[ n ];
536 rProp.Handle = -1; // n/a
537 rProp.Value = pValues[ n ];
538 // rProp.State = ;
541 Command aCommand;
542 aCommand.Name = rtl::OUString("setPropertyValues");
543 aCommand.Handle = -1; // n/a
544 aCommand.Argument <<= aProps;
546 Any aResult = m_xImpl->executeCommand( aCommand );
548 Sequence< Any > aErrors;
549 aResult >>= aErrors;
550 return aErrors;
553 //=========================================================================
554 Any Content::executeCommand( const rtl::OUString& rCommandName,
555 const Any& rCommandArgument )
556 throw( CommandAbortedException, RuntimeException, Exception )
558 Command aCommand;
559 aCommand.Name = rCommandName;
560 aCommand.Handle = -1; // n/a
561 aCommand.Argument = rCommandArgument;
563 return m_xImpl->executeCommand( aCommand );
566 //=========================================================================
567 Any Content::createCursorAny( const Sequence< rtl::OUString >& rPropertyNames,
568 ResultSetInclude eMode )
569 throw( CommandAbortedException, RuntimeException, Exception )
571 sal_Int32 nCount = rPropertyNames.getLength();
572 Sequence< Property > aProps( nCount );
573 Property* pProps = aProps.getArray();
574 const rtl::OUString* pNames = rPropertyNames.getConstArray();
575 for ( sal_Int32 n = 0; n < nCount; ++n )
577 Property& rProp = pProps[ n ];
578 rProp.Name = pNames[ n ];
579 rProp.Handle = -1; // n/a
582 OpenCommandArgument2 aArg;
583 aArg.Mode = ( eMode == INCLUDE_FOLDERS_ONLY )
584 ? OpenMode::FOLDERS
585 : ( eMode == INCLUDE_DOCUMENTS_ONLY )
586 ? OpenMode::DOCUMENTS : OpenMode::ALL;
587 aArg.Priority = 0; // unused
588 aArg.Sink = Reference< XInterface >(); // unused
589 aArg.Properties = aProps;
591 Command aCommand;
592 aCommand.Name = rtl::OUString("open");
593 aCommand.Handle = -1; // n/a
594 aCommand.Argument <<= aArg;
596 return m_xImpl->executeCommand( aCommand );
599 //=========================================================================
600 Reference< XResultSet > Content::createCursor(
601 const Sequence< rtl::OUString >& rPropertyNames,
602 ResultSetInclude eMode )
603 throw( CommandAbortedException, RuntimeException, Exception )
605 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
607 Reference< XDynamicResultSet > xDynSet;
608 Reference< XResultSet > aResult;
610 aCursorAny >>= xDynSet;
611 if ( xDynSet.is() )
612 aResult = xDynSet->getStaticResultSet();
614 OSL_ENSURE( aResult.is(), "Content::createCursor - no cursor!" );
616 if ( !aResult.is() )
618 // Former, the open command directly returned a XResultSet.
619 aCursorAny >>= aResult;
621 OSL_ENSURE( !aResult.is(),
622 "Content::createCursor - open-Command must "
623 "return a Reference< XDynnamicResultSet >!" );
626 return aResult;
629 //=========================================================================
630 Reference< XDynamicResultSet > Content::createDynamicCursor(
631 const Sequence< rtl::OUString >& rPropertyNames,
632 ResultSetInclude eMode )
633 throw( CommandAbortedException, RuntimeException, Exception )
635 Reference< XDynamicResultSet > aResult;
636 createCursorAny( rPropertyNames, eMode ) >>= aResult;
638 OSL_ENSURE( aResult.is(), "Content::createDynamicCursor - no cursor!" );
640 return aResult;
643 //=========================================================================
644 Reference< XResultSet > Content::createSortedCursor(
645 const Sequence< rtl::OUString >& rPropertyNames,
646 const Sequence< NumberedSortingInfo >& rSortInfo,
647 Reference< XAnyCompareFactory > rAnyCompareFactory,
648 ResultSetInclude eMode )
649 throw( CommandAbortedException, RuntimeException, Exception )
651 Reference< XResultSet > aResult;
652 Reference< XDynamicResultSet > aDynSet;
654 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
656 aCursorAny >>= aDynSet;
658 if( aDynSet.is() )
660 Reference< XDynamicResultSet > aDynResult;
662 if( m_xImpl->getComponentContext().is() )
664 Reference< XSortedDynamicResultSetFactory > aSortFactory =
665 SortedDynamicResultSetFactory::create( m_xImpl->getComponentContext());
667 aDynResult = aSortFactory->createSortedDynamicResultSet( aDynSet,
668 rSortInfo,
669 rAnyCompareFactory );
672 OSL_ENSURE( aDynResult.is(), "Content::createSortedCursor - no sorted cursor!\n" );
674 if( aDynResult.is() )
675 aResult = aDynResult->getStaticResultSet();
676 else
677 aResult = aDynSet->getStaticResultSet();
680 OSL_ENSURE( aResult.is(), "Content::createSortedCursor - no cursor!" );
682 if ( !aResult.is() )
684 // Former, the open command directly returned a XResultSet.
685 aCursorAny >>= aResult;
687 OSL_ENSURE( !aResult.is(),
688 "Content::createCursor - open-Command must "
689 "return a Reference< XDynnamicResultSet >!" );
692 return aResult;
695 //=========================================================================
696 Reference< XInputStream > Content::openStream()
697 throw( CommandAbortedException, RuntimeException, Exception )
699 if ( !isDocument() )
700 return Reference< XInputStream >();
702 Reference< XActiveDataSink > xSink = new ActiveDataSink;
704 OpenCommandArgument2 aArg;
705 aArg.Mode = OpenMode::DOCUMENT;
706 aArg.Priority = 0; // unused
707 aArg.Sink = xSink;
708 aArg.Properties = Sequence< Property >( 0 ); // unused
710 Command aCommand;
711 aCommand.Name = rtl::OUString("open");
712 aCommand.Handle = -1; // n/a
713 aCommand.Argument <<= aArg;
715 m_xImpl->executeCommand( aCommand );
717 return xSink->getInputStream();
720 //=========================================================================
721 Reference< XInputStream > Content::openStreamNoLock()
722 throw( CommandAbortedException, RuntimeException, Exception )
724 if ( !isDocument() )
725 return Reference< XInputStream >();
727 Reference< XActiveDataSink > xSink = new ActiveDataSink;
729 OpenCommandArgument2 aArg;
730 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
731 aArg.Priority = 0; // unused
732 aArg.Sink = xSink;
733 aArg.Properties = Sequence< Property >( 0 ); // unused
735 Command aCommand;
736 aCommand.Name = rtl::OUString("open");
737 aCommand.Handle = -1; // n/a
738 aCommand.Argument <<= aArg;
740 m_xImpl->executeCommand( aCommand );
742 return xSink->getInputStream();
745 //=========================================================================
746 Reference< XStream > Content::openWriteableStream()
747 throw( CommandAbortedException, RuntimeException, Exception )
749 if ( !isDocument() )
750 return Reference< XStream >();
752 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
754 OpenCommandArgument2 aArg;
755 aArg.Mode = OpenMode::DOCUMENT;
756 aArg.Priority = 0; // unused
757 aArg.Sink = xStreamer;
758 aArg.Properties = Sequence< Property >( 0 ); // unused
760 Command aCommand;
761 aCommand.Name = rtl::OUString("open");
762 aCommand.Handle = -1; // n/a
763 aCommand.Argument <<= aArg;
765 m_xImpl->executeCommand( aCommand );
767 return xStreamer->getStream();
770 //=========================================================================
771 Reference< XStream > Content::openWriteableStreamNoLock()
772 throw( CommandAbortedException, RuntimeException, Exception )
774 if ( !isDocument() )
775 return Reference< XStream >();
777 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
779 OpenCommandArgument2 aArg;
780 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
781 aArg.Priority = 0; // unused
782 aArg.Sink = xStreamer;
783 aArg.Properties = Sequence< Property >( 0 ); // unused
785 Command aCommand;
786 aCommand.Name = rtl::OUString("open");
787 aCommand.Handle = -1; // n/a
788 aCommand.Argument <<= aArg;
790 m_xImpl->executeCommand( aCommand );
792 return xStreamer->getStream();
795 //=========================================================================
796 sal_Bool Content::openStream( const Reference< XActiveDataSink >& rSink )
797 throw( CommandAbortedException, RuntimeException, Exception )
799 if ( !isDocument() )
800 return sal_False;
802 OpenCommandArgument2 aArg;
803 aArg.Mode = OpenMode::DOCUMENT;
804 aArg.Priority = 0; // unused
805 aArg.Sink = rSink;
806 aArg.Properties = Sequence< Property >( 0 ); // unused
808 Command aCommand;
809 aCommand.Name = rtl::OUString("open");
810 aCommand.Handle = -1; // n/a
811 aCommand.Argument <<= aArg;
813 m_xImpl->executeCommand( aCommand );
815 return sal_True;
818 //=========================================================================
819 sal_Bool Content::openStream( const Reference< XOutputStream >& rStream )
820 throw( CommandAbortedException, RuntimeException, Exception )
822 if ( !isDocument() )
823 return sal_False;
825 OpenCommandArgument2 aArg;
826 aArg.Mode = OpenMode::DOCUMENT;
827 aArg.Priority = 0; // unused
828 aArg.Sink = rStream;
829 aArg.Properties = Sequence< Property >( 0 ); // unused
831 Command aCommand;
832 aCommand.Name = rtl::OUString("open");
833 aCommand.Handle = -1; // n/a
834 aCommand.Argument <<= aArg;
836 m_xImpl->executeCommand( aCommand );
838 return sal_True;
841 //=========================================================================
842 void Content::writeStream( const Reference< XInputStream >& rStream,
843 sal_Bool bReplaceExisting )
844 throw( CommandAbortedException, RuntimeException, Exception )
846 InsertCommandArgument aArg;
847 aArg.Data = rStream.is() ? rStream : new EmptyInputStream;
848 aArg.ReplaceExisting = bReplaceExisting;
850 Command aCommand;
851 aCommand.Name = rtl::OUString("insert");
852 aCommand.Handle = -1; // n/a
853 aCommand.Argument <<= aArg;
855 m_xImpl->executeCommand( aCommand );
857 m_xImpl->inserted();
860 //=========================================================================
861 Sequence< ContentInfo > Content::queryCreatableContentsInfo()
862 throw( CommandAbortedException, RuntimeException, Exception )
864 // First, try it using "CreatableContentsInfo" property -> the "new" way.
865 Sequence< ContentInfo > aInfo;
866 if ( getPropertyValue(
867 rtl::OUString("CreatableContentsInfo") )
868 >>= aInfo )
869 return aInfo;
871 // Second, try it using XContentCreator interface -> the "old" way (not
872 // providing the chance to supply an XCommandEnvironment.
873 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
874 if ( xCreator.is() )
875 aInfo = xCreator->queryCreatableContentsInfo();
877 return aInfo;
880 //=========================================================================
881 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
882 const Sequence< rtl::OUString >&
883 rPropertyNames,
884 const Sequence< Any >& rPropertyValues,
885 Content& rNewContent )
886 throw( CommandAbortedException, RuntimeException, Exception )
888 return insertNewContent( rContentType,
889 rPropertyNames,
890 rPropertyValues,
891 new EmptyInputStream,
892 rNewContent );
895 //=========================================================================
896 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
897 const Sequence< rtl::OUString >&
898 rPropertyNames,
899 const Sequence< Any >& rPropertyValues,
900 const Reference< XInputStream >& rData,
901 Content& rNewContent )
902 throw( CommandAbortedException, RuntimeException, Exception )
904 if ( rContentType.isEmpty() )
905 return sal_False;
907 // First, try it using "createNewContent" command -> the "new" way.
908 ContentInfo aInfo;
909 aInfo.Type = rContentType;
910 aInfo.Attributes = 0;
912 Command aCommand;
913 aCommand.Name = rtl::OUString("createNewContent");
914 aCommand.Handle = -1; // n/a
915 aCommand.Argument <<= aInfo;
917 Reference< XContent > xNew;
920 m_xImpl->executeCommand( aCommand ) >>= xNew;
922 catch ( RuntimeException const & )
924 throw;
926 catch ( Exception const & )
930 if ( !xNew.is() )
932 // Second, try it using XContentCreator interface -> the "old"
933 // way (not providing the chance to supply an XCommandEnvironment.
934 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
936 if ( !xCreator.is() )
937 return sal_False;
939 xNew = xCreator->createNewContent( aInfo );
941 if ( !xNew.is() )
942 return sal_False;
945 Content aNewContent(
946 xNew, m_xImpl->getEnvironment(), m_xImpl->getComponentContext() );
947 aNewContent.setPropertyValues( rPropertyNames, rPropertyValues );
948 aNewContent.executeCommand( rtl::OUString("insert"),
949 makeAny(
950 InsertCommandArgument(
951 rData.is() ? rData : new EmptyInputStream,
952 sal_False /* ReplaceExisting */ ) ) );
953 aNewContent.m_xImpl->inserted();
955 rNewContent = aNewContent;
956 return sal_True;
959 //=========================================================================
960 sal_Bool Content::transferContent( const Content& rSourceContent,
961 InsertOperation eOperation,
962 const rtl::OUString & rTitle,
963 const sal_Int32 nNameClashAction,
964 const rtl::OUString & rMimeType,
965 bool bMajorVersion,
966 const rtl::OUString & rVersionComment,
967 rtl::OUString* pResultURL )
968 throw( CommandAbortedException, RuntimeException, Exception )
970 Reference< XUniversalContentBroker > pBroker(
971 UniversalContentBroker::create( m_xImpl->getComponentContext() ) );
973 // Execute command "globalTransfer" at UCB.
975 TransferCommandOperation eTransOp = TransferCommandOperation();
976 rtl::OUString sCommand( "globalTransfer" );
977 bool bCheckIn = false;
978 switch ( eOperation )
980 case InsertOperation_COPY:
981 eTransOp = TransferCommandOperation_COPY;
982 break;
984 case InsertOperation_MOVE:
985 eTransOp = TransferCommandOperation_MOVE;
986 break;
988 case InsertOperation_LINK:
989 eTransOp = TransferCommandOperation_LINK;
990 break;
992 case InsertOperation_CHECKIN:
993 eTransOp = TransferCommandOperation_COPY;
994 sCommand = rtl::OUString( "checkin" );
995 bCheckIn = true;
996 break;
998 default:
999 ucbhelper::cancelCommandExecution(
1000 makeAny( IllegalArgumentException(
1001 rtl::OUString(
1002 "Unknown transfer operation!" ),
1003 get(),
1004 -1 ) ),
1005 m_xImpl->getEnvironment() );
1006 // Unreachable
1008 Command aCommand;
1009 aCommand.Name = sCommand;
1010 aCommand.Handle = -1; // n/a
1012 if ( !bCheckIn )
1014 GlobalTransferCommandArgument2 aTransferArg(
1015 eTransOp,
1016 rSourceContent.getURL(), // SourceURL
1017 getURL(), // TargetFolderURL,
1018 rTitle,
1019 nNameClashAction,
1020 rMimeType );
1021 aCommand.Argument <<= aTransferArg;
1023 else
1025 CheckinArgument aCheckinArg( bMajorVersion, rVersionComment,
1026 rSourceContent.getURL(), getURL(), rTitle, rMimeType );
1027 aCommand.Argument <<= aCheckinArg;
1030 Any aRet = pBroker->execute( aCommand, 0, m_xImpl->getEnvironment() );
1031 if ( pResultURL != NULL )
1032 aRet >>= *pResultURL;
1033 return sal_True;
1036 //=========================================================================
1037 sal_Bool Content::isFolder()
1038 throw( CommandAbortedException, RuntimeException, Exception )
1040 sal_Bool bFolder = sal_False;
1041 if ( getPropertyValue( rtl::OUString("IsFolder") )
1042 >>= bFolder )
1043 return bFolder;
1045 ucbhelper::cancelCommandExecution(
1046 makeAny( UnknownPropertyException(
1047 rtl::OUString(
1048 "Unable to retreive value of property 'IsFolder'!" ),
1049 get() ) ),
1050 m_xImpl->getEnvironment() );
1052 // Unreachable - cancelCommandExecution always throws an exception.
1053 // But some compilers complain...
1054 return sal_False;
1057 //=========================================================================
1058 sal_Bool Content::isDocument()
1059 throw( CommandAbortedException, RuntimeException, Exception )
1061 sal_Bool bDoc = sal_False;
1062 if ( getPropertyValue( rtl::OUString("IsDocument") )
1063 >>= bDoc )
1064 return bDoc;
1066 ucbhelper::cancelCommandExecution(
1067 makeAny( UnknownPropertyException(
1068 rtl::OUString(
1069 "Unable to retreive value of property 'IsDocument'!" ),
1070 get() ) ),
1071 m_xImpl->getEnvironment() );
1073 // Unreachable - cancelCommandExecution always throws an exception,
1074 // But some compilers complain...
1075 return sal_False;
1078 //=========================================================================
1079 //=========================================================================
1081 // Content_Impl Implementation.
1083 //=========================================================================
1084 //=========================================================================
1086 Content_Impl::Content_Impl( const Reference< XComponentContext >& rCtx,
1087 const Reference< XContent >& rContent,
1088 const Reference< XCommandEnvironment >& rEnv )
1089 : m_xCtx( rCtx ),
1090 m_xContent( rContent ),
1091 m_xEnv( rEnv ),
1092 m_nCommandId( 0 )
1094 assert(rCtx.is());
1095 if ( m_xContent.is() )
1097 m_xContentEventListener = new ContentEventListener_Impl( *this );
1098 m_xContent->addContentEventListener( m_xContentEventListener );
1100 #if OSL_DEBUG_LEVEL > 1
1101 // Only done on demand in product version for performance reasons,
1102 // but a nice debug helper.
1103 getURL();
1104 #endif
1108 //=========================================================================
1109 void Content_Impl::reinit( const Reference< XContent >& xContent )
1111 osl::MutexGuard aGuard( m_aMutex );
1113 m_xCommandProcessor = 0;
1114 m_nCommandId = 0;
1116 // #92581# - Don't reset m_aURL!!!
1118 if ( m_xContent.is() )
1122 m_xContent->removeContentEventListener( m_xContentEventListener );
1124 catch ( RuntimeException const & )
1129 if ( xContent.is() )
1131 m_xContent = xContent;
1132 m_xContent->addContentEventListener( m_xContentEventListener );
1134 #if OSL_DEBUG_LEVEL > 1
1135 // Only done on demand in product version for performance reasons,
1136 // but a nice debug helper.
1137 getURL();
1138 #endif
1140 else
1142 // We need m_xContent's URL in order to be able to create the
1143 // content object again if demanded ( --> Content_Impl::getContent() )
1144 getURL();
1146 m_xContent = 0;
1150 //=========================================================================
1151 // virtual
1152 Content_Impl::~Content_Impl()
1154 if ( m_xContent.is() )
1158 m_xContent->removeContentEventListener( m_xContentEventListener );
1160 catch ( RuntimeException const & )
1166 //=========================================================================
1167 void Content_Impl::disposing( const EventObject& Source )
1169 Reference<XContent> xContent;
1172 osl::MutexGuard aGuard( m_aMutex );
1173 if(Source.Source != m_xContent)
1174 return;
1176 xContent = m_xContent;
1178 m_nCommandId = 0;
1179 m_aURL = rtl::OUString();
1180 m_xCommandProcessor = 0;
1181 m_xContent = 0;
1184 if ( xContent.is() )
1188 xContent->removeContentEventListener( m_xContentEventListener );
1190 catch ( RuntimeException const & )
1196 //=========================================================================
1197 const rtl::OUString& Content_Impl::getURL() const
1199 if ( m_aURL.isEmpty() && m_xContent.is() )
1201 osl::MutexGuard aGuard( m_aMutex );
1203 if ( m_aURL.isEmpty() && m_xContent.is() )
1205 Reference< XContentIdentifier > xId = m_xContent->getIdentifier();
1206 if ( xId.is() )
1207 m_aURL = xId->getContentIdentifier();
1211 return m_aURL;
1214 //=========================================================================
1215 Reference< XContent > Content_Impl::getContent()
1217 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1219 osl::MutexGuard aGuard( m_aMutex );
1221 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1223 Reference< XUniversalContentBroker > pBroker(
1224 UniversalContentBroker::create( getComponentContext() ) );
1226 OSL_ENSURE( pBroker->queryContentProviders().getLength(),
1227 "Content Broker not configured (no providers)!" );
1229 Reference< XContentIdentifier > xId
1230 = pBroker->createContentIdentifier( m_aURL );
1232 OSL_ENSURE( xId.is(), "No Content Identifier!" );
1234 if ( xId.is() )
1238 m_xContent = pBroker->queryContent( xId );
1240 catch ( IllegalIdentifierException const & )
1244 if ( m_xContent.is() )
1245 m_xContent->addContentEventListener(
1246 m_xContentEventListener );
1251 return m_xContent;
1254 //=========================================================================
1255 Reference< XCommandProcessor > Content_Impl::getCommandProcessor()
1257 if ( !m_xCommandProcessor.is() )
1259 osl::MutexGuard aGuard( m_aMutex );
1261 if ( !m_xCommandProcessor.is() )
1262 m_xCommandProcessor
1263 = Reference< XCommandProcessor >( getContent(), UNO_QUERY );
1266 return m_xCommandProcessor;
1269 //=========================================================================
1270 sal_Int32 Content_Impl::getCommandId()
1272 if ( m_nCommandId == 0 )
1274 osl::MutexGuard aGuard( m_aMutex );
1276 if ( m_nCommandId == 0 )
1278 Reference< XCommandProcessor > xProc = getCommandProcessor();
1279 if ( xProc.is() )
1280 m_nCommandId = xProc->createCommandIdentifier();
1284 return m_nCommandId;
1287 //=========================================================================
1288 Any Content_Impl::executeCommand( const Command& rCommand )
1290 Reference< XCommandProcessor > xProc = getCommandProcessor();
1291 if ( !xProc.is() )
1292 return Any();
1294 // Execute command
1295 return xProc->execute( rCommand, getCommandId(), m_xEnv );
1298 //=========================================================================
1299 inline const Reference< XCommandEnvironment >&
1300 Content_Impl::getEnvironment() const
1302 return m_xEnv;
1305 //=========================================================================
1306 inline void Content_Impl::setEnvironment(
1307 const Reference< XCommandEnvironment >& xNewEnv )
1309 osl::MutexGuard aGuard( m_aMutex );
1310 m_xEnv = xNewEnv;
1313 //=========================================================================
1314 void Content_Impl::inserted()
1316 // URL might have changed during 'insert' => recalculate in next getURL()
1317 osl::MutexGuard aGuard( m_aMutex );
1318 m_aURL = ::rtl::OUString();
1321 //=========================================================================
1322 //=========================================================================
1324 // ContentEventListener_Impl Implementation.
1326 //=========================================================================
1327 //=========================================================================
1329 //=========================================================================
1331 // XInterface methods.
1333 //=========================================================================
1335 XINTERFACE_IMPL_2( ContentEventListener_Impl,
1336 XContentEventListener,
1337 XEventListener ); /* base of XContentEventListener */
1339 //=========================================================================
1341 // XContentEventListener methods.
1343 //=========================================================================
1345 // virtual
1346 void SAL_CALL ContentEventListener_Impl::contentEvent( const ContentEvent& evt )
1347 throw( RuntimeException )
1349 if ( evt.Source == m_rContent.m_xContent )
1351 switch ( evt.Action )
1353 case ContentAction::DELETED:
1354 m_rContent.reinit( Reference< XContent >() );
1355 break;
1357 case ContentAction::EXCHANGED:
1358 m_rContent.reinit( evt.Content );
1359 break;
1361 default:
1362 break;
1367 //=========================================================================
1369 // XEventListenr methods.
1371 //=========================================================================
1373 // virtual
1374 void SAL_CALL ContentEventListener_Impl::disposing( const EventObject& Source )
1375 throw( RuntimeException )
1377 m_rContent.disposing(Source);
1380 } /* namespace ucbhelper */
1382 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */