/* * 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.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import net.sf.json.JSONArray; import org.apache.jetspeed.om.profile.Control; import org.apache.jetspeed.om.profile.Controller; import org.apache.jetspeed.om.profile.Entry; import org.apache.jetspeed.om.profile.IdentityElement; import org.apache.jetspeed.om.profile.Layout; import org.apache.jetspeed.om.profile.MetaInfo; import org.apache.jetspeed.om.profile.Parameter; import org.apache.jetspeed.om.profile.Portlets; import org.apache.jetspeed.om.profile.Profile; import org.apache.jetspeed.om.profile.Reference; import org.apache.jetspeed.om.profile.psml.PsmlControl; import org.apache.jetspeed.om.profile.psml.PsmlController; import org.apache.jetspeed.om.profile.psml.PsmlEntry; import org.apache.jetspeed.om.profile.psml.PsmlLayout; import org.apache.jetspeed.om.profile.psml.PsmlParameter; import org.apache.jetspeed.om.registry.PortletEntry; import org.apache.jetspeed.portal.PortletController; import org.apache.jetspeed.portal.security.portlets.PortletWrapper; import org.apache.jetspeed.services.PortalToolkit; import org.apache.jetspeed.services.PortletFactory; import org.apache.jetspeed.services.Registry; import org.apache.jetspeed.services.idgenerator.JetspeedIdGenerator; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.rundata.JetspeedRunData; import org.apache.jetspeed.services.statemanager.SessionState; import org.apache.turbine.services.localization.Localization; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; import com.aimluck.eip.common.ALApplication; import com.aimluck.eip.http.HttpServletRequestLocator; import com.aimluck.eip.services.accessctl.ALAccessControlConstants; import com.aimluck.eip.services.social.ALApplicationService; import com.aimluck.eip.services.social.model.ALApplicationGetRequest; import com.aimluck.eip.util.ALEipUtils; import com.aimluck.eip.util.CustomizeUtils; /** * ToDoをJSONデータとして出力するクラスです。 <br /> * */ public class CustomizeFormJSONScreen extends ALJSONScreen { /** logger */ private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(CustomizeFormJSONScreen.class.getName()); @Override protected String getJSONString(RunData rundata, Context context) throws Exception { String result = new JSONArray().toString(); try { String mode = rundata.getParameters().get("mode"); if ("add".equals(mode)) { doAdd(rundata, context); } if ("delete".equals(mode)) { doDelete(rundata, context); } if ("layout".equals(mode)) { doLayout(rundata, context); } if ("page_title".equals(mode)) { doPageTitleEdit(rundata, context); } } catch (Exception e) { logger.error("CustomizeFormJSONScreen.getJSONString", e); } return result; } public void doPageTitleEdit(RunData rundata, Context context) throws Exception { // maintainUserSelections(rundata); // Map<String, PortletEntry> userSelections = // CustomizeUtils.getUserSelections(rundata); // String[] pnames = new String[userSelections.size()]; // userSelections.keySet().toArray(pnames); // // // Create a ClearPortletControl // Control ctrl = new PsmlControl(); // ctrl.setName("ClearPortletControl"); // JetspeedRunData jdata = (JetspeedRunData) rundata; Profile profile = jdata.getProfile(); String pid = rundata.getParameters().get("portlet_id"); Portlets portlets = profile.getDocument().getPortletsById(pid); setController(rundata, context, portlets); editPageTitle(rundata, context); // 理由等 :追加したポートレットを PSML に保存する. if (portlets != null) { doSaveAddAction(rundata, context, portlets); } SessionState customizationState = ((JetspeedRunData) rundata).getPageSessionState(); customizationState.setAttribute("customize-mode", "layout"); } private void editPageTitle(RunData rundata, Context context) { String pid = rundata.getParameters().get("portlet_id"); Portlets[] portletArrays = (((JetspeedRunData) rundata).getProfile().getDocument().getPortlets()) .getPortletsArray(); String pageTitle = rundata.getParameters().getString("pageTitle"); if (pageTitle != null && pageTitle.length() > 0 && !"マイページ".equals(pageTitle)) { for (Portlets p : portletArrays) { if (p.getId().equals(pid)) { MetaInfo info = p.getMetaInfo(); if (info != null) { info.setTitle(pageTitle); } p.setTitle(pageTitle); } } } } /** Add new portlets in the customized set */ public void doAdd(RunData rundata, Context context) throws Exception { maintainUserSelections(rundata); Map<String, PortletEntry> userSelections = CustomizeUtils.getUserSelections(rundata); String[] pnames = new String[userSelections.size()]; userSelections.keySet().toArray(pnames); // Create a ClearPortletControl Control ctrl = new PsmlControl(); ctrl.setName("ClearPortletControl"); JetspeedRunData jdata = (JetspeedRunData) rundata; Profile profile = jdata.getProfile(); String pid = rundata.getParameters().get("portlet_id"); Portlets portlets = profile.getDocument().getPortletsById(pid); setController(rundata, context, portlets); if (pnames != null) { boolean addIt; for (int i = 0; i < pnames.length; i++) { String pname = pnames[i]; PortletEntry entry = null; boolean isGadgets = false; ALApplication app = null; if (pname.startsWith("GadgetsTemplate::")) { String[] split = pname.split("::"); String appId = split[1]; app = ALApplicationService.get(new ALApplicationGetRequest() .withAppId(appId)); entry = (PortletEntry) Registry.getEntry( Registry.PORTLET, "GadgetsTemplate"); isGadgets = true; } else { entry = (PortletEntry) Registry.getEntry(Registry.PORTLET, pnames[i]); } // add only new portlets! // アクセス権限のチェック if (ALEipUtils.getHasAuthority( rundata, context, ALAccessControlConstants.VALUE_ACL_INSERT)) { if ((entry != null) && (portlets != null)) { addIt = true; if (addIt) { Entry p = new PsmlEntry(); p.setParent(isGadgets ? "GadgetsTemplate" : pnames[i]); p.setId(JetspeedIdGenerator.getNextPeid()); if (isGadgets) { p.setTitle(app.getTitle().getValue()); Parameter p1 = new PsmlParameter(); p1.setName("aid"); p1.setValue(app.getAppId().getValue()); p.addParameter(p1); Parameter p2 = new PsmlParameter(); p2.setName("url"); p2.setValue(app.getUrl().getValue()); p.addParameter(p2); Parameter p3 = new PsmlParameter(); p3.setName("mid"); String moduleId = String.valueOf(ALApplicationService.getNextModuleId()); p3.setValue(moduleId); p.addParameter(p3); p.setId(moduleId); } portlets.addEntry(p); } } } } } // -------------------------------------------------------------------------- editPageTitle(rundata, context); // 理由等 :追加したポートレットを PSML に保存する. if (portlets != null) { doSaveAddAction(rundata, context, portlets); } SessionState customizationState = ((JetspeedRunData) rundata).getPageSessionState(); customizationState.setAttribute("customize-mode", "layout"); } public void doDelete(RunData rundata, Context context) { JetspeedRunData jdata = (JetspeedRunData) rundata; // アクセス権限のチェック ALEipUtils.checkAclPermissionForCustomize( rundata, context, ALAccessControlConstants.VALUE_ACL_DELETE); String portletId = rundata.getParameters().get("js_peid"); Portlets portlets = jdata.getProfile().getDocument().getPortlets(); Portlets[] portletList = portlets.getPortletsArray(); if (portletList == null) { return; } Profile profile = jdata.getProfile(); List<PortletEntry> normalPortlets = CustomizeUtils.buildAllPortletList( rundata, profile.getMediaType(), new ArrayList<PortletEntry>()); List<String> editablePortlets = new ArrayList<String>(); for (PortletEntry entry : normalPortlets) { editablePortlets.add(entry.getName()); } try { int length = portletList.length; int timelineCount = 0; for (int i = 0; i < length; i++) { Entry[] entries = portletList[i].getEntriesArray(); if (entries == null || entries.length <= 0) { continue; } int ent_length = entries.length; for (int j = 0; j < ent_length; j++) { String parent = entries[j].getParent(); if (parent.equals("Timeline")) { timelineCount++; } } } search: for (int i = 0; i < length; i++) { Entry[] entries = portletList[i].getEntriesArray(); if (entries == null || entries.length <= 0) { continue; } int ent_length = entries.length; for (int j = 0; j < ent_length; j++) { String parent = entries[j].getParent(); if (entries[j].getId().equals(portletId) && (editablePortlets.contains(entries[j].getParent()) || parent .startsWith("GadgetsTemplate")) && (!parent.equals("Timeline") || timelineCount > 1)) { PortletWrapper wrapper = (PortletWrapper) PortletFactory.getPortlet(entries[j]); if (wrapper != null) { portletList[i].removeEntry(j); break search; } } } } profile.store(); } catch (Exception e) { // probably got wrong coordinates logger.error( "MultiColumnControllerAction: Probably got wrong coordinates", e); } jdata.getUser().removeTemp("js_peid"); rundata.setRedirectURI("/aipo/portal"); } public void doLayout(RunData rundata, Context context) { JetspeedRunData jdata = (JetspeedRunData) rundata; // アクセス権限のチェック ALEipUtils.checkAclPermissionForCustomize( rundata, context, ALAccessControlConstants.VALUE_ACL_UPDATE); Portlets portlets = jdata.getProfile().getDocument().getPortlets(); Portlets[] portletList = portlets.getPortletsArray(); if (portletList == null) { return; } Profile profile = jdata.getProfile(); List<PortletEntry> normalPortlets = CustomizeUtils.buildAllPortletList( rundata, profile.getMediaType(), new ArrayList<PortletEntry>()); List<String> editablePortlets = new ArrayList<String>(); for (PortletEntry entry : normalPortlets) { editablePortlets.add(entry.getName()); } try { int length = portletList.length; for (int i = 0; i < length; i++) { Entry[] entries = portletList[i].getEntriesArray(); if (entries == null || entries.length <= 0) { continue; } int ent_length = entries.length; for (int j = 0; j < ent_length; j++) { String parent = entries[j].getParent(); if (editablePortlets.contains(parent) || parent.startsWith("GadgetsTemplate")) { String pid = entries[j].getId(); int col = rundata.getParameters().getInt(pid + "_col", -1); int row = rundata.getParameters().getInt(pid + "_row", -1); if (col != -1 && row != -1) { setPosition(entries[j], col, row); } } } } profile.store(); } catch (Exception e) { // probably got wrong coordinates logger.error( "MultiColumnControllerAction: Probably got wrong coordinates", e); } } protected void maintainUserSelections(RunData rundata) throws Exception { JetspeedRunData jdata = (JetspeedRunData) rundata; Profile profile = jdata.getProfile(); String mediaType = profile.getMediaType(); String[] pnames = rundata.getParameters().getStrings("pname"); Map<String, PortletEntry> userSelections = CustomizeUtils.getUserSelections(rundata); List<PortletEntry> portlets = CustomizeUtils.buildAllPortletList( rundata, mediaType, new ArrayList<PortletEntry>()); if (portlets == null) { throw new Exception("Master Portlet List is null!"); } if (pnames != null) { for (String pname : pnames) { for (PortletEntry entry : portlets) { String name = entry.getName(); if (name.equals(pname)) { userSelections.put(pname, userSelections.get(pname)); break; } } } } HttpServletRequest request = HttpServletRequestLocator.get(); if (request != null) { request.setAttribute("portlets.selections", userSelections); } } public void doSaveAddAction(RunData data, Context context, Portlets portlets) { setPageLayout(data, context, portlets); // String REFERENCES_REMOVED = "references-removed"; // get the customization state for this page // update the changes made here to the profile being edited List<?>[] columns = CustomizeUtils.buildCustomizeColumns(data, context, portlets); for (int col = 0; col < columns.length; col++) { for (int row = 0; row < columns[col].size(); row++) { setPosition((IdentityElement) columns[col].get(row), col, row); } } // save the edit profile and make it current try { ((JetspeedRunData) data).getProfile().store(); // // Because of the way references are stored in memory, we have to // completely refresh // // the profile after a references is removed (otherwise it will // continue being displayed) // String referencesRemoved = // (String) customizationState.getAttribute(REFERENCES_REMOVED); // if (referencesRemoved != null && referencesRemoved.equals("true")) { // PsmlManager.refresh(((JetspeedRunData) data).getCustomizedProfile()); // } } catch (Exception e) { logger.error("Unable to save profile ", e); } } protected static void setPosition(IdentityElement identityElement, int col, int row) { boolean colFound = false; boolean rowFound = false; if (identityElement != null) { Layout layout = identityElement.getLayout(); if (layout == null) { layout = new PsmlLayout(); identityElement.setLayout(layout); } for (int i = 0; i < layout.getParameterCount(); i++) { Parameter p = layout.getParameter(i); if (p.getName().equals("column")) { p.setValue(String.valueOf(col)); colFound = true; } else if (p.getName().equals("row")) { p.setValue(String.valueOf(row)); rowFound = true; } } if (!colFound) { Parameter p = new PsmlParameter(); p.setName("column"); p.setValue(String.valueOf(col)); layout.addParameter(p); } if (!rowFound) { Parameter p = new PsmlParameter(); p.setName("row"); p.setValue(String.valueOf(row)); layout.addParameter(p); } } } @SuppressWarnings("deprecation") private void setPageLayout(RunData rundata, Context context, Portlets portlets) { HttpServletRequest request = HttpServletRequestLocator.get(); List<?>[] columns = CustomizeUtils.buildCustomizeColumns(rundata, context, portlets); String controllerName = portlets.getController().getName(); int colNum = 2; if (controllerName.startsWith("One")) { colNum = 1; } else if (controllerName.startsWith("Three")) { colNum = 3; } Portlets set = portlets; if (logger.isDebugEnabled()) { logger.debug("MultiCol: columns " + Arrays.toString(columns) + " set " + set); } if ((columns != null) && (columns.length == colNum)) { int eCount = 0; for (int i = 0; i < columns.length; i++) { eCount += columns[i].size(); } if (logger.isDebugEnabled()) { logger.debug("MultiCol: eCount " + eCount + " setCount" + set.getEntryCount() + set.getPortletsCount()); } if (eCount != set.getEntryCount() + set.getPortletsCount()) { if (logger.isDebugEnabled()) { logger.debug("MultiCol: rebuilding columns "); } columns = CustomizeUtils.buildColumns(set, colNum); } } else { if (logger.isDebugEnabled()) { logger.debug("MultiCol: rebuilding columns "); } columns = CustomizeUtils.buildColumns(set, colNum); } if (request != null) { request.setAttribute("customize-columns", columns); } context.put("portlets", columns); Map<String, String> titles = new HashMap<String, String>(); for (int col = 0; col < columns.length; col++) { for (int row = 0; row < columns[col].size(); row++) { IdentityElement identityElement = (IdentityElement) columns[col].get(row); MetaInfo metaInfo = identityElement.getMetaInfo(); if ((metaInfo != null) && (metaInfo.getTitle() != null)) { titles.put(identityElement.getId(), metaInfo.getTitle()); continue; } if (identityElement instanceof Entry) { Entry entry = (Entry) identityElement; PortletEntry pentry = (PortletEntry) Registry.getEntry(Registry.PORTLET, entry .getParent()); if ((pentry != null) && (pentry.getTitle() != null)) { titles.put(entry.getId(), pentry.getTitle()); continue; } titles.put(entry.getId(), entry.getParent()); continue; } if (identityElement instanceof Reference) { titles.put(identityElement.getId(), Localization.getString( rundata, "CUSTOMIZER_REF_DEFAULTTITLE")); continue; } // Let's make sure their is a title titles.put(identityElement.getId(), Localization.getString( rundata, "CUSTOMIZER_NOTITLESET")); } } Map<String, String> descriptions = new HashMap<String, String>(); for (int col = 0; col < columns.length; col++) { for (int row = 0; row < columns[col].size(); row++) { IdentityElement identityElement = (IdentityElement) columns[col].get(row); MetaInfo metaInfo = identityElement.getMetaInfo(); if ((metaInfo != null) && (metaInfo.getDescription() != null)) { descriptions.put(identityElement.getId(), metaInfo.getDescription()); continue; } if (identityElement instanceof Entry) { Entry entry = (Entry) identityElement; PortletEntry pentry = (PortletEntry) Registry.getEntry(Registry.PORTLET, entry .getParent()); if ((pentry != null) && (pentry.getDescription() != null)) { descriptions.put(entry.getId(), pentry.getDescription()); continue; } descriptions.put(entry.getId(), entry.getParent()); continue; } } } } /** Updates the customized portlet entry */ private void setController(RunData rundata, Context context, Portlets portlets) { ALEipUtils.checkAclPermissionForCustomize( rundata, context, ALAccessControlConstants.VALUE_ACL_UPDATE); try { String controller = rundata.getParameters().getString("controller"); if (controller != null) { PortletController pc = PortalToolkit.getController(controller); if (pc != null) { Controller c = portlets.getController(); if (c == null) { c = new PsmlController(); } c.setName(controller); portlets.setController(c); String linkedControl = pc.getConfig().getInitParameter("control"); if (linkedControl != null) { Control ctl = new PsmlControl(); ctl.setName(linkedControl); portlets.setControl(ctl); } else { portlets.setControl(null); } } } } catch (Exception e) { logger.error("CustomizeFormJSONScreen.setController", e); } } }