View Javadoc

1   package org.kuali.student.lum.lu.ui.course.client.controllers;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.kuali.student.common.ui.client.application.Application;
7   import org.kuali.student.common.ui.client.application.KSAsyncCallback;
8   import org.kuali.student.common.ui.client.configurable.mvc.layouts.BasicLayoutWithContentHeader;
9   import org.kuali.student.common.ui.client.configurable.mvc.sections.HorizontalSection;
10  import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
11  import org.kuali.student.common.ui.client.mvc.Callback;
12  import org.kuali.student.common.ui.client.mvc.Controller;
13  import org.kuali.student.common.ui.client.mvc.DataModel;
14  import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
15  import org.kuali.student.common.ui.client.mvc.ModelProvider;
16  import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
17  import org.kuali.student.common.ui.client.widgets.KSButton;
18  import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
19  import org.kuali.student.common.ui.client.widgets.KSLabel;
20  import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
21  import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
22  import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
23  import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
24  import org.kuali.student.lum.common.client.lu.LUUIConstants;
25  import org.kuali.student.lum.lu.ui.course.client.configuration.CourseSummaryConfigurer;
26  import org.kuali.student.lum.lu.ui.course.client.requirements.CourseRequirementsDataModel;
27  import org.kuali.student.lum.lu.ui.course.client.requirements.HasRequirements;
28  import org.kuali.student.lum.lu.ui.course.client.service.CourseRpcService;
29  import org.kuali.student.lum.lu.ui.course.client.service.CourseRpcServiceAsync;
30  import org.kuali.student.lum.lu.ui.course.client.views.SelectVersionsView;
31  import org.kuali.student.lum.lu.ui.course.client.views.ShowVersionView;
32  import org.kuali.student.lum.lu.ui.course.client.widgets.CourseWorkflowActionList;
33  import org.kuali.student.r1.common.assembly.data.Data;
34  import org.kuali.student.r1.common.assembly.data.Metadata;
35  import org.kuali.student.r2.common.dto.DtoConstants;
36  import org.kuali.student.r1.core.statement.dto.StatementTypeInfo;
37  
38  import com.google.gwt.core.client.GWT;
39  import com.google.gwt.event.dom.client.ClickEvent;
40  import com.google.gwt.event.dom.client.ClickHandler;
41  import com.google.gwt.user.client.Window;
42  import com.google.gwt.user.client.ui.Widget;
43  
44  public class VersionsController extends BasicLayoutWithContentHeader implements HasRequirements{
45  	
46  	public static enum Views{VERSION_SELECT, VERSION_VIEW, VERSION_COMPARE}
47  	
48  	private SelectVersionsView select = new SelectVersionsView(this, "", Views.VERSION_SELECT);
49  	private ShowVersionView view;
50  	private VerticalSectionView compare;
51      private static final String MSG_GROUP = "course";
52      private String type = "course";
53      private String state = DtoConstants.STATE_DRAFT;
54      private String groupName = LUUIConstants.COURSE_GROUP_NAME;
55  	CourseSummaryConfigurer summaryConfigurer;
56  	CourseRpcServiceAsync rpcServiceAsync = GWT.create(CourseRpcService.class);
57  	DataModelDefinition definition;
58  	
59  	private DataModel cluModel1;
60  	private DataModel cluModel2;
61  	
62  	private String lastId1 = "";
63  	private String lastId2 = "";
64  	private HorizontalSection workflowVersionInfoSection = new HorizontalSection();
65  	
66      private final CourseRequirementsDataModel reqDataModel1;
67      private final CourseRequirementsDataModel reqDataModel2;
68  	
69  	private boolean initialized = false;
70  	private String versionIndId = "";
71  	private String currentVersionId = "";
72  	private final BlockingTask loadDataTask = new BlockingTask("Retrieving Data....");
73  	
74  	private List<CourseWorkflowActionList> actionDropDownWidgets = new ArrayList<CourseWorkflowActionList>();
75  	private KSLabel statusLabel = new KSLabel("");
76  	
77  	public VersionsController(Enum<?> viewType) {
78  		super(VersionsController.class.toString());
79  		this.addView(select);
80          this.setDefaultView(Views.VERSION_SELECT);
81          this.setName("Versions");
82          this.setViewEnum(viewType);
83          KSButton versionHistoryButton = new KSButton("Version History", ButtonStyle.DEFAULT_ANCHOR, new ClickHandler(){
84  
85      		@Override
86      		public void onClick(ClickEvent event) {
87      			VersionsController.this.showDefaultView(Controller.NO_OP_CALLBACK);
88      		}
89      	});
90          versionHistoryButton.addStyleName("versionHistoryLink");
91  
92          reqDataModel1 = new CourseRequirementsDataModel(this);
93          reqDataModel2 = new CourseRequirementsDataModel(this);
94  
95          workflowVersionInfoSection.addWidget(this.getStatusLabel());
96          workflowVersionInfoSection.addWidget(this.generateActionDropDown());
97          workflowVersionInfoSection.addWidget(versionHistoryButton);
98  		
99          this.getHeader().addWidget(workflowVersionInfoSection);
100         this.viewContainer.addStyleName("standard-content-padding");
101         initialize();
102     }	
103 
104 	public void setVersionIndId(String versionIndId) {
105 		this.versionIndId = versionIndId;
106 	}
107 	
108 	private void initialize() {
109         super.setDefaultModelId("Model");
110         super.registerModel("Model", new ModelProvider<DataModel>() {
111 
112             @Override
113             public void requestModel(final ModelRequestCallback<DataModel> callback) {
114                 if(getViewContext().getId() != null && !getViewContext().getId().isEmpty()){
115             		getCourseFromCluId(getViewContext().getId(), 1, callback, true);
116                 }
117                 else{
118                 	callback.onModelReady(null);
119                 }
120             }
121         });
122         
123         super.registerModel("ComparisonModel", new ModelProvider<DataModel>() {
124             @Override
125             public void requestModel(final ModelRequestCallback<DataModel> callback) {
126             	if(getViewContext().getAttribute("docId2") != null && !getViewContext().getAttribute("docId2").isEmpty()){
127             		getCourseFromCluId(getViewContext().getAttribute("docId2"), 2, callback, false);	
128             	}
129             	else{
130             		callback.onModelReady(null);
131             	}
132             }
133         });
134 	}
135 	 
136 	@SuppressWarnings("unchecked")    
137 	private void getCourseFromCluId(final String courseId, final int modelNum, final ModelRequestCallback callback, final boolean id1Model){
138 		KSBlockingProgressIndicator.addTask(loadDataTask);
139 	
140 	    rpcServiceAsync.getData(courseId, new KSAsyncCallback<Data>(){
141 	
142 	        @Override
143 	        public void handleFailure(Throwable caught) {
144 	            Window.alert("Error loading Course: "+caught.getMessage());
145 	            callback.onRequestFail(caught);
146 	            KSBlockingProgressIndicator.removeTask(loadDataTask);
147 	        }
148 	
149 	        @Override
150 	        public void onSuccess(Data result) {
151 	        	if(modelNum == 1){
152 	        		cluModel1 = new DataModel();
153 	        		cluModel1.setDefinition(definition);
154 	        		cluModel1.setRoot(result);
155 	        		if(courseId.equals(currentVersionId)){
156 	        			String name = "Version " + cluModel1.get("version/sequenceNumber") + " (current version)";
157 	        			cluModel1.setModelName(name);
158 	        			view.setName(name);
159 	        			view.showWarningMessage(false);
160 	        		}
161 	        		else{
162 	        			String name = "Version " + cluModel1.get("version/sequenceNumber");
163 	        			cluModel1.setModelName(name);
164 	        			view.setName(name);
165 	        			view.showWarningMessage(true);
166 	        		}
167 	        		updateState(cluModel1);
168 
169 	 	            reqDataModel1.retrieveStatementTypes(cluModel1.<String>get("id"), new Callback<Boolean>() {
170 	                    @Override
171 	                    public void exec(Boolean result) {
172 	                        if (result) {
173 	                            KSBlockingProgressIndicator.removeTask(loadDataTask);
174 	        	 	            callback.onModelReady(cluModel1);
175 	                        }
176 	                    }
177 	                }); 
178 	        	}
179 	        	else{
180 	        		cluModel2 = new DataModel();
181 	        		cluModel2.setDefinition(definition);
182 	        		cluModel2.setRoot(result);
183 	        		if(courseId.equals(currentVersionId)){
184 	        			cluModel2.setModelName("Version " + cluModel2.get("version/sequenceNumber") + " (current version)");
185 	        		}
186 	        		else{
187 	        			cluModel2.setModelName("Version " + cluModel2.get("version/sequenceNumber"));
188 	        		}
189 
190 	 	            reqDataModel2.retrieveStatementTypes(cluModel2.<String>get("id"), new Callback<Boolean>() {
191 	                    @Override
192 	                    public void exec(Boolean result) {
193 	                        if (result) {
194 	                            KSBlockingProgressIndicator.removeTask(loadDataTask);
195 	        	 	            callback.onModelReady(cluModel2);
196 	                        }
197 	                    }
198 	                });
199 	        	}	            
200 	        }	
201 	    });
202 	}
203 	
204     @Override
205     public void showDefaultView(final Callback<Boolean> onReadyCallback) {
206     	KSBlockingProgressIndicator.addTask(loadDataTask);
207     	
208         init(new Callback<Boolean>() {
209 
210             @Override
211             public void exec(Boolean result) {
212                 if (result) {
213                 	VersionsController.super.showDefaultView(new Callback<Boolean>() {
214                 		
215                 		@Override
216                 		public void exec(Boolean result) {
217                 			onReadyCallback.exec(result);
218                 			KSBlockingProgressIndicator.removeTask(loadDataTask);
219                 		}
220                 	});
221                 } else {
222                     onReadyCallback.exec(false);
223                     KSBlockingProgressIndicator.removeTask(loadDataTask);
224                 }
225                 
226             }
227         });
228     }
229     
230     @Override
231     public void beforeShow(Callback<Boolean> onReadyCallback) {
232     	workflowVersionInfoSection.setVisible(false);
233     	this.getHeader().showPrint(false);
234     	this.getHeader().showExport(false);
235     	showDefaultView(onReadyCallback);
236     }
237     
238     private void init(final Callback<Boolean> onReadyCallback) {
239 
240         KSBlockingProgressIndicator.addTask(loadDataTask);
241 
242         rpcServiceAsync.getMetadata("", null, new KSAsyncCallback<Metadata>() {
243 
244             public void handleFailure(Throwable caught) {
245                 initialized = false;
246                 onReadyCallback.exec(false);
247                 KSBlockingProgressIndicator.removeTask(loadDataTask);
248                 throw new RuntimeException("Failed to get model definition.", caught);
249             }
250 
251             public void onSuccess(Metadata result) {
252                 definition = new DataModelDefinition(result);
253                 KSBlockingProgressIndicator.removeTask(loadDataTask);
254                 configureScreens(onReadyCallback);
255             }
256         });
257 
258     }
259 
260     private void configureScreens(final Callback<Boolean> onReadyCallback) {
261         CourseRequirementsDataModel.getStatementTypes(new Callback<List<StatementTypeInfo>>() {
262 
263             @Override
264             public void exec(List<StatementTypeInfo> stmtTypes) {
265                 List<StatementTypeInfo> stmtTypesOut = new ArrayList<StatementTypeInfo>();
266                 if (stmtTypes != null) {
267                     for (StatementTypeInfo stmtType : stmtTypes) {
268                         if (stmtType.getId().contains("kuali.statement.type.course.enrollmentEligibility") ||
269                             stmtType.getId().contains("kuali.statement.type.course.creditConstraints")) {
270                             continue;
271                         }
272                         stmtTypesOut.add(stmtType);
273                     }
274                 }
275 
276                 summaryConfigurer = GWT.create(CourseSummaryConfigurer.class);
277                 summaryConfigurer.init(type, state, groupName, definition, stmtTypesOut, VersionsController.this, "Model");
278                 view = new ShowVersionView(Views.VERSION_VIEW, "Version", "Model", VersionsController.this, stmtTypesOut);
279                 compare = summaryConfigurer.generateCourseSummarySection();
280                 compare.setLayoutController(VersionsController.this);
281                 compare.setSectionTitle("Compare Versions");
282                 compare.setName("Compare Versions");
283                 compare.setViewEnum(Views.VERSION_COMPARE);
284                 VersionsController.this.addView(view);
285                 VersionsController.this.addView(compare);
286                 initialized = true;
287                 onReadyCallback.exec(true);
288             }
289         });
290     }
291     
292     public Widget generateActionDropDown(){
293     	CourseWorkflowActionList actionList = GWT.create(CourseWorkflowActionList.class);
294     	actionList.initialise(this.getMessage("cluActionsLabel"));
295     	actionDropDownWidgets.add(actionList);
296         
297     	return actionList;
298     }
299     
300     private void updateState(final DataModel cluModel) {
301     	if(cluModel.get("stateKey") != null){
302             statusLabel.setText(getMessage("courseStatusLabel") + ": " + cluModel.get("stateKey"));
303 	    	
304 	    	for(CourseWorkflowActionList widget: actionDropDownWidgets){
305 				widget.init(getViewContext(), "/HOME/CURRICULUM_HOME/COURSE_PROPOSAL", cluModel, new Callback<String>() {
306 					@Override
307 			        public void exec(String newState) {
308 			            if (newState != null) {
309 			                KSNotifier.add(new KSNotification(getMessage("cluStateChangeNotification" + newState), false, 5000));
310 			                // FIXME: this is not updating the cluModel so state will not be updated in the model.  May not be a problem.
311                                     statusLabel.setText(getMessage("courseStatusLabel") + ": " + newState);
312 			            } else {
313 			            	KSNotifier.add(new KSNotification(getMessage("cluStateChangeFailedNotification"), false, 5000));
314 			            }
315 			        }
316 				});
317 				widget.updateCourseActionItems(cluModel);
318 
319 			}
320     	}
321     }
322     
323 	public Widget getStatusLabel() {
324 		statusLabel.setStyleName("courseStatusLabel");
325 		return statusLabel;
326 	}
327     
328     public DataModelDefinition getDefinition(){
329     	return definition;
330     }
331 
332 	public void setCurrentVersionId(String id) {
333 		this.currentVersionId = id;
334 	}
335 
336 	public String getCurrentVersionId() {
337 		return currentVersionId;
338 	}
339 	
340 	public String getVersionIndId() {
341 		return versionIndId;
342 	}
343 	
344     public String getMessage(String courseMessageKey) {
345     	String msg = Application.getApplicationContext().getMessage(MSG_GROUP, courseMessageKey);
346     	if (msg == null) {
347     		msg = courseMessageKey;
348     	}
349     	return msg;
350     }
351 	
352 	
353 	@Override
354 	public <V extends Enum<?>> void showView(V viewType, Callback<Boolean> onReadyCallback) {
355 		if(viewType != Views.VERSION_SELECT){
356 			workflowVersionInfoSection.setVisible(true);
357 			this.getHeader().showPrint(true);
358 			this.getHeader().showExport(true);
359 		}
360 		else{
361 			workflowVersionInfoSection.setVisible(false);
362 			this.getHeader().showPrint(false);
363 			this.getHeader().showExport(false);
364 		}
365 		super.showView(viewType, onReadyCallback);
366 	}
367 
368 
369 
370 	public void setCurrentTitle(String currentTitle) {
371     	this.getHeader().setTitle(currentTitle);
372 	}
373 	
374 	
375 	@Override
376 	public CourseRequirementsDataModel getReqDataModel() {
377 		return reqDataModel1;
378 	}
379 
380 	public CourseRequirementsDataModel getReqDataModelComp() {
381 		return reqDataModel2;
382 	} 
383 }