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