001/**
002 * Copyright 2005-2016 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.kew.document;
017
018import java.util.Collection;
019import java.util.HashSet;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.kuali.rice.kew.actionitem.ActionItem;
025import org.kuali.rice.kew.actionitem.OutboxItemActionListExtension;
026import org.kuali.rice.kew.actionlist.service.ActionListService;
027import org.kuali.rice.kew.api.KEWPropertyConstants;
028import org.kuali.rice.kew.api.WorkflowRuntimeException;
029import org.kuali.rice.kew.doctype.bo.DocumentType;
030import org.kuali.rice.kew.doctype.service.DocumentTypeService;
031import org.kuali.rice.kew.service.KEWServiceLocator;
032import org.kuali.rice.kew.xml.DocumentTypeXmlParser;
033import org.kuali.rice.kns.datadictionary.MaintainableItemDefinition;
034import org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition;
035import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
036import org.kuali.rice.kns.web.ui.Field;
037import org.kuali.rice.kns.web.ui.Row;
038import org.kuali.rice.kns.web.ui.Section;
039import org.kuali.rice.krad.bo.DocumentHeader;
040import org.kuali.rice.kns.document.MaintenanceDocument;
041import org.kuali.rice.kns.maintenance.Maintainable;
042import org.kuali.rice.krad.util.ObjectUtils;
043
044/**
045 * This class is the maintainable implementation for the Workflow {@link DocumentType} 
046 * 
047 * @author Kuali Rice Team (rice.collab@kuali.org)
048 *
049 */
050public class DocumentTypeMaintainable extends KualiMaintainableImpl {
051    
052    private static final long serialVersionUID = -5920808902137192662L;
053
054    /**
055     * Override the getSections method on this maintainable so that the document type name field
056     * can be set to read-only for 
057     */
058    @Override
059    public List getSections(MaintenanceDocument document, Maintainable oldMaintainable) {
060        List<Section> sections = super.getSections(document, oldMaintainable);
061        // if the document isn't new then we need to make the document type name field read-only
062        if (!document.isNew()) {
063            sectionLoop: for (Section section : sections) {
064                for (Row row : section.getRows()) {
065                    for (Field field : row.getFields()) {
066                        if (KEWPropertyConstants.NAME.equals(field.getPropertyName())) {
067                            field.setReadOnly(true);
068                            break sectionLoop;
069                        }
070                    }
071                }
072            }
073        }
074        return sections;
075    }
076
077    /**
078     * This overridden method resets the name
079     * 
080     *
081     */
082    @Override
083    public void processAfterCopy(MaintenanceDocument document, Map<String, String[]> parameters) {
084        super.processAfterCopy(document, parameters);
085        DocumentType docType = ((DocumentType)getBusinessObject());
086        docType.setDocumentTypeId(null);
087        docType.setName("");
088        docType.setPreviousVersionId(null);
089        docType.setObjectId(null);
090    }
091
092    @Override
093    public void doRouteStatusChange(DocumentHeader documentHeader) {
094        super.doRouteStatusChange(documentHeader);
095    }
096    
097    private Set<String> constructUserInterfaceEditablePropertyNamesList() {
098        Set<String> propertyNames = new HashSet<String>();
099        List<MaintainableSectionDefinition> sectionDefinitions = getMaintenanceDocumentDictionaryService().getMaintainableSections(getDocumentTypeName());
100        for (MaintainableSectionDefinition maintainableSectionDefinition : sectionDefinitions) {
101            for (MaintainableItemDefinition maintainableItemDefinition : maintainableSectionDefinition.getMaintainableItems()) {
102                propertyNames.add(maintainableItemDefinition.getName());
103            }
104        }
105        return propertyNames;
106    }
107
108    /**
109     * This is a complete override which does not call into
110     * {@link KualiMaintainableImpl}. This method calls
111     * {@link DocumentTypeService#versionAndSave(DocumentType)}.
112     *
113     */
114    @Override
115    public void saveBusinessObject() {
116        DocumentTypeService docTypeService = KEWServiceLocator.getDocumentTypeService();
117        DocumentType newDocumentType = (DocumentType) getBusinessObject();
118        String documentTypeName = newDocumentType.getName();
119        DocumentType docTypeFromDatabase = docTypeService.findByName(documentTypeName);
120        if (ObjectUtils.isNull(docTypeFromDatabase)) {
121            docTypeService.versionAndSave(newDocumentType);
122        }
123        else {
124            Boolean applyRetroactively = newDocumentType.getApplyRetroactively();
125                DocumentType newDocumentTypeFromDatabase;
126            DocumentTypeXmlParser parser = new DocumentTypeXmlParser();
127            try {
128                newDocumentTypeFromDatabase = parser.generateNewDocumentTypeFromExisting(documentTypeName);
129            } catch (Exception e) {
130                throw new WorkflowRuntimeException("Error while attempting to generate new document type from existing " +
131                                "database document type with name '" + documentTypeName + "'", e);
132            }
133            newDocumentTypeFromDatabase.populateDataDictionaryEditableFields(constructUserInterfaceEditablePropertyNamesList(), newDocumentType);
134            docTypeService.versionAndSave(newDocumentTypeFromDatabase);
135            if (ObjectUtils.isNotNull(applyRetroactively) && applyRetroactively.booleanValue()) {
136                // save all previous instances of document type with the same name
137                // fields: label, description, unresolvedHelpDefinitionUrl
138                List<DocumentType> previousDocTypeInstances = docTypeService.findPreviousInstances(documentTypeName);
139                for (DocumentType prevDocType : previousDocTypeInstances) {
140                    // set up fields
141                    prevDocType.setLabel(newDocumentType.getLabel());
142                    prevDocType.setDescription(newDocumentType.getDescription());
143                    prevDocType.setUnresolvedHelpDefinitionUrl(newDocumentType.getUnresolvedHelpDefinitionUrl());
144                    prevDocType.setUnresolvedDocSearchHelpUrl(newDocumentType.getUnresolvedDocSearchHelpUrl());
145                    docTypeService.save(prevDocType);
146                }
147                // save all former/current action items matching document type name
148                // fields: docLabel
149                ActionListService actionListService = KEWServiceLocator.getActionListService(); 
150                Collection<ActionItem> items = actionListService.findByDocumentTypeName(documentTypeName);
151                for (ActionItem actionItem : items) {
152                    actionItem.setDocLabel(newDocumentType.getLabel());
153                    actionListService.saveActionItem(actionItem);
154                }
155                // save all former/current outbox action items matching document type name
156                // fields: docLabel
157                Collection<OutboxItemActionListExtension> outboxItems = actionListService.getOutboxItemsByDocumentType(documentTypeName);
158                for (ActionItem outboxItem : outboxItems) {
159                    outboxItem.setDocLabel(newDocumentType.getLabel());
160                    actionListService.saveActionItem(outboxItem);
161                }
162            }
163        }
164    }
165
166}