001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.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/ecl2.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 */
016package org.kuali.rice.krad.service.impl;
017
018import java.util.Collection;
019import java.util.List;
020
021import org.apache.commons.lang.StringUtils;
022import org.kuali.rice.kew.api.KewApiServiceLocator;
023import org.kuali.rice.kew.api.doctype.DocumentType;
024import org.kuali.rice.krad.datadictionary.DataDictionary;
025import org.kuali.rice.krad.datadictionary.DocumentEntry;
026import org.kuali.rice.krad.datadictionary.MaintenanceDocumentEntry;
027import org.kuali.rice.krad.document.Document;
028import org.kuali.rice.krad.document.DocumentAuthorizer;
029import org.kuali.rice.krad.document.DocumentAuthorizerBase;
030import org.kuali.rice.krad.document.DocumentPresentationController;
031import org.kuali.rice.krad.document.DocumentPresentationControllerBase;
032import org.kuali.rice.krad.maintenance.MaintenanceDocument;
033import org.kuali.rice.krad.maintenance.Maintainable;
034import org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizerBase;
035import org.kuali.rice.krad.maintenance.MaintenanceDocumentPresentationControllerBase;
036import org.kuali.rice.krad.rules.rule.BusinessRule;
037import org.kuali.rice.krad.service.DataDictionaryService;
038import org.kuali.rice.krad.service.DocumentDictionaryService;
039import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
040
041/**
042 * Implementation of <code>DocumentDictionaryService</code> which reads configuration
043 * from the data dictionary
044 *
045 * @author Kuali Rice Team (rice.collab@kuali.org)
046 */
047public class DocumentDictionaryServiceImpl implements DocumentDictionaryService {
048    private DataDictionaryService dataDictionaryService;
049
050    /**
051     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getLabel
052     */
053    @Override
054    public String getLabel(String documentTypeName) {
055        String label = null;
056
057        DocumentType docType = getDocumentType(documentTypeName);
058        if (docType != null) {
059            label = docType.getLabel();
060        }
061
062        return label;
063    }
064
065    /**
066     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getMaintenanceDocumentTypeName
067     */
068    @Override
069    public String getMaintenanceDocumentTypeName(Class dataObjectClass) {
070        String documentTypeName = null;
071
072        MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(dataObjectClass);
073        if (entry != null) {
074            documentTypeName = entry.getDocumentTypeName();
075        }
076
077        return documentTypeName;
078    }
079
080    /**
081     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDescription
082     */
083    @Override
084    public String getDescription(String documentTypeName) {
085        String description = null;
086
087        DocumentType docType = getDocumentType(documentTypeName);
088        if (docType != null) {
089            description = docType.getDescription();
090        }
091
092        return description;
093    }
094
095    /**
096     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDefaultExistenceChecks
097     */
098    @Override
099    public Collection getDefaultExistenceChecks(Class dataObjectClass) {
100        return getDefaultExistenceChecks(getMaintenanceDocumentTypeName(dataObjectClass));
101    }
102
103    /**
104     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDefaultExistenceChecks
105     */
106    @Override
107    public Collection getDefaultExistenceChecks(Document document) {
108        return getDefaultExistenceChecks(getDocumentEntry(document).getDocumentTypeName());
109    }
110
111    /**
112     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDefaultExistenceChecks
113     */
114    @Override
115    public Collection getDefaultExistenceChecks(String docTypeName) {
116        Collection defaultExistenceChecks = null;
117
118        DocumentEntry entry = getDocumentEntry(docTypeName);
119        if (entry != null) {
120            defaultExistenceChecks = entry.getDefaultExistenceChecks();
121        }
122
123        return defaultExistenceChecks;
124    }
125
126    /**
127     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getMaintenanceDataObjectClass
128     */
129    @Override
130    public Class<?> getMaintenanceDataObjectClass(String docTypeName) {
131        Class dataObjectClass = null;
132
133        MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(docTypeName);
134        if (entry != null) {
135            dataObjectClass = entry.getDataObjectClass();
136        }
137
138        return dataObjectClass;
139    }
140
141    /**
142     * @see org.kuali.rice.krad.service.impl.DocumentDictionaryService#getMaintainableClass
143     */
144    @Override
145    public Class<? extends Maintainable> getMaintainableClass(String docTypeName) {
146        Class maintainableClass = null;
147
148        MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(docTypeName);
149        if (entry != null) {
150            maintainableClass = entry.getMaintainableClass();
151        }
152
153        return maintainableClass;
154    }
155
156    /**
157     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getBusinessRulesClass
158     */
159    @Override
160    public Class<? extends BusinessRule> getBusinessRulesClass(Document document) {
161        Class<? extends BusinessRule> businessRulesClass = null;
162
163        String docTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
164        DocumentEntry entry = getDocumentEntry(docTypeName);
165        if (entry != null) {
166            businessRulesClass = entry.getBusinessRulesClass();
167        }
168
169        return businessRulesClass;
170    }
171
172    /**
173     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getAllowsCopy
174     */
175    @Override
176    public Boolean getAllowsCopy(Document document) {
177        Boolean allowsCopy = Boolean.FALSE;
178
179        if (document == null) {
180            return allowsCopy;
181        }
182
183        DocumentEntry entry = null;
184        if (document instanceof MaintenanceDocument) {
185            MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
186            if (maintenanceDocument.getNewMaintainableObject() != null) {
187                entry = getMaintenanceDocumentEntry(
188                        maintenanceDocument.getNewMaintainableObject().getDataObjectClass());
189            }
190        } else {
191            entry = getDocumentEntry(document);
192        }
193
194        if (entry != null) {
195            allowsCopy = Boolean.valueOf(entry.getAllowsCopy());
196        }
197
198        return allowsCopy;
199    }
200
201    /**
202     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getAllowsNewOrCopy
203     */
204    @Override
205    public Boolean getAllowsNewOrCopy(String docTypeName) {
206        Boolean allowsNewOrCopy = Boolean.FALSE;
207
208        if (docTypeName != null) {
209            MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(docTypeName);
210            if (entry != null) {
211                allowsNewOrCopy = Boolean.valueOf(entry.getAllowsNewOrCopy());
212            }
213        }
214
215        return allowsNewOrCopy;
216    }
217
218    /**
219     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentEntry(java.lang.String)
220     */
221    @Override
222    public DocumentEntry getDocumentEntry(String documentTypeName) {
223        if (documentTypeName == null) {
224            throw new IllegalArgumentException("invalid (null) document type name");
225        }
226
227        DocumentEntry entry = getDataDictionary().getDocumentEntry(documentTypeName);
228
229        return entry;
230    }
231
232    /**
233     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentEntryByClass(java.lang.Class<? extends
234     *      org.kuali.rice.krad.document.Document>)
235     */
236    @Override
237    public DocumentEntry getDocumentEntryByClass(Class<? extends Document> documentClass) {
238        DocumentEntry entry = null;
239
240        String documentTypeName = getDocumentTypeByClass(documentClass);
241        if (StringUtils.isNotBlank(documentTypeName)) {
242            entry = getDocumentEntry(documentTypeName);
243        }
244
245        return entry;
246    }
247
248    /**
249     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getMaintenanceDocumentEntry
250     */
251    @Override
252    public MaintenanceDocumentEntry getMaintenanceDocumentEntry(String docTypeName) {
253        if (StringUtils.isBlank(docTypeName)) {
254            throw new IllegalArgumentException("invalid (blank) docTypeName");
255        }
256
257        MaintenanceDocumentEntry entry = (MaintenanceDocumentEntry) getDataDictionary().getDocumentEntry(docTypeName);
258        return entry;
259    }
260
261    /**
262     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentClassByName
263     */
264    @Override
265    public Class<?> getDocumentClassByName(String documentTypeName) {
266        Class documentClass = null;
267
268        DocumentEntry entry = getDocumentEntry(documentTypeName);
269        if (entry != null) {
270            documentClass = entry.getDocumentClass();
271        }
272
273        return documentClass;
274    }
275
276    /**
277     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentTypeByClass(java.lang.Class<? extends org.kuali.rice.krad.document.Document>)
278     */
279    @Override
280    public String getDocumentTypeByClass(Class<? extends Document> documentClass) {
281        if (documentClass == null) {
282            throw new IllegalArgumentException("invalid (null) document class");
283        }
284
285        DocumentEntry entry = getDataDictionary().getDocumentEntry(documentClass.getName());
286        if (entry != null) {
287            return entry.getDocumentTypeName();
288        }
289
290        return null;
291    }
292
293    /**
294     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getAllowsRecordDeletion
295     */
296    @Override
297    public Boolean getAllowsRecordDeletion(Class dataObjectClass) {
298        Boolean allowsRecordDeletion = Boolean.FALSE;
299
300        MaintenanceDocumentEntry docEntry = getMaintenanceDocumentEntry(dataObjectClass);
301
302        if (docEntry != null) {
303            allowsRecordDeletion = Boolean.valueOf(docEntry.getAllowsRecordDeletion());
304        }
305
306        return allowsRecordDeletion;
307    }
308
309    /**
310     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getAllowsRecordDeletion
311     */
312    @Override
313    public Boolean getAllowsRecordDeletion(MaintenanceDocument document) {
314        return document != null ?
315                this.getAllowsRecordDeletion(document.getNewMaintainableObject().getDataObjectClass()) : Boolean.FALSE;
316    }
317
318    /**
319     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getLockingKeys
320     */
321    @Override
322    public List<String> getLockingKeys(String docTypeName) {
323        List lockingKeys = null;
324
325        MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(docTypeName);
326        if (entry != null) {
327            lockingKeys = entry.getLockingKeyFieldNames();
328        }
329
330        return lockingKeys;
331    }
332
333    /**
334     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getPreserveLockingKeysOnCopy
335     */
336    @Override
337    public boolean getPreserveLockingKeysOnCopy(Class dataObjectClass) {
338        boolean preserveLockingKeysOnCopy = false;
339
340        MaintenanceDocumentEntry docEntry = getMaintenanceDocumentEntry(dataObjectClass);
341
342        if (docEntry != null) {
343            preserveLockingKeysOnCopy = docEntry.getPreserveLockingKeysOnCopy();
344        }
345
346        return preserveLockingKeysOnCopy;
347    }
348
349    /**
350     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentAuthorizer(java.lang.String)
351     */
352    public DocumentAuthorizer getDocumentAuthorizer(String documentType) {
353        DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
354
355        if (StringUtils.isBlank(documentType)) {
356            throw new IllegalArgumentException("invalid (blank) documentType");
357        }
358
359        DocumentEntry documentEntry = dataDictionary.getDocumentEntry(documentType);
360        if (documentEntry == null) {
361            throw new IllegalArgumentException("unknown documentType '" + documentType + "'");
362        }
363
364        Class<? extends DocumentAuthorizer> documentAuthorizerClass = documentEntry.getDocumentAuthorizerClass();
365
366        DocumentAuthorizer documentAuthorizer = null;
367        try {
368            if (documentAuthorizerClass != null) {
369                documentAuthorizer = documentAuthorizerClass.newInstance();
370            } else if (documentEntry instanceof MaintenanceDocumentEntry) {
371                documentAuthorizer = new MaintenanceDocumentAuthorizerBase();
372            } else {
373                documentAuthorizer = new DocumentAuthorizerBase();
374            }
375        } catch (Exception e) {
376            throw new RuntimeException("unable to instantiate documentAuthorizer '"
377                    + documentAuthorizerClass.getName()
378                    + "' for doctype '"
379                    + documentType
380                    + "'", e);
381        }
382
383        return documentAuthorizer;
384    }
385
386    /**
387     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentAuthorizer(java.lang.String)
388     */
389    public DocumentAuthorizer getDocumentAuthorizer(Document document) {
390        if (document == null) {
391            throw new IllegalArgumentException("invalid (null) document");
392        } else if (document.getDocumentHeader() == null) {
393            throw new IllegalArgumentException("invalid (null) document.documentHeader");
394        } else if (!document.getDocumentHeader().hasWorkflowDocument()) {
395            throw new IllegalArgumentException("invalid (null) document.documentHeader.workflowDocument");
396        }
397
398        String documentType = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
399
400        DocumentAuthorizer documentAuthorizer = getDocumentAuthorizer(documentType);
401
402        return documentAuthorizer;
403    }
404
405    /**
406     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentPresentationController(java.lang.String)
407     */
408    public DocumentPresentationController getDocumentPresentationController(String documentType) {
409        DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
410
411        if (StringUtils.isBlank(documentType)) {
412            throw new IllegalArgumentException("invalid (blank) documentType");
413        }
414
415        DocumentEntry documentEntry = dataDictionary.getDocumentEntry(documentType);
416        if (documentEntry == null) {
417            throw new IllegalArgumentException("unknown documentType '" + documentType + "'");
418        }
419
420        Class<? extends DocumentPresentationController> documentPresentationControllerClass =
421                documentEntry.getDocumentPresentationControllerClass();
422
423        DocumentPresentationController documentPresentationController = null;
424        try {
425            if (documentPresentationControllerClass != null) {
426                documentPresentationController = documentPresentationControllerClass.newInstance();
427            } else if (documentEntry instanceof MaintenanceDocumentEntry) {
428                documentPresentationController = new MaintenanceDocumentPresentationControllerBase();
429            } else {
430                documentPresentationController = new DocumentPresentationControllerBase();
431            }
432        } catch (Exception e) {
433            throw new RuntimeException("unable to instantiate documentAuthorizer '"
434                    + documentPresentationControllerClass.getName()
435                    + "' for doctype '"
436                    + documentType
437                    + "'", e);
438        }
439
440        return documentPresentationController;
441    }
442
443    /**
444     * @see org.kuali.rice.krad.service.DocumentDictionaryService#getDocumentPresentationController(java.lang.String)
445     */
446    public DocumentPresentationController getDocumentPresentationController(Document document) {
447        if (document == null) {
448            throw new IllegalArgumentException("invalid (null) document");
449        } else if (document.getDocumentHeader() == null) {
450            throw new IllegalArgumentException("invalid (null) document.documentHeader");
451        } else if (!document.getDocumentHeader().hasWorkflowDocument()) {
452            throw new IllegalArgumentException("invalid (null) document.documentHeader.workflowDocument");
453        }
454
455        String documentType = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
456
457        DocumentPresentationController documentPresentationController = getDocumentPresentationController(documentType);
458
459        return documentPresentationController;
460    }
461
462    /**
463     * Retrieves the maintenance document entry associated with the given data object class
464     *
465     * @param dataObjectClass - data object class to retrieve maintenance document entry for
466     * @return MaintenanceDocumentEntry for associated data object class
467     */
468    protected MaintenanceDocumentEntry getMaintenanceDocumentEntry(Class dataObjectClass) {
469        if (dataObjectClass == null) {
470            throw new IllegalArgumentException("invalid (blank) dataObjectClass");
471        }
472
473        MaintenanceDocumentEntry entry =
474                getDataDictionary().getMaintenanceDocumentEntryForBusinessObjectClass(dataObjectClass);
475        return entry;
476    }
477
478    /**
479     * Retrieves the document entry for the document type of the given document instance
480     *
481     * @param document - document instance to retrieve document entry for
482     * @return DocumentEntry instance found for document type
483     */
484    protected DocumentEntry getDocumentEntry(Document document) {
485        if (document == null) {
486            throw new IllegalArgumentException("invalid (null) document");
487        }
488
489        DocumentEntry entry = getDataDictionary().getDocumentEntry(document.getClass().getName());
490
491        return entry;
492    }
493
494    /**
495     * Gets the workflow document type dto for the given documentTypeName
496     *
497     * @param documentTypeName - document type name to retrieve document type dto
498     * @return DocumentType for given document type name
499     */
500    protected DocumentType getDocumentType(String documentTypeName) {
501        return KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(documentTypeName);
502    }
503
504    protected DataDictionary getDataDictionary() {
505        return getDataDictionaryService().getDataDictionary();
506    }
507
508    protected DataDictionaryService getDataDictionaryService() {
509        if (dataDictionaryService == null) {
510            this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
511        }
512        return dataDictionaryService;
513    }
514
515    public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
516        this.dataDictionaryService = dataDictionaryService;
517    }
518}