View Javadoc

1   /**
2    * Copyright 2005-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.impl.ui;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
20  import org.kuali.rice.core.api.uif.RemotableAttributeField;
21  import org.kuali.rice.krad.bo.PersistableBusinessObject;
22  import org.kuali.rice.krad.document.MaintenanceDocument;
23  import org.kuali.rice.krad.maintenance.Maintainable;
24  import org.kuali.rice.krad.maintenance.MaintainableImpl;
25  import org.kuali.rice.krad.service.BusinessObjectService;
26  import org.kuali.rice.krad.service.KRADServiceLocator;
27  import org.kuali.rice.krad.uif.container.CollectionGroup;
28  import org.kuali.rice.krad.uif.container.Container;
29  import org.kuali.rice.krad.uif.view.View;
30  import org.kuali.rice.krad.util.KRADConstants;
31  import org.kuali.rice.krad.web.form.MaintenanceForm;
32  import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
33  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
34  import org.kuali.rice.krms.framework.type.ActionTypeService;
35  import org.kuali.rice.krms.framework.type.AgendaTypeService;
36  import org.kuali.rice.krms.framework.type.RuleTypeService;
37  import org.kuali.rice.krms.impl.repository.ActionBo;
38  import org.kuali.rice.krms.impl.repository.AgendaBo;
39  import org.kuali.rice.krms.impl.repository.ContextBoService;
40  import org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService;
41  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
42  import org.kuali.rice.krms.impl.type.ActionTypeServiceBase;
43  import org.kuali.rice.krms.impl.type.AgendaTypeServiceBase;
44  import org.kuali.rice.krms.impl.type.RuleTypeServiceBase;
45  
46  import java.util.ArrayList;
47  import java.util.HashMap;
48  import java.util.List;
49  import java.util.Map;
50  
51  /**
52   * {@link Maintainable} for the {@link AgendaEditor}
53   * 
54   * @author Kuali Rice Team (rice.collab@kuali.org)
55   *
56   */
57  public class AgendaEditorMaintainable extends MaintainableImpl {
58  	
59  	private static final long serialVersionUID = 1L;
60  
61      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AgendaEditorMaintainable.class);
62  
63  	/**
64  	 * @return the boService
65  	 */
66  	public BusinessObjectService getBoService() {
67  		return KRADServiceLocator.getBusinessObjectService();
68  	}
69  
70      /**
71       * return the contextBoService
72       */
73      private ContextBoService getContextBoService() {
74          return KrmsRepositoryServiceLocator.getContextBoService();
75      }
76  
77      public List<RemotableAttributeField> retrieveCustomAttributes(View view, Object model, Container container) {
78          List<RemotableAttributeField> results = new ArrayList<RemotableAttributeField>();
79  
80          MaintenanceForm maintenanceForm = (MaintenanceForm)model;
81          AgendaEditor agendaEditor = (AgendaEditor)maintenanceForm.getDocument().getNewMaintainableObject().getDataObject();
82  
83          // if we have an agenda w/ a typeId set on it
84          if (agendaEditor.getAgenda() != null && !StringUtils.isBlank(agendaEditor.getAgenda().getTypeId())) {
85  
86              String krmsTypeId = agendaEditor.getAgenda().getTypeId();
87  
88              AgendaTypeService agendaTypeService = getAgendaTypeService(krmsTypeId);
89              results.addAll(agendaTypeService.getAttributeFields(krmsTypeId));
90          }
91  
92          return results;
93      }
94  
95      private AgendaTypeService getAgendaTypeService(String krmsTypeId) {
96          //
97          // Get the AgendaTypeService by hook or by crook
98          //
99  
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 saveDataObject() {
291         AgendaBo agendaBo = ((AgendaEditor) getDataObject()).getAgenda();
292         if (agendaBo instanceof PersistableBusinessObject) {
293             Map<String,String> primaryKeys = new HashMap<String, String>();
294             primaryKeys.put("id", agendaBo.getId());
295             AgendaBo blah = getBusinessObjectService().findByPrimaryKey(AgendaBo.class, primaryKeys);
296             getBusinessObjectService().delete(blah);
297 
298             getBusinessObjectService().linkAndSave(agendaBo);
299         } else {
300             throw new RuntimeException(
301                     "Cannot save object of type: " + agendaBo + " with business object service");
302         }
303     }
304 
305     /**
306      * Build a map from attribute name to attribute definition from all the defined attribute definitions for the
307      * specified agenda type
308      * @param agendaTypeId
309      * @return
310      */
311     private Map<String, KrmsAttributeDefinition> buildAttributeDefinitionMap(String agendaTypeId) {
312         KrmsAttributeDefinitionService attributeDefinitionService =
313             KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
314 
315         // build a map from attribute name to definition
316         Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
317 
318         List<KrmsAttributeDefinition> attributeDefinitions =
319                 attributeDefinitionService.findAttributeDefinitionsByType(agendaTypeId);
320 
321         for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
322             attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
323         }
324         return attributeDefinitionMap;
325     }
326 
327     @Override
328     public boolean isOldDataObjectInDocument() {
329         boolean isOldDataObjectInExistence = true;
330 
331         if (getDataObject() == null) {
332             isOldDataObjectInExistence = false;
333         } else {
334             // dataObject contains a non persistable wrapper - use agenda from the wrapper object instead
335             Map<String, ?> keyFieldValues = getDataObjectMetaDataService().getPrimaryKeyFieldValues(((AgendaEditor) getDataObject()).getAgenda());
336             for (Object keyValue : keyFieldValues.values()) {
337                 if (keyValue == null) {
338                     isOldDataObjectInExistence = false;
339                 } else if ((keyValue instanceof String) && StringUtils.isBlank((String) keyValue)) {
340                     isOldDataObjectInExistence = false;
341                 }
342 
343                 if (!isOldDataObjectInExistence) {
344                     break;
345                 }
346             }
347         }
348 
349         return isOldDataObjectInExistence;
350     }
351 
352      // Since the dataObject is a wrapper class we need to return the agendaBo instead.
353     @Override
354     public Class getDataObjectClass() {
355         return AgendaBo.class;
356     }
357 
358     @Override
359     protected void processBeforeAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
360         MaintenanceForm form = (MaintenanceForm) model;
361         AgendaEditor agendaEditor = (AgendaEditor) form.getDocument().getNewMaintainableObject().getDataObject();
362         if (addLine instanceof ActionBo) {
363             ((ActionBo) addLine).setNamespace(agendaEditor.getAgendaItemLine().getRule().getNamespace());
364         }
365 
366         super.processBeforeAddLine(view, collectionGroup, model, addLine);
367     }
368 }