LibreOffice Module xmlhelp (master) 1
content.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20/**************************************************************************
21 TODO
22 **************************************************************************
23
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>
37#include <ucbhelper/macros.hxx>
38#include <utility>
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"
47
48using namespace com::sun::star;
49using namespace chelp;
50
51// Content Implementation.
52
53Content::Content( const uno::Reference< uno::XComponentContext >& rxContext,
55 const uno::Reference< ucb::XContentIdentifier >&
56 Identifier,
57 Databases* pDatabases )
58 : ContentImplHelper( rxContext, pProvider, Identifier ),
59 m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ),
60 m_pDatabases( pDatabases ) // not owner
61{
62}
63
64// virtual
65Content::~Content()
66{
67}
68
69// virtual
70uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
71{
72 uno::Any aRet;
73 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
74}
75
76// XTypeProvider methods.
77
79
80// virtual
81uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
82{
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 ) );
94
95 return ourTypeCollection.getTypes();
96}
97
98// XServiceInfo methods.
99
100// virtual
102{
103 return "CHelpContent";
104}
105
106// virtual
107uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
108{
109 return { "com.sun.star.ucb.CHelpContent" };
110}
111
112// XContent methods.
113
114// virtual
115OUString SAL_CALL Content::getContentType()
116{
117 return MYUCP_CONTENT_TYPE;
118}
119
120// XCommandProcessor methods.
121
122//virtual
123void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
124{
125}
126
127namespace {
128
129class ResultSetForRootFactory
130 : public ResultSetFactory
131{
132private:
133
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;
139
140public:
141
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 )),
150 m_seq( seq ),
151 m_aURLParameter(rURLParameter),
152 m_pDatabases( pDatabases )
153 {
154 }
155
156 rtl::Reference<ResultSetBase> createResultSet() override
157 {
158 return new ResultSetForRoot( m_xContext,
159 m_xProvider,
160 m_seq,
161 m_aURLParameter,
162 m_pDatabases );
163 }
164};
165
166class ResultSetForQueryFactory
167 : public ResultSetFactory
168{
169private:
170
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;
176
177public:
178
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 )),
187 m_seq( seq ),
188 m_aURLParameter(rURLParameter),
189 m_pDatabases( pDatabases )
190 {
191 }
192
193 rtl::Reference<ResultSetBase> createResultSet() override
194 {
195 return new ResultSetForQuery( m_xContext,
196 m_xProvider,
197 m_seq,
198 m_aURLParameter,
199 m_pDatabases );
200 }
201};
202
203}
204
205// virtual
207 const ucb::Command& aCommand,
208 sal_Int32,
209 const uno::Reference< ucb::XCommandEnvironment >& Environment )
210{
211 uno::Any aRet;
212
213 if ( aCommand.Name == "getPropertyValues" )
214 {
215 uno::Sequence< beans::Property > Properties;
216 if ( !( aCommand.Argument >>= Properties ) )
217 {
218 aRet <<= lang::IllegalArgumentException();
219 ucbhelper::cancelCommandExecution(aRet,Environment);
220 }
221
222 aRet <<= getPropertyValues( Properties );
223 }
224 else if ( aCommand.Name == "setPropertyValues" )
225 {
226 uno::Sequence<beans::PropertyValue> propertyValues;
227
228 if( ! ( aCommand.Argument >>= propertyValues ) ) {
229 aRet <<= lang::IllegalArgumentException();
230 ucbhelper::cancelCommandExecution(aRet,Environment);
231 }
232
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());
242 });
243
244 aRet <<= ret;
245 }
246 else if ( aCommand.Name == "getPropertySetInfo" )
247 {
248 // Note: Implemented by base class.
249 aRet <<= getPropertySetInfo( Environment );
250 }
251 else if ( aCommand.Name == "getCommandInfo" )
252 {
253 // Note: Implemented by base class.
254 aRet <<= getCommandInfo( Environment );
255 }
256 else if ( aCommand.Name == "open" )
257 {
258 ucb::OpenCommandArgument2 aOpenCommand;
259 if ( !( aCommand.Argument >>= aOpenCommand ) )
260 {
261 aRet <<= lang::IllegalArgumentException();
262 ucbhelper::cancelCommandExecution(aRet,Environment);
263 }
264
265 uno::Reference< io::XActiveDataSink > xActiveDataSink(
266 aOpenCommand.Sink, uno::UNO_QUERY);
267
268 if(xActiveDataSink.is())
269 m_aURLParameter.open(xActiveDataSink);
270
271 uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer(
272 aOpenCommand.Sink, uno::UNO_QUERY);
273
274 if(xActiveDataStreamer.is()) {
275 aRet <<= ucb::UnsupportedDataSinkException();
276 ucbhelper::cancelCommandExecution(aRet,Environment);
277 }
278
279 uno::Reference< io::XOutputStream > xOutputStream(
280 aOpenCommand.Sink, uno::UNO_QUERY);
281
282 if(xOutputStream.is() )
283 m_aURLParameter.open(xOutputStream);
284
285 if( m_aURLParameter.isRoot() )
286 {
287 uno::Reference< ucb::XDynamicResultSet > xSet
288 = new DynamicResultSet(
289 m_xContext,
290 aOpenCommand,
291 std::make_unique<ResultSetForRootFactory>(
292 m_xContext,
293 m_xProvider.get(),
294 aOpenCommand.Properties,
295 m_aURLParameter,
296 m_pDatabases));
297 aRet <<= xSet;
298 }
299 else if( m_aURLParameter.isQuery() )
300 {
301 uno::Reference< ucb::XDynamicResultSet > xSet
302 = new DynamicResultSet(
303 m_xContext,
304 aOpenCommand,
305 std::make_unique<ResultSetForQueryFactory>(
306 m_xContext,
307 m_xProvider.get(),
308 aOpenCommand.Properties,
309 m_aURLParameter,
310 m_pDatabases ) );
311 aRet <<= xSet;
312 }
313 }
314 else
315 {
316 // Unsupported command
317 aRet <<= ucb::UnsupportedCommandException();
318 ucbhelper::cancelCommandExecution(aRet,Environment);
319 }
320
321 return aRet;
322}
323
324uno::Reference< sdbc::XRow > Content::getPropertyValues(
325 const uno::Sequence< beans::Property >& rProperties )
326{
327 osl::MutexGuard aGuard( m_aMutex );
328
330 new ::ucbhelper::PropertyValueSet( m_xContext );
331
332 for ( const beans::Property& rProp : rProperties )
333 {
334 if ( rProp.Name == "ContentType" )
335 xRow->appendString(
336 rProp,
337 OUString(
338 "application/vnd.sun.star.help" ) );
339 else if ( rProp.Name == "Title" )
340 xRow->appendString ( rProp,m_aURLParameter.get_title() );
341 else if ( rProp.Name == "IsReadOnly" )
342 xRow->appendBoolean( rProp,true );
343 else if ( rProp.Name == "IsDocument" )
344 xRow->appendBoolean(
345 rProp,
347 else if ( rProp.Name == "IsFolder" )
348 xRow->appendBoolean(
349 rProp,
351 else if ( rProp.Name == "IsErrorDocument" )
352 xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() );
353 else if ( rProp.Name == "MediaType" )
355 xRow->appendString(
356 rProp,
357 OUString( "text/plain" ) );
358 else if( m_aURLParameter.isFile() )
359 xRow->appendString(
360 rProp,OUString( "text/html" ) );
361 else if( m_aURLParameter.isRoot() )
362 xRow->appendString(
363 rProp,
364 OUString( "text/css" ) );
365 else
366 xRow->appendVoid( rProp );
367 else if( m_aURLParameter.isModule() )
368 if ( rProp.Name == "KeywordList" )
369 {
370 KeywordInfo *inf =
373
374 uno::Any aAny;
375 if( inf )
376 aAny <<= inf->getKeywordList();
377 xRow->appendObject( rProp,aAny );
378 }
379 else if ( rProp.Name == "KeywordRef" )
380 {
381 KeywordInfo *inf =
384
385 uno::Any aAny;
386 if( inf )
387 aAny <<= inf->getIdList();
388 xRow->appendObject( rProp,aAny );
389 }
390 else if ( rProp.Name == "KeywordAnchorForRef" )
391 {
392 KeywordInfo *inf =
395
396 uno::Any aAny;
397 if( inf )
398 aAny <<= inf->getAnchorList();
399 xRow->appendObject( rProp,aAny );
400 }
401 else if ( rProp.Name == "KeywordTitleForRef" )
402 {
403 KeywordInfo *inf =
406
407 uno::Any aAny;
408 if( inf )
409 aAny <<= inf->getTitleList();
410 xRow->appendObject( rProp,aAny );
411 }
412 else if ( rProp.Name == "SearchScopes" )
413 {
414 uno::Sequence< OUString > seq{ "Heading", "FullText" };
415 xRow->appendObject( rProp, uno::Any(seq) );
416 }
417 else if ( rProp.Name == "Order" )
418 {
423
424 uno::Any aAny;
425 if( inf )
426 aAny <<= sal_Int32( inf->get_order() );
427 xRow->appendObject( rProp,aAny );
428 }
429 else
430 xRow->appendVoid( rProp );
431 else if( "AnchorName" == rProp.Name &&
433 xRow->appendString( rProp,m_aURLParameter.get_tag() );
434 else
435 xRow->appendVoid( rProp );
436 }
437
438 return xRow;
439}
440
441/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
Databases * m_pDatabases
Definition: content.hxx:82
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
virtual css::uno::Sequence< css::beans::Property > getProperties(const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv) override
URLParameter m_aURLParameter
Definition: content.hxx:81
virtual OUString SAL_CALL getImplementationName() override
Definition: content.cxx:101
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: content.cxx:107
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: content.cxx:81
virtual OUString SAL_CALL getContentType() override
Definition: content.cxx:115
virtual void SAL_CALL abort(sal_Int32 CommandId) override
Definition: content.cxx:123
css::uno::Reference< css::sdbc::XRow > getPropertyValues(const css::uno::Sequence< css::beans::Property > &rProperties)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
KeywordInfo * getKeyword(const OUString &Module, const OUString &Language)
Definition: databases.cxx:722
StaticModuleInformation * getStaticInformationForModule(std::u16string_view Module, const OUString &Language)
Definition: databases.cxx:323
css::uno::Sequence< css::uno::Sequence< OUString > > & getIdList()
Definition: databases.hxx:115
css::uno::Sequence< css::uno::Sequence< OUString > > & getAnchorList()
Definition: databases.hxx:118
css::uno::Sequence< css::uno::Sequence< OUString > > & getTitleList()
Definition: databases.hxx:121
css::uno::Sequence< OUString > & getKeywordList()
Definition: databases.hxx:112
bool isModule() const
bool isActive() const
const OUString & get_module() const
OUString const & get_language() const
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
css::uno::Reference< css::uno::XComponentContext > m_xContext
XTYPEPROVIDER_COMMON_IMPL(Content)
#define CPPU_TYPE_REF(T)
constexpr OUStringLiteral MYUCP_CONTENT_TYPE
Definition: provider.hxx:38
dictionary props
void cancelCommandExecution(const uno::Any &rException, const uno::Reference< ucb::XCommandEnvironment > &xEnv)
bool hasValue()
OUString aCommand