All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kuali.student.lum.program.client.ProgramController Maven / Gradle / Ivy

There is a newer version: 2.0.3-cm
Show newest version
package org.kuali.student.lum.program.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import org.kuali.student.common.ui.client.application.Application;
import org.kuali.student.common.ui.client.application.ViewContext;
import org.kuali.student.common.ui.client.configurable.mvc.layouts.MenuSectionController;
import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
import org.kuali.student.common.ui.client.mvc.*;
import org.kuali.student.common.ui.client.mvc.dto.ReferenceModel;
import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
import org.kuali.student.common.ui.client.service.DataSaveResult;
import org.kuali.student.common.ui.client.util.ExportElement;
import org.kuali.student.common.ui.client.util.ExportUtils;
import org.kuali.student.common.ui.client.widgets.KSButton;
import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
import org.kuali.student.common.ui.client.widgets.dialog.ButtonMessageDialog;
import org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup;
import org.kuali.student.common.ui.client.widgets.field.layout.button.YesNoCancelGroup;
import org.kuali.student.common.ui.shared.IdAttributes;
import org.kuali.student.common.ui.shared.IdAttributes.IdType;
import org.kuali.student.core.comments.ui.client.widgets.commenttool.CommentTool;
import org.kuali.student.lum.common.client.helpers.RecentlyViewedHelper;
import org.kuali.student.lum.common.client.widgets.AppLocations;
import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
import org.kuali.student.lum.program.client.events.UpdateEvent;
import org.kuali.student.lum.program.client.rpc.AbstractCallback;
import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService;
import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcServiceAsync;
import org.kuali.student.lum.program.client.widgets.ProgramSideBar;
import org.kuali.student.r1.common.assembly.data.Data;
import org.kuali.student.r1.common.assembly.data.Metadata;
import org.kuali.student.r1.common.rice.authorization.PermissionType;
import org.kuali.student.r2.common.dto.DtoConstants;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Igor
 */
public abstract class ProgramController extends MenuSectionController {

    protected MajorDisciplineRpcServiceAsync programRemoteService;

    protected boolean initialized = false;

    protected DataModel programModel;

    protected AbstractProgramConfigurer configurer;

    protected HandlerManager eventBus;

	protected Label statusLabel = new Label();

    protected ProgramSideBar sideBar;

    private boolean needToLoadOldModel = false;

    protected ProgramStatus lastLoadedStatus;

    protected boolean reloadMetadata = false;

    protected boolean processBeforeShow = true;
    
    /**
     * Constructor.
     *
     * @param programModel
     */
    public ProgramController(String name, DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
        super();
        programRemoteService = createProgramRemoteService();
        this.eventBus = eventBus;
        this.programModel = programModel;
        setViewContext(viewContext);
        initializeModel();
    }


    /**
     * Create a ProgramRpcServiceAsync appropriate for this Controller
     */
    protected MajorDisciplineRpcServiceAsync createProgramRemoteService() {
        return GWT.create(MajorDisciplineRpcService.class);
    }

    @Override
    public void beforeViewChange(Enum viewChangingTo, final Callback okToChange) {
        if (processBeforeShow) {
            super.beforeViewChange(viewChangingTo, new Callback() {

                @Override
                public void exec(Boolean result) {
                    if (result) {
                        if (getCurrentView() instanceof SectionView && ((SectionView) getCurrentView()).isDirty()) {
                            ButtonGroup buttonGroup = new YesNoCancelGroup();
                            final ButtonMessageDialog dialog = new ButtonMessageDialog("Warning", "You may have unsaved changes.  Save changes?", buttonGroup);
                            buttonGroup.addCallback(new Callback() {

                                @Override
                                public void exec(ButtonEnumerations.YesNoCancelEnum result) {
                                    switch (result) {
                                        case YES:
                                            dialog.hide();
                                            fireUpdateEvent(okToChange);
                                            break;
                                        case NO:
                                            dialog.hide();
                                            resetModel();
                                            needToLoadOldModel = true;
                                            resetFieldInteractionFlag();
                                            okToChange.exec(true);
                                            break;
                                        case CANCEL:
                                            okToChange.exec(false);
                                            dialog.hide();
                                            // Because this event fires after the history change event we need to "undo" the history events. 
                                            HistoryManager.logHistoryChange();  
                                            break;
                                    }
                                }
                            });
                            dialog.addCloseLinkClickHandler(new ClickHandler() {
                                
                                @Override
                                public void onClick(ClickEvent event) {
                                    okToChange.exec(false);
                                    dialog.hide();
                                    // Because this event fires after the history change event we need to "undo" the history events. 
                                    HistoryManager.logHistoryChange();  
                                }
                            });
                            dialog.show();
                        } else {
                            okToChange.exec(true);
                        }
                    } else {
                        okToChange.exec(false);
                    }
                }
            });
        } else {
            processBeforeShow = true;
        }
    }

    protected void fireUpdateEvent(final Callback okToChange) {
        eventBus.fireEvent(new UpdateEvent(okToChange));
    }

    protected void resetModel() {
        programModel.resetRoot();
    }

    protected void resetFieldInteractionFlag() {
        View currentView = getCurrentView();
        if (currentView instanceof Section) {
            ((Section) currentView).resetFieldInteractionFlags();
        }
    }

    /**
     * Initialized model of the controller.
     */
    private void initializeModel() {
        setDefaultModelId(ProgramConstants.PROGRAM_MODEL_ID);
        registerModel(ProgramConstants.PROGRAM_MODEL_ID, new ModelProvider() {
            @Override
            public void requestModel(final ModelRequestCallback callback) {
                if (programModel.getRoot() == null || programModel.getRoot().size() == 0) {
                    loadModel(callback);
                } else {
                    callback.onModelReady(programModel);
                }
            }
        });
    }


    @Override
    public void requestModel(Class modelType, ModelRequestCallback callback) {
        if (modelType == ReferenceModel.class) {
            ReferenceModel referenceModel = new ReferenceModel();
            referenceModel.setReferenceId(ProgramUtils.getProgramId(programModel));
            referenceModel.setReferenceTypeKey(ProgramConstants.MAJOR_REFERENCE_TYPE_ID);
            referenceModel.setReferenceType(ProgramConstants.MAJOR_LU_TYPE_ID);
            Map attributes = new HashMap();
            attributes.put("name", getStringProperty("name"));
            referenceModel.setReferenceAttributes(attributes);
            callback.onModelReady(referenceModel);
        } else {
            super.requestModel(modelType, callback);
        }
    }


    /**
     * Loads data model from the server.
     *
     * @param callback we have to invoke this callback when model is loaded or failed.
     */
    protected void loadModel(final ModelRequestCallback callback) {
        programRemoteService.getData(getViewContext().getId(), new AbstractCallback(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {

            @Override
            public void onFailure(Throwable caught) {
                super.onFailure(caught);
                callback.onRequestFail(caught);
            }

            @Override
            public void onSuccess(Data result) {
                super.onSuccess(result);
                programModel.setRoot(result);
                setHeaderTitle();
                callback.onModelReady(programModel);
            }
        });
    }

    private void setModelData() {
        setHeaderTitle();
        setStatus();
        configurer.applyPermissions();
        //We don't want to throw ModelLoadedEvent when we just want to rollback the model
        if (needToLoadOldModel) {
            needToLoadOldModel = false;
        } else {
            String id = ProgramUtils.getProgramId(programModel);
            if (null != id) {
                // add to recently viewed
                ViewContext docContext = new ViewContext();
                docContext.setId(id);
                docContext.setIdType(IdType.OBJECT_ID);
                String pgmType = getStringProperty(ProgramConstants.TYPE);
                docContext.setAttribute(ProgramConstants.TYPE, pgmType + '/' + ProgramSections.PROGRAM_DETAILS_VIEW);
                RecentlyViewedHelper.addDocument(getProgramName(),
                        HistoryManager.appendContext(getProgramViewLocation(pgmType), docContext));
            }
            eventBus.fireEvent(new ModelLoadedEvent(programModel));
            onModelLoadedEvent();
        }
    }

    private String getProgramViewLocation(String pgmType) {
        if (ProgramClientConstants.MAJOR_PROGRAM.equals(pgmType)) {
            return AppLocations.Locations.VIEW_PROGRAM.getLocation();
        } else if (ProgramClientConstants.CORE_PROGRAM.equals(pgmType)) {
            return AppLocations.Locations.VIEW_CORE_PROGRAM.getLocation();
        } else if (ProgramClientConstants.CREDENTIAL_PROGRAM_TYPES.contains(pgmType)) {
            return AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation();
        }
        return null;
    }

    protected void setStatus() {
        statusLabel.setText(getLabel(ProgramMsgConstants.COMMON_STATUS,getStringProperty(ProgramConstants.STATE)));
    }

    public String getProgramName() {
        String name = getStringProperty(ProgramConstants.LONG_TITLE);
        if (name == null) {
            name = getLabel(ProgramMsgConstants.COMMON_NEWPROGRAM);
        }
        return name;
    }

    /**
     * Got invoked by framework before showing the view of the controller.
     *
     * @param onReadyCallback
     */
    @Override
    public void beforeShow(final Callback onReadyCallback) {
        if (programModel.getRoot() == null) {
            loadModel(new ModelRequestCallback() {
                @Override
                public void onModelReady(DataModel model) {
                    if (loadMetadataCondition()) {
                        loadMetadata(onReadyCallback);
                    } else {

                        onReadyCallback.exec(true);
                    }
                }

                @Override
                public void onRequestFail(Throwable cause) {
                    GWT.log(cause.getMessage());
                }
            });
        } else {
            afterMetadataLoaded(onReadyCallback);
        }
    }

    /**
     * We should only load metadata if the status of model is changed.
     *
     * @return
     */
    protected boolean loadMetadataCondition() {
        return lastLoadedStatus == null || ProgramStatus.of(programModel) != lastLoadedStatus;
    }

    /**
     * Loads metadata from the server.
     *
     * @param onReadyCallback
     */
    protected void loadMetadata(final Callback onReadyCallback) {
        Map idAttributes = new HashMap();
        ViewContext viewContext = getViewContext();
        IdType idType = viewContext.getIdType();
        String viewContextId = null;
        if (idType != null) {
            idAttributes.put(IdAttributes.ID_TYPE, idType.toString());
            viewContextId = viewContext.getId();
            if (idType == IdType.COPY_OF_OBJECT_ID) {
   
                viewContextId = null;
            }
        }
        if (programModel.getRoot() != null) {
            ProgramStatus programStatus = ProgramStatus.of(programModel);
            idAttributes.put(DtoConstants.DTO_STATE, programStatus.getValue());
            if (programStatus.getNextStatus() != null) {
                idAttributes.put(DtoConstants.DTO_NEXT_STATE, programStatus.getNextStatus().getValue());
            }
        }
        programRemoteService.getMetadata(viewContextId, idAttributes, new AbstractCallback() {

            @Override
            public void onSuccess(Metadata result) {
                super.onSuccess(result);
                DataModelDefinition def = new DataModelDefinition(result);
                programModel.setDefinition(def);
                lastLoadedStatus = ProgramStatus.of(programModel);
                afterMetadataLoaded(onReadyCallback);
            }

            @Override
            public void onFailure(Throwable caught) {
                super.onFailure(caught);
                onReadyCallback.exec(false);
            }
        });
    }

    protected void configureView() {
        addStyleName("programController");
        configurer.setModelDefinition(programModel.getDefinition());
        configurer.configure(this);
        addContentWidget(statusLabel);
        setSideBarWidget(sideBar);
    }

    @Override
    public void setViewContext(ViewContext viewContext) {
        super.setViewContext(viewContext);
        if (viewContext.getId() != null && !viewContext.getId().isEmpty()) {

       viewContext.setPermissionType(PermissionType.OPEN);
        } else {

        viewContext.setPermissionType(PermissionType.INITIATE);
        }
    }

    /**
     * Called when metadata is loaded.
     *
     * @param onReadyCallback
     */
    protected void afterMetadataLoaded(Callback onReadyCallback) {
        if (!reloadMetadata) {
            configureView();
            onReadyCallback.exec(true);
            reloadMetadata = true;
        } else {
            onReadyCallback.exec(true);
            ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
        }
        if (programModel.getRoot() != null) {
            setModelData();
        }
    }

    protected void setHeaderTitle() {
        String title = getProgramName();
        this.setContentTitle(title);
        this.setName(title);
    }

    protected Widget createCommentPanel() {
        final CommentTool commentTool = new CommentTool(ProgramSections.COMMENTS, "Comments", "kuali.comment.type.generalRemarks", "Program Comments");
        commentTool.setController(this);
        KSButton commentsButton = new KSButton(getLabel(ProgramMsgConstants.COMMENTS_BUTTON), KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR, new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                commentTool.show();
            }
        });
        return commentsButton;
    }

    protected void doSave() {
    }
    
    
    /**
     * Update the state of the program and all of its statements.
     * 

* This is only called when the state change event fires. *

* There are several types of programs (majorDiscipline, core, credential). The * state of each program changes when buttons are pressed. For example, pressing * the activate button may change the state of the program from draft to active. *

* This method is triggered when the state changes. It will pass the * new state to the controller servlet, which will then use it to update the state * by calling the web services. *

* Note that state and status are different. *

* It is placed in ProgramController so core, credential, etc all have access it. *

* * * @param state the state we changed to * @param okCallback will return true if update succeeded */ protected void updateState(String state, final Callback okCallback) { programRemoteService.updateState(programModel.getRoot(), state, new AbstractCallback(getLabel(ProgramMsgConstants.COMMON_SAVINGDATA)) { @Override public void onSuccess(DataSaveResult result) { if(result.getValidationResults()==null || result.getValidationResults().isEmpty()){ super.onSuccess(result); okCallback.exec(true); refreshModelAndView(result); }else{ //Remove the blocking progress super.onSuccess(result); //Do proper validation error handling isValid(result.getValidationResults(), false, true); ProgramUtils.handleValidationErrorsForSpecializations(result.getValidationResults(), programModel); //return false since this was not successful okCallback.exec(false); } } }); } /** * This method will refresh the model and view with the data sent back from * the server. * */ public void refreshModelAndView(DataSaveResult result){ if (result != null) { programModel.setRoot(result.getValue()); } setHeaderTitle(); setStatus(); } public DataModel getProgramModel() { return programModel; } public void onModelLoadedEvent() { } protected String getStringProperty(String key) { return programModel.get(key); } protected Data getDataProperty(String key) { return programModel.get(key); } public boolean isExportButtonActive() { if (this.getCurrentViewEnum() != null) { if (this.getCurrentViewEnum().equals(ProgramSections.SUMMARY) || this.getCurrentViewEnum().equals(ProgramSections.VIEW_ALL)) { return true; } else { return false; } } else { return false; } } /** * * @see org.kuali.student.common.ui.client.reporting.ReportExport#getExportTemplateName() */ @Override public String getExportTemplateName() { if (this.getCurrentViewEnum().equals(ProgramSections.VIEW_ALL)){ return "base.template"; } return "proposal.template"; } @Override public List getExportElementsFromView() { String viewName = null; String sectionTitle = null; View currentView = this.getCurrentView(); if (currentView != null) { List exportElements = new ArrayList(); ExportElement heading = GWT.create(ExportElement.class); heading.setFieldLabel(""); heading.setFieldValue(currentView.getName()); exportElements.add(heading); if (currentView instanceof Section) { Section currentSection = (Section) currentView; List

nestedSections = currentSection.getSections(); for (int i = 0; i < nestedSections.size(); i++) { ExportElement sectionExportItem = GWT.create(ExportElement.class); ArrayList subList = null; Section nestedSection = nestedSections.get(i); if (nestedSection != null && nestedSection instanceof SectionView) { SectionView nestedSectionView = (SectionView) nestedSection; viewName = nestedSectionView.getName(); sectionTitle = nestedSectionView.getTitle(); sectionExportItem.setSectionName(sectionTitle + " " + i + " - " + viewName); sectionExportItem.setViewName(sectionTitle + " " + i + " - " + viewName); subList = ExportUtils.getExportElementsFromView(nestedSectionView, subList, viewName, sectionTitle); if (subList != null && subList.size()> 0) { sectionExportItem.setSubset(subList); exportElements.add(sectionExportItem); } } } } return exportElements; } return null; } protected String getLabel(String messageKey) { return Application.getApplicationContext().getUILabel(ProgramMsgConstants.PROGRAM_MSG_GROUP, messageKey); } protected String getLabel(String messageKey, String parameter) { Map parameters = new HashMap(); parameters.put("0", parameter); return Application.getApplicationContext().getUILabel(ProgramMsgConstants.PROGRAM_MSG_GROUP, messageKey, parameters); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy