/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.modules.screens; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Stack; import net.sf.json.JSONArray; import org.apache.jetspeed.om.BaseSecurityReference; import org.apache.jetspeed.om.SecurityReference; import org.apache.jetspeed.om.profile.Entry; import org.apache.jetspeed.om.profile.Profile; import org.apache.jetspeed.om.profile.Skin; import org.apache.jetspeed.om.profile.psml.PsmlSkin; import org.apache.jetspeed.om.registry.Parameter; import org.apache.jetspeed.om.registry.PortletEntry; import org.apache.jetspeed.portal.Portlet; import org.apache.jetspeed.portal.PortletConfig; import org.apache.jetspeed.portal.PortletControl; import org.apache.jetspeed.portal.PortletException; import org.apache.jetspeed.portal.PortletInstance; import org.apache.jetspeed.portal.PortletSet; import org.apache.jetspeed.portal.PortletSkin; import org.apache.jetspeed.services.PortalToolkit; import org.apache.jetspeed.services.Registry; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.persistence.PersistenceManager; import org.apache.jetspeed.services.rundata.JetspeedRunData; import org.apache.jetspeed.services.statemanager.SessionState; import org.apache.jetspeed.util.MetaData; import org.apache.turbine.modules.ActionLoader; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; /** * PortletCustomizeをJSONデータとして出力するクラスです。 <br /> * */ public class PortletCustomizeFormJSONScreen extends ALJSONScreen { /** logger */ private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(PortletCustomizeFormJSONScreen.class.getName()); @Override protected String getJSONString(RunData rundata, Context context) throws Exception { String result = new JSONArray().toString(); // get the customization state for this page SessionState customizationState = ((JetspeedRunData) rundata).getPageSessionState(); JetspeedRunData jdata = (JetspeedRunData) rundata; String peid = jdata.getParameters().getString("js_peid"); // we should first retrieve the portlet to customize and its parameters // definition Portlet found = null; List<?> params = (List<?>) customizationState.getAttribute("customize-parameters"); String newSecurityParent = rundata.getParameters().getString("_security_ref"); String newSkinName = rundata.getParameters().getString("_skin"); String newTitle = rundata.getParameters().getString("current_title"); boolean changeRequested = ((params != null) || (newSkinName != null) || (newSecurityParent != null) || (newTitle != null)); boolean madePsChange = false; boolean madePcChange = false; if ((peid == null) || (changeRequested == false)) { doCancel(rundata, context); return result; } Profile profile = ((JetspeedRunData) rundata).getCustomizedProfile(); Entry entry = profile.getDocument().getEntryById(peid); Stack<Portlet> sets = new Stack<Portlet>(); sets.push(profile.getRootSet()); while ((found == null) && (sets.size() > 0)) { PortletSet set = (PortletSet) sets.pop(); if (set.getID().equals(peid)) { found = set; } else { Enumeration<?> en = set.getPortlets(); while ((found == null) && en.hasMoreElements()) { Portlet p = (Portlet) en.nextElement(); // unstack the controls to find the real PortletSets Portlet real = p; while (real instanceof PortletControl) { real = ((PortletControl) p).getPortlet(); } if (real instanceof PortletSet) { if (real.getID().equals(peid)) { found = real; } else { // we'll explore this set afterwards sets.push(real); } } else if (p.getID().equals(peid)) { found = p; } } } } if (found == null) { doCancel(rundata, context); return result; } PortletConfig pc = found.getPortletConfig(); // Only update the security ref if the parent changed if ((newSecurityParent != null)) { boolean securityChanged = false; SecurityReference currentSecurityRef = pc.getSecurityRef(); if (currentSecurityRef != null) { securityChanged = (newSecurityParent.equals(currentSecurityRef.getParent()) == false); } else { securityChanged = (newSecurityParent.trim().length() > 0); } if (securityChanged == true) { SecurityReference securityRef = null; if ((newSecurityParent.trim().length() > 0)) { securityRef = new BaseSecurityReference(); securityRef.setParent(newSecurityParent); } // Note: setting the portlet's config may not be a good idea - // it might be used as the Portlet for other PSMLDocument Entries that // have a different idea of security - and the caching of Portlets does // NOT include security -ggolden. pc.setSecurityRef(securityRef); entry.setSecurityRef(securityRef); madePcChange = true; } } // Only update the skin if the name changed if (newSkinName != null) { boolean skinChanged = false; String currentSkinName = null; if (pc.getSkin() != null) { currentSkinName = pc.getPortletSkin().getName(); } if (currentSkinName != null) { skinChanged = (newSkinName.equals(currentSkinName) == false); } else { skinChanged = (newSkinName.trim().length() > 0); } if (skinChanged == true) { PortletSkin skin = null; if ((newSkinName.trim().length() > 0)) { skin = PortalToolkit.getSkin(newSkinName); if (skin != null) { // Note: setting the portlet's config may not be a good idea - // it might be used as the Portlet for other PSMLDocument Entries // that // have a different idea of skin - and the caching of Portlets does // NOT include skin -ggolden. pc.setPortletSkin(skin); Skin psmlSkin = entry.getSkin(); if (psmlSkin == null) { entry.setSkin(new PsmlSkin()); } entry.getSkin().setName(newSkinName); } else { logger.warn("Unable to update skin for portlet entry " + entry.getId() + " because skin does not exist."); } } else { // Note: setting the portlet's config may not be a good idea - // it might be used as the Portlet for other PSMLDocument Entries that // have a different idea of skin - and the caching of Portlets does // NOT include skin -ggolden. pc.setPortletSkin(null); entry.setSkin(null); } madePcChange = true; } } // Only update the title if the title changed if (newTitle != null) { boolean titleChanged = false; String currentTitle = entry.getTitle(); MetaData md = pc.getMetainfo(); if (currentTitle == null && md != null && md.getTitle() != null) { currentTitle = md.getTitle(); } if (currentTitle != null) { titleChanged = (newTitle.equals(currentTitle) == false); } else { titleChanged = (newTitle.trim().length() > 0); } if (titleChanged == true) { if ((newTitle.trim().length() > 0)) { // Note: setting the portlet's config may not be a good idea - // it might be used as the Portlet for other PSMLDocument Entries that // have a different idea of title - and the caching of Portlets does // NOT include title -ggolden. if (md == null) { md = new MetaData(); pc.setMetainfo(md); } md.setTitle(newTitle); entry.setTitle(newTitle); madePcChange = true; } } } // Update paramaters try { PortletInstance instance = PersistenceManager.getInstance(found, rundata); PortletEntry regEntry = (PortletEntry) Registry.getEntry(Registry.PORTLET, found.getName()); Iterator<?> i = params.iterator(); while (i.hasNext()) { Parameter param = (Parameter) i.next(); String name = param.getName(); String newValue = null; String[] testArray = rundata.getParameters().getStrings(name); if (testArray != null && testArray.length > 1) { newValue = org.apache.jetspeed.util.StringUtils.arrayToString(testArray, ","); } else { newValue = rundata.getParameters().getString(name); if (newValue == null) { newValue = ""; } } String regValue = name.startsWith("pref-") ? "" : regEntry .getParameter(name) .getValue(); String psmlValue = instance.getAttribute(name); // New value for this parameter exists if (newValue != null) { if (!regValue.equals(newValue) || !psmlValue.equals(newValue)) { instance.setAttribute(name, newValue); psmlValue = newValue; } madePsChange = true; } // Remove duplicate parameters from psml if (psmlValue != null && psmlValue.equals(regValue)) { instance.removeAttribute(name); madePsChange = true; } } // save all the changes if ((madePsChange == true) || (madePcChange == true)) { try { // JetspeedRunData jdata = (JetspeedRunData) rundata; profile.store(); // FIXME: this hack is due to the corrupted lifecycle of the portlet // in the // current API when caching is activated found.init(); org.apache.jetspeed.util.PortletSessionState.setPortletConfigChanged( found, rundata); } catch (PortletException e) { logger.error("Customizer failed to reinitialize the portlet " + found.getName(), e); } catch (Exception e) { logger.error("Unable to save profile ", e); } } // we're done, make sure clean up the // session doCancel(rundata, context); } catch (Exception e) { logger.error("ALCustomizeAction.doUpdate", e); } return result; } /** Clean up the customization state */ public void doCancel(RunData rundata, Context context) { ((JetspeedRunData) rundata).setCustomized(null); if (((JetspeedRunData) rundata).getCustomized() == null) { try { ActionLoader.getInstance().exec(rundata, "controls.EndCustomize"); } catch (Exception e) { logger.error("Unable to load action controls.EndCustomize ", e); } } } }