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 105*07a3d7f1SPedro 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 140cdf0e10cSrcweir special URL wich match his registration. He can agree by returning of a valid dispatch 141cdf0e10cSrcweir instance or disagree by returning <NULL/>. 142*07a3d7f1SPedro 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 { 196*07a3d7f1SPedro 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 { 223*07a3d7f1SPedro 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 295*07a3d7f1SPedro 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 329*07a3d7f1SPedro 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