/** * Copyright (C) 2009 eXo Platform SAS. * * This 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 software 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. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.applicationregistry.webui.component; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.exoplatform.commons.serialization.api.annotations.Converted; import org.exoplatform.commons.serialization.api.annotations.Serialized; import org.exoplatform.container.ExoContainer; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.web.application.ApplicationMessage; import org.exoplatform.webui.application.WebuiRequestContext; import org.exoplatform.webui.config.annotation.ComponentConfig; import org.exoplatform.webui.config.annotation.EventConfig; import org.exoplatform.webui.core.UIContainer; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import org.gatein.common.i18n.LocalizedString; import org.gatein.pc.api.Portlet; import org.gatein.pc.api.PortletContext; import org.gatein.pc.api.info.MetaInfo; import org.gatein.pc.api.info.PortletInfo; import org.gatein.pc.api.info.PreferencesInfo; import org.gatein.pc.federation.FederatingPortletInvoker; /** * Created by The eXo Platform SAS Author : Pham Thanh Tung thanhtungty@gmail.com Jun 24, 2008 */ @ComponentConfig(template = "app:/groovy/applicationregistry/webui/component/UIPortletManagement.gtmpl", events = { @EventConfig(listeners = UIPortletManagement.SelectPortletActionListener.class), @EventConfig(listeners = UIPortletManagement.SelectPortletType.class) }) @Serialized public class UIPortletManagement extends UIContainer { /** Should match WSRPPortletInfo.PRODUCER_NAME_META_INFO_KEY */ private static final String PRODUCER_NAME_META_INFO_KEY = "producer-name"; public static final String LOCAL = "local"; public static final String REMOTE = "remote"; private List<WebApp> webApps; private PortletExtra selectedPorlet; private String[] portletTypes = new String[] { LOCAL, REMOTE }; private String selectedType; private static final Comparator<WebApp> WEB_APP_COMPARATOR = new Comparator<WebApp>() { public int compare(WebApp app1, WebApp app2) { return app1.getName().compareToIgnoreCase(app2.getName()); } }; private static final Comparator<PortletExtra> PORTLET_EXTRA_COMPARATOR = new Comparator<PortletExtra>() { public int compare(PortletExtra portlet1, PortletExtra portlet2) { return portlet1.getName().compareToIgnoreCase(portlet2.getName()); } }; public UIPortletManagement() throws Exception { setSelectedType(LOCAL); } private void initWebApps(String type) throws Exception { webApps = new LinkedList<WebApp>(); // LinkedList is more appropriate here since we add lots of elements and sort // julien : who said that LinkedList is appropriate for sorting ? ExoContainer manager = ExoContainerContext.getCurrentContainer(); FederatingPortletInvoker portletInvoker = (FederatingPortletInvoker) manager .getComponentInstance(FederatingPortletInvoker.class); boolean remote = REMOTE.equals(type); Set<Portlet> portlets; if (!remote) { portlets = portletInvoker.getLocalPortlets(); } else { portlets = portletInvoker.getRemotePortlets(); } if (portlets == null || portlets.isEmpty()) { return; } for (Portlet portlet : portlets) { PortletInfo info = portlet.getInfo(); // in the remote case, the "application name" will be the name of the remote invoker String appName; if (remote) { LocalizedString producerNameLS = info.getMeta().getMetaValue(PRODUCER_NAME_META_INFO_KEY); if (producerNameLS != null) { appName = producerNameLS.getDefaultString(); } else { throw new IllegalStateException("Missing PortletInvoker id in remote portlet metadata"); } } else { appName = info.getApplicationName(); } WebApp webApp = getWebApp(appName); if (webApp == null) { webApp = new WebApp(appName); webApps.add(webApp); } webApp.addPortlet(new PortletExtra(portlet)); } Collections.sort(webApps, WEB_APP_COMPARATOR); for (WebApp ele : webApps) { Collections.sort(ele.getPortlets(), PORTLET_EXTRA_COMPARATOR); } } public WebApp getWebApp(String name) { for (WebApp ele : webApps) { if (ele.getName().equals(name)) { return ele; } } return null; } public List<WebApp> getWebApps() { return webApps; } public String getSelectedType() { return selectedType; } public void setSelectedType(String type) throws Exception { selectedType = type; initWebApps(type); if (webApps != null && !webApps.isEmpty()) { List<PortletExtra> list = webApps.get(0).getPortlets(); if (!list.isEmpty()) { setSelectedPortlet(list.get(0)); } } else { setSelectedPortlet((PortletExtra) null); } } public String[] getPortletTypes() { return portletTypes; } public PortletExtra getSelectedPortlet() { return selectedPorlet; } public void setSelectedPortlet(PortletExtra portlet) throws Exception { selectedPorlet = portlet; if (selectedPorlet == null) { getChildren().clear(); UIMessageBoard uiMessage = addChild(UIMessageBoard.class, null, null); uiMessage.setMessage(new ApplicationMessage("UIPortletManagement.msg.noPortlet", null)); return; } UIPortletInfo uiPortletInfo = getChild(UIPortletInfo.class); if (uiPortletInfo == null) { getChildren().clear(); uiPortletInfo = addChild(UIPortletInfo.class, null, null); } uiPortletInfo.setPortlet(selectedPorlet); uiPortletInfo.getChild(UICategorySelector.class).setRendered(false); } public void setSelectedPortlet(String id) throws Exception { String webAppName; String portletName; if (LOCAL.equals(selectedType)) { String[] fragments = id.split("/"); webAppName = fragments[0]; portletName = fragments[1]; } else { // extract PortletInvoker id to use as WebApp name final int separatorIndex = id.indexOf('.'); webAppName = id.substring(0, separatorIndex); portletName = id.substring(separatorIndex + 1); } WebApp webApp = getWebApp(webAppName); for (PortletExtra ele : webApp.getPortlets()) { if (ele.getName().equals(portletName)) { setSelectedPortlet(ele); break; } } } public void processRender(WebuiRequestContext context) throws Exception { super.processRender(context); } public static class SelectPortletType extends EventListener<UIPortletManagement> { public void execute(Event<UIPortletManagement> event) throws Exception { UIPortletManagement uiManagement = event.getSource(); String type = event.getRequestContext().getRequestParameter(OBJECTID); uiManagement.setSelectedType(type); event.getRequestContext().addUIComponentToUpdateByAjax(uiManagement); } } public static class SelectPortletActionListener extends EventListener<UIPortletManagement> { public void execute(Event<UIPortletManagement> event) throws Exception { UIPortletManagement uiManagement = event.getSource(); String portletId = event.getRequestContext().getRequestParameter(OBJECTID); uiManagement.setSelectedPortlet(portletId); event.getRequestContext().addUIComponentToUpdateByAjax(uiManagement); } } @Converted(PortletExtraSerializer.class) public static class PortletExtra { private String id_; private String name_; private String group_; private String type_; private PortletInfo portletInfo_; final PortletContext context; public PortletExtra(Portlet portlet) { PortletInfo info = portlet.getInfo(); context = portlet.getContext(); String appName = info.getApplicationName(); boolean remote = portlet.isRemote(); String portletId; if (remote) { portletId = context.getId(); } else { portletId = info.getApplicationName() + "/" + info.getName(); } String type = remote ? REMOTE : LOCAL; // id_ = portletId; group_ = appName; name_ = info.getName(); type_ = type; portletInfo_ = info; } public String getId() { return id_; } public String getName() { return name_; } public String getPortletGroup() { return group_; } public String getType() { return type_; } public String getDisplayName() { try { final String displayName = getMetaValue(MetaInfo.DISPLAY_NAME, name_); return isRemote() ? displayName + " (remote)" : displayName; } catch (Exception ex) { return "COULD NOT GET DISPLAY NAME OF THE PORTLET"; } } public String getDescription() { try { return getMetaValue(MetaInfo.DESCRIPTION, name_); } catch (Exception ex) { return "COULD NOT GET DESCRIPTION OF THE PORTLET"; } } public PreferencesInfo getPortletPreferences() { try { return portletInfo_.getPreferences(); } catch (Exception ex) { return null; } } private String getMetaValue(String metaKey, String defaultValue) { LocalizedString metaValue = portletInfo_.getMeta().getMetaValue(metaKey); if (metaValue == null || metaValue.getDefaultString() == null) { return defaultValue; } return metaValue.getDefaultString(); } public boolean isRemote() { return REMOTE.equals(type_); } } @Serialized public static class WebApp { String name_; List<PortletExtra> portlets_; public WebApp() { } public WebApp(String name) { name_ = name; } public WebApp(String name, List<PortletExtra> portlets) { name_ = name; portlets_ = portlets; } public String getName() { return name_; } public void setName(String name) { name_ = name; } public List<PortletExtra> getPortlets() { return portlets_; } public void setPortlets(List<PortletExtra> portlets) { portlets_ = portlets; } public void addPortlet(PortletExtra portlet) { if (portlets_ == null) { portlets_ = new ArrayList<PortletExtra>(); } portlets_.add(portlet); } } }