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