View Javadoc

1   /*
2    * Copyright 2007 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 1.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/ecl1.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.student.lum.service.assembler;
17  
18  import org.kuali.student.common.assembly.BaseDTOAssemblyNode;
19  import org.kuali.student.common.assembly.BaseDTOAssemblyNode.NodeOperation;
20  import org.kuali.student.common.assembly.data.AssemblyException;
21  import org.kuali.student.common.dto.RichTextInfo;
22  import org.kuali.student.common.exceptions.DoesNotExistException;
23  import org.kuali.student.common.exceptions.InvalidParameterException;
24  import org.kuali.student.common.exceptions.MissingParameterException;
25  import org.kuali.student.common.exceptions.OperationFailedException;
26  import org.kuali.student.lum.course.dto.LoDisplayInfo;
27  import org.kuali.student.lum.course.service.assembler.LoAssembler;
28  import org.kuali.student.lum.lo.dto.LoInfo;
29  import org.kuali.student.lum.lo.service.LearningObjectiveService;
30  import org.kuali.student.lum.lu.dto.CluLoRelationInfo;
31  import org.kuali.student.lum.lu.dto.CluResultInfo;
32  import org.kuali.student.lum.lu.dto.ResultOptionInfo;
33  import org.kuali.student.lum.lu.service.LuService;
34  
35  import java.util.ArrayList;
36  import java.util.Date;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Map;
40  import java.util.Map.Entry;
41  
42  /**
43   * This is a description of what this class does - jimt don't forget to fill this in.
44   *
45   * @author Kuali Rice Team (kuali-rice@googlegroups.com)
46   *
47   */
48  public class CluAssemblerUtils {
49      private LuService luService;
50      private LearningObjectiveService loService;
51      private LoAssembler loAssembler;
52  
53      public List<String> assembleCluResults(List<String> resultTypes, List<CluResultInfo> cluResults) throws AssemblyException{
54  		if(resultTypes==null){
55  			throw new AssemblyException("result types can not be null");
56  		}
57  		List<String> results = new ArrayList<String>();
58  		//Loop through all the CluResults to find those with the matching types
59  		for(CluResultInfo cluResult:cluResults){
60  			if(resultTypes.contains(cluResult.getType())){
61  				//Loop through all options and add to the list of Strings
62  				for(ResultOptionInfo resultOption: cluResult.getResultOptions()){
63  					results.add(resultOption.getResultComponentId());
64  				}
65  			}
66  		}
67  		return results;
68  	}
69  
70      public BaseDTOAssemblyNode<?, ?> disassembleCluResults(String cluId,
71  			String cluState, List<String> options, NodeOperation operation, String resultType,
72  			String resultsDescription, String resultDescription) throws AssemblyException {
73  		BaseDTOAssemblyNode<List<String>, CluResultInfo> cluResultNode = new BaseDTOAssemblyNode<List<String>, CluResultInfo>(null);
74  		if(resultType==null){
75  			throw new AssemblyException("resultType can not be null");
76  		}
77  
78  		// Get the current options and put them in a map of option type id/cluResult
79  		Map<String, ResultOptionInfo> currentResults = new HashMap<String, ResultOptionInfo>();
80  
81  		CluResultInfo cluResult = null;
82  
83          //TODO Check this for proper handling of multiple CluResultInfos?  
84  		//If this is not a create, lookup the results for this clu
85  		if (!NodeOperation.CREATE.equals(operation)) {
86  			try {
87  				List<CluResultInfo> cluResultList = luService.getCluResultByClu(cluId);
88  
89  				for (CluResultInfo currentResult : cluResultList) {
90  					if (resultType.equals(currentResult.getType())) {
91  						cluResult = currentResult;
92  						if(NodeOperation.DELETE.equals(operation)){
93  							//if this is a delete, then we only need the CluResultInfo
94  							cluResultNode.setOperation(NodeOperation.DELETE);
95  						}else{
96  							//Find all the Result options and store in a map for easy access later
97  							cluResultNode.setOperation(NodeOperation.UPDATE);
98  							for(ResultOptionInfo resultOption:currentResult.getResultOptions()){
99  								currentResults.put(resultOption.getResultComponentId(), resultOption);
100 							}
101 						}
102 					}
103 				}
104 			} catch (DoesNotExistException e) {
105 			} catch (InvalidParameterException e) {
106 				throw new AssemblyException("Error getting related " + resultsDescription, e);
107 			} catch (MissingParameterException e) {
108 				throw new AssemblyException("Error getting related " + resultsDescription, e);
109 			} catch (OperationFailedException e) {
110 				throw new AssemblyException("Error getting related " + resultsDescription, e);
111 			}
112 		}
113 
114 		//If this is a delete we don't need the result options, just the CluResultInfo
115 		if(!NodeOperation.DELETE.equals(operation)){
116 			if(cluResult == null){
117 				//Create a new resultInfo of the given type if one does not exist and set operation to Create
118 				cluResult = new CluResultInfo();
119 				cluResult.setCluId(cluId);
120 				cluResult.setState(cluState);
121 				cluResult.setType(resultType);
122 				RichTextInfo desc = new RichTextInfo();
123 				desc.setPlain(resultsDescription);
124 				cluResult.setDesc(desc);
125 				cluResult.setEffectiveDate(new Date());
126 				cluResultNode.setOperation(NodeOperation.CREATE);
127 			}
128 
129 			cluResult.setResultOptions(new ArrayList<ResultOptionInfo>());
130 
131 			// Loop through all the credit options in this clu
132 			for (String optionType : options) {
133 				if(currentResults.containsKey(optionType)){
134 					//If the option exists already copy it to the new list of result options
135 					ResultOptionInfo resultOptionInfo = currentResults.get(optionType);
136 					cluResult.getResultOptions().add(resultOptionInfo);
137 				}else{
138 					//Otherwise create a new result option
139 					ResultOptionInfo resultOptionInfo = new ResultOptionInfo();
140 					RichTextInfo desc = new RichTextInfo();
141 					desc.setPlain(resultDescription);
142 					resultOptionInfo.setDesc(desc);
143 					resultOptionInfo.setResultComponentId(optionType);
144 					resultOptionInfo.setState(cluState);
145 
146 					cluResult.getResultOptions().add(resultOptionInfo);
147 				}
148 			}
149 		}
150 
151 		cluResultNode.setNodeData(cluResult);
152 		return cluResultNode;
153 	}
154 
155     public List<LoDisplayInfo> assembleLos(String cluId, boolean shallowBuild) throws AssemblyException {
156         List<LoDisplayInfo> loInfos = new ArrayList<LoDisplayInfo>();
157         try {
158             List<CluLoRelationInfo> cluLoRelations = luService.getCluLoRelationsByClu(cluId);
159             for (CluLoRelationInfo cluLoRelation : cluLoRelations) {
160                 String loId = cluLoRelation.getLoId();
161                 LoInfo lo = loService.getLo(loId);
162                 loInfos.add(loAssembler.assemble(lo, null, shallowBuild));
163             }
164         } catch (Exception e) {
165             throw new AssemblyException("Error getting learning objectives", e);
166         }
167 
168         return loInfos;
169     }
170     
171 	public List<BaseDTOAssemblyNode<?, ?>> disassembleLos(String cluId, String cluState, List<LoDisplayInfo> loInfos,
172 			NodeOperation operation) throws AssemblyException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException{
173 		// TODO Auto-generated method stub
174 		List<BaseDTOAssemblyNode<?, ?>> results = new ArrayList<BaseDTOAssemblyNode<?, ?>>();
175 
176 		// Get the current formats and put them in a map of format id/relation
177 		// id
178 		Map<String, CluLoRelationInfo> currentCluLoRelations = new HashMap<String, CluLoRelationInfo>();
179 		try {
180 			List<CluLoRelationInfo> cluLoRelations = luService.getCluLoRelationsByClu(cluId);
181 			for(CluLoRelationInfo cluLoRelation:cluLoRelations){
182 				if(CluAssemblerConstants.CLU_LO_CLU_SPECIFIC_RELATION.equals(cluLoRelation.getType())){
183 					currentCluLoRelations.put(cluLoRelation.getLoId(), cluLoRelation);
184 				}
185 			}
186 		} catch (DoesNotExistException e) {
187 		} catch (Exception e) {
188 			throw new AssemblyException("Error finding related Los", e);
189 		}
190 
191 		// Loop through all the los in this clu
192 		for(LoDisplayInfo loDisplay : loInfos){
193 
194 			// If this is a clu create/new lo update then all los will be created
195 		    if (NodeOperation.CREATE == operation
196 		            || (NodeOperation.UPDATE == operation &&  !currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId()))) {
197 
198                 // the lo does not exist, so create
199                 // Assemble and add the lo
200 		    	loDisplay.getLoInfo().setId(null);
201                 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
202                         .disassemble(loDisplay, NodeOperation.CREATE);
203                 results.add(loNode);
204 
205                 // Create the relationship and add it as well
206                 CluLoRelationInfo relation = new CluLoRelationInfo();
207                 relation.setCluId(cluId);
208                 relation.setLoId(loNode.getNodeData().getId());
209                 relation.setType(CluAssemblerConstants.CLU_LO_CLU_SPECIFIC_RELATION);
210                 relation.setState(cluState);
211 
212                 BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
213                         null);
214                 relationNode.setNodeData(relation);
215                 relationNode.setOperation(NodeOperation.CREATE);
216 
217                 results.add(relationNode);
218             } else if (NodeOperation.UPDATE == operation
219 					&& currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId())) {
220 				// If the clu already has this lo, then just update the lo
221                 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
222                 		.disassemble(loDisplay, NodeOperation.UPDATE);
223 				results.add(loNode);
224 
225 				// remove this entry from the map so we can tell what needs to
226 				// be deleted at the end
227 				currentCluLoRelations.remove(loDisplay.getLoInfo().getId());
228 			} else if (NodeOperation.DELETE == operation
229                     && currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId())) {
230 
231                 // Delete the Format and its relation
232 				CluLoRelationInfo relationToDelete = currentCluLoRelations.get(loDisplay.getLoInfo().getId());
233                 BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
234                         null);
235                 relationToDeleteNode.setNodeData(relationToDelete);
236                 relationToDeleteNode.setOperation(NodeOperation.DELETE);
237                 results.add(relationToDeleteNode);
238 
239                 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
240         				.disassemble(loDisplay, NodeOperation.DELETE);
241                 results.add(loNode);
242 
243                 // remove this entry from the map so we can tell what needs to
244                 // be deleted at the end
245                 currentCluLoRelations.remove(loDisplay.getLoInfo().getId());
246 			}
247 		}
248 
249         // Now any leftover lo ids are no longer needed, so delete
250         // los and relations
251         for (Entry<String, CluLoRelationInfo> entry : currentCluLoRelations.entrySet()) {
252             // Create a new relation with the id of the relation we want to
253             // delete
254         	CluLoRelationInfo relationToDelete = entry.getValue();
255             BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
256                     null);
257             relationToDeleteNode.setNodeData(relationToDelete);
258             relationToDeleteNode.setOperation(NodeOperation.DELETE);
259             results.add(relationToDeleteNode);
260 
261             LoInfo loToDelete = loService.getLo(entry.getKey());
262             LoDisplayInfo loDisplayToDelete = loAssembler.assemble(loToDelete, null, false);
263             BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
264             		.disassemble(loDisplayToDelete, NodeOperation.DELETE);
265             results.add(loNode);
266         }
267 
268 		return results;
269 	}
270 
271     // Spring setters
272     public void setLuService(LuService luService) {
273         this.luService = luService;
274     }
275 
276     public void setLoService(LearningObjectiveService loService) {
277         this.loService = loService;
278     }
279 
280     public void setLoAssembler(LoAssembler loAssembler) {
281         this.loAssembler = loAssembler;
282     }
283 }