001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.kuali.core.datadictionary;
018:
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025:
026: import org.apache.commons.lang.StringUtils;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.kuali.core.datadictionary.exception.ClassValidationException;
030: import org.kuali.core.datadictionary.exception.DuplicateEntryException;
031: import org.kuali.core.document.authorization.DocumentAuthorizer;
032: import org.kuali.core.lookup.keyvalues.KeyValuesFinder;
033: import org.kuali.core.rule.BusinessRule;
034: import org.kuali.core.service.KualiConfigurationService;
035: import org.kuali.core.service.KualiGroupService;
036:
037: /**
038: * A single Document entry in the DataDictionary, which contains information relating to the display, validation, and general
039: * maintenance of a Document (transactional or maintenance) and its attributes.
040: *
041: * Note: the setters do copious amounts of validation, to facilitate generating errors during the parsing process.
042: *
043: *
044: */
045: abstract public class DocumentEntry extends DataDictionaryEntryBase {
046: // logger
047: private static Log LOG = LogFactory.getLog(DocumentEntry.class);
048:
049: private Class documentClass;
050: private Class businessRulesClass;
051: private Class preRulesCheckClass;
052:
053: private String documentTypeName;
054: private String documentTypeCode;
055:
056: private String label;
057: private String shortLabel;
058:
059: private HelpDefinition helpDefinition;
060:
061: private boolean allowsNoteDelete;
062: private Class attachmentTypesValuesFinderClass;
063: private boolean displayTopicFieldInNotes;
064:
065: private String summary;
066: private String description;
067: private List<String> webScriptFiles;
068:
069: protected Class documentAuthorizerClass;
070: private Map authorizations;
071: private List<HeaderNavigation> headerNavigationList;
072:
073: private boolean allowsCopy;
074:
075: /**
076: * Default constructor
077: */
078: public DocumentEntry() {
079: super ();
080:
081: LOG.debug("creating new DocumentEntry");
082: authorizations = new HashMap();
083: headerNavigationList = new ArrayList<HeaderNavigation>();
084: webScriptFiles = new ArrayList<String>(3);
085: }
086:
087: /**
088: * @see org.kuali.core.datadictionary.DataDictionaryEntry#getJstlKey()
089: */
090: public String getJstlKey() {
091: if (StringUtils.isBlank(this .documentTypeName)) {
092: throw new IllegalStateException(
093: "unable to generate JSTL key: documentTypeName is blank");
094: }
095:
096: return this .documentTypeName;
097: }
098:
099: public void setDocumentClass(Class documentClass) {
100: if (documentClass == null) {
101: throw new IllegalArgumentException(
102: "invalid (null) documentClass");
103: }
104:
105: this .documentClass = documentClass;
106: }
107:
108: public Class getDocumentClass() {
109: return this .documentClass;
110: }
111:
112: public void setBusinessRulesClass(Class businessRulesClass) {
113: this .businessRulesClass = businessRulesClass;
114: }
115:
116: public Class getBusinessRulesClass() {
117: return businessRulesClass;
118: }
119:
120: public void setDocumentAuthorizerClass(Class documentAuthorizerClass) {
121: this .documentAuthorizerClass = documentAuthorizerClass;
122: }
123:
124: public Class getDocumentAuthorizerClass() {
125: return documentAuthorizerClass;
126: }
127:
128: /**
129: * @return Returns the preRulesCheckClass.
130: */
131: public Class getPreRulesCheckClass() {
132: return preRulesCheckClass;
133: }
134:
135: /**
136: * @param preRulesCheckClass The preRulesCheckClass to set.
137: */
138: public void setPreRulesCheckClass(Class preRulesCheckClass) {
139: this .preRulesCheckClass = preRulesCheckClass;
140: }
141:
142: /**
143: * Adds the given AuthorizationDefinition to the authorization map for this documentEntry
144: *
145: * @param authorizationDefinition
146: */
147: public void addAuthorizationDefinition(
148: AuthorizationDefinition authorizationDefinition) {
149: String action = authorizationDefinition.getAction();
150: if (StringUtils.isBlank(action)) {
151: throw new IllegalArgumentException(
152: "invalid (blank) action name");
153: }
154:
155: if (authorizations.containsKey(action)) {
156: throw new DuplicateEntryException(
157: "an authorizationDefinition with action '" + action
158: + "' already exists for this document type");
159: }
160:
161: authorizations.put(action, authorizationDefinition);
162: }
163:
164: /**
165: *
166: * @return
167: */
168: public Map getAuthorizationDefinitions() {
169: return Collections.unmodifiableMap(authorizations);
170: }
171:
172: public void setDocumentTypeName(String documentTypeName) {
173: if (StringUtils.isBlank(documentTypeName)) {
174: throw new IllegalArgumentException(
175: "invalid (blank) documentTypeName");
176: }
177: LOG.debug("calling setDocumentTypeName '" + documentTypeName
178: + "'");
179:
180: this .documentTypeName = documentTypeName;
181: }
182:
183: public String getDocumentTypeName() {
184: return this .documentTypeName;
185: }
186:
187: public void setDocumentTypeCode(String documentTypeCode) {
188: if (StringUtils.isBlank(documentTypeCode)) {
189: throw new IllegalArgumentException(
190: "invalid (blank) documentTypeCode");
191: }
192: LOG.debug("calling setDocumentTypeCode '" + documentTypeCode
193: + "'");
194:
195: this .documentTypeCode = documentTypeCode;
196: }
197:
198: public String getDocumentTypeCode() {
199: return documentTypeCode;
200: }
201:
202: public String getLabel() {
203: return label;
204: }
205:
206: public void setLabel(String label) {
207: if (StringUtils.isBlank(label)) {
208: throw new IllegalArgumentException("invalid (blank) label");
209: }
210: LOG.debug("calling setLabel '" + label + "'");
211:
212: this .label = label;
213: }
214:
215: /**
216: * @return the shortLabel, or the label if no shortLabel has been set
217: */
218: public String getShortLabel() {
219: return (shortLabel != null) ? shortLabel : getLabel();
220: }
221:
222: public void setShortLabel(String shortLabel) {
223: if (StringUtils.isBlank(shortLabel)) {
224: throw new IllegalArgumentException(
225: "invalid (blank) shortLabel");
226: }
227: LOG.debug("calling setShortLabel '" + shortLabel + "'");
228:
229: this .shortLabel = shortLabel;
230: }
231:
232: public String getSummary() {
233: return summary;
234: }
235:
236: public void setSummary(String summary) {
237: if (StringUtils.isBlank(summary)) {
238: throw new IllegalArgumentException(
239: "invalid (blank) summary");
240: }
241: LOG.debug("calling setSummary '" + summary + "'");
242:
243: this .summary = summary;
244: }
245:
246: public String getDescription() {
247: return description;
248: }
249:
250: public void setDescription(String description) {
251: if (StringUtils.isBlank(description)) {
252: throw new IllegalArgumentException(
253: "invalid (blank) description");
254: }
255: LOG.debug("calling setDescription '" + description + "'");
256:
257: this .description = description;
258: }
259:
260: /**
261: * Validate common fields for subclass' benefit.
262: *
263: * @see org.kuali.core.datadictionary.DataDictionaryEntry#completeValidation(java.lang.Object)
264: */
265: public void completeValidation(
266: ValidationCompletionUtils validationCompletionUtils) {
267: super .completeValidation(validationCompletionUtils);
268: // TODO: validate documentTypeName against some external source
269: // TODO: validate documentTypeCode against some external source
270:
271: if (businessRulesClass != null) {
272: if (!validationCompletionUtils.isDescendentClass(
273: businessRulesClass, BusinessRule.class)) {
274: throw new ClassValidationException(
275: "businessRulesClass value '"
276: + businessRulesClass.getName()
277: + "' is not a BusinessRule class");
278: }
279: }
280:
281: if (!authorizations.isEmpty()) {
282: for (Iterator i = authorizations.entrySet().iterator(); i
283: .hasNext();) {
284: Map.Entry e = (Map.Entry) i.next();
285:
286: String action = (String) e.getKey();
287: AuthorizationDefinition auth = (AuthorizationDefinition) e
288: .getValue();
289:
290: auth.completeValidation(null, null,
291: validationCompletionUtils);
292: }
293: }
294:
295: if (!validationCompletionUtils
296: .isDocumentClass(this .documentClass)) {
297: throw new ClassValidationException("documentClass '"
298: + documentClass.getName()
299: + "' is not a Document class");
300: }
301:
302: if (this .preRulesCheckClass != null
303: && !validationCompletionUtils
304: .isPreRulesCheckClass(this .preRulesCheckClass)) {
305: throw new ClassValidationException("class '"
306: + this .preRulesCheckClass
307: + "' is not a PreRulesCheck class");
308: }
309: }
310:
311: /**
312: * Perform authorization validation, which requires access to KualiGroupService which isn't available during earlier
313: * validation-related methods
314: *
315: * @param kualiGroupService
316: */
317: public void validateAuthorizations(
318: KualiGroupService kualiGroupService) {
319: if (!authorizations.isEmpty()) {
320: for (Iterator i = authorizations.entrySet().iterator(); i
321: .hasNext();) {
322: Map.Entry e = (Map.Entry) i.next();
323:
324: String action = (String) e.getKey();
325: AuthorizationDefinition auth = (AuthorizationDefinition) e
326: .getValue();
327:
328: auth.validateWorkroups(kualiGroupService);
329: }
330: }
331: }
332:
333: /**
334: * Validate the required documentAuthorizerClass
335: *
336: * @param kualiConfigurationService
337: */
338: public void validateAuthorizer(
339: KualiConfigurationService kualiConfigurationService,
340: ValidationCompletionUtils validationCompletionUtils) {
341: if (documentAuthorizerClass == null) {
342: throw new ClassValidationException(
343: "documentAuthorizerClass is required");
344: } else {
345:
346: if (!validationCompletionUtils.isDescendentClass(
347: documentAuthorizerClass, DocumentAuthorizer.class)) {
348: throw new ClassValidationException(
349: "documentAuthorizerClass value '"
350: + documentAuthorizerClass.getName()
351: + "' is not a DocumentAuthorizer class");
352: }
353:
354: }
355:
356: }
357:
358: /**
359: * @see org.kuali.core.datadictionary.DataDictionaryEntry#getFullClassName()
360: */
361: public String getFullClassName() {
362: if (getDocumentClass() != null) {
363: return getDocumentClass().getName();
364: }
365: return "";
366: }
367:
368: /**
369: * @see org.kuali.core.datadictionary.DataDictionaryEntryBase#getEntryClass()
370: */
371: public Class getEntryClass() {
372: return getDocumentClass();
373: }
374:
375: public String toString() {
376: return "DocumentEntry for documentType " + documentTypeName;
377: }
378:
379: /**
380: * Accessor method for contained <code>{@link HelpDefinition}</code>
381: *
382: * @return HelpDefinition
383: */
384: public HelpDefinition getHelpDefinition() {
385: return helpDefinition;
386: }
387:
388: /**
389: * @param financialSystemParameterHelp
390: */
391: public void setHelpDefinition(HelpDefinition helpDefinition) {
392: this .helpDefinition = helpDefinition;
393: }
394:
395: /**
396: * @param allowsNoteDelete
397: */
398: public void setAllowsNoteDelete(boolean allowsNoteDelete) {
399: LOG.debug("calling setAllowsNoteDelete '" + allowsNoteDelete
400: + "'");
401:
402: this .allowsNoteDelete = allowsNoteDelete;
403: }
404:
405: /**
406: * Accessor method for contained allowsNoteDelete
407: *
408: * @return allowsNoteDelete
409: */
410: public boolean getAllowsNoteDelete() {
411: return allowsNoteDelete;
412: }
413:
414: /**
415: * Accessor method for contained displayTopicFieldInNotes
416: *
417: * @return displayTopicFieldInNotes boolean
418: */
419: public boolean getDisplayTopicFieldInNotes() {
420: return displayTopicFieldInNotes;
421: }
422:
423: /**
424: *
425: * This method...
426: * @param displayTopicFieldInNotes
427: */
428: public void setDisplayTopicFieldInNotes(
429: boolean displayTopicFieldInNotes) {
430: LOG.debug("calling setDisplayTopicFieldInNotes '"
431: + displayTopicFieldInNotes + "'");
432:
433: this .displayTopicFieldInNotes = displayTopicFieldInNotes;
434: }
435:
436: /**
437: * @see org.kuali.core.datadictionary.control.ControlDefinition#setKeyValuesFinder(java.lang.String)
438: */
439: public void setAttachmentTypesValuesFinderClass(
440: Class<KeyValuesFinder> attachmentTypesValuesFinderClass) {
441: if (attachmentTypesValuesFinderClass == null) {
442: throw new IllegalArgumentException(
443: "invalid (null) attachmentTypesValuesFinderClass");
444: }
445:
446: LOG.debug("calling setAttachmentTypesValuesFinderClass '"
447: + attachmentTypesValuesFinderClass.getName() + "'");
448:
449: this .attachmentTypesValuesFinderClass = attachmentTypesValuesFinderClass;
450: }
451:
452: /**
453: * @see org.kuali.core.datadictionary.control.ControlDefinition#getKeyValuesFinder()
454: */
455: public Class getAttachmentTypeValuesFinderClass() {
456: return attachmentTypesValuesFinderClass;
457: }
458:
459: public void setAllowsCopy(boolean allowsCopy) {
460: if (LOG.isDebugEnabled()) {
461: LOG.debug("calling setAllowsCopy '" + allowsCopy + "'");
462: }
463:
464: this .allowsCopy = allowsCopy;
465: }
466:
467: public boolean getAllowsCopy() {
468: return allowsCopy;
469: }
470:
471: public HeaderNavigation[] getHeaderTabNavigation() {
472: return headerNavigationList
473: .toArray(new HeaderNavigation[headerNavigationList
474: .size()]);
475: }
476:
477: public void addHeaderNavigation(HeaderNavigation headerNavigation) {
478: this .headerNavigationList.add(headerNavigation);
479: }
480:
481: public void addWebScriptFile(String webScriptFile) {
482: if (LOG.isDebugEnabled()) {
483: LOG.debug("calling addWebScriptFile '" + webScriptFile
484: + "'");
485: }
486: this .webScriptFiles.add(webScriptFile);
487: }
488:
489: public List<String> getWebScriptFiles() {
490: return webScriptFiles;
491: }
492:
493: public void setWebScriptFiles(List<String> webScriptFiles) {
494: this.webScriptFiles = webScriptFiles;
495: }
496:
497: }
|