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.assembly.data.Data;
7   import org.kuali.student.common.assembly.data.Metadata;
8   import org.kuali.student.common.dto.DtoConstants;
9   import org.kuali.student.common.ui.client.application.Application;
10  import org.kuali.student.common.ui.client.application.KSAsyncCallback;
11  import org.kuali.student.common.ui.client.configurable.mvc.layouts.BasicLayoutWithContentHeader;
12  import org.kuali.student.common.ui.client.configurable.mvc.sections.HorizontalSection;
13  import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
14  import org.kuali.student.common.ui.client.mvc.Callback;
15  import org.kuali.student.common.ui.client.mvc.Controller;
16  import org.kuali.student.common.ui.client.mvc.DataModel;
17  import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
18  import org.kuali.student.common.ui.client.mvc.ModelProvider;
19  import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
20  import org.kuali.student.common.ui.client.widgets.KSButton;
21  import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
22  import org.kuali.student.common.ui.client.widgets.KSLabel;
23  import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
24  import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
25  import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
26  import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
27  import org.kuali.student.core.statement.dto.StatementTypeInfo;
28  import org.kuali.student.lum.common.client.lu.LUUIConstants;
29  import org.kuali.student.lum.lu.ui.course.client.configuration.CourseSummaryConfigurer;
30  import org.kuali.student.lum.lu.ui.course.client.requirements.CourseRequirementsDataModel;
31  import org.kuali.student.lum.lu.ui.course.client.requirements.HasRequirements;
32  import org.kuali.student.lum.lu.ui.course.client.service.CourseRpcService;
33  import org.kuali.student.lum.lu.ui.course.client.service.CourseRpcServiceAsync;
34  import org.kuali.student.lum.lu.ui.course.client.views.SelectVersionsView;
35  import org.kuali.student.lum.lu.ui.course.client.views.ShowVersionView;
36  import org.kuali.student.lum.lu.ui.course.client.widgets.CourseWorkflowActionList;
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("versionInfo/sequenceNumber") + " (current version)";
157 	        			cluModel1.setModelName(name);
158 	        			view.setName(name);
159 	        			view.showWarningMessage(false);
160 	        		}
161 	        		else{
162 	        			String name = "Version " + cluModel1.get("versionInfo/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("versionInfo/sequenceNumber") + " (current version)");
185 	        		}
186 	        		else{
187 	        			cluModel2.setModelName("Version " + cluModel2.get("versionInfo/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         if (initialized) {
241             onReadyCallback.exec(true);
242         } else {
243         	KSBlockingProgressIndicator.addTask(loadDataTask);
244     		
245         	rpcServiceAsync.getMetadata("", null, new KSAsyncCallback<Metadata>(){
246 
247 	        	public void handleFailure(Throwable caught) {
248 	        		initialized = false;
249                 	onReadyCallback.exec(false);
250                 	KSBlockingProgressIndicator.removeTask(loadDataTask);
251                     throw new RuntimeException("Failed to get model definition.", caught);
252                 }
253 
254                 public void onSuccess(Metadata result) {
255                 	definition = new DataModelDefinition(result);
256                     KSBlockingProgressIndicator.removeTask(loadDataTask);
257                     configureScreens(onReadyCallback);
258                 }
259 	          });
260             
261         }
262     }
263 
264     private void configureScreens(final Callback<Boolean> onReadyCallback) {
265         CourseRequirementsDataModel.getStatementTypes(new Callback<List<StatementTypeInfo>>() {
266 
267             @Override
268             public void exec(List<StatementTypeInfo> stmtTypes) {
269                 List<StatementTypeInfo> stmtTypesOut = new ArrayList<StatementTypeInfo>();
270                 if (stmtTypes != null) {
271                     for (StatementTypeInfo stmtType : stmtTypes) {
272                         if (stmtType.getId().contains("kuali.statement.type.course.enrollmentEligibility") ||
273                             stmtType.getId().contains("kuali.statement.type.course.creditConstraints")) {
274                             continue;
275                         }
276                         stmtTypesOut.add(stmtType);
277                     }
278                 }
279 
280                 summaryConfigurer = new CourseSummaryConfigurer(type, state, groupName, definition, stmtTypesOut, VersionsController.this, "Model");
281                 view = new ShowVersionView(Views.VERSION_VIEW, "Version", "Model", VersionsController.this, stmtTypesOut);
282                 compare = summaryConfigurer.generateCourseSummarySection();
283                 compare.setLayoutController(VersionsController.this);
284                 compare.setSectionTitle("Compare Versions");
285                 compare.setName("Compare Versions");
286                 compare.setViewEnum(Views.VERSION_COMPARE);
287                 VersionsController.this.addView(view);
288                 VersionsController.this.addView(compare);
289                 initialized = true;
290                 onReadyCallback.exec(true);
291             }
292         });
293     }
294     
295     public Widget generateActionDropDown(){
296     	CourseWorkflowActionList actionList = new CourseWorkflowActionList(this.getMessage("cluActionsLabel"));
297 
298     	actionDropDownWidgets.add(actionList);
299         
300     	return actionList;
301     }
302     
303     private void updateState(final DataModel cluModel) {
304     	if(cluModel.get("state") != null){
305             statusLabel.setText(getMessage("courseStatusLabel") + ": " + cluModel.get("state"));
306 	    	
307 	    	for(CourseWorkflowActionList widget: actionDropDownWidgets){
308 				widget.init(getViewContext(), "/HOME/CURRICULUM_HOME/COURSE_PROPOSAL", cluModel, new Callback<String>() {
309 					@Override
310 			        public void exec(String newState) {
311 			            if (newState != null) {
312 			                KSNotifier.add(new KSNotification(getMessage("cluStateChangeNotification" + newState), false, 5000));
313 			                // FIXME: this is not updating the cluModel so state will not be updated in the model.  May not be a problem.
314                                     statusLabel.setText(getMessage("courseStatusLabel") + ": " + newState);
315 			            } else {
316 			            	KSNotifier.add(new KSNotification(getMessage("cluStateChangeFailedNotification"), false, 5000));
317 			            }
318 			        }
319 				});
320 				widget.updateCourseActionItems(cluModel);
321 
322 			}
323     	}
324     }
325     
326 	public Widget getStatusLabel() {
327 		statusLabel.setStyleName("courseStatusLabel");
328 		return statusLabel;
329 	}
330     
331     public DataModelDefinition getDefinition(){
332     	return definition;
333     }
334 
335 	public void setCurrentVersionId(String id) {
336 		this.currentVersionId = id;
337 	}
338 
339 	public String getCurrentVersionId() {
340 		return currentVersionId;
341 	}
342 	
343 	public String getVersionIndId() {
344 		return versionIndId;
345 	}
346 	
347     public String getMessage(String courseMessageKey) {
348     	String msg = Application.getApplicationContext().getMessage(MSG_GROUP, courseMessageKey);
349     	if (msg == null) {
350     		msg = courseMessageKey;
351     	}
352     	return msg;
353     }
354 	
355 	
356 	@Override
357 	public <V extends Enum<?>> void showView(V viewType, Callback<Boolean> onReadyCallback) {
358 		if(viewType != Views.VERSION_SELECT){
359 			workflowVersionInfoSection.setVisible(true);
360 			this.getHeader().showPrint(true);
361 			this.getHeader().showExport(true);
362 		}
363 		else{
364 			workflowVersionInfoSection.setVisible(false);
365 			this.getHeader().showPrint(false);
366 			this.getHeader().showExport(false);
367 		}
368 		super.showView(viewType, onReadyCallback);
369 	}
370 
371 
372 
373 	public void setCurrentTitle(String currentTitle) {
374     	this.getHeader().setTitle(currentTitle);
375 	}
376 	
377 	
378 	@Override
379 	public CourseRequirementsDataModel getReqDataModel() {
380 		return reqDataModel1;
381 	}
382 
383 	public CourseRequirementsDataModel getReqDataModelComp() {
384 		return reqDataModel2;
385 	} 
386 }