bump product version to 4.1.6.2
[LibreOffice.git] / framework / source / jobs / shelljob.cxx
blob52583f864beaf468223c02be3810d22bfc542abc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 //_______________________________________________
22 // include own header
24 #include <jobs/shelljob.hxx>
25 #include <jobs/jobconst.hxx>
26 #include <threadhelp/readguard.hxx>
27 #include <services.h>
29 //_______________________________________________
30 // include others
32 #include <osl/file.hxx>
33 #include <osl/process.h>
34 #include <vcl/svapp.hxx>
35 #include <rtl/ustrbuf.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/sequenceashashmap.hxx>
39 //_______________________________________________
40 // include interfaces
42 #include <com/sun/star/util/PathSubstitution.hpp>
43 #include <com/sun/star/util/XStringSubstitution.hpp>
46 namespace framework{
49 /** address job configuration inside argument set provided on method execute(). */
50 static const OUString PROP_JOBCONFIG("JobConfig");
52 /** address job configuration property "Command". */
53 static const OUString PROP_COMMAND("Command");
55 /** address job configuration property "Arguments". */
56 static const OUString PROP_ARGUMENTS("Arguments");
58 /** address job configuration property "DeactivateJobIfDone". */
59 static const OUString PROP_DEACTIVATEJOBIFDONE("DeactivateJobIfDone");
61 /** address job configuration property "CheckExitCode". */
62 static const OUString PROP_CHECKEXITCODE("CheckExitCode");
64 //-----------------------------------------------
66 DEFINE_XSERVICEINFO_MULTISERVICE(ShellJob ,
67 ::cppu::OWeakObject ,
68 SERVICENAME_JOB ,
69 IMPLEMENTATIONNAME_SHELLJOB)
71 DEFINE_INIT_SERVICE(ShellJob,
73 /* Attention
74 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
75 to create a new instance of this class by our own supported service factory.
76 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
81 //-----------------------------------------------
82 ShellJob::ShellJob(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
83 : ThreadHelpBase( )
84 , m_xSMGR (xSMGR)
88 //-----------------------------------------------
89 ShellJob::~ShellJob()
93 //-----------------------------------------------
94 css::uno::Any SAL_CALL ShellJob::execute(const css::uno::Sequence< css::beans::NamedValue >& lJobArguments)
95 throw(css::lang::IllegalArgumentException,
96 css::uno::Exception ,
97 css::uno::RuntimeException )
99 ::comphelper::SequenceAsHashMap lArgs (lJobArguments);
100 ::comphelper::SequenceAsHashMap lOwnCfg(lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG, css::uno::Sequence< css::beans::NamedValue >()));
102 const OUString sCommand = lOwnCfg.getUnpackedValueOrDefault(PROP_COMMAND , OUString());
103 const css::uno::Sequence< OUString > lCommandArguments = lOwnCfg.getUnpackedValueOrDefault(PROP_ARGUMENTS , css::uno::Sequence< OUString >());
104 const ::sal_Bool bDeactivateJobIfDone = lOwnCfg.getUnpackedValueOrDefault(PROP_DEACTIVATEJOBIFDONE , sal_True );
105 const ::sal_Bool bCheckExitCode = lOwnCfg.getUnpackedValueOrDefault(PROP_CHECKEXITCODE , sal_True );
107 // replace all might existing place holder.
108 OUString sRealCommand = impl_substituteCommandVariables(sCommand);
110 // Command is required as minimum.
111 // If it does not exists ... we cant do our job.
112 // Deactivate such miss configured job silently .-)
113 if (sRealCommand.isEmpty())
114 return ShellJob::impl_generateAnswer4Deactivation();
116 // do it
117 ::sal_Bool bDone = impl_execute(sRealCommand, lCommandArguments, bCheckExitCode);
118 if (! bDone)
119 return css::uno::Any();
121 // Job was done ... user configured deactivation of this job
122 // in such case.
123 if (bDeactivateJobIfDone)
124 return ShellJob::impl_generateAnswer4Deactivation();
126 // There was no decision about deactivation of this job.
127 // So we have to return nothing here !
128 return css::uno::Any();
131 //-----------------------------------------------
132 css::uno::Any ShellJob::impl_generateAnswer4Deactivation()
134 css::uno::Sequence< css::beans::NamedValue > aAnswer(1);
135 aAnswer[0].Name = JobConst::ANSWER_DEACTIVATE_JOB();
136 aAnswer[0].Value = css::uno::makeAny(sal_True);
138 return css::uno::makeAny(aAnswer);
141 //-----------------------------------------------
142 OUString ShellJob::impl_substituteCommandVariables(const OUString& sCommand)
144 // SYNCHRONIZED ->
145 ReadGuard aReadLock(m_aLock);
146 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
147 aReadLock.unlock();
148 // <- SYNCHRONIZED
152 css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::getComponentContext(xSMGR) );
153 css::uno::Reference< css::util::XStringSubstitution > xSubst( css::util::PathSubstitution::create(xContext) );
154 const ::sal_Bool bSubstRequired = sal_True;
155 const OUString sCompleteCommand = xSubst->substituteVariables(sCommand, bSubstRequired);
157 return sCompleteCommand;
159 catch(const css::uno::Exception&)
162 return OUString();
165 //-----------------------------------------------
166 ::sal_Bool ShellJob::impl_execute(const OUString& sCommand ,
167 const css::uno::Sequence< OUString >& lArguments ,
168 ::sal_Bool bCheckExitCode)
170 ::rtl_uString** pArgs = NULL;
171 const ::sal_Int32 nArgs = lArguments.getLength ();
172 oslProcessOption nOptions = osl_Process_WAIT;
173 oslProcess hProcess(0);
175 if (nArgs > 0)
176 pArgs = reinterpret_cast< ::rtl_uString** >(const_cast< OUString* >(lArguments.getConstArray()));
178 oslProcessError eError = osl_executeProcess(sCommand.pData, pArgs, nArgs, nOptions, NULL, NULL, NULL, 0, &hProcess);
180 // executable not found or couldnt be started
181 if (eError != osl_Process_E_None)
182 return sal_False;
184 ::sal_Bool bRet = sal_True;
185 if (bCheckExitCode)
187 // check its return codes ...
188 oslProcessInfo aInfo;
189 aInfo.Size = sizeof (oslProcessInfo);
190 eError = osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo);
192 if (eError != osl_Process_E_None)
193 bRet = sal_False;
194 else
195 bRet = (aInfo.Code == 0);
197 osl_freeProcessHandle(hProcess);
198 return bRet;
201 } // namespace framework
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */