001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.impl.model.portal;
023:
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import org.jboss.logging.Logger;
033: import org.jboss.portal.core.model.portal.DuplicatePortalObjectException;
034: import org.jboss.portal.core.model.portal.NoSuchPortalObjectException;
035: import org.jboss.portal.core.model.portal.PortalObjectId;
036: import org.jboss.portal.jems.hibernate.ContextObject;
037: import org.jboss.portal.security.RoleSecurityBinding;
038:
039: /**
040: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
041: * @version $Revision: 8822 $
042: */
043: public class ObjectNode implements ContextObject {
044:
045: /** . */
046: protected static final Logger log = Logger
047: .getLogger(ObjectNode.class);
048:
049: /** . */
050: protected static final boolean trace = log.isTraceEnabled();
051:
052: // Persistent fields
053: private Long key;
054: private PortalObjectId path;
055: private String name;
056: private ObjectNode parent;
057: private Map children;
058: private PortalObjectImpl object;
059: private Map securityConstraints;
060:
061: // Runtime fields
062: private AbstractPortalObjectContainer.ContainerContext containerContext;
063:
064: public ObjectNode() {
065: this .containerContext = null;
066: this .path = null;
067: this .name = null;
068: this .children = null;
069: this .securityConstraints = null;
070: }
071:
072: public ObjectNode(
073: AbstractPortalObjectContainer.ContainerContext containerContext,
074: PortalObjectId path, String name) {
075: if (containerContext == null) {
076: throw new IllegalArgumentException("No context provided");
077: }
078: this .containerContext = containerContext;
079: this .path = path;
080: this .name = name;
081: this .children = new HashMap();
082: this .securityConstraints = new HashMap();
083: }
084:
085: // ContextObject implementation *************************************************************************************
086:
087: public void setContext(Object context) {
088: this .containerContext = (AbstractPortalObjectContainer.ContainerContext) context;
089: }
090:
091: public Long getKey() {
092: return key;
093: }
094:
095: public void setKey(Long key) {
096: this .key = key;
097: }
098:
099: public PortalObjectImpl getObject() {
100: return object;
101: }
102:
103: public void setObject(PortalObjectImpl object) {
104: this .object = object;
105: }
106:
107: /**
108: * Create and persist the provided child object. The object also becomes of child of this node.
109: *
110: * @param name the child name
111: * @param childObject the child object
112: * @throws DuplicatePortalObjectException if a child with such a name already exists
113: * @throws IllegalArgumentException if the name is null or zero length or the child object is null
114: */
115: void addChild(String name, PortalObjectImpl childObject)
116: throws DuplicatePortalObjectException,
117: IllegalArgumentException {
118: if (name == null) {
119: throw new IllegalArgumentException("No null name accepted");
120: }
121: if (name.length() == 0) {
122: throw new IllegalArgumentException(
123: "No name with null value accepted");
124: }
125: if (childObject == null) {
126: throw new IllegalArgumentException("No null child accepted");
127: }
128: if (children.containsKey(name)) {
129: throw new DuplicatePortalObjectException("Object " + path
130: + " has already a child with the name " + name);
131: }
132:
133: //
134: PortalObjectId childPath = toChildPath(name);
135:
136: //
137: log.debug("Creating child of path='" + path + "' with path='"
138: + childPath + "'");
139: ObjectNode childNode = new ObjectNode(containerContext,
140: childPath, name);
141: childNode.setObject(childObject);
142: childObject.setObjectNode(childNode);
143:
144: //
145: containerContext.createChild(childNode);
146:
147: //
148: children.put(name, childNode);
149: childNode.parent = this ;
150:
151: // Contextualize
152: if (childObject instanceof ContextObject) {
153: ContextObject co = (ContextObject) childObject;
154: co.setContext(containerContext);
155: }
156: }
157:
158: /** Destroy the association. */
159: void removeChild(String name) throws NoSuchPortalObjectException,
160: IllegalArgumentException {
161: if (name == null) {
162: throw new IllegalArgumentException("No null name accepted");
163: }
164:
165: //
166: log.debug("Removing child of '" + path + "' with name '" + name
167: + "'");
168: ObjectNode child = (ObjectNode) children.get(name);
169: if (child == null) {
170: throw new NoSuchPortalObjectException("Child " + name
171: + " of " + path + " does not exist");
172: }
173:
174: // Destroy the children recursively
175: for (Iterator i = new ArrayList(child.getChildren().keySet())
176: .iterator(); i.hasNext();) {
177: String childName = (String) i.next();
178: child.removeChild(childName);
179: }
180:
181: // Callback
182: child.getObject().destroy();
183:
184: // Let the container destroy it
185: containerContext.destroyChild(child);
186:
187: // Break the relationship
188: children.remove(name);
189: child.setParent(null);
190: }
191:
192: public PortalObjectId getPath() {
193: return path;
194: }
195:
196: public void setPath(PortalObjectId path) {
197: this .path = path;
198: }
199:
200: public String getName() {
201: return name;
202: }
203:
204: public void setName(String name) {
205: this .name = name;
206: }
207:
208: public ObjectNode getParent() {
209: return parent;
210: }
211:
212: public void setParent(ObjectNode parent) {
213: this .parent = parent;
214: }
215:
216: public Map getChildren() {
217: return children;
218: }
219:
220: public void setChildren(Map children) {
221: this .children = children;
222: }
223:
224: public AbstractPortalObjectContainer.ContainerContext getContext() {
225: return containerContext;
226: }
227:
228: public String toString() {
229: return "PortalObject[id=" + path + "]";
230: }
231:
232: protected PortalObjectId toChildPath(String name) {
233: return new PortalObjectId(path.getNamespace(), path.getPath()
234: .getChild(name));
235: }
236:
237: public Map getSecurityConstraints() {
238: return securityConstraints;
239: }
240:
241: public void setSecurityConstraints(Map securityConstraints) {
242: this .securityConstraints = securityConstraints;
243: }
244:
245: public void setBindings(Set bindings) {
246: // Clear existing constraints
247: securityConstraints.clear();
248: for (Iterator i = securityConstraints.values().iterator(); i
249: .hasNext();) {
250: ObjectNodeSecurityConstraint onsc = (ObjectNodeSecurityConstraint) i
251: .next();
252: i.remove();
253: onsc.setObjectNode(null);
254: }
255:
256: // Replace with new ones
257: for (Iterator i = bindings.iterator(); i.hasNext();) {
258: RoleSecurityBinding sc = (RoleSecurityBinding) i.next();
259:
260: // Optmize a bit
261: if (sc.getActions().size() > 0) {
262: ObjectNodeSecurityConstraint onsc = new ObjectNodeSecurityConstraint(
263: sc.getActions(), sc.getRoleName());
264:
265: //
266: onsc.setObjectNode(this );
267: securityConstraints.put(onsc.getRole(), onsc);
268: }
269: }
270:
271: //
272: containerContext.updated(this );
273: }
274:
275: public Set getBindings() {
276: Set bindings = new HashSet();
277: for (Iterator i = securityConstraints.values().iterator(); i
278: .hasNext();) {
279: ObjectNodeSecurityConstraint onsc = (ObjectNodeSecurityConstraint) i
280: .next();
281: Set actions = onsc.getActions();
282: RoleSecurityBinding sc = new RoleSecurityBinding(actions,
283: onsc.getRole());
284: bindings.add(sc);
285: }
286: return bindings;
287: }
288:
289: public RoleSecurityBinding getBinding(String roleName) {
290: Set actions = null;
291: for (Iterator i = securityConstraints.values().iterator(); i
292: .hasNext();) {
293: ObjectNodeSecurityConstraint onsc = (ObjectNodeSecurityConstraint) i
294: .next();
295: if (onsc.getRole().equals(roleName)) {
296: actions = onsc.getActions();
297: break;
298: }
299: }
300:
301: //
302: if ("dashboard".equals(path.getNamespace())) {
303: if (actions == null) {
304: actions = Collections.singleton("dashboard");
305: } else {
306: actions = new HashSet(actions);
307: actions.add("dashboard");
308: }
309: }
310:
311: // Add the dashboard permission
312: if (actions != null) {
313: return new RoleSecurityBinding(actions, roleName);
314: } else {
315: return null;
316: }
317: }
318: }
|