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