/******************************************************************************* * Copyright 2006 - 2014 Vienna University of Technology, * Department of Software Technology and Interactive Systems, IFS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package eu.scape_project.planning.plato.wfview; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import org.slf4j.Logger; import eu.scape_project.planning.exception.PlanningException; import eu.scape_project.planning.model.ITouchable; import eu.scape_project.planning.model.Plan; import eu.scape_project.planning.model.PlanState; import eu.scape_project.planning.plato.wf.AbstractWorkflowStep; import eu.scape_project.planning.utils.FacesMessages; import eu.scape_project.planning.validation.ValidationError; /** * This class represents the core/base-functionality of each viewWorkflow step. * This is modifying the plan and saving it. * * @author Markus Hamm, Michael Kraxner */ public abstract class AbstractView implements Serializable { private static final long serialVersionUID = 4032545177598725457L; @Inject private Logger log; @Inject protected FacesMessages facesMessages; /** * The plan to modify/work on. */ protected Plan plan; /** * Plan state this workflow step view is responsible for. */ protected PlanState currentPlanState; /** * Name of the workflow step. */ protected String name; /** * View URL of the workflow step. */ protected String viewUrl; /** * Group of the workflow step. */ protected String group; /** * This flag is used in views to prevent navigation per menu when there are * unsaved changes. This property preserves the changed-state during * requests like adding a node and can be used to reset the changed-state * i.e. after save and discard */ protected String changed; /** * Creates a new abstract view object. */ public AbstractView() { this.currentPlanState = PlanState.CREATED; this.name = "abstract step"; this.viewUrl = "nonExistent"; } /** * Initializes the view with the given plan. This includes initializing the * corresponding BL. * * @param plan * plan used to initialize */ public void init(Plan plan) { this.plan = plan; getWfStep().init(plan); } /** * Stores the plan changes in database if validation was successful. */ public void save() { try { getWfStep().save(); changed = ""; facesMessages.addInfo("Your changes have been saved."); } catch (Exception e) { facesMessages.addError("Failed to save your changes"); log.error("failed to save changes:", e); } } /** * Discards all changes which have not been persisted so far. Derived views * may use this also to undo changes which do not concern the plan, like * deleting created files... */ public void discard() { try { getWfStep().discard(); plan = getWfStep().getPlan(); // reset the view to its initial init(plan); changed = ""; } catch (PlanningException e) { log.error("Failed to discard changes.", e); facesMessages.addError("Failed to dicard changes."); } } /** * Finishes the current step - this includes validating if the plan has * progressed enough - if there are problems, they are displayed as * FacesMessages. * * @return "success", if the plan state could be advanced, <code>null</code> * otherwise */ public String proceed() { ArrayList<ValidationError> errors = new ArrayList<ValidationError>(); if (tryProceed(errors)) { changed = ""; return "success"; } else { for (ValidationError e : errors) { facesMessages.addError(e.getMessage()); } return null; } } /** * Does the actual proceed, for internal use only. Any occurring errors * should be added to the provided list. * * @param errors * list of errors * @return true, if plan state could be advanced */ protected boolean tryProceed(List<ValidationError> errors) { try { return getWfStep().proceed(errors); } catch (Exception e) { errors.add(new ValidationError("Failed to save changes.")); log.error("Failed to save changes.", e); } return false; } /** * Returns the workflow stop of this view. * * @return the current workflow step */ protected abstract AbstractWorkflowStep getWfStep(); /** * Touches the given object. Used for a4j:ajax listener, which can not cope * with complex method el expressions * * @param object * the object to touch */ public void touch(Object object) { if (object instanceof ITouchable) { ((ITouchable) object).touch(); } } // --------------- getter/setter --------------- public PlanState getCurrentPlanState() { return currentPlanState; } public void setCurrentPlanState(PlanState currentPlanState) { this.currentPlanState = currentPlanState; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getViewUrl() { return viewUrl; } public void setViewUrl(String viewUrl) { this.viewUrl = viewUrl; } public Plan getPlan() { return plan; } public void setPlan(Plan plan) { this.plan = plan; } public String getChanged() { return changed; } public void setChanged(String changed) { this.changed = changed; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } }