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