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