001
014
015 package com.liferay.portlet.plugininstaller.action;
016
017 import com.liferay.portal.deploy.DeployUtil;
018 import com.liferay.portal.events.GlobalStartupAction;
019 import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
020 import com.liferay.portal.kernel.deploy.auto.AutoDeployListener;
021 import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.servlet.SessionErrors;
025 import com.liferay.portal.kernel.servlet.SessionMessages;
026 import com.liferay.portal.kernel.upload.UploadPortletRequest;
027 import com.liferay.portal.kernel.util.ArrayUtil;
028 import com.liferay.portal.kernel.util.CharPool;
029 import com.liferay.portal.kernel.util.Constants;
030 import com.liferay.portal.kernel.util.FileUtil;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.HttpUtil;
033 import com.liferay.portal.kernel.util.ParamUtil;
034 import com.liferay.portal.kernel.util.PropsKeys;
035 import com.liferay.portal.kernel.util.ServerDetector;
036 import com.liferay.portal.kernel.util.StringBundler;
037 import com.liferay.portal.kernel.util.StringPool;
038 import com.liferay.portal.kernel.util.StringUtil;
039 import com.liferay.portal.kernel.util.Validator;
040 import com.liferay.portal.plugin.PluginPackageUtil;
041 import com.liferay.portal.plugin.RepositoryReport;
042 import com.liferay.portal.security.auth.PrincipalException;
043 import com.liferay.portal.security.permission.PermissionChecker;
044 import com.liferay.portal.struts.PortletAction;
045 import com.liferay.portal.theme.ThemeDisplay;
046 import com.liferay.portal.tools.deploy.BaseDeployer;
047 import com.liferay.portal.upload.ProgressInputStream;
048 import com.liferay.portal.util.HttpImpl;
049 import com.liferay.portal.util.PortalUtil;
050 import com.liferay.portal.util.PrefsPropsUtil;
051 import com.liferay.portal.util.PropsUtil;
052 import com.liferay.portal.util.PropsValues;
053 import com.liferay.portal.util.WebKeys;
054 import com.liferay.util.servlet.UploadException;
055
056 import java.io.File;
057 import java.io.FileOutputStream;
058 import java.io.IOException;
059
060 import java.net.MalformedURLException;
061 import java.net.URL;
062
063 import java.util.List;
064
065 import javax.portlet.ActionRequest;
066 import javax.portlet.ActionResponse;
067 import javax.portlet.PortletConfig;
068 import javax.portlet.PortletPreferences;
069
070 import javax.servlet.http.HttpServletResponse;
071
072 import org.apache.commons.httpclient.HostConfiguration;
073 import org.apache.commons.httpclient.HttpClient;
074 import org.apache.commons.httpclient.methods.GetMethod;
075 import org.apache.struts.action.ActionForm;
076 import org.apache.struts.action.ActionMapping;
077
078
083 public class InstallPluginAction extends PortletAction {
084
085 public void processAction(
086 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
087 ActionRequest actionRequest, ActionResponse actionResponse)
088 throws Exception {
089
090 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
091 WebKeys.THEME_DISPLAY);
092
093 PermissionChecker permissionChecker =
094 themeDisplay.getPermissionChecker();
095
096 if (!permissionChecker.isOmniadmin()) {
097 SessionErrors.add(
098 actionRequest, PrincipalException.class.getName());
099
100 setForward(actionRequest, "portlet.plugin_installer.error");
101
102 return;
103 }
104
105 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
106
107 if (cmd.equals("deployConfiguration")) {
108 deployConfiguration(actionRequest);
109 }
110 else if (cmd.equals("ignorePackages")) {
111 ignorePackages(actionRequest);
112 }
113 else if (cmd.equals("localDeploy")) {
114 localDeploy(actionRequest);
115 }
116 else if (cmd.equals("reloadRepositories")) {
117 reloadRepositories(actionRequest);
118 }
119 else if (cmd.equals("remoteDeploy")) {
120 remoteDeploy(actionRequest);
121 }
122 else if (cmd.equals("unignorePackages")) {
123 unignorePackages(actionRequest);
124 }
125 else if (cmd.equals("uninstall")) {
126 uninstall(actionRequest);
127 }
128
129 sendRedirect(actionRequest, actionResponse);
130 }
131
132 protected void deployConfiguration(ActionRequest actionRequest)
133 throws Exception {
134
135 boolean enabled = ParamUtil.getBoolean(actionRequest, "enabled");
136 String deployDir = ParamUtil.getString(actionRequest, "deployDir");
137 String destDir = ParamUtil.getString(actionRequest, "destDir");
138 long interval = ParamUtil.getLong(actionRequest, "interval");
139 int blacklistThreshold = ParamUtil.getInteger(
140 actionRequest, "blacklistThreshold");
141 boolean unpackWar = ParamUtil.getBoolean(actionRequest, "unpackWar");
142 boolean customPortletXml = ParamUtil.getBoolean(
143 actionRequest, "customPortletXml");
144 String jbossPrefix = ParamUtil.getString(actionRequest, "jbossPrefix");
145 String tomcatConfDir = ParamUtil.getString(
146 actionRequest, "tomcatConfDir");
147 String tomcatLibDir = ParamUtil.getString(
148 actionRequest, "tomcatLibDir");
149 String pluginRepositoriesTrusted = ParamUtil.getString(
150 actionRequest, "pluginRepositoriesTrusted");
151 String pluginRepositoriesUntrusted = ParamUtil.getString(
152 actionRequest, "pluginRepositoriesUntrusted");
153 boolean pluginNotificationsEnabled = ParamUtil.getBoolean(
154 actionRequest, "pluginNotificationsEnabled");
155 String pluginPackagesIgnored = ParamUtil.getString(
156 actionRequest, "pluginPackagesIgnored");
157
158 PortletPreferences preferences = PrefsPropsUtil.getPreferences();
159
160 preferences.setValue(
161 PropsKeys.AUTO_DEPLOY_ENABLED, String.valueOf(enabled));
162 preferences.setValue(PropsKeys.AUTO_DEPLOY_DEPLOY_DIR, deployDir);
163 preferences.setValue(PropsKeys.AUTO_DEPLOY_DEST_DIR, destDir);
164 preferences.setValue(
165 PropsKeys.AUTO_DEPLOY_INTERVAL, String.valueOf(interval));
166 preferences.setValue(
167 PropsKeys.AUTO_DEPLOY_BLACKLIST_THRESHOLD,
168 String.valueOf(blacklistThreshold));
169 preferences.setValue(
170 PropsKeys.AUTO_DEPLOY_UNPACK_WAR, String.valueOf(unpackWar));
171 preferences.setValue(
172 PropsKeys.AUTO_DEPLOY_CUSTOM_PORTLET_XML,
173 String.valueOf(customPortletXml));
174 preferences.setValue(PropsKeys.AUTO_DEPLOY_JBOSS_PREFIX, jbossPrefix);
175 preferences.setValue(
176 PropsKeys.AUTO_DEPLOY_TOMCAT_CONF_DIR, tomcatConfDir);
177 preferences.setValue(
178 PropsKeys.AUTO_DEPLOY_TOMCAT_LIB_DIR, tomcatLibDir);
179 preferences.setValue(
180 PropsKeys.PLUGIN_REPOSITORIES_TRUSTED, pluginRepositoriesTrusted);
181 preferences.setValue(
182 PropsKeys.PLUGIN_REPOSITORIES_UNTRUSTED,
183 pluginRepositoriesUntrusted);
184 preferences.setValue(
185 PropsKeys.PLUGIN_NOTIFICATIONS_ENABLED,
186 String.valueOf(pluginNotificationsEnabled));
187 preferences.setValue(
188 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
189 pluginPackagesIgnored);
190
191 preferences.store();
192
193 reloadRepositories(actionRequest);
194
195 if (_log.isInfoEnabled()) {
196 _log.info("Unregistering auto deploy directories");
197 }
198
199 AutoDeployUtil.unregisterDir("defaultAutoDeployDir");
200
201 if (enabled) {
202 if (_log.isInfoEnabled()) {
203 _log.info("Registering auto deploy directories");
204 }
205
206 List<AutoDeployListener> autoDeployListeners =
207 GlobalStartupAction.getAutoDeployListeners();
208
209 AutoDeployDir autoDeployDir = new AutoDeployDir(
210 "defaultAutoDeployDir", new File(deployDir), new File(destDir),
211 interval, blacklistThreshold, autoDeployListeners);
212
213 AutoDeployUtil.registerDir(autoDeployDir);
214 }
215 else {
216 if (_log.isInfoEnabled()) {
217 _log.info("Not registering auto deploy directories");
218 }
219 }
220 }
221
222 protected String[] getSourceForgeMirrors() {
223 return PropsUtil.getArray(PropsKeys.SOURCE_FORGE_MIRRORS);
224 }
225
226 protected void ignorePackages(ActionRequest actionRequest)
227 throws Exception {
228
229 String pluginPackagesIgnored = ParamUtil.getString(
230 actionRequest, "pluginPackagesIgnored");
231
232 String oldPluginPackagesIgnored= PrefsPropsUtil.getString(
233 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED);
234
235 PortletPreferences preferences = PrefsPropsUtil.getPreferences();
236
237 if (Validator.isNotNull(oldPluginPackagesIgnored)) {
238 preferences.setValue(
239 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
240 oldPluginPackagesIgnored.concat(StringPool.NEW_LINE).concat(
241 pluginPackagesIgnored));
242 }
243 else {
244 preferences.setValue(
245 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
246 pluginPackagesIgnored);
247 }
248
249 preferences.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(CharPool.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 repositoryReport =
312 PluginPackageUtil.reloadRepositories();
313
314 SessionMessages.add(
315 actionRequest, WebKeys.PLUGIN_REPOSITORY_REPORT, repositoryReport);
316 }
317
318 protected void remoteDeploy(ActionRequest actionRequest) throws Exception {
319 try {
320 String url = ParamUtil.getString(actionRequest, "url");
321
322 URL urlObj = new URL(url);
323
324 String host = urlObj.getHost();
325
326 if (host.endsWith(".sf.net") || host.endsWith(".sourceforge.net")) {
327 remoteDeploySourceForge(urlObj.getPath(), actionRequest);
328 }
329 else {
330 remoteDeploy(url, urlObj, actionRequest, true);
331 }
332 }
333 catch (MalformedURLException murle) {
334 SessionErrors.add(actionRequest, "invalidUrl", murle);
335 }
336 }
337
338 protected int remoteDeploy(
339 String url, URL urlObj, ActionRequest actionRequest,
340 boolean failOnError)
341 throws Exception {
342
343 int responseCode = HttpServletResponse.SC_OK;
344
345 GetMethod getMethod = null;
346
347 String deploymentContext = ParamUtil.getString(
348 actionRequest, "deploymentContext");
349
350 try {
351 HttpImpl httpImpl = (HttpImpl)HttpUtil.getHttp();
352
353 HostConfiguration hostConfig = httpImpl.getHostConfig(url);
354
355 HttpClient client = httpImpl.getClient(hostConfig);
356
357 getMethod = new GetMethod(url);
358
359 String fileName = null;
360
361 if (Validator.isNotNull(deploymentContext)) {
362 fileName =
363 BaseDeployer.DEPLOY_TO_PREFIX + deploymentContext + ".war";
364 }
365 else {
366 fileName = url.substring(url.lastIndexOf(CharPool.SLASH) + 1);
367
368 int pos = fileName.lastIndexOf(CharPool.PERIOD);
369
370 if (pos != -1) {
371 deploymentContext = fileName.substring(0, pos);
372 }
373 }
374
375 PluginPackageUtil.registerPluginPackageInstallation(
376 deploymentContext);
377
378 responseCode = client.executeMethod(hostConfig, getMethod);
379
380 if (responseCode != HttpServletResponse.SC_OK) {
381 if (failOnError) {
382 SessionErrors.add(
383 actionRequest, "errorConnectingToUrl",
384 new Object[] {String.valueOf(responseCode)});
385 }
386
387 return responseCode;
388 }
389
390 long contentLength = getMethod.getResponseContentLength();
391
392 String progressId = ParamUtil.getString(
393 actionRequest, Constants.PROGRESS_ID);
394
395 ProgressInputStream pis = new ProgressInputStream(
396 actionRequest, getMethod.getResponseBodyAsStream(),
397 contentLength, progressId);
398
399 String deployDir = PrefsPropsUtil.getString(
400 PropsKeys.AUTO_DEPLOY_DEPLOY_DIR,
401 PropsValues.AUTO_DEPLOY_DEPLOY_DIR);
402
403 String tmpFilePath =
404 deployDir + StringPool.SLASH + _DOWNLOAD_DIR +
405 StringPool.SLASH + fileName;
406
407 File tmpFile = new File(tmpFilePath);
408
409 if (!tmpFile.getParentFile().exists()) {
410 tmpFile.getParentFile().mkdirs();
411 }
412
413 FileOutputStream fos = new FileOutputStream(tmpFile);
414
415 try {
416 pis.readAll(fos);
417
418 if (_log.isInfoEnabled()) {
419 _log.info(
420 "Downloaded plugin from " + urlObj + " has " +
421 pis.getTotalRead() + " bytes");
422 }
423 }
424 finally {
425 pis.clearProgress();
426 }
427
428 getMethod.releaseConnection();
429
430 if (pis.getTotalRead() > 0) {
431 String destination = deployDir + StringPool.SLASH + fileName;
432
433 File destinationFile = new File(destination);
434
435 boolean moved = FileUtil.move(tmpFile, destinationFile);
436
437 if (!moved) {
438 FileUtil.copyFile(tmpFile, destinationFile);
439 FileUtil.delete(tmpFile);
440 }
441
442 SessionMessages.add(actionRequest, "pluginDownloaded");
443 }
444 else {
445 if (failOnError) {
446 SessionErrors.add(
447 actionRequest, UploadException.class.getName());
448 }
449
450 responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
451 }
452 }
453 catch (MalformedURLException murle) {
454 SessionErrors.add(actionRequest, "invalidUrl", murle);
455 }
456 catch (IOException ioe) {
457 SessionErrors.add(actionRequest, "errorConnectingToUrl", ioe);
458 }
459 finally {
460 if (getMethod != null) {
461 getMethod.releaseConnection();
462 }
463
464 PluginPackageUtil.endPluginPackageInstallation(deploymentContext);
465 }
466
467 return responseCode;
468 }
469
470 protected void remoteDeploySourceForge(
471 String path, ActionRequest actionRequest)
472 throws Exception {
473
474 String[] sourceForgeMirrors = getSourceForgeMirrors();
475
476 for (int i = 0; i < sourceForgeMirrors.length; i++) {
477 try {
478 String url = sourceForgeMirrors[i] + path;
479
480 if (_log.isDebugEnabled()) {
481 _log.debug("Downloading from SourceForge mirror " + url);
482 }
483
484 URL urlObj = new URL(url);
485
486 boolean failOnError = false;
487
488 if ((i + 1) == sourceForgeMirrors.length) {
489 failOnError = true;
490 }
491
492 int responseCode = remoteDeploy(
493 url, urlObj, actionRequest, failOnError);
494
495 if (responseCode == HttpServletResponse.SC_OK) {
496 return;
497 }
498 }
499 catch (MalformedURLException murle) {
500 SessionErrors.add(actionRequest, "invalidUrl", murle);
501 }
502 }
503 }
504
505 protected void unignorePackages(ActionRequest actionRequest)
506 throws Exception {
507
508 String[] pluginPackagesUnignored = StringUtil.split(
509 ParamUtil.getString(actionRequest, "pluginPackagesUnignored"),
510 StringPool.NEW_LINE);
511
512 String[] pluginPackagesIgnored = PrefsPropsUtil.getStringArray(
513 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED,
514 StringPool.NEW_LINE,
515 PropsValues.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED);
516
517 StringBundler sb = new StringBundler();
518
519 for (int i = 0; i < pluginPackagesIgnored.length; i++) {
520 String packageId = pluginPackagesIgnored[i];
521
522 if (!ArrayUtil.contains(pluginPackagesUnignored, packageId)) {
523 sb.append(packageId);
524 sb.append(StringPool.NEW_LINE);
525 }
526 }
527
528 PortletPreferences preferences = PrefsPropsUtil.getPreferences();
529
530 preferences.setValue(
531 PropsKeys.PLUGIN_NOTIFICATIONS_PACKAGES_IGNORED, sb.toString());
532
533 preferences.store();
534
535 PluginPackageUtil.refreshUpdatesAvailableCache();
536 }
537
538 protected void uninstall(ActionRequest actionRequest) throws Exception {
539 String appServerType = ServerDetector.getServerId();
540
541 String deploymentContext = ParamUtil.getString(
542 actionRequest, "deploymentContext");
543
544 if (appServerType.startsWith(ServerDetector.JBOSS_ID)) {
545 deploymentContext += ".war";
546 }
547
548 File deployDir = new File(
549 DeployUtil.getAutoDeployDestDir() + "/" + deploymentContext);
550
551 DeployUtil.undeploy(appServerType, deployDir);
552 }
553
554 private static final String _DOWNLOAD_DIR = "download";
555
556 private static Log _log = LogFactoryUtil.getLog(InstallPluginAction.class);
557
558 }