/** * 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.portal.webui.application; import java.util.Random; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.exoplatform.application.gadget.Gadget; import org.exoplatform.application.gadget.GadgetRegistryService; import org.exoplatform.commons.utils.PropertyManager; import org.exoplatform.portal.application.PortalRequestContext; import org.exoplatform.portal.config.DataStorage; import org.exoplatform.portal.config.model.ApplicationState; import org.exoplatform.portal.config.model.ApplicationType; import org.exoplatform.portal.config.model.Properties; import org.exoplatform.portal.pom.data.ModelDataStorage; import org.exoplatform.portal.webui.util.Util; 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.UIComponent; import org.exoplatform.webui.core.UIPortletApplication; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import org.exoplatform.webui.exception.MessageException; import org.gatein.common.logging.Logger; import org.gatein.common.logging.LoggerFactory; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * Created by The eXo Platform SAS Author : dang.tung tungcnw@gmail.com May 06, 2008 */ @ComponentConfig(template = "system:/groovy/portal/webui/application/UIGadget.gtmpl", events = { @EventConfig(listeners = UIGadget.SaveUserPrefActionListener.class) }) /** * This class represents user interface gadgets, it using UIGadget.gtmpl for * rendering UI in eXo. It mapped to Application model in page or container. */ public class UIGadget extends UIComponent { /** The storage id. */ private String storageId; /** The storage name. */ private String storageName; /** . */ private ApplicationState<org.exoplatform.portal.pom.spi.gadget.Gadget> state; /** . */ private String gadgetId; private Properties properties_; private JSONObject metadata_; private String url_; private final Logger log = LoggerFactory.getLogger(UIGadget.class); public static final String PREF_KEY = "_pref_gadget_"; public static final String PREF_NO_CACHE = "_pref_no_cache_"; public static final String PREF_DEBUG = "_pref_debug_"; public static final String HOME_VIEW = "home"; public static final String CANVAS_VIEW = "canvas"; public static final String METADATA_GADGETS = "gadgets"; public static final String METADATA_USERPREFS = "userPrefs"; public static final String METADATA_MODULEPREFS = "modulePrefs"; public static final String METADATA_ERROR = "error"; public static final String RPC_RESULT = "result"; public static final String METADATA_USERPREFS_TYPE = "dataType"; public static final String METADATA_USERPREFS_TYPE_HIDDEN = "hidden"; public static final String METADATA_USERPREFS_TYPE_LIST = "list"; public String view = HOME_VIEW; public static String SAVE_PREF_FAIL = "UIGadget.savePrefFail"; private static final String GTN_PREFIX = "gtn"; /** * Initializes a newly created <code>UIGadget</code> object * * @throws Exception if can't initialize object */ public UIGadget() { // That value will be overriden when it is mapped onto a data storage storageName = UUID.randomUUID().toString(); } public String getStorageId() { return storageId; } public void setStorageId(String storageId) { this.storageId = storageId; } public String getStorageName() { return storageName; } public void setStorageName(String storageName) { this.storageName = storageName; } public String getId() { return new StringBuilder().append(GTN_PREFIX).append(storageName).toString(); } public String getStandaloneURL() { PortalRequestContext portalRC = Util.getPortalRequestContext(); HttpServletRequest request = portalRC.getRequest(); StringBuilder urlBuilder = new StringBuilder(request.getScheme()); urlBuilder.append("://").append(request.getServerName()).append(":").append(request.getServerPort()); urlBuilder.append(request.getContextPath()).append("/standalone/").append(storageId); HttpServletResponse response = portalRC.getResponse(); return response.encodeURL(urlBuilder.toString()); } public ApplicationState<org.exoplatform.portal.pom.spi.gadget.Gadget> getState() { return state; } public void setState(ApplicationState<org.exoplatform.portal.pom.spi.gadget.Gadget> state) { if (state != null) { try { DataStorage ds = getApplicationComponent(DataStorage.class); String gadgetId = ds.getId(state); // this.gadgetId = gadgetId; this.state = state; } catch (Exception e) { log.error(e.getMessage(), e); } } else { this.gadgetId = null; this.state = null; } } /** * Gets name of gadget application * * @return the string represents name of gadget application */ public String getApplicationName() { return gadgetId; } /** * Gets Properties of gadget application such as locationX, locationY in desktop page * * @return all properties of gadget application * @see org.exoplatform.portal.config.model.Application * @see org.exoplatform.portal.config.model.Properties */ public Properties getProperties() { if (properties_ == null) properties_ = new Properties(); return properties_; } /** * Sets Properties of gadget application such as locationX, locationY in desktop page * * @param properties Properties that is the properties of gadget application * @see org.exoplatform.portal.config.model.Properties * @see org.exoplatform.portal.config.model.Application */ public void setProperties(Properties properties) { this.properties_ = properties; } @Deprecated public String getMetadata() { try { if (metadata_ == null) { String strMetadata = GadgetUtil.fetchGagdetRpcMetadata(getUrl()); metadata_ = new JSONObject(strMetadata); } JSONObject obj = metadata_.getJSONArray(METADATA_GADGETS).getJSONObject(0); String token = GadgetUtil.createToken(this.getUrl(), new Random().nextLong()); obj.put("secureToken", token); return metadata_.toString(); } catch (JSONException e) { return null; } } /** * Get metadata of this gadget application This metadata contains both metadata of gadget specification (.xml file) and a * token from container * * @return String represent metadata of gadget */ public String getRpcMetadata() { try { if (metadata_ == null) { metadata_ = fetchRpcMetadata(); } String token = GadgetUtil.createToken(this.getUrl(), new Random().nextLong()); metadata_.put("secureToken", token); return metadata_.toString(); } catch (JSONException e) { return null; } } private JSONObject fetchRpcMetadata() { try { String gadgetUrl = getUrl(); String strMetadata = GadgetUtil.fetchGagdetRpcMetadata(gadgetUrl); JSONObject metadata = new JSONArray(strMetadata).getJSONObject(0).getJSONObject(UIGadget.RPC_RESULT) .getJSONObject(gadgetUrl); return metadata; } catch (JSONException e) { return null; } } /** * Check if content of gadget has <UserPref>? (Content is parsed from gadget specification in .xml file) * * @return boolean */ public boolean isSettingUserPref() { try { if (metadata_ != null) { JSONObject userPrefs = metadata_.getJSONObject(METADATA_USERPREFS); JSONArray names = userPrefs.names(); int count = names.length(); if (count > 0) { for (int i = 0; i < count; i++) { JSONObject o = (JSONObject) userPrefs.get(names.get(i).toString()); String prefType = o.optString(METADATA_USERPREFS_TYPE); if (!(METADATA_USERPREFS_TYPE_HIDDEN.equalsIgnoreCase(prefType) || METADATA_USERPREFS_TYPE_LIST .equalsIgnoreCase(prefType))) return true; } return false; } } return false; } catch (Exception e) { return false; } } public boolean isLossData() { try { DataStorage service = getApplicationComponent(DataStorage.class); service.load(state, ApplicationType.GADGET); if (getApplication() == null) { throw new Exception(); } if (metadata_ == null) { metadata_ = fetchRpcMetadata(); } if (metadata_ == null || metadata_.has(METADATA_ERROR)) { throw new Exception(); } } catch (Exception e) { return true; } return false; } /** * Gets GadgetApplication by GadgedRegistryService * * @return Gadget Application * @throws Exception */ private Gadget getApplication() { try { GadgetRegistryService gadgetService = getApplicationComponent(GadgetRegistryService.class); return gadgetService.getGadget(gadgetId); } catch (Exception ex) { return null; } } /** * Gets Url of gadget application, it saved before by GadgetRegistryService * * @return url of gadget application, such as "http://www.google.com/ig/modules/horoscope.xml" */ public String getUrl() { if (url_ == null) { Gadget gadget = getApplication(); url_ = GadgetUtil.reproduceUrl(gadget.getUrl(), gadget.isLocal()); } return url_; } public boolean isNoCache() { return PropertyManager.isDevelopping(); } public boolean isDebug() { return PropertyManager.isDevelopping(); } public String getView() { if (view != null) return view; return HOME_VIEW; } public void setView(String view) { this.view = view; } /** * Gets user preference of gadget application * * @return the string represents user preference of gadget application * @throws Exception when can't convert object to string */ public String getUserPref() throws Exception { DataStorage service = getApplicationComponent(DataStorage.class); org.exoplatform.portal.pom.spi.gadget.Gadget pp = service.load(state, ApplicationType.GADGET); return pp != null ? pp.getUserPref() : null; } public void addUserPref(String addedUserPref) throws Exception { DataStorage service = getApplicationComponent(DataStorage.class); org.exoplatform.portal.pom.spi.gadget.Gadget gadget = new org.exoplatform.portal.pom.spi.gadget.Gadget(); // gadget.addUserPref(addedUserPref); // state = service.save(state, gadget); // WARNING : // This is used to force a state save and it should not be copied else where to make things // convenient as this could lead to a severe performance degradation ModelDataStorage mds = getApplicationComponent(ModelDataStorage.class); mds.save(); } /** * Initializes a newly created <code>SaveUserPrefActionListener</code> object */ public static class SaveUserPrefActionListener extends EventListener<UIGadget> { public void execute(Event<UIGadget> event) throws Exception { UIGadget uiGadget = event.getSource(); WebuiRequestContext context = WebuiRequestContext.getCurrentInstance(); // try { uiGadget.addUserPref(event.getRequestContext().getRequestParameter("userPref")); Util.getPortalRequestContext().setResponseComplete(true); } catch (Exception e) { UIPortletApplication uiPortlet = uiGadget.getAncestorOfType(UIPortletApplication.class); context.addUIComponentToUpdateByAjax(uiPortlet); context.setAttribute(UIGadget.SAVE_PREF_FAIL, true); throw new MessageException(new ApplicationMessage("UIDashboard.msg.ApplicationNotExisted", null, ApplicationMessage.ERROR)); } // if (uiGadget.isLossData()) { /* * UIPortalApplication uiApp = Util.getUIPortalApplication(); uiApp.addMessage(new * ApplicationMessage("UIDashboard.msg.ApplicationNotExisted", null)); PortalRequestContext pcontext = * Util.getPortalRequestContext(); pcontext.addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages()); */ return; } // event.getRequestContext().setResponseComplete(true); } } }