/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal.layout.dlm; import org.apereo.portal.PortalException; import org.apereo.portal.layout.IUserLayoutStore; import org.apereo.portal.security.IPerson; import org.apereo.portal.spring.locator.UserLayoutStoreLocator; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Utility functions for applying user changes to the user's plf prior to persisting. * * @since 2.5 */ public class HandlerUtils { /** * This method returns the PLF version of the passed in compViewNode. If create is false and a * node with the same id is not found in the PLF then null is returned. If the create is true * then an attempt is made to create the node along with any necessary ancestor nodes needed to * represent the path along the tree. */ public static Element getPLFNode( Element compViewNode, IPerson person, boolean create, boolean includeChildNodes) throws PortalException { Document plf = (Document) person.getAttribute(Constants.PLF); String ID = compViewNode.getAttribute(Constants.ATT_ID); Element plfNode = plf.getElementById(ID); if (plfNode != null) return plfNode; // make sure that the root isn't what we are trying to get. Root is not // registered with document under an id. if (compViewNode.getNodeName().equals("layout")) return plf.getDocumentElement(); // if not found then create if indicated. if (create == true) return createPlfNodeAndPath(compViewNode, includeChildNodes, person); return null; } /** * Creates a copy of the passed in ILF node in the PLF if not already there as well as creating * any ancestor nodes along the path from this node up to the layout root if they are not there. */ public static Element createPlfNodeAndPath( Element compViewNode, boolean includeChildNodes, IPerson person) throws PortalException { // first attempt to get parent Element compViewParent = (Element) compViewNode.getParentNode(); Element plfParent = getPLFNode(compViewParent, person, true, false); Document plf = (Document) person.getAttribute(Constants.PLF); // if ilf copy being created we can append to parent and use the // position set to place it. if (compViewNode .getAttribute(Constants.ATT_ID) .startsWith(Constants.FRAGMENT_ID_USER_PREFIX)) return createILFCopy( compViewNode, compViewParent, includeChildNodes, plf, plfParent, person); return createOrMovePLFOwnedNode( compViewNode, compViewParent, true, // create if not found includeChildNodes, plf, plfParent, person); } /** Creates a copy of an ilf node in the plf and sets up necessary storage attributes. */ private static Element createILFCopy( Element compViewNode, Element compViewParent, boolean includeChildNodes, Document plf, Element plfParent, IPerson person) throws PortalException { Element plfNode = (Element) plf.importNode(compViewNode, includeChildNodes); // make sure that we don't include ILF restriction params in the PLF if // this ILF node contained any. plfNode.removeAttributeNS(Constants.NS_URI, Constants.LCL_ADD_CHILD_ALLOWED); plfNode.removeAttributeNS(Constants.NS_URI, Constants.LCL_DELETE_ALLOWED); plfNode.removeAttributeNS(Constants.NS_URI, Constants.LCL_EDIT_ALLOWED); plfNode.removeAttributeNS(Constants.NS_URI, Constants.LCL_MOVE_ALLOWED); String ID = plfNode.getAttribute(Constants.ATT_ID); plfNode.setIdAttribute(Constants.ATT_ID, true); IUserLayoutStore uls = null; uls = UserLayoutStoreLocator.getUserLayoutStore(); if (plfNode.getAttribute(Constants.ATT_PLF_ID).equals("")) { String plfID = null; try { if (!plfNode.getAttribute(Constants.ATT_CHANNEL_ID) .equals("")) // dealing with a channel plfID = uls.generateNewChannelSubscribeId(person); else plfID = uls.generateNewFolderId(person); } catch (Exception e) { throw new PortalException( "Exception encountered while " + "generating new user layout node " + "Id for userId=" + person.getID(), e); } plfNode.setAttributeNS(Constants.NS_URI, Constants.ATT_PLF_ID, plfID); plfNode.setAttributeNS(Constants.NS_URI, Constants.ATT_ORIGIN, ID); } plfParent.appendChild(plfNode); PositionManager.updatePositionSet(compViewParent, plfParent, person); return plfNode; } /** * Creates or moves the plf copy of a node in the composite view and inserting it before its * next highest sibling so that if dlm is not used then the model ends up exactly like the * original non-dlm persistance version. The position set is also updated and if no ilf copy * nodes are found in the sibling list the set is cleared if it exists. */ static Element createOrMovePLFOwnedNode( Element compViewNode, Element compViewParent, boolean createIfNotFound, boolean createChildNodes, Document plf, Element plfParent, IPerson person) throws PortalException { Element child = (Element) compViewParent.getFirstChild(); Element nextOwnedSibling = null; boolean insertionPointFound = false; while (child != null) { if (insertionPointFound && nextOwnedSibling == null && !child.getAttribute(Constants.ATT_ID) .startsWith(Constants.FRAGMENT_ID_USER_PREFIX)) nextOwnedSibling = child; if (child == compViewNode) insertionPointFound = true; child = (Element) child.getNextSibling(); } if (insertionPointFound == false) return null; String nextSibID = null; Element nextPlfSib = null; if (nextOwnedSibling != null) { nextSibID = nextOwnedSibling.getAttribute(Constants.ATT_ID); nextPlfSib = plf.getElementById(nextSibID); } String plfNodeID = compViewNode.getAttribute(Constants.ATT_ID); Element plfNode = plf.getElementById(plfNodeID); if (plfNode == null) { if (createIfNotFound == true) { plfNode = (Element) plf.importNode(compViewNode, createChildNodes); plfNode.setIdAttribute(Constants.ATT_ID, true); } else return null; } if (nextPlfSib == null) plfParent.appendChild(plfNode); else plfParent.insertBefore(plfNode, nextPlfSib); PositionManager.updatePositionSet(compViewParent, plfParent, person); return (Element) plfNode; } }