1
2
3
4
5
6
7
8
9
10 package com.sri.emo.dbobj;
11
12 import com.jcorporate.expresso.core.db.DBException;
13 import com.jcorporate.expresso.core.security.User;
14 import com.sri.common.controller.AbstractDBController;
15
16 import java.util.Collections;
17 import java.util.Iterator;
18 import java.util.List;
19
20
21 /***
22 * Encapsulation of a part of a node.
23 * Parts can be other nodes or (owned) attributes,
24 * and have various characteristics.
25 */
26 public class PartDescriptor {
27 public static final boolean IS_NODE_OBJECT = true;
28 public static final boolean IS_OWNED = false;
29 public static final String PART_DISPAY_NAME = "PART_DISPLAY_NAME";
30 public static final String PART_HELP_STRING = "PART_HELP_STRING";
31
32 /***
33 * cardinalities
34 */
35 public static final int SINGLE_ITEM_ALLOWED = 1;
36 public static final int MULTIPLE_ITEM_ALLOWED = 2;
37 public static final int PICKLIST_SINGLE_ITEM = 3;
38 public static final int SUMMARY_SINGLE_ITEM = 4;
39
40 /***
41 * is this part a node (which is often shared); an owned attribute
42 */
43 private boolean mIsNodeObject;
44
45 /***
46 * optional handler for custom attributes
47 */
48 private IPartHandler mCustomHandler;
49
50 /***
51 * the label for this part which will appear in displays
52 */
53 private String mLabel;
54
55 /***
56 * relation is a value from RelationType for shared objects, and
57 */
58 private String mRelation;
59
60 /***
61 * identifier string for type of node or attribute (a part can be either)
62 */
63 private String mNodeType;
64
65 /***
66 * number of part in list for owner object;
67 * necessary since the JSP doesn't know anything but
68 * must iterate to display attributes and send back edits with some discernable
69 * connection between input text and attribute destination.
70 */
71 private int mPartNum;
72
73 /***
74 * each part may be restricted to just one item,
75 * or many items of the same type
76 * or one item from picklist
77 */
78 private int mCardinality = MULTIPLE_ITEM_ALLOWED;
79
80 /***
81 * name of object of which we are part
82 */
83 private String mParentObjectType;
84 public static final String DELIMITER = "|";
85
86 /***
87 * constructor for shared nodes
88 */
89 public PartDescriptor(String label, boolean isNodeObject, String relation,
90 int partNum, String typeNode) {
91 this(label, isNodeObject, relation, partNum, typeNode,
92 MULTIPLE_ITEM_ALLOWED);
93 }
94
95 /***
96 * combined constructor
97 */
98 private PartDescriptor(String label, boolean isNodeObject, String relation,
99 int partNum, String type, int areManyAllowed) {
100 mLabel = label;
101 mIsNodeObject = isNodeObject;
102 mRelation = relation;
103 mNodeType = type;
104 mPartNum = partNum;
105 mCardinality = areManyAllowed;
106 }
107
108 /***
109 * constructor for attributes which have no summary
110 */
111 public PartDescriptor(String label, boolean isNodeObject,
112 String attributeType, int partNum, int areManyAllowed) {
113 this(label, isNodeObject, null, partNum, attributeType, areManyAllowed);
114 }
115
116 /***
117 * constructor for attributes which HAVE summary
118 *
119 * @param relation is the object name for items to summarize
120 */
121 public PartDescriptor(String label, boolean isNodeObject,
122 String attributeType, int partNum, int areManyAllowed, String relation) {
123 this(label, isNodeObject, relation, partNum, attributeType,
124 areManyAllowed);
125 }
126
127 public boolean isNode() {
128 return mIsNodeObject;
129 }
130
131 public boolean isAttribute() {
132 return !mIsNodeObject;
133 }
134
135 /***
136 * @return int code which represents the cardinality (single, multiple, etc.) of this attribute
137 */
138 private int cardinality() {
139 return mCardinality;
140 }
141
142 /***
143 * the label for this part which will appear in displays
144 */
145 public String label() {
146 return mLabel;
147 }
148
149 public String relation() {
150 return mRelation;
151 }
152
153 public String typeOfPart() {
154 return mNodeType;
155 }
156
157 public int partNum() {
158 return mPartNum;
159 }
160
161 /***
162 * return display title of node type of parent node, or empty string "" if not found
163 */
164 public String getDisplayTitleOfParentNodeType(int requestingUid) {
165 String result = "";
166
167 try {
168 NodeType nodeType = new NodeType();
169
170 nodeType.setRequestingUser(User.getUserFromId(requestingUid));
171 nodeType.setField(NodeType.NODE_TYPE_NAME,
172 getParentObjectType());
173
174 if (!nodeType.find()) {
175 throw new DBException("cannot find node type: " +
176 getParentObjectType());
177 }
178
179 result = nodeType.getField(NodeType.DISPLAY_TITLE);
180
181 if (result == null) {
182 result = "";
183 }
184 } catch (DBException e) {
185 e.printStackTrace();
186 }
187
188 return result;
189 }
190
191 /***
192 * @return array of values in picklist; return null if attribute has no picklist
193 */
194 public String[][] getPicklistArray(int userId) throws Exception {
195 if (!hasPicklist()) {
196 return null;
197 }
198
199 List found = getPicklist(userId);
200
201 if (found == null) {
202 return new String[0][2];
203 }
204
205
206 if (found.size() > 0) {
207 Collections.sort(found);
208 }
209
210
211 String[][] result = new String[found.size()][2];
212 int i = 0;
213
214 for (Iterator iter = found.iterator(); iter.hasNext();) {
215 PickList pickList = (PickList) iter.next();
216 result[i][0] = pickList.getField(PickList.LIST_ID);
217 result[i][1] = pickList.getField(PickList.DISPLAY_IN_PICKLIST);
218 i++;
219 }
220
221 return result;
222 }
223
224 public List getPicklist(int userId) throws Exception {
225 if (!hasPicklist()) {
226 return null;
227 }
228
229 PickList listItem = new PickList(User.getUserFromId(userId));
230 listItem.setField(PickList.NODE_TYPE, getParentObjectType());
231 listItem.setField(PickList.ATTRIBUTE_TYPE, typeOfPart());
232
233 return (List) listItem.searchAndRetrieveList(PickList.LIST_ID);
234 }
235
236 /***
237 * @return true if this attribute has a picklist
238 */
239 public boolean hasPicklist() {
240 return isAttribute() &&
241 (cardinality() == PartDescriptor.PICKLIST_SINGLE_ITEM);
242 }
243
244 /***
245 * @return true if this attribute is a summary
246 */
247 public boolean isSummary() {
248 return isAttribute() &&
249 (cardinality() == PartDescriptor.SUMMARY_SINGLE_ITEM);
250 }
251
252 /***
253 * @return true if this attribute allows multiple entries
254 */
255 public boolean areMultipleAttributesAllowed() {
256 return cardinality() == PartDescriptor.MULTIPLE_ITEM_ALLOWED;
257 }
258
259 public String getParentObjectType() {
260 return mParentObjectType;
261 }
262
263 public void setParentObjectType(String parentObjectType) {
264 mParentObjectType = parentObjectType;
265 }
266
267 public String getAttribLimit() {
268 String result = Part.SINGLE_ALLOWED;
269
270 if (areMultipleAttributesAllowed()) {
271 result = Part.MULTIPLE_ALLOWED;
272 } else if (hasPicklist()) {
273 result = Part.PICKLIST_SINGLE_ALLOWED;
274 } else if (isSummary()) {
275 result = Part.SUMMARY_SINGLE_ALLOWED;
276 }
277
278 return result;
279 }
280
281 public boolean hasCustomHandler() {
282 return mCustomHandler != null;
283 }
284
285 /***
286 * @return the custom editting handler or null if this part does not have one
287 */
288 public IPartHandler getCustomHandler() {
289 return mCustomHandler;
290 }
291
292 public void setCustomHandler(IPartHandler customHandler) {
293 mCustomHandler = customHandler;
294 }
295
296 /***
297 * @param cardinality use internal int flags
298 * @see #SINGLE_ITEM_ALLOWED and related constants
299 */
300 public void setCardinality(int cardinality) {
301 mCardinality = cardinality;
302 }
303
304 public int numDisplayLines() {
305 int numLines = AbstractDBController.SINGLE_TEXTAREA_NUM_LINES;
306
307 if (areMultipleAttributesAllowed()) {
308 numLines = AbstractDBController.MULTIPLE_TEXTAREA_NUM_LINES;
309 }
310
311 return numLines;
312 }
313
314 public String getCardinalityString() {
315 String result = Part.MULTIPLE_ALLOWED;
316
317 if (cardinality() == SINGLE_ITEM_ALLOWED) {
318 result = Part.SINGLE_ALLOWED;
319 } else if (cardinality() == PICKLIST_SINGLE_ITEM) {
320 result = Part.PICKLIST_SINGLE_ALLOWED;
321 } else if (cardinality() == SUMMARY_SINGLE_ITEM) {
322 result = Part.SUMMARY_SINGLE_ALLOWED;
323 }
324
325 return result;
326 }
327 }