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