001 /*
002 * Copyright 2011 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 */
016 package org.kuali.kfs.coa.document;
017
018 import java.util.ArrayList;
019 import java.util.Collection;
020 import java.util.Collections;
021 import java.util.Comparator;
022 import java.util.List;
023
024 import org.kuali.kfs.coa.businessobject.OrganizationReversion;
025 import org.kuali.kfs.coa.businessobject.OrganizationReversionCategory;
026 import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobal;
027 import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobalDetail;
028 import org.kuali.kfs.coa.businessobject.OrganizationReversionGlobalOrganization;
029 import org.kuali.kfs.coa.service.OrganizationReversionService;
030 import org.kuali.kfs.sys.KFSConstants;
031 import org.kuali.kfs.sys.context.SpringContext;
032 import org.kuali.kfs.sys.document.FinancialSystemGlobalMaintainable;
033 import org.kuali.rice.kns.bo.PersistableBusinessObject;
034 import org.kuali.rice.kns.document.MaintenanceLock;
035 import org.kuali.rice.kns.util.TypedArrayList;
036
037 /**
038 * This class provides some specific functionality for the {@link OrganizationReversionGlobal} maintenance document inner class for
039 * doing comparisons on {@link OrganizationReversionCategory} generateMaintenanceLocks - generates the appropriate maintenance locks
040 * on {@link OrganizationReversion} setBusinessObject - populates the {@link OrganizationReversionGlobalDetail}s
041 * isRelationshipRefreshable - makes sure that {@code organizationReversionGlobalDetails} isn't wiped out accidentally
042 * processGlobalsAfterRetrieve - provides special handling for the details (which aren't a true collection)
043 */
044 public class OrganizationReversionGlobalMaintainableImpl extends FinancialSystemGlobalMaintainable {
045 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrganizationReversionGlobalMaintainableImpl.class);
046
047 /**
048 * This class is an inner class for comparing two {@link OrganizationReversionCategory}s
049 */
050 private class CategoryComparator implements Comparator<OrganizationReversionGlobalDetail> {
051 public int compare(OrganizationReversionGlobalDetail detailA, OrganizationReversionGlobalDetail detailB) {
052 OrganizationReversionCategory categoryA = detailA.getOrganizationReversionCategory();
053 OrganizationReversionCategory categoryB = detailB.getOrganizationReversionCategory();
054
055 String code0 = categoryA.getOrganizationReversionCategoryCode();
056 String code1 = categoryB.getOrganizationReversionCategoryCode();
057
058 return code0.compareTo(code1);
059 }
060 }
061
062 /**
063 * This implementation locks all organization reversions that would be accessed by this global organization reversion. It does
064 * not lock any OrganizationReversionDetail objects, as we expect that those will be inaccessible
065 *
066 * @see org.kuali.rice.kns.maintenance.KualiGlobalMaintainableImpl#generateMaintenaceLocks()
067 */
068 @Override
069 public List<MaintenanceLock> generateMaintenanceLocks() {
070 List<MaintenanceLock> locks = new ArrayList<MaintenanceLock>();
071 OrganizationReversionGlobal globalOrgRev = (OrganizationReversionGlobal) this.getBusinessObject();
072 if (globalOrgRev.getUniversityFiscalYear() != null && globalOrgRev.getOrganizationReversionGlobalOrganizations() != null && globalOrgRev.getOrganizationReversionGlobalOrganizations().size() > 0) { // only generate locks if we're going to have primary keys
073 for (OrganizationReversionGlobalOrganization orgRevOrg : globalOrgRev.getOrganizationReversionGlobalOrganizations()) {
074 MaintenanceLock maintenanceLock = new MaintenanceLock();
075 maintenanceLock.setDocumentNumber(globalOrgRev.getDocumentNumber());
076
077 StringBuffer lockRep = new StringBuffer();
078 lockRep.append(OrganizationReversion.class.getName());
079 lockRep.append(KFSConstants.Maintenance.AFTER_CLASS_DELIM);
080 lockRep.append("chartOfAccountsCode");
081 lockRep.append(KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
082 lockRep.append(orgRevOrg.getChartOfAccountsCode());
083 lockRep.append(KFSConstants.Maintenance.AFTER_VALUE_DELIM);
084 lockRep.append("universityFiscalYear");
085 lockRep.append(KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
086 lockRep.append(globalOrgRev.getUniversityFiscalYear().toString());
087 lockRep.append(KFSConstants.Maintenance.AFTER_VALUE_DELIM);
088 lockRep.append("organizationCode");
089 lockRep.append(KFSConstants.Maintenance.AFTER_FIELDNAME_DELIM);
090 lockRep.append(orgRevOrg.getOrganizationCode());
091 lockRep.append(KFSConstants.Maintenance.AFTER_VALUE_DELIM);
092
093 maintenanceLock.setLockingRepresentation(lockRep.toString());
094 locks.add(maintenanceLock);
095 }
096 }
097
098 return locks;
099 }
100
101 /**
102 * Just like OrganizationReversionMaintainableImpl's setBusinessObject method populates the list of details so there is one
103 * detail per active Organization Reversion Category, this method populates a list of Organization Reversion Change details.
104 *
105 * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#setBusinessObject(org.kuali.rice.kns.bo.PersistableBusinessObject)
106 */
107 @Override
108 public void setBusinessObject(PersistableBusinessObject businessObject) {
109 super.setBusinessObject(businessObject);
110 OrganizationReversionService organizationReversionService = SpringContext.getBean(OrganizationReversionService.class);
111 OrganizationReversionGlobal globalOrgRev = (OrganizationReversionGlobal) businessObject;
112 List<OrganizationReversionGlobalDetail> details = globalOrgRev.getOrganizationReversionGlobalDetails();
113 LOG.debug("Details size before adding categories = " + details.size());
114
115 if (details == null) {
116 details = new TypedArrayList(OrganizationReversionGlobalDetail.class);
117 globalOrgRev.setOrganizationReversionGlobalDetails(details);
118 }
119
120 if (details.size() == 0) {
121
122 Collection<OrganizationReversionCategory> categories = organizationReversionService.getCategoryList();
123 for (OrganizationReversionCategory category : categories) {
124 if (category.isActive()) {
125 OrganizationReversionGlobalDetail detail = new OrganizationReversionGlobalDetail();
126 detail.setOrganizationReversionCategoryCode(category.getOrganizationReversionCategoryCode());
127 detail.setOrganizationReversionCategory(category);
128 detail.setParentGlobalOrganizationReversion(globalOrgRev);
129 details.add(detail);
130 }
131 }
132 LOG.debug("Details size after adding categories = " + details.size());
133 Collections.sort(details, new CategoryComparator());
134 }
135 super.setBusinessObject(businessObject);
136 }
137
138 /**
139 * Prevents Organization Reversion Change Details from being refreshed by a look up (because doing that refresh before a save
140 * would wipe out the list of organization reversion change details).
141 *
142 * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#isRelationshipRefreshable(java.lang.Class, java.lang.String)
143 */
144 @Override
145 protected boolean isRelationshipRefreshable(Class boClass, String relationshipName) {
146 if (relationshipName.equals("organizationReversionGlobalDetails")) {
147 return false;
148 }
149 else {
150 return super.isRelationshipRefreshable(boClass, relationshipName);
151 }
152 }
153
154 /**
155 * The org reversion detail collection does not behave like a true collection (no add lines). The records on the collection
156 * should not have the delete option.
157 *
158 * @see org.kuali.rice.kns.maintenance.KualiGlobalMaintainableImpl#processGlobalsAfterRetrieve()
159 */
160 @Override
161 protected void processGlobalsAfterRetrieve() {
162 super.processGlobalsAfterRetrieve();
163 for (OrganizationReversionGlobalDetail changeDetail : ((OrganizationReversionGlobal) businessObject).getOrganizationReversionGlobalDetails()) {
164 changeDetail.setNewCollectionRecord(false);
165 }
166 }
167
168 @Override
169 public Class<? extends PersistableBusinessObject> getPrimaryEditedBusinessObjectClass() {
170 return OrganizationReversion.class;
171 }
172 }