| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmlhelp.hxx" |
| |
| /************************************************************************** |
| TODO |
| ************************************************************************** |
| |
| *************************************************************************/ |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/beans/XPropertyAccess.hpp> |
| #include <com/sun/star/sdbc/XRow.hpp> |
| #include <com/sun/star/ucb/OpenCommandArgument2.hpp> |
| #include <com/sun/star/ucb/OpenMode.hpp> |
| #include <com/sun/star/ucb/XCommandInfo.hpp> |
| #include <com/sun/star/io/XActiveDataSink.hpp> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/lang/IllegalAccessException.hpp> |
| #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> |
| #include <com/sun/star/io/XActiveDataStreamer.hpp> |
| #include <com/sun/star/ucb/XPersistentPropertySet.hpp> |
| #ifndef _VOS_DIAGNOSE_HXX_ |
| #include <vos/diagnose.hxx> |
| #endif |
| #include <ucbhelper/contentidentifier.hxx> |
| #include <ucbhelper/propertyvalueset.hxx> |
| #ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX |
| #include <ucbhelper/cancelcommandexecution.hxx> |
| #endif |
| #include "content.hxx" |
| #include "provider.hxx" |
| #include "resultset.hxx" |
| #include "databases.hxx" |
| #include "resultsetfactory.hxx" |
| #include "resultsetbase.hxx" |
| #include "resultsetforroot.hxx" |
| #include "resultsetforquery.hxx" |
| |
| using namespace com::sun::star; |
| using namespace chelp; |
| |
| //========================================================================= |
| //========================================================================= |
| // |
| // Content Implementation. |
| // |
| //========================================================================= |
| //========================================================================= |
| |
| Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, |
| ::ucbhelper::ContentProviderImplHelper* pProvider, |
| const uno::Reference< ucb::XContentIdentifier >& |
| Identifier, |
| Databases* pDatabases ) |
| : ContentImplHelper( rxSMgr, pProvider, Identifier ), |
| m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ), |
| m_pDatabases( pDatabases ) // not owner |
| { |
| } |
| |
| //========================================================================= |
| // virtual |
| Content::~Content() |
| { |
| } |
| |
| //========================================================================= |
| // |
| // XInterface methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL Content::acquire() |
| throw( ) |
| { |
| ContentImplHelper::acquire(); |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL Content::release() |
| throw( ) |
| { |
| ContentImplHelper::release(); |
| } |
| |
| //========================================================================= |
| // virtual |
| uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) |
| throw ( uno::RuntimeException ) |
| { |
| uno::Any aRet; |
| return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); |
| } |
| |
| //========================================================================= |
| // |
| // XTypeProvider methods. |
| // |
| //========================================================================= |
| |
| XTYPEPROVIDER_COMMON_IMPL( Content ); |
| |
| //========================================================================= |
| // virtual |
| uno::Sequence< uno::Type > SAL_CALL Content::getTypes() |
| throw( uno::RuntimeException ) |
| { |
| static cppu::OTypeCollection* pCollection = NULL; |
| |
| if ( !pCollection ) |
| { |
| osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ); |
| if ( !pCollection ) |
| { |
| static cppu::OTypeCollection aCollection( |
| CPPU_TYPE_REF( lang::XTypeProvider ), |
| CPPU_TYPE_REF( lang::XServiceInfo ), |
| CPPU_TYPE_REF( lang::XComponent ), |
| CPPU_TYPE_REF( ucb::XContent ), |
| CPPU_TYPE_REF( ucb::XCommandProcessor ), |
| CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), |
| CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), |
| CPPU_TYPE_REF( beans::XPropertyContainer ), |
| CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), |
| CPPU_TYPE_REF( container::XChild ) ); |
| pCollection = &aCollection; |
| } |
| } |
| |
| return (*pCollection).getTypes(); |
| } |
| |
| //========================================================================= |
| // |
| // XServiceInfo methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| rtl::OUString SAL_CALL Content::getImplementationName() |
| throw( uno::RuntimeException ) |
| { |
| return rtl::OUString::createFromAscii( "CHelpContent" ); |
| } |
| |
| //========================================================================= |
| // virtual |
| uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() |
| throw( uno::RuntimeException ) |
| { |
| uno::Sequence< rtl::OUString > aSNS( 1 ); |
| aSNS.getArray()[ 0 ] |
| = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); |
| return aSNS; |
| } |
| |
| //========================================================================= |
| // |
| // XContent methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| rtl::OUString SAL_CALL Content::getContentType() |
| throw( uno::RuntimeException ) |
| { |
| return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); |
| } |
| |
| //========================================================================= |
| // |
| // XCommandProcessor methods. |
| // |
| //========================================================================= |
| |
| //virtual |
| void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) |
| throw( uno::RuntimeException ) |
| { |
| } |
| |
| |
| |
| class ResultSetForRootFactory |
| : public ResultSetFactory |
| { |
| private: |
| |
| uno::Reference< lang::XMultiServiceFactory > m_xSMgr; |
| uno::Reference< ucb::XContentProvider > m_xProvider; |
| sal_Int32 m_nOpenMode; |
| uno::Sequence< beans::Property > m_seq; |
| uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; |
| URLParameter m_aURLParameter; |
| Databases* m_pDatabases; |
| |
| |
| public: |
| |
| 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 ) |
| : m_xSMgr( xSMgr ), |
| m_xProvider( xProvider ), |
| m_nOpenMode( nOpenMode ), |
| m_seq( seq ), |
| m_seqSort( seqSort ), |
| m_aURLParameter( aURLParameter ), |
| m_pDatabases( pDatabases ) |
| { |
| } |
| |
| ResultSetBase* createResultSet() |
| { |
| return new ResultSetForRoot( m_xSMgr, |
| m_xProvider, |
| m_nOpenMode, |
| m_seq, |
| m_seqSort, |
| m_aURLParameter, |
| m_pDatabases ); |
| } |
| }; |
| |
| |
| |
| class ResultSetForQueryFactory |
| : public ResultSetFactory |
| { |
| private: |
| |
| uno::Reference< lang::XMultiServiceFactory > m_xSMgr; |
| uno::Reference< ucb::XContentProvider > m_xProvider; |
| sal_Int32 m_nOpenMode; |
| uno::Sequence< beans::Property > m_seq; |
| uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; |
| URLParameter m_aURLParameter; |
| Databases* m_pDatabases; |
| |
| |
| public: |
| |
| 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 ) |
| : m_xSMgr( xSMgr ), |
| m_xProvider( xProvider ), |
| m_nOpenMode( nOpenMode ), |
| m_seq( seq ), |
| m_seqSort( seqSort ), |
| m_aURLParameter( aURLParameter ), |
| m_pDatabases( pDatabases ) |
| { |
| } |
| |
| ResultSetBase* createResultSet() |
| { |
| return new ResultSetForQuery( m_xSMgr, |
| m_xProvider, |
| m_nOpenMode, |
| m_seq, |
| m_seqSort, |
| m_aURLParameter, |
| m_pDatabases ); |
| } |
| }; |
| |
| |
| |
| // virtual |
| uno::Any SAL_CALL Content::execute( |
| const ucb::Command& aCommand, |
| sal_Int32 CommandId, |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception, |
| ucb::CommandAbortedException, |
| uno::RuntimeException ) |
| { |
| uno::Any aRet; |
| |
| if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 ) |
| { |
| uno::Sequence< beans::Property > Properties; |
| if ( !( aCommand.Argument >>= Properties ) ) |
| { |
| aRet <<= lang::IllegalArgumentException(); |
| ucbhelper::cancelCommandExecution(aRet,Environment); |
| } |
| |
| aRet <<= getPropertyValues( Properties ); |
| } |
| else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 ) |
| { |
| uno::Sequence<beans::PropertyValue> propertyValues; |
| |
| if( ! ( aCommand.Argument >>= propertyValues ) ) { |
| aRet <<= lang::IllegalArgumentException(); |
| ucbhelper::cancelCommandExecution(aRet,Environment); |
| } |
| |
| uno::Sequence< uno::Any > ret(propertyValues.getLength()); |
| uno::Sequence< beans::Property > props(getProperties(Environment)); |
| // No properties can be set |
| for(sal_Int32 i = 0; i < ret.getLength(); ++i) { |
| ret[i] <<= beans::UnknownPropertyException(); |
| for(sal_Int32 j = 0; j < props.getLength(); ++j) |
| if(props[j].Name == propertyValues[i].Name) { |
| ret[i] <<= lang::IllegalAccessException(); |
| break; |
| } |
| } |
| |
| aRet <<= ret; |
| } |
| else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 ) |
| { |
| // Note: Implemented by base class. |
| aRet <<= getPropertySetInfo( Environment ); |
| } |
| else if ( aCommand.Name.compareToAscii( "getCommandInfo" ) == 0 ) |
| { |
| // Note: Implemented by base class. |
| aRet <<= getCommandInfo( Environment ); |
| } |
| else if ( aCommand.Name.compareToAscii( "open" ) == 0 ) |
| { |
| ucb::OpenCommandArgument2 aOpenCommand; |
| if ( !( aCommand.Argument >>= aOpenCommand ) ) |
| { |
| aRet <<= lang::IllegalArgumentException(); |
| ucbhelper::cancelCommandExecution(aRet,Environment); |
| } |
| |
| uno::Reference< io::XActiveDataSink > xActiveDataSink( |
| aOpenCommand.Sink, uno::UNO_QUERY); |
| |
| if(xActiveDataSink.is()) |
| m_aURLParameter.open(m_xSMgr, |
| aCommand, |
| CommandId, |
| Environment, |
| xActiveDataSink); |
| |
| uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer( |
| aOpenCommand.Sink, uno::UNO_QUERY); |
| |
| if(xActiveDataStreamer.is()) { |
| aRet <<= ucb::UnsupportedDataSinkException(); |
| ucbhelper::cancelCommandExecution(aRet,Environment); |
| } |
| |
| uno::Reference< io::XOutputStream > xOutputStream( |
| aOpenCommand.Sink, uno::UNO_QUERY); |
| |
| if(xOutputStream.is() ) |
| m_aURLParameter.open(m_xSMgr, |
| aCommand, |
| CommandId, |
| Environment, |
| xOutputStream); |
| |
| if( m_aURLParameter.isRoot() ) |
| { |
| uno::Reference< ucb::XDynamicResultSet > xSet |
| = new DynamicResultSet( |
| m_xSMgr, |
| this, |
| aOpenCommand, |
| Environment, |
| new ResultSetForRootFactory( |
| m_xSMgr, |
| m_xProvider.get(), |
| aOpenCommand.Mode, |
| aOpenCommand.Properties, |
| aOpenCommand.SortingInfo, |
| m_aURLParameter, |
| m_pDatabases)); |
| aRet <<= xSet; |
| } |
| else if( m_aURLParameter.isQuery() ) |
| { |
| uno::Reference< ucb::XDynamicResultSet > xSet |
| = new DynamicResultSet( |
| m_xSMgr, |
| this, |
| aOpenCommand, |
| Environment, |
| new ResultSetForQueryFactory( |
| m_xSMgr, |
| m_xProvider.get(), |
| aOpenCommand.Mode, |
| aOpenCommand.Properties, |
| aOpenCommand.SortingInfo, |
| m_aURLParameter, |
| m_pDatabases ) ); |
| aRet <<= xSet; |
| } |
| } |
| else |
| { |
| ////////////////////////////////////////////////////////////////// |
| // Unsupported command |
| ////////////////////////////////////////////////////////////////// |
| aRet <<= ucb::UnsupportedCommandException(); |
| ucbhelper::cancelCommandExecution(aRet,Environment); |
| } |
| |
| return aRet; |
| } |
| |
| |
| |
| |
| //========================================================================= |
| uno::Reference< sdbc::XRow > Content::getPropertyValues( |
| const uno::Sequence< beans::Property >& rProperties ) |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = |
| new ::ucbhelper::PropertyValueSet( m_xSMgr ); |
| |
| for ( sal_Int32 n = 0; n < rProperties.getLength(); ++n ) |
| { |
| const beans::Property& rProp = rProperties[n]; |
| |
| if ( rProp.Name.compareToAscii( "ContentType" ) == 0 ) |
| xRow->appendString( |
| rProp, |
| rtl::OUString::createFromAscii( |
| "application/vnd.sun.star.help" ) ); |
| else if( rProp.Name.compareToAscii( "Title" ) == 0 ) |
| xRow->appendString ( rProp,m_aURLParameter.get_title() ); |
| else if( rProp.Name.compareToAscii( "IsReadOnly" ) == 0 ) |
| xRow->appendBoolean( rProp,true ); |
| else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 ) |
| xRow->appendBoolean( |
| rProp, |
| m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); |
| else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 ) |
| xRow->appendBoolean( |
| rProp, |
| ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); |
| else if( rProp.Name.compareToAscii( "IsErrorDocument" ) == 0 ) |
| xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() ); |
| else if( rProp.Name.compareToAscii( "MediaType" ) == 0 ) |
| if( m_aURLParameter.isPicture() ) |
| xRow->appendString( |
| rProp, |
| rtl::OUString::createFromAscii( "image/gif" ) ); |
| else if( m_aURLParameter.isActive() ) |
| xRow->appendString( |
| rProp, |
| rtl::OUString::createFromAscii( "text/plain" ) ); |
| else if( m_aURLParameter.isFile() ) |
| xRow->appendString( |
| rProp,rtl::OUString::createFromAscii( "text/html" ) ); |
| else if( m_aURLParameter.isRoot() ) |
| xRow->appendString( |
| rProp, |
| rtl::OUString::createFromAscii( "text/css" ) ); |
| else |
| xRow->appendVoid( rProp ); |
| else if( m_aURLParameter.isModule() ) |
| if( rProp.Name.compareToAscii( "KeywordList" ) == 0 ) |
| { |
| KeywordInfo *inf = |
| m_pDatabases->getKeyword( m_aURLParameter.get_module(), |
| m_aURLParameter.get_language() ); |
| |
| uno::Any aAny; |
| if( inf ) |
| aAny <<= inf->getKeywordList(); |
| xRow->appendObject( rProp,aAny ); |
| } |
| else if( rProp.Name.compareToAscii( "KeywordRef" ) == 0 ) |
| { |
| KeywordInfo *inf = |
| m_pDatabases->getKeyword( m_aURLParameter.get_module(), |
| m_aURLParameter.get_language() ); |
| |
| uno::Any aAny; |
| if( inf ) |
| aAny <<= inf->getIdList(); |
| xRow->appendObject( rProp,aAny ); |
| } |
| else if( rProp.Name.compareToAscii( "KeywordAnchorForRef" ) == 0 ) |
| { |
| KeywordInfo *inf = |
| m_pDatabases->getKeyword( m_aURLParameter.get_module(), |
| m_aURLParameter.get_language() ); |
| |
| uno::Any aAny; |
| if( inf ) |
| aAny <<= inf->getAnchorList(); |
| xRow->appendObject( rProp,aAny ); |
| } |
| else if( rProp.Name.compareToAscii( "KeywordTitleForRef" ) == 0 ) |
| { |
| KeywordInfo *inf = |
| m_pDatabases->getKeyword( m_aURLParameter.get_module(), |
| m_aURLParameter.get_language() ); |
| |
| uno::Any aAny; |
| if( inf ) |
| aAny <<= inf->getTitleList(); |
| xRow->appendObject( rProp,aAny ); |
| } |
| else if( rProp.Name.compareToAscii( "SearchScopes" ) == 0 ) |
| { |
| uno::Sequence< rtl::OUString > seq( 2 ); |
| seq[0] = rtl::OUString::createFromAscii( "Heading" ); |
| seq[1] = rtl::OUString::createFromAscii( "FullText" ); |
| uno::Any aAny; |
| aAny <<= seq; |
| xRow->appendObject( rProp,aAny ); |
| } |
| else if( rProp.Name.compareToAscii( "Order" ) == 0 ) |
| { |
| StaticModuleInformation *inf = |
| m_pDatabases->getStaticInformationForModule( |
| m_aURLParameter.get_module(), |
| m_aURLParameter.get_language() ); |
| |
| uno::Any aAny; |
| if( inf ) |
| aAny <<= sal_Int32( inf->get_order() ); |
| xRow->appendObject( rProp,aAny ); |
| } |
| else |
| xRow->appendVoid( rProp ); |
| else if( rProp.Name.compareToAscii( "AnchorName" ) == 0 && |
| m_aURLParameter.isFile() ) |
| xRow->appendString( rProp,m_aURLParameter.get_tag() ); |
| else |
| xRow->appendVoid( rProp ); |
| } |
| |
| return uno::Reference< sdbc::XRow >( xRow.get() ); |
| } |