View Javadoc

1   /**
2    *
3    */
4   package org.kuali.student.r2.lum.program.service.impl;
5   
6   import static org.apache.commons.collections.CollectionUtils.isEmpty;
7   import static org.apache.commons.lang.StringUtils.isEmpty;
8   
9   import java.util.ArrayList;
10  import java.util.List;
11  
12  import org.apache.log4j.Logger;
13  import org.kuali.student.common.conversion.util.R1R2ConverterUtil;
14  import org.kuali.student.common.util.UUIDHelper;
15  import org.kuali.student.r2.lum.course.service.assembler.LoAssembler;
16  import org.kuali.student.r2.lum.program.service.assembler.ProgramAssemblerConstants;
17  import org.kuali.student.r2.lum.program.service.assembler.ProgramAssemblerUtils;
18  import org.kuali.student.r2.lum.service.assembler.CluAssemblerUtils;
19  import org.kuali.student.r1.common.assembly.BOAssembler;
20  import org.kuali.student.r1.common.assembly.BaseDTOAssemblyNode;
21  import org.kuali.student.r1.common.assembly.BaseDTOAssemblyNode.NodeOperation;
22  import org.kuali.student.r2.common.dto.DtoConstants;
23  import org.kuali.student.r1.core.statement.dto.RefStatementRelationInfo;
24  import org.kuali.student.r1.core.statement.dto.StatementTreeViewInfo;
25  import org.kuali.student.r1.core.statement.service.StatementService;
26  import org.kuali.student.r1.core.statement.service.assembler.StatementTreeViewAssembler;
27  import org.kuali.student.r2.common.assembler.AssemblyException;
28  import org.kuali.student.r2.common.dto.AttributeInfo;
29  import org.kuali.student.r2.common.dto.ContextInfo;
30  import org.kuali.student.r2.common.exceptions.DoesNotExistException;
31  import org.kuali.student.r2.lum.clu.dto.CluCluRelationInfo;
32  import org.kuali.student.r2.lum.clu.dto.CluIdentifierInfo;
33  import org.kuali.student.r2.lum.clu.dto.CluInfo;
34  import org.kuali.student.r2.lum.clu.service.CluService;
35  import org.kuali.student.r2.lum.lo.service.LearningObjectiveService;
36  import org.kuali.student.r2.lum.program.dto.ProgramRequirementInfo;
37  import org.kuali.student.r2.lum.program.service.assembler.ProgramAssemblerUtils;
38  
39  
40  /**
41   * @author glindholm
42   *
43   */
44  public class ProgramRequirementAssembler implements BOAssembler<ProgramRequirementInfo, CluInfo> {
45      final static Logger LOG = Logger.getLogger(ProgramRequirementAssembler.class);
46  
47  	private StatementService statementService;
48  	private StatementTreeViewAssembler statementTreeViewAssembler;
49  	private LearningObjectiveService loService;
50  	private CluService cluService;
51  	private LoAssembler loAssembler;
52  	private CluAssemblerUtils cluAssemblerUtils;
53      private ProgramAssemblerUtils programAssemblerUtils;
54  
55  
56  	@Override
57  	public ProgramRequirementInfo assemble(CluInfo clu,
58  			ProgramRequirementInfo progReqInfo, boolean shallowBuild,ContextInfo contextInfo)
59  			throws AssemblyException {
60  		ProgramRequirementInfo progReq = (progReqInfo != null ? progReqInfo : new ProgramRequirementInfo());
61  
62  		if (clu.getOfficialIdentifier() != null) {
63  			progReq.setShortTitle(clu.getOfficialIdentifier().getShortName());
64  			progReq.setLongTitle(clu.getOfficialIdentifier().getLongName());
65  		}
66  		progReq.setDescr(clu.getDescr());
67  
68  		//assembling minCredits & maxCredits
69  		assembleCredits(clu, progReq);
70  
71  		if (progReq.getStatement() == null) {
72  			try {
73  				List<RefStatementRelationInfo> relations = statementService.getRefStatementRelationsByRef(ProgramAssemblerConstants.PROGRAM_REQUIREMENT, clu.getId());
74  				StatementTreeViewInfo statementTree = new StatementTreeViewInfo();
75  				if (relations != null) {
76  					statementTreeViewAssembler.assemble(statementService.getStatementTreeView(relations.get(0).getStatementId()), statementTree, shallowBuild, contextInfo);
77  				}
78  				progReq.setStatement(statementTree);
79  				} catch (AssemblyException e) {
80  				throw e;
81  			} catch (Exception e) {
82  				throw new AssemblyException(e);
83  			}
84  		}
85  
86  		if (isEmpty(progReq.getLearningObjectives())) {
87  			 progReq.setLearningObjectives(cluAssemblerUtils.assembleLos(clu.getId(), shallowBuild,contextInfo)); 
88  		}
89  
90  		progReq.setMeta(clu.getMeta());
91  		progReq.setTypeKey(clu.getTypeKey());
92  		progReq.setAttributes(clu.getAttributes());
93  		progReq.setId(clu.getId());
94  
95  		return progReq;
96  	}
97  
98  	@Override
99  	public BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> disassemble(
100 			ProgramRequirementInfo progReq, NodeOperation operation,ContextInfo contextInfo)
101 			throws AssemblyException {
102 
103 		if (progReq == null) {
104 			// FIXME Unsure now if this is an exception or just return null or
105 			// empty assemblyNode
106 		    LOG.error("ProgramRequirementInfo to disassemble is null!");
107 			throw new AssemblyException("ProgramRequirementInfo can not be null");
108 		}
109 
110 		BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> result = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo>(null);
111 		
112 		// Create the Statement Tree
113         StatementTreeViewInfo statement = progReq.getStatement();
114         statement.setId(UUIDHelper.genStringUUID(statement.getId()));
115         BaseDTOAssemblyNode<StatementTreeViewInfo, StatementTreeViewInfo> statementTree;
116 		try {
117 			statementTree = statementTreeViewAssembler.disassemble(statement, operation,contextInfo);
118 		} catch (AssemblyException e) {
119 			throw e;
120 		} catch (Exception e) {
121 			throw new AssemblyException(e);
122 		}
123         result.getChildNodes().add(statementTree);
124 
125 		CluInfo clu;
126 		try {
127 			clu = (NodeOperation.UPDATE == operation) ?  cluService.getClu(progReq.getId(), contextInfo) : new CluInfo();
128         } catch (Exception e) {
129 			throw new AssemblyException("Error getting existing learning unit during program requirement update", e);
130         }
131 
132         if (operation.equals(NodeOperation.DELETE)) {
133             try {
134 				final List<CluCluRelationInfo> relations = cluService.getCluCluRelationsByClu(progReq.getId(), contextInfo);
135 	            final BaseDTOAssemblyNode<ProgramRequirementInfo, CluCluRelationInfo> cluRelation = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluCluRelationInfo>(null);
136 	            if (relations.size() > 1) {
137 	            	throw new AssemblyException("Unable to dissamble ProgramRequirement, more than one CluCluRelation found");
138 	            } else if (relations.size() == 1) {
139 	            	cluRelation.setNodeData(relations.get(0));
140 	            	cluRelation.setOperation(operation);
141 	            	result.getChildNodes().add(cluRelation);
142 	            }
143 			} catch (Exception e) {
144 				throw new AssemblyException(e);
145 			}
146         }
147 
148         BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> cluResult = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo>(this);
149 
150         cluResult.setNodeData(clu);
151         cluResult.setBusinessDTORef(progReq);
152         cluResult.setOperation(operation);
153         result.getChildNodes().add(cluResult);
154 
155         clu.setTypeKey(progReq.getTypeKey());
156         clu.setId(UUIDHelper.genStringUUID(progReq.getId()));
157         
158         // Default 
159         clu.setStateKey(progReq.getStateKey());
160         clu.setMeta(progReq.getMeta());
161         clu.setAttributes(progReq.getAttributes());
162         clu.setIsEnrollable(false);
163 
164 		//disassembling minCredits & maxCredits
165         disassembleCredits(clu, progReq,contextInfo);
166 
167         progReq.setId(clu.getId());
168         CluIdentifierInfo official = null != clu.getOfficialIdentifier() ? clu.getOfficialIdentifier() : new CluIdentifierInfo();
169         official.setLongName(progReq.getLongTitle());
170         official.setShortName(progReq.getShortTitle());
171         
172         // We decided not to do null checks in the disassembler.  Instead we will just 
173         // set state to whatever is passed into the method (I missed this change when working on 1834)      
174         official.setStateKey(progReq.getStateKey());
175         
176         // gotta be this type
177         official.setTypeKey(ProgramAssemblerConstants.OFFICIAL);
178         clu.setOfficialIdentifier(official);
179 
180         clu.setDescr(progReq.getDescr());
181         if (progReq.getLearningObjectives() != null) {
182             disassembleLearningObjectives(progReq, operation, result,contextInfo);
183         }
184 
185         RefStatementRelationInfo relation;
186         if (operation == NodeOperation.CREATE) {
187             relation = new RefStatementRelationInfo();
188             relation.setId(UUIDHelper.genStringUUID(null));
189         } else {
190         	try {
191         		relation = statementService.getRefStatementRelationsByRef(ProgramAssemblerConstants.PROGRAM_REQUIREMENT, clu.getId()).get(0);
192 			} catch (Exception e) {
193 				throw new AssemblyException("Unable to find RefStatementRelation", e);
194 			}
195         }
196         relation.setType("clu.prerequisites"); // FIXME Derive from statement and rule types
197         relation.setType(ProgramAssemblerConstants.PROGRAM_REFERENCE_TYPE);
198         relation.setRefObjectId(clu.getId());
199         relation.setRefObjectTypeKey(ProgramAssemblerConstants.PROGRAM_REQUIREMENT);
200         relation.setStatementId(statement.getId());
201         // Relations can be either Active or Suspended
202         // For now, we always use Active (never use draft, etc for relations)
203         relation.setState(DtoConstants.STATE_ACTIVE);
204 
205         BaseDTOAssemblyNode<ProgramRequirementInfo, RefStatementRelationInfo> relationNode = new BaseDTOAssemblyNode<ProgramRequirementInfo, RefStatementRelationInfo>(null);
206         relationNode.setNodeData(relation);
207         relationNode.setOperation(operation);
208 
209         result.getChildNodes().add(relationNode);
210         result.setBusinessDTORef(progReq);
211         result.setOperation(operation);
212 		return result;
213 	}
214 
215 	private void disassembleLearningObjectives(ProgramRequirementInfo progReq,
216 			NodeOperation operation,
217 			BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> result,ContextInfo contextInfo) throws AssemblyException {
218 		try {
219         	
220              List<BaseDTOAssemblyNode<?, ?>> loResults = cluAssemblerUtils.disassembleLos(progReq.getId(), progReq.getStateKey(),  progReq.getLearningObjectives(), operation,contextInfo);
221             if (loResults != null) {
222                 result.getChildNodes().addAll(loResults);
223             }
224         } catch (DoesNotExistException e) {
225         } catch (Exception e) {
226             throw new AssemblyException("Error while disassembling los", e);
227         }
228 	}
229 
230 	private void disassembleCredits(CluInfo clu, ProgramRequirementInfo progReq,ContextInfo contextInfo){
231         List<AttributeInfo> attributes = null != clu.getAttributes() ? clu.getAttributes() : new ArrayList<AttributeInfo>();
232 
233 		if(progReq.getMinCredits() != null){
234             attributes.add(new AttributeInfo(ProgramAssemblerConstants.MIN_CREDITS, Integer.toString(progReq.getMinCredits())));
235 		}else{
236             attributes.add(new AttributeInfo(ProgramAssemblerConstants.MIN_CREDITS, null));
237 		}
238 		if(progReq.getMaxCredits() != null) {
239             attributes.add(new AttributeInfo(ProgramAssemblerConstants.MAX_CREDITS, Integer.toString(progReq.getMaxCredits())));
240 		}else{
241             attributes.add(new AttributeInfo(ProgramAssemblerConstants.MAX_CREDITS, null));
242 		}
243 			
244 		clu.setAttributes(attributes);
245 	}
246 
247 	private void assembleCredits(CluInfo clu, ProgramRequirementInfo progReq){
248         if (clu.getAttributes() != null) {
249             for (AttributeInfo attribute : clu.getAttributes()) {
250                 if (attribute.getKey().equals(ProgramAssemblerConstants.MIN_CREDITS)) {
251                     String minCredits = attribute.getValue();
252                     progReq.setMinCredits(isEmpty(minCredits)?null:Integer.parseInt(minCredits));
253                 }
254                 if (attribute.getKey().equals(ProgramAssemblerConstants.MAX_CREDITS)) {
255                     String maxCredits = attribute.getValue();
256                     progReq.setMaxCredits(isEmpty(maxCredits)?null:Integer.parseInt(maxCredits));
257                 }
258             }
259         }
260     }
261 
262 	public StatementTreeViewAssembler getStatementTreeViewAssembler() {
263 		return statementTreeViewAssembler;
264 	}
265 
266 	public void setStatementTreeViewAssembler(
267 			StatementTreeViewAssembler statementTreeViewAssembler) {
268 		this.statementTreeViewAssembler = statementTreeViewAssembler;
269 	}
270 
271 	public StatementService getStatementService() {
272 		return statementService;
273 	}
274 
275 	public void setStatementService(StatementService statementService) {
276 		this.statementService = statementService;
277 	}
278 
279 	public LearningObjectiveService getLoService() {
280 		return loService;
281 	}
282 
283 	public void setLoService(LearningObjectiveService loService) {
284 		this.loService = loService;
285 	}
286 
287 	public CluService getCluService() {
288 		return cluService;
289 	}
290 
291 	public void setCluService(CluService cluService) {
292 		this.cluService = cluService;
293 	}
294 
295 	public LoAssembler getLoAssembler() {
296 		return loAssembler;
297 	}
298 
299 	public void setLoAssembler(LoAssembler loAssembler) {
300 		this.loAssembler = loAssembler;
301 	}
302 
303 	public CluAssemblerUtils getCluAssemblerUtils() {
304 		return cluAssemblerUtils;
305 	}
306 
307 	public void setCluAssemblerUtils(CluAssemblerUtils cluAssemblerUtils) {
308 		this.cluAssemblerUtils = cluAssemblerUtils;
309 	}
310 
311 	public ProgramAssemblerUtils getProgramAssemblerUtils() {
312 		return programAssemblerUtils;
313 	}
314 
315 	public void setProgramAssemblerUtils(ProgramAssemblerUtils programAssemblerUtils) {
316 		this.programAssemblerUtils = programAssemblerUtils;
317 	}
318 	
319 }