0001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
0002: * See license distributed with this file and
0003: * available online at http://www.uportal.org/license.html
0004: */
0005:
0006: package org.jasig.portal.layout.alm;
0007:
0008: import java.security.MessageDigest;
0009: import java.util.Collection;
0010: import java.util.Date;
0011: import java.util.Enumeration;
0012: import java.util.HashSet;
0013: import java.util.Hashtable;
0014: import java.util.Iterator;
0015: import java.util.Set;
0016: import java.util.Vector;
0017:
0018: import javax.servlet.http.HttpServletRequest;
0019:
0020: import org.apache.commons.logging.Log;
0021: import org.apache.commons.logging.LogFactory;
0022: import org.jasig.portal.ChannelStaticData;
0023: import org.jasig.portal.PortalException;
0024: import org.jasig.portal.StructureStylesheetUserPreferences;
0025: import org.jasig.portal.ThemeStylesheetUserPreferences;
0026: import org.jasig.portal.UserPreferences;
0027: import org.jasig.portal.UserProfile;
0028: import org.jasig.portal.groups.IGroupMember;
0029: import org.jasig.portal.layout.IUserLayout;
0030: import org.jasig.portal.layout.IUserLayoutStore;
0031: import org.jasig.portal.layout.LayoutEvent;
0032: import org.jasig.portal.layout.LayoutEventListener;
0033: import org.jasig.portal.layout.LayoutMoveEvent;
0034: import org.jasig.portal.layout.node.IUserLayoutChannelDescription;
0035: import org.jasig.portal.layout.node.IUserLayoutFolderDescription;
0036: import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
0037: import org.jasig.portal.layout.restrictions.IUserLayoutRestriction;
0038: import org.jasig.portal.layout.restrictions.UserLayoutRestriction;
0039: import org.jasig.portal.layout.restrictions.UserLayoutRestrictionFactory;
0040: import org.jasig.portal.layout.restrictions.alm.IALRestrictionManager;
0041: import org.jasig.portal.layout.restrictions.alm.PriorityRestriction;
0042: import org.jasig.portal.layout.restrictions.alm.RestrictionManagerFactory;
0043: import org.jasig.portal.layout.restrictions.alm.RestrictionTypes;
0044: import org.jasig.portal.security.IPerson;
0045: import org.jasig.portal.utils.CommonUtils;
0046: import org.jasig.portal.utils.DocumentFactory;
0047: import org.jasig.portal.utils.GuidGenerator;
0048: import org.jasig.portal.utils.XML;
0049: import org.w3c.dom.Document;
0050: import org.w3c.dom.Element;
0051: import org.w3c.dom.Node;
0052: import org.w3c.dom.NodeList;
0053: import org.xml.sax.ContentHandler;
0054:
0055: /**
0056: * An implementation of Aggregated User Layout Manager Interface defining common operations on user layout nodes,
0057: * that is channels and folders.
0058: *
0059: * Prior to uPortal 2.5, this class existed in the package org.jasig.portal.layout.
0060: * It was moved to its present package to reflect that it is part of Aggregated
0061: * Layouts.
0062: *
0063: * @author <a href="mailto:mvi@immagic.com">Michael Ivanov</a>
0064: * @version $Revision: 36812 $
0065: */
0066: public class AggregatedLayoutManager implements
0067: IAggregatedUserLayoutManager {
0068:
0069: private static final Log log = LogFactory
0070: .getLog(AggregatedLayoutManager.class);
0071:
0072: private IALRestrictionManager restrictionManager;
0073: private AggregatedUserLayoutStore layoutStore;
0074: private AggregatedLayout layout;
0075: private UserProfile userProfile;
0076: private IPerson person;
0077: private Set listeners = new HashSet();
0078:
0079: private IALNodeDescription addTargetsNodeDesc;
0080: private String moveTargetsNodeId;
0081:
0082: // The ID of the current loaded fragment
0083: private String fragmentId;
0084:
0085: // GUID generator
0086: private static GuidGenerator guid = null;
0087: private String cacheKey = null;
0088:
0089: private IUserLayoutNodeDescription newNodeDescription = null;
0090:
0091: public AggregatedLayoutManager(IPerson person,
0092: UserProfile userProfile) throws PortalException {
0093: this .person = person;
0094: this .userProfile = userProfile;
0095: layout = new AggregatedLayout(String.valueOf(getLayoutId()),
0096: this );
0097: restrictionManager = (IALRestrictionManager) RestrictionManagerFactory
0098: .getRestrictionManager(layout);
0099: if (guid == null)
0100: guid = new GuidGenerator();
0101: cacheKey = guid.getNewGuid();
0102: }
0103:
0104: public AggregatedLayoutManager(IPerson person,
0105: UserProfile userProfile, IUserLayoutStore layoutStore)
0106: throws Exception {
0107: this (person, userProfile);
0108: this .layoutStore = (AggregatedUserLayoutStore) layoutStore;
0109: this .loadUserLayout();
0110: }
0111:
0112: private void updateCacheKey() {
0113: cacheKey = generateNewCacheKey();
0114: }
0115:
0116: private String generateNewCacheKey() {
0117: String cacheKey = null;
0118: long startTime = new Date().getTime();
0119: try {
0120: MessageDigest md = MessageDigest.getInstance("MD5");
0121: md.update(XML.serializeNode(this .getUserLayoutDOM())
0122: .getBytes());
0123: byte[] digest = md.digest();
0124: StringBuffer sb = new StringBuffer(32);
0125: for (int i = 0; i < digest.length; i++) {
0126: if (digest[i] < 0x10 && digest[i] >= 0x0) {
0127: // add a leading 0
0128: sb.append("0");
0129: }
0130: sb.append(Integer.toHexString((0xff & digest[i])));
0131: }
0132: cacheKey = sb.toString();
0133: } catch (Exception e) {
0134: log
0135: .error(
0136: "AggregatedUserLayoutManager::generateNewCacheKey() : unable to generate new cache key, using new guid",
0137: e);
0138: cacheKey = guid.getNewGuid();
0139: }
0140:
0141: if (log.isDebugEnabled()) {
0142: log
0143: .debug("AggregatedUserLayoutManager::generateNewCacheKey() : generating new cache key took "
0144: + (new Date().getTime() - startTime) + "ms");
0145: }
0146: return cacheKey;
0147: }
0148:
0149: public IUserLayout getUserLayout() throws PortalException {
0150: return layout;
0151: }
0152:
0153: public void setUserLayout(IUserLayout layout)
0154: throws PortalException {
0155: if (!(layout instanceof AggregatedLayout))
0156: throw new PortalException(
0157: "The user layout instance must have AggregatedLayout type!");
0158: this .layout = (AggregatedLayout) layout;
0159: restrictionManager.setUserLayout(layout);
0160: updateCacheKey();
0161: }
0162:
0163: /**
0164: * A factory method to create an empty <code>IUserLayoutNodeDescription</code> instance
0165: *
0166: * @param nodeType a node type value
0167: * @return an <code>IUserLayoutNodeDescription</code> instance
0168: * @exception PortalException if the error occurs.
0169: */
0170: public IUserLayoutNodeDescription createNodeDescription(int nodeType)
0171: throws PortalException {
0172: IALNodeDescription nodeDesc = null;
0173: switch (nodeType) {
0174: case IUserLayoutNodeDescription.FOLDER:
0175: nodeDesc = new ALFolderDescription();
0176: break;
0177: case IUserLayoutNodeDescription.CHANNEL:
0178: nodeDesc = new ALChannelDescription();
0179: break;
0180: }
0181: // Adding the user priority restriction
0182: if (nodeDesc != null) {
0183: int[] priorityRange = UserPriorityManager
0184: .getPriorityRange(person);
0185: PriorityRestriction restriction = (PriorityRestriction) UserLayoutRestrictionFactory
0186: .createRestriction(RestrictionTypes.PRIORITY_RESTRICTION);
0187: restriction.setRestriction(priorityRange[0],
0188: priorityRange[1]);
0189: nodeDesc.addRestriction(restriction);
0190: }
0191: return nodeDesc;
0192: }
0193:
0194: /**
0195: * Sets a layout manager to auto-commit mode that allows to update the database immediately
0196: * @param autoCommit a boolean value
0197: * @deprecated this method no longer has any effect
0198: */
0199: public void setAutoCommit(boolean autoCommit) {
0200: throw new UnsupportedOperationException();
0201: }
0202:
0203: /**
0204: * Returns an Id of the current user layout.
0205: *
0206: * @return a <code>int</code> value
0207: */
0208: public int getLayoutId() {
0209: return userProfile.getLayoutId();
0210: }
0211:
0212: /**
0213: * Returns an Id of a parent user layout node.
0214: * The user layout root node always has ID={@link IUserLayout#ROOT_NODE_NAME}
0215: *
0216: * @param nodeId a <code>String</code> value
0217: * @return a <code>String</code> value
0218: * @exception PortalException if an error occurs
0219: */
0220: public String getParentId(String nodeId) throws PortalException {
0221: return layout.getParentId(nodeId);
0222: }
0223:
0224: /**
0225: * Returns a list of child node Ids for a given node.
0226: *
0227: * @param nodeId a <code>String</code> value
0228: * @return a <code>Enumeration</code> of <code>String</code> child node Ids.
0229: * @exception PortalException if an error occurs
0230: */
0231: public Enumeration getChildIds(String nodeId)
0232: throws PortalException {
0233: return layout.getChildIds(nodeId);
0234: }
0235:
0236: /**
0237: * Determine an Id of a previous sibling node.
0238: *
0239: * @param nodeId a <code>String</code> node ID
0240: * @return a <code>String</code> Id value of a previous sibling node, or <code>null</code> if this is the first sibling.
0241: * @exception PortalException if an error occurs
0242: */
0243: public String getPreviousSiblingId(String nodeId)
0244: throws PortalException {
0245: return layout.getPreviousSiblingId(nodeId);
0246: }
0247:
0248: /**
0249: * Determine an Id of a next sibling node.
0250: *
0251: * @param nodeId a <code>String</code> node ID
0252: * @return a <code>String</code> Id value of a next sibling node, or <code>null</code> if this is the last sibling.
0253: * @exception PortalException if an error occurs
0254: */
0255: public String getNextSiblingId(String nodeId)
0256: throws PortalException {
0257: return layout.getNextSiblingId(nodeId);
0258: }
0259:
0260: private void moveWrongFragmentsToLostFolder()
0261: throws PortalException {
0262: Collection nodes = layoutStore.getIncorrectPushedFragmentNodes(
0263: person, userProfile);
0264: for (Iterator i = nodes.iterator(); i.hasNext();) {
0265: String nodeId = (String) i.next();
0266: ALNode node = getLayoutNode(nodeId);
0267: if (node != null && nodeId != null) {
0268: String prevNodeId = node.getPreviousNodeId();
0269: ALNode prevNode = getLayoutNode(prevNodeId);
0270:
0271: if (prevNode != null && !moveNodeToLostFolder(nodeId))
0272: log
0273: .info("Unable to move the pushed fragment with ID="
0274: + node.getFragmentId()
0275: + " to the lost folder");
0276: }
0277: }
0278: }
0279:
0280: /**
0281: * Moves the nodes to the lost folder if they don't satisfy their restrictions
0282: * @exception PortalException if an error occurs
0283: */
0284: protected void moveWrongNodesToLostFolder() throws PortalException {
0285: moveWrongNodesToLostFolder(getRootFolderId(), 0);
0286: }
0287:
0288: /**
0289: * Moves the nodes to the lost folder if they don't satisfy their restrictions
0290: * @param nodeId a <code>String</code> node ID
0291: * @param depth a depth of the given node
0292: * @exception PortalException if an error occurs
0293: */
0294: private void moveWrongNodesToLostFolder(String nodeId, int depth)
0295: throws PortalException {
0296:
0297: ALNode node = getLayoutNode(nodeId);
0298:
0299: // Checking restrictions on the node
0300: Collection restrictions = node
0301: .getRestrictionsByPath(IUserLayoutRestriction.LOCAL_RESTRICTION_PATH);
0302: for (Iterator i = restrictions.iterator(); i.hasNext();) {
0303: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
0304: .next();
0305: // check other restrictions except priority and depth
0306: if (!restriction.getName().equals(
0307: RestrictionTypes.DEPTH_RESTRICTION)
0308: && !restriction.getName().equals(
0309: RestrictionTypes.PRIORITY_RESTRICTION)
0310: && !restriction.checkRestriction(node)) {
0311: moveNodeToLostFolder(nodeId);
0312: break;
0313: }
0314: }
0315:
0316: // Checking the depth restriction
0317: if (!restrictionManager.checkRestriction(nodeId,
0318: RestrictionTypes.DEPTH_RESTRICTION, depth + "")) {
0319: moveNodeToLostFolder(nodeId);
0320: }
0321:
0322: // Checking children related restrictions on the children if they exist
0323: restrictions = node
0324: .getRestrictionsByPath(IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH);
0325: boolean isFolder = (node.getNodeType() == IUserLayoutNodeDescription.FOLDER);
0326: if (isFolder) {
0327: for (Iterator i = restrictions.iterator(); i.hasNext();) {
0328: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
0329: .next();
0330: for (String nextId = ((ALFolder) node)
0331: .getFirstChildNodeId(); nextId != null;) {
0332: ALNode nextNode = getLayoutNode(nextId);
0333: String tmpNodeId = nextNode.getNextNodeId();
0334: if (!restriction.getName().equals(
0335: RestrictionTypes.DEPTH_RESTRICTION)
0336: && !restriction.checkRestriction(nextNode)) {
0337: moveNodeToLostFolder(nextId);
0338: }
0339: nextId = tmpNodeId;
0340: }
0341: }
0342: }
0343:
0344: // Checking parent related restrictions on the parent if it exists
0345: String parentNodeId = node.getParentNodeId();
0346: if (parentNodeId != null) {
0347: restrictions = node
0348: .getRestrictionsByPath(IUserLayoutRestriction.PARENT_RESTRICTION_PATH);
0349: ALNode parentNode = getLayoutNode(parentNodeId);
0350: for (Iterator i = restrictions.iterator(); i.hasNext();) {
0351: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
0352: .next();
0353: if (!restriction.getName().equals(
0354: RestrictionTypes.DEPTH_RESTRICTION)
0355: && !restriction.checkRestriction(parentNode)) {
0356: moveNodeToLostFolder(nodeId);
0357: break;
0358: }
0359: }
0360: }
0361:
0362: if (isFolder) {
0363: ++depth;
0364: ALFolder folder = (ALFolder) node;
0365: String firstChildId = folder.getFirstChildNodeId();
0366: if (firstChildId != null) {
0367: String id = getLastSiblingNode(firstChildId).getId();
0368: while (id != null
0369: && !changeSiblingNodesOrder(folder
0370: .getFirstChildNodeId())) {
0371: String lastNodeId = getLastSiblingNode(id).getId();
0372: id = getLayoutNode(lastNodeId).getPreviousNodeId();
0373: moveNodeToLostFolder(lastNodeId);
0374: }
0375: for (String nextId = folder.getFirstChildNodeId(); nextId != null; nextId = getLayoutNode(
0376: nextId).getNextNodeId())
0377: moveWrongNodesToLostFolder(nextId, depth);
0378: }
0379: }
0380:
0381: }
0382:
0383: // Gets the content of the lost folder
0384: public String getLostFolderXML() throws PortalException {
0385: Document document = DocumentFactory.getNewDocument();
0386: layout.writeTo(ALFolderDescription.LOST_FOLDER_ID, document);
0387: return org.jasig.portal.utils.XML.serializeNode(document);
0388: }
0389:
0390: /**
0391: * Gets the tree depth for a given node
0392: * @param nodeId a <code>String</code> node ID
0393: * @return a depth value
0394: * @exception PortalException if an error occurs
0395: */
0396: public int getDepth(String nodeId) throws PortalException {
0397: return layout.getDepth(nodeId);
0398: }
0399:
0400: /**
0401: * Moves the node to the lost folder
0402: * @param nodeId a <code>String</code> node ID
0403: * @return a boolean value
0404: * @exception PortalException if an error occurs
0405: */
0406: private boolean moveNodeToLostFolder(String nodeId)
0407: throws PortalException {
0408: ALFolder lostFolder = getLayoutFolder(IALFolderDescription.LOST_FOLDER_ID);
0409: if (lostFolder == null) {
0410: lostFolder = ALFolder.createLostFolder();
0411: }
0412: // Moving the node to the lost folder
0413: return moveNode(nodeId, IALFolderDescription.LOST_FOLDER_ID,
0414: null);
0415: }
0416:
0417: /**
0418: * Gets the restriction specified by the parameters below
0419: * @param node a <code>ALNode</code> node
0420: * @param restrictionName a restriction name
0421: * @param restrictionPath a <code>String</code> restriction path
0422: * @return a <code>IUserLayoutRestriction</code> instance
0423: * @exception PortalException if an error occurs
0424: */
0425: private static IUserLayoutRestriction getRestriction(ALNode node,
0426: String restrictionName, String restrictionPath)
0427: throws PortalException {
0428: return node.getRestriction(UserLayoutRestriction.getUniqueKey(
0429: restrictionName, restrictionPath));
0430: }
0431:
0432: /**
0433: * Return a priority restriction for the given node.
0434: * @return a <code>PriorityRestriction</code> object
0435: * @exception PortalException if an error occurs
0436: */
0437: public static PriorityRestriction getPriorityRestriction(ALNode node)
0438: throws PortalException {
0439: PriorityRestriction priorRestriction = getPriorityRestriction(
0440: node, IUserLayoutRestriction.LOCAL_RESTRICTION_PATH);
0441: if (priorRestriction == null) {
0442: priorRestriction = (PriorityRestriction) UserLayoutRestrictionFactory
0443: .createRestriction(
0444: RestrictionTypes.PRIORITY_RESTRICTION, "0-"
0445: + java.lang.Integer.MAX_VALUE);
0446: }
0447: return priorRestriction;
0448: }
0449:
0450: /**
0451: * Return a priority restriction for the given node.
0452: * @return a <code>PriorityRestriction</code> object
0453: * @exception PortalException if an error occurs
0454: */
0455: private static PriorityRestriction getPriorityRestriction(
0456: ALNode node, String restrictionPath) throws PortalException {
0457: return (PriorityRestriction) getRestriction(node,
0458: RestrictionTypes.PRIORITY_RESTRICTION, restrictionPath);
0459: }
0460:
0461: /**
0462: * Change if it's possible priority values for all the sibling nodes
0463: * @param nodeId a <code>String</code> any node ID from the sibling line to be checked
0464: * @return a boolean value
0465: * @exception PortalException if an error occurs
0466: */
0467: protected boolean changeSiblingNodesPriorities(String nodeId)
0468: throws PortalException {
0469:
0470: int tmpPriority = Integer.MAX_VALUE;
0471: String firstNodeId = getFirstSiblingNode(nodeId).getId();
0472:
0473: // Fill out the vector by priority values
0474: for (String nextId = firstNodeId; nextId != null;) {
0475: ALNode nextNode = getLayoutNode(nextId);
0476: int[] nextRange = getPriorityRestriction(nextNode)
0477: .getRange();
0478: int value = Math.min(nextRange[1], tmpPriority - 1);
0479: if (value < tmpPriority && value >= nextRange[0]) {
0480: nextNode.setPriority(value);
0481: tmpPriority = value;
0482: } else
0483: return false;
0484: nextId = nextNode.getNextNodeId();
0485: }
0486:
0487: return true;
0488: }
0489:
0490: /**
0491: * Change if it's possible priority values for all the sibling nodes defined by the collection
0492: * @param nodes a <code>Vector</code> instance with ALNode objects
0493: * @return a boolean value
0494: * @exception PortalException if an error occurs
0495: */
0496: protected boolean changeSiblingNodesPriorities(Vector nodes)
0497: throws PortalException {
0498:
0499: int tmpPriority = Integer.MAX_VALUE;
0500:
0501: // Fill out the vector by priority values
0502: int size = nodes.size();
0503: for (int i = 0; i < size; i++) {
0504: ALNode nextNode = (ALNode) nodes.get(i);
0505: if (nextNode == null)
0506: return false;
0507: int[] nextRange = getPriorityRestriction(nextNode)
0508: .getRange();
0509: int value = Math.min(nextRange[1], tmpPriority - 1);
0510: if (value < tmpPriority && value >= nextRange[0]) {
0511: nextNode.setPriority(value);
0512: tmpPriority = value;
0513: } else
0514: return false;
0515: }
0516:
0517: return true;
0518: }
0519:
0520: /**
0521: * Change priority values for all the sibling nodes when trying to add a new node
0522: * @param node a <code>ALNode</code> a node to be added
0523: * @param parentNodeId a <code>String</code> parent node ID
0524: * @param nextNodeId a <code>String</code> next sibling node ID
0525: * @return a boolean value
0526: * @exception PortalException if an error occurs
0527: */
0528: protected synchronized boolean changeSiblingNodesPriorities(
0529: ALNode node, String parentNodeId, String nextNodeId)
0530: throws PortalException {
0531: ALNode firstNode = null, nextNode = null;
0532: String firstNodeId = null;
0533: int priority = 0, nextPriority = 0, prevPriority = 0, range[] = null, prevRange[] = null, nextRange[] = null;
0534: PriorityRestriction priorityRestriction = null;
0535: String nodeId = node.getId();
0536:
0537: ALFolder parent = getLayoutFolder(parentNodeId);
0538: if (parentNodeId != null) {
0539: firstNodeId = parent.getFirstChildNodeId();
0540: // if the node is equal the first node in the sibling line we get the next node
0541: if (nodeId.equals(firstNodeId))
0542: firstNodeId = node.getNextNodeId();
0543: if (firstNodeId == null)
0544: return true;
0545: } else
0546: return false;
0547:
0548: firstNode = getLayoutNode(firstNodeId);
0549:
0550: if (nextNodeId != null) {
0551: nextNode = getLayoutNode(nextNodeId);
0552: nextPriority = nextNode.getPriority();
0553: priorityRestriction = getPriorityRestriction(nextNode);
0554: nextRange = priorityRestriction.getRange();
0555: }
0556:
0557: priority = node.getPriority();
0558: priorityRestriction = getPriorityRestriction(node);
0559: range = priorityRestriction.getRange();
0560:
0561: // If we add a new node to the beginning of the sibling line
0562: if (firstNodeId.equals(nextNodeId)) {
0563:
0564: if (range[1] <= nextRange[0])
0565: return false;
0566:
0567: if (priority > nextPriority)
0568: return true;
0569:
0570: if (range[1] > nextPriority) {
0571: node.setPriority(range[1]);
0572: return true;
0573: }
0574:
0575: if ((nextPriority + 1) <= range[1]
0576: && (nextPriority + 1) >= range[0]) {
0577: node.setPriority(nextPriority + 1);
0578: return true;
0579: }
0580: }
0581:
0582: // If we add a new node to the end of the sibling line
0583: if (nextNode == null) {
0584:
0585: // Getting the last node
0586: ALNode lastNode = getLastSiblingNode(firstNodeId);
0587:
0588: int lastPriority = lastNode.getPriority();
0589: PriorityRestriction lastPriorityRestriction = getPriorityRestriction(lastNode);
0590: int[] lastRange = lastPriorityRestriction.getRange();
0591:
0592: if (range[0] >= lastRange[1])
0593: return false;
0594:
0595: if (priority < lastPriority)
0596: return true;
0597:
0598: if (range[0] < lastPriority) {
0599: node.setPriority(range[0]);
0600: return true;
0601: }
0602:
0603: if ((lastPriority - 1) <= range[1]
0604: && (lastPriority - 1) >= range[0]) {
0605: node.setPriority(range[0]);
0606: return true;
0607: }
0608:
0609: }
0610:
0611: // If we add a new node in a general case
0612: if (nextNode != null && !nextNode.equals(firstNode)
0613: && !nodeId.equals(nextNodeId)) {
0614:
0615: // Getting the last node
0616: ALNode prevNode = getLayoutNode(nextNode
0617: .getPreviousNodeId());
0618:
0619: prevPriority = prevNode.getPriority();
0620: PriorityRestriction lastPriorityRestriction = getPriorityRestriction(prevNode);
0621: prevRange = lastPriorityRestriction.getRange();
0622:
0623: if (range[1] <= nextRange[0] || range[0] >= prevRange[1])
0624: return false;
0625:
0626: if (priority < prevPriority && priority > nextPriority)
0627: return true;
0628:
0629: int maxPossibleLowValue = Math.max(range[0],
0630: nextPriority + 1);
0631: int minPossibleHighValue = Math.min(range[1],
0632: prevPriority - 1);
0633:
0634: if (minPossibleHighValue >= maxPossibleLowValue) {
0635: node.setPriority(minPossibleHighValue);
0636: return true;
0637: }
0638:
0639: }
0640:
0641: Vector nodes = new Vector();
0642: for (String nextId = firstNodeId; nextId != null;) {
0643: if (!nextId.equals(nodeId)) {
0644: if (nextId.equals(nextNodeId))
0645: nodes.add(node);
0646: nodes.add(getLayoutNode(nextId));
0647: }
0648: nextId = getLayoutNode(nextId).getNextNodeId();
0649: }
0650:
0651: if (nextNodeId == null)
0652: nodes.add(node);
0653:
0654: return changeSiblingNodesPriorities(nodes);
0655:
0656: }
0657:
0658: /**
0659: * Change the sibling nodes order depending on their priority values
0660: * @param firstNodeId a <code>String</code> first node ID in the sibling line
0661: * @return a boolean value
0662: * @exception PortalException if an error occurs
0663: */
0664: protected boolean changeSiblingNodesOrder(String firstNodeId)
0665: throws PortalException {
0666: if (firstNodeId == null)
0667: throw new PortalException(
0668: "The first node ID in the sibling line cannot be NULL!");
0669: ALNode firstNode = getLayoutNode(firstNodeId);
0670: String parentNodeId = firstNode.getParentNodeId();
0671: boolean rightOrder = true;
0672: ALNode node = null;
0673: for (String nextNodeId = firstNodeId; nextNodeId != null;) {
0674: node = getLayoutNode(nextNodeId);
0675: nextNodeId = node.getNextNodeId();
0676: if (nextNodeId != null) {
0677: ALNode nextNode = getLayoutNode(nextNodeId);
0678: if (node.getPriority() <= nextNode.getPriority()) {
0679: rightOrder = false;
0680: break;
0681: }
0682: }
0683: }
0684:
0685: if (rightOrder)
0686: return true;
0687:
0688: // Check if the current order is right
0689: if (changeSiblingNodesPriorities(firstNodeId))
0690: return true;
0691:
0692: Set movedNodes = new HashSet();
0693: // Choosing more suitable order of the nodes in the sibling line
0694: for (String lastNodeId = getLastSiblingNode(firstNodeId)
0695: .getId(); lastNodeId != null;) {
0696:
0697: for (String curNodeId = lastNodeId; curNodeId != null;) {
0698: if (!lastNodeId.equals(curNodeId)
0699: && !movedNodes.contains(lastNodeId)) {
0700: if (moveNode(lastNodeId, parentNodeId, curNodeId)) {
0701: if (changeSiblingNodesPriorities(getLayoutFolder(
0702: parentNodeId).getFirstChildNodeId()))
0703: return true;
0704: movedNodes.add(lastNodeId);
0705: lastNodeId = getLastSiblingNode(curNodeId)
0706: .getId();
0707: curNodeId = lastNodeId;
0708: }
0709: }
0710: curNodeId = getLayoutNode(curNodeId)
0711: .getPreviousNodeId();
0712:
0713: }
0714:
0715: if (!movedNodes.contains(lastNodeId)) {
0716: if (moveNode(lastNodeId, parentNodeId, null)) {
0717: if (changeSiblingNodesPriorities(getLayoutFolder(
0718: parentNodeId).getFirstChildNodeId()))
0719: return true;
0720: movedNodes.add(lastNodeId);
0721: }
0722: }
0723:
0724: lastNodeId = getLayoutNode(lastNodeId).getPreviousNodeId();
0725: }
0726:
0727: return false;
0728:
0729: }
0730:
0731: /**
0732: * Return a cache key, uniqly corresponding to the composition and the structure of the user layout.
0733: *
0734: * @return a <code>String</code> value
0735: * @exception PortalException if an error occurs
0736: */
0737: public String getCacheKey() throws PortalException {
0738: return cacheKey;
0739: }
0740:
0741: /**
0742: * Output a tree of a user layout (with appropriate markings) defined by a particular node into
0743: * a <code>ContentHandler</code>
0744: * @param contentHandler a <code>ContentHandler</code> value
0745: * @exception PortalException if an error occurs
0746: */
0747: public void getUserLayout(ContentHandler contentHandler)
0748: throws PortalException {
0749: layout.writeTo(contentHandler);
0750: }
0751:
0752: /**
0753: * Output subtree of a user layout (with appropriate markings) defined by a particular node into
0754: * a <code>ContentHandler</code>
0755: *
0756: * @param nodeId a <code>String</code> a node determining a user layout subtree.
0757: * @param contentHandler a <code>ContentHandler</code> value
0758: * @exception PortalException if an error occurs
0759: */
0760: public void getUserLayout(String nodeId,
0761: ContentHandler contentHandler) throws PortalException {
0762: layout.writeTo(nodeId, contentHandler);
0763: }
0764:
0765: private ALNode getLayoutNode(String nodeId) {
0766: return layout.getLayoutNode(nodeId);
0767: }
0768:
0769: private ALFolder getLayoutFolder(String folderId) {
0770: return layout.getLayoutFolder(folderId);
0771: }
0772:
0773: private ALNode getLastSiblingNode(String nodeId) {
0774: return layout.getLastSiblingNode(nodeId);
0775: }
0776:
0777: private ALNode getFirstSiblingNode(String nodeId) {
0778: return layout.getFirstSiblingNode(nodeId);
0779: }
0780:
0781: public Document getUserLayoutDOM() throws PortalException {
0782: Document document = DocumentFactory.getNewDocument();
0783: layout.writeTo(document);
0784: return document;
0785: }
0786:
0787: private void setUserLayoutDOM(Node n, String parentNodeId,
0788: Hashtable layoutData) throws PortalException {
0789:
0790: Element node = (Element) n;
0791:
0792: NodeList childNodes = node.getChildNodes();
0793:
0794: IALNodeDescription nodeDesc = ALNode
0795: .createUserLayoutNodeDescription(node);
0796:
0797: String nodeId = node.getAttribute("ID");
0798:
0799: nodeDesc.setId(nodeId);
0800: nodeDesc.setName(node.getAttribute("name"));
0801: nodeDesc.setFragmentId(node.getAttribute("fragmentID"));
0802: nodeDesc.setHidden(CommonUtils.strToBool(node
0803: .getAttribute("hidden")));
0804: nodeDesc.setImmutable(CommonUtils.strToBool(node
0805: .getAttribute("immutable")));
0806: nodeDesc.setUnremovable(CommonUtils.strToBool(node
0807: .getAttribute("unremovable")));
0808: nodeDesc.setHidden(CommonUtils.strToBool(node
0809: .getAttribute("hidden")));
0810:
0811: ALNode layoutNode = null;
0812: IALChannelDescription channelDesc = null;
0813:
0814: if (nodeDesc instanceof IALChannelDescription)
0815: channelDesc = (IALChannelDescription) nodeDesc;
0816:
0817: // Getting parameters and restrictions
0818: for (int i = 0; i < childNodes.getLength(); i++) {
0819: Element childNode = (Element) childNodes.item(i);
0820: String nodeName = childNode.getNodeName();
0821: if (IAggregatedLayout.PARAMETER.equals(nodeName)
0822: && channelDesc != null) {
0823: String paramName = childNode.getAttribute("name");
0824: String paramValue = childNode.getAttribute("value");
0825: String overParam = childNode.getAttribute("override");
0826:
0827: if (paramName != null && paramValue != null) {
0828: channelDesc
0829: .setParameterValue(paramName, paramValue);
0830: channelDesc
0831: .setParameterOverride(paramName, "yes"
0832: .equalsIgnoreCase(overParam) ? true
0833: : false);
0834: }
0835: } else if (IAggregatedLayout.RESTRICTION.equals(nodeName)) {
0836: String restrPath = childNode.getAttribute("path");
0837: String restrValue = childNode.getAttribute("value");
0838: String restrType = childNode.getAttribute("type");
0839:
0840: if (restrValue != null) {
0841: IUserLayoutRestriction restriction = UserLayoutRestrictionFactory
0842: .createRestriction(restrType, restrValue,
0843: restrPath);
0844: nodeDesc.addRestriction(restriction);
0845: }
0846: }
0847: }
0848:
0849: if (channelDesc != null) {
0850: channelDesc
0851: .setChannelPublishId(node.getAttribute("chanID"));
0852: channelDesc.setChannelTypeId(node.getAttribute("typeID"));
0853: channelDesc.setClassName(node.getAttribute("class"));
0854: channelDesc
0855: .setDescription(node.getAttribute("description"));
0856: channelDesc.setEditable(CommonUtils.strToBool(node
0857: .getAttribute("editable")));
0858: channelDesc.setHasAbout(CommonUtils.strToBool(node
0859: .getAttribute("hasAbout")));
0860: channelDesc.setHasHelp(CommonUtils.strToBool(node
0861: .getAttribute("hasHelp")));
0862: channelDesc.setIsSecure(CommonUtils.strToBool(node
0863: .getAttribute("secure")));
0864: channelDesc.setFunctionalName(node.getAttribute("fname"));
0865: channelDesc.setTimeout(Long.parseLong(node
0866: .getAttribute("timeout")));
0867: channelDesc.setTitle(node.getAttribute("title"));
0868:
0869: // Adding to the layout
0870: layoutNode = new ALChannel(channelDesc);
0871: } else {
0872: layoutNode = new ALFolder((IALFolderDescription) nodeDesc);
0873: }
0874: // Setting priority value
0875: layoutNode.setPriority(CommonUtils.parseInt(node
0876: .getAttribute("priority"), 0));
0877:
0878: ALFolder parentFolder = getLayoutFolder(parentNodeId);
0879: // Binding the current node to the parent child list and parentNodeId to the current node
0880: if (parentFolder != null) {
0881: //parentFolder.addChildNode(nodeDesc.getId());
0882: layoutNode.setParentNodeId(parentNodeId);
0883: }
0884:
0885: Element nextNode = (Element) node.getNextSibling();
0886: Element prevNode = (Element) node.getPreviousSibling();
0887:
0888: if (nextNode != null && isNodeFolderOrChannel(nextNode))
0889: layoutNode.setNextNodeId(nextNode.getAttribute("ID"));
0890: if (prevNode != null && isNodeFolderOrChannel(prevNode))
0891: layoutNode.setPreviousNodeId(prevNode.getAttribute("ID"));
0892:
0893: // Setting the first child node ID
0894: if (layoutNode.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
0895: Node firstChild = node.getFirstChild();
0896: if (firstChild != null) {
0897: String id = ((Element) firstChild).getAttribute("ID");
0898: if (id != null && id.length() > 0)
0899: ((ALFolder) layoutNode).setFirstChildNodeId(id);
0900: }
0901: }
0902:
0903: // Putting the LayoutNode object into the layout
0904: layoutData.put(nodeDesc.getId(), layoutNode);
0905:
0906: // Recurrence for all children
0907: for (int i = 0; i < childNodes.getLength()
0908: && (layoutNode.getNodeType() == IUserLayoutNodeDescription.FOLDER); i++) {
0909: Element childNode = (Element) childNodes.item(i);
0910: if (isNodeFolderOrChannel(childNode))
0911: setUserLayoutDOM(childNode, nodeDesc.getId(),
0912: layoutData);
0913: }
0914:
0915: }
0916:
0917: public void setUserLayoutDOM(Document domLayout)
0918: throws PortalException {
0919: Hashtable layoutData = new Hashtable();
0920: String rootId = getRootFolderId();
0921: Element rootNode = (Element) domLayout.getDocumentElement()
0922: .getFirstChild();
0923: ALFolder rootFolder = new ALFolder(
0924: (IALFolderDescription) ALNode
0925: .createUserLayoutNodeDescription(rootNode));
0926: rootFolder.setFirstChildNodeId(((Element) rootNode
0927: .getFirstChild()).getAttribute("ID"));
0928: layoutData.put(rootId, rootFolder);
0929: NodeList childNodes = rootNode.getChildNodes();
0930: layout.setLayoutData(layoutData);
0931: for (int i = 0; i < childNodes.getLength(); i++)
0932: setUserLayoutDOM(childNodes.item(i), rootId, layoutData);
0933: updateCacheKey();
0934: }
0935:
0936: private boolean isNodeFolderOrChannel(Element node) {
0937: String nodeName = node.getNodeName();
0938: return (IAggregatedLayout.FOLDER.equals(nodeName) || IAggregatedLayout.CHANNEL
0939: .equals(nodeName));
0940: }
0941:
0942: public void setLayoutStore(IUserLayoutStore layoutStore) {
0943: this .layoutStore = (AggregatedUserLayoutStore) layoutStore;
0944: }
0945:
0946: public void loadUserLayout() throws PortalException {
0947: try {
0948: if (layoutStore != null) {
0949: fragmentId = null;
0950: layout = (AggregatedLayout) layoutStore
0951: .getAggregatedLayout(person, userProfile);
0952: layout.setLayoutManager(this );
0953: restrictionManager.setUserLayout(layout);
0954: // Setting the first child node id for the root node to NULL if it does not exist in the layout
0955: ALFolder rootFolder = getLayoutFolder(getRootFolderId());
0956: String firstChildId = rootFolder.getFirstChildNodeId();
0957: if (firstChildId != null
0958: && getLayoutNode(firstChildId) == null)
0959: rootFolder.setFirstChildNodeId(null);
0960: // Moving the wrong pushed fragments to the lost folder
0961: moveWrongFragmentsToLostFolder();
0962: // Checking restrictions and move "wrong" nodes to the lost folder
0963: moveWrongNodesToLostFolder();
0964: // Inform layout listeners
0965: for (Iterator i = listeners.iterator(); i.hasNext();) {
0966: LayoutEventListener lel = (LayoutEventListener) i
0967: .next();
0968: lel.layoutLoaded();
0969: }
0970: updateCacheKey();
0971: }
0972: } catch (Exception e) {
0973: log.error("Error loading user layout.", e);
0974: throw new PortalException("Error loading user layout.", e);
0975: }
0976: }
0977:
0978: /**
0979: * Returns true if any fragment is currently loaded into the layout manager,
0980: * false - otherwise
0981: * @return a boolean value
0982: * @exception PortalException if an error occurs
0983: */
0984: public boolean isFragmentLoaded() throws PortalException {
0985: return isLayoutFragment();
0986: }
0987:
0988: public void saveUserLayout() throws PortalException {
0989: try {
0990: if (!isLayoutFragment()) {
0991: layoutStore.setAggregatedLayout(person, userProfile,
0992: layout);
0993: // Inform layout listeners
0994: for (Iterator i = listeners.iterator(); i.hasNext();) {
0995: LayoutEventListener lel = (LayoutEventListener) i
0996: .next();
0997: lel.layoutSaved();
0998: }
0999: } else {
1000: saveFragment();
1001: }
1002:
1003: updateCacheKey();
1004: } catch (Exception e) {
1005: throw new PortalException(e);
1006: }
1007: }
1008:
1009: public void saveUserLayout(UserPreferences userPrefs)
1010: throws PortalException {
1011: try {
1012: if (!isLayoutFragment()) {
1013: layoutStore.setAggregatedLayout(person, userProfile,
1014: layout);
1015: // Inform layout listeners
1016: for (Iterator i = listeners.iterator(); i.hasNext();) {
1017: LayoutEventListener lel = (LayoutEventListener) i
1018: .next();
1019: lel.layoutSaved();
1020: }
1021: } else {
1022: saveFragment(userPrefs);
1023: }
1024:
1025: updateCacheKey();
1026: } catch (Exception e) {
1027: throw new PortalException(e);
1028: }
1029:
1030: }
1031:
1032: public void saveFragment(ILayoutFragment fragment)
1033: throws PortalException {
1034: layoutStore.setFragment(person, fragment, null);
1035: }
1036:
1037: public void saveFragment(ILayoutFragment fragment,
1038: UserPreferences userPrefs) throws PortalException {
1039: layoutStore.setFragment(person, fragment, userPrefs);
1040: }
1041:
1042: public void deleteFragment(String fragmentId)
1043: throws PortalException {
1044: layoutStore.deleteFragment(person, fragmentId);
1045: // Refresh the current layout and update the cache key
1046: // If the layout is not refreshed the manager may attempt
1047: // to save fragments that were deleted as part of user's
1048: // layout
1049: loadUserLayout();
1050: updateCacheKey();
1051: }
1052:
1053: /**
1054: * Returns the list of Ids of the fragments that the user can subscribe to
1055: * @return <code>Collection</code> a set of the fragment IDs
1056: * @exception PortalException if an error occurs
1057: */
1058: public Collection getSubscribableFragments() throws PortalException {
1059: return layoutStore.getSubscribableFragments(person);
1060: }
1061:
1062: public Collection getFragments() throws PortalException {
1063: return layoutStore.getFragments(person).keySet();
1064: }
1065:
1066: /**
1067: * Returns the user group keys which the fragment is published to
1068: * @param fragmentId a <code>String</code> value
1069: * @return a <code>Collection</code> object containing the group keys
1070: * @exception PortalException if an error occurs
1071: */
1072: public Collection getPublishGroups(String fragmentId)
1073: throws PortalException {
1074: return layoutStore.getPublishGroups(person, fragmentId);
1075: }
1076:
1077: /**
1078: * Persists the user groups which the fragment is published to
1079: * @param groups an array of <code>IGroupMember</code> objects
1080: * @param fragmentId a <code>String</code> value
1081: * @exception PortalException if an error occurs
1082: */
1083: public void setPublishGroups(IGroupMember[] groups,
1084: String fragmentId) throws PortalException {
1085: layoutStore.setPublishGroups(groups, person, fragmentId);
1086: }
1087:
1088: public ILayoutFragment getFragment(String fragmentId)
1089: throws PortalException {
1090: return layoutStore.getFragment(person, fragmentId);
1091: }
1092:
1093: public String createFragment(String fragmentName,
1094: String fragmentDesc, String fragmentRootName)
1095: throws PortalException {
1096:
1097: try {
1098:
1099: // Creating an empty layout with a root folder
1100: String newFragmentId = layoutStore.getNextFragmentId();
1101: ALFragment fragment = new ALFragment(newFragmentId, this );
1102:
1103: // Creating the layout root node
1104: ALFolder rootFolder = ALFolder.createRootFolder();
1105:
1106: // Creating the fragment root node
1107: ALFolderDescription nodeDesc = (ALFolderDescription) createNodeDescription(IUserLayoutNodeDescription.FOLDER);
1108:
1109: // Setting the root fragment ID = 1
1110: nodeDesc.setId("1");
1111: nodeDesc.setName(fragmentRootName);
1112: nodeDesc
1113: .setFolderType(IUserLayoutFolderDescription.REGULAR_TYPE);
1114: // Setting the fragment ID
1115: nodeDesc.setFragmentId(newFragmentId);
1116:
1117: //Creating a new folder with the folder description
1118: ALFolder fragmentRoot = new ALFolder(nodeDesc);
1119:
1120: // Setting the link between the layout root and the fragment root
1121: fragmentRoot.setParentNodeId(rootFolder.getId());
1122: rootFolder.setFirstChildNodeId(fragmentRoot.getId());
1123:
1124: // Fill the hashtable with the new nodes
1125: Hashtable layoutData = new Hashtable();
1126: layoutData.put(rootFolder.getId(), rootFolder);
1127: layoutData.put(fragmentRoot.getId(), fragmentRoot);
1128:
1129: // Setting the layout data
1130: fragment.setLayoutData(layoutData);
1131: fragment.setName(fragmentName);
1132: fragment.setDescription(fragmentDesc);
1133:
1134: // Setting the fragment in the database
1135: layoutStore.setFragment(person, fragment, null);
1136:
1137: updateCacheKey();
1138:
1139: // Return a new fragment ID
1140: return newFragmentId;
1141:
1142: } catch (Exception e) {
1143: log.error(e, e);
1144: throw new PortalException(e);
1145: }
1146: }
1147:
1148: public void loadFragment(String fragmentId) throws PortalException {
1149: try {
1150: layout = (ALFragment) layoutStore.getFragment(person,
1151: fragmentId);
1152: layout.setLayoutManager(this );
1153: restrictionManager.setUserLayout(layout);
1154: this .fragmentId = fragmentId;
1155: updateCacheKey();
1156: } catch (Exception e) {
1157: throw new PortalException(e);
1158: }
1159: }
1160:
1161: public void saveFragment() throws PortalException {
1162: try {
1163: if (isLayoutFragment()) {
1164: layoutStore.setFragment(person,
1165: (ILayoutFragment) layout, null);
1166: }
1167: updateCacheKey();
1168: } catch (Exception e) {
1169: throw new PortalException(e);
1170: }
1171: }
1172:
1173: public void saveFragment(UserPreferences userPrefs)
1174: throws PortalException {
1175: try {
1176: if (isLayoutFragment()) {
1177: layoutStore.setFragment(person,
1178: (ILayoutFragment) layout, userPrefs);
1179: }
1180: updateCacheKey();
1181: } catch (Exception e) {
1182: throw new PortalException(e);
1183: }
1184: }
1185:
1186: /**
1187: * Deletes the current fragment if the layout is a fragment
1188: * @exception PortalException if an error occurs
1189: */
1190: public void deleteFragment() throws PortalException {
1191: try {
1192: if (isLayoutFragment()) {
1193: layoutStore.deleteFragment(person, fragmentId);
1194: }
1195: loadUserLayout();
1196: updateCacheKey();
1197: } catch (Exception e) {
1198: throw new PortalException(e);
1199: }
1200: }
1201:
1202: private boolean isLayoutFragment() {
1203: return (fragmentId != null && layout != null);
1204: }
1205:
1206: public IUserLayoutNodeDescription getNode(String nodeId)
1207: throws PortalException {
1208: return layout.getNodeDescription(nodeId);
1209: }
1210:
1211: /**
1212: * Moves a node to a place in the tree denoted by parent and next sibling.
1213: *
1214: * @param nodeId node to be moved
1215: * @param parentId parent of where nodeId should be moved
1216: * @param nextSiblingId nextSibling of where nodeId should be moved
1217: */
1218: public synchronized boolean moveNode(String nodeId,
1219: String parentId, String nextSiblingId)
1220: throws PortalException {
1221:
1222: // if the node is being moved to itself that operation must be prevented
1223: if (nodeId.equals(nextSiblingId))
1224: return false;
1225:
1226: ALNode node = getLayoutNode(nodeId);
1227:
1228: // If the node is being moved to the same position
1229: if (parentId.equals(node.getParentNodeId()))
1230: if (CommonUtils.nvl(nextSiblingId).equals(
1231: CommonUtils.nvl(node.getNextNodeId())))
1232: return true;
1233:
1234: // Checking restrictions if the parent is not the lost folder
1235: if (!parentId.equals(IALFolderDescription.LOST_FOLDER_ID))
1236: if (!canMoveNode(nodeId, parentId, nextSiblingId))
1237: return false;
1238:
1239: ALFolder targetFolder = getLayoutFolder(parentId);
1240: ALFolder sourceFolder = getLayoutFolder(node.getParentNodeId());
1241: String sourcePrevNodeId = node.getPreviousNodeId();
1242: String sourceNextNodeId = node.getNextNodeId();
1243: ALNode targetNextNode = getLayoutNode(nextSiblingId);
1244: ALNode targetPrevNode = null, sourcePrevNode = null, sourceNextNode = null;
1245: String prevSiblingId = null;
1246:
1247: // If the nextNode != null we calculate the prev node from it otherwise we have to run to the last node in the sibling line
1248:
1249: if (targetNextNode != null)
1250: targetPrevNode = getLayoutNode(targetNextNode
1251: .getPreviousNodeId());
1252: else
1253: targetPrevNode = getLastSiblingNode(targetFolder
1254: .getFirstChildNodeId());
1255:
1256: if (targetPrevNode != null) {
1257: targetPrevNode.setNextNodeId(nodeId);
1258: prevSiblingId = targetPrevNode.getId();
1259: }
1260:
1261: // Changing the previous node id for the new next sibling node
1262: if (targetNextNode != null)
1263: targetNextNode.setPreviousNodeId(nodeId);
1264:
1265: if (nodeId.equals(sourceFolder.getFirstChildNodeId())) {
1266: // Set the new first child node ID to the source folder
1267: sourceFolder.setFirstChildNodeId(node.getNextNodeId());
1268: }
1269:
1270: String firstChildId = targetFolder.getFirstChildNodeId();
1271: if (firstChildId == null || firstChildId.equals(nextSiblingId)) {
1272: // Set the new first child node ID to the target folder
1273: targetFolder.setFirstChildNodeId(nodeId);
1274: }
1275:
1276: // Set the new next node ID for the source previous node
1277: if (sourcePrevNodeId != null) {
1278: sourcePrevNode = getLayoutNode(sourcePrevNodeId);
1279: sourcePrevNode.setNextNodeId(sourceNextNodeId);
1280: }
1281:
1282: // Set the new previous node ID for the source next node
1283: if (sourceNextNodeId != null) {
1284: sourceNextNode = getLayoutNode(sourceNextNodeId);
1285: sourceNextNode.setPreviousNodeId(sourcePrevNodeId);
1286: }
1287:
1288: node.setParentNodeId(parentId);
1289: node.setNextNodeId(nextSiblingId);
1290: node.setPreviousNodeId(prevSiblingId);
1291:
1292: // TO UPDATE THE APPROPRIATE INFO IN THE DB
1293: // TO BE DONE !!!!!!!!!!!
1294: // Inform the layout listeners
1295: LayoutMoveEvent ev = new LayoutMoveEvent(this , getNode(nodeId),
1296: getParentId(nodeId));
1297: for (Iterator i = listeners.iterator(); i.hasNext();) {
1298: LayoutEventListener lel = (LayoutEventListener) i.next();
1299: if (node.getNodeDescription().getType() == IUserLayoutNodeDescription.CHANNEL) {
1300: lel.channelMoved(ev);
1301: } else {
1302: lel.folderMoved(ev);
1303: }
1304: }
1305:
1306: updateCacheKey();
1307:
1308: return true;
1309: }
1310:
1311: public synchronized boolean deleteNode(String nodeId)
1312: throws PortalException {
1313:
1314: if (nodeId == null)
1315: return false;
1316:
1317: ALNode node = getLayoutNode(nodeId);
1318:
1319: if (node == null)
1320: return false;
1321:
1322: // Checking restrictions
1323: if (!canDeleteNode(nodeId)) {
1324: if (log.isDebugEnabled())
1325: log.debug("The node with ID = '" + nodeId
1326: + "' cannot be deleted");
1327: return false;
1328: }
1329:
1330: // Inform the layout listeners
1331: LayoutMoveEvent ev = new LayoutMoveEvent(this , node
1332: .getNodeDescription(), node.getParentNodeId());
1333: for (Iterator i = listeners.iterator(); i.hasNext();) {
1334: LayoutEventListener lel = (LayoutEventListener) i.next();
1335: if (getNode(nodeId).getType() == IUserLayoutNodeDescription.CHANNEL) {
1336: lel.channelDeleted(ev);
1337: } else {
1338: lel.folderDeleted(ev);
1339: }
1340: }
1341:
1342: // Deleting the node from the parent
1343: ALFolder parentFolder = getLayoutFolder(node.getParentNodeId());
1344:
1345: boolean result = true;
1346: if (nodeId.equals(parentFolder.getFirstChildNodeId())) {
1347: // Set the new first child node ID to the source folder
1348: parentFolder.setFirstChildNodeId(node.getNextNodeId());
1349: }
1350:
1351: // Changing the next node id for the previous sibling node
1352: // and the previous node for the next sibling node
1353: String prevSiblingId = node.getPreviousNodeId();
1354: String nextSiblingId = node.getNextNodeId();
1355:
1356: if (prevSiblingId != null) {
1357: ALNode prevNode = getLayoutNode(prevSiblingId);
1358: prevNode.setNextNodeId(nextSiblingId);
1359: }
1360:
1361: if (nextSiblingId != null) {
1362: ALNode nextNode = getLayoutNode(nextSiblingId);
1363: nextNode.setPreviousNodeId(prevSiblingId);
1364: }
1365:
1366: // Deleting the node and its children from the hashtable and returning the result value
1367: cleanLayoutData(nodeId, result);
1368:
1369: updateCacheKey();
1370:
1371: return result;
1372:
1373: }
1374:
1375: private void cleanLayoutData(String nodeId, boolean result)
1376: throws PortalException {
1377: ALNode node = getLayoutNode(nodeId);
1378: result = (layout.getLayoutData().remove(nodeId) != null)
1379: && result;
1380: if (node != null
1381: && node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
1382: // Loop for all children
1383: String firstChildId = ((ALFolder) node)
1384: .getFirstChildNodeId();
1385: for (String nextNodeId = firstChildId; nextNodeId != null;) {
1386: cleanLayoutData(nextNodeId, result);
1387: ALNode temp = getLayoutNode(nextNodeId);
1388: if (temp != null)
1389: nextNodeId = temp.getNextNodeId();
1390: else
1391: nextNodeId = null;
1392: }
1393: }
1394: }
1395:
1396: public synchronized IUserLayoutNodeDescription addNode(
1397: IUserLayoutNodeDescription nodeDesc, String parentId,
1398: String nextSiblingId) throws PortalException {
1399:
1400: // Checking restrictions
1401: if (!canAddNode(nodeDesc, parentId, nextSiblingId))
1402: return null;
1403:
1404: ALFolder parentFolder = getLayoutFolder(parentId);
1405: ALNode nextNode = getLayoutNode(nextSiblingId);
1406: ALNode prevNode = null;
1407:
1408: // If the nextNode != null we calculate the prev node from it otherwise we have to run to the last node in the sibling line
1409: if (nextNode != null)
1410: prevNode = getLayoutNode(nextNode.getPreviousNodeId());
1411: else
1412: prevNode = getLastSiblingNode(parentFolder
1413: .getFirstChildNodeId());
1414:
1415: // If currently a fragment is loaded the node desc should have a fragment ID
1416: if (isFragmentLoaded())
1417: ((IALNodeDescription) nodeDesc).setFragmentId(fragmentId);
1418:
1419: ALNode layoutNode = ALNode.createALNode(nodeDesc);
1420:
1421: // Setting the parent node ID
1422: layoutNode.setParentNodeId(parentId);
1423:
1424: if (prevNode != null)
1425: layoutNode.setPreviousNodeId(prevNode.getId());
1426: if (nextNode != null)
1427: layoutNode.setNextNodeId(nextSiblingId);
1428:
1429: // Add the new node to the database and get the node with a new node ID
1430: IALNodeDescription desc = (IALNodeDescription) layoutNode
1431: .getNodeDescription();
1432: desc.setId(layoutStore.getNextNodeId(person));
1433: if (desc.getType() == IUserLayoutNodeDescription.CHANNEL)
1434: layoutStore
1435: .fillChannelDescription((IALChannelDescription) desc);
1436:
1437: String nodeId = layoutNode.getId();
1438: // assert that no node references itself
1439: if (layoutNode != null
1440: && (nodeId.equals(layoutNode.getNextNodeId())
1441: || nodeId
1442: .equals(layoutNode.getPreviousNodeId()) || nodeId
1443: .equals(layoutNode.getParentNodeId()))) {
1444: throw new RuntimeException(
1445: "corrupted layout detected, node: " + nodeId + " "
1446: + "layout:" + layout);
1447: }
1448:
1449: // Putting the new node into the hashtable
1450: layout.getLayoutData().put(nodeId, layoutNode);
1451:
1452: if (prevNode != null)
1453: prevNode.setNextNodeId(nodeId);
1454:
1455: if (nextNode != null)
1456: nextNode.setPreviousNodeId(nodeId);
1457:
1458: // Setting new child node ID to the parent node
1459: if (prevNode == null)
1460: parentFolder.setFirstChildNodeId(nodeId);
1461:
1462: // Inform the layout listeners
1463: LayoutEvent ev = new LayoutEvent(this , layoutNode
1464: .getNodeDescription());
1465: for (Iterator i = listeners.iterator(); i.hasNext();) {
1466: LayoutEventListener lel = (LayoutEventListener) i.next();
1467: if (layoutNode.getNodeDescription().getType() == IUserLayoutNodeDescription.CHANNEL) {
1468: lel.channelAdded(ev);
1469: } else {
1470: lel.folderAdded(ev);
1471: }
1472: }
1473:
1474: updateCacheKey();
1475:
1476: return layoutNode.getNodeDescription();
1477: }
1478:
1479: private void changeDescendantsBooleanProperties(
1480: IALNodeDescription nodeDesc,
1481: IALNodeDescription oldNodeDesc, String nodeId)
1482: throws PortalException {
1483: changeDescendantsBooleanProperties(
1484: nodeDesc.isHidden() == oldNodeDesc.isHidden(),
1485: nodeDesc.isImmutable() == oldNodeDesc.isImmutable(),
1486: nodeDesc.isUnremovable() == oldNodeDesc.isUnremovable(),
1487: nodeDesc, nodeId);
1488: updateCacheKey();
1489: }
1490:
1491: private void changeDescendantsBooleanProperties(
1492: boolean hiddenValuesMatch, boolean immutableValuesMatch,
1493: boolean unremovableValuesMatch,
1494: IALNodeDescription nodeDesc, String nodeId)
1495: throws PortalException {
1496:
1497: ALNode node = getLayoutNode(nodeId);
1498:
1499: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
1500: // Loop for all children
1501: String firstChildId = ((ALFolder) node)
1502: .getFirstChildNodeId();
1503: for (String nextNodeId = firstChildId; nextNodeId != null;) {
1504:
1505: ALNode currentNode = getLayoutNode(nextNodeId);
1506:
1507: // Checking the hidden property if it's changed
1508: if (!hiddenValuesMatch) {
1509: // Checking the hidden node restriction
1510: boolean canChange = restrictionManager
1511: .checkRestriction(
1512: currentNode,
1513: RestrictionTypes.HIDDEN_RESTRICTION,
1514: CommonUtils.boolToStr(nodeDesc
1515: .isHidden()));
1516: // Checking the hidden parent node related restriction
1517: canChange &= restrictionManager
1518: .checkRestriction(
1519: currentNode.getParentNodeId(),
1520: RestrictionTypes.HIDDEN_RESTRICTION,
1521: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH,
1522: CommonUtils.boolToStr(nodeDesc
1523: .isHidden()));
1524: // Checking the hidden children node related restrictions
1525: if (currentNode.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
1526: ALFolder folder = (ALFolder) node;
1527: //Loop for all children
1528: for (String nextId = folder
1529: .getFirstChildNodeId(); nextId != null; nextId = getLayoutNode(
1530: nextId).getNextNodeId())
1531: canChange &= restrictionManager
1532: .checkRestriction(
1533: nextId,
1534: RestrictionTypes.HIDDEN_RESTRICTION,
1535: IUserLayoutRestriction.PARENT_RESTRICTION_PATH,
1536: CommonUtils
1537: .boolToStr(nodeDesc
1538: .isHidden()));
1539: }
1540: // Changing the hidden value if canChange is true
1541: if (canChange)
1542: currentNode.getNodeDescription().setHidden(
1543: nodeDesc.isHidden());
1544: }
1545:
1546: // Checking the immutable property if it's changed
1547: if (!immutableValuesMatch) {
1548: // Checking the immutable node restriction
1549: boolean canChange = restrictionManager
1550: .checkRestriction(
1551: currentNode,
1552: RestrictionTypes.IMMUTABLE_RESTRICTION,
1553: CommonUtils.boolToStr(nodeDesc
1554: .isImmutable()));
1555: // Checking the immutable parent node related restriction
1556: canChange &= restrictionManager
1557: .checkRestriction(
1558: currentNode.getParentNodeId(),
1559: RestrictionTypes.IMMUTABLE_RESTRICTION,
1560: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH,
1561: CommonUtils.boolToStr(nodeDesc
1562: .isImmutable()));
1563: // Checking the immutable children node related restrictions
1564: if (currentNode.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
1565: ALFolder folder = (ALFolder) node;
1566: //Loop for all children
1567: for (String nextId = folder
1568: .getFirstChildNodeId(); nextId != null; nextId = getLayoutNode(
1569: nextId).getNextNodeId())
1570: canChange &= restrictionManager
1571: .checkRestriction(
1572: nextId,
1573: RestrictionTypes.IMMUTABLE_RESTRICTION,
1574: IUserLayoutRestriction.PARENT_RESTRICTION_PATH,
1575: CommonUtils
1576: .boolToStr(nodeDesc
1577: .isImmutable()));
1578: }
1579: // Changing the immutable value if canChange is true
1580: if (canChange)
1581: currentNode.getNodeDescription().setImmutable(
1582: nodeDesc.isImmutable());
1583: }
1584:
1585: // Checking the unremovable property if it's changed
1586: if (!unremovableValuesMatch) {
1587: // Checking the unremovable node restriction
1588: boolean canChange = restrictionManager
1589: .checkRestriction(
1590: currentNode,
1591: RestrictionTypes.UNREMOVABLE_RESTRICTION,
1592: CommonUtils.boolToStr(nodeDesc
1593: .isUnremovable()));
1594: // Checking the unremovable parent node related restriction
1595: canChange &= restrictionManager
1596: .checkRestriction(
1597: currentNode.getParentNodeId(),
1598: RestrictionTypes.UNREMOVABLE_RESTRICTION,
1599: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH,
1600: CommonUtils.boolToStr(nodeDesc
1601: .isUnremovable()));
1602: // Checking the unremovable children node related restrictions
1603: if (currentNode.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
1604: ALFolder folder = (ALFolder) node;
1605: //Loop for all children
1606: for (String nextId = folder
1607: .getFirstChildNodeId(); nextId != null; nextId = getLayoutNode(
1608: nextId).getNextNodeId())
1609: canChange &= restrictionManager
1610: .checkRestriction(
1611: nextId,
1612: RestrictionTypes.UNREMOVABLE_RESTRICTION,
1613: IUserLayoutRestriction.PARENT_RESTRICTION_PATH,
1614: CommonUtils
1615: .boolToStr(nodeDesc
1616: .isImmutable()));
1617: }
1618: // Changing the unremovable value if canChange is true
1619: if (canChange)
1620: currentNode.getNodeDescription()
1621: .setUnremovable(
1622: nodeDesc.isUnremovable());
1623: }
1624: /// Recurrence
1625: changeDescendantsBooleanProperties(hiddenValuesMatch,
1626: immutableValuesMatch, unremovableValuesMatch,
1627: nodeDesc, nextNodeId);
1628: nextNodeId = currentNode.getNextNodeId();
1629: }
1630: }
1631:
1632: }
1633:
1634: public synchronized boolean updateNode(
1635: IUserLayoutNodeDescription nodeDesc) throws PortalException {
1636:
1637: // Checking restrictions
1638: if (!canUpdateNode(nodeDesc))
1639: return false;
1640:
1641: ALNode node = getLayoutNode(nodeDesc.getId());
1642: IALNodeDescription oldNodeDesc = (IALNodeDescription) node
1643: .getNodeDescription();
1644:
1645: // We have to change all the boolean properties on descendants
1646: changeDescendantsBooleanProperties(
1647: (IALNodeDescription) nodeDesc, oldNodeDesc, nodeDesc
1648: .getId());
1649: node.setNodeDescription((IALNodeDescription) nodeDesc);
1650:
1651: // Inform the layout listeners
1652: LayoutEvent ev = new LayoutEvent(this , nodeDesc);
1653: for (Iterator i = listeners.iterator(); i.hasNext();) {
1654: LayoutEventListener lel = (LayoutEventListener) i.next();
1655: if (nodeDesc.getType() == IUserLayoutNodeDescription.CHANNEL) {
1656: lel.channelUpdated(ev);
1657: } else {
1658: lel.folderUpdated(ev);
1659: }
1660: }
1661: updateCacheKey();
1662: return true;
1663: }
1664:
1665: public boolean canAddNode(IUserLayoutNodeDescription nodeDesc,
1666: String parentId, String nextSiblingId)
1667: throws PortalException {
1668:
1669: if (!(nodeDesc instanceof IALNodeDescription))
1670: throw new PortalException(
1671: "The node description must be IALNodeDescription type!");
1672:
1673: String newNodeId = nodeDesc.getId();
1674: ALNode newNode = null;
1675: if (newNodeId == null) {
1676: if (nodeDesc instanceof IALChannelDescription)
1677: newNode = new ALChannel(
1678: (IALChannelDescription) nodeDesc);
1679: else
1680: newNode = new ALFolder((IALFolderDescription) nodeDesc);
1681: } else
1682: newNode = layout.getLayoutNode(newNodeId);
1683:
1684: boolean result = restrictionManager.checkAddRestrictions(
1685: newNode, parentId, nextSiblingId);
1686: return (result && newNodeId != null) ? changeSiblingNodesPriorities(
1687: newNode, parentId, nextSiblingId)
1688: : result;
1689: }
1690:
1691: public boolean canMoveNode(String nodeId, String parentId,
1692: String nextSiblingId) throws PortalException {
1693: return restrictionManager.checkMoveRestrictions(nodeId,
1694: parentId, nextSiblingId) ? changeSiblingNodesPriorities(
1695: getLayoutNode(nodeId), parentId, nextSiblingId)
1696: : false;
1697: }
1698:
1699: public boolean canDeleteNode(String nodeId) throws PortalException {
1700: return restrictionManager.checkDeleteRestrictions(nodeId);
1701: }
1702:
1703: public boolean canUpdateNode(
1704: IUserLayoutNodeDescription nodeDescription)
1705: throws PortalException {
1706: return restrictionManager
1707: .checkUpdateRestrictions(nodeDescription);
1708: }
1709:
1710: public void markAddTargets(IUserLayoutNodeDescription nodeDesc)
1711: throws PortalException {
1712: if (nodeDesc != null
1713: && !(nodeDesc instanceof IALNodeDescription))
1714: throw new PortalException(
1715: "The given argument is not a node description!");
1716:
1717: boolean needsCacheKeyUpdate = (addTargetsNodeDesc != null && nodeDesc != null);
1718: addTargetsNodeDesc = (IALNodeDescription) nodeDesc;
1719: if (needsCacheKeyUpdate) {
1720: updateCacheKey();
1721: }
1722: }
1723:
1724: public void markMoveTargets(String nodeId) throws PortalException {
1725: if (nodeId != null && getLayoutNode(nodeId) == null)
1726: throw new PortalException("The node with nodeID=" + nodeId
1727: + " does not exist in the layout!");
1728:
1729: boolean needsCacheKeyUpdate = (moveTargetsNodeId != null && nodeId != null);
1730: moveTargetsNodeId = nodeId;
1731: if (needsCacheKeyUpdate) {
1732: updateCacheKey();
1733: }
1734: }
1735:
1736: /**
1737: * Returns the description of the node currently being added to the layout
1738: *
1739: * @return node an <code>IALNodeDescription</code> object
1740: * @exception PortalException if an error occurs
1741: */
1742: public IALNodeDescription getNodeBeingAdded()
1743: throws PortalException {
1744: return addTargetsNodeDesc;
1745: }
1746:
1747: /**
1748: * Returns the description of the node currently being moved in the layout
1749: *
1750: * @return node an <code>IALNodeDescription</code> object
1751: * @exception PortalException if an error occurs
1752: */
1753: public IALNodeDescription getNodeBeingMoved()
1754: throws PortalException {
1755: if (moveTargetsNodeId != null) {
1756: ALNode node = getLayoutNode(moveTargetsNodeId);
1757: return (node != null) ? (IALNodeDescription) node
1758: .getNodeDescription() : null;
1759: }
1760: return null;
1761: }
1762:
1763: public boolean addLayoutEventListener(LayoutEventListener l) {
1764: return listeners.add(l);
1765: }
1766:
1767: public boolean removeLayoutEventListener(LayoutEventListener l) {
1768: return listeners.remove(l);
1769: }
1770:
1771: /**
1772: * Returns an id of the root folder.
1773: *
1774: * @return a <code>String</code> value
1775: */
1776: public String getRootFolderId() {
1777: return layout.getRootId();
1778: }
1779:
1780: /**
1781: * Returns a subscription id given a functional name.
1782: * @param fname the functional name to lookup.
1783: * @return a <code>String</code> subscription id.
1784: */
1785: public String getSubscribeId(String fname) throws PortalException {
1786: return layout.getNodeId(fname);
1787: }
1788:
1789: /* (non-Javadoc)
1790: * @see org.jasig.portal.layout.IUserLayoutManager#processLayoutParameters(org.jasig.portal.security.IPerson, org.jasig.portal.UserPreferences, javax.servlet.http.HttpServletRequest)
1791: */
1792: public void processLayoutParameters(IPerson person,
1793: UserPreferences userPrefs, HttpServletRequest req)
1794: throws PortalException {
1795: try {
1796: String newNodeId = null;
1797:
1798: // Sending the theme stylesheets parameters based on the user security context
1799: ThemeStylesheetUserPreferences themePrefs = userPrefs
1800: .getThemeStylesheetUserPreferences();
1801: StructureStylesheetUserPreferences structPrefs = userPrefs
1802: .getStructureStylesheetUserPreferences();
1803:
1804: String authenticated = String.valueOf(person
1805: .getSecurityContext().isAuthenticated());
1806: structPrefs.putParameterValue("authenticated",
1807: authenticated);
1808: try {
1809: if (ChannelStaticData.getAuthorizationPrincipal(person)
1810: .canPublish()) {
1811: themePrefs.putParameterValue(
1812: "authorizedFragmentPublisher", "true");
1813: themePrefs.putParameterValue(
1814: "authorizedChannelPublisher", "true");
1815: }
1816: } catch (Exception e) {
1817: log.error("Exception determining publish rights for "
1818: + this .person, e);
1819: }
1820:
1821: String[] values;
1822:
1823: if ((values = req
1824: .getParameterValues("uP_request_move_targets")) != null) {
1825: if (values[0].trim().length() == 0)
1826: values[0] = null;
1827: this .markMoveTargets(values[0]);
1828: } else {
1829: this .markMoveTargets(null);
1830: }
1831:
1832: if ((values = req
1833: .getParameterValues("uP_request_add_targets")) != null) {
1834: String value;
1835: int nodeType = values[0].equals("folder") ? IUserLayoutNodeDescription.FOLDER
1836: : IUserLayoutNodeDescription.CHANNEL;
1837: IUserLayoutNodeDescription nodeDesc = this
1838: .createNodeDescription(nodeType);
1839: nodeDesc.setName("Unnamed");
1840: if (nodeType == IUserLayoutNodeDescription.CHANNEL
1841: && (value = req
1842: .getParameter("channelPublishID")) != null) {
1843: String contentPublishId = value.trim();
1844: if (contentPublishId.length() > 0) {
1845: ((IUserLayoutChannelDescription) nodeDesc)
1846: .setChannelPublishId(contentPublishId);
1847: themePrefs.putParameterValue(
1848: "channelPublishID", contentPublishId);
1849: }
1850: } else if (nodeType == IUserLayoutNodeDescription.FOLDER
1851: && (value = req
1852: .getParameter("fragmentPublishID")) != null) {
1853: String contentPublishId = value.trim();
1854: String fragmentRootId = CommonUtils.nvl(req
1855: .getParameter("fragmentRootID"));
1856: if (contentPublishId.length() > 0
1857: && fragmentRootId.length() > 0) {
1858: IALFolderDescription folderDesc = (IALFolderDescription) nodeDesc;
1859: folderDesc.setFragmentId(contentPublishId);
1860: folderDesc.setFragmentNodeId(fragmentRootId);
1861: }
1862: //themePrefs.putParameterValue("uP_fragmentPublishID",contentPublishId);
1863: }
1864: newNodeDescription = nodeDesc;
1865: this .markAddTargets(newNodeDescription);
1866: } else {
1867: this .markAddTargets(null);
1868: }
1869:
1870: if ((values = req.getParameterValues("uP_add_target")) != null) {
1871: String[] values1, values2;
1872: String value = null;
1873: values1 = req.getParameterValues("targetNextID");
1874: if (values1 != null && values1.length > 0)
1875: value = values1[0];
1876: if ((values2 = req.getParameterValues("targetParentID")) != null) {
1877: if (newNodeDescription != null) {
1878: if (CommonUtils.nvl(value).trim().length() == 0)
1879: value = null;
1880:
1881: // Adding a new node
1882: newNodeId = this .addNode(newNodeDescription,
1883: values2[0], value).getId();
1884:
1885: // if the new node is a fragment being added - we need to re-load the layout
1886: if (newNodeDescription instanceof IALFolderDescription) {
1887: IALFolderDescription folderDesc = (IALFolderDescription) newNodeDescription;
1888: if (folderDesc.getFragmentNodeId() != null) {
1889: this .saveUserLayout();
1890: this .loadUserLayout();
1891: }
1892: }
1893:
1894: }
1895: }
1896: newNodeDescription = null;
1897: }
1898:
1899: if ((values = req.getParameterValues("uP_move_target")) != null) {
1900: String[] values1, values2;
1901: String value = null;
1902: values1 = req.getParameterValues("targetNextID");
1903: if (values1 != null && values1.length > 0)
1904: value = values1[0];
1905: if ((values2 = req.getParameterValues("targetParentID")) != null) {
1906: if (CommonUtils.nvl(value).trim().length() == 0)
1907: value = null;
1908: this .moveNode(values[0], values2[0], value);
1909: }
1910: }
1911:
1912: if ((values = req.getParameterValues("uP_rename_target")) != null) {
1913: String[] values1;
1914: if ((values1 = req.getParameterValues("uP_target_name")) != null) {
1915: IUserLayoutNodeDescription nodeDesc = this
1916: .getNode(values[0]);
1917: if (nodeDesc != null) {
1918: String oldName = nodeDesc.getName();
1919: nodeDesc.setName(values1[0]);
1920: if (!this .updateNode(nodeDesc))
1921: nodeDesc.setName(oldName);
1922: }
1923: }
1924: }
1925:
1926: if ((values = req.getParameterValues("uP_remove_target")) != null) {
1927: for (int i = 0; i < values.length; i++) {
1928: this .deleteNode(values[i]);
1929: }
1930: }
1931:
1932: String param = req.getParameter("uP_cancel_targets");
1933: if (param != null && param.equals("true")) {
1934: this .markAddTargets(null);
1935: this .markMoveTargets(null);
1936: newNodeDescription = null;
1937: }
1938:
1939: param = req.getParameter("uP_reload_layout");
1940: if (param != null && param.equals("true")) {
1941: this .loadUserLayout();
1942: }
1943:
1944: param = req.getParameter("uPcFM_action");
1945: if (param != null) {
1946: String fragmentId = req.getParameter("uP_fragmentID");
1947: if (param.equals("edit") && fragmentId != null) {
1948: if (CommonUtils.parseInt(fragmentId) > 0)
1949: this .loadFragment(fragmentId);
1950: else
1951: this .loadUserLayout();
1952: } else if (param.equals("save")) {
1953: this .saveFragment();
1954: }
1955: }
1956:
1957: // If we have created a new node we need to let the structure XSL know about it
1958: structPrefs.putParameterValue("newNodeID", CommonUtils
1959: .nvl(newNodeId));
1960: // Sending the parameter indicating whether the layout or the fragment is loaded in the preferences mode
1961: structPrefs.putParameterValue("current_structure", this
1962: .isFragmentLoaded() ? "fragment" : "layout");
1963: } catch (Exception e) {
1964: throw new PortalException(e);
1965: }
1966: }
1967:
1968: }
|