Line data Source code
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 : /**************************************************************************
22 : TODO
23 : **************************************************************************
24 :
25 : *************************************************************************/
26 : #include <com/sun/star/beans/PropertyAttribute.hpp>
27 : #include <com/sun/star/beans/XPropertyAccess.hpp>
28 : #include <com/sun/star/sdbc/XRow.hpp>
29 : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
30 : #include <com/sun/star/ucb/OpenMode.hpp>
31 : #include <com/sun/star/ucb/XCommandInfo.hpp>
32 : #include <com/sun/star/io/XActiveDataSink.hpp>
33 : #include <com/sun/star/io/XOutputStream.hpp>
34 : #include <com/sun/star/lang/IllegalAccessException.hpp>
35 : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
36 : #include <com/sun/star/io/XActiveDataStreamer.hpp>
37 : #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
38 : #include <osl/diagnose.h>
39 : #include <comphelper/processfactory.hxx>
40 : #include <ucbhelper/contentidentifier.hxx>
41 : #include <ucbhelper/propertyvalueset.hxx>
42 : #include <ucbhelper/cancelcommandexecution.hxx>
43 : #include "content.hxx"
44 : #include "provider.hxx"
45 : #include "resultset.hxx"
46 : #include "databases.hxx"
47 : #include "resultsetfactory.hxx"
48 : #include "resultsetbase.hxx"
49 : #include "resultsetforroot.hxx"
50 : #include "resultsetforquery.hxx"
51 :
52 : using namespace com::sun::star;
53 : using namespace chelp;
54 :
55 : //=========================================================================
56 : //=========================================================================
57 : //
58 : // Content Implementation.
59 : //
60 : //=========================================================================
61 : //=========================================================================
62 :
63 0 : Content::Content( const uno::Reference< uno::XComponentContext >& rxContext,
64 : ::ucbhelper::ContentProviderImplHelper* pProvider,
65 : const uno::Reference< ucb::XContentIdentifier >&
66 : Identifier,
67 : Databases* pDatabases )
68 : : ContentImplHelper( rxContext, pProvider, Identifier ),
69 0 : m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ),
70 0 : m_pDatabases( pDatabases ) // not owner
71 : {
72 0 : }
73 :
74 : //=========================================================================
75 : // virtual
76 0 : Content::~Content()
77 : {
78 0 : }
79 :
80 : //=========================================================================
81 : //
82 : // XInterface methods.
83 : //
84 : //=========================================================================
85 :
86 : // virtual
87 0 : void SAL_CALL Content::acquire()
88 : throw( )
89 : {
90 0 : ContentImplHelper::acquire();
91 0 : }
92 :
93 : //=========================================================================
94 : // virtual
95 0 : void SAL_CALL Content::release()
96 : throw( )
97 : {
98 0 : ContentImplHelper::release();
99 0 : }
100 :
101 : //=========================================================================
102 : // virtual
103 0 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
104 : throw ( uno::RuntimeException )
105 : {
106 0 : uno::Any aRet;
107 0 : return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
108 : }
109 :
110 : //=========================================================================
111 : //
112 : // XTypeProvider methods.
113 : //
114 : //=========================================================================
115 :
116 0 : XTYPEPROVIDER_COMMON_IMPL( Content );
117 :
118 : //=========================================================================
119 : // virtual
120 0 : uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
121 : throw( uno::RuntimeException )
122 : {
123 : static cppu::OTypeCollection* pCollection = NULL;
124 :
125 0 : if ( !pCollection )
126 : {
127 0 : osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
128 0 : if ( !pCollection )
129 : {
130 : static cppu::OTypeCollection aCollection(
131 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
132 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
133 0 : CPPU_TYPE_REF( lang::XComponent ),
134 0 : CPPU_TYPE_REF( ucb::XContent ),
135 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
136 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
137 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
138 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
139 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
140 0 : CPPU_TYPE_REF( container::XChild ) );
141 0 : pCollection = &aCollection;
142 0 : }
143 : }
144 :
145 0 : return (*pCollection).getTypes();
146 : }
147 :
148 : //=========================================================================
149 : //
150 : // XServiceInfo methods.
151 : //
152 : //=========================================================================
153 :
154 : // virtual
155 0 : rtl::OUString SAL_CALL Content::getImplementationName()
156 : throw( uno::RuntimeException )
157 : {
158 0 : return rtl::OUString( "CHelpContent" );
159 : }
160 :
161 : //=========================================================================
162 : // virtual
163 0 : uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
164 : throw( uno::RuntimeException )
165 : {
166 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
167 : aSNS.getArray()[ 0 ]
168 0 : = rtl::OUString( MYUCP_CONTENT_SERVICE_NAME );
169 0 : return aSNS;
170 : }
171 :
172 : //=========================================================================
173 : //
174 : // XContent methods.
175 : //
176 : //=========================================================================
177 :
178 : // virtual
179 0 : rtl::OUString SAL_CALL Content::getContentType()
180 : throw( uno::RuntimeException )
181 : {
182 0 : return rtl::OUString( MYUCP_CONTENT_TYPE );
183 : }
184 :
185 : //=========================================================================
186 : //
187 : // XCommandProcessor methods.
188 : //
189 : //=========================================================================
190 :
191 : //virtual
192 0 : void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
193 : throw( uno::RuntimeException )
194 : {
195 0 : }
196 :
197 :
198 :
199 0 : class ResultSetForRootFactory
200 : : public ResultSetFactory
201 : {
202 : private:
203 :
204 : uno::Reference< uno::XComponentContext > m_xContext;
205 : uno::Reference< ucb::XContentProvider > m_xProvider;
206 : sal_Int32 m_nOpenMode;
207 : uno::Sequence< beans::Property > m_seq;
208 : uno::Sequence< ucb::NumberedSortingInfo > m_seqSort;
209 : URLParameter m_aURLParameter;
210 : Databases* m_pDatabases;
211 :
212 :
213 : public:
214 :
215 0 : ResultSetForRootFactory(
216 : const uno::Reference< uno::XComponentContext >& xContext,
217 : const uno::Reference< ucb::XContentProvider >& xProvider,
218 : sal_Int32 nOpenMode,
219 : const uno::Sequence< beans::Property >& seq,
220 : const uno::Sequence< ucb::NumberedSortingInfo >& seqSort,
221 : URLParameter aURLParameter,
222 : Databases* pDatabases )
223 : : m_xContext( xContext ),
224 : m_xProvider( xProvider ),
225 : m_nOpenMode( nOpenMode ),
226 : m_seq( seq ),
227 : m_seqSort( seqSort ),
228 : m_aURLParameter( aURLParameter ),
229 0 : m_pDatabases( pDatabases )
230 : {
231 0 : }
232 :
233 0 : ResultSetBase* createResultSet()
234 : {
235 : return new ResultSetForRoot( m_xContext,
236 : m_xProvider,
237 : m_nOpenMode,
238 : m_seq,
239 : m_seqSort,
240 : m_aURLParameter,
241 0 : m_pDatabases );
242 : }
243 : };
244 :
245 :
246 :
247 0 : class ResultSetForQueryFactory
248 : : public ResultSetFactory
249 : {
250 : private:
251 :
252 : uno::Reference< uno::XComponentContext > m_xContext;
253 : uno::Reference< ucb::XContentProvider > m_xProvider;
254 : sal_Int32 m_nOpenMode;
255 : uno::Sequence< beans::Property > m_seq;
256 : uno::Sequence< ucb::NumberedSortingInfo > m_seqSort;
257 : URLParameter m_aURLParameter;
258 : Databases* m_pDatabases;
259 :
260 :
261 : public:
262 :
263 0 : ResultSetForQueryFactory(
264 : const uno::Reference< uno::XComponentContext >& rxContext,
265 : const uno::Reference< ucb::XContentProvider >& xProvider,
266 : sal_Int32 nOpenMode,
267 : const uno::Sequence< beans::Property >& seq,
268 : const uno::Sequence< ucb::NumberedSortingInfo >& seqSort,
269 : URLParameter aURLParameter,
270 : Databases* pDatabases )
271 : : m_xContext( rxContext ),
272 : m_xProvider( xProvider ),
273 : m_nOpenMode( nOpenMode ),
274 : m_seq( seq ),
275 : m_seqSort( seqSort ),
276 : m_aURLParameter( aURLParameter ),
277 0 : m_pDatabases( pDatabases )
278 : {
279 0 : }
280 :
281 0 : ResultSetBase* createResultSet()
282 : {
283 : return new ResultSetForQuery( m_xContext,
284 : m_xProvider,
285 : m_nOpenMode,
286 : m_seq,
287 : m_seqSort,
288 : m_aURLParameter,
289 0 : m_pDatabases );
290 : }
291 : };
292 :
293 :
294 :
295 : // virtual
296 0 : uno::Any SAL_CALL Content::execute(
297 : const ucb::Command& aCommand,
298 : sal_Int32 CommandId,
299 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
300 : throw( uno::Exception,
301 : ucb::CommandAbortedException,
302 : uno::RuntimeException )
303 : {
304 0 : uno::Any aRet;
305 :
306 0 : if ( aCommand.Name == "getPropertyValues" )
307 : {
308 0 : uno::Sequence< beans::Property > Properties;
309 0 : if ( !( aCommand.Argument >>= Properties ) )
310 : {
311 0 : aRet <<= lang::IllegalArgumentException();
312 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
313 : }
314 :
315 0 : aRet <<= getPropertyValues( Properties );
316 : }
317 0 : else if ( aCommand.Name == "setPropertyValues" )
318 : {
319 0 : uno::Sequence<beans::PropertyValue> propertyValues;
320 :
321 0 : if( ! ( aCommand.Argument >>= propertyValues ) ) {
322 0 : aRet <<= lang::IllegalArgumentException();
323 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
324 : }
325 :
326 0 : uno::Sequence< uno::Any > ret(propertyValues.getLength());
327 0 : uno::Sequence< beans::Property > props(getProperties(Environment));
328 : // No properties can be set
329 0 : for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
330 0 : ret[i] <<= beans::UnknownPropertyException();
331 0 : for(sal_Int32 j = 0; j < props.getLength(); ++j)
332 0 : if(props[j].Name == propertyValues[i].Name) {
333 0 : ret[i] <<= lang::IllegalAccessException();
334 0 : break;
335 : }
336 : }
337 :
338 0 : aRet <<= ret;
339 : }
340 0 : else if ( aCommand.Name == "getPropertySetInfo" )
341 : {
342 : // Note: Implemented by base class.
343 0 : aRet <<= getPropertySetInfo( Environment );
344 : }
345 0 : else if ( aCommand.Name == "getCommandInfo" )
346 : {
347 : // Note: Implemented by base class.
348 0 : aRet <<= getCommandInfo( Environment );
349 : }
350 0 : else if ( aCommand.Name == "open" )
351 : {
352 0 : ucb::OpenCommandArgument2 aOpenCommand;
353 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
354 : {
355 0 : aRet <<= lang::IllegalArgumentException();
356 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
357 : }
358 :
359 : uno::Reference< io::XActiveDataSink > xActiveDataSink(
360 0 : aOpenCommand.Sink, uno::UNO_QUERY);
361 :
362 0 : if(xActiveDataSink.is())
363 : m_aURLParameter.open(aCommand,
364 : CommandId,
365 : Environment,
366 0 : xActiveDataSink);
367 :
368 : uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer(
369 0 : aOpenCommand.Sink, uno::UNO_QUERY);
370 :
371 0 : if(xActiveDataStreamer.is()) {
372 0 : aRet <<= ucb::UnsupportedDataSinkException();
373 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
374 : }
375 :
376 : uno::Reference< io::XOutputStream > xOutputStream(
377 0 : aOpenCommand.Sink, uno::UNO_QUERY);
378 :
379 0 : if(xOutputStream.is() )
380 : m_aURLParameter.open(aCommand,
381 : CommandId,
382 : Environment,
383 0 : xOutputStream);
384 :
385 0 : if( m_aURLParameter.isRoot() )
386 : {
387 : uno::Reference< ucb::XDynamicResultSet > xSet
388 : = new DynamicResultSet(
389 : m_xContext,
390 : this,
391 : aOpenCommand,
392 : Environment,
393 : new ResultSetForRootFactory(
394 : m_xContext,
395 0 : m_xProvider.get(),
396 : aOpenCommand.Mode,
397 : aOpenCommand.Properties,
398 : aOpenCommand.SortingInfo,
399 : m_aURLParameter,
400 0 : m_pDatabases));
401 0 : aRet <<= xSet;
402 : }
403 0 : else if( m_aURLParameter.isQuery() )
404 : {
405 : uno::Reference< ucb::XDynamicResultSet > xSet
406 : = new DynamicResultSet(
407 : m_xContext,
408 : this,
409 : aOpenCommand,
410 : Environment,
411 : new ResultSetForQueryFactory(
412 : m_xContext,
413 0 : m_xProvider.get(),
414 : aOpenCommand.Mode,
415 : aOpenCommand.Properties,
416 : aOpenCommand.SortingInfo,
417 : m_aURLParameter,
418 0 : m_pDatabases ) );
419 0 : aRet <<= xSet;
420 0 : }
421 : }
422 : else
423 : {
424 : //////////////////////////////////////////////////////////////////
425 : // Unsupported command
426 : //////////////////////////////////////////////////////////////////
427 0 : aRet <<= ucb::UnsupportedCommandException();
428 0 : ucbhelper::cancelCommandExecution(aRet,Environment);
429 : }
430 :
431 0 : return aRet;
432 : }
433 :
434 :
435 :
436 :
437 : //=========================================================================
438 0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
439 : const uno::Sequence< beans::Property >& rProperties )
440 : {
441 0 : osl::MutexGuard aGuard( m_aMutex );
442 :
443 : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow =
444 0 : new ::ucbhelper::PropertyValueSet( m_xContext );
445 :
446 0 : for ( sal_Int32 n = 0; n < rProperties.getLength(); ++n )
447 : {
448 0 : const beans::Property& rProp = rProperties[n];
449 :
450 0 : if ( rProp.Name == "ContentType" )
451 : xRow->appendString(
452 : rProp,
453 : rtl::OUString(
454 0 : "application/vnd.sun.star.help" ) );
455 0 : else if ( rProp.Name == "Title" )
456 0 : xRow->appendString ( rProp,m_aURLParameter.get_title() );
457 0 : else if ( rProp.Name == "IsReadOnly" )
458 0 : xRow->appendBoolean( rProp,true );
459 0 : else if ( rProp.Name == "IsDocument" )
460 : xRow->appendBoolean(
461 : rProp,
462 0 : m_aURLParameter.isFile() || m_aURLParameter.isRoot() );
463 0 : else if ( rProp.Name == "IsFolder" )
464 : xRow->appendBoolean(
465 : rProp,
466 0 : ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() );
467 0 : else if ( rProp.Name == "IsErrorDocument" )
468 0 : xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() );
469 0 : else if ( rProp.Name == "MediaType" )
470 0 : if( m_aURLParameter.isPicture() )
471 : xRow->appendString(
472 : rProp,
473 0 : rtl::OUString( "image/gif" ) );
474 0 : else if( m_aURLParameter.isActive() )
475 : xRow->appendString(
476 : rProp,
477 0 : rtl::OUString( "text/plain" ) );
478 0 : else if( m_aURLParameter.isFile() )
479 : xRow->appendString(
480 0 : rProp,rtl::OUString( "text/html" ) );
481 0 : else if( m_aURLParameter.isRoot() )
482 : xRow->appendString(
483 : rProp,
484 0 : rtl::OUString( "text/css" ) );
485 : else
486 0 : xRow->appendVoid( rProp );
487 0 : else if( m_aURLParameter.isModule() )
488 0 : if ( rProp.Name == "KeywordList" )
489 : {
490 : KeywordInfo *inf =
491 : m_pDatabases->getKeyword( m_aURLParameter.get_module(),
492 0 : m_aURLParameter.get_language() );
493 :
494 0 : uno::Any aAny;
495 0 : if( inf )
496 0 : aAny <<= inf->getKeywordList();
497 0 : xRow->appendObject( rProp,aAny );
498 : }
499 0 : else if ( rProp.Name == "KeywordRef" )
500 : {
501 : KeywordInfo *inf =
502 : m_pDatabases->getKeyword( m_aURLParameter.get_module(),
503 0 : m_aURLParameter.get_language() );
504 :
505 0 : uno::Any aAny;
506 0 : if( inf )
507 0 : aAny <<= inf->getIdList();
508 0 : xRow->appendObject( rProp,aAny );
509 : }
510 0 : else if ( rProp.Name == "KeywordAnchorForRef" )
511 : {
512 : KeywordInfo *inf =
513 : m_pDatabases->getKeyword( m_aURLParameter.get_module(),
514 0 : m_aURLParameter.get_language() );
515 :
516 0 : uno::Any aAny;
517 0 : if( inf )
518 0 : aAny <<= inf->getAnchorList();
519 0 : xRow->appendObject( rProp,aAny );
520 : }
521 0 : else if ( rProp.Name == "KeywordTitleForRef" )
522 : {
523 : KeywordInfo *inf =
524 : m_pDatabases->getKeyword( m_aURLParameter.get_module(),
525 0 : m_aURLParameter.get_language() );
526 :
527 0 : uno::Any aAny;
528 0 : if( inf )
529 0 : aAny <<= inf->getTitleList();
530 0 : xRow->appendObject( rProp,aAny );
531 : }
532 0 : else if ( rProp.Name == "SearchScopes" )
533 : {
534 0 : uno::Sequence< rtl::OUString > seq( 2 );
535 0 : seq[0] = rtl::OUString( "Heading" );
536 0 : seq[1] = rtl::OUString( "FullText" );
537 0 : uno::Any aAny;
538 0 : aAny <<= seq;
539 0 : xRow->appendObject( rProp,aAny );
540 : }
541 0 : else if ( rProp.Name == "Order" )
542 : {
543 : StaticModuleInformation *inf =
544 : m_pDatabases->getStaticInformationForModule(
545 : m_aURLParameter.get_module(),
546 0 : m_aURLParameter.get_language() );
547 :
548 0 : uno::Any aAny;
549 0 : if( inf )
550 0 : aAny <<= sal_Int32( inf->get_order() );
551 0 : xRow->appendObject( rProp,aAny );
552 : }
553 : else
554 0 : xRow->appendVoid( rProp );
555 0 : else if( "AnchorName" == rProp.Name &&
556 0 : m_aURLParameter.isFile() )
557 0 : xRow->appendString( rProp,m_aURLParameter.get_tag() );
558 : else
559 0 : xRow->appendVoid( rProp );
560 : }
561 :
562 0 : return uno::Reference< sdbc::XRow >( xRow.get() );
563 : }
564 :
565 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|