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.krad.datadictionary;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import org.apache.commons.lang.StringUtils;
022import org.kuali.rice.krad.datadictionary.parse.BeanTag;
023import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
024import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
025import org.kuali.rice.krad.document.Document;
026import org.kuali.rice.krad.maintenance.Maintainable;
027import org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizer;
028import org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizerBase;
029import org.kuali.rice.krad.maintenance.MaintenanceDocumentBase;
030import org.kuali.rice.krad.maintenance.MaintenanceDocumentPresentationControllerBase;
031
032/**
033 * Data dictionary entry class for <code>MaintenanceDocument</code>
034 *
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037@BeanTag(name = "maintenanceDocumentEntry", parent = "uifMaintenanceDocumentEntry")
038public class MaintenanceDocumentEntry extends DocumentEntry {
039    private static final long serialVersionUID = 4990040987835057251L;
040
041    protected Class<?> dataObjectClass;
042    protected Class<? extends Maintainable> maintainableClass;
043
044    protected List<String> lockingKeys = new ArrayList<String>();
045    protected List<String> clearValueOnCopyPropertyNames = new ArrayList<String>();
046
047    protected boolean allowsNewOrCopy = true;
048    protected boolean preserveLockingKeysOnCopy = false;
049    protected boolean allowsRecordDeletion = false;
050
051    public MaintenanceDocumentEntry() {
052        super();
053
054        setDocumentClass(getStandardDocumentBaseClass());
055        documentAuthorizerClass = MaintenanceDocumentAuthorizerBase.class;
056        documentPresentationControllerClass = MaintenanceDocumentPresentationControllerBase.class;
057    }
058
059    public Class<? extends Document> getStandardDocumentBaseClass() {
060        return MaintenanceDocumentBase.class;
061    }
062
063    /*
064            This attribute is used in many contexts, for example, in maintenance docs, it's used to specify the classname
065            of the BO being maintained.
066     */
067    public void setDataObjectClass(Class<?> dataObjectClass) {
068        this.dataObjectClass = dataObjectClass;
069    }
070
071    @BeanTagAttribute(name = "dataObjectClass")
072    public Class<?> getDataObjectClass() {
073        return dataObjectClass;
074    }
075
076    /**
077     * @see org.kuali.rice.krad.datadictionary.DocumentEntry#getEntryClass()
078     */
079    @SuppressWarnings("unchecked")
080    @Override
081    public Class getEntryClass() {
082        return dataObjectClass;
083    }
084
085    /*
086            The maintainableClass element specifies the name of the
087            java class which is responsible for implementing the
088            maintenance logic.
089            The normal one is KualiMaintainableImpl.java.
090     */
091    public void setMaintainableClass(Class<? extends Maintainable> maintainableClass) {
092        this.maintainableClass = maintainableClass;
093    }
094
095    @BeanTagAttribute(name = "maintainableClass")
096    public Class<? extends Maintainable> getMaintainableClass() {
097        return maintainableClass;
098    }
099
100    /**
101     * @return List of all lockingKey fieldNames associated with this LookupDefinition, in the order in which they were
102     *         added
103     */
104    public List<String> getLockingKeyFieldNames() {
105        return lockingKeys;
106    }
107
108    /**
109     * Gets the allowsNewOrCopy attribute.
110     *
111     * @return Returns the allowsNewOrCopy.
112     */
113    @BeanTagAttribute(name = "allowsNewOrCopy")
114    public boolean getAllowsNewOrCopy() {
115        return allowsNewOrCopy;
116    }
117
118    /**
119     * The allowsNewOrCopy element contains a value of true or false.
120     * If true, this indicates the maintainable should allow the
121     * new and/or copy maintenance actions.
122     */
123    public void setAllowsNewOrCopy(boolean allowsNewOrCopy) {
124        this.allowsNewOrCopy = allowsNewOrCopy;
125    }
126
127    /**
128     * Directly validate simple fields, call completeValidation on Definition fields.
129     *
130     * @see org.kuali.rice.krad.datadictionary.DocumentEntry#completeValidation()
131     */
132    @Override
133    public void completeValidation(ValidationTrace tracer) {
134        super.completeValidation(tracer);
135
136        if (dataObjectClass == null) {
137            String currentValues[] = {};
138            tracer.createError("invalid (null) dataObjectClass", currentValues);
139        }
140
141        if (maintainableClass == null) {
142            String currentValues[] = {};
143            tracer.createError("invalid (null) maintainableClass", currentValues);
144        }
145
146        for (String lockingKey : lockingKeys) {
147            if ( StringUtils.isBlank(lockingKey) ) {
148                String currentValues[] = {"lockingKeys = " + lockingKeys};
149                tracer.createError("invalid (blank) lockingKey", currentValues);
150            } else if (!DataDictionary.isPropertyOf(dataObjectClass, lockingKey)) {
151                String currentValues[] = {"dataObjectClass = " + dataObjectClass, "lockingKey = " + lockingKey};
152                tracer.createError("lockingKey not found in data object class", currentValues);
153            }
154        }
155
156        for (String clearValueOnCopyPropertyName : clearValueOnCopyPropertyNames) {
157            if (StringUtils.isBlank(clearValueOnCopyPropertyName)) {
158                String currentValues[] = {"clearValueOnCopyPropertyNames = " + clearValueOnCopyPropertyNames};
159                tracer.createError("invalid (blank) clearValueOnCopyPropertyNames", currentValues);
160            } else if (!DataDictionary.isPropertyOf(dataObjectClass, clearValueOnCopyPropertyName)) {
161                String currentValues[] = {"dataObjectClass = " + dataObjectClass,
162                        "clearValueOnCopyPropertyName = " + clearValueOnCopyPropertyName};
163                tracer.createError("clearValueOnCopyPropertyName not found in data object class", currentValues);
164            }
165        }
166
167        if (documentAuthorizerClass != null
168                && !MaintenanceDocumentAuthorizer.class.isAssignableFrom(documentAuthorizerClass)) {
169            String currentValues[] = {"documentAuthorizerClass = " + documentAuthorizerClass.getName()};
170            tracer.createError("Maintenance Documents must use an implementation of MaintenanceDocumentAuthorizer", currentValues);
171        }
172    }
173
174    @Override
175    protected void validateDefaultExistenceChecks( ValidationTrace tracer ) {
176        for ( ReferenceDefinition refDef : defaultExistenceChecks ) {
177            refDef.completeValidation(dataObjectClass, null, tracer.getCopy());
178        }
179    }
180
181
182    @BeanTagAttribute(name = "lockingKeys", type = BeanTagAttribute.AttributeType.LISTVALUE)
183    public List<String> getLockingKeys() {
184        return lockingKeys;
185    }
186
187    /*
188           The lockingKeys element specifies a list of fields
189           that comprise a unique key.  This is used for record locking
190           during the file maintenance process.
191    */
192    public void setLockingKeys(List<String> lockingKeys) {
193        this.lockingKeys = lockingKeys;
194    }
195
196    /**
197     * @return the preserveLockingKeysOnCopy
198     */
199    @BeanTagAttribute(name = "preserveLockingKeysOnCopy")
200    public boolean getPreserveLockingKeysOnCopy() {
201        return this.preserveLockingKeysOnCopy;
202    }
203
204    /**
205     * @param preserveLockingKeysOnCopy the preserveLockingKeysOnCopy to set
206     */
207    public void setPreserveLockingKeysOnCopy(boolean preserveLockingKeysOnCopy) {
208        this.preserveLockingKeysOnCopy = preserveLockingKeysOnCopy;
209    }
210
211    /**
212     * @return the clearValueOnCopyPropertyNames
213     */
214    @BeanTagAttribute(name = "clearValueOnCopyPropertyNames", type = BeanTagAttribute.AttributeType.LISTVALUE)
215    public List<String> getClearValueOnCopyPropertyNames() {
216        return clearValueOnCopyPropertyNames;
217    }
218
219    /**
220     * @param clearValueOnCopyPropertyNames the clearValueOnCopyPropertyNames to set
221     */
222    public void setClearValueOnCopyPropertyNames(List<String> clearValueOnCopyPropertyNames) {
223        this.clearValueOnCopyPropertyNames = clearValueOnCopyPropertyNames;
224    }
225
226    /**
227     * @return the allowRecordDeletion
228     */
229    @BeanTagAttribute(name = "allowsRecordDeletion")
230    public boolean getAllowsRecordDeletion() {
231        return this.allowsRecordDeletion;
232    }
233
234    /**
235     * @param allowsRecordDeletion the allowRecordDeletion to set
236     */
237    public void setAllowsRecordDeletion(boolean allowsRecordDeletion) {
238        this.allowsRecordDeletion = allowsRecordDeletion;
239    }
240
241}