xref: /trunk/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