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