Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BusinessObjectEntry |
|
| 1.7142857142857142;1.714 |
1 | /* | |
2 | * Copyright 2005-2008 The Kuali Foundation | |
3 | * | |
4 | * Licensed under the Educational Community License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.opensource.org/licenses/ecl2.php | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package org.kuali.rice.kns.datadictionary; | |
18 | ||
19 | import java.util.List; | |
20 | ||
21 | import org.apache.commons.lang.StringUtils; | |
22 | import org.kuali.rice.kns.bo.BusinessObject; | |
23 | import org.kuali.rice.kns.bo.Exporter; | |
24 | import org.kuali.rice.kns.datadictionary.exception.AttributeValidationException; | |
25 | import org.kuali.rice.kns.datadictionary.exception.ClassValidationException; | |
26 | ||
27 | /** | |
28 | * A single BusinessObject entry in the DataDictionary, which contains information relating to the display, validation, and general | |
29 | * maintenance of a BusinessObject and its attributes. | |
30 | * | |
31 | * | |
32 | DD: See BusinessObjectEntry.java | |
33 | ||
34 | JSTL: each businessObject is exposed as a Map which is accessed | |
35 | using a key of the business object class name. | |
36 | This map contains enties with the following keys | |
37 | ||
38 | * businessObjectClass (String) | |
39 | * exporterClass (String) | |
40 | * inquiry (Map, optional) | |
41 | * lookup (Map, optional) | |
42 | * attributes (Map) | |
43 | * collections (Map, optional) | |
44 | * relationships (Map, optional) | |
45 | * objectLabel (String, optional) | |
46 | * objectDescription (String, optional) | |
47 | ||
48 | See BusinessObjectEntryMapper.java | |
49 | ||
50 | Note: the use of extraButton in the <businessObject> tag is deprecated, and may be removed in future versions of the data dictionary. | |
51 | ||
52 | * Note: the setters do copious amounts of validation, to facilitate generating errors during the parsing process. | |
53 | */ | |
54 | public class BusinessObjectEntry extends DataDictionaryEntryBase { | |
55 | // logger | |
56 | //private static Log LOG = LogFactory.getLog(BusinessObjectEntry.class); | |
57 | ||
58 | protected Class<? extends BusinessObject> businessObjectClass; | |
59 | protected Class<? extends BusinessObject> baseBusinessObjectClass; | |
60 | protected Class<? extends Exporter> exporterClass; | |
61 | ||
62 | 0 | protected boolean boNotesEnabled = false; |
63 | ||
64 | protected InquiryDefinition inquiryDefinition; | |
65 | protected LookupDefinition lookupDefinition; | |
66 | protected HelpDefinition helpDefinition; | |
67 | ||
68 | protected String titleAttribute; | |
69 | protected String objectLabel; | |
70 | protected String objectDescription; | |
71 | ||
72 | protected List<InactivationBlockingDefinition> inactivationBlockingDefinitions; | |
73 | ||
74 | protected List<String> primaryKeys; | |
75 | ||
76 | protected List<String> groupByAttributesForEffectiveDating; | |
77 | ||
78 | 0 | public BusinessObjectEntry() {} |
79 | ||
80 | /** | |
81 | * @see org.kuali.rice.kns.datadictionary.DataDictionaryEntry#getJstlKey() | |
82 | */ | |
83 | public String getJstlKey() { | |
84 | 0 | if (businessObjectClass == null) { |
85 | 0 | throw new IllegalStateException("cannot generate JSTL key: businessObjectClass is null"); |
86 | } | |
87 | ||
88 | 0 | return (baseBusinessObjectClass != null) ? baseBusinessObjectClass.getSimpleName() : businessObjectClass.getSimpleName(); |
89 | } | |
90 | ||
91 | public void setBusinessObjectClass(Class<? extends BusinessObject> businessObjectClass) { | |
92 | 0 | if (businessObjectClass == null) { |
93 | 0 | throw new IllegalArgumentException("invalid (null) businessObjectClass"); |
94 | } | |
95 | ||
96 | 0 | if ( getRelationships() != null ) { |
97 | 0 | for ( RelationshipDefinition rd : getRelationships() ) { |
98 | 0 | rd.setSourceClass(businessObjectClass); |
99 | } | |
100 | } | |
101 | ||
102 | 0 | this.businessObjectClass = businessObjectClass; |
103 | 0 | } |
104 | ||
105 | public Class<? extends BusinessObject> getBusinessObjectClass() { | |
106 | 0 | return businessObjectClass; |
107 | } | |
108 | ||
109 | /** | |
110 | * The baseBusinessObjectClass is an optional parameter for specifying a superclass | |
111 | * for the businessObjectClass, allowing the data dictionary to index by superclass | |
112 | * in addition to the current class. | |
113 | */ | |
114 | ||
115 | public void setBaseBusinessObjectClass(Class<? extends BusinessObject> baseBusinessObjectClass) { | |
116 | ||
117 | 0 | this.baseBusinessObjectClass = baseBusinessObjectClass; |
118 | 0 | } |
119 | ||
120 | public Class<? extends BusinessObject> getBaseBusinessObjectClass() { | |
121 | 0 | return baseBusinessObjectClass; |
122 | } | |
123 | ||
124 | public Class<? extends Exporter> getExporterClass() { | |
125 | 0 | return this.exporterClass; |
126 | } | |
127 | ||
128 | public void setExporterClass(Class<? extends Exporter> exporterClass) { | |
129 | 0 | this.exporterClass = exporterClass; |
130 | 0 | } |
131 | ||
132 | public boolean isBoNotesEnabled() { | |
133 | 0 | return boNotesEnabled; |
134 | } | |
135 | ||
136 | /** | |
137 | * boNotesEnabled = true or false | |
138 | * true indicates that notes and attachments will be permanently | |
139 | associated with the business object | |
140 | * false indicates that notes and attachments are associated | |
141 | with the document used to create or edit the business object. | |
142 | */ | |
143 | public void setBoNotesEnabled(boolean boNotesEnabled) { | |
144 | 0 | this.boNotesEnabled = boNotesEnabled; |
145 | 0 | } |
146 | ||
147 | /** | |
148 | * @return true if this instance has an inquiryDefinition | |
149 | */ | |
150 | public boolean hasInquiryDefinition() { | |
151 | 0 | return (inquiryDefinition != null); |
152 | } | |
153 | ||
154 | /** | |
155 | * @return current inquiryDefinition for this BusinessObjectEntry, or null if there is none | |
156 | */ | |
157 | public InquiryDefinition getInquiryDefinition() { | |
158 | 0 | return inquiryDefinition; |
159 | } | |
160 | ||
161 | /** | |
162 | The inquiry element is used to specify the fields that will be displayed on the | |
163 | inquiry screen for this business object and the order in which they will appear. | |
164 | ||
165 | DD: See InquiryDefinition.java | |
166 | ||
167 | JSTL: The inquiry element is a Map which is accessed using | |
168 | a key of "inquiry". This map contains the following keys: | |
169 | * title (String) | |
170 | * inquiryFields (Map) | |
171 | ||
172 | See InquiryMapBuilder.java | |
173 | */ | |
174 | public void setInquiryDefinition(InquiryDefinition inquiryDefinition) { | |
175 | 0 | this.inquiryDefinition = inquiryDefinition; |
176 | 0 | } |
177 | ||
178 | /** | |
179 | * @return true if this instance has a lookupDefinition | |
180 | */ | |
181 | public boolean hasLookupDefinition() { | |
182 | 0 | return (lookupDefinition != null); |
183 | } | |
184 | ||
185 | /** | |
186 | * @return current lookupDefinition for this BusinessObjectEntry, or null if there is none | |
187 | */ | |
188 | public LookupDefinition getLookupDefinition() { | |
189 | 0 | return lookupDefinition; |
190 | } | |
191 | ||
192 | /** | |
193 | The lookup element is used to specify the rules for "looking up" | |
194 | a business object. These specifications define the following: | |
195 | * How to specify the search criteria used to locate a set of business objects | |
196 | * How to display the search results | |
197 | ||
198 | DD: See LookupDefinition.java | |
199 | ||
200 | JSTL: The lookup element is a Map which is accessed using | |
201 | a key of "lookup". This map contains the following keys: | |
202 | * lookupableID (String, optional) | |
203 | * title (String) | |
204 | * menubar (String, optional) | |
205 | * defaultSort (Map, optional) | |
206 | * lookupFields (Map) | |
207 | * resultFields (Map) | |
208 | * resultSetLimit (String, optional) | |
209 | ||
210 | See LookupMapBuilder.java | |
211 | */ | |
212 | public void setLookupDefinition(LookupDefinition lookupDefinition) { | |
213 | 0 | this.lookupDefinition = lookupDefinition; |
214 | 0 | } |
215 | ||
216 | /** | |
217 | * @return Returns the titleAttribute. | |
218 | */ | |
219 | public String getTitleAttribute() { | |
220 | 0 | return titleAttribute; |
221 | } | |
222 | ||
223 | ||
224 | /** | |
225 | The titleAttribute element is the name of the attribute that | |
226 | will be used as an inquiry field when the lookup search results | |
227 | fields are displayed. | |
228 | ||
229 | For some business objects, there is no obvious field to serve | |
230 | as the inquiry field. in that case a special field may be required | |
231 | for inquiry purposes. | |
232 | */ | |
233 | public void setTitleAttribute(String titleAttribute) { | |
234 | 0 | this.titleAttribute = titleAttribute; |
235 | 0 | } |
236 | ||
237 | ||
238 | /** | |
239 | * Directly validate simple fields, call completeValidation on Definition fields. | |
240 | */ | |
241 | public void completeValidation() { | |
242 | try { | |
243 | //KFSMI-1340 - Object label should never be blank | |
244 | 0 | if (StringUtils.isBlank(getObjectLabel())) { |
245 | 0 | throw new AttributeValidationException("Object label cannot be blank for class " + businessObjectClass.getName()); |
246 | } | |
247 | ||
248 | 0 | if (baseBusinessObjectClass != null && !baseBusinessObjectClass.isAssignableFrom(businessObjectClass)) { |
249 | 0 | throw new ClassValidationException("The baseBusinessObjectClass " + baseBusinessObjectClass.getName() + |
250 | " is not a superclass of the businessObjectClass " + businessObjectClass.getName()); | |
251 | } | |
252 | ||
253 | 0 | super.completeValidation(); |
254 | ||
255 | 0 | if (hasInquiryDefinition()) { |
256 | 0 | inquiryDefinition.completeValidation(businessObjectClass, null); |
257 | } | |
258 | ||
259 | 0 | if (hasLookupDefinition()) { |
260 | 0 | lookupDefinition.completeValidation(businessObjectClass, null); |
261 | } | |
262 | ||
263 | 0 | if (inactivationBlockingDefinitions != null && !inactivationBlockingDefinitions.isEmpty()) { |
264 | 0 | for (InactivationBlockingDefinition inactivationBlockingDefinition : inactivationBlockingDefinitions) { |
265 | 0 | inactivationBlockingDefinition.completeValidation(businessObjectClass, null); |
266 | } | |
267 | } | |
268 | 0 | } catch ( DataDictionaryException ex ) { |
269 | // just rethrow | |
270 | 0 | throw ex; |
271 | 0 | } catch ( Exception ex ) { |
272 | 0 | throw new DataDictionaryException( "Exception validating " + this, ex); |
273 | 0 | } |
274 | 0 | } |
275 | ||
276 | /** | |
277 | * @see org.kuali.rice.kns.datadictionary.DataDictionaryEntryBase#getEntryClass() | |
278 | */ | |
279 | @SuppressWarnings("unchecked") | |
280 | public Class getEntryClass() { | |
281 | 0 | return businessObjectClass; |
282 | } | |
283 | ||
284 | ||
285 | /** | |
286 | * @see org.kuali.rice.kns.datadictionary.DataDictionaryEntry#getFullClassName() | |
287 | */ | |
288 | public String getFullClassName() { | |
289 | 0 | return businessObjectClass.getName(); |
290 | } | |
291 | ||
292 | /** | |
293 | * @return Returns the objectLabel. | |
294 | */ | |
295 | public String getObjectLabel() { | |
296 | 0 | return objectLabel; |
297 | } | |
298 | ||
299 | /** | |
300 | The objectLabel provides a short name of the business | |
301 | object for use on help screens. | |
302 | * | |
303 | * @param objectLabel The objectLabel to set. | |
304 | */ | |
305 | public void setObjectLabel(String objectLabel) { | |
306 | 0 | this.objectLabel = objectLabel; |
307 | 0 | } |
308 | ||
309 | /** | |
310 | * @return Returns the description. | |
311 | */ | |
312 | public String getObjectDescription() { | |
313 | 0 | return objectDescription; |
314 | } | |
315 | ||
316 | /** | |
317 | The objectDescription provides a brief description | |
318 | of the business object for use on help screens. | |
319 | * | |
320 | * @param description The description to set. | |
321 | */ | |
322 | public void setObjectDescription(String objectDescription) { | |
323 | 0 | this.objectDescription = objectDescription; |
324 | 0 | } |
325 | ||
326 | /** | |
327 | * Gets the helpDefinition attribute. | |
328 | * | |
329 | * @return Returns the helpDefinition. | |
330 | */ | |
331 | public HelpDefinition getHelpDefinition() { | |
332 | 0 | return helpDefinition; |
333 | } | |
334 | ||
335 | /** | |
336 | * Sets the helpDefinition attribute value. | |
337 | * | |
338 | The objectHelp element provides the keys to | |
339 | obtain a help description from the system parameters table. | |
340 | ||
341 | parameterNamespace the namespace of the parameter containing help information | |
342 | parameterName the name of the parameter containing help information | |
343 | parameterDetailType the detail type of the parameter containing help information | |
344 | * | |
345 | * @param helpDefinition The helpDefinition to set. | |
346 | */ | |
347 | public void setHelpDefinition(HelpDefinition helpDefinition) { | |
348 | 0 | this.helpDefinition = helpDefinition; |
349 | 0 | } |
350 | ||
351 | /** | |
352 | * @see java.lang.Object#toString() | |
353 | */ | |
354 | public String toString() { | |
355 | 0 | return "BusinessObjectEntry for " + getBusinessObjectClass(); |
356 | } | |
357 | ||
358 | public List<InactivationBlockingDefinition> getInactivationBlockingDefinitions() { | |
359 | 0 | return this.inactivationBlockingDefinitions; |
360 | } | |
361 | ||
362 | public void setInactivationBlockingDefinitions(List<InactivationBlockingDefinition> inactivationBlockingDefinitions) { | |
363 | 0 | this.inactivationBlockingDefinitions = inactivationBlockingDefinitions; |
364 | 0 | } |
365 | ||
366 | /** | |
367 | * @return the primaryKeys | |
368 | */ | |
369 | public List<String> getPrimaryKeys() { | |
370 | 0 | return this.primaryKeys; |
371 | } | |
372 | ||
373 | /** | |
374 | * @param primaryKeys the primaryKeys to set | |
375 | */ | |
376 | public void setPrimaryKeys(List<String> primaryKeys) { | |
377 | 0 | this.primaryKeys = primaryKeys; |
378 | 0 | } |
379 | ||
380 | public List<String> getGroupByAttributesForEffectiveDating() { | |
381 | 0 | return this.groupByAttributesForEffectiveDating; |
382 | } | |
383 | ||
384 | public void setGroupByAttributesForEffectiveDating(List<String> groupByAttributesForEffectiveDating) { | |
385 | 0 | this.groupByAttributesForEffectiveDating = groupByAttributesForEffectiveDating; |
386 | 0 | } |
387 | ||
388 | /** | |
389 | * @see org.kuali.rice.kns.datadictionary.DataDictionaryEntryBase#afterPropertiesSet() | |
390 | */ | |
391 | @SuppressWarnings("unchecked") | |
392 | @Override | |
393 | public void afterPropertiesSet() throws Exception { | |
394 | 0 | super.afterPropertiesSet(); |
395 | 0 | if ( inactivationBlockingDefinitions != null ) { |
396 | 0 | for ( InactivationBlockingDefinition ibd : inactivationBlockingDefinitions ) { |
397 | 0 | ibd.setBusinessObjectClass( getBusinessObjectClass() ); |
398 | 0 | if (StringUtils.isNotBlank(ibd.getBlockedReferencePropertyName()) && ibd.getBlockedBusinessObjectClass() == null) { |
399 | // if the user didn't specify a class name for the blocked reference, determine it here | |
400 | 0 | ibd.setBlockedBusinessObjectClass( DataDictionary.getAttributeClass(businessObjectClass, ibd.getBlockedReferencePropertyName()) ); |
401 | } | |
402 | 0 | ibd.setBlockingReferenceBusinessObjectClass(getBusinessObjectClass()); |
403 | } | |
404 | } | |
405 | 0 | } |
406 | } |