/**
* ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium.
*/
package org.esupportail.helpdesk.domain.departmentSelection;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.esupportail.commons.aop.monitor.Monitor;
import org.esupportail.commons.services.logging.Logger;
import org.esupportail.commons.services.logging.LoggerImpl;
import org.esupportail.commons.utils.strings.XmlUtils;
import org.esupportail.helpdesk.domain.departmentSelection.actions.Action;
import org.esupportail.helpdesk.domain.departmentSelection.actions.DoNothingAction;
import org.esupportail.helpdesk.domain.departmentSelection.conditions.Condition;
import org.esupportail.helpdesk.domain.departmentSelection.conditions.FalseCondition;
import org.esupportail.helpdesk.web.controllers.DepartmentSelectionController;
import org.springframework.util.StringUtils;
/**
* This class reads the configuration of the department selection.
*/
@Monitor
public class DepartmentSelectionConfigReaderImpl implements Serializable, DepartmentSelectionConfigReader {
/**
* The serialization id.
*/
private static final long serialVersionUID = 7523371895705933609L;
/**
* A logger.
*/
private final Logger logger = new LoggerImpl(getClass());
/**
* The description.
*/
private String description;
/**
* Raw user-defined conditions.
*/
private List<UserDefinedCondition> rawUserDefinedConditions;
/**
* Compiled user-defined conditions.
*/
private UserDefinedConditions userDefinedConditions;
/**
* Raw rules.
*/
private List<Rule> rawRules;
/**
* Compiles rules.
*/
private Rules rules;
/**
* Raw actions.
*/
private List<Action> rawActions;
/**
* Compiled actions.
*/
private Actions whenEmptyActions;
/**
* Constructor, read the configuration from a string.
* @param config
* @throws DepartmentSelectionCompileError
*/
public DepartmentSelectionConfigReaderImpl(final String config)
throws DepartmentSelectionCompileError {
super();
if (!StringUtils.hasText(config)) {
throw new DepartmentSelectionCompileError("null config");
}
rawUserDefinedConditions = new ArrayList<UserDefinedCondition>();
rawRules = new ArrayList<Rule>();
rawActions = new ArrayList<Action>();
DigesterUtils.parseConfigReader(config, this);
compile();
}
/**
* Constructor, read the configuration from another config reader.
* @param configReader
* @throws DepartmentSelectionCompileError
*/
public DepartmentSelectionConfigReaderImpl(
final DepartmentSelectionConfigReader configReader)
throws DepartmentSelectionCompileError {
this(configReader.toString());
}
/**
* Compile.
* @throws DepartmentSelectionCompileError
*/
public void compile()
throws DepartmentSelectionCompileError {
userDefinedConditions = new UserDefinedConditions();
rules = new Rules();
whenEmptyActions = new Actions();
for (UserDefinedCondition userDefinedCondition : rawUserDefinedConditions) {
userDefinedConditions.compileAndAdd(userDefinedCondition);
}
for (Rule rule : rawRules) {
rules.compileAndAdd(userDefinedConditions, rule);
}
int i = 0;
for (Action action : rawActions) {
try {
action.compile();
whenEmptyActions.addAction(action);
} catch (DepartmentSelectionCompileError e) {
throw new DepartmentSelectionCompileError(
"default action #" + i + ": " + e.getMessage());
}
i++;
}
if (logger.isDebugEnabled()) {
logger.debug(toString());
}
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
str += "<department-selection><description>";
if (description != null) {
str += description;
}
str += "</description>";
str += userDefinedConditions;
str += rules;
str += whenEmptyActions;
str += "</department-selection>";
return str;
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader#export()
*/
@Override
public String export() {
return XmlUtils.format(toString(), false);
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #moveUserDefinedCondition(int, java.lang.String)
*/
@Override
public void moveUserDefinedCondition(
final int index,
final String direction)
throws DepartmentSelectionCompileError {
UserDefinedCondition userDefinedConditionToMove = rawUserDefinedConditions.get(index);
rawUserDefinedConditions.remove(index);
if (DepartmentSelectionController.FIRST.equals(direction)) {
rawUserDefinedConditions.add(0, userDefinedConditionToMove);
} else if (DepartmentSelectionController.UP.equals(direction)) {
rawUserDefinedConditions.add(index - 1, userDefinedConditionToMove);
} else if (DepartmentSelectionController.DOWN.equals(direction)) {
rawUserDefinedConditions.add(index + 1, userDefinedConditionToMove);
} else if (DepartmentSelectionController.LAST.equals(direction)) {
rawUserDefinedConditions.add(userDefinedConditionToMove);
}
compile();
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #moveRule(int, java.lang.String)
*/
@Override
public void moveRule(
final int index,
final String direction)
throws DepartmentSelectionCompileError {
Rule ruleToMove = rawRules.get(index);
rawRules.remove(index);
if (DepartmentSelectionController.FIRST.equals(direction)) {
rawRules.add(0, ruleToMove);
} else if (DepartmentSelectionController.UP.equals(direction)) {
rawRules.add(index - 1, ruleToMove);
} else if (DepartmentSelectionController.DOWN.equals(direction)) {
rawRules.add(index + 1, ruleToMove);
} else if (DepartmentSelectionController.LAST.equals(direction)) {
rawRules.add(ruleToMove);
}
compile();
}
/**
* Set the condition.
* @param cond the condition to add
* @throws DepartmentSelectionCompileError
*/
public void addCondition(
final Condition cond) throws DepartmentSelectionCompileError {
throw new DepartmentSelectionCompileError("unexpected condition: " + cond);
}
/**
* add a user-defined condition.
* @param userDefinedCondition the condition
*/
public void addUserDefinedCondition(
final UserDefinedCondition userDefinedCondition) {
rawUserDefinedConditions.add(userDefinedCondition);
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #addNewUserDefinedCondition()
*/
@Override
public void addNewUserDefinedCondition() throws DepartmentSelectionCompileError {
UserDefinedCondition newUserDefinedCondition = new UserDefinedCondition();
String name = "";
while (true) {
name += "?";
boolean nameUsed = false;
for (UserDefinedCondition userDefinedCondition : rawUserDefinedConditions) {
if (name.equals(userDefinedCondition.getName())) {
nameUsed = true;
break;
}
}
if (!nameUsed) {
newUserDefinedCondition.setName(name);
break;
}
}
newUserDefinedCondition.addCondition(new FalseCondition());
rawUserDefinedConditions.add(newUserDefinedCondition);
compile();
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #replaceUserDefinedCondition(int, org.esupportail.helpdesk.domain.departmentSelection.UserDefinedCondition)
*/
@Override
public void replaceUserDefinedCondition(
final int index,
final UserDefinedCondition userDefinedCondition)
throws DepartmentSelectionCompileError {
UserDefinedCondition oldUserDefinedCondition = rawUserDefinedConditions.get(index);
rawUserDefinedConditions.remove(index);
rawUserDefinedConditions.add(index, userDefinedCondition);
if (!oldUserDefinedCondition.getName().equals(userDefinedCondition.getName())) {
for (UserDefinedCondition theUserDefinedCondition : rawUserDefinedConditions) {
theUserDefinedCondition.getCondition().refactorNamedConditions(
oldUserDefinedCondition.getName(),
userDefinedCondition.getName());
}
for (Rule rule : rawRules) {
rule.getCondition().refactorNamedConditions(
oldUserDefinedCondition.getName(),
userDefinedCondition.getName());
}
}
compile();
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #addNewRule()
*/
@Override
public void addNewRule() throws DepartmentSelectionCompileError {
Rule newRule = new Rule();
newRule.addAction(new DoNothingAction());
newRule.setName("?");
newRule.addCondition(new FalseCondition());
rawRules.add(newRule);
compile();
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #replaceRule(int, org.esupportail.helpdesk.domain.departmentSelection.Rule)
*/
@Override
public void replaceRule(
final int index,
final Rule rule)
throws DepartmentSelectionCompileError {
rawRules.remove(index);
rawRules.add(index, rule);
compile();
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #removeWhenEmptyActions()
*/
@Override
public void removeWhenEmptyActions() {
rawActions = new ArrayList<Action>();
}
/**
* add an action.
* @param action the action
*/
public void addAction(final Action action) {
rawActions.add(action);
}
/**
* add a rule to compute the list of the departments that will be seen by a user.
* @param rule the rule to add
*/
public void addRule(final Rule rule) {
rawRules.add(rule);
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #getUserDefinedConditions()
*/
@Override
public UserDefinedConditions getUserDefinedConditions() {
return userDefinedConditions;
}
/**
* @param userDefinedConditions the userDefinedConditions to set
*/
protected void setUserDefinedConditions(final UserDefinedConditions userDefinedConditions) {
this.userDefinedConditions = userDefinedConditions;
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader#getRules()
*/
@Override
public Rules getRules() {
return rules;
}
/**
* @param rules the rules to set
*/
protected void setRules(final Rules rules) {
this.rules = rules;
}
/**
* @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelectionConfigReader
* #getWhenEmptyActions()
*/
@Override
public Actions getWhenEmptyActions() {
return whenEmptyActions;
}
/**
* @param whenEmptyActions the whenEmptyActions to set
*/
protected void setWhenEmptyActions(final Actions whenEmptyActions) {
this.whenEmptyActions = whenEmptyActions;
}
/**
* @return the description
*/
public String getDescription() {
return description;
}
/**
* @param description the description to set
*/
public void setDescription(final String description) {
this.description = description;
}
}