merged tag ooo/OOO330_m14
[LibreOffice.git] / framework / source / jobs / shelljob.cxx
blobb7b6d370bb404d575aa6038abfb5ed3ad9e9ebde
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
31 //_______________________________________________
32 // include own header
34 #include <jobs/shelljob.hxx>
35 #include <jobs/jobconst.hxx>
36 #include <threadhelp/readguard.hxx>
37 #include <services.h>
39 //_______________________________________________
40 // include others
42 #include <osl/file.hxx>
43 #include <osl/process.h>
44 #include <vcl/svapp.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include <comphelper/sequenceashashmap.hxx>
48 //_______________________________________________
49 // include interfaces
51 #include <com/sun/star/system/XSystemShellExecute.hpp>
52 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
53 #include <com/sun/star/util/XStringSubstitution.hpp>
55 //_______________________________________________
56 // namespace
58 namespace framework{
60 //_______________________________________________
61 // definitions
63 /** adress job configuration inside argument set provided on method execute(). */
64 static const ::rtl::OUString PROP_JOBCONFIG = ::rtl::OUString::createFromAscii("JobConfig");
66 /** adress job configuration property "Command". */
67 static const ::rtl::OUString PROP_COMMAND = ::rtl::OUString::createFromAscii("Command");
69 /** adress job configuration property "Arguments". */
70 static const ::rtl::OUString PROP_ARGUMENTS = ::rtl::OUString::createFromAscii("Arguments");
72 /** adress job configuration property "DeactivateJobIfDone". */
73 static const ::rtl::OUString PROP_DEACTIVATEJOBIFDONE = ::rtl::OUString::createFromAscii("DeactivateJobIfDone");
75 /** adress job configuration property "CheckExitCode". */
76 static const ::rtl::OUString PROP_CHECKEXITCODE = ::rtl::OUString::createFromAscii("CheckExitCode");
78 //-----------------------------------------------
80 DEFINE_XSERVICEINFO_MULTISERVICE(ShellJob ,
81 ::cppu::OWeakObject ,
82 SERVICENAME_JOB ,
83 IMPLEMENTATIONNAME_SHELLJOB)
85 DEFINE_INIT_SERVICE(ShellJob,
87 /* Attention
88 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
89 to create a new instance of this class by our own supported service factory.
90 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
95 //-----------------------------------------------
96 ShellJob::ShellJob(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
97 : ThreadHelpBase( )
98 , m_xSMGR (xSMGR)
102 //-----------------------------------------------
103 ShellJob::~ShellJob()
107 //-----------------------------------------------
108 css::uno::Any SAL_CALL ShellJob::execute(const css::uno::Sequence< css::beans::NamedValue >& lJobArguments)
109 throw(css::lang::IllegalArgumentException,
110 css::uno::Exception ,
111 css::uno::RuntimeException )
113 ::comphelper::SequenceAsHashMap lArgs (lJobArguments);
114 ::comphelper::SequenceAsHashMap lOwnCfg(lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG, css::uno::Sequence< css::beans::NamedValue >()));
116 const ::rtl::OUString sCommand = lOwnCfg.getUnpackedValueOrDefault(PROP_COMMAND , ::rtl::OUString());
117 const css::uno::Sequence< ::rtl::OUString > lCommandArguments = lOwnCfg.getUnpackedValueOrDefault(PROP_ARGUMENTS , css::uno::Sequence< ::rtl::OUString >());
118 const ::sal_Bool bDeactivateJobIfDone = lOwnCfg.getUnpackedValueOrDefault(PROP_DEACTIVATEJOBIFDONE , sal_True );
119 const ::sal_Bool bCheckExitCode = lOwnCfg.getUnpackedValueOrDefault(PROP_CHECKEXITCODE , sal_True );
121 // replace all might existing place holder.
122 ::rtl::OUString sRealCommand = impl_substituteCommandVariables(sCommand);
124 // Command is required as minimum.
125 // If it does not exists ... we cant do our job.
126 // Deactivate such miss configured job silently .-)
127 if (sRealCommand.getLength() < 1)
128 return ShellJob::impl_generateAnswer4Deactivation();
130 // do it
131 ::sal_Bool bDone = impl_execute(sRealCommand, lCommandArguments, bCheckExitCode);
132 if (! bDone)
133 return css::uno::Any();
135 // Job was done ... user configured deactivation of this job
136 // in such case.
137 if (bDeactivateJobIfDone)
138 return ShellJob::impl_generateAnswer4Deactivation();
140 // There was no decision about deactivation of this job.
141 // So we have to return nothing here !
142 return css::uno::Any();
145 //-----------------------------------------------
146 css::uno::Any ShellJob::impl_generateAnswer4Deactivation()
148 css::uno::Sequence< css::beans::NamedValue > aAnswer(1);
149 aAnswer[0].Name = JobConst::ANSWER_DEACTIVATE_JOB();
150 aAnswer[0].Value = css::uno::makeAny(sal_True);
152 return css::uno::makeAny(aAnswer);
155 //-----------------------------------------------
156 ::rtl::OUString ShellJob::impl_substituteCommandVariables(const ::rtl::OUString& sCommand)
158 // SYNCHRONIZED ->
159 ReadGuard aReadLock(m_aLock);
160 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
161 aReadLock.unlock();
162 // <- SYNCHRONIZED
166 css::uno::Reference< css::util::XStringSubstitution > xSubst ( xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES), css::uno::UNO_QUERY_THROW);
167 const ::sal_Bool bSubstRequired = sal_True;
168 const ::rtl::OUString sCompleteCommand = xSubst->substituteVariables(sCommand, bSubstRequired);
170 return sCompleteCommand;
172 catch(const css::uno::Exception&)
175 return ::rtl::OUString();
178 //-----------------------------------------------
179 ::sal_Bool ShellJob::impl_execute(const ::rtl::OUString& sCommand ,
180 const css::uno::Sequence< ::rtl::OUString >& lArguments ,
181 ::sal_Bool bCheckExitCode)
183 ::rtl_uString** pArgs = NULL;
184 const ::sal_Int32 nArgs = lArguments.getLength ();
185 oslProcessOption nOptions = osl_Process_WAIT;
186 oslProcess hProcess(0);
188 if (nArgs > 0)
189 pArgs = reinterpret_cast< ::rtl_uString** >(const_cast< ::rtl::OUString* >(lArguments.getConstArray()));
191 oslProcessError eError = osl_executeProcess(sCommand.pData, pArgs, nArgs, nOptions, NULL, NULL, NULL, 0, &hProcess);
193 // executable not found or couldnt be started
194 if (eError != osl_Process_E_None)
195 return sal_False;
197 ::sal_Bool bRet = sal_True;
198 if (bCheckExitCode)
200 // check its return codes ...
201 oslProcessInfo aInfo;
202 aInfo.Size = sizeof (oslProcessInfo);
203 eError = osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo);
205 if (eError != osl_Process_E_None)
206 bRet = sal_False;
207 else
208 bRet = (aInfo.Code == 0);
210 osl_freeProcessHandle(hProcess);
211 return bRet;
214 } // namespace framework