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