| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.commons.jexl2; |
| |
| import java.math.MathContext; |
| |
| /** |
| * A derived arithmetic that allows different threads to operate with |
| * different strict/lenient/math modes using the same JexlEngine. |
| * @since 2.1 |
| */ |
| public class JexlThreadedArithmetic extends JexlArithmetic { |
| |
| /** Holds the threaded version of some arithmetic features. */ |
| static class Features { |
| /** Default ctor. */ |
| Features() {} |
| /** Whether this JexlArithmetic instance behaves in strict or lenient mode. */ |
| private Boolean lenient = null; |
| /** The big decimal math context. */ |
| private MathContext mathContext = null; |
| /** The big decimal scale. */ |
| private Integer mathScale = null; |
| } |
| |
| /** |
| * Standard ctor. |
| * @param lenient lenient versus strict evaluation flag |
| */ |
| public JexlThreadedArithmetic(boolean lenient) { |
| super(lenient); |
| } |
| |
| /** |
| * Creates a JexlThreadedArithmetic instance. |
| * @param lenient whether this arithmetic is lenient or strict |
| * @param bigdContext the math context instance to use for +,-,/,*,% operations on big decimals. |
| * @param bigdScale the scale used for big decimals. |
| */ |
| public JexlThreadedArithmetic(boolean lenient, MathContext bigdContext, int bigdScale) { |
| super(lenient, bigdContext, bigdScale); |
| } |
| |
| /** Whether this JexlArithmetic instance behaves in strict or lenient mode for this thread. */ |
| static final ThreadLocal<Features> FEATURES = new ThreadLocal<Features>() { |
| @Override |
| protected synchronized Features initialValue() { |
| return new Features(); |
| } |
| }; |
| |
| |
| /** |
| * Overrides the default behavior and sets whether this JexlArithmetic instance triggers errors |
| * during evaluation when null is used as an operand for the current thread. |
| * <p>It is advised to protect calls by either calling JexlThreadedArithmetic.setLenient explicitly |
| * before evaluation or add a try/finally clause resetting the flag to avoid unexpected reuse of the lenient |
| * flag value through thread pools side-effects.</p> |
| * @see JexlEngine#setSilent |
| * @see JexlEngine#setDebug |
| * @param flag true means no JexlException will occur, false allows them, null reverts to default behavior |
| */ |
| public static void setLenient(Boolean flag) { |
| FEATURES.get().lenient = flag; |
| } |
| |
| /** |
| * Sets the math scale. |
| * <p>The goal and constraints are the same than for setLenient.</p> |
| * @param scale the scale |
| */ |
| public static void setMathScale(Integer scale) { |
| FEATURES.get().mathScale = scale; |
| } |
| |
| /** |
| * Sets the math context. |
| * <p>The goal and constraints are the same than for setLenient.</p> |
| * @param mc the math context |
| */ |
| public static void setMathContext(MathContext mc) { |
| FEATURES.get().mathContext = mc; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| public boolean isLenient() { |
| Boolean lenient = FEATURES.get().lenient; |
| return lenient == null ? super.isLenient() : lenient.booleanValue(); |
| } |
| |
| @Override |
| public int getMathScale() { |
| Integer scale = FEATURES.get().mathScale; |
| return scale == null ? super.getMathScale() : scale.intValue(); |
| } |
| |
| @Override |
| public MathContext getMathContext() { |
| MathContext mc = FEATURES.get().mathContext; |
| return mc == null? super.getMathContext() : mc; |
| } |
| } |