001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.core.impl.parameter;
017
018
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.coreservice.api.parameter.EvaluationOperator;
021import org.kuali.rice.coreservice.api.parameter.Parameter;
022import org.kuali.rice.core.api.parameter.ParameterEvaluator;
023import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
024import org.kuali.rice.coreservice.framework.parameter.ParameterService;
025
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029
030public class ParameterEvaluatorServiceImpl implements ParameterEvaluatorService {
031
032    private ParameterService parameterService;
033
034    public void setParameterService(ParameterService parameterService) {
035        this.parameterService = parameterService;
036    }
037
038    /**
039         * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
040         * corresponding to the specified componentClass and parameterName and the values of the Parameter.
041         *
042         * @param componentClass
043         * @param parameterName
044         * @return ParameterEvaluator instance initialized with the Parameter corresponding to the specified componentClass and
045         *         parameterName and the values of the Parameter
046         */
047        @Override
048        public ParameterEvaluator getParameterEvaluator(Class componentClass, String parameterName) {
049            return getParameterEvaluator(parameterService.getParameter(componentClass, parameterName));
050        }
051
052        /**
053     * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
054     * corresponding to the specified componentClass and parameterName and the values of the Parameter.
055     *
056     * @param namespaceCode
057     * @param detailTypeCode
058     * @param parameterName
059     * @return ParameterEvaluator instance initialized with the Parameter corresponding to the specified componentClass and
060     *         parameterName and the values of the Parameter
061     */
062    @Override
063        public ParameterEvaluator getParameterEvaluator(String namespaceCode, String detailTypeCode, String parameterName) {
064        return getParameterEvaluator(parameterService.getParameter(namespaceCode, detailTypeCode, parameterName));
065    }
066
067        /**
068         * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
069         * corresponding to the specified componentClass and parameterName, the values of the Parameter, the knowledge of whether the
070         * values are allowed or denied, and the constrainedValue.
071         *
072         * @param componentClass
073         * @param parameterName
074         * @return ParameterEvaluator instance initialized with the Parameter corresponding to the specified componentClass and
075         *         parameterName, the values of the Parameter, the knowledge of whether the values are allowed or denied, and the
076         *         constrainedValue
077         */
078        @Override
079        public ParameterEvaluator getParameterEvaluator(Class componentClass, String parameterName, String constrainedValue) {
080            return getParameterEvaluator(parameterService.getParameter(componentClass, parameterName), constrainedValue);
081        }
082
083        /**
084     * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
085     * corresponding to the specified componentClass and parameterName and the values of the Parameter.
086     *
087     * @param namespaceCode
088     * @param detailTypeCode
089     * @param parameterName
090     * @return ParameterEvaluator instance initialized with the Parameter corresponding to the specified componentClass and
091     *         parameterName and the values of the Parameter
092     */
093        @Override
094    public ParameterEvaluator getParameterEvaluator(String namespaceCode, String detailTypeCode, String parameterName, String constrainedValue) {
095        return getParameterEvaluator(parameterService.getParameter(namespaceCode, detailTypeCode, parameterName), constrainedValue);
096    }
097
098        /**
099         * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
100         * corresponding to the specified componentClass and parameterName, the values of the Parameter that correspond to the specified
101         * constrainingValue, the knowledge of whether the values are allowed or denied, and the constrainedValue.
102         *
103         * @param componentClass
104         * @param parameterName
105         * @return ParameterEvaluator instance initialized with the Parameter corresponding to the specified componentClass and
106         *         parameterName, the values of the Parameter that correspond to the specified constrainingValue, the knowledge of
107         *         whether the values are allowed or denied, and the constrainedValue
108         */
109        @Override
110        public ParameterEvaluator getParameterEvaluator(Class componentClass, String parameterName, String constrainingValue,
111                        String constrainedValue) {
112                            return getParameterEvaluator(parameterService.getParameter(componentClass, parameterName), constrainingValue, constrainedValue);
113                        }
114
115        /**
116         * This method will return an instance of the parameterEvaluator bean defined in Spring, initialized with the Parameter
117         * corresponding to the specified componentClass and allowParameterName or to the specified componentClass and denyParameterName
118         * (depending on which restricts based on the constraining value) or an instance of AlwaysSucceedParameterEvaluatorImpl if
119         * neither restricts, the values of the Parameter that correspond to the specified constrainingValue, the knowledge of whether
120         * the values are allowed or denied, and the constrainedValue.
121         *
122         * @param componentClass
123         * @param allowParameterName
124         * @param denyParameterName
125         * @param constrainingValue
126         * @param constrainedValue
127         * @return AlwaysSucceedParameterEvaluatorImpl or ParameterEvaluator instance initialized with the Parameter that corresponds to
128         *         the constrainingValue restriction, the values of the Parameter that correspond to the specified constrainingValue,
129         *         the knowledge of whether the values are allowed or denied, and the constrainedValue
130         */
131        @Override
132        public ParameterEvaluator getParameterEvaluator(Class componentClass, String allowParameterName, String denyParameterName,
133                        String constrainingValue, String constrainedValue) {
134                            Parameter allowParameter = parameterService.getParameter(componentClass, allowParameterName);
135                            Parameter denyParameter = parameterService.getParameter(componentClass, denyParameterName);
136                            if (!getParameterValues(allowParameter, constrainingValue).isEmpty() && !getParameterValues(denyParameter, constrainingValue).isEmpty()) {
137                                throw new IllegalArgumentException("The getParameterEvaluator(Class componentClass, String allowParameterName, String denyParameterName, String constrainingValue, String constrainedValue) method of ParameterServiceImpl does not facilitate evaluation of combination allow and deny parameters that both have values for the constraining value: " + allowParameterName + " / " + denyParameterName + " / " + constrainingValue);
138                            }
139                            if (getParameterValues(allowParameter, constrainingValue).isEmpty() && getParameterValues(denyParameter, constrainingValue).isEmpty()) {
140                                return AlwaysSucceedParameterEvaluatorImpl.getInstance();
141                            }
142                            return getParameterEvaluator(getParameterValues(denyParameter, constrainingValue).isEmpty() ? allowParameter : denyParameter, constrainingValue, constrainedValue);
143        }
144
145    protected List<String> getParameterValues(Parameter parameter, String constrainingValue) {
146            List<String> constraintValuePairs = getParameterValues(parameter);
147            for (String pair : constraintValuePairs) {
148                if (StringUtils.equals(constrainingValue, StringUtils.substringBefore(pair, "="))) {
149                    return Arrays.asList(StringUtils.substringAfter(pair, "=").split(","));
150                }
151            }
152            return Collections.emptyList();
153        }
154
155    private List<String> getParameterValues(Parameter parameter) {
156            if (parameter == null || StringUtils.isBlank(parameter.getValue())) {
157                return Collections.emptyList();
158            }
159            return Arrays.asList(parameter.getValue().split(";"));
160        }
161
162    protected ParameterEvaluatorImpl getParameterEvaluator(Parameter parameter) {
163            ParameterEvaluatorImpl parameterEvaluator = new ParameterEvaluatorImpl();
164            parameterEvaluator.setParameter(parameter);
165            parameterEvaluator.setConstraintIsAllow(constraintIsAllow(parameter));
166            parameterEvaluator.setValues(getParameterValues(parameter));
167            return parameterEvaluator;
168        }
169
170        protected ParameterEvaluatorImpl getParameterEvaluator(Parameter parameter, String constrainedValue) {
171            ParameterEvaluatorImpl parameterEvaluator = getParameterEvaluator(parameter);
172            parameterEvaluator.setConstrainedValue(constrainedValue);
173            return parameterEvaluator;
174        }
175
176        protected ParameterEvaluatorImpl getParameterEvaluator(Parameter parameter, String constrainingValue,
177                        String constrainedValue) {
178            ParameterEvaluatorImpl parameterEvaluator = getParameterEvaluator(parameter, constrainedValue);
179            parameterEvaluator.setValues(getParameterValues(parameter, constrainingValue));
180            return parameterEvaluator;
181        }
182
183    private boolean constraintIsAllow(Parameter parameter) {
184            return EvaluationOperator.ALLOW.equals(parameter.getEvaluationOperator());
185        }
186}