1*6d739b60SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*6d739b60SAndrew Rist * distributed with this work for additional information 6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance 9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10*6d739b60SAndrew Rist * 11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*6d739b60SAndrew Rist * 13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*6d739b60SAndrew Rist * software distributed under the License is distributed on an 15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the 17*6d739b60SAndrew Rist * specific language governing permissions and limitations 18*6d739b60SAndrew Rist * under the License. 19*6d739b60SAndrew Rist * 20*6d739b60SAndrew Rist *************************************************************/ 21*6d739b60SAndrew Rist 22*6d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_framework.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir //_______________________________________________ 28cdf0e10cSrcweir // include own header 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include <jobs/shelljob.hxx> 31cdf0e10cSrcweir #include <jobs/jobconst.hxx> 32cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 33cdf0e10cSrcweir #include <services.h> 34cdf0e10cSrcweir 35cdf0e10cSrcweir //_______________________________________________ 36cdf0e10cSrcweir // include others 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <osl/file.hxx> 39cdf0e10cSrcweir #include <osl/process.h> 40cdf0e10cSrcweir #include <vcl/svapp.hxx> 41cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 42cdf0e10cSrcweir #include <comphelper/sequenceashashmap.hxx> 43cdf0e10cSrcweir 44cdf0e10cSrcweir //_______________________________________________ 45cdf0e10cSrcweir // include interfaces 46cdf0e10cSrcweir 47cdf0e10cSrcweir #include <com/sun/star/system/XSystemShellExecute.hpp> 48cdf0e10cSrcweir #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 49cdf0e10cSrcweir #include <com/sun/star/util/XStringSubstitution.hpp> 50cdf0e10cSrcweir 51cdf0e10cSrcweir //_______________________________________________ 52cdf0e10cSrcweir // namespace 53cdf0e10cSrcweir 54cdf0e10cSrcweir namespace framework{ 55cdf0e10cSrcweir 56cdf0e10cSrcweir //_______________________________________________ 57cdf0e10cSrcweir // definitions 58cdf0e10cSrcweir 59cdf0e10cSrcweir /** adress job configuration inside argument set provided on method execute(). */ 60cdf0e10cSrcweir static const ::rtl::OUString PROP_JOBCONFIG = ::rtl::OUString::createFromAscii("JobConfig"); 61cdf0e10cSrcweir 62cdf0e10cSrcweir /** adress job configuration property "Command". */ 63cdf0e10cSrcweir static const ::rtl::OUString PROP_COMMAND = ::rtl::OUString::createFromAscii("Command"); 64cdf0e10cSrcweir 65cdf0e10cSrcweir /** adress job configuration property "Arguments". */ 66cdf0e10cSrcweir static const ::rtl::OUString PROP_ARGUMENTS = ::rtl::OUString::createFromAscii("Arguments"); 67cdf0e10cSrcweir 68cdf0e10cSrcweir /** adress job configuration property "DeactivateJobIfDone". */ 69cdf0e10cSrcweir static const ::rtl::OUString PROP_DEACTIVATEJOBIFDONE = ::rtl::OUString::createFromAscii("DeactivateJobIfDone"); 70cdf0e10cSrcweir 71cdf0e10cSrcweir /** adress job configuration property "CheckExitCode". */ 72cdf0e10cSrcweir static const ::rtl::OUString PROP_CHECKEXITCODE = ::rtl::OUString::createFromAscii("CheckExitCode"); 73cdf0e10cSrcweir 74cdf0e10cSrcweir //----------------------------------------------- 75cdf0e10cSrcweir 76cdf0e10cSrcweir DEFINE_XSERVICEINFO_MULTISERVICE(ShellJob , 77cdf0e10cSrcweir ::cppu::OWeakObject , 78cdf0e10cSrcweir SERVICENAME_JOB , 79cdf0e10cSrcweir IMPLEMENTATIONNAME_SHELLJOB) 80cdf0e10cSrcweir 81cdf0e10cSrcweir DEFINE_INIT_SERVICE(ShellJob, 82cdf0e10cSrcweir { 83cdf0e10cSrcweir /* Attention 84cdf0e10cSrcweir I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() 85cdf0e10cSrcweir to create a new instance of this class by our own supported service factory. 86cdf0e10cSrcweir see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! 87cdf0e10cSrcweir */ 88cdf0e10cSrcweir } 89cdf0e10cSrcweir ) 90cdf0e10cSrcweir 91cdf0e10cSrcweir //----------------------------------------------- 92cdf0e10cSrcweir ShellJob::ShellJob(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 93cdf0e10cSrcweir : ThreadHelpBase( ) 94cdf0e10cSrcweir , m_xSMGR (xSMGR) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir //----------------------------------------------- 99cdf0e10cSrcweir ShellJob::~ShellJob() 100cdf0e10cSrcweir { 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 103cdf0e10cSrcweir //----------------------------------------------- 104cdf0e10cSrcweir css::uno::Any SAL_CALL ShellJob::execute(const css::uno::Sequence< css::beans::NamedValue >& lJobArguments) 105cdf0e10cSrcweir throw(css::lang::IllegalArgumentException, 106cdf0e10cSrcweir css::uno::Exception , 107cdf0e10cSrcweir css::uno::RuntimeException ) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir ::comphelper::SequenceAsHashMap lArgs (lJobArguments); 110cdf0e10cSrcweir ::comphelper::SequenceAsHashMap lOwnCfg(lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG, css::uno::Sequence< css::beans::NamedValue >())); 111cdf0e10cSrcweir 112cdf0e10cSrcweir const ::rtl::OUString sCommand = lOwnCfg.getUnpackedValueOrDefault(PROP_COMMAND , ::rtl::OUString()); 113cdf0e10cSrcweir const css::uno::Sequence< ::rtl::OUString > lCommandArguments = lOwnCfg.getUnpackedValueOrDefault(PROP_ARGUMENTS , css::uno::Sequence< ::rtl::OUString >()); 114cdf0e10cSrcweir const ::sal_Bool bDeactivateJobIfDone = lOwnCfg.getUnpackedValueOrDefault(PROP_DEACTIVATEJOBIFDONE , sal_True ); 115cdf0e10cSrcweir const ::sal_Bool bCheckExitCode = lOwnCfg.getUnpackedValueOrDefault(PROP_CHECKEXITCODE , sal_True ); 116cdf0e10cSrcweir 117cdf0e10cSrcweir // replace all might existing place holder. 118cdf0e10cSrcweir ::rtl::OUString sRealCommand = impl_substituteCommandVariables(sCommand); 119cdf0e10cSrcweir 120cdf0e10cSrcweir // Command is required as minimum. 121cdf0e10cSrcweir // If it does not exists ... we cant do our job. 122cdf0e10cSrcweir // Deactivate such miss configured job silently .-) 123cdf0e10cSrcweir if (sRealCommand.getLength() < 1) 124cdf0e10cSrcweir return ShellJob::impl_generateAnswer4Deactivation(); 125cdf0e10cSrcweir 126cdf0e10cSrcweir // do it 127cdf0e10cSrcweir ::sal_Bool bDone = impl_execute(sRealCommand, lCommandArguments, bCheckExitCode); 128cdf0e10cSrcweir if (! bDone) 129cdf0e10cSrcweir return css::uno::Any(); 130cdf0e10cSrcweir 131cdf0e10cSrcweir // Job was done ... user configured deactivation of this job 132cdf0e10cSrcweir // in such case. 133cdf0e10cSrcweir if (bDeactivateJobIfDone) 134cdf0e10cSrcweir return ShellJob::impl_generateAnswer4Deactivation(); 135cdf0e10cSrcweir 136cdf0e10cSrcweir // There was no decision about deactivation of this job. 137cdf0e10cSrcweir // So we have to return nothing here ! 138cdf0e10cSrcweir return css::uno::Any(); 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir //----------------------------------------------- 142cdf0e10cSrcweir css::uno::Any ShellJob::impl_generateAnswer4Deactivation() 143cdf0e10cSrcweir { 144cdf0e10cSrcweir css::uno::Sequence< css::beans::NamedValue > aAnswer(1); 145cdf0e10cSrcweir aAnswer[0].Name = JobConst::ANSWER_DEACTIVATE_JOB(); 146cdf0e10cSrcweir aAnswer[0].Value = css::uno::makeAny(sal_True); 147cdf0e10cSrcweir 148cdf0e10cSrcweir return css::uno::makeAny(aAnswer); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir //----------------------------------------------- 152cdf0e10cSrcweir ::rtl::OUString ShellJob::impl_substituteCommandVariables(const ::rtl::OUString& sCommand) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir // SYNCHRONIZED -> 155cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 156cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 157cdf0e10cSrcweir aReadLock.unlock(); 158cdf0e10cSrcweir // <- SYNCHRONIZED 159cdf0e10cSrcweir 160cdf0e10cSrcweir try 161cdf0e10cSrcweir { 162cdf0e10cSrcweir css::uno::Reference< css::util::XStringSubstitution > xSubst ( xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES), css::uno::UNO_QUERY_THROW); 163cdf0e10cSrcweir const ::sal_Bool bSubstRequired = sal_True; 164cdf0e10cSrcweir const ::rtl::OUString sCompleteCommand = xSubst->substituteVariables(sCommand, bSubstRequired); 165cdf0e10cSrcweir 166cdf0e10cSrcweir return sCompleteCommand; 167cdf0e10cSrcweir } 168cdf0e10cSrcweir catch(const css::uno::Exception&) 169cdf0e10cSrcweir {} 170cdf0e10cSrcweir 171cdf0e10cSrcweir return ::rtl::OUString(); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir //----------------------------------------------- 175cdf0e10cSrcweir ::sal_Bool ShellJob::impl_execute(const ::rtl::OUString& sCommand , 176cdf0e10cSrcweir const css::uno::Sequence< ::rtl::OUString >& lArguments , 177cdf0e10cSrcweir ::sal_Bool bCheckExitCode) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir ::rtl_uString** pArgs = NULL; 180cdf0e10cSrcweir const ::sal_Int32 nArgs = lArguments.getLength (); 181cdf0e10cSrcweir oslProcessOption nOptions = osl_Process_WAIT; 182cdf0e10cSrcweir oslProcess hProcess(0); 183cdf0e10cSrcweir 184cdf0e10cSrcweir if (nArgs > 0) 185cdf0e10cSrcweir pArgs = reinterpret_cast< ::rtl_uString** >(const_cast< ::rtl::OUString* >(lArguments.getConstArray())); 186cdf0e10cSrcweir 187cdf0e10cSrcweir oslProcessError eError = osl_executeProcess(sCommand.pData, pArgs, nArgs, nOptions, NULL, NULL, NULL, 0, &hProcess); 188cdf0e10cSrcweir 189cdf0e10cSrcweir // executable not found or couldnt be started 190cdf0e10cSrcweir if (eError != osl_Process_E_None) 191cdf0e10cSrcweir return sal_False; 192cdf0e10cSrcweir 193cdf0e10cSrcweir ::sal_Bool bRet = sal_True; 194cdf0e10cSrcweir if (bCheckExitCode) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir // check its return codes ... 197cdf0e10cSrcweir oslProcessInfo aInfo; 198cdf0e10cSrcweir aInfo.Size = sizeof (oslProcessInfo); 199cdf0e10cSrcweir eError = osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo); 200cdf0e10cSrcweir 201cdf0e10cSrcweir if (eError != osl_Process_E_None) 202cdf0e10cSrcweir bRet = sal_False; 203cdf0e10cSrcweir else 204cdf0e10cSrcweir bRet = (aInfo.Code == 0); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir osl_freeProcessHandle(hProcess); 207cdf0e10cSrcweir return bRet; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir } // namespace framework 211