/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.condition.interpreter;
import org.olat.core.id.Identity;
import org.olat.core.id.User;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.course.editor.CourseEditorEnv;
import org.olat.course.run.userview.UserCourseEnvironment;
/**
* Class to collect the different possible condition functions on the value of a userproperty
*
* @author dfurrer, dirk.furrer@frentix.com, http://www.frentix.com
*/
public class EvalUserPropertyFunction extends AbstractFunction {
private static final OLog log = Tracing.createLoggerFor(EvalUserPropertyFunction.class);
// user must have exactly this expression in one of the values of given property
public static final int FUNCTION_TYPE_HAS_PROPERTY = 0;
public static final String FUNCTION_NAME_HAS_PROPERTY = "hasUserProperty";
// one of the values of given property must start with the given expression
public static final int FUNCTION_TYPE_PROPERTY_STARTS_WITH = 1;
public static final String FUNCTION_NAME_PROPERTY_STARTS_WITH = "userPropertyStartswith";
// one of the values of given property must end with the given expression
public static final int FUNCTION_TYPE_PROPERTY_ENDS_WITH = 2;
public static final String FUNCTION_NAME_PROPERTY_ENDS_WITH = "userPropertyEndswith";
// given expression must be part of one of the values of given property
public static final int FUNCTION_TYPE_IS_IN_PROPERTY = 3;
public static final String FUNCTION_NAME_IS_IN_PROPERTY = "isInUserProperty";
// neither of the values of given property may contain the given expression
public static final int FUNCTION_TYPE_IS_NOT_IN_PROPERTY = 4;
public static final String FUNCTION_NAME_IS_NOT_IN_PROPERTY = "isNotInUserProperty";
// neither of the values of given property may match the given expression
public static final int FUNCTION_TYPE_HAS_NOT_PROPERTY = 5;
public static final String FUNCTION_NAME_HAS_NOT_PROPERTY = "hasNotUserProperty";
private final int functionType;
/**
* @param userCourseEnv
* @param functionType the type of function (use defined constants)
*/
public EvalUserPropertyFunction(UserCourseEnvironment userCourseEnv, int functionType) {
super(userCourseEnv);
this.functionType = functionType;
if (functionType < 0 | functionType > 5){
throw new OLATRuntimeException("This function type index is undefined: " + functionType, null);
}
}
/**
* Searches the searchValue in the corresponding userValue with the intended method
* function
*
* @param searchValue
* The expression to search for.
* @param userValue
* The property value(s)
* @return true if found, false otherwise
*/
private boolean checkPropertyValue(String searchValue, String userValue) {
switch (functionType) {
case FUNCTION_TYPE_HAS_PROPERTY:
if (userValue.equals(searchValue)) return true;
break;
case FUNCTION_TYPE_HAS_NOT_PROPERTY:
if (!userValue.equals(searchValue)) return true;
break;
case FUNCTION_TYPE_PROPERTY_STARTS_WITH:
if ((userValue.startsWith(searchValue))) return true;
break;
case FUNCTION_TYPE_PROPERTY_ENDS_WITH:
if (userValue.endsWith(searchValue)) return true;
break;
case FUNCTION_TYPE_IS_IN_PROPERTY:
if (userValue.indexOf(searchValue) > -1) return true;
break;
case FUNCTION_TYPE_IS_NOT_IN_PROPERTY:
if (userValue.indexOf(searchValue) == -1) return true;
break;
default:
return false;
}
return false;
}
/**
* @see com.neemsoft.jmep.FunctionCB#call(java.lang.Object[])
*/
public Object call(Object[] inStack) {
/*
* argument check
*/
if (inStack.length > 2) {
String name = getFunctionName(functionType);
return handleException( new ArgumentParseException(ArgumentParseException.NEEDS_FEWER_ARGUMENTS, name, "", "error.fewerargs",
"solution.providetwo.attrvalue"));
} else if (inStack.length < 2) {
String name = getFunctionName(functionType);
return handleException( new ArgumentParseException(ArgumentParseException.NEEDS_MORE_ARGUMENTS, name, "",
"error.moreargs", "solution.providetwo.attrvalue"));
}
/*
* argument type check
*/
if (!(inStack[0] instanceof String)) {
String name = getFunctionName(functionType);
return handleException( new ArgumentParseException(ArgumentParseException.WRONG_ARGUMENT_FORMAT, name, "",
"error.argtype.attributename", "solution.example.name.infunction"));
}
if (!(inStack[1] instanceof String)){
String name = getFunctionName(functionType);
return handleException( new ArgumentParseException(ArgumentParseException.WRONG_ARGUMENT_FORMAT, name, "",
"error.argtype.attribvalue", "solution.example.name.infunction"));
}else {
String propValue = (String) inStack[1];
if(!StringHelper.containsNonWhitespace(propValue)){
String name = getFunctionName(functionType);
return handleException( new ArgumentParseException(ArgumentParseException.WRONG_ARGUMENT_FORMAT, name, "",
"error.argtype.attribvalue", "solution.example.whiteSpace"));
}
}
/*
* check reference integrity
*/
CourseEditorEnv cev = getUserCourseEnv().getCourseEditorEnv();
if (cev != null) {
// return a valid value to continue with condition evaluation test
return defaultValue();
}
/*
* the real function evaluation which is used during run time
*/
String propName = (String) inStack[0];
String searchValue = (String) inStack[1];
Identity ident = getUserCourseEnv().getIdentityEnvironment().getIdentity();
if(ident == null) {
return defaultValue();
}
User user = ident.getUser();
String userValue = user.getPropertyOrIdentityEnvAttribute(propName, null);
boolean match = false;
boolean debug = log.isDebug();
if (debug) {
log.debug("value : " + userValue);
log.debug("searchValue: " + searchValue);
log.debug("fT : " + functionType);
}
if (StringHelper.containsNonWhitespace(userValue)) {
match = checkPropertyValue(searchValue, userValue);
}
if (debug) {
log.debug("identity '" + ident.getName() + "' tested on properties '" + propName + "' to have value '" +
searchValue + "' user's value was '" + userValue + "', match=" + match);
}
return match ? ConditionInterpreter.INT_TRUE : ConditionInterpreter.INT_FALSE;
}
protected Object defaultValue() {
return ConditionInterpreter.INT_FALSE;
}
private String getFunctionName(int type){
switch (type) {
case FUNCTION_TYPE_HAS_PROPERTY:
return FUNCTION_NAME_HAS_PROPERTY;
case FUNCTION_TYPE_HAS_NOT_PROPERTY:
return FUNCTION_NAME_HAS_NOT_PROPERTY;
case FUNCTION_TYPE_PROPERTY_STARTS_WITH:
return FUNCTION_NAME_PROPERTY_STARTS_WITH;
case FUNCTION_TYPE_PROPERTY_ENDS_WITH:
return FUNCTION_NAME_PROPERTY_ENDS_WITH;
case FUNCTION_TYPE_IS_IN_PROPERTY:
return FUNCTION_NAME_IS_IN_PROPERTY;
case FUNCTION_TYPE_IS_NOT_IN_PROPERTY:
return FUNCTION_NAME_IS_NOT_IN_PROPERTY;
default:
return "unknown EvalUserPropertyFunction";
}
}
}