xref: /trunk/main/xmlhelp/source/cxxhelp/provider/content.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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