/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ /************************************************************************** TODO ************************************************************************** *************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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< uno::XComponentContext >& rxContext, ::ucbhelper::ContentProviderImplHelper* pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier, Databases* pDatabases ) : ContentImplHelper( rxContext, pProvider, Identifier ), m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ), m_pDatabases( pDatabases ) // not owner { } // virtual Content::~Content() { } // virtual uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) { 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() { static cppu::OTypeCollection ourTypeCollection( 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 ) ); return ourTypeCollection.getTypes(); } // XServiceInfo methods. // virtual OUString SAL_CALL Content::getImplementationName() { return u"CHelpContent"_ustr; } // virtual uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames() { return { u"com.sun.star.ucb.CHelpContent"_ustr }; } // XContent methods. // virtual OUString SAL_CALL Content::getContentType() { return MYUCP_CONTENT_TYPE; } // XCommandProcessor methods. //virtual void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) { } namespace { class ResultSetForRootFactory : public ResultSetFactory { private: uno::Reference< uno::XComponentContext > m_xContext; uno::Reference< ucb::XContentProvider > m_xProvider; uno::Sequence< beans::Property > m_seq; URLParameter m_aURLParameter; Databases* m_pDatabases; public: ResultSetForRootFactory( uno::Reference< uno::XComponentContext > xContext, uno::Reference< ucb::XContentProvider > xProvider, const uno::Sequence< beans::Property >& seq, const URLParameter& rURLParameter, Databases* pDatabases ) : m_xContext(std::move( xContext )), m_xProvider(std::move( xProvider )), m_seq( seq ), m_aURLParameter(rURLParameter), m_pDatabases( pDatabases ) { } rtl::Reference createResultSet() override { return new ResultSetForRoot( m_xContext, m_xProvider, m_seq, m_aURLParameter, m_pDatabases ); } }; class ResultSetForQueryFactory : public ResultSetFactory { private: uno::Reference< uno::XComponentContext > m_xContext; uno::Reference< ucb::XContentProvider > m_xProvider; uno::Sequence< beans::Property > m_seq; URLParameter m_aURLParameter; Databases* m_pDatabases; public: ResultSetForQueryFactory( uno::Reference< uno::XComponentContext > xContext, uno::Reference< ucb::XContentProvider > xProvider, const uno::Sequence< beans::Property >& seq, const URLParameter& rURLParameter, Databases* pDatabases ) : m_xContext(std::move( xContext )), m_xProvider(std::move( xProvider )), m_seq( seq ), m_aURLParameter(rURLParameter), m_pDatabases( pDatabases ) { } rtl::Reference createResultSet() override { return new ResultSetForQuery( m_xContext, m_xProvider, m_seq, m_aURLParameter, m_pDatabases ); } }; } // virtual uno::Any SAL_CALL Content::execute( const ucb::Command& aCommand, sal_Int32, const uno::Reference< ucb::XCommandEnvironment >& Environment ) { uno::Any aRet; if ( aCommand.Name == "getPropertyValues" ) { uno::Sequence< beans::Property > Properties; if ( !( aCommand.Argument >>= Properties ) ) { aRet <<= lang::IllegalArgumentException(); ucbhelper::cancelCommandExecution(aRet,Environment); } aRet <<= getPropertyValues( Properties ); } else if ( aCommand.Name == "setPropertyValues" ) { uno::Sequence propertyValues; if( ! ( aCommand.Argument >>= propertyValues ) ) { aRet <<= lang::IllegalArgumentException(); ucbhelper::cancelCommandExecution(aRet,Environment); } uno::Sequence< uno::Any > ret(propertyValues.getLength()); const uno::Sequence< beans::Property > props(getProperties(Environment)); // No properties can be set std::transform(std::cbegin(propertyValues), std::cend(propertyValues), ret.getArray(), [&props](const beans::PropertyValue& rPropVal) { if (std::any_of(props.begin(), props.end(), [&rPropVal](const beans::Property& rProp) { return rProp.Name == rPropVal.Name; })) return css::uno::toAny(lang::IllegalAccessException()); return css::uno::toAny(beans::UnknownPropertyException()); }); aRet <<= ret; } else if ( aCommand.Name == "getPropertySetInfo" ) { // Note: Implemented by base class. aRet <<= getPropertySetInfo( Environment ); } else if ( aCommand.Name == "getCommandInfo" ) { // Note: Implemented by base class. aRet <<= getCommandInfo( Environment ); } else if ( aCommand.Name == "open" ) { 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(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(xOutputStream); if( m_aURLParameter.isRoot() ) { uno::Reference< ucb::XDynamicResultSet > xSet = new DynamicResultSet( m_xContext, aOpenCommand, std::make_unique( m_xContext, m_xProvider.get(), aOpenCommand.Properties, m_aURLParameter, m_pDatabases)); aRet <<= xSet; } else if( m_aURLParameter.isQuery() ) { uno::Reference< ucb::XDynamicResultSet > xSet = new DynamicResultSet( m_xContext, aOpenCommand, std::make_unique( m_xContext, m_xProvider.get(), aOpenCommand.Properties, 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_xContext ); for ( const beans::Property& rProp : rProperties ) { if ( rProp.Name == "ContentType" ) xRow->appendString( rProp, u"application/vnd.sun.star.help"_ustr ); else if ( rProp.Name == "Title" ) xRow->appendString ( rProp,m_aURLParameter.get_title() ); else if ( rProp.Name == "IsReadOnly" ) xRow->appendBoolean( rProp,true ); else if ( rProp.Name == "IsDocument" ) xRow->appendBoolean( rProp, m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); else if ( rProp.Name == "IsFolder" ) xRow->appendBoolean( rProp, ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); else if ( rProp.Name == "IsErrorDocument" ) xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() ); else if ( rProp.Name == "MediaType" ) if( m_aURLParameter.isActive() ) xRow->appendString( rProp, u"text/plain"_ustr ); else if( m_aURLParameter.isFile() ) xRow->appendString( rProp,u"text/html"_ustr ); else if( m_aURLParameter.isRoot() ) xRow->appendString( rProp, u"text/css"_ustr ); else xRow->appendVoid( rProp ); else if( m_aURLParameter.isModule() ) if ( rProp.Name == "KeywordList" ) { 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 == "KeywordRef" ) { 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 == "KeywordAnchorForRef" ) { 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 == "KeywordTitleForRef" ) { 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 == "SearchScopes" ) { uno::Sequence< OUString > seq{ u"Heading"_ustr, u"FullText"_ustr }; xRow->appendObject( rProp, uno::Any(seq) ); } else if ( rProp.Name == "Order" ) { 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( "AnchorName" == rProp.Name && m_aURLParameter.isFile() ) xRow->appendString( rProp,m_aURLParameter.get_tag() ); else xRow->appendVoid( rProp ); } return xRow; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */