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