/** * ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium. */ package org.esupportail.helpdesk.web.controllers; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import javax.faces.model.SelectItem; import org.apache.myfaces.custom.fileupload.UploadedFile; import org.apache.myfaces.custom.tree2.TreeState; import org.esupportail.commons.aop.cache.RequestCache; import org.esupportail.commons.exceptions.UserNotFoundException; import org.esupportail.commons.utils.Assert; import org.esupportail.commons.utils.DownloadUtils; import org.esupportail.commons.utils.strings.StringUtils; import org.esupportail.commons.utils.strings.XmlUtils; import org.esupportail.commons.web.beans.TreeModelBase; import org.esupportail.commons.web.controllers.LdapSearchCaller; import org.esupportail.helpdesk.domain.beans.User; import org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionCompileError; import org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader; import org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReaderImpl; import org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelector; import org.esupportail.helpdesk.domain.departmentSelection.DigesterUtils; import org.esupportail.helpdesk.domain.departmentSelection.Rule; import org.esupportail.helpdesk.domain.departmentSelection.UserDefinedCondition; import org.esupportail.helpdesk.web.beans.departmentSelection.ActionsNode; import org.esupportail.helpdesk.web.beans.departmentSelection.RulesNode; import org.esupportail.helpdesk.web.beans.departmentSelection.UserDefinedConditionsNode; /** * A bean to manage department visibility. */ public class DepartmentSelectionController extends AbstractContextAwareController implements LdapSearchCaller { /** * A direction. */ public static final String FIRST = "FIRST"; /** * A direction. */ public static final String UP = "UP"; /** * A direction. */ public static final String DOWN = "DOWN"; /** * A direction. */ public static final String LAST = "LAST"; /** * The serialization id. */ private static final long serialVersionUID = -7399807037061814125L; /** * The department selector. */ private DepartmentSelector departmentSelector; /** * The testUser id. */ private String ldapUid; /** * The computer. */ private String computer; /** * The index of the object to update/delete. */ private int indexToUpdate; /** * The name of the object to update. */ private String nameToUpdate; /** * The previous name of the object to update. */ private String previousName; /** * The direction in which objects should be moved. */ private String direction; /** * The (resolved) testClient. */ private InetAddress testClient; /** * The (resolved) testUser. */ private User testUser; /** * The visibility type. */ private int type; /** * The root node for user-defined conditions. */ private UserDefinedConditionsNode userDefinedConditionsNode; /** * The tree for user-defined conditions. */ private TreeModelBase userDefinedConditionsTree; /** * The root node for rules. */ private RulesNode rulesNode; /** * The tree for rules. */ private TreeModelBase rulesTree; /** * The tree for when empty actions. */ private TreeModelBase whenEmptyActionsTree; /** * The root node for when empty actions. */ private ActionsNode whenEmptyActionsNode; /** * The config reader. */ private DepartmentSelectionConfigReader configReader; /** * The download id. */ private Long downloadId; /** * The uploaded file. */ private UploadedFile uploadedFile; /** * The config to edit. */ private String config; /** * True to show the advanced features. */ private boolean advanced; /** * Bean constructor. */ public DepartmentSelectionController() { super(); } /** * @see org.esupportail.helpdesk.web.controllers.AbstractContextAwareController#afterPropertiesSetInternal() */ @Override public void afterPropertiesSetInternal() { super.afterPropertiesSetInternal(); Assert.notNull(departmentSelector, "property departmentSelector of class " + this.getClass().getName() + " can not be null"); } /** * @see org.esupportail.helpdesk.web.controllers.AbstractContextAwareController#reset() */ @Override public void reset() { super.reset(); setConfigReader(null); ldapUid = null; computer = null; type = 0; uploadedFile = null; advanced = false; } /** * Set the config reader. * @param configReader */ protected void setConfigReader(final DepartmentSelectionConfigReader configReader) { this.configReader = configReader; if (configReader == null) { userDefinedConditionsNode = null; userDefinedConditionsTree = null; rulesNode = null; rulesTree = null; whenEmptyActionsNode = null; whenEmptyActionsTree = null; } else { TreeState state = null; if (userDefinedConditionsTree != null) { state = userDefinedConditionsTree.getTreeState(); } userDefinedConditionsNode = new UserDefinedConditionsNode( configReader.getUserDefinedConditions()); userDefinedConditionsTree = new TreeModelBase(userDefinedConditionsNode); if (state != null) { userDefinedConditionsTree.setTreeState(state); } state = null; if (rulesTree != null) { state = rulesTree.getTreeState(); } rulesNode = new RulesNode(configReader.getRules()); rulesTree = new TreeModelBase(rulesNode); if (state != null) { rulesTree.setTreeState(state); } state = null; if (whenEmptyActionsTree != null) { state = whenEmptyActionsTree.getTreeState(); } whenEmptyActionsNode = new ActionsNode(configReader.getWhenEmptyActions()); whenEmptyActionsTree = new TreeModelBase(whenEmptyActionsNode); if (state != null) { whenEmptyActionsTree.setTreeState(state); } clear(); } } /** * Reset the results. */ public void clear() { testUser = null; testClient = null; userDefinedConditionsNode.resetEval(); rulesNode.resetEval(); whenEmptyActionsNode.resetEval(); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return getClass().getSimpleName() + "#" + hashCode() + "[ldapUid=[" + ldapUid + "]" + ", computer=[" + computer + "]" + ", type=[" + type + "]" + "]"; } /** * @return true if the current testUser is allowed to access the view. */ @RequestCache public boolean isPageAuthorized() { if (getCurrentUser() == null) { return false; } if (getCurrentUser().getAdmin()) { return true; } if (!getDomainService().isDepartmentManager(getCurrentUser())) { return false; } return true; } /** * JSF callback. * @return A String. */ public String enter() { if (!isPageAuthorized()) { return null; } getSessionController().setShowShortMenu(false); if (configReader == null) { loadConfig(); } return "navigationDepartmentSelection"; } /** * @return the utilitiesItems */ @RequestCache public List<SelectItem> getTypeItems() { List<SelectItem> typesItems = new ArrayList<SelectItem>(); typesItems.add(new SelectItem( 0, getString("DEPARTMENT_SELECTION.TEXT.TYPE.NONE"))); typesItems.add(new SelectItem( DepartmentSelector.TICKET_CREATION_SELECTION, getString("DEPARTMENT_SELECTION.TEXT.TYPE.TICKET_CREATION"))); typesItems.add(new SelectItem( DepartmentSelector.TICKET_VIEW_SELECTION, getString("DEPARTMENT_SELECTION.TEXT.TYPE.TICKET_VIEW"))); typesItems.add(new SelectItem( DepartmentSelector.FAQ_VIEW_SELECTION, getString("DEPARTMENT_SELECTION.TEXT.TYPE.FAQ_VIEW"))); typesItems.add(new SelectItem( DepartmentSelector.SEARCH_SELECTION, getString("DEPARTMENT_SELECTION.TEXT.TYPE.SEARCH"))); return typesItems; } /** * Add an error message for compile eroors. * @param e */ protected void addCompileErrorMessage( final Exception e) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.COMPILE_ERROR", e.getMessage()); } /** * Resolve the user. * @return true if resolved. */ protected boolean resolveTestUser() { testUser = null; try { if (ldapUid == null) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.ENTER_ID"); return false; } testUser = getUserStore().getUserFromRealId(ldapUid); return true; } catch (UserNotFoundException e) { addErrorMessage(null, "_.MESSAGE.USER_NOT_FOUND", ldapUid); return false; } } /** * JSF callback. * @return a String. */ public String test() { clear(); if (type == 0) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.ENTER_TYPE"); return null; } boolean error = !resolveTestUser(); try { if (computer != null) { testClient = InetAddress.getByName(computer); computer = testClient.getHostName(); } } catch (UnknownHostException e) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.UNKNOWN_HOST", computer); error = true; } if (error) { return null; } userDefinedConditionsNode.eval(getDomainService(), testUser, testClient); rulesNode.eval(getDomainService(), testUser, testClient, type); if (rulesNode.getEvalResult().isEmpty()) { whenEmptyActionsNode.eval(getDomainService(), type); } return "tested"; } /** * JSF callback. */ public void downloadConfig() { downloadId = DownloadUtils.setDownload( configReader.export().getBytes(), "config.xml", "application/octet-stream"); } /** * @return true if the current user can edit the department selection config. */ @RequestCache public boolean isCurrentUserCanEditDepartmentSelection() { return getDomainService().userCanEditDepartmentSelection(getCurrentUser()); } /** * JSF callback. */ public void uploadConfig() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return; } if (uploadedFile == null) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.ENTER_FILE"); return; } String filename = uploadedFile.getName(); // a hack for IE if (filename.contains("\\")) { filename = filename.substring(filename.lastIndexOf('\\') + 1); } if (uploadedFile.getSize() == 0) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.UPLOAD_ZERO"); return; } byte [] fileContent; try { fileContent = uploadedFile.getBytes(); } catch (IOException e) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.UPLOAD_ERROR", e.getMessage()); return; } try { setConfigReader(new DepartmentSelectionConfigReaderImpl(new String(fileContent, "UTF-8"))); } catch (UnsupportedEncodingException e) { addCompileErrorMessage( new DepartmentSelectionCompileError( "error while reading file [" + uploadedFile.getName() + "]", e)); return; } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_UPLOADED"); clear(); } /** * JSF callback. */ public void loadConfig() { try { setConfigReader(new DepartmentSelectionConfigReaderImpl( getDomainService().getDepartmentSelectionConfig().getData())); } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_LOADED"); clear(); } /** * JSF callback. */ public void saveConfig() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return; } getDomainService().setDepartmentSelectionConfig(getCurrentUser(), configReader.toString()); addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_SAVED"); } /** * JSF callback. * @return a String. */ public String editConfig() { clear(); if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } config = configReader.export(); return "editConfig"; } /** * JSF callback. * @return a String. */ public String doEditConfig() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return "navigationDepartmentSelection"; } try { setConfigReader(new DepartmentSelectionConfigReaderImpl(config)); } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_UPDATED"); clear(); return "configEdited"; } /** * JSF callback. * @return a String. */ public String addUserDefinedCondition() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); newConfigReader.addNewUserDefinedCondition(); indexToUpdate = newConfigReader.getUserDefinedConditions().size() - 1; UserDefinedCondition userDefinedCondition = newConfigReader.getUserDefinedConditions().getByOrder(indexToUpdate); nameToUpdate = userDefinedCondition.getName(); previousName = userDefinedCondition.getName(); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); clear(); return editUserDefinedCondition(); } /** * JSF callback. * @return a String. */ public String editUserDefinedCondition() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } UserDefinedCondition userDefinedCondition = configReader.getUserDefinedConditions().getByOrder(indexToUpdate); config = XmlUtils.format("<edit>" + userDefinedCondition.contentToString() + "</edit>", true); return "editUserDefinedCondition"; } /** * JSF callback. * @return a String. */ public String doEditUserDefinedCondition() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return "navigationDepartmentSelection"; } try { DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); UserDefinedCondition userDefinedCondition = new UserDefinedCondition(); if (nameToUpdate == null) { addErrorMessage(null, "DEPARTMENT_SELECTION.MESSAGE.NULL_USER_DEFINED_CONDITION_NAME"); return null; } userDefinedCondition.setName(nameToUpdate); DigesterUtils.parseUserDefinedCondition(config, userDefinedCondition); newConfigReader.replaceUserDefinedCondition(indexToUpdate, userDefinedCondition); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_UPDATED"); clear(); return "userDefinedConditionEdited"; } /** * JSF callback. * @return a String. */ public String addRule() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); newConfigReader.addNewRule(); indexToUpdate = newConfigReader.getRules().getRules().size() - 1; Rule rule = newConfigReader.getRules().getRules().get(indexToUpdate); nameToUpdate = rule.getName(); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); clear(); return editRule(); } /** * JSF callback. * @return a String. */ public String editRule() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } Rule rule = configReader.getRules().getRules().get(indexToUpdate); config = XmlUtils.format("<edit>" + rule.contentToString() + "</edit>", true); return "editRule"; } /** * JSF callback. * @return a String. */ public String doEditRule() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return "navigationDepartmentSelection"; } try { DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); Rule rule = new Rule(); rule.setName(nameToUpdate); DigesterUtils.parseRule(config, rule); newConfigReader.replaceRule(indexToUpdate, rule); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_UPDATED"); clear(); return "ruleEdited"; } /** * JSF callback. * @return a String. */ public String editActions() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return null; } config = XmlUtils.format("<edit>" + configReader.getWhenEmptyActions().contentToString() + "</edit>", true); return "editActions"; } /** * JSF callback. * @return a String. */ public String doEditActions() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return "navigationDepartmentSelection"; } try { DepartmentSelectionConfigReaderImpl newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); newConfigReader.removeWhenEmptyActions(); DigesterUtils.parseConfigReader(config, newConfigReader); newConfigReader.compile(); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } addInfoMessage(null, "DEPARTMENT_SELECTION.MESSAGE.CONFIG_UPDATED"); clear(); return "actionsEdited"; } /** * Move a user-defined condition. * @return a String. */ public String moveUserDefinedCondition() { try { DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); newConfigReader.moveUserDefinedCondition(indexToUpdate, direction); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); clear(); return "updated"; } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } } /** * Move a rule. * @return a String. */ public String moveRule() { try { DepartmentSelectionConfigReader newConfigReader = new DepartmentSelectionConfigReaderImpl(configReader); newConfigReader.moveRule(indexToUpdate, direction); setConfigReader(new DepartmentSelectionConfigReaderImpl(newConfigReader)); clear(); return "updated"; } catch (DepartmentSelectionCompileError e) { addCompileErrorMessage(e); return null; } } /** * @see org.esupportail.commons.web.controllers.LdapSearchCaller#getLdapUid() */ @Override public String getLdapUid() { return ldapUid; } /** * @see org.esupportail.commons.web.controllers.LdapSearchCaller#setLdapUid(java.lang.String) */ @Override public void setLdapUid(final String ldapUid) { this.ldapUid = StringUtils.nullIfEmpty(ldapUid); } /** * @return the computer */ public String getComputer() { return computer; } /** * @param computer the computer to set */ public void setComputer(final String computer) { this.computer = StringUtils.nullIfEmpty(computer); } /** * @return the testClient */ public InetAddress getTestClient() { return testClient; } /** * @param testClient the testClient to set */ protected void setTestClient(final InetAddress testClient) { this.testClient = testClient; } /** * @return the testUser */ public User getTestUser() { return testUser; } /** * @param testUser the testUser to set */ protected void setTestUser(final User testUser) { this.testUser = testUser; } /** * @return the departmentSelector */ protected DepartmentSelector getDepartmentSelector() { return departmentSelector; } /** * @param departmentSelector the departmentSelector to set */ public void setDepartmentSelector(final DepartmentSelector departmentSelector) { this.departmentSelector = departmentSelector; } /** * @return the type */ public int getType() { return type; } /** * @param type the type to set */ public void setType(final int type) { this.type = type; } /** * @return the userDefinedConditionsTree */ public TreeModelBase getUserDefinedConditionsTree() { return userDefinedConditionsTree; } /** * @param userDefinedConditionsTree the userDefinedConditionsTree to set */ protected void setUserDefinedConditionsTree(final TreeModelBase userDefinedConditionsTree) { this.userDefinedConditionsTree = userDefinedConditionsTree; } /** * @return the whenEmptyActionsTree */ public TreeModelBase getWhenEmptyActionsTree() { return whenEmptyActionsTree; } /** * @param whenEmptyActionsTree the whenEmptyActionsTree to set */ protected void setWhenEmptyActionsTree(final TreeModelBase whenEmptyActionsTree) { this.whenEmptyActionsTree = whenEmptyActionsTree; } /** * @return the rulesTree */ public TreeModelBase getRulesTree() { return rulesTree; } /** * @param rulesTree the rulesTree to set */ protected void setRulesTree(final TreeModelBase rulesTree) { this.rulesTree = rulesTree; } /** * @param downloadId the downloadId to set */ protected void setDownloadId(final Long downloadId) { this.downloadId = downloadId; } /** * @return the downloadId */ public Long getDownloadId() { Long id = downloadId; downloadId = null; return id; } /** * @param uploadedFile the uploadedFile to set */ public void setUploadedFile(final UploadedFile uploadedFile) { this.uploadedFile = uploadedFile; } /** * @return the uploadedFile */ public UploadedFile getUploadedFile() { return uploadedFile; } /** * @return the config */ public String getConfig() { return config; } /** * @param config the config to set */ public void setConfig(final String config) { this.config = config; } /** * Toggle the advanced flag. */ public void toggleAdvanced() { if (!isCurrentUserCanEditDepartmentSelection()) { addUnauthorizedActionMessage(); return; } advanced = !advanced; } /** * @return the advanced */ public boolean isAdvanced() { return advanced; } /** * @return the indexToUpdate */ protected int getIndexToUpdate() { return indexToUpdate; } /** * @param indexToUpdate the indexToUpdate to set */ public void setIndexToUpdate(final int indexToUpdate) { this.indexToUpdate = indexToUpdate; } /** * @return the direction */ protected String getDirection() { return direction; } /** * @param direction the direction to set */ public void setDirection(final String direction) { this.direction = direction; } /** * @return the nameToUpdate */ public String getNameToUpdate() { return nameToUpdate; } /** * @param nameToUpdate the nameToUpdate to set */ public void setNameToUpdate(final String nameToUpdate) { this.nameToUpdate = StringUtils.nullIfEmpty(nameToUpdate); } /** * @return the previousName */ protected String getPreviousName() { return previousName; } /** * @param previousName the previousName to set */ public void setPreviousName(final String previousName) { this.previousName = StringUtils.nullIfEmpty(previousName); } }