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