001 /**
002 * Copyright 2005-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.rice.krms.impl.ui;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
020 import org.kuali.rice.core.api.uif.RemotableAttributeField;
021 import org.kuali.rice.krad.bo.PersistableBusinessObject;
022 import org.kuali.rice.krad.document.MaintenanceDocument;
023 import org.kuali.rice.krad.maintenance.Maintainable;
024 import org.kuali.rice.krad.maintenance.MaintainableImpl;
025 import org.kuali.rice.krad.service.BusinessObjectService;
026 import org.kuali.rice.krad.service.KRADServiceLocator;
027 import org.kuali.rice.krad.uif.container.CollectionGroup;
028 import org.kuali.rice.krad.uif.container.Container;
029 import org.kuali.rice.krad.uif.view.View;
030 import org.kuali.rice.krad.util.KRADConstants;
031 import org.kuali.rice.krad.web.form.MaintenanceForm;
032 import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
033 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
034 import org.kuali.rice.krms.framework.type.ActionTypeService;
035 import org.kuali.rice.krms.framework.type.AgendaTypeService;
036 import org.kuali.rice.krms.framework.type.RuleTypeService;
037 import org.kuali.rice.krms.impl.repository.ActionBo;
038 import org.kuali.rice.krms.impl.repository.AgendaBo;
039 import org.kuali.rice.krms.impl.repository.ContextBoService;
040 import org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService;
041 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
042 import org.kuali.rice.krms.impl.type.ActionTypeServiceBase;
043 import org.kuali.rice.krms.impl.type.AgendaTypeServiceBase;
044 import org.kuali.rice.krms.impl.type.RuleTypeServiceBase;
045
046 import java.util.ArrayList;
047 import java.util.HashMap;
048 import java.util.List;
049 import java.util.Map;
050
051 /**
052 * {@link Maintainable} for the {@link AgendaEditor}
053 *
054 * @author Kuali Rice Team (rice.collab@kuali.org)
055 *
056 */
057 public class AgendaEditorMaintainable extends MaintainableImpl {
058
059 private static final long serialVersionUID = 1L;
060
061 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AgendaEditorMaintainable.class);
062
063 /**
064 * @return the boService
065 */
066 public BusinessObjectService getBoService() {
067 return KRADServiceLocator.getBusinessObjectService();
068 }
069
070 /**
071 * return the contextBoService
072 */
073 private ContextBoService getContextBoService() {
074 return KrmsRepositoryServiceLocator.getContextBoService();
075 }
076
077 public List<RemotableAttributeField> retrieveCustomAttributes(View view, Object model, Container container) {
078 List<RemotableAttributeField> results = new ArrayList<RemotableAttributeField>();
079
080 MaintenanceForm maintenanceForm = (MaintenanceForm)model;
081 AgendaEditor agendaEditor = (AgendaEditor)maintenanceForm.getDocument().getNewMaintainableObject().getDataObject();
082
083 // if we have an agenda w/ a typeId set on it
084 if (agendaEditor.getAgenda() != null && !StringUtils.isBlank(agendaEditor.getAgenda().getTypeId())) {
085
086 String krmsTypeId = agendaEditor.getAgenda().getTypeId();
087
088 AgendaTypeService agendaTypeService = getAgendaTypeService(krmsTypeId);
089 results.addAll(agendaTypeService.getAttributeFields(krmsTypeId));
090 }
091
092 return results;
093 }
094
095 private AgendaTypeService getAgendaTypeService(String krmsTypeId) {
096 //
097 // Get the AgendaTypeService by hook or by crook
098 //
099
100 KrmsTypeDefinition krmsType =
101 KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().
102 getTypeById(krmsTypeId);
103
104 AgendaTypeService agendaTypeService = null;
105
106 if (!StringUtils.isBlank(krmsTypeId)) {
107 String serviceName = krmsType.getServiceName();
108
109 if (!StringUtils.isBlank(serviceName)) {
110 agendaTypeService = KrmsRepositoryServiceLocator.getService(serviceName);
111 }
112 }
113
114 if (agendaTypeService == null) { agendaTypeService = AgendaTypeServiceBase.defaultAgendaTypeService; }
115
116 return agendaTypeService;
117 }
118
119 /**
120 * This only supports a single action within a rule.
121 */
122 public List<RemotableAttributeField> retrieveRuleActionCustomAttributes(View view, Object model, Container container) {
123 List<RemotableAttributeField> results = new ArrayList<RemotableAttributeField>();
124
125 MaintenanceForm maintenanceForm = (MaintenanceForm)model;
126 AgendaEditor agendaEditor = (AgendaEditor)maintenanceForm.getDocument().getNewMaintainableObject().getDataObject();
127
128 // if we have an rule action w/ a typeId set on it
129 if (!StringUtils.isBlank(agendaEditor.getAgendaItemLineRuleAction().getTypeId())) {
130 ActionTypeService actionTypeService = getActionTypeService(agendaEditor.getAgendaItemLineRuleAction().getTypeId());
131 results.addAll(actionTypeService.getAttributeFields(agendaEditor.getAgendaItemLineRuleAction().getTypeId()));
132 }
133
134 return results;
135 }
136
137 public List<RemotableAttributeField> retrieveRuleCustomAttributes(View view, Object model, Container container) {
138 List<RemotableAttributeField> results = new ArrayList<RemotableAttributeField>();
139
140 MaintenanceForm maintenanceForm = (MaintenanceForm)model;
141 AgendaEditor agendaEditor = (AgendaEditor)maintenanceForm.getDocument().getNewMaintainableObject().getDataObject();
142
143 // if we have an rule w/ a typeId set on it
144 if (agendaEditor.getAgendaItemLine() != null && agendaEditor.getAgendaItemLine().getRule() != null
145 && !StringUtils.isBlank(agendaEditor.getAgendaItemLine().getRule().getTypeId())) {
146
147 String krmsTypeId = agendaEditor.getAgendaItemLine().getRule().getTypeId();
148
149 RuleTypeService ruleTypeService = getRuleTypeService(krmsTypeId);
150 results.addAll(ruleTypeService.getAttributeFields(krmsTypeId));
151 }
152
153 return results;
154 }
155
156 private ActionTypeService getActionTypeService(String krmsTypeId) {
157 //
158 // Get the ActionTypeService by hook or by crook
159 //
160
161 KrmsTypeDefinition krmsType =
162 KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().
163 getTypeById(krmsTypeId);
164
165 ActionTypeService actionTypeService = null;
166
167 if (!StringUtils.isBlank(krmsTypeId)) {
168 String serviceName = krmsType.getServiceName();
169
170 if (!StringUtils.isBlank(serviceName)) {
171 actionTypeService = KrmsRepositoryServiceLocator.getService(serviceName);
172 }
173 }
174 if (actionTypeService == null) {
175 actionTypeService = ActionTypeServiceBase.defaultActionTypeService;
176 }
177
178 // if (actionTypeService == null) { actionTypeService = AgendaTypeServiceBase.defaultAgendaTypeService; }
179
180 return actionTypeService;
181 }
182
183 private RuleTypeService getRuleTypeService(String krmsTypeId) {
184 RuleTypeService ruleTypeService = null;
185 String serviceName = getRuleTypeServiceName(krmsTypeId);
186
187 if (!StringUtils.isBlank(serviceName)) {
188 ruleTypeService = KrmsRepositoryServiceLocator.getService(serviceName);
189 }
190 if (ruleTypeService == null) {
191 ruleTypeService = RuleTypeServiceBase.defaultRuleTypeService;
192 }
193 return ruleTypeService;
194 }
195
196 private String getRuleTypeServiceName(String krmsTypeId) {
197 String serviceName = null;
198 KrmsTypeDefinition krmsType =
199 KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().
200 getTypeById(krmsTypeId);
201
202 if (!StringUtils.isBlank(krmsTypeId)) {
203 serviceName = krmsType.getServiceName();
204 }
205 return serviceName;
206 }
207
208 @Override
209 public Object retrieveObjectForEditOrCopy(MaintenanceDocument document, Map<String, String> dataObjectKeys) {
210 Object dataObject = null;
211
212 try {
213 // Since the dataObject is a wrapper class we need to build it and populate with the agenda bo.
214 AgendaEditor agendaEditor = new AgendaEditor();
215 AgendaBo agenda = getLookupService().findObjectBySearch(((AgendaEditor) getDataObject()).getAgenda().getClass(), dataObjectKeys);
216 if (KRADConstants.MAINTENANCE_COPY_ACTION.equals(getMaintenanceAction())) {
217 // If we don't clear the primary key and set the fieldsClearedOnCopy flag then the
218 // MaintenanceDocumentServiceImpl.processMaintenanceObjectForCopy() will try to locate the primary keys in
219 // an attempt to clear them which again would cause an exception due to the wrapper class.
220 agenda.setId(null);
221 document.setFieldsClearedOnCopy(true);
222 }
223 agendaEditor.setAgenda(agenda);
224
225 // set custom attributes map in AgendaEditor
226 agendaEditor.setCustomAttributesMap(agenda.getAttributes());
227
228 // set extra fields on AgendaEditor
229 agendaEditor.setNamespace(agenda.getContext().getNamespace());
230 agendaEditor.setContextName(agenda.getContext().getName());
231
232 dataObject = agendaEditor;
233 } catch (ClassNotPersistenceCapableException ex) {
234 if (!document.getOldMaintainableObject().isExternalBusinessObject()) {
235 throw new RuntimeException("Data Object Class: " + getDataObjectClass() +
236 " is not persistable and is not externalizable - configuration error");
237 }
238 // otherwise, let fall through
239 }
240
241 return dataObject;
242 }
243
244 /**
245 * {@inheritDoc}
246 */
247 @Override
248 public void processAfterNew(MaintenanceDocument document,
249 Map<String, String[]> requestParameters) {
250
251 super.processAfterNew(document, requestParameters);
252 document.getDocumentHeader().setDocumentDescription("New Agenda Editor Document");
253
254 // if (KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) {
255 // String[] agendaIds = requestParameters.get("agendaId");
256 // if (agendaIds == null || agendaIds.length != 1) {
257 // //throw new RiceRuntimeException("one and only one agendaId request parameter may be passed");
258 // } else {
259 // // TODO: change this, it makes more sense for MAINTENANCE_EDIT_ACTION
260 // String agendaId = agendaIds[0];
261 //
262 // AgendaBo agenda = getBoService().findBySinglePrimaryKey(AgendaBo.class, agendaId);
263 // String contextId = agenda.getContextId();
264 //
265 // ContextBo context = getBoService().findBySinglePrimaryKey(ContextBo.class, contextId);
266 //
267 // AgendaEditor editor = (AgendaEditor) document.getDocumentBusinessObject();
268 //
269 // editor.setContext(context);
270 // editor.setAgenda(agenda);
271 // }
272 // }
273
274
275 }
276
277 @Override
278 public void processAfterCopy(MaintenanceDocument document, Map<String, String[]> requestParameters) {
279 super.processAfterCopy(document, requestParameters);
280 document.getDocumentHeader().setDocumentDescription("New Agenda Editor Document");
281 }
282
283 @Override
284 public void processAfterEdit(MaintenanceDocument document, Map<String, String[]> requestParameters) {
285 super.processAfterEdit(document, requestParameters);
286 document.getDocumentHeader().setDocumentDescription("Modify Agenda Editor Document");
287 }
288
289 @Override
290 public void prepareForSave() {
291 // set agenda attributes
292 AgendaEditor agendaEditor = (AgendaEditor) getDataObject();
293 agendaEditor.getAgenda().setAttributes(agendaEditor.getCustomAttributesMap());
294 }
295
296 @Override
297 public void saveDataObject() {
298 AgendaBo agendaBo = ((AgendaEditor) getDataObject()).getAgenda();
299 if (agendaBo instanceof PersistableBusinessObject) {
300 Map<String,String> primaryKeys = new HashMap<String, String>();
301 primaryKeys.put("id", agendaBo.getId());
302 AgendaBo blah = getBusinessObjectService().findByPrimaryKey(AgendaBo.class, primaryKeys);
303 getBusinessObjectService().delete(blah);
304
305 getBusinessObjectService().linkAndSave(agendaBo);
306 } else {
307 throw new RuntimeException(
308 "Cannot save object of type: " + agendaBo + " with business object service");
309 }
310 }
311
312 /**
313 * Build a map from attribute name to attribute definition from all the defined attribute definitions for the
314 * specified agenda type
315 * @param agendaTypeId
316 * @return
317 */
318 private Map<String, KrmsAttributeDefinition> buildAttributeDefinitionMap(String agendaTypeId) {
319 KrmsAttributeDefinitionService attributeDefinitionService =
320 KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
321
322 // build a map from attribute name to definition
323 Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
324
325 List<KrmsAttributeDefinition> attributeDefinitions =
326 attributeDefinitionService.findAttributeDefinitionsByType(agendaTypeId);
327
328 for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
329 attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
330 }
331 return attributeDefinitionMap;
332 }
333
334 @Override
335 public boolean isOldDataObjectInDocument() {
336 boolean isOldDataObjectInExistence = true;
337
338 if (getDataObject() == null) {
339 isOldDataObjectInExistence = false;
340 } else {
341 // dataObject contains a non persistable wrapper - use agenda from the wrapper object instead
342 Map<String, ?> keyFieldValues = getDataObjectMetaDataService().getPrimaryKeyFieldValues(((AgendaEditor) getDataObject()).getAgenda());
343 for (Object keyValue : keyFieldValues.values()) {
344 if (keyValue == null) {
345 isOldDataObjectInExistence = false;
346 } else if ((keyValue instanceof String) && StringUtils.isBlank((String) keyValue)) {
347 isOldDataObjectInExistence = false;
348 }
349
350 if (!isOldDataObjectInExistence) {
351 break;
352 }
353 }
354 }
355
356 return isOldDataObjectInExistence;
357 }
358
359 // Since the dataObject is a wrapper class we need to return the agendaBo instead.
360 @Override
361 public Class getDataObjectClass() {
362 return AgendaBo.class;
363 }
364
365 @Override
366 protected void processBeforeAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
367 MaintenanceForm form = (MaintenanceForm) model;
368 AgendaEditor agendaEditor = (AgendaEditor) form.getDocument().getNewMaintainableObject().getDataObject();
369 if (addLine instanceof ActionBo) {
370 ((ActionBo) addLine).setNamespace(agendaEditor.getAgendaItemLine().getRule().getNamespace());
371 }
372
373 super.processBeforeAddLine(view, collectionGroup, model, addLine);
374 }
375 }