001package org.kuali.student.lum.program.server; 002 003import java.util.ArrayList; 004import java.util.HashMap; 005import java.util.List; 006import java.util.Map; 007 008import org.apache.log4j.Logger; 009import org.kuali.student.common.ui.client.service.DataSaveResult; 010import org.kuali.student.common.ui.server.gwt.DataGwtServlet; 011import org.kuali.student.core.statement.ui.client.widgets.rules.ReqComponentInfoUi; 012import org.kuali.student.core.statement.ui.client.widgets.rules.RulesUtil; 013import org.kuali.student.lum.common.server.StatementUtil; 014import org.kuali.student.lum.program.client.requirements.ProgramRequirementsDataModel; 015import org.kuali.student.lum.program.client.requirements.ProgramRequirementsSummaryView; 016import org.kuali.student.lum.program.client.rpc.MajorDisciplineProposalRpcService; 017import org.kuali.student.r1.common.assembly.data.Data; 018import org.kuali.student.r2.common.dto.RichTextInfo; 019import org.kuali.student.r2.core.search.dto.SearchRequestInfo; 020import org.kuali.student.r2.core.search.dto.SearchResultInfo; 021import org.kuali.student.r2.common.util.ContextUtils; 022import org.kuali.student.r1.core.statement.dto.ReqComponentInfo; 023import org.kuali.student.r1.core.statement.dto.StatementTreeViewInfo; 024import org.kuali.student.r1.core.statement.service.StatementService; 025import org.kuali.student.r2.core.proposal.dto.ProposalInfo; 026import org.kuali.student.r2.core.proposal.service.ProposalService; 027import org.kuali.student.r2.lum.clu.service.CluService; 028import org.kuali.student.r2.lum.program.dto.ProgramRequirementInfo; 029import org.kuali.student.r2.lum.program.service.ProgramService; 030 031public class MajorDisciplineProposalRpcServlet extends DataGwtServlet implements MajorDisciplineProposalRpcService { 032 033 public static final String PREVIOUS_VERSION_INFO = "previousVersionInfo"; 034 035 final Logger LOG = Logger.getLogger(MajorDisciplineProposalRpcServlet.class); 036 037 private static final long serialVersionUID = 1L; 038 039 private ProgramService programService; 040 private StatementService statementService; 041 protected StateChangeService stateChangeService; 042 private ProposalService proposalService; 043 private CluService cluService; 044 045 /** 046 * 047 * This method will update the state of a major discipline. 048 * 049 * @see org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService#updateStatus(org.kuali.student.common.assembly.data.Data, 050 * java.lang.String) 051 */ 052 public DataSaveResult updateState(Data data, String state) throws Exception { 053 throw new UnsupportedOperationException("Proposals can not update state explicitly"); 054 } 055 056 public List<ProgramRequirementInfo> getProgramRequirements(List<String> programRequirementIds) throws Exception { 057 058 List<ProgramRequirementInfo> programReqInfos = new ArrayList<ProgramRequirementInfo>(); 059 try 060 { 061 062 for (String programReqId : programRequirementIds) { 063 ProgramRequirementInfo rule = null; 064 rule = programService.getProgramRequirement(programReqId, ContextUtils.getContextInfo()); 065 setProgReqNL(rule); 066 programReqInfos.add(rule); 067 } 068 069 return programReqInfos; 070 } catch (Exception ex) { 071 // Log exception 072 ex.printStackTrace(); 073 throw new RuntimeException(ex); 074 } 075 } 076 077 public Map<Integer, ProgramRequirementInfo> storeProgramRequirements( 078 Map<Integer, ProgramRequirementsDataModel.requirementState> states, 079 Map<Integer, ProgramRequirementInfo> progReqs) throws Exception { 080 Map<Integer, ProgramRequirementInfo> storedRules = new HashMap<Integer, ProgramRequirementInfo>(); 081 try 082 { 083 for (Integer key : progReqs.keySet()) { 084 ProgramRequirementInfo rule = progReqs.get(key); 085 switch (states.get(key)) { 086 case STORED: 087 //rule was not changed so continue 088 storedRules.put(key, null); 089 break; 090 case ADDED: 091 storedRules.put(key, createProgramRequirement(rule)); 092 break; 093 case EDITED: 094 storedRules.put(key, updateProgramRequirement(rule)); 095 break; 096 case DELETED: 097 storedRules.put(key, null); 098 deleteProgramRequirement(rule.getId()); 099 break; 100 default: 101 break; 102 } 103 } 104 return storedRules; 105 } catch (Exception ex) { 106 // Log exception 107 ex.printStackTrace(); 108 throw new RuntimeException(ex); 109 } 110 } 111 112 public ProgramRequirementInfo createProgramRequirement(ProgramRequirementInfo programRequirementInfo) 113 throws Exception { 114 try { 115 116 // If this requirement is using a temporary statement ID set the state to null 117 if (programRequirementInfo.getId().indexOf(ProgramRequirementsSummaryView.NEW_PROG_REQ_ID) >= 0) { 118 programRequirementInfo.setId(null); 119 } 120 121 // Strip the temporary statement IDs and allow permanent IDs to be created when written to the web service 122 StatementUtil.stripStatementIds(programRequirementInfo.getStatement()); 123 124 // Update the state of the statement tree to match the state of the requirement 125 // Note: the requirement state already matches the program state (e.g. Draft, Approved, etc) 126 StatementUtil.updateStatementTreeViewInfoState(programRequirementInfo.getStateKey(), 127 programRequirementInfo.getStatement()); 128 129 // Call the web service to create the requirement and statement tree in the database 130 ProgramRequirementInfo rule = programService.createProgramRequirement(programRequirementInfo.getTypeKey(), 131 programRequirementInfo, ContextUtils.getContextInfo()); 132 133 // Translate the requirement into its natural language equivalent 134 setProgReqNL(rule); 135 136 return rule; 137 } catch (Exception ex) { 138 // Log exception 139 ex.printStackTrace(); 140 throw new RuntimeException(ex); 141 } 142 } 143 144 public org.kuali.student.r2.common.dto.StatusInfo deleteProgramRequirement(String programRequirementId) 145 throws Exception { 146 try{ 147 return programService.deleteProgramRequirement(programRequirementId, ContextUtils.getContextInfo()); 148 } 149 catch(Exception ex){ 150 // Log exception 151 ex.printStackTrace(); 152 throw new RuntimeException(ex); 153 } 154 } 155 156 public ProgramRequirementInfo updateProgramRequirement(ProgramRequirementInfo programRequirementInfo) 157 throws Exception { 158 try { 159 // Strip the temporary statement IDs and allow permanent IDs to be created when written to the web service 160 StatementUtil.stripStatementIds(programRequirementInfo.getStatement()); 161 162 // Update the state of the statement tree to match the state of the requirement 163 // Note: the requirement state already matches the program state (e.g. Draft, Approved, etc) 164 StatementUtil.updateStatementTreeViewInfoState(programRequirementInfo.getStateKey(), 165 programRequirementInfo.getStatement()); 166 167 //TODO temporary fix - see KSLUM 1421 168 if (programRequirementInfo.getDescr() == null) { 169 programRequirementInfo.setDescr(new RichTextInfo()); 170 } 171 172 ProgramRequirementInfo rule = programService.updateProgramRequirement(null, null, programRequirementInfo, 173 ContextUtils.getContextInfo()); 174 setProgReqNL(rule); 175 return rule; 176 } catch (Exception ex) { 177 // Log exception 178 ex.printStackTrace(); 179 throw new RuntimeException(ex); 180 } 181 } 182 183 private void setProgReqNL(ProgramRequirementInfo programRequirementInfo) throws Exception { 184 setReqCompNL(programRequirementInfo.getStatement()); 185 } 186 187 private void setReqCompNL(StatementTreeViewInfo tree) throws Exception { 188 List<StatementTreeViewInfo> statements = tree.getStatements(); 189 List<ReqComponentInfo> reqComponentInfos = tree.getReqComponents(); 190 191 if ((statements != null) && (statements.size() > 0)) { 192 // retrieve all statements 193 for (StatementTreeViewInfo statement : statements) { 194 setReqCompNL(statement); // inside set the children of this statementTreeViewInfo 195 } 196 } else if ((reqComponentInfos != null) && (reqComponentInfos.size() > 0)) { 197 // retrieve all req. component LEAFS 198 for (int i = 0; i < reqComponentInfos.size(); i++) { 199 ReqComponentInfoUi reqUi = null; 200 reqUi = RulesUtil.clone(reqComponentInfos.get(i)); 201 reqUi.setNaturalLanguageTranslation(statementService.translateReqComponentToNL(reqUi, "KUALI.RULE", 202 "en")); 203 reqUi.setPreviewNaturalLanguageTranslation(statementService.translateReqComponentToNL(reqUi, 204 "KUALI.RULE.PREVIEW", "en")); 205 reqComponentInfos.set(i, reqUi); 206 } 207 } 208 } 209 210 @Override 211 public Boolean isLatestVersion(String versionIndId, Long versionSequenceNumber) throws Exception { 212 //Perform a search to see if there are any new versions of the course that are approved, draft, etc. 213 //We don't want to version if there are 214 try { 215 SearchRequestInfo request = new SearchRequestInfo("lu.search.isVersionable"); 216 request.addParam("lu.queryParam.versionIndId", versionIndId); 217 request.addParam("lu.queryParam.sequenceNumber", versionSequenceNumber.toString()); 218 List<String> states = new ArrayList<String>(); 219 states.add("Approved"); 220 states.add("Active"); 221 states.add("Draft"); 222 states.add("Superseded"); 223 request.addParam("lu.queryParam.luOptionalState", states); 224 SearchResultInfo result = cluService.search(request, ContextUtils.getContextInfo()); 225 226 String resultString = result.getRows().get(0).getCells().get(0).getValue(); 227 return "0".equals(resultString); 228 } catch (Exception e) { 229 LOG.error("IS LATEST VERSION ERROR"); 230 return false; 231 } 232 233 } 234 235 public void setProgramService(ProgramService programService) { 236 this.programService = programService; 237 } 238 239 public void setStatementService(StatementService statementService) { 240 this.statementService = statementService; 241 } 242 243 public void setStateChangeService(StateChangeService stateChangeService) { 244 this.stateChangeService = stateChangeService; 245 } 246 247 /** 248 * 249 * This method will check to see if an object with the given reference ID is a 250 * proposal. 251 * <p> 252 * At the moment, it is used by the UI to decide if we should hide the action box when 253 * opening a draft proposal. 254 * 255 * @see org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService#isProposal(java.lang.String, 256 * java.lang.String) 257 */ 258 @Override 259 public Boolean isProposal(String referenceTypeKey, String referenceId) { 260 try { 261 // Wire in proposal service from spring 262 // Call method getProposalByReference(). 263 // ProposalWorkflowFilter.applyOutboundDataFilter(). Set on line 130-131. Use these for reference ID. 264 265 // Ask the proposal service to return a list of proposals with this reference id 266 List<ProposalInfo> proposals = proposalService.getProposalsByReference(referenceTypeKey, referenceId, ContextUtils.getContextInfo()); 267 268 // If at least one proposal is returned, this is a proposal, so return true 269 if (proposals != null && proposals.size() >= 1) { 270 return Boolean.TRUE; 271 } 272 273 // This was not a proposal, so return false 274 return Boolean.FALSE; 275 } catch (Exception ex) { 276 // Log exception 277 ex.printStackTrace(); 278 throw new RuntimeException(ex); 279 } 280 } 281 282 /** 283 * 284 * Proposal service is injected by spring in the lum-gwt-context.xml file 285 * 286 * @return 287 */ 288 public ProposalService getProposalService() { 289 return proposalService; 290 } 291 292 public void setProposalService(ProposalService proposalService) { 293 this.proposalService = proposalService; 294 } 295 296 public void setCluService(CluService cluService) { 297 this.cluService = cluService; 298 } 299 300}