/* * Copyright (c) 2013-2017 Evolveum * * 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 com.evolveum.midpoint.model.impl.expr; import java.util.ArrayDeque; import java.util.Deque; import com.evolveum.midpoint.model.common.expression.Expression; import com.evolveum.midpoint.model.common.expression.ExpressionEvaluationContext; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; /** * @author Radovan Semancik * */ public class ModelExpressionThreadLocalHolder { private static ThreadLocal<Deque<ExpressionEnvironment<ObjectType>>> expressionEnvironmentStackTl = new ThreadLocal<>(); public static <F extends ObjectType> void pushExpressionEnvironment(ExpressionEnvironment<F> env) { Deque<ExpressionEnvironment<ObjectType>> stack = expressionEnvironmentStackTl.get(); if (stack == null) { stack = new ArrayDeque<>(); expressionEnvironmentStackTl.set(stack); } stack.push((ExpressionEnvironment<ObjectType>)env); } public static <F extends ObjectType> void popExpressionEnvironment() { Deque<ExpressionEnvironment<ObjectType>> stack = expressionEnvironmentStackTl.get(); stack.pop(); } public static <F extends ObjectType> ExpressionEnvironment<F> getExpressionEnvironment() { Deque<ExpressionEnvironment<ObjectType>> stack = expressionEnvironmentStackTl.get(); if (stack == null) { return null; } return (ExpressionEnvironment<F>) stack.peek(); } public static <F extends ObjectType> LensContext<F> getLensContext() { ExpressionEnvironment<ObjectType> env = getExpressionEnvironment(); if (env == null) { return null; } return (LensContext<F>) env.getLensContext(); } public static <F extends ObjectType> LensProjectionContext getProjectionContext() { ExpressionEnvironment<ObjectType> env = getExpressionEnvironment(); if (env == null) { return null; } return env.getProjectionContext(); } public static Task getCurrentTask() { ExpressionEnvironment<ObjectType> env = getExpressionEnvironment(); if (env == null) { return null; } return env.getCurrentTask(); } public static OperationResult getCurrentResult() { ExpressionEnvironment<ObjectType> env = getExpressionEnvironment(); if (env == null) { return null; } return env.getCurrentResult(); } // TODO move to better place public static <T> PrismValueDeltaSetTriple<PrismPropertyValue<T>> evaluateExpressionInContext(Expression<PrismPropertyValue<T>, PrismPropertyDefinition<T>> expression, ExpressionEvaluationContext context, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result)); try { return expression.evaluate(context); } finally { ModelExpressionThreadLocalHolder.popExpressionEnvironment(); } } public static PrismValueDeltaSetTriple<PrismReferenceValue> evaluateRefExpressionInContext(Expression<PrismReferenceValue, PrismReferenceDefinition> expression, ExpressionEvaluationContext context, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result)); try { return expression.evaluate(context); } finally { ModelExpressionThreadLocalHolder.popExpressionEnvironment(); } } public static <T> PrismValueDeltaSetTriple<PrismPropertyValue<T>> evaluateExpressionInContext(Expression<PrismPropertyValue<T>, PrismPropertyDefinition<T>> expression, ExpressionEvaluationContext context, LensContext<?> lensContext, LensProjectionContext projectionContext, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { ExpressionEnvironment<?> env = new ExpressionEnvironment<>(lensContext, projectionContext, task, result); ModelExpressionThreadLocalHolder.pushExpressionEnvironment(env); PrismValueDeltaSetTriple<PrismPropertyValue<T>> exprResultTriple; try { exprResultTriple = expression.evaluate(context); } finally { ModelExpressionThreadLocalHolder.popExpressionEnvironment(); } return exprResultTriple; } }