16d739b60SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 36d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 46d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 56d739b60SAndrew Rist * distributed with this work for additional information 66d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 76d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 86d739b60SAndrew Rist * "License"); you may not use this file except in compliance 96d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 116d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 136d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 146d739b60SAndrew Rist * software distributed under the License is distributed on an 156d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 166d739b60SAndrew Rist * KIND, either express or implied. See the License for the 176d739b60SAndrew Rist * specific language governing permissions and limitations 186d739b60SAndrew Rist * under the License. 19cdf0e10cSrcweir * 206d739b60SAndrew Rist *************************************************************/ 216d739b60SAndrew Rist 226d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_framework.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 28cdf0e10cSrcweir // my own includes 29cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 30cdf0e10cSrcweir #include <dispatch/servicehandler.hxx> 31cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 32cdf0e10cSrcweir #include <general.h> 33cdf0e10cSrcweir #include <services.h> 34cdf0e10cSrcweir 35cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 36cdf0e10cSrcweir // interface includes 37cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 38cdf0e10cSrcweir #include <com/sun/star/frame/DispatchResultState.hpp> 39cdf0e10cSrcweir #include <com/sun/star/task/XJobExecutor.hpp> 40cdf0e10cSrcweir 41cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 42cdf0e10cSrcweir // includes of other projects 43cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include <vcl/svapp.hxx> 46cdf0e10cSrcweir 47cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 48cdf0e10cSrcweir // namespace 49cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 50cdf0e10cSrcweir 51cdf0e10cSrcweir namespace framework{ 52cdf0e10cSrcweir 53cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 54cdf0e10cSrcweir // non exported const 55cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 56cdf0e10cSrcweir 57cdf0e10cSrcweir #define PROTOCOL_VALUE "service:" 58cdf0e10cSrcweir #define PROTOCOL_LENGTH 8 59cdf0e10cSrcweir 60cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 61cdf0e10cSrcweir // non exported definitions 62cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 63cdf0e10cSrcweir 64cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 65cdf0e10cSrcweir // declarations 66cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 67cdf0e10cSrcweir 68cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 69cdf0e10cSrcweir // XInterface, XTypeProvider, XServiceInfo 70cdf0e10cSrcweir 71cdf0e10cSrcweir DEFINE_XINTERFACE_5(ServiceHandler , 72cdf0e10cSrcweir OWeakObject , 73cdf0e10cSrcweir DIRECT_INTERFACE(css::lang::XTypeProvider ), 74cdf0e10cSrcweir DIRECT_INTERFACE(css::lang::XServiceInfo ), 75cdf0e10cSrcweir DIRECT_INTERFACE(css::frame::XDispatchProvider ), 76cdf0e10cSrcweir DIRECT_INTERFACE(css::frame::XNotifyingDispatch), 77cdf0e10cSrcweir DIRECT_INTERFACE(css::frame::XDispatch )) 78cdf0e10cSrcweir 79cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_5(ServiceHandler , 80cdf0e10cSrcweir css::lang::XTypeProvider , 81cdf0e10cSrcweir css::lang::XServiceInfo , 82cdf0e10cSrcweir css::frame::XDispatchProvider , 83cdf0e10cSrcweir css::frame::XNotifyingDispatch, 84cdf0e10cSrcweir css::frame::XDispatch ) 85cdf0e10cSrcweir 86cdf0e10cSrcweir DEFINE_XSERVICEINFO_MULTISERVICE(ServiceHandler , 87cdf0e10cSrcweir ::cppu::OWeakObject , 88cdf0e10cSrcweir SERVICENAME_PROTOCOLHANDLER , 89cdf0e10cSrcweir IMPLEMENTATIONNAME_SERVICEHANDLER) 90cdf0e10cSrcweir 91cdf0e10cSrcweir DEFINE_INIT_SERVICE(ServiceHandler, 92cdf0e10cSrcweir { 93cdf0e10cSrcweir /*Attention 94cdf0e10cSrcweir I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() 95cdf0e10cSrcweir to create a new instance of this class by our own supported service factory. 96cdf0e10cSrcweir see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! 97cdf0e10cSrcweir */ 98cdf0e10cSrcweir } 99cdf0e10cSrcweir ) 100cdf0e10cSrcweir 101cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 102cdf0e10cSrcweir 103cdf0e10cSrcweir /** 104cdf0e10cSrcweir @short standard ctor 10507a3d7f1SPedro Giffuni @descr These initialize a new instance of this class with needed informations for work. 106cdf0e10cSrcweir 107cdf0e10cSrcweir @param xFactory 108cdf0e10cSrcweir reference to uno servicemanager for creation of new services 109cdf0e10cSrcweir 110cdf0e10cSrcweir @modified 02.05.2002 08:16, as96863 111cdf0e10cSrcweir */ 112cdf0e10cSrcweir ServiceHandler::ServiceHandler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ) 113cdf0e10cSrcweir // Init baseclasses first 114cdf0e10cSrcweir : ThreadHelpBase( &Application::GetSolarMutex() ) 115cdf0e10cSrcweir , OWeakObject ( ) 116cdf0e10cSrcweir // Init member 117cdf0e10cSrcweir , m_xFactory ( xFactory ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir } 120cdf0e10cSrcweir 121cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 122cdf0e10cSrcweir 123cdf0e10cSrcweir /** 124cdf0e10cSrcweir @short standard dtor 125cdf0e10cSrcweir @descr - 126cdf0e10cSrcweir 127cdf0e10cSrcweir @modified 02.05.2002 08:16, as96863 128cdf0e10cSrcweir */ 129cdf0e10cSrcweir ServiceHandler::~ServiceHandler() 130cdf0e10cSrcweir { 131cdf0e10cSrcweir m_xFactory = NULL; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 135cdf0e10cSrcweir 136cdf0e10cSrcweir /** 137cdf0e10cSrcweir @short decide if this dispatch implementation can be used for requested URL or not 138cdf0e10cSrcweir @descr A protocol handler is registerd for an URL pattern inside configuration and will 139cdf0e10cSrcweir be asked by the generic dispatch mechanism inside framework, if he can handle this 140*30acf5e8Spfg special URL which match his registration. He can agree by returning of a valid dispatch 141cdf0e10cSrcweir instance or disagree by returning <NULL/>. 14207a3d7f1SPedro Giffuni We don't create new dispatch instances here really - we return THIS as result to handle it 143cdf0e10cSrcweir at the same implementation. 144cdf0e10cSrcweir 145cdf0e10cSrcweir @modified 02.05.2002 15:25, as96863 146cdf0e10cSrcweir */ 147cdf0e10cSrcweir css::uno::Reference< css::frame::XDispatch > SAL_CALL ServiceHandler::queryDispatch( const css::util::URL& aURL , 148cdf0e10cSrcweir const ::rtl::OUString& /*sTarget*/ , 149cdf0e10cSrcweir sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException ) 150cdf0e10cSrcweir { 151cdf0e10cSrcweir css::uno::Reference< css::frame::XDispatch > xDispatcher; 152cdf0e10cSrcweir if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0) 153cdf0e10cSrcweir xDispatcher = this; 154cdf0e10cSrcweir return xDispatcher; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 158cdf0e10cSrcweir 159cdf0e10cSrcweir /** 160cdf0e10cSrcweir @short do the same like dispatch() but for multiple requests at the same time 161cdf0e10cSrcweir @descr - 162cdf0e10cSrcweir 163cdf0e10cSrcweir @modified 02.05.2002 15:27, as96863 164cdf0e10cSrcweir */ 165cdf0e10cSrcweir css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL ServiceHandler::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir sal_Int32 nCount = lDescriptor.getLength(); 168cdf0e10cSrcweir css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount ); 169cdf0e10cSrcweir for( sal_Int32 i=0; i<nCount; ++i ) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir lDispatcher[i] = this->queryDispatch( 172cdf0e10cSrcweir lDescriptor[i].FeatureURL, 173cdf0e10cSrcweir lDescriptor[i].FrameName, 174cdf0e10cSrcweir lDescriptor[i].SearchFlags); 175cdf0e10cSrcweir } 176cdf0e10cSrcweir return lDispatcher; 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 180cdf0e10cSrcweir 181cdf0e10cSrcweir /** 182cdf0e10cSrcweir @short dispatch URL with arguments 183cdf0e10cSrcweir @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it. 184cdf0e10cSrcweir Because we doesn't support status listener notifications here. 185cdf0e10cSrcweir 186cdf0e10cSrcweir @param aURL 187cdf0e10cSrcweir uno URL which should be executed 188cdf0e10cSrcweir @param lArguments 189cdf0e10cSrcweir list of optional arguments for this request 190cdf0e10cSrcweir 191cdf0e10cSrcweir @modified 02.05.2002 08:19, as96863 192cdf0e10cSrcweir */ 193cdf0e10cSrcweir void SAL_CALL ServiceHandler::dispatch( const css::util::URL& aURL , 194cdf0e10cSrcweir const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException ) 195cdf0e10cSrcweir { 19607a3d7f1SPedro Giffuni // dispatch() is an [oneway] call ... and may our user release his reference to us immediately. 197cdf0e10cSrcweir // So we should hold us self alive till this call ends. 198cdf0e10cSrcweir css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 199cdf0e10cSrcweir implts_dispatch(aURL,lArguments); 200cdf0e10cSrcweir // No notification for status listener! 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 204cdf0e10cSrcweir 205cdf0e10cSrcweir /** 206cdf0e10cSrcweir @short dispatch with guaranteed notifications about success 207cdf0e10cSrcweir @descr We use threadsafe internal method to do so. Return state of this function will be used 208cdf0e10cSrcweir for notification if an optional listener is given. 209cdf0e10cSrcweir 210cdf0e10cSrcweir @param aURL 211cdf0e10cSrcweir uno URL which should be executed 212cdf0e10cSrcweir @param lArguments 213cdf0e10cSrcweir list of optional arguments for this request 214cdf0e10cSrcweir @param xListener 215cdf0e10cSrcweir optional listener for state events 216cdf0e10cSrcweir 217cdf0e10cSrcweir @modified 30.04.2002 14:49, as96863 218cdf0e10cSrcweir */ 219cdf0e10cSrcweir void SAL_CALL ServiceHandler::dispatchWithNotification( const css::util::URL& aURL , 220cdf0e10cSrcweir const css::uno::Sequence< css::beans::PropertyValue >& lArguments, 221cdf0e10cSrcweir const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException ) 222cdf0e10cSrcweir { 22307a3d7f1SPedro Giffuni // This class was designed to die by reference. And if user release his reference to us immediately after calling this method 224cdf0e10cSrcweir // we can run into some problems. So we hold us self alive till this method ends. 225cdf0e10cSrcweir // Another reason: We can use this reference as source of sending event at the end too. 226cdf0e10cSrcweir css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 227cdf0e10cSrcweir 228cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > xService = implts_dispatch(aURL,lArguments); 229cdf0e10cSrcweir if (xListener.is()) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir css::frame::DispatchResultEvent aEvent; 232cdf0e10cSrcweir if (xService.is()) 233cdf0e10cSrcweir aEvent.State = css::frame::DispatchResultState::SUCCESS; 234cdf0e10cSrcweir else 235cdf0e10cSrcweir aEvent.State = css::frame::DispatchResultState::FAILURE; 236cdf0e10cSrcweir aEvent.Result <<= xService; // may NULL for state=FAILED! 237cdf0e10cSrcweir aEvent.Source = xThis; 238cdf0e10cSrcweir 239cdf0e10cSrcweir xListener->dispatchFinished( aEvent ); 240cdf0e10cSrcweir } 241cdf0e10cSrcweir } 242cdf0e10cSrcweir 243cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 244cdf0e10cSrcweir 245cdf0e10cSrcweir /** 246cdf0e10cSrcweir @short threadsafe helper for dispatch calls 247cdf0e10cSrcweir @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal 248cdf0e10cSrcweir function. It implements the real dispatch operation and returns a state value which inform caller 249cdf0e10cSrcweir about success. He can notify listener then by using this return value. 250cdf0e10cSrcweir 251cdf0e10cSrcweir @param aURL 252cdf0e10cSrcweir uno URL which should be executed 253cdf0e10cSrcweir @param lArguments 254cdf0e10cSrcweir list of optional arguments for this request 255cdf0e10cSrcweir 256cdf0e10cSrcweir @return <NULL/> if requested service couldn't be created successullfy; 257cdf0e10cSrcweir a valid reference otherwise. This return value can be used to indicate, 258cdf0e10cSrcweir if dispatch was successfully or not. 259cdf0e10cSrcweir 260cdf0e10cSrcweir @modified 02.05.2002 10:51, as96863 261cdf0e10cSrcweir */ 262cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > ServiceHandler::implts_dispatch( const css::util::URL& aURL , 263cdf0e10cSrcweir const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException ) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir /* SAFE */ 266cdf0e10cSrcweir ReadGuard aReadLock( m_aLock ); 267cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory; 268cdf0e10cSrcweir aReadLock.unlock(); 269cdf0e10cSrcweir /* SAFE */ 270cdf0e10cSrcweir 271cdf0e10cSrcweir if (!xFactory.is()) 272cdf0e10cSrcweir return css::uno::Reference< css::uno::XInterface >(); 273cdf0e10cSrcweir 274cdf0e10cSrcweir // extract service name and may optional given parameters from given URL 275cdf0e10cSrcweir // and use it to create and start the component 276cdf0e10cSrcweir ::rtl::OUString sServiceAndArguments = aURL.Complete.copy(PROTOCOL_LENGTH); 277cdf0e10cSrcweir ::rtl::OUString sServiceName; 278cdf0e10cSrcweir ::rtl::OUString sArguments ; 279cdf0e10cSrcweir 280cdf0e10cSrcweir sal_Int32 nArgStart = sServiceAndArguments.indexOf('?',0); 281cdf0e10cSrcweir if (nArgStart!=-1) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir sServiceName = sServiceAndArguments.copy(0,nArgStart); 284cdf0e10cSrcweir ++nArgStart; // ignore '?'! 285cdf0e10cSrcweir sArguments = sServiceAndArguments.copy(nArgStart); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir else 288cdf0e10cSrcweir { 289cdf0e10cSrcweir sServiceName = sServiceAndArguments; 290cdf0e10cSrcweir } 291cdf0e10cSrcweir 292cdf0e10cSrcweir if (!sServiceName.getLength()) 293cdf0e10cSrcweir return css::uno::Reference< css::uno::XInterface >(); 294cdf0e10cSrcweir 29507a3d7f1SPedro Giffuni // If a service doesn't support an optional job executor interface - he can't get 296cdf0e10cSrcweir // any given parameters! 297cdf0e10cSrcweir // Because we can't know if we must call createInstanceWithArguments() or XJobExecutor::trigger() ... 298cdf0e10cSrcweir 299cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > xService; 300cdf0e10cSrcweir try 301cdf0e10cSrcweir { 302cdf0e10cSrcweir // => a) a service starts running inside his own ctor and we create it only 303cdf0e10cSrcweir xService = xFactory->createInstance(sServiceName); 304cdf0e10cSrcweir // or b) he implements the right interface and starts there (may with optional parameters) 305cdf0e10cSrcweir css::uno::Reference< css::task::XJobExecutor > xExecuteable(xService, css::uno::UNO_QUERY); 306cdf0e10cSrcweir if (xExecuteable.is()) 307cdf0e10cSrcweir xExecuteable->trigger(sArguments); 308cdf0e10cSrcweir } 309cdf0e10cSrcweir // ignore all errors - inclusive runtime errors! 310cdf0e10cSrcweir // E.g. a script based service (written in phyton) could not be executed 311cdf0e10cSrcweir // because it contains syntax errors, which was detected at runtime ... 312cdf0e10cSrcweir catch(const css::uno::Exception&) 313cdf0e10cSrcweir { xService.clear(); } 314cdf0e10cSrcweir 315cdf0e10cSrcweir return xService; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir 318cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 319cdf0e10cSrcweir 320cdf0e10cSrcweir /** 321cdf0e10cSrcweir @short add/remove listener for state events 322cdf0e10cSrcweir @descr We use an internal container to hold such registered listener. This container lives if we live. 323cdf0e10cSrcweir And if call pas registration as non breakable transaction - we can accept the request without 324cdf0e10cSrcweir any explicit lock. Because we share our mutex with this container. 325cdf0e10cSrcweir 326cdf0e10cSrcweir @param xListener 327cdf0e10cSrcweir reference to a valid listener for state events 328cdf0e10cSrcweir @param aURL 32907a3d7f1SPedro Giffuni URL about listener will be informed, if something occurred 330cdf0e10cSrcweir 331cdf0e10cSrcweir @modified 30.04.2002 14:49, as96863 332cdf0e10cSrcweir */ 333cdf0e10cSrcweir void SAL_CALL ServiceHandler::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 334cdf0e10cSrcweir const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 335cdf0e10cSrcweir { 336cdf0e10cSrcweir // not suported yet 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 340cdf0e10cSrcweir 341cdf0e10cSrcweir void SAL_CALL ServiceHandler::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 342cdf0e10cSrcweir const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir // not suported yet 345cdf0e10cSrcweir } 346cdf0e10cSrcweir 347cdf0e10cSrcweir } // namespace framework 348