/*
* Tanaguru - Automated webpage assessment
* Copyright (C) 2008-2015 Tanaguru.org
*
* This file is part of Tanaguru.
*
* Tanaguru is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact us by mail: tanaguru AT tanaguru DOT org
*/
package org.tanaguru.webapp.controller;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.tanaguru.webapp.command.AuditSetUpCommand;
import org.tanaguru.webapp.command.factory.AuditSetUpCommandFactory;
import org.tanaguru.webapp.entity.contract.Contract;
import org.tanaguru.webapp.entity.contract.ScopeEnum;
import org.tanaguru.webapp.entity.functionality.Functionality;
import org.tanaguru.webapp.entity.option.OptionElement;
import org.tanaguru.webapp.entity.referential.Referential;
import org.tanaguru.webapp.entity.user.User;
import org.tanaguru.webapp.exception.ForbiddenPageException;
import org.tanaguru.webapp.form.SelectFormField;
import org.tanaguru.webapp.form.builder.SelectFormFieldBuilderImpl;
import org.tanaguru.webapp.form.parameterization.AuditSetUpFormField;
import org.tanaguru.webapp.form.parameterization.builder.AuditSetUpFormFieldBuilderImpl;
import org.tanaguru.webapp.form.parameterization.helper.AuditSetUpFormFieldHelper;
import org.tanaguru.webapp.util.TgolKeyStore;
import org.tanaguru.webapp.validator.AuditSetUpFormValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
/**
*
* @author jkowalczyk
*/
@Controller
public abstract class AbstractAuditSetUpController extends AbstractAuditDataHandlerController{
private String defaultReferential = "Aw22";
public String getDefaultReferential() {
return defaultReferential;
}
public void setDefaultReferential(String defaultReferential) {
this.defaultReferential = defaultReferential;
}
/**
* The list of FormField builders that handles the audit site options
*/
private Map<String, List<AuditSetUpFormFieldBuilderImpl>> siteOptionFormFieldBuilderMap;
public Map<String, List<AuditSetUpFormFieldBuilderImpl>> getSiteOptionFormFieldBuilderMap() {
return siteOptionFormFieldBuilderMap;
}
public final void setSiteOptionFormFieldBuilderMap(final Map<String, List<AuditSetUpFormFieldBuilderImpl>> formFieldBuilderMap) {
this.siteOptionFormFieldBuilderMap = formFieldBuilderMap;
}
/**
* The audit Site set-up validator
*/
private AuditSetUpFormValidator auditSiteSetUpFormValidator;
public AuditSetUpFormValidator getAuditSiteSetUpFormValidator() {
return auditSiteSetUpFormValidator;
}
public final void setAuditSiteSetUpValidator(AuditSetUpFormValidator auditSiteSetUpValidator) {
this.auditSiteSetUpFormValidator = auditSiteSetUpValidator;
}
/**
* The list of FormField builders that handles the audit page options
*/
private Map<String, List<AuditSetUpFormFieldBuilderImpl>> pageOptionFormFieldBuilderMap;
public Map<String, List<AuditSetUpFormFieldBuilderImpl>> getPageOptionFormFieldBuilderMap() {
return pageOptionFormFieldBuilderMap;
}
public final void setPageOptionFormFieldBuilderMap(final Map<String, List<AuditSetUpFormFieldBuilderImpl>> formFieldBuilderMap) {
this.pageOptionFormFieldBuilderMap = formFieldBuilderMap;
}
/**
* The audit Page set-up validator
*/
private AuditSetUpFormValidator auditPageSetUpFormValidator;
public AuditSetUpFormValidator getAuditPageSetUpFormValidator() {
return auditPageSetUpFormValidator;
}
public final void setAuditPageSetUpValidator(AuditSetUpFormValidator auditPageSetUpValidator) {
this.auditPageSetUpFormValidator = auditPageSetUpValidator;
}
/**
* The list of FormField builders that handles the audit upload options
*/
private Map<String, List<AuditSetUpFormFieldBuilderImpl>> uploadOptionFormFieldBuilderMap;
public Map<String, List<AuditSetUpFormFieldBuilderImpl>> getUploadOptionFormFieldBuilderMap() {
return uploadOptionFormFieldBuilderMap;
}
public final void setUploadOptionFormFieldBuilderMap(final Map<String, List<AuditSetUpFormFieldBuilderImpl>> formFieldBuilderMap) {
this.uploadOptionFormFieldBuilderMap = formFieldBuilderMap;
}
/**
* The audit Upload set-up validator
*/
private AuditSetUpFormValidator auditUploadSetUpFormValidator;
public AuditSetUpFormValidator getAuditUploadSetUpFormValidator() {
return auditUploadSetUpFormValidator;
}
public final void setAuditUploadSetUpValidator(AuditSetUpFormValidator auditUploadSetUpValidator) {
this.auditUploadSetUpFormValidator = auditUploadSetUpValidator;
}
/**
* The list of FormField builders that handles the choice of the referential
* and its level
*/
List<SelectFormFieldBuilderImpl> referentialAndLevelFormFieldBuilderList;
public final void setReferentialAndLevelFormFieldBuilderList(List<SelectFormFieldBuilderImpl> selectFormFieldBuilderList) {
this.referentialAndLevelFormFieldBuilderList = selectFormFieldBuilderList;
}
/**
* This map binds the audit set-up view with the functionality code that
* allows to access. It is used to ensure the displayed set-up view
* is authorised regarding the contract functionalities.
*/
Map<String, String> viewFunctionalityBindingMap;
public Map<String, String> getViewFunctionalityBindingMap() {
return viewFunctionalityBindingMap;
}
public void setViewFunctionalityBindingMap(Map<String, String> viewFunctionalityBindingMap) {
this.viewFunctionalityBindingMap = viewFunctionalityBindingMap;
}
private AuditLauncherController auditLauncherController;
public AuditLauncherController getAuditLauncherController() {
return auditLauncherController;
}
@Autowired
public void setAuditLauncherController(AuditLauncherController auditLauncherController) {
this.auditLauncherController = auditLauncherController;
}
public AbstractAuditSetUpController() {
super();
}
/**
*
* @param viewName
* @param contractId
* @param scenarioId
* @param optionFormFieldBuilderMap
* @param scope
* @param model
* @return
*/
protected String displayAuditSetUpView(
String viewName,
String contractId,
String scenarioId,
Map<String, List<AuditSetUpFormFieldBuilderImpl>> optionFormFieldBuilderMap,
ScopeEnum scope,
Model model) {
Long contractIdValue;
try {
contractIdValue = Long.valueOf(contractId);
} catch (NumberFormatException nfe) {
throw new ForbiddenPageException(getCurrentUser());
}
Contract contract = getContractDataService().read(contractIdValue);
if (isUserAllowedToDisplaySetUpPage(contract, viewName)) {
Collection<String> authorisedReferentialList = getAuthorisedReferentialCodeFromContract(contract);
// Get a fresh list of the auditSetUpFormField that handles the choice
// of the referential and its level
List<SelectFormField> refAndLevelFormFieldList =
this.getFreshRefAndLevelSetUpFormFieldList(
authorisedReferentialList,
referentialAndLevelFormFieldBuilderList);
String defaultRef = getDefaultReferential(authorisedReferentialList);
AuditSetUpFormFieldHelper.selectDefaultLevelFromRefValue(
refAndLevelFormFieldList,
defaultRef);
// Get a fresh map of auditSetUpFormField. The value of the field is
// them set by Parameter mapping handled by the AuditSetUpCommandObject
Map<String, List<AuditSetUpFormField>> optionFormFieldMap =
this.getFreshAuditSetUpFormFieldMap(contract, optionFormFieldBuilderMap);
AuditSetUpCommand asuc;
// Regarding the type of audit, we retrieve the appropriate
// instance of AuditSetUpCommand
switch (scope) {
case DOMAIN:
asuc = AuditSetUpCommandFactory.getInstance().
getSiteAuditSetUpCommand(contract,refAndLevelFormFieldList, optionFormFieldMap);
break;
case FILE:
case GROUPOFFILES:
asuc = AuditSetUpCommandFactory.getInstance().
getUploadAuditSetUpCommand(contract,refAndLevelFormFieldList, optionFormFieldMap);
break;
case SCENARIO:
asuc = AuditSetUpCommandFactory.getInstance().
getScenarioAuditSetUpCommand(contract, scenarioId,refAndLevelFormFieldList, optionFormFieldMap);
break;
case PAGE:
case GROUPOFPAGES:
default:
asuc = AuditSetUpCommandFactory.getInstance().
getPageAuditSetUpCommand(contract,refAndLevelFormFieldList, optionFormFieldMap);
}
model.addAttribute(TgolKeyStore.AUDIT_SET_UP_COMMAND_KEY, asuc);
model.addAttribute(TgolKeyStore.DEFAULT_PARAM_SET_KEY,
asuc.isDefaultParamSet());
this.prepareFormModel(
model,
contract,
refAndLevelFormFieldList,
optionFormFieldMap);
return viewName;
} else {
return TgolKeyStore.ACCESS_DENIED_VIEW_NAME;
}
}
/**
*
* @param contract
* @param auditSetUpCommand
* @param formFielMap
* @param auditSetUpFormValidator
* @param model
* @param result
* @param request
* @return
*/
protected String submitForm(
Contract contract,
AuditSetUpCommand auditSetUpCommand,
Map<String, List<AuditSetUpFormField>> formFielMap,
AuditSetUpFormValidator auditSetUpFormValidator,
Model model,
BindingResult result,
HttpServletRequest request) {
if (formFielMap == null || auditSetUpFormValidator == null) {
Logger.getLogger(this.getClass()).info("oups" );
return TgolKeyStore.OUPS_VIEW_NAME;
}
Collection<String> authorisedReferentialList =
getAuthorisedReferentialCodeFromContract(contract);
auditSetUpFormValidator.setAuditSetUpFormFieldMap(formFielMap);
auditSetUpFormValidator.validate(auditSetUpCommand, result);
auditSetUpFormValidator.validateLevel(auditSetUpCommand, result,authorisedReferentialList);
// If the form has some errors, we display it again with errors' details
if (result.hasErrors()) {
Contract currentContract =
getContractDataService().read(auditSetUpCommand.getContractId());
return displayFormWithErrors(
model,
currentContract,
auditSetUpCommand,
authorisedReferentialList,
formFielMap);
}
// If the form is valid, the audit is launched with data from form
model.addAttribute(TgolKeyStore.CONTRACT_ID_KEY, auditSetUpCommand.getContractId());
model.addAttribute(TgolKeyStore.AUDIT_SET_UP_COMMAND_KEY, auditSetUpCommand);
return launchAudit(
contract,
auditSetUpCommand,
model,
request);
}
/**
*
* @param contract
* @param auditSetUpCommand
* @param model
* @param request
* @return
*/
protected String launchAudit(
Contract contract,
AuditSetUpCommand auditSetUpCommand,
Model model,
HttpServletRequest request) {
// If the form is valid, the audit is launched with data from form
model.addAttribute(TgolKeyStore.CONTRACT_ID_KEY, auditSetUpCommand.getContractId());
model.addAttribute(TgolKeyStore.AUDIT_SET_UP_COMMAND_KEY, auditSetUpCommand);
return getAuditLauncherController().launchAudit(
auditSetUpCommand,
getLocaleResolver().resolveLocale(request),
model);
}
/**
*
* @param model
* @param contract
* @param auditSetUpCommand
* @param authorisedReferentialList
* @param parametersMap
* @return
*/
private String displayFormWithErrors(
Model model,
Contract contract,
AuditSetUpCommand auditSetUpCommand,
Collection<String> authorisedReferentialList,
Map<String, List<AuditSetUpFormField>> parametersMap) {
model.addAttribute(TgolKeyStore.EXPANDED_KEY, TgolKeyStore.EXPANDED_VALUE);
model.addAttribute(TgolKeyStore.AUDIT_SET_UP_COMMAND_KEY,
auditSetUpCommand);
model.addAttribute(TgolKeyStore.PARAMETERS_MAP_KEY, parametersMap);
// Get a fresh list of the auditSetUpFormField that handles the choice
// of the referential and its level
List<SelectFormField> refAndLevelFormFieldList =
this.getFreshRefAndLevelSetUpFormFieldList(
authorisedReferentialList,
referentialAndLevelFormFieldBuilderList);
// Otherwise it corresponds to the default behaviour;
// The selection of default level is delegated to the helper.
// When the form is on error, the default level value corresponds to the
// one the user has chosen.
AuditSetUpFormFieldHelper.selectDefaultLevelFromLevelValue(
refAndLevelFormFieldList,
auditSetUpCommand.getLevel());
model.addAttribute(TgolKeyStore.LEVEL_LIST_KEY, refAndLevelFormFieldList);
// if the user is authenticated, the url of the form is under
// /home/contract/. To display error pages, we need to precise the
// backward relative path and to add the breadCrumb.
model.addAttribute(TgolKeyStore.CONTRACT_NAME_KEY, contract.getLabel());
ScopeEnum auditScope = auditSetUpCommand.getScope();
switch (auditScope) {
case DOMAIN :
return TgolKeyStore.AUDIT_SITE_SET_UP_VIEW_NAME;
case PAGE :
return TgolKeyStore.AUDIT_PAGE_SET_UP_VIEW_NAME;
case FILE :
return TgolKeyStore.AUDIT_UPLOAD_SET_UP_VIEW_NAME;
}
return TgolKeyStore.OUPS_VIEW_NAME;
}
/**
* This methods checks whether the current user is allowed to display the
* audit set-up for a given contract. To do so, we verify that the contract
* belongs to the current user. We also check that the current contract handles
* the functionality associated with the set-up page.
*
* @param contract
* @param viewName
* @return
* true if the user is allowed to display the result, false otherwise.
*/
protected boolean isUserAllowedToDisplaySetUpPage(
Contract contract,
String viewName) {
if (contract == null) {
throw new ForbiddenPageException(getCurrentUser());
}
User user = getCurrentUser();
if (!contract.getUser().getId().equals(user.getId())) {
throw new ForbiddenPageException(user);
}
Collection<String> functionalitySet = getAuthorisedFunctionalityCodeFromContract(contract);
if (!functionalitySet.contains(viewFunctionalityBindingMap.get(viewName))) {
throw new ForbiddenPageException(user);
}
return true;
}
/**
* This method prepares the data to display in the set-up form.
*
* @param model
* @param contractId
* @param parametersMap
* @param auditSite
*/
private void prepareFormModel(
Model model,
Contract contract,
List<SelectFormField> refAndLevelFormFieldList,
Map<String, List<AuditSetUpFormField>> optionFormFieldMap) {
model.addAttribute(TgolKeyStore.CONTRACT_NAME_KEY, contract.getLabel());
model.addAttribute(TgolKeyStore.URL_KEY,
getContractDataService().getUrlFromContractOption(contract));
model.addAttribute(TgolKeyStore.PARAMETERS_MAP_KEY, optionFormFieldMap);
model.addAttribute(TgolKeyStore.LEVEL_LIST_KEY, refAndLevelFormFieldList);
}
/**
* Create a fresh map of auditSetUpFormField from an auditSetUpFormFieldBuilder
* map
*
* @param contract
* @param auditSetUpFormFieldBuilderMap
* @return
*/
protected Map<String, List<AuditSetUpFormField>> getFreshAuditSetUpFormFieldMap (
Contract contract,
Map<String, List<AuditSetUpFormFieldBuilderImpl>> auditSetUpFormFieldBuilderMap) {
// Copy the audit setup form field map from the builders
Map<String, List<AuditSetUpFormField>> initialisedSetUpFormFielMap = new LinkedHashMap();
for (Map.Entry<String, List<AuditSetUpFormFieldBuilderImpl>> entry : auditSetUpFormFieldBuilderMap.entrySet()) {
initialisedSetUpFormFielMap.put(
entry.getKey(),
getFreshAuditSetUpFormFieldList(entry.getValue()));
}
// once the FormField are created, we check whether any option associated
// with the contract overide the default values of the element
applyRestrictionRegardingOption(
contract.getOptionElementSet(),
initialisedSetUpFormFielMap.values());
return initialisedSetUpFormFielMap;
}
/**
* Create a fresh list of auditSetUpFormField from a auditSetUpFormFieldBuilder
* list
*
* @param auditSetUpFormFieldBuilderList
* @return
*/
protected List<AuditSetUpFormField> getFreshAuditSetUpFormFieldList(
List<AuditSetUpFormFieldBuilderImpl> auditSetUpFormFieldBuilderList) {
List<AuditSetUpFormField> setUpFormFieldList = new LinkedList();
for (AuditSetUpFormFieldBuilderImpl seb : auditSetUpFormFieldBuilderList) {
setUpFormFieldList.add(seb.build());
}
return setUpFormFieldList;
}
/**
* Create a fresh list of SelectFormField dedicated to the referential and
* level choice.
* The call of the helper method is due to activation mechanism.
* In this case, the activation of the element is done through the referential
* list associated with the contract
*
* @param authorisedReferentialList
* @param auditSetUpFormFieldBuilderList
* @return
*/
protected List<SelectFormField> getFreshRefAndLevelSetUpFormFieldList(
Collection<String> authorisedReferentialList,
List<SelectFormFieldBuilderImpl> auditSetUpFormFieldBuilderList) {
List<SelectFormField> selectFormFieldList = new LinkedList();
for (SelectFormFieldBuilderImpl seb : auditSetUpFormFieldBuilderList) {
// Create the SelectElement from the builder
SelectFormField selectFormField = seb.build();
// enable-disable elements from the authorised referentials
AuditSetUpFormFieldHelper.activateAllowedReferentialField(
selectFormField,
authorisedReferentialList);
// add the fresh instance to the returned list
selectFormFieldList.add(selectFormField);
}
return selectFormFieldList;
}
/**
*
* @param optionElementSet
* @param setUpFormFielList
*/
protected void applyRestrictionRegardingOption(
Collection<OptionElement> optionElementSet,
Collection<List<AuditSetUpFormField>> setUpFormFielList) {
if (optionElementSet.isEmpty()) {
return;
}
for (List<AuditSetUpFormField> apl : setUpFormFielList) {
for (AuditSetUpFormField ap : apl) {
AuditSetUpFormFieldHelper.applyRestrictionToAuditSetUpFormField(
ap,
optionElementSet);
}
}
}
/**
* The contract handles a list of authorised referential. This method parses
* the Collection of Refential associated with the contract and returns a list
* of String containing the code of each authorised referential.
*
* @param contract
* @return
*/
protected Collection<String> getAuthorisedReferentialCodeFromContract (Contract contract) {
Set<String> authorisedReferentialSet = new HashSet();
for (Referential ref : contract.getReferentialSet()) {
authorisedReferentialSet.add(ref.getCode());
}
return authorisedReferentialSet;
}
/**
* The contract handles a list of authorised functionality. This method parses
* the Collection of Functionalities associated with the contract and returns a list
* of String containing the code of each authorised functionality.
*
* @param contract
* @return
*/
protected Collection<String> getAuthorisedFunctionalityCodeFromContract (Contract contract) {
Set<String> authorisedFunctionalitySet = new HashSet();
for (Functionality funct : contract.getFunctionalitySet()) {
authorisedFunctionalitySet.add(funct.getCode());
}
return authorisedFunctionalitySet;
}
/**
*
* @param authorisedReferentialList
* @return
*/
protected String getDefaultReferential(Collection<String> authorisedReferentialList) {
if (authorisedReferentialList.isEmpty()) {
return "";
}
if (authorisedReferentialList.contains(defaultReferential)) {
return defaultReferential;
} else {
return authorisedReferentialList.iterator().next();
}
}
}