1
22
23 package com.liferay.portlet.plugininstaller.action;
24
25 import com.liferay.portal.events.GlobalStartupAction;
26 import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
27 import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
28 import com.liferay.portal.kernel.security.permission.PermissionChecker;
29 import com.liferay.portal.kernel.util.ArrayUtil;
30 import com.liferay.portal.kernel.util.Constants;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.ParamUtil;
33 import com.liferay.portal.kernel.util.StringMaker;
34 import com.liferay.portal.kernel.util.StringPool;
35 import com.liferay.portal.kernel.util.StringUtil;
36 import com.liferay.portal.kernel.util.Validator;
37 import com.liferay.portal.plugin.PluginPackageUtil;
38 import com.liferay.portal.plugin.RepositoryReport;
39 import com.liferay.portal.security.auth.PrincipalException;
40 import com.liferay.portal.struts.PortletAction;
41 import com.liferay.portal.theme.ThemeDisplay;
42 import com.liferay.portal.tools.BaseDeployer;
43 import com.liferay.portal.util.PortalUtil;
44 import com.liferay.portal.util.PrefsPropsUtil;
45 import com.liferay.portal.util.PropsUtil;
46 import com.liferay.portal.util.PropsValues;
47 import com.liferay.portal.util.WebKeys;
48 import com.liferay.util.FileUtil;
49 import com.liferay.util.Http;
50 import com.liferay.util.servlet.ProgressInputStream;
51 import com.liferay.util.servlet.SessionErrors;
52 import com.liferay.util.servlet.SessionMessages;
53 import com.liferay.util.servlet.UploadException;
54 import com.liferay.util.servlet.UploadPortletRequest;
55
56 import java.io.File;
57 import java.io.FileOutputStream;
58 import java.io.IOException;
59
60 import java.net.MalformedURLException;
61 import java.net.URL;
62
63 import java.util.List;
64
65 import javax.portlet.ActionRequest;
66 import javax.portlet.ActionResponse;
67 import javax.portlet.PortletConfig;
68 import javax.portlet.PortletPreferences;
69
70 import javax.servlet.http.HttpServletResponse;
71
72 import org.apache.commons.httpclient.HostConfiguration;
73 import org.apache.commons.httpclient.HttpClient;
74 import org.apache.commons.httpclient.methods.GetMethod;
75 import org.apache.commons.logging.Log;
76 import org.apache.commons.logging.LogFactory;
77 import org.apache.struts.action.ActionForm;
78 import org.apache.struts.action.ActionMapping;
79
80
88 public class InstallPluginAction extends PortletAction {
89
90 public void processAction(
91 ActionMapping mapping, ActionForm form, PortletConfig config,
92 ActionRequest req, ActionResponse res)
93 throws Exception {
94
95 ThemeDisplay themeDisplay =
96 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
97
98 PermissionChecker permissionChecker =
99 themeDisplay.getPermissionChecker();
100
101 if (!permissionChecker.isOmniadmin()) {
102 SessionErrors.add(req, PrincipalException.class.getName());
103
104 setForward(req, "portlet.plugin_installer.error");
105
106 return;
107 }
108
109 String cmd = ParamUtil.getString(req, Constants.CMD);
110
111 if (cmd.equals("deployConfiguration")) {
112 deployConfiguration(req);
113 }
114 else if (cmd.equals("ignorePackages")) {
115 ignorePackages(req);
116 }
117 else if (cmd.equals("localDeploy")) {
118 localDeploy(req);
119 }
120 else if (cmd.equals("reloadRepositories")) {
121 reloadRepositories(req);
122 }
123 else if (cmd.equals("remoteDeploy")) {
124 remoteDeploy(req);
125 }
126 else if (cmd.equals("unignorePackages")) {
127 unignorePackages(req);
128 }
129
130 sendRedirect(req, res);
131 }
132
133 protected void deployConfiguration(ActionRequest req) throws Exception {
134 boolean enabled = ParamUtil.getBoolean(req, "enabled");
135 String deployDir = ParamUtil.getString(req, "deployDir");
136 String destDir = ParamUtil.getString(req, "destDir");
137 long interval = ParamUtil.getLong(req, "interval");
138 int blacklistThreshold = ParamUtil.getInteger(
139 req, "blacklistThreshold");
140 boolean unpackWar = ParamUtil.getBoolean(req, "unpackWar");
141 boolean customPortletXml = ParamUtil.getBoolean(
142 req, "customPortletXml");
143 String jbossPrefix = ParamUtil.getString(req, "jbossPrefix");
144 String tomcatConfDir = ParamUtil.getString(req, "tomcatConfDir");
145 String tomcatLibDir = ParamUtil.getString(req, "tomcatLibDir");
146 String pluginRepositoriesTrusted = ParamUtil.getString(
147 req, "pluginRepositoriesTrusted");
148 String pluginRepositoriesUntrusted = ParamUtil.getString(
149 req, "pluginRepositoriesUntrusted");
150 boolean pluginNotificationsEnabled = ParamUtil.getBoolean(
151 req, "pluginNotificationsEnabled");
152 String pluginPackagesIgnored = ParamUtil.getString(
153 req, "pluginPackagesIgnored");
154
155 PortletPreferences prefs = PrefsPropsUtil.getPreferences();
156
157 prefs.setValue(PropsUtil.AUTO_DEPLOY_ENABLED, String.valueOf(enabled));
158 prefs.setValue(PropsUtil.AUTO_DEPLOY_DEPLOY_DIR, deployDir);
159 prefs.setValue(PropsUtil.AUTO_DEPLOY_DEST_DIR, destDir);
160 prefs.setValue(
161 PropsUtil.AUTO_DEPLOY_INTERVAL, String.valueOf(interval));
162 prefs.setValue(
163 PropsUtil.AUTO_DEPLOY_BLACKLIST_THRESHOLD,
164 String.valueOf(blacklistThreshold));
165 prefs.setValue(
166 PropsUtil.AUTO_DEPLOY_UNPACK_WAR, String.valueOf(unpackWar));
167 prefs.setValue(
168 PropsUtil.AUTO_DEPLOY_CUSTOM_PORTLET_XML,
169 String.valueOf(customPortletXml));
170 prefs.setValue(PropsUtil.AUTO_DEPLOY_JBOSS_PREFIX, jbossPrefix);
171 prefs.setValue(PropsUtil.AUTO_DEPLOY_TOMCAT_CONF_DIR, tomcatConfDir);
172 prefs.setValue(PropsUtil.AUTO_DEPLOY_TOMCAT_LIB_DIR, tomcatLibDir);
173 prefs.setValue(
174 PropsUtil.PLUGIN_REPOSITORIES_TRUSTED, pluginRepositoriesTrusted);
175 prefs.setValue(
176 PropsUtil.PLUGIN_REPOSITORIES_UNTRUSTED,
177 pluginRepositoriesUntrusted);
178 prefs.setValue(
179 PropsUtil.PLUGIN_NOTIFICATIONS_ENABLED,
180 String.valueOf(pluginNotificationsEnabled));
181 prefs.setValue(
182 PropsUtil.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
183 pluginPackagesIgnored);
184
185 prefs.store();
186
187 reloadRepositories(req);
188
189 if (_log.isInfoEnabled()) {
190 _log.info("Unregistering auto deploy directories");
191 }
192
193 AutoDeployUtil.unregisterDir("defaultAutoDeployDir");
194
195 if (enabled) {
196 if (_log.isInfoEnabled()) {
197 _log.info("Registering auto deploy directories");
198 }
199
200 List autoDeployListeners =
201 GlobalStartupAction.getAutoDeployListeners();
202
203 AutoDeployDir autoDeployDir = new AutoDeployDir(
204 "defaultAutoDeployDir", new File(deployDir), new File(destDir),
205 interval, blacklistThreshold, autoDeployListeners);
206
207 AutoDeployUtil.registerDir(autoDeployDir);
208 }
209 else {
210 if (_log.isInfoEnabled()) {
211 _log.info("Not registering auto deploy directories");
212 }
213 }
214 }
215
216 protected String[] getSourceForgeMirrors() {
217 return PropsUtil.getArray(PropsUtil.SOURCE_FORGE_MIRRORS);
218 }
219
220 protected void ignorePackages(ActionRequest req) throws Exception {
221 String pluginPackagesIgnored = ParamUtil.getString(
222 req, "pluginPackagesIgnored");
223
224 String oldPluginPackagesIgnored= PrefsPropsUtil.getString(
225 PropsUtil.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED);
226
227 StringMaker sm = new StringMaker();
228
229 sm.append(oldPluginPackagesIgnored);
230 sm.append(StringPool.NEW_LINE);
231 sm.append(pluginPackagesIgnored);
232
233 PortletPreferences prefs = PrefsPropsUtil.getPreferences();
234
235 prefs.setValue(
236 PropsUtil.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED, sm.toString());
237
238 prefs.store();
239
240 PluginPackageUtil.refreshUpdatesAvailableCache();
241 }
242
243 protected void localDeploy(ActionRequest req) throws Exception {
244 UploadPortletRequest uploadReq =
245 PortalUtil.getUploadPortletRequest(req);
246
247 String fileName = null;
248
249 String deploymentContext = ParamUtil.getString(
250 req, "deploymentContext");
251
252 if (Validator.isNotNull(deploymentContext)) {
253 fileName =
254 BaseDeployer.DEPLOY_TO_PREFIX + deploymentContext + ".war";
255 }
256 else {
257 fileName = GetterUtil.getString(uploadReq.getFileName("file"));
258
259 int pos = fileName.lastIndexOf(StringPool.PERIOD);
260
261 if (pos != -1) {
262 deploymentContext = fileName.substring(0, pos);
263 }
264 }
265
266 File file = uploadReq.getFile("file");
267
268 byte[] bytes = FileUtil.getBytes(file);
269
270 if ((bytes == null) || (bytes.length == 0)) {
271 SessionErrors.add(req, UploadException.class.getName());
272
273 return;
274 }
275
276 try {
277 PluginPackageUtil.registerPluginPackageInstallation(
278 deploymentContext);
279
280 String source = file.toString();
281
282 String deployDir = PrefsPropsUtil.getString(
283 PropsUtil.AUTO_DEPLOY_DEPLOY_DIR,
284 PropsValues.AUTO_DEPLOY_DEPLOY_DIR);
285
286 String destination = deployDir + StringPool.SLASH + fileName;
287
288 FileUtil.copyFile(source, destination);
289
290 SessionMessages.add(req, "pluginUploaded");
291 }
292 finally {
293 PluginPackageUtil.endPluginPackageInstallation(deploymentContext);
294 }
295 }
296
297 protected void reloadRepositories(ActionRequest req) throws Exception {
298 RepositoryReport report = PluginPackageUtil.reloadRepositories();
299
300 SessionMessages.add(req, WebKeys.PLUGIN_REPOSITORY_REPORT, report);
301 }
302
303 protected void remoteDeploy(ActionRequest req) throws Exception {
304 try {
305 String url = ParamUtil.getString(req, "url");
306
307 URL urlObj = new URL(url);
308
309 String host = urlObj.getHost();
310
311 if (host.endsWith(".sf.net") || host.endsWith(".sourceforge.net")) {
312 remoteDeploySourceForge(urlObj.getPath(), req);
313 }
314 else {
315 remoteDeploy(url, urlObj, req, true);
316 }
317 }
318 catch (MalformedURLException murle) {
319 SessionErrors.add(req, "invalidUrl", murle);
320 }
321 }
322
323 protected int remoteDeploy(
324 String url, URL urlObj, ActionRequest req, boolean failOnError)
325 throws Exception {
326
327 int responseCode = HttpServletResponse.SC_OK;
328
329 GetMethod getMethod = null;
330
331 String deploymentContext = ParamUtil.getString(
332 req, "deploymentContext");
333
334 try {
335 HostConfiguration hostConfig = Http.getHostConfig(url);
336
337 HttpClient client = Http.getClient(hostConfig);
338
339 getMethod = new GetMethod(url);
340
341 String fileName = null;
342
343 if (Validator.isNotNull(deploymentContext)) {
344 fileName =
345 BaseDeployer.DEPLOY_TO_PREFIX + deploymentContext + ".war";
346 }
347 else {
348 fileName = url.substring(url.lastIndexOf(StringPool.SLASH) + 1);
349
350 int pos = fileName.lastIndexOf(StringPool.PERIOD);
351
352 if (pos != -1) {
353 deploymentContext = fileName.substring(0, pos);
354 }
355 }
356
357 PluginPackageUtil.registerPluginPackageInstallation(
358 deploymentContext);
359
360 responseCode = client.executeMethod(hostConfig, getMethod);
361
362 if (responseCode != HttpServletResponse.SC_OK) {
363 if (failOnError) {
364 SessionErrors.add(
365 req, "errorConnectingToUrl",
366 new Object[] {String.valueOf(responseCode)});
367 }
368
369 return responseCode;
370 }
371
372 long contentLength = getMethod.getResponseContentLength();
373
374 String progressId = ParamUtil.getString(req, Constants.PROGRESS_ID);
375
376 ProgressInputStream pis = new ProgressInputStream(
377 req, getMethod.getResponseBodyAsStream(), contentLength,
378 progressId);
379
380 String deployDir = PrefsPropsUtil.getString(
381 PropsUtil.AUTO_DEPLOY_DEPLOY_DIR,
382 PropsValues.AUTO_DEPLOY_DEPLOY_DIR);
383
384 String tmpFilePath =
385 deployDir + StringPool.SLASH + _DOWNLOAD_DIR +
386 StringPool.SLASH + fileName;
387
388 File tmpFile = new File(tmpFilePath);
389
390 if (!tmpFile.getParentFile().exists()) {
391 tmpFile.getParentFile().mkdirs();
392 }
393
394 FileOutputStream fos = new FileOutputStream(tmpFile);
395
396 try {
397 pis.readAll(fos);
398
399 if (_log.isInfoEnabled()) {
400 _log.info(
401 "Downloaded plugin from " + urlObj + " has " +
402 pis.getTotalRead() + " bytes");
403 }
404 }
405 finally {
406 pis.clearProgress();
407 }
408
409 getMethod.releaseConnection();
410
411 if (pis.getTotalRead() > 0) {
412 String destination = deployDir + StringPool.SLASH + fileName;
413
414 File destinationFile = new File(destination);
415
416 boolean moved = FileUtil.move(tmpFile, destinationFile);
417
418 if (!moved) {
419 FileUtil.copyFile(tmpFile, destinationFile);
420 FileUtil.delete(tmpFile);
421 }
422
423 SessionMessages.add(req, "pluginDownloaded");
424 }
425 else {
426 if (failOnError) {
427 SessionErrors.add(req, UploadException.class.getName());
428 }
429
430 responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
431 }
432 }
433 catch (MalformedURLException murle) {
434 SessionErrors.add(req, "invalidUrl", murle);
435 }
436 catch (IOException ioe) {
437 SessionErrors.add(req, "errorConnectingToUrl", ioe);
438 }
439 finally {
440 if (getMethod != null) {
441 getMethod.releaseConnection();
442 }
443
444 PluginPackageUtil.endPluginPackageInstallation(deploymentContext);
445 }
446
447 return responseCode;
448 }
449
450 protected void remoteDeploySourceForge(String path, ActionRequest req)
451 throws Exception {
452
453 String[] sourceForgeMirrors = getSourceForgeMirrors();
454
455 for (int i = 0; i < sourceForgeMirrors.length; i++) {
456 try {
457 String url = sourceForgeMirrors[i] + path;
458
459 if (_log.isDebugEnabled()) {
460 _log.debug("Downloading from SourceForge mirror " + url);
461 }
462
463 URL urlObj = new URL(url);
464
465 boolean failOnError = false;
466
467 if ((i + 1) == sourceForgeMirrors.length) {
468 failOnError = true;
469 }
470
471 int responseCode = remoteDeploy(url, urlObj, req, failOnError);
472
473 if (responseCode == HttpServletResponse.SC_OK) {
474 return;
475 }
476 }
477 catch (MalformedURLException murle) {
478 SessionErrors.add(req, "invalidUrl", murle);
479 }
480 }
481 }
482
483 protected void unignorePackages(ActionRequest req) throws Exception {
484 String[] pluginPackagesUnignored = StringUtil.split(
485 ParamUtil.getString(req, "pluginPackagesUnignored"),
486 StringPool.NEW_LINE);
487
488 String[] pluginPackagesIgnored = PrefsPropsUtil.getStringArray(
489 PropsUtil.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
490 StringPool.NEW_LINE,
491 PropsValues.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED);
492
493 StringMaker sm = new StringMaker();
494
495 for (int i = 0; i < pluginPackagesIgnored.length; i++) {
496 String packageId = pluginPackagesIgnored[i];
497
498 if (!ArrayUtil.contains(pluginPackagesUnignored, packageId)) {
499 sm.append(packageId);
500 sm.append(StringPool.NEW_LINE);
501 }
502 }
503
504 PortletPreferences prefs = PrefsPropsUtil.getPreferences();
505
506 prefs.setValue(
507 PropsUtil.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED, sm.toString());
508
509 prefs.store();
510
511 PluginPackageUtil.refreshUpdatesAvailableCache();
512 }
513
514 private static final String _DOWNLOAD_DIR = "download";
515
516 private static Log _log = LogFactory.getLog(InstallPluginAction.class);
517
518 }