/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.marketplace.app.manager.web.internal.portlet;
import com.liferay.application.list.PanelAppRegistry;
import com.liferay.application.list.PanelCategoryRegistry;
import com.liferay.application.list.constants.ApplicationListWebKeys;
import com.liferay.application.list.display.context.logic.PanelCategoryHelper;
import com.liferay.marketplace.app.manager.web.internal.constants.MarketplaceAppManagerPortletKeys;
import com.liferay.marketplace.app.manager.web.internal.util.BundleUtil;
import com.liferay.marketplace.bundle.BundleManagerUtil;
import com.liferay.marketplace.exception.FileExtensionException;
import com.liferay.marketplace.service.AppService;
import com.liferay.portal.kernel.deploy.DeployManagerUtil;
import com.liferay.portal.kernel.model.LayoutTemplate;
import com.liferay.portal.kernel.model.Plugin;
import com.liferay.portal.kernel.model.PluginSetting;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.model.Theme;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.service.PluginSettingLocalService;
import com.liferay.portal.kernel.service.PluginSettingService;
import com.liferay.portal.kernel.service.PortletService;
import com.liferay.portal.kernel.servlet.ServletContextPool;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.upload.UploadException;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.Http;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.WebKeys;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.osgi.framework.Bundle;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Ryan Park
* @author Joan Kim
*/
@Component(
immediate = true,
property = {
"com.liferay.portlet.css-class-wrapper=marketplace-app-manager-portlet",
"com.liferay.portlet.display-category=category.hidden",
"com.liferay.portlet.header-portlet-css=/css/main.css",
"com.liferay.portlet.icon=/icons/marketplace_app_manager.png",
"com.liferay.portlet.preferences-owned-by-group=false",
"com.liferay.portlet.private-request-attributes=false",
"com.liferay.portlet.private-session-attributes=false",
"com.liferay.portlet.render-weight=50",
"com.liferay.portlet.use-default-template=true",
"javax.portlet.description=", "javax.portlet.display-name=App Manager",
"javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.name=" + MarketplaceAppManagerPortletKeys.MARKETPLACE_APP_MANAGER,
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=administrator,guest,power-user,user",
"javax.portlet.supports.mime-type=text/html"
},
service = {javax.portlet.Portlet.class}
)
public class MarketplaceAppManagerPortlet extends MVCPortlet {
public void activateBundles(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
long[] bundleIds = StringUtil.split(
ParamUtil.getString(actionRequest, "bundleIds"), 0L);
List<Bundle> bundles = BundleManagerUtil.getInstalledBundles();
for (Bundle bundle : bundles) {
if (BundleUtil.isFragment(bundle)) {
continue;
}
if (ArrayUtil.contains(bundleIds, bundle.getBundleId())) {
bundle.start();
}
}
}
public void deactivateBundles(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
long[] bundleIds = StringUtil.split(
ParamUtil.getString(actionRequest, "bundleIds"), 0L);
List<Bundle> bundles = BundleManagerUtil.getInstalledBundles();
for (Bundle bundle : bundles) {
if (BundleUtil.isFragment(bundle)) {
continue;
}
if (ArrayUtil.contains(bundleIds, bundle.getBundleId())) {
bundle.stop();
}
}
}
public void installLocalApp(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
UploadPortletRequest uploadPortletRequest =
_portal.getUploadPortletRequest(actionRequest);
String fileName = GetterUtil.getString(
uploadPortletRequest.getFileName("file"));
File file = uploadPortletRequest.getFile("file");
byte[] bytes = FileUtil.getBytes(file);
if (ArrayUtil.isEmpty(bytes)) {
SessionErrors.add(actionRequest, UploadException.class.getName());
}
else if (!fileName.endsWith(".jar") && !fileName.endsWith(".lpkg") &&
!fileName.endsWith(".war")) {
throw new FileExtensionException();
}
else {
String deployDir = PrefsPropsUtil.getString(
PropsKeys.AUTO_DEPLOY_DEPLOY_DIR);
FileUtil.copyFile(
file.toString(), deployDir + StringPool.SLASH + fileName);
SessionMessages.add(actionRequest, "pluginUploaded");
}
sendRedirect(actionRequest, actionResponse);
}
public void installRemoteApp(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
try {
String url = ParamUtil.getString(actionRequest, "url");
URL urlObj = new URL(url);
String host = urlObj.getHost();
if (host.endsWith("sf.net") || host.endsWith("sourceforge.net")) {
doInstallSourceForgeApp(urlObj.getPath(), actionRequest);
}
else {
doInstallRemoteApp(url, actionRequest, true);
}
}
catch (MalformedURLException murle) {
SessionErrors.add(actionRequest, "invalidURL", murle);
}
}
@Override
public void processAction(
ActionRequest actionRequest, ActionResponse actionResponse)
throws IOException, PortletException {
checkOmniAdmin();
super.processAction(actionRequest, actionResponse);
}
@Override
public void render(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
checkOmniAdmin();
super.render(renderRequest, renderResponse);
}
@Override
public void serveResource(
ResourceRequest resourceRequest, ResourceResponse resourceResponse)
throws IOException, PortletException {
checkOmniAdmin();
super.serveResource(resourceRequest, resourceResponse);
}
public void uninstallApp(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
long remoteAppId = ParamUtil.getLong(actionRequest, "remoteAppId");
if (remoteAppId > 0) {
_appService.uninstallApp(remoteAppId);
}
else {
String[] contextNames = StringUtil.split(
ParamUtil.getString(actionRequest, "contextNames"));
for (String contextName : contextNames) {
DeployManagerUtil.undeploy(contextName);
}
}
SessionMessages.add(actionRequest, "triggeredPortletUndeploy");
}
public void uninstallBundles(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
long[] bundleIds = StringUtil.split(
ParamUtil.getString(actionRequest, "bundleIds"), 0L);
List<Bundle> bundles = BundleManagerUtil.getInstalledBundles();
for (Bundle bundle : bundles) {
if (ArrayUtil.contains(bundleIds, bundle.getBundleId())) {
bundle.uninstall();
}
}
}
public void updatePluginSetting(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String pluginId = ParamUtil.getString(actionRequest, "pluginId");
String pluginType = ParamUtil.getString(actionRequest, "pluginType");
String[] roles = StringUtil.split(
ParamUtil.getString(actionRequest, "roles"), CharPool.NEW_LINE);
Arrays.sort(roles);
boolean active = ParamUtil.getBoolean(actionRequest, "active");
if (pluginType.equals(Plugin.TYPE_PORTLET)) {
_portletService.updatePortlet(
themeDisplay.getCompanyId(), pluginId, StringPool.BLANK,
active);
}
else {
if (roles.length == 0) {
PluginSetting pluginSetting =
_pluginSettingLocalService.getPluginSetting(
themeDisplay.getCompanyId(), pluginId, pluginType);
roles = StringUtil.split(pluginSetting.getRoles());
}
_pluginSettingService.updatePluginSetting(
themeDisplay.getCompanyId(), pluginId, pluginType,
StringUtil.merge(roles), active);
}
}
public void updatePluginSettings(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String[] contextNames = StringUtil.split(
ParamUtil.getString(actionRequest, "contextNames"));
boolean active = ParamUtil.getBoolean(actionRequest, "active");
for (String contextName : contextNames) {
ServletContext servletContext = ServletContextPool.get(contextName);
List<LayoutTemplate> layoutTemplates =
(List<LayoutTemplate>)servletContext.getAttribute(
WebKeys.PLUGIN_LAYOUT_TEMPLATES);
if (layoutTemplates != null) {
for (LayoutTemplate layoutTemplate : layoutTemplates) {
PluginSetting pluginSetting =
_pluginSettingLocalService.getPluginSetting(
themeDisplay.getCompanyId(),
layoutTemplate.getLayoutTemplateId(),
Plugin.TYPE_LAYOUT_TEMPLATE);
_pluginSettingService.updatePluginSetting(
themeDisplay.getCompanyId(),
layoutTemplate.getLayoutTemplateId(),
Plugin.TYPE_LAYOUT_TEMPLATE, pluginSetting.getRoles(),
active);
}
}
List<Portlet> portlets = (List<Portlet>)servletContext.getAttribute(
WebKeys.PLUGIN_PORTLETS);
if (portlets != null) {
for (Portlet portlet : portlets) {
_portletService.updatePortlet(
themeDisplay.getCompanyId(), portlet.getPortletId(),
StringPool.BLANK, active);
}
}
List<Theme> themes = (List<Theme>)servletContext.getAttribute(
WebKeys.PLUGIN_THEMES);
if (themes != null) {
for (Theme theme : themes) {
PluginSetting pluginSetting =
_pluginSettingLocalService.getPluginSetting(
themeDisplay.getCompanyId(), theme.getThemeId(),
Plugin.TYPE_THEME);
_pluginSettingService.updatePluginSetting(
themeDisplay.getCompanyId(), theme.getThemeId(),
Plugin.TYPE_THEME, pluginSetting.getRoles(), active);
}
}
}
}
protected void checkOmniAdmin() throws PortletException {
PermissionChecker permissionChecker =
PermissionThreadLocal.getPermissionChecker();
if (!permissionChecker.isOmniadmin()) {
PrincipalException principalException =
new PrincipalException.MustBeCompanyAdmin(
permissionChecker.getUserId());
throw new PortletException(principalException);
}
}
@Override
protected void doDispatch(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
renderRequest.setAttribute(
ApplicationListWebKeys.PANEL_APP_REGISTRY, _panelAppRegistry);
PanelCategoryHelper panelCategoryHelper = new PanelCategoryHelper(
_panelAppRegistry, _panelCategoryRegistry);
renderRequest.setAttribute(
ApplicationListWebKeys.PANEL_CATEGORY_HELPER, panelCategoryHelper);
renderRequest.setAttribute(
ApplicationListWebKeys.PANEL_CATEGORY_REGISTRY,
_panelCategoryRegistry);
super.doDispatch(renderRequest, renderResponse);
}
protected int doInstallRemoteApp(
String url, ActionRequest actionRequest, boolean failOnError)
throws Exception {
int responseCode = HttpServletResponse.SC_OK;
try {
String fileName = null;
Http.Options options = new Http.Options();
options.setFollowRedirects(false);
options.setLocation(url);
options.setPost(false);
byte[] bytes = _http.URLtoByteArray(options);
Http.Response response = options.getResponse();
responseCode = response.getResponseCode();
if ((responseCode == HttpServletResponse.SC_OK) &&
(bytes.length > 0)) {
String deployDir = PrefsPropsUtil.getString(
PropsKeys.AUTO_DEPLOY_DEPLOY_DIR);
String destination = deployDir + StringPool.SLASH + fileName;
File destinationFile = new File(destination);
FileUtil.write(destinationFile, bytes);
SessionMessages.add(actionRequest, "pluginDownloaded");
}
else {
if (failOnError) {
SessionErrors.add(
actionRequest, UploadException.class.getName());
}
responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
}
}
catch (MalformedURLException murle) {
SessionErrors.add(actionRequest, "invalidUrl", murle);
}
catch (IOException ioe) {
SessionErrors.add(actionRequest, "errorConnectingToUrl", ioe);
}
return responseCode;
}
protected void doInstallSourceForgeApp(
String path, ActionRequest actionRequest)
throws Exception {
String[] sourceForgeMirrors = PropsUtil.getArray(
PropsKeys.SOURCE_FORGE_MIRRORS);
for (int i = 0; i < sourceForgeMirrors.length; i++) {
try {
String url = sourceForgeMirrors[i] + path;
boolean failOnError = false;
if ((i + 1) == sourceForgeMirrors.length) {
failOnError = true;
}
int responseCode = doInstallRemoteApp(
url, actionRequest, failOnError);
if (responseCode == HttpServletResponse.SC_OK) {
return;
}
}
catch (MalformedURLException murle) {
SessionErrors.add(actionRequest, "invalidUrl", murle);
}
}
}
@Reference(unbind = "-")
protected void setAppService(AppService appService) {
_appService = appService;
}
@Reference(unbind = "-")
protected void setPanelAppRegistry(PanelAppRegistry panelAppRegistry) {
_panelAppRegistry = panelAppRegistry;
}
@Reference(unbind = "-")
protected void setPanelCategoryRegistry(
PanelCategoryRegistry panelCategoryRegistry) {
_panelCategoryRegistry = panelCategoryRegistry;
}
@Reference(unbind = "-")
protected void setPluginSettingLocalService(
PluginSettingLocalService pluginSettingLocalService) {
_pluginSettingLocalService = pluginSettingLocalService;
}
@Reference(unbind = "-")
protected void setPluginSettingService(
PluginSettingService pluginSettingService) {
_pluginSettingService = pluginSettingService;
}
@Reference(unbind = "-")
protected void setPortletService(PortletService portletService) {
_portletService = portletService;
}
private static final String _DEPLOY_TO_PREFIX = "DEPLOY_TO__";
private AppService _appService;
@Reference
private Http _http;
private PanelAppRegistry _panelAppRegistry;
private PanelCategoryRegistry _panelCategoryRegistry;
private PluginSettingLocalService _pluginSettingLocalService;
private PluginSettingService _pluginSettingService;
@Reference
private Portal _portal;
private PortletService _portletService;
}