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