fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucbhelper / source / client / content.cxx
blobf0f0572dc6ea589db66b73b8e01eb6cd47f875ba
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 <sal/log.hxx>
27 #include <salhelper/simplereferenceobject.hxx>
28 #include <cppuhelper/weak.hxx>
30 #include <cppuhelper/implbase1.hxx>
31 #include <com/sun/star/ucb/CheckinArgument.hpp>
32 #include <com/sun/star/ucb/ContentCreationError.hpp>
33 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
34 #include <com/sun/star/ucb/XCommandInfo.hpp>
35 #include <com/sun/star/ucb/XCommandProcessor.hpp>
36 #include <com/sun/star/ucb/Command.hpp>
37 #include <com/sun/star/ucb/CommandInfo.hpp>
38 #include <com/sun/star/ucb/ContentAction.hpp>
39 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
40 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
41 #include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
42 #include <com/sun/star/ucb/NameClash.hpp>
43 #include <com/sun/star/ucb/OpenMode.hpp>
44 #include <com/sun/star/ucb/XContentCreator.hpp>
45 #include <com/sun/star/ucb/XContentEventListener.hpp>
46 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
47 #include <com/sun/star/ucb/XContentProvider.hpp>
48 #include <com/sun/star/ucb/XContentProviderManager.hpp>
49 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
50 #include <com/sun/star/ucb/SortedDynamicResultSetFactory.hpp>
51 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
52 #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
53 #include <com/sun/star/beans/XPropertySetInfo.hpp>
54 #include <com/sun/star/beans/Property.hpp>
55 #include <com/sun/star/beans/PropertyValue.hpp>
56 #include <com/sun/star/sdbc/XResultSet.hpp>
57 #include <com/sun/star/sdbc/XRow.hpp>
58 #include <com/sun/star/lang/IllegalArgumentException.hpp>
59 #include <com/sun/star/beans/UnknownPropertyException.hpp>
60 #include <ucbhelper/macros.hxx>
61 #include <ucbhelper/content.hxx>
62 #include <ucbhelper/activedatasink.hxx>
63 #include <ucbhelper/activedatastreamer.hxx>
64 #include <ucbhelper/interactionrequest.hxx>
65 #include <ucbhelper/cancelcommandexecution.hxx>
67 using namespace com::sun::star::container;
68 using namespace com::sun::star::beans;
69 using namespace com::sun::star::io;
70 using namespace com::sun::star::lang;
71 using namespace com::sun::star::sdbc;
72 using namespace com::sun::star::task;
73 using namespace com::sun::star::ucb;
74 using namespace com::sun::star::uno;
76 namespace ucbhelper
79 class EmptyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
81 public:
82 virtual sal_Int32 SAL_CALL readBytes(
83 Sequence< sal_Int8 > & data, sal_Int32 nBytesToRead )
84 throw (IOException, RuntimeException, std::exception) SAL_OVERRIDE;
85 virtual sal_Int32 SAL_CALL readSomeBytes(
86 Sequence< sal_Int8 > & data, sal_Int32 nMaxBytesToRead )
87 throw (IOException, RuntimeException, std::exception) SAL_OVERRIDE;
88 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
89 throw (IOException, RuntimeException, std::exception) SAL_OVERRIDE;
90 virtual sal_Int32 SAL_CALL available()
91 throw (IOException, RuntimeException, std::exception) SAL_OVERRIDE;
92 virtual void SAL_CALL closeInput()
93 throw (IOException, RuntimeException, std::exception) SAL_OVERRIDE;
96 sal_Int32 EmptyInputStream::readBytes(
97 Sequence< sal_Int8 > & data, sal_Int32 )
98 throw (IOException, RuntimeException, std::exception)
100 data.realloc( 0 );
101 return 0;
104 sal_Int32 EmptyInputStream::readSomeBytes(
105 Sequence< sal_Int8 > & data, sal_Int32 )
106 throw (IOException, RuntimeException, std::exception)
108 data.realloc( 0 );
109 return 0;
112 void EmptyInputStream::skipBytes( sal_Int32 )
113 throw (IOException, RuntimeException, std::exception)
117 sal_Int32 EmptyInputStream::available()
118 throw (IOException, RuntimeException, std::exception)
120 return 0;
123 void EmptyInputStream::closeInput()
124 throw (IOException, RuntimeException, std::exception)
132 // class ContentEventListener_Impl.
137 class ContentEventListener_Impl : public cppu::OWeakObject,
138 public XContentEventListener
140 Content_Impl& m_rContent;
142 public:
143 ContentEventListener_Impl( Content_Impl& rContent )
144 : m_rContent( rContent ) {}
146 // XInterface
147 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType )
148 throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
149 virtual void SAL_CALL acquire()
150 throw() SAL_OVERRIDE;
151 virtual void SAL_CALL release()
152 throw() SAL_OVERRIDE;
154 // XContentEventListener
155 virtual void SAL_CALL contentEvent( const ContentEvent& evt )
156 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
158 // XEventListener ( base of XContentEventListener )
159 virtual void SAL_CALL disposing( const EventObject& Source )
160 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
166 // class Content_Impl.
171 class Content_Impl : public salhelper::SimpleReferenceObject
173 friend class ContentEventListener_Impl;
175 mutable OUString m_aURL;
176 Reference< XComponentContext > m_xCtx;
177 Reference< XContent > m_xContent;
178 Reference< XCommandProcessor > m_xCommandProcessor;
179 Reference< XCommandEnvironment > m_xEnv;
180 Reference< XContentEventListener > m_xContentEventListener;
181 mutable osl::Mutex m_aMutex;
183 private:
184 void reinit( const Reference< XContent >& xContent );
185 void disposing(const EventObject& Source);
187 public:
188 Content_Impl() {};
189 Content_Impl( const Reference< XComponentContext >& rCtx,
190 const Reference< XContent >& rContent,
191 const Reference< XCommandEnvironment >& rEnv );
193 virtual ~Content_Impl();
195 const OUString& getURL() const;
196 Reference< XContent > getContent();
197 Reference< XCommandProcessor > getCommandProcessor();
198 Reference< XComponentContext > getComponentContext()
199 { assert(m_xCtx.is()); return m_xCtx; }
201 Any executeCommand( const Command& rCommand );
203 inline const Reference< XCommandEnvironment >& getEnvironment() const;
204 inline void setEnvironment(
205 const Reference< XCommandEnvironment >& xNewEnv );
207 void inserted();
211 // Helpers.
214 static void ensureContentProviderForURL( const Reference< XUniversalContentBroker >& rBroker,
215 const OUString & rURL )
216 throw ( ContentCreationException, RuntimeException )
218 Reference< XContentProvider > xProv
219 = rBroker->queryContentProvider( rURL );
220 if ( !xProv.is() )
222 throw ContentCreationException(
223 "No Content Provider available for URL: " + rURL,
224 Reference< XInterface >(),
225 ContentCreationError_NO_CONTENT_PROVIDER );
230 static Reference< XContentIdentifier > getContentIdentifierThrow(
231 const Reference< XUniversalContentBroker > & rBroker,
232 const OUString & rURL)
233 throw (ContentCreationException, RuntimeException)
235 Reference< XContentIdentifier > xId
236 = rBroker->createContentIdentifier( rURL );
238 if (!xId.is())
240 ensureContentProviderForURL( rBroker, rURL );
242 throw ContentCreationException(
243 "Unable to create Content Identifier!",
244 Reference< XInterface >(),
245 ContentCreationError_IDENTIFIER_CREATION_FAILED );
248 return xId;
251 static Reference< XContentIdentifier > getContentIdentifierNoThrow(
252 const Reference< XUniversalContentBroker > & rBroker,
253 const OUString & rURL)
254 throw (RuntimeException)
256 return rBroker->createContentIdentifier(rURL);
259 static Reference< XContent > getContentThrow(
260 const Reference< XUniversalContentBroker > & rBroker,
261 const Reference< XContentIdentifier > & xId)
262 throw ( ContentCreationException, RuntimeException )
264 Reference< XContent > xContent;
265 OUString msg;
268 xContent = rBroker->queryContent( xId );
270 catch ( IllegalIdentifierException const & e )
272 msg = e.Message;
273 // handled below.
276 if ( !xContent.is() )
278 ensureContentProviderForURL( rBroker, xId->getContentIdentifier() );
280 throw ContentCreationException(
281 "Unable to create Content for <" + xId->getContentIdentifier() + ">: " + msg,
282 Reference< XInterface >(),
283 ContentCreationError_CONTENT_CREATION_FAILED );
286 return xContent;
290 static Reference< XContent > getContentNoThrow(
291 const Reference< XUniversalContentBroker > & rBroker,
292 const Reference< XContentIdentifier > & xId)
293 throw ( RuntimeException )
295 Reference< XContent > xContent;
298 xContent = rBroker->queryContent( xId );
300 catch ( IllegalIdentifierException const & e )
302 SAL_WARN("ucbhelper", "getContentNoThrow: exception: " << e.Message);
305 return xContent;
311 // Content Implementation.
316 Content::Content()
317 : m_xImpl( new Content_Impl )
322 Content::Content( const OUString& rURL,
323 const Reference< XCommandEnvironment >& rEnv,
324 const Reference< XComponentContext >& rCtx )
325 throw ( ContentCreationException, RuntimeException )
327 Reference< XUniversalContentBroker > pBroker(
328 UniversalContentBroker::create( rCtx ) );
330 Reference< XContentIdentifier > xId
331 = getContentIdentifierThrow(pBroker, rURL);
333 Reference< XContent > xContent = getContentThrow(pBroker, xId);
335 m_xImpl = new Content_Impl( rCtx, xContent, rEnv );
339 Content::Content( const Reference< XContent >& rContent,
340 const Reference< XCommandEnvironment >& rEnv,
341 const Reference< XComponentContext >& rCtx )
342 throw ( ContentCreationException, RuntimeException )
344 m_xImpl = new Content_Impl( rCtx, rContent, rEnv );
348 Content::Content( const Content& rOther )
350 m_xImpl = rOther.m_xImpl;
354 // static
355 bool Content::create( const OUString& rURL,
356 const Reference< XCommandEnvironment >& rEnv,
357 const Reference< XComponentContext >& rCtx,
358 Content& rContent )
360 Reference< XUniversalContentBroker > pBroker(
361 UniversalContentBroker::create( rCtx ) );
363 Reference< XContentIdentifier > xId
364 = getContentIdentifierNoThrow(pBroker, rURL);
365 if ( !xId.is() )
366 return false;
368 Reference< XContent > xContent = getContentNoThrow(pBroker, xId);
369 if ( !xContent.is() )
370 return false;
372 rContent.m_xImpl
373 = new Content_Impl( rCtx, xContent, rEnv );
375 return true;
379 Content::~Content()
384 Content& Content::operator=( const Content& rOther )
386 m_xImpl = rOther.m_xImpl;
387 return *this;
391 Reference< XContent > Content::get() const
393 return m_xImpl->getContent();
397 const OUString& Content::getURL() const
399 return m_xImpl->getURL();
403 const Reference< XCommandEnvironment >& Content::getCommandEnvironment() const
405 return m_xImpl->getEnvironment();
409 void Content::setCommandEnvironment(
410 const Reference< XCommandEnvironment >& xNewEnv )
412 m_xImpl->setEnvironment( xNewEnv );
416 Reference< XCommandInfo > Content::getCommands()
417 throw( CommandAbortedException, RuntimeException, Exception )
419 Command aCommand;
420 aCommand.Name = "getCommandInfo";
421 aCommand.Handle = -1; // n/a
422 aCommand.Argument = Any();
424 Any aResult = m_xImpl->executeCommand( aCommand );
426 Reference< XCommandInfo > xInfo;
427 aResult >>= xInfo;
428 return xInfo;
432 Reference< XPropertySetInfo > Content::getProperties()
433 throw( CommandAbortedException, RuntimeException, Exception )
435 Command aCommand;
436 aCommand.Name = "getPropertySetInfo";
437 aCommand.Handle = -1; // n/a
438 aCommand.Argument = Any();
440 Any aResult = m_xImpl->executeCommand( aCommand );
442 Reference< XPropertySetInfo > xInfo;
443 aResult >>= xInfo;
444 return xInfo;
448 Any Content::getPropertyValue( const OUString& rPropertyName )
449 throw( CommandAbortedException, RuntimeException, Exception )
451 Sequence< OUString > aNames( 1 );
452 aNames.getArray()[ 0 ] = rPropertyName;
454 Sequence< Any > aRet = getPropertyValues( aNames );
455 return aRet.getConstArray()[ 0 ];
459 Any Content::setPropertyValue( const OUString& rName,
460 const Any& rValue )
461 throw( CommandAbortedException, RuntimeException, Exception )
463 Sequence< OUString > aNames( 1 );
464 aNames.getArray()[ 0 ] = rName;
466 Sequence< Any > aValues( 1 );
467 aValues.getArray()[ 0 ] = rValue;
469 Sequence< Any > aErrors = setPropertyValues( aNames, aValues );
470 return aErrors.getConstArray()[ 0 ];
474 Sequence< Any > Content::getPropertyValues(
475 const Sequence< OUString >& rPropertyNames )
476 throw( CommandAbortedException, RuntimeException, Exception )
478 Reference< XRow > xRow = getPropertyValuesInterface( rPropertyNames );
480 sal_Int32 nCount = rPropertyNames.getLength();
481 Sequence< Any > aValues( nCount );
483 if ( xRow.is() )
485 Any* pValues = aValues.getArray();
487 for ( sal_Int32 n = 0; n < nCount; ++n )
488 pValues[ n ] = xRow->getObject( n + 1, Reference< XNameAccess >() );
491 return aValues;
495 Reference< XRow > Content::getPropertyValuesInterface(
496 const Sequence< OUString >& rPropertyNames )
497 throw( CommandAbortedException, RuntimeException, Exception )
499 sal_Int32 nCount = rPropertyNames.getLength();
500 Sequence< Property > aProps( nCount );
501 Property* pProps = aProps.getArray();
503 const OUString* pNames = rPropertyNames.getConstArray();
505 for ( sal_Int32 n = 0; n< nCount; ++n )
507 Property& rProp = pProps[ n ];
509 rProp.Name = pNames[ n ];
510 rProp.Handle = -1; // n/a
511 // rProp.Type =
512 // rProp.Attributes = ;
515 Command aCommand;
516 aCommand.Name = "getPropertyValues";
517 aCommand.Handle = -1; // n/a
518 aCommand.Argument <<= aProps;
520 Any aResult = m_xImpl->executeCommand( aCommand );
522 Reference< XRow > xRow;
523 aResult >>= xRow;
524 return xRow;
528 Sequence< Any > Content::setPropertyValues(
529 const Sequence< OUString >& rPropertyNames,
530 const Sequence< Any >& rValues )
531 throw( CommandAbortedException, RuntimeException, Exception )
533 if ( rPropertyNames.getLength() != rValues.getLength() )
535 ucbhelper::cancelCommandExecution(
536 makeAny( IllegalArgumentException(
537 OUString(
538 "Length of property names sequence and value "
539 "sequence are unequal!" ),
540 get(),
541 -1 ) ),
542 m_xImpl->getEnvironment() );
543 // Unreachable
546 sal_Int32 nCount = rValues.getLength();
547 Sequence< PropertyValue > aProps( nCount );
548 PropertyValue* pProps = aProps.getArray();
550 const OUString* pNames = rPropertyNames.getConstArray();
551 const Any* pValues = rValues.getConstArray();
553 for ( sal_Int32 n = 0; n< nCount; ++n )
555 PropertyValue& rProp = pProps[ n ];
557 rProp.Name = pNames[ n ];
558 rProp.Handle = -1; // n/a
559 rProp.Value = pValues[ n ];
560 // rProp.State = ;
563 Command aCommand;
564 aCommand.Name = "setPropertyValues";
565 aCommand.Handle = -1; // n/a
566 aCommand.Argument <<= aProps;
568 Any aResult = m_xImpl->executeCommand( aCommand );
570 Sequence< Any > aErrors;
571 aResult >>= aErrors;
572 return aErrors;
576 Any Content::executeCommand( const OUString& rCommandName,
577 const Any& rCommandArgument )
578 throw( CommandAbortedException, RuntimeException, Exception )
580 Command aCommand;
581 aCommand.Name = rCommandName;
582 aCommand.Handle = -1; // n/a
583 aCommand.Argument = rCommandArgument;
585 return m_xImpl->executeCommand( aCommand );
589 Any Content::createCursorAny( const Sequence< OUString >& rPropertyNames,
590 ResultSetInclude eMode )
591 throw( CommandAbortedException, RuntimeException, Exception )
593 sal_Int32 nCount = rPropertyNames.getLength();
594 Sequence< Property > aProps( nCount );
595 Property* pProps = aProps.getArray();
596 const OUString* pNames = rPropertyNames.getConstArray();
597 for ( sal_Int32 n = 0; n < nCount; ++n )
599 Property& rProp = pProps[ n ];
600 rProp.Name = pNames[ n ];
601 rProp.Handle = -1; // n/a
604 OpenCommandArgument2 aArg;
605 aArg.Mode = ( eMode == INCLUDE_FOLDERS_ONLY )
606 ? OpenMode::FOLDERS
607 : ( eMode == INCLUDE_DOCUMENTS_ONLY )
608 ? OpenMode::DOCUMENTS : OpenMode::ALL;
609 aArg.Priority = 0; // unused
610 aArg.Sink.clear(); // unused
611 aArg.Properties = aProps;
613 Command aCommand;
614 aCommand.Name = "open";
615 aCommand.Handle = -1; // n/a
616 aCommand.Argument <<= aArg;
618 return m_xImpl->executeCommand( aCommand );
622 Reference< XResultSet > Content::createCursor(
623 const Sequence< OUString >& rPropertyNames,
624 ResultSetInclude eMode )
625 throw( CommandAbortedException, RuntimeException, Exception )
627 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
629 Reference< XDynamicResultSet > xDynSet;
630 Reference< XResultSet > aResult;
632 aCursorAny >>= xDynSet;
633 if ( xDynSet.is() )
634 aResult = xDynSet->getStaticResultSet();
636 OSL_ENSURE( aResult.is(), "Content::createCursor - no cursor!" );
638 if ( !aResult.is() )
640 // Former, the open command directly returned a XResultSet.
641 aCursorAny >>= aResult;
643 OSL_ENSURE( !aResult.is(),
644 "Content::createCursor - open-Command must "
645 "return a Reference< XDynnamicResultSet >!" );
648 return aResult;
652 Reference< XDynamicResultSet > Content::createDynamicCursor(
653 const Sequence< OUString >& rPropertyNames,
654 ResultSetInclude eMode )
655 throw( CommandAbortedException, RuntimeException, Exception )
657 Reference< XDynamicResultSet > aResult;
658 createCursorAny( rPropertyNames, eMode ) >>= aResult;
660 OSL_ENSURE( aResult.is(), "Content::createDynamicCursor - no cursor!" );
662 return aResult;
666 Reference< XResultSet > Content::createSortedCursor(
667 const Sequence< OUString >& rPropertyNames,
668 const Sequence< NumberedSortingInfo >& rSortInfo,
669 Reference< XAnyCompareFactory > rAnyCompareFactory,
670 ResultSetInclude eMode )
671 throw( CommandAbortedException, RuntimeException, Exception )
673 Reference< XResultSet > aResult;
674 Reference< XDynamicResultSet > aDynSet;
676 Any aCursorAny = createCursorAny( rPropertyNames, eMode );
678 aCursorAny >>= aDynSet;
680 if( aDynSet.is() )
682 Reference< XDynamicResultSet > aDynResult;
684 if( m_xImpl->getComponentContext().is() )
686 Reference< XSortedDynamicResultSetFactory > aSortFactory =
687 SortedDynamicResultSetFactory::create( m_xImpl->getComponentContext());
689 aDynResult = aSortFactory->createSortedDynamicResultSet( aDynSet,
690 rSortInfo,
691 rAnyCompareFactory );
694 OSL_ENSURE( aDynResult.is(), "Content::createSortedCursor - no sorted cursor!\n" );
696 if( aDynResult.is() )
697 aResult = aDynResult->getStaticResultSet();
698 else
699 aResult = aDynSet->getStaticResultSet();
702 OSL_ENSURE( aResult.is(), "Content::createSortedCursor - no cursor!" );
704 if ( !aResult.is() )
706 // Former, the open command directly returned a XResultSet.
707 aCursorAny >>= aResult;
709 OSL_ENSURE( !aResult.is(),
710 "Content::createCursor - open-Command must "
711 "return a Reference< XDynnamicResultSet >!" );
714 return aResult;
718 Reference< XInputStream > Content::openStream()
719 throw( CommandAbortedException, RuntimeException, Exception )
721 if ( !isDocument() )
722 return Reference< XInputStream >();
724 Reference< XActiveDataSink > xSink = new ActiveDataSink;
726 OpenCommandArgument2 aArg;
727 aArg.Mode = OpenMode::DOCUMENT;
728 aArg.Priority = 0; // unused
729 aArg.Sink = xSink;
730 aArg.Properties = Sequence< Property >( 0 ); // unused
732 Command aCommand;
733 aCommand.Name = "open";
734 aCommand.Handle = -1; // n/a
735 aCommand.Argument <<= aArg;
737 m_xImpl->executeCommand( aCommand );
739 return xSink->getInputStream();
743 Reference< XInputStream > Content::openStreamNoLock()
744 throw( CommandAbortedException, RuntimeException, Exception )
746 if ( !isDocument() )
747 return Reference< XInputStream >();
749 Reference< XActiveDataSink > xSink = new ActiveDataSink;
751 OpenCommandArgument2 aArg;
752 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
753 aArg.Priority = 0; // unused
754 aArg.Sink = xSink;
755 aArg.Properties = Sequence< Property >( 0 ); // unused
757 Command aCommand;
758 aCommand.Name = "open";
759 aCommand.Handle = -1; // n/a
760 aCommand.Argument <<= aArg;
762 m_xImpl->executeCommand( aCommand );
764 return xSink->getInputStream();
768 Reference< XStream > Content::openWriteableStream()
769 throw( CommandAbortedException, RuntimeException, Exception )
771 if ( !isDocument() )
772 return Reference< XStream >();
774 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
776 OpenCommandArgument2 aArg;
777 aArg.Mode = OpenMode::DOCUMENT;
778 aArg.Priority = 0; // unused
779 aArg.Sink = xStreamer;
780 aArg.Properties = Sequence< Property >( 0 ); // unused
782 Command aCommand;
783 aCommand.Name = "open";
784 aCommand.Handle = -1; // n/a
785 aCommand.Argument <<= aArg;
787 m_xImpl->executeCommand( aCommand );
789 return xStreamer->getStream();
793 Reference< XStream > Content::openWriteableStreamNoLock()
794 throw( CommandAbortedException, RuntimeException, Exception )
796 if ( !isDocument() )
797 return Reference< XStream >();
799 Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
801 OpenCommandArgument2 aArg;
802 aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE;
803 aArg.Priority = 0; // unused
804 aArg.Sink = xStreamer;
805 aArg.Properties = Sequence< Property >( 0 ); // unused
807 Command aCommand;
808 aCommand.Name = "open";
809 aCommand.Handle = -1; // n/a
810 aCommand.Argument <<= aArg;
812 m_xImpl->executeCommand( aCommand );
814 return xStreamer->getStream();
818 bool Content::openStream( const Reference< XActiveDataSink >& rSink )
819 throw( CommandAbortedException, RuntimeException, Exception )
821 if ( !isDocument() )
822 return false;
824 OpenCommandArgument2 aArg;
825 aArg.Mode = OpenMode::DOCUMENT;
826 aArg.Priority = 0; // unused
827 aArg.Sink = rSink;
828 aArg.Properties = Sequence< Property >( 0 ); // unused
830 Command aCommand;
831 aCommand.Name = "open";
832 aCommand.Handle = -1; // n/a
833 aCommand.Argument <<= aArg;
835 m_xImpl->executeCommand( aCommand );
837 return true;
841 bool Content::openStream( const Reference< XOutputStream >& rStream )
842 throw( CommandAbortedException, RuntimeException, Exception )
844 if ( !isDocument() )
845 return false;
847 OpenCommandArgument2 aArg;
848 aArg.Mode = OpenMode::DOCUMENT;
849 aArg.Priority = 0; // unused
850 aArg.Sink = rStream;
851 aArg.Properties = Sequence< Property >( 0 ); // unused
853 Command aCommand;
854 aCommand.Name = "open";
855 aCommand.Handle = -1; // n/a
856 aCommand.Argument <<= aArg;
858 m_xImpl->executeCommand( aCommand );
860 return true;
864 void Content::writeStream( const Reference< XInputStream >& rStream,
865 bool bReplaceExisting )
866 throw( CommandAbortedException, RuntimeException, Exception )
868 InsertCommandArgument aArg;
869 aArg.Data = rStream.is() ? rStream : new EmptyInputStream;
870 aArg.ReplaceExisting = bReplaceExisting;
872 Command aCommand;
873 aCommand.Name = "insert";
874 aCommand.Handle = -1; // n/a
875 aCommand.Argument <<= aArg;
877 m_xImpl->executeCommand( aCommand );
879 m_xImpl->inserted();
883 Sequence< ContentInfo > Content::queryCreatableContentsInfo()
884 throw( CommandAbortedException, RuntimeException, Exception )
886 // First, try it using "CreatableContentsInfo" property -> the "new" way.
887 Sequence< ContentInfo > aInfo;
888 if ( getPropertyValue(
889 OUString("CreatableContentsInfo") )
890 >>= aInfo )
891 return aInfo;
893 // Second, try it using XContentCreator interface -> the "old" way (not
894 // providing the chance to supply an XCommandEnvironment.
895 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
896 if ( xCreator.is() )
897 aInfo = xCreator->queryCreatableContentsInfo();
899 return aInfo;
903 bool Content::insertNewContent( const OUString& rContentType,
904 const Sequence< OUString >&
905 rPropertyNames,
906 const Sequence< Any >& rPropertyValues,
907 Content& rNewContent )
908 throw( CommandAbortedException, RuntimeException, Exception )
910 return insertNewContent( rContentType,
911 rPropertyNames,
912 rPropertyValues,
913 new EmptyInputStream,
914 rNewContent );
918 bool Content::insertNewContent( const OUString& rContentType,
919 const Sequence< OUString >&
920 rPropertyNames,
921 const Sequence< Any >& rPropertyValues,
922 const Reference< XInputStream >& rData,
923 Content& rNewContent )
924 throw( CommandAbortedException, RuntimeException, Exception )
926 if ( rContentType.isEmpty() )
927 return false;
929 // First, try it using "createNewContent" command -> the "new" way.
930 ContentInfo aInfo;
931 aInfo.Type = rContentType;
932 aInfo.Attributes = 0;
934 Command aCommand;
935 aCommand.Name = "createNewContent";
936 aCommand.Handle = -1; // n/a
937 aCommand.Argument <<= aInfo;
939 Reference< XContent > xNew;
942 m_xImpl->executeCommand( aCommand ) >>= xNew;
944 catch ( RuntimeException const & )
946 throw;
948 catch ( Exception const & )
952 if ( !xNew.is() )
954 // Second, try it using XContentCreator interface -> the "old"
955 // way (not providing the chance to supply an XCommandEnvironment.
956 Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
958 if ( !xCreator.is() )
959 return false;
961 xNew = xCreator->createNewContent( aInfo );
963 if ( !xNew.is() )
964 return false;
967 Content aNewContent(
968 xNew, m_xImpl->getEnvironment(), m_xImpl->getComponentContext() );
969 aNewContent.setPropertyValues( rPropertyNames, rPropertyValues );
970 aNewContent.executeCommand( OUString("insert"),
971 makeAny(
972 InsertCommandArgument(
973 rData.is() ? rData : new EmptyInputStream,
974 sal_False /* ReplaceExisting */ ) ) );
975 aNewContent.m_xImpl->inserted();
977 rNewContent = aNewContent;
978 return true;
982 bool Content::transferContent( const Content& rSourceContent,
983 InsertOperation eOperation,
984 const OUString & rTitle,
985 const sal_Int32 nNameClashAction,
986 const OUString & rMimeType,
987 bool bMajorVersion,
988 const OUString & rVersionComment,
989 OUString* pResultURL,
990 const OUString & rDocumentId )
991 throw( CommandAbortedException, RuntimeException, Exception )
993 Reference< XUniversalContentBroker > pBroker(
994 UniversalContentBroker::create( m_xImpl->getComponentContext() ) );
996 // Execute command "globalTransfer" at UCB.
998 TransferCommandOperation eTransOp = TransferCommandOperation();
999 OUString sCommand( "globalTransfer" );
1000 bool bCheckIn = false;
1001 switch ( eOperation )
1003 case InsertOperation_COPY:
1004 eTransOp = TransferCommandOperation_COPY;
1005 break;
1007 case InsertOperation_MOVE:
1008 eTransOp = TransferCommandOperation_MOVE;
1009 break;
1011 case InsertOperation_LINK:
1012 eTransOp = TransferCommandOperation_LINK;
1013 break;
1015 case InsertOperation_CHECKIN:
1016 eTransOp = TransferCommandOperation_COPY;
1017 sCommand = "checkin";
1018 bCheckIn = true;
1019 break;
1021 Command aCommand;
1022 aCommand.Name = sCommand;
1023 aCommand.Handle = -1; // n/a
1025 if ( !bCheckIn )
1027 GlobalTransferCommandArgument2 aTransferArg(
1028 eTransOp,
1029 rSourceContent.getURL(), // SourceURL
1030 getURL(), // TargetFolderURL,
1031 rTitle,
1032 nNameClashAction,
1033 rMimeType,
1034 rDocumentId );
1035 aCommand.Argument <<= aTransferArg;
1037 else
1039 CheckinArgument aCheckinArg( bMajorVersion, rVersionComment,
1040 rSourceContent.getURL(), getURL(), rTitle, rMimeType );
1041 aCommand.Argument <<= aCheckinArg;
1044 Any aRet = pBroker->execute( aCommand, 0, m_xImpl->getEnvironment() );
1045 if ( pResultURL != NULL )
1046 aRet >>= *pResultURL;
1047 return true;
1051 bool Content::isFolder()
1052 throw( CommandAbortedException, RuntimeException, Exception )
1054 bool bFolder = false;
1055 if ( getPropertyValue("IsFolder")
1056 >>= bFolder )
1057 return bFolder;
1059 ucbhelper::cancelCommandExecution(
1060 makeAny( UnknownPropertyException(
1061 OUString(
1062 "Unable to retrieve value of property 'IsFolder'!" ),
1063 get() ) ),
1064 m_xImpl->getEnvironment() );
1066 #if !(defined(_MSC_VER) && defined(ENABLE_LTO))
1067 // Unreachable - cancelCommandExecution always throws an exception.
1068 // But some compilers complain...
1069 return false;
1070 #endif
1075 SAL_WNOUNREACHABLE_CODE_PUSH
1077 bool Content::isDocument()
1078 throw( CommandAbortedException, RuntimeException, Exception )
1080 bool bDoc = false;
1081 if ( getPropertyValue("IsDocument")
1082 >>= bDoc )
1083 return bDoc;
1085 ucbhelper::cancelCommandExecution(
1086 makeAny( UnknownPropertyException(
1087 OUString(
1088 "Unable to retrieve value of property 'IsDocument'!" ),
1089 get() ) ),
1090 m_xImpl->getEnvironment() );
1092 // Unreachable - cancelCommandExecution always throws an exception,
1093 // But some compilers complain...
1094 return false;
1097 SAL_WNOUNREACHABLE_CODE_POP
1102 // Content_Impl Implementation.
1107 Content_Impl::Content_Impl( const Reference< XComponentContext >& rCtx,
1108 const Reference< XContent >& rContent,
1109 const Reference< XCommandEnvironment >& rEnv )
1110 : m_xCtx( rCtx ),
1111 m_xContent( rContent ),
1112 m_xEnv( rEnv )
1114 assert(rCtx.is());
1115 if ( m_xContent.is() )
1117 m_xContentEventListener = new ContentEventListener_Impl( *this );
1118 m_xContent->addContentEventListener( m_xContentEventListener );
1120 #if OSL_DEBUG_LEVEL > 1
1121 // Only done on demand in product version for performance reasons,
1122 // but a nice debug helper.
1123 getURL();
1124 #endif
1129 void Content_Impl::reinit( const Reference< XContent >& xContent )
1131 osl::MutexGuard aGuard( m_aMutex );
1133 m_xCommandProcessor = 0;
1135 // #92581# - Don't reset m_aURL!!!
1137 if ( m_xContent.is() )
1141 m_xContent->removeContentEventListener( m_xContentEventListener );
1143 catch ( RuntimeException const & )
1148 if ( xContent.is() )
1150 m_xContent = xContent;
1151 m_xContent->addContentEventListener( m_xContentEventListener );
1153 #if OSL_DEBUG_LEVEL > 1
1154 // Only done on demand in product version for performance reasons,
1155 // but a nice debug helper.
1156 getURL();
1157 #endif
1159 else
1161 // We need m_xContent's URL in order to be able to create the
1162 // content object again if demanded ( --> Content_Impl::getContent() )
1163 getURL();
1165 m_xContent = 0;
1170 // virtual
1171 Content_Impl::~Content_Impl()
1173 if ( m_xContent.is() )
1177 m_xContent->removeContentEventListener( m_xContentEventListener );
1179 catch ( RuntimeException const & )
1186 void Content_Impl::disposing( const EventObject& Source )
1188 Reference<XContent> xContent;
1191 osl::MutexGuard aGuard( m_aMutex );
1192 if(Source.Source != m_xContent)
1193 return;
1195 xContent = m_xContent;
1197 m_aURL.clear();
1198 m_xCommandProcessor = 0;
1199 m_xContent = 0;
1202 if ( xContent.is() )
1206 xContent->removeContentEventListener( m_xContentEventListener );
1208 catch ( RuntimeException const & )
1215 const OUString& Content_Impl::getURL() const
1217 if ( m_aURL.isEmpty() && m_xContent.is() )
1219 osl::MutexGuard aGuard( m_aMutex );
1221 if ( m_aURL.isEmpty() && m_xContent.is() )
1223 Reference< XContentIdentifier > xId = m_xContent->getIdentifier();
1224 if ( xId.is() )
1225 m_aURL = xId->getContentIdentifier();
1229 return m_aURL;
1233 Reference< XContent > Content_Impl::getContent()
1235 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1237 osl::MutexGuard aGuard( m_aMutex );
1239 if ( !m_xContent.is() && !m_aURL.isEmpty() )
1241 Reference< XUniversalContentBroker > pBroker(
1242 UniversalContentBroker::create( getComponentContext() ) );
1244 OSL_ENSURE( pBroker->queryContentProviders().getLength(),
1245 "Content Broker not configured (no providers)!" );
1247 Reference< XContentIdentifier > xId
1248 = pBroker->createContentIdentifier( m_aURL );
1250 OSL_ENSURE( xId.is(), "No Content Identifier!" );
1252 if ( xId.is() )
1256 m_xContent = pBroker->queryContent( xId );
1258 catch ( IllegalIdentifierException const & )
1262 if ( m_xContent.is() )
1263 m_xContent->addContentEventListener(
1264 m_xContentEventListener );
1269 return m_xContent;
1273 Reference< XCommandProcessor > Content_Impl::getCommandProcessor()
1275 if ( !m_xCommandProcessor.is() )
1277 osl::MutexGuard aGuard( m_aMutex );
1279 if ( !m_xCommandProcessor.is() )
1280 m_xCommandProcessor
1281 = Reference< XCommandProcessor >( getContent(), UNO_QUERY );
1284 return m_xCommandProcessor;
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, 0, m_xEnv );
1299 inline const Reference< XCommandEnvironment >&
1300 Content_Impl::getEnvironment() const
1302 return m_xEnv;
1306 inline void Content_Impl::setEnvironment(
1307 const Reference< XCommandEnvironment >& xNewEnv )
1309 osl::MutexGuard aGuard( m_aMutex );
1310 m_xEnv = xNewEnv;
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.clear();
1324 // ContentEventListener_Impl Implementation.
1331 // XInterface methods.
1333 void SAL_CALL ContentEventListener_Impl::acquire()
1334 throw()
1336 OWeakObject::acquire();
1339 void SAL_CALL ContentEventListener_Impl::release()
1340 throw()
1342 OWeakObject::release();
1345 css::uno::Any SAL_CALL ContentEventListener_Impl::queryInterface( const css::uno::Type & rType )
1346 throw( css::uno::RuntimeException, std::exception )
1348 css::uno::Any aRet = cppu::queryInterface( rType,
1349 (static_cast< XContentEventListener* >(this)),
1350 (static_cast< XEventListener* >(this))
1352 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
1355 // XContentEventListener methods.
1359 // virtual
1360 void SAL_CALL ContentEventListener_Impl::contentEvent( const ContentEvent& evt )
1361 throw( RuntimeException, std::exception )
1363 if ( evt.Source == m_rContent.m_xContent )
1365 switch ( evt.Action )
1367 case ContentAction::DELETED:
1368 m_rContent.reinit( Reference< XContent >() );
1369 break;
1371 case ContentAction::EXCHANGED:
1372 m_rContent.reinit( evt.Content );
1373 break;
1375 default:
1376 break;
1383 // XEventListenr methods.
1387 // virtual
1388 void SAL_CALL ContentEventListener_Impl::disposing( const EventObject& Source )
1389 throw( RuntimeException, std::exception )
1391 m_rContent.disposing(Source);
1394 } /* namespace ucbhelper */
1396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */