1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 /**************************************************************************
22 **************************************************************************
24 *************************************************************************/
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/sdbc/XRow.hpp>
27 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
28 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
29 #include <com/sun/star/ucb/XCommandInfo.hpp>
30 #include <com/sun/star/io/XActiveDataSink.hpp>
31 #include <com/sun/star/io/XOutputStream.hpp>
32 #include <com/sun/star/lang/IllegalAccessException.hpp>
33 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
34 #include <com/sun/star/io/XActiveDataStreamer.hpp>
35 #include <ucbhelper/propertyvalueset.hxx>
36 #include <ucbhelper/cancelcommandexecution.hxx>
37 #include <ucbhelper/macros.hxx>
39 #include "content.hxx"
40 #include "provider.hxx"
41 #include "resultset.hxx"
42 #include "databases.hxx"
43 #include "resultsetfactory.hxx"
44 #include "resultsetbase.hxx"
45 #include "resultsetforroot.hxx"
46 #include "resultsetforquery.hxx"
48 using namespace com::sun::star
;
49 using namespace chelp
;
51 // Content Implementation.
53 Content::Content( const uno::Reference
< uno::XComponentContext
>& rxContext
,
54 ::ucbhelper::ContentProviderImplHelper
* pProvider
,
55 const uno::Reference
< ucb::XContentIdentifier
>&
57 Databases
* pDatabases
)
58 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
59 m_aURLParameter( Identifier
->getContentIdentifier(),pDatabases
),
60 m_pDatabases( pDatabases
) // not owner
70 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
)
73 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface( rType
);
76 // XTypeProvider methods.
78 XTYPEPROVIDER_COMMON_IMPL( Content
);
81 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
83 static cppu::OTypeCollection
ourTypeCollection(
84 CPPU_TYPE_REF( lang::XTypeProvider
),
85 CPPU_TYPE_REF( lang::XServiceInfo
),
86 CPPU_TYPE_REF( lang::XComponent
),
87 CPPU_TYPE_REF( ucb::XContent
),
88 CPPU_TYPE_REF( ucb::XCommandProcessor
),
89 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
90 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
91 CPPU_TYPE_REF( beans::XPropertyContainer
),
92 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
93 CPPU_TYPE_REF( container::XChild
) );
95 return ourTypeCollection
.getTypes();
98 // XServiceInfo methods.
101 OUString SAL_CALL
Content::getImplementationName()
103 return u
"CHelpContent"_ustr
;
107 uno::Sequence
< OUString
> SAL_CALL
Content::getSupportedServiceNames()
109 return { u
"com.sun.star.ucb.CHelpContent"_ustr
};
115 OUString SAL_CALL
Content::getContentType()
117 return MYUCP_CONTENT_TYPE
;
120 // XCommandProcessor methods.
123 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
129 class ResultSetForRootFactory
130 : public ResultSetFactory
134 uno::Reference
< uno::XComponentContext
> m_xContext
;
135 uno::Reference
< ucb::XContentProvider
> m_xProvider
;
136 uno::Sequence
< beans::Property
> m_seq
;
137 URLParameter m_aURLParameter
;
138 Databases
* m_pDatabases
;
142 ResultSetForRootFactory(
143 uno::Reference
< uno::XComponentContext
> xContext
,
144 uno::Reference
< ucb::XContentProvider
> xProvider
,
145 const uno::Sequence
< beans::Property
>& seq
,
146 const URLParameter
& rURLParameter
,
147 Databases
* pDatabases
)
148 : m_xContext(std::move( xContext
)),
149 m_xProvider(std::move( xProvider
)),
151 m_aURLParameter(rURLParameter
),
152 m_pDatabases( pDatabases
)
156 rtl::Reference
<ResultSetBase
> createResultSet() override
158 return new ResultSetForRoot( m_xContext
,
166 class ResultSetForQueryFactory
167 : public ResultSetFactory
171 uno::Reference
< uno::XComponentContext
> m_xContext
;
172 uno::Reference
< ucb::XContentProvider
> m_xProvider
;
173 uno::Sequence
< beans::Property
> m_seq
;
174 URLParameter m_aURLParameter
;
175 Databases
* m_pDatabases
;
179 ResultSetForQueryFactory(
180 uno::Reference
< uno::XComponentContext
> xContext
,
181 uno::Reference
< ucb::XContentProvider
> xProvider
,
182 const uno::Sequence
< beans::Property
>& seq
,
183 const URLParameter
& rURLParameter
,
184 Databases
* pDatabases
)
185 : m_xContext(std::move( xContext
)),
186 m_xProvider(std::move( xProvider
)),
188 m_aURLParameter(rURLParameter
),
189 m_pDatabases( pDatabases
)
193 rtl::Reference
<ResultSetBase
> createResultSet() override
195 return new ResultSetForQuery( m_xContext
,
206 uno::Any SAL_CALL
Content::execute(
207 const ucb::Command
& aCommand
,
209 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
213 if ( aCommand
.Name
== "getPropertyValues" )
215 uno::Sequence
< beans::Property
> Properties
;
216 if ( !( aCommand
.Argument
>>= Properties
) )
218 aRet
<<= lang::IllegalArgumentException();
219 ucbhelper::cancelCommandExecution(aRet
,Environment
);
222 aRet
<<= getPropertyValues( Properties
);
224 else if ( aCommand
.Name
== "setPropertyValues" )
226 uno::Sequence
<beans::PropertyValue
> propertyValues
;
228 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
229 aRet
<<= lang::IllegalArgumentException();
230 ucbhelper::cancelCommandExecution(aRet
,Environment
);
233 uno::Sequence
< uno::Any
> ret(propertyValues
.getLength());
234 const uno::Sequence
< beans::Property
> props(getProperties(Environment
));
235 // No properties can be set
236 std::transform(std::cbegin(propertyValues
), std::cend(propertyValues
), ret
.getArray(),
237 [&props
](const beans::PropertyValue
& rPropVal
) {
238 if (std::any_of(props
.begin(), props
.end(),
239 [&rPropVal
](const beans::Property
& rProp
) { return rProp
.Name
== rPropVal
.Name
; }))
240 return css::uno::toAny(lang::IllegalAccessException());
241 return css::uno::toAny(beans::UnknownPropertyException());
246 else if ( aCommand
.Name
== "getPropertySetInfo" )
248 // Note: Implemented by base class.
249 aRet
<<= getPropertySetInfo( Environment
);
251 else if ( aCommand
.Name
== "getCommandInfo" )
253 // Note: Implemented by base class.
254 aRet
<<= getCommandInfo( Environment
);
256 else if ( aCommand
.Name
== "open" )
258 ucb::OpenCommandArgument2 aOpenCommand
;
259 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
261 aRet
<<= lang::IllegalArgumentException();
262 ucbhelper::cancelCommandExecution(aRet
,Environment
);
265 uno::Reference
< io::XActiveDataSink
> xActiveDataSink(
266 aOpenCommand
.Sink
, uno::UNO_QUERY
);
268 if(xActiveDataSink
.is())
269 m_aURLParameter
.open(xActiveDataSink
);
271 uno::Reference
< io::XActiveDataStreamer
> xActiveDataStreamer(
272 aOpenCommand
.Sink
, uno::UNO_QUERY
);
274 if(xActiveDataStreamer
.is()) {
275 aRet
<<= ucb::UnsupportedDataSinkException();
276 ucbhelper::cancelCommandExecution(aRet
,Environment
);
279 uno::Reference
< io::XOutputStream
> xOutputStream(
280 aOpenCommand
.Sink
, uno::UNO_QUERY
);
282 if(xOutputStream
.is() )
283 m_aURLParameter
.open(xOutputStream
);
285 if( m_aURLParameter
.isRoot() )
287 uno::Reference
< ucb::XDynamicResultSet
> xSet
288 = new DynamicResultSet(
291 std::make_unique
<ResultSetForRootFactory
>(
294 aOpenCommand
.Properties
,
299 else if( m_aURLParameter
.isQuery() )
301 uno::Reference
< ucb::XDynamicResultSet
> xSet
302 = new DynamicResultSet(
305 std::make_unique
<ResultSetForQueryFactory
>(
308 aOpenCommand
.Properties
,
316 // Unsupported command
317 aRet
<<= ucb::UnsupportedCommandException();
318 ucbhelper::cancelCommandExecution(aRet
,Environment
);
324 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
325 const uno::Sequence
< beans::Property
>& rProperties
)
327 osl::MutexGuard
aGuard( m_aMutex
);
329 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
=
330 new ::ucbhelper::PropertyValueSet( m_xContext
);
332 for ( const beans::Property
& rProp
: rProperties
)
334 if ( rProp
.Name
== "ContentType" )
337 u
"application/vnd.sun.star.help"_ustr
);
338 else if ( rProp
.Name
== "Title" )
339 xRow
->appendString ( rProp
,m_aURLParameter
.get_title() );
340 else if ( rProp
.Name
== "IsReadOnly" )
341 xRow
->appendBoolean( rProp
,true );
342 else if ( rProp
.Name
== "IsDocument" )
345 m_aURLParameter
.isFile() || m_aURLParameter
.isRoot() );
346 else if ( rProp
.Name
== "IsFolder" )
349 ! m_aURLParameter
.isFile() || m_aURLParameter
.isRoot() );
350 else if ( rProp
.Name
== "IsErrorDocument" )
351 xRow
->appendBoolean( rProp
, m_aURLParameter
.isErrorDocument() );
352 else if ( rProp
.Name
== "MediaType" )
353 if( m_aURLParameter
.isActive() )
356 u
"text/plain"_ustr
);
357 else if( m_aURLParameter
.isFile() )
359 rProp
,u
"text/html"_ustr
);
360 else if( m_aURLParameter
.isRoot() )
365 xRow
->appendVoid( rProp
);
366 else if( m_aURLParameter
.isModule() )
367 if ( rProp
.Name
== "KeywordList" )
370 m_pDatabases
->getKeyword( m_aURLParameter
.get_module(),
371 m_aURLParameter
.get_language() );
375 aAny
<<= inf
->getKeywordList();
376 xRow
->appendObject( rProp
,aAny
);
378 else if ( rProp
.Name
== "KeywordRef" )
381 m_pDatabases
->getKeyword( m_aURLParameter
.get_module(),
382 m_aURLParameter
.get_language() );
386 aAny
<<= inf
->getIdList();
387 xRow
->appendObject( rProp
,aAny
);
389 else if ( rProp
.Name
== "KeywordAnchorForRef" )
392 m_pDatabases
->getKeyword( m_aURLParameter
.get_module(),
393 m_aURLParameter
.get_language() );
397 aAny
<<= inf
->getAnchorList();
398 xRow
->appendObject( rProp
,aAny
);
400 else if ( rProp
.Name
== "KeywordTitleForRef" )
403 m_pDatabases
->getKeyword( m_aURLParameter
.get_module(),
404 m_aURLParameter
.get_language() );
408 aAny
<<= inf
->getTitleList();
409 xRow
->appendObject( rProp
,aAny
);
411 else if ( rProp
.Name
== "SearchScopes" )
413 uno::Sequence
< OUString
> seq
{ u
"Heading"_ustr
, u
"FullText"_ustr
};
414 xRow
->appendObject( rProp
, uno::Any(seq
) );
416 else if ( rProp
.Name
== "Order" )
418 StaticModuleInformation
*inf
=
419 m_pDatabases
->getStaticInformationForModule(
420 m_aURLParameter
.get_module(),
421 m_aURLParameter
.get_language() );
425 aAny
<<= sal_Int32( inf
->get_order() );
426 xRow
->appendObject( rProp
,aAny
);
429 xRow
->appendVoid( rProp
);
430 else if( "AnchorName" == rProp
.Name
&&
431 m_aURLParameter
.isFile() )
432 xRow
->appendString( rProp
,m_aURLParameter
.get_tag() );
434 xRow
->appendVoid( rProp
);
440 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */