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