Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : //_______________________________________________
31 : : // include own header
32 : :
33 : : #include <jobs/shelljob.hxx>
34 : : #include <jobs/jobconst.hxx>
35 : : #include <threadhelp/readguard.hxx>
36 : : #include <services.h>
37 : :
38 : : //_______________________________________________
39 : : // include others
40 : :
41 : : #include <osl/file.hxx>
42 : : #include <osl/process.h>
43 : : #include <vcl/svapp.hxx>
44 : : #include <rtl/ustrbuf.hxx>
45 : : #include <comphelper/componentcontext.hxx>
46 : : #include <comphelper/sequenceashashmap.hxx>
47 : :
48 : : //_______________________________________________
49 : : // include interfaces
50 : :
51 : : #include <com/sun/star/util/PathSubstitution.hpp>
52 : : #include <com/sun/star/util/XStringSubstitution.hpp>
53 : :
54 : :
55 : : namespace framework{
56 : :
57 : :
58 : : /** address job configuration inside argument set provided on method execute(). */
59 : 0 : static const ::rtl::OUString PROP_JOBCONFIG("JobConfig");
60 : :
61 : : /** address job configuration property "Command". */
62 : 0 : static const ::rtl::OUString PROP_COMMAND("Command");
63 : :
64 : : /** address job configuration property "Arguments". */
65 : 0 : static const ::rtl::OUString PROP_ARGUMENTS("Arguments");
66 : :
67 : : /** address job configuration property "DeactivateJobIfDone". */
68 : 0 : static const ::rtl::OUString PROP_DEACTIVATEJOBIFDONE("DeactivateJobIfDone");
69 : :
70 : : /** address job configuration property "CheckExitCode". */
71 : 0 : static const ::rtl::OUString PROP_CHECKEXITCODE("CheckExitCode");
72 : :
73 : : //-----------------------------------------------
74 : :
75 : 0 : DEFINE_XSERVICEINFO_MULTISERVICE(ShellJob ,
76 : : ::cppu::OWeakObject ,
77 : : SERVICENAME_JOB ,
78 : : IMPLEMENTATIONNAME_SHELLJOB)
79 : :
80 : 0 : DEFINE_INIT_SERVICE(ShellJob,
81 : : {
82 : : /* Attention
83 : : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
84 : : to create a new instance of this class by our own supported service factory.
85 : : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
86 : : */
87 : : }
88 : : )
89 : :
90 : : //-----------------------------------------------
91 : 0 : ShellJob::ShellJob(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
92 : : : ThreadHelpBase( )
93 : 0 : , m_xSMGR (xSMGR)
94 : : {
95 : 0 : }
96 : :
97 : : //-----------------------------------------------
98 : 0 : ShellJob::~ShellJob()
99 : : {
100 : 0 : }
101 : :
102 : : //-----------------------------------------------
103 : 0 : css::uno::Any SAL_CALL ShellJob::execute(const css::uno::Sequence< css::beans::NamedValue >& lJobArguments)
104 : : throw(css::lang::IllegalArgumentException,
105 : : css::uno::Exception ,
106 : : css::uno::RuntimeException )
107 : : {
108 : 0 : ::comphelper::SequenceAsHashMap lArgs (lJobArguments);
109 : 0 : ::comphelper::SequenceAsHashMap lOwnCfg(lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG, css::uno::Sequence< css::beans::NamedValue >()));
110 : :
111 : 0 : const ::rtl::OUString sCommand = lOwnCfg.getUnpackedValueOrDefault(PROP_COMMAND , ::rtl::OUString());
112 : 0 : const css::uno::Sequence< ::rtl::OUString > lCommandArguments = lOwnCfg.getUnpackedValueOrDefault(PROP_ARGUMENTS , css::uno::Sequence< ::rtl::OUString >());
113 : 0 : const ::sal_Bool bDeactivateJobIfDone = lOwnCfg.getUnpackedValueOrDefault(PROP_DEACTIVATEJOBIFDONE , sal_True );
114 : 0 : const ::sal_Bool bCheckExitCode = lOwnCfg.getUnpackedValueOrDefault(PROP_CHECKEXITCODE , sal_True );
115 : :
116 : : // replace all might existing place holder.
117 : 0 : ::rtl::OUString sRealCommand = impl_substituteCommandVariables(sCommand);
118 : :
119 : : // Command is required as minimum.
120 : : // If it does not exists ... we cant do our job.
121 : : // Deactivate such miss configured job silently .-)
122 : 0 : if (sRealCommand.isEmpty())
123 : 0 : return ShellJob::impl_generateAnswer4Deactivation();
124 : :
125 : : // do it
126 : 0 : ::sal_Bool bDone = impl_execute(sRealCommand, lCommandArguments, bCheckExitCode);
127 : 0 : if (! bDone)
128 : 0 : return css::uno::Any();
129 : :
130 : : // Job was done ... user configured deactivation of this job
131 : : // in such case.
132 : 0 : if (bDeactivateJobIfDone)
133 : 0 : return ShellJob::impl_generateAnswer4Deactivation();
134 : :
135 : : // There was no decision about deactivation of this job.
136 : : // So we have to return nothing here !
137 : 0 : return css::uno::Any();
138 : : }
139 : :
140 : : //-----------------------------------------------
141 : 0 : css::uno::Any ShellJob::impl_generateAnswer4Deactivation()
142 : : {
143 : 0 : css::uno::Sequence< css::beans::NamedValue > aAnswer(1);
144 : 0 : aAnswer[0].Name = JobConst::ANSWER_DEACTIVATE_JOB();
145 : 0 : aAnswer[0].Value = css::uno::makeAny(sal_True);
146 : :
147 : 0 : return css::uno::makeAny(aAnswer);
148 : : }
149 : :
150 : : //-----------------------------------------------
151 : 0 : ::rtl::OUString ShellJob::impl_substituteCommandVariables(const ::rtl::OUString& sCommand)
152 : : {
153 : : // SYNCHRONIZED ->
154 : 0 : ReadGuard aReadLock(m_aLock);
155 : 0 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
156 : 0 : aReadLock.unlock();
157 : : // <- SYNCHRONIZED
158 : :
159 : : try
160 : : {
161 : 0 : css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::ComponentContext(xSMGR).getUNOContext() );
162 : 0 : css::uno::Reference< css::util::XStringSubstitution > xSubst( css::util::PathSubstitution::create(xContext) );
163 : 0 : const ::sal_Bool bSubstRequired = sal_True;
164 : 0 : const ::rtl::OUString sCompleteCommand = xSubst->substituteVariables(sCommand, bSubstRequired);
165 : :
166 : 0 : return sCompleteCommand;
167 : : }
168 : 0 : catch(const css::uno::Exception&)
169 : : {}
170 : :
171 : 0 : return ::rtl::OUString();
172 : : }
173 : :
174 : : //-----------------------------------------------
175 : 0 : ::sal_Bool ShellJob::impl_execute(const ::rtl::OUString& sCommand ,
176 : : const css::uno::Sequence< ::rtl::OUString >& lArguments ,
177 : : ::sal_Bool bCheckExitCode)
178 : : {
179 : 0 : ::rtl_uString** pArgs = NULL;
180 : 0 : const ::sal_Int32 nArgs = lArguments.getLength ();
181 : 0 : oslProcessOption nOptions = osl_Process_WAIT;
182 : 0 : oslProcess hProcess(0);
183 : :
184 : 0 : if (nArgs > 0)
185 : 0 : pArgs = reinterpret_cast< ::rtl_uString** >(const_cast< ::rtl::OUString* >(lArguments.getConstArray()));
186 : :
187 : 0 : oslProcessError eError = osl_executeProcess(sCommand.pData, pArgs, nArgs, nOptions, NULL, NULL, NULL, 0, &hProcess);
188 : :
189 : : // executable not found or couldnt be started
190 : 0 : if (eError != osl_Process_E_None)
191 : 0 : return sal_False;
192 : :
193 : 0 : ::sal_Bool bRet = sal_True;
194 : 0 : if (bCheckExitCode)
195 : : {
196 : : // check its return codes ...
197 : : oslProcessInfo aInfo;
198 : 0 : aInfo.Size = sizeof (oslProcessInfo);
199 : 0 : eError = osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo);
200 : :
201 : 0 : if (eError != osl_Process_E_None)
202 : 0 : bRet = sal_False;
203 : : else
204 : 0 : bRet = (aInfo.Code == 0);
205 : : }
206 : 0 : osl_freeProcessHandle(hProcess);
207 : 0 : return bRet;
208 : : }
209 : :
210 : 0 : } // namespace framework
211 : :
212 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|