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