Source code: com/flexstor/common/data/ejb/search/AssetTree.java
1 /*
2 * AssetTree.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:37 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.common.data.ejb.search;
12
13 import java.util.Enumeration;
14 import java.util.Vector;
15
16 import com.flexstor.common.constants.BucketConstantsI;
17 import com.flexstor.common.util.FlexNode;
18
19 /**
20 * For a single disguise, this object is filled by the
21 * SearchResultRetrievalBean.getAssetsStructure() method with information
22 * about some assets in a tree-like structure.
23 * The root element of the tree contains the disguise id, the next level
24 * contains the element bucket and from there downwards are all assets in their
25 * hierarchical structure (primary parent, child, parent, child, etc).
26 */
27 public class AssetTree
28 extends FlexNode
29 {
30 /**
31 * Constant to denote a disguise node (the root node)
32 */
33 public final static int DISGUISE = -1;
34
35 /**
36 * For the root node, this will be the disguise id, for first-level nodes
37 * this will be the element id, for the rest, it will be the asset ids.
38 */
39 private long lNodeId;
40
41 /**
42 * Defines whether this is a node representing the root node, an element or
43 * an asset. It uses the constants in com.flexstor.common.constants.
44 * BucketConstantsI class for identifying an element and an asset, and
45 * AssetTree.DISGUISE for the root level
46 */
47 private int nNodeType;
48
49 /**
50 * Defines the asset role for this node, only if this is an ASSET node; otherwise it will
51 * be set to -1.
52 */
53 private int nNodeRole = -1;
54
55 /**
56 * Constructor to create a DISGUISE, ELEMENT or ASSET node.
57 * Attempting to create any other type of node will throw a runtime IllegalArgumentException
58 *
59 * @param lId Record id for the node. Disguise id, Element id or Asset id according to the type
60 * @param nType AssetTree.DISGUISE, BucketConstantsI.ELEMENT_BUCKET or BucketConstantsI.ASSET_BUCKET
61 */
62 public AssetTree( long lId, int nType )
63 {
64 switch ( nType )
65 {
66 case DISGUISE:
67 case BucketConstantsI.ELEMENT_BUCKET:
68 case BucketConstantsI.ASSET_BUCKET:
69 lNodeId = lId;
70 nNodeType = nType;
71 break;
72 default:
73 throw new IllegalArgumentException( "Invalid type specified: " + nType );
74 }
75 }
76
77 public long getId() { return lNodeId; }
78
79 public int getType() { return nNodeType; }
80
81 /**
82 * Set the role for an ASSET node; if this is not an ASSET node, the role will be set to -1
83 * @param nRole
84 */
85 public void setRole( int nRole )
86 {
87 if ( nNodeType == BucketConstantsI.ASSET_BUCKET )
88 nNodeRole = nRole;
89 }
90
91 public int getRole() { return nNodeRole; }
92
93 public boolean isDisguise() { return nNodeType == DISGUISE; }
94
95 public boolean isElement() { return nNodeType == BucketConstantsI.ELEMENT_BUCKET; }
96
97 public boolean isAsset() { return nNodeType == BucketConstantsI.ASSET_BUCKET; }
98
99 public boolean isPrimaryAsset() { return isAsset() && (getParent() == null ? false : ((AssetTree)getParent()).isElement()); }
100
101 public boolean isChildAsset() { return isAsset() && (getParent() == null ? false : ((AssetTree)getParent()).isAsset()); }
102
103 public boolean isParentAsset() { return isAsset() && !isPrimaryAsset() && hasChildren(); }
104
105 /**
106 * Sets a node as the parent of this one. If a parent was already set, this method will set a new
107 * parent. The previous parent-child relationship will be removed.
108 * Three basic rules will be checked prior to assigning a parent to the current node:
109 * - If the current node is a DISGUISE, it cannot have a parent node.
110 * - If the current node is an ELEMENT, the parent node must be a DISGUISE.
111 * - If the current node is an ASSET, the parent node must be either an ELEMENT or another ASSET.
112 *
113 * If any of the above rules is broken, a runtime IllegalArgumentException will be thrown indicating
114 * so in the message.
115 *
116 * @param node The node to set as the parent of this node
117 */
118 public void setParent( FlexNode n )
119 {
120 if ( !(n instanceof AssetTree) )
121 throw new IllegalArgumentException( "Attempted to assign a non-AssetTree object as parent of a node" );
122
123 AssetTree node = (AssetTree) n;
124 switch( this.nNodeType )
125 {
126 case DISGUISE:
127 throw new IllegalArgumentException( "Attempted to assign a parent to the root node." );
128 case BucketConstantsI.ELEMENT_BUCKET:
129 if ( node.isDisguise() )
130 super.setParent(node);
131 else
132 throw new IllegalArgumentException( "Attempted to assign a non-DISGUISE parent node to an ELEMENT node." );
133 break;
134 case BucketConstantsI.ASSET_BUCKET:
135 if ( node.isElement() || node.isAsset() )
136 super.setParent(node);
137 else
138 throw new IllegalArgumentException( "Attempted to assign a non-ELEMENT or non-ASSET parent node to an ASSET node." );
139 break;
140 }
141 }
142
143 /**
144 * Adds a node as a child of this one. Multiple children can be added to a node.
145 * Three basic rules will be checked prior to assigning a parent to the current node:
146 * - If the current node is a DISGUISE, the child node must be an ELEMENT.
147 * - If the current node is an ELEMENT, the child node must be an ASSET. If the element
148 * has a child already assigned to it, an IllegalArgumentException is thrown indicating
149 * the operation is not possible.
150 * - If the current node is an ASSET, the child node must be an ASSET.
151 *
152 * If any of the above rules is broken, a runtime IllegalArgumentException will be thrown
153 * indicating so in the message.
154 *
155 * @param node The node to add as child of this node
156 */
157 public void addChild( FlexNode n )
158 {
159 if ( !(n instanceof AssetTree) )
160 throw new IllegalArgumentException( "Attempted to add a non-AssetTree object as child of a node" );
161
162 AssetTree node = (AssetTree) n;
163 switch( this.nNodeType )
164 {
165 case DISGUISE:
166 if ( node.isElement() )
167 super.addChild(node);
168 else
169 throw new IllegalArgumentException( "Attempted to add a non-ELEMENT node to the root node" );
170 break;
171 case BucketConstantsI.ELEMENT_BUCKET:
172 if ( this.hasChildren() )
173 throw new IllegalArgumentException( "Cannot add node. ELEMENT already contains an ASSET node" );
174 else if ( node.isAsset() )
175 super.addChild(node);
176 else
177 throw new IllegalArgumentException( "Attempted to add a non-ASSET node to an ELEMENT node" );
178 break;
179 case BucketConstantsI.ASSET_BUCKET:
180 if ( node.isAsset() )
181 super.addChild(node);
182 else
183 throw new IllegalArgumentException( "Attempted to add a non-ASSET node to an ASSET node" );
184 break;
185 }
186 }
187
188 /**
189 * Starting at root, parse the tree looking for a specific node, based on the record id
190 * and type pecified
191 *
192 * @param lId
193 * @param nType
194 * @return AssetTree
195 */
196 public AssetTree getNode( long lId, int nType )
197 {
198 // Before parsing the entire tree, lets first find out if this is the node we've asked for
199 if ( this.lNodeId == lId && nNodeType == nType )
200 return this;
201
202 AssetTree node;
203 Vector vChildren;
204
205 AssetTree root = (AssetTree) getRoot();
206 switch ( nType )
207 {
208 case DISGUISE:
209 if ( root.getId() == lId && root.isDisguise() )
210 return root;
211 else
212 break;
213 case BucketConstantsI.ELEMENT_BUCKET:
214 if ( root.isDisguise() )
215 {
216 vChildren = root.getChildren();
217 for ( Enumeration e = vChildren.elements(); e.hasMoreElements(); )
218 {
219 node = (AssetTree) e.nextElement();
220 if ( node.getId() == lId )
221 return node;
222 }
223 }
224 break;
225 case BucketConstantsI.ASSET_BUCKET:
226 vChildren = root.getChildrenFlattened();
227 for ( Enumeration e = vChildren.elements(); e.hasMoreElements(); )
228 {
229 node = (AssetTree) e.nextElement();
230 if ( node.getId() == lId && node.isAsset() )
231 return node;
232 }
233 break;
234 }
235 return null;
236 }
237
238 public boolean equals( Object o )
239 {
240 if ( o instanceof AssetTree )
241 {
242 AssetTree other = (AssetTree) o;
243 if ( other.lNodeId == this.lNodeId && other.nNodeType == this.nNodeType )
244 return true;
245 }
246
247 return false;
248 }
249
250 public int hashCode()
251 {
252 return (int) lNodeId;
253 }
254 }