001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.layout.restrictions.alm;
007:
008: import java.util.Collection;
009: import java.util.Enumeration;
010: import java.util.Hashtable;
011: import java.util.Iterator;
012: import org.jasig.portal.PortalException;
013: import org.jasig.portal.layout.IUserLayout;
014: import org.jasig.portal.layout.alm.ALFolder;
015: import org.jasig.portal.layout.alm.ALNode;
016: import org.jasig.portal.layout.alm.IALNodeDescription;
017: import org.jasig.portal.layout.alm.IAggregatedLayout;
018: import org.jasig.portal.layout.node.ILayoutNode;
019: import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
020: import org.jasig.portal.layout.restrictions.IUserLayoutRestriction;
021: import org.jasig.portal.layout.restrictions.UserLayoutRestriction;
022: import org.jasig.portal.layout.restrictions.UserLayoutRestrictionFactory;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: /**
027: * An implementation of Restriction Manager Interface
028: *
029: * @author <a href="mailto:mvi@immagic.com">Michael Ivanov</a>
030: * @version $Revision: 35731 $
031: * @since uPortal 2.5
032: */
033: public class ALRestrictionManager implements IALRestrictionManager {
034:
035: private static final Log log = LogFactory
036: .getLog(ALRestrictionManager.class);
037: private IAggregatedLayout layout;
038:
039: public ALRestrictionManager() throws Exception {
040: }
041:
042: public ALRestrictionManager(IAggregatedLayout layout)
043: throws Exception {
044: this .layout = layout;
045: }
046:
047: public void setUserLayout(IUserLayout layout)
048: throws PortalException {
049: if (!(layout instanceof IAggregatedLayout))
050: throw new PortalException(
051: "The user layout instance must have IAggregatedLayout type!");
052: this .layout = (IAggregatedLayout) layout;
053: }
054:
055: /**
056: * Checks the restriction specified by the parameters below
057: * @param nodeId a <code>String</code> node ID
058: * @param restrictionName a restriction name
059: * @param restrictionPath a <code>String</code> restriction path
060: * @param propertyValue a <code>String</code> property value to be checked
061: * @return a boolean value
062: * @exception PortalException if an error occurs
063: */
064: public boolean checkRestriction(String nodeId,
065: String restrictionName, String restrictionPath,
066: String propertyValue) throws PortalException {
067: ALNode node = layout.getLayoutNode(nodeId);
068: return (node != null) ? checkRestriction(node, restrictionName,
069: restrictionPath, propertyValue) : true;
070: }
071:
072: /**
073: * Checks the local restriction specified by the parameters below
074: * @param nodeId a <code>String</code> node ID
075: * @param restrictionName a restriction name
076: * @param propertyValue a <code>String</code> property value to be checked
077: * @return a boolean value
078: * @exception PortalException if an error occurs
079: */
080: public boolean checkRestriction(String nodeId,
081: String restrictionName, String propertyValue)
082: throws PortalException {
083: return (nodeId != null) ? checkRestriction(nodeId,
084: restrictionName,
085: IUserLayoutRestriction.LOCAL_RESTRICTION_PATH,
086: propertyValue) : true;
087: }
088:
089: /**
090: * Checks the restriction specified by the parameters below
091: * @param node a <code>ALNode</code> node to be checked
092: * @param restrictionName a restriction name
093: * @param restrictionPath a <code>String</code> restriction path
094: * @param propertyValue a <code>String</code> property value to be checked
095: * @return a boolean value
096: * @exception PortalException if an error occurs
097: */
098: public boolean checkRestriction(ALNode node,
099: String restrictionName, String restrictionPath,
100: String propertyValue) throws PortalException {
101: IUserLayoutRestriction restriction = node
102: .getRestriction(UserLayoutRestriction.getUniqueKey(
103: restrictionName, restrictionPath));
104: if (restriction != null)
105: return restriction.checkRestriction(propertyValue);
106: return true;
107: }
108:
109: /**
110: * Checks the local restriction specified by the parameters below
111: * @param node a <code>ALNode</code> node to be checked
112: * @param restrictionName a restriction name
113: * @param propertyValue a <code>String</code> property value to be checked
114: * @return a boolean value
115: * @exception PortalException if an error occurs
116: */
117: public boolean checkRestriction(ALNode node,
118: String restrictionName, String propertyValue)
119: throws PortalException {
120: return checkRestriction(node, restrictionName,
121: IUserLayoutRestriction.LOCAL_RESTRICTION_PATH,
122: propertyValue);
123: }
124:
125: /**
126: * Checks the necessary restrictions while adding a new node
127: * @param node a <code>ILayoutNode</code> a new node to be added
128: * @param parentId a <code>String</code> parent node ID
129: * @param nextSiblingId a <code>String</code> next sibling node ID
130: * @return a boolean value
131: * @exception PortalException if an error occurs
132: */
133: public boolean checkAddRestrictions(ILayoutNode node,
134: String parentId, String nextSiblingId)
135: throws PortalException {
136:
137: if (!(node instanceof ALNode))
138: throw new PortalException("The node must be ALNode type!");
139:
140: ALNode newNode = (ALNode) node;
141: String newNodeId = newNode.getId();
142: ALNode parentNode = layout.getLayoutNode(parentId);
143:
144: if (!(parentNode.getNodeType() == IUserLayoutNodeDescription.FOLDER))
145: throw new PortalException(
146: "The target parent node should be a folder!");
147:
148: //if ( checkRestriction(parentNode,RestrictionTypes.IMMUTABLE_RESTRICTION,"false") ) {
149: if (!parentNode.getNodeDescription().isImmutable()) {
150:
151: // Checking children related restrictions
152: Collection restrictions = parentNode
153: .getRestrictionsByPath(IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH);
154: for (Iterator i = restrictions.iterator(); i.hasNext();) {
155: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
156: .next();
157: if (!restriction.getName().equals(
158: RestrictionTypes.DEPTH_RESTRICTION)
159: && !restriction.checkRestriction(newNode))
160: return false;
161: }
162:
163: // Checking parent related restrictions
164: restrictions = newNode
165: .getRestrictionsByPath(IUserLayoutRestriction.PARENT_RESTRICTION_PATH);
166: for (Iterator i = restrictions.iterator(); i.hasNext();) {
167: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
168: .next();
169: if (!restriction.getName().equals(
170: RestrictionTypes.DEPTH_RESTRICTION)
171: && !restriction.checkRestriction(parentNode))
172: return false;
173: }
174:
175: // Considering two cases if the node is new or it is already in the user layout
176: if (newNodeId != null) {
177: // Checking depth restrictions for the node and all its descendants (if there are any)
178: if (!checkDepthRestrictions(newNodeId, parentId))
179: return false;
180: } else
181: return checkRestriction(newNode,
182: RestrictionTypes.DEPTH_RESTRICTION, (layout
183: .getDepth(parentId) + 1)
184: + "");
185:
186: // Checking sibling nodes order
187: //return changeSiblingNodesPriorities(newNode,parentId,nextSiblingId);
188: return true;
189:
190: } else
191: return false;
192: }
193:
194: /**
195: * Checks the necessary restrictions while moving a node
196: * @param nodeId a <code>String</code> node ID of a node to be moved
197: * @param newParentId a <code>String</code> new parent node ID
198: * @param nextSiblingId a <code>String</code> next sibling node ID
199: * @return a boolean value
200: * @exception PortalException if an error occurs
201: */
202: public boolean checkMoveRestrictions(String nodeId,
203: String newParentId, String nextSiblingId)
204: throws PortalException {
205:
206: ALNode node = layout.getLayoutNode(nodeId);
207: ALNode oldParentNode = layout.getLayoutNode(node
208: .getParentNodeId());
209: ALFolder newParentNode = layout.getLayoutFolder(newParentId);
210:
211: /*if ( checkRestriction(oldParentNode,RestrictionTypes.IMMUTABLE_RESTRICTION,"false") &&
212: checkRestriction(newParentNode,RestrictionTypes.IMMUTABLE_RESTRICTION,"false") ) {*/
213: if (!oldParentNode.getNodeDescription().isImmutable()
214: && !newParentNode.getNodeDescription().isImmutable()) {
215:
216: if (!oldParentNode.equals(newParentNode)) {
217: // Checking children related restrictions
218: Collection restrictions = newParentNode
219: .getRestrictionsByPath(IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH);
220: for (Iterator i = restrictions.iterator(); i.hasNext();) {
221: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
222: .next();
223: if (!restriction.getName().equals(
224: RestrictionTypes.DEPTH_RESTRICTION)
225: && !restriction.checkRestriction(node))
226: return false;
227: }
228:
229: // Checking parent related restrictions
230: restrictions = node
231: .getRestrictionsByPath(IUserLayoutRestriction.PARENT_RESTRICTION_PATH);
232: for (Iterator i = restrictions.iterator(); i.hasNext();) {
233: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
234: .next();
235: if (!restriction.getName().equals(
236: RestrictionTypes.DEPTH_RESTRICTION)
237: && !restriction
238: .checkRestriction(newParentNode))
239: return false;
240: }
241:
242: // Checking depth restrictions for the node and all its descendants
243: if (!checkDepthRestrictions(nodeId, newParentId))
244: return false;
245: }
246:
247: return true;
248:
249: } else
250: return false;
251: }
252:
253: /**
254: * Checks the necessary restrictions while deleting a node
255: * @param nodeId a <code>String</code> node ID of a node to be deleted
256: * @return a boolean value
257: * @exception PortalException if an error occurs
258: */
259: public boolean checkDeleteRestrictions(String nodeId)
260: throws PortalException {
261: ALNode node = layout.getLayoutNode(nodeId);
262: if (nodeId == null || node == null)
263: return true;
264: //if ( checkRestriction(node.getParentNodeId(),RestrictionTypes.IMMUTABLE_RESTRICTION,"false") ) {
265: if (!layout.getLayoutNode(node.getParentNodeId())
266: .getNodeDescription().isImmutable()) {
267: // Checking the unremovable restriction on the node to be deleted
268: //return checkRestriction(nodeId,RestrictionTypes.UNREMOVABLE_RESTRICTION,"false");
269: return !node.getNodeDescription().isUnremovable();
270: } else
271: return false;
272: }
273:
274: /**
275: * Recursively checks the depth restrictions beginning with a given node
276: * @param nodeId a <code>String</code> node ID
277: * @param newParentId a <code>String</code> new parent node ID
278: * @return a boolean value
279: * @exception PortalException if an error occurs
280: */
281: public boolean checkDepthRestrictions(String nodeId,
282: String newParentId) throws PortalException {
283: if (nodeId == null)
284: return true;
285: int nodeDepth = layout.getDepth(nodeId);
286: int parentDepth = layout.getDepth(newParentId);
287: if (nodeDepth == parentDepth + 1)
288: return true;
289: return checkDepthRestrictions(nodeId, parentDepth + 1);
290: }
291:
292: /**
293: * Recursively checks the depth restrictions beginning with a given node
294: * @param nodeId a <code>String</code> node ID
295: * @param depth a depth on which the node is going to be attached
296: * @return a boolean value
297: * @exception PortalException if an error occurs
298: */
299: public boolean checkDepthRestrictions(String nodeId, int depth)
300: throws PortalException {
301: ALNode node = layout.getLayoutNode(nodeId);
302: // Checking restrictions for the node
303: if (!checkRestriction(nodeId,
304: RestrictionTypes.DEPTH_RESTRICTION, depth + ""))
305: return false;
306: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
307: for (String nextId = ((ALFolder) node)
308: .getFirstChildNodeId(); nextId != null; nextId = node
309: .getNextNodeId()) {
310: node = layout.getLayoutNode(nextId);
311: if (!checkDepthRestrictions(nextId, depth + 1))
312: return false;
313: }
314: }
315: return true;
316: }
317:
318: /**
319: * Gets the restriction specified by the parameters below
320: * @param node a <code>ALNode</code> node
321: * @param restrictionName a restriction name
322: * @param restrictionPath a <code>String</code> restriction path
323: * @return a <code>IUserLayoutRestriction</code> instance
324: * @exception PortalException if an error occurs
325: */
326: public static IUserLayoutRestriction getRestriction(ALNode node,
327: String restrictionName, String restrictionPath)
328: throws PortalException {
329: return node.getRestriction(UserLayoutRestriction.getUniqueKey(
330: restrictionName, restrictionPath));
331: }
332:
333: /**
334: * Return a priority restriction for the given node.
335: * @return a <code>PriorityRestriction</code> object
336: * @exception PortalException if an error occurs
337: */
338: public static PriorityRestriction getPriorityRestriction(ALNode node)
339: throws PortalException {
340: PriorityRestriction priorRestriction = getPriorityRestriction(
341: node, IUserLayoutRestriction.LOCAL_RESTRICTION_PATH);
342: if (priorRestriction == null) {
343: priorRestriction = (PriorityRestriction) UserLayoutRestrictionFactory
344: .createRestriction(
345: RestrictionTypes.PRIORITY_RESTRICTION, "0-"
346: + java.lang.Integer.MAX_VALUE);
347: }
348: return priorRestriction;
349: }
350:
351: /**
352: * Return a priority restriction for the given node.
353: * @return a <code>PriorityRestriction</code> object
354: * @exception PortalException if an error occurs
355: */
356: public static PriorityRestriction getPriorityRestriction(
357: ALNode node, String restrictionPath) throws PortalException {
358: return (PriorityRestriction) getRestriction(node,
359: RestrictionTypes.PRIORITY_RESTRICTION, restrictionPath);
360: }
361:
362: public boolean checkUpdateRestrictions(
363: IUserLayoutNodeDescription nodeDescription)
364: throws PortalException {
365: IALNodeDescription nodeDesc = (IALNodeDescription) nodeDescription;
366: String nodeId = nodeDesc.getId();
367:
368: if (nodeId == null)
369: return false;
370: ALNode node = layout.getLayoutNode(nodeId);
371: IALNodeDescription currentNodeDesc = (IALNodeDescription) node
372: .getNodeDescription();
373: // If the node Ids do no match to each other then return false
374: if (!nodeId.equals(currentNodeDesc.getId()))
375: return false;
376:
377: // Checking the immutable node restriction
378: //if ( checkRestriction(node,RestrictionTypes.IMMUTABLE_RESTRICTION,"true") )
379: if (currentNodeDesc.isImmutable())
380: return false;
381:
382: // Checking the immutable parent node related restriction
383: if (getRestriction(
384: layout.getLayoutNode(node.getParentNodeId()),
385: RestrictionTypes.IMMUTABLE_RESTRICTION,
386: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH) != null
387: && checkRestriction(
388: node.getParentNodeId(),
389: RestrictionTypes.IMMUTABLE_RESTRICTION,
390: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH,
391: "true"))
392: return false;
393:
394: // Checking the immutable children node related restrictions
395: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
396: ALFolder folder = (ALFolder) node;
397: //Loop for all children
398: for (String nextId = folder.getFirstChildNodeId(); nextId != null; nextId = layout
399: .getLayoutNode(nextId).getNextNodeId())
400: if (getRestriction(layout.getLayoutNode(nextId),
401: RestrictionTypes.IMMUTABLE_RESTRICTION,
402: IUserLayoutRestriction.PARENT_RESTRICTION_PATH) != null
403: && checkRestriction(
404: nextId,
405: RestrictionTypes.IMMUTABLE_RESTRICTION,
406: IUserLayoutRestriction.PARENT_RESTRICTION_PATH,
407: "true"))
408: return false;
409: }
410:
411: // if a new node description doesn't contain any restrictions the old restrictions will be used
412: if (nodeDesc.getRestrictions() == null)
413: nodeDesc.setRestrictions(currentNodeDesc.getRestrictions());
414: Hashtable rhash = nodeDesc.getRestrictions();
415: // Setting the new node description to the node
416: node.setNodeDescription(nodeDesc);
417:
418: // Checking restrictions for the node
419: if (rhash != null) {
420: for (Enumeration enum1 = rhash.elements(); enum1
421: .hasMoreElements();)
422: if (!((IUserLayoutRestriction) enum1.nextElement())
423: .checkRestriction(node)) {
424: node.setNodeDescription(currentNodeDesc);
425: return false;
426: }
427: }
428:
429: // Checking parent related restrictions for the children
430: Collection restrictions = layout.getLayoutNode(
431: node.getParentNodeId()).getRestrictionsByPath(
432: IUserLayoutRestriction.CHILDREN_RESTRICTION_PATH);
433: for (Iterator i = restrictions.iterator(); i.hasNext();) {
434: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
435: .next();
436: if (!restriction.checkRestriction(node)) {
437: node.setNodeDescription(currentNodeDesc);
438: return false;
439: }
440: }
441:
442: // Checking child related restrictions for the parent
443: if (node.getNodeType() == IUserLayoutNodeDescription.FOLDER) {
444: for (String nextId = ((ALFolder) node)
445: .getFirstChildNodeId(); nextId != null;) {
446: ALNode child = layout.getLayoutNode(nextId);
447: restrictions = child
448: .getRestrictionsByPath(IUserLayoutRestriction.PARENT_RESTRICTION_PATH);
449: for (Iterator i = restrictions.iterator(); i.hasNext();) {
450: IUserLayoutRestriction restriction = (IUserLayoutRestriction) i
451: .next();
452: if (!restriction.checkRestriction(node)) {
453: node.setNodeDescription(currentNodeDesc);
454: return false;
455: }
456: }
457: nextId = child.getNextNodeId();
458: }
459: }
460:
461: return true;
462: }
463:
464: }
|