/** * MVEL 2.0 * Copyright (C) 2007 The Codehaus * Mike Brock, Dhanji Prasanna, John Graham, Mark Proctor * * 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 org.mvel2.integration.impl; import org.mvel2.ast.Function; import org.mvel2.integration.VariableResolver; import org.mvel2.integration.VariableResolverFactory; import java.util.HashMap; public class FunctionVariableResolverFactory extends BaseVariableResolverFactory implements LocalVariableResolverFactory { private Function function; public FunctionVariableResolverFactory(Function function, VariableResolverFactory nextFactory, String[] indexedVariables, Object[] parameters) { this.function = function; this.variableResolvers = new HashMap<String, VariableResolver>(); this.nextFactory = nextFactory; this.indexedVariableResolvers = new VariableResolver[(this.indexedVariableNames = indexedVariables).length]; for (int i = 0; i < parameters.length; i++) { variableResolvers.put(indexedVariableNames[i], null); this.indexedVariableResolvers[i] = new SimpleValueResolver(parameters[i]); // variableResolvers.put(indexedVariableNames[i], this.indexedVariableResolvers[i] = new SimpleValueResolver(parameters[i])); } } public boolean isResolveable(String name) { return variableResolvers.containsKey(name) || (nextFactory != null && nextFactory.isResolveable(name)); } public VariableResolver createVariable(String name, Object value) { VariableResolver resolver = getVariableResolver(name); if (resolver == null) { int idx = increaseRegisterTableSize(); this.indexedVariableNames[idx] = name; this.indexedVariableResolvers[idx] = new SimpleValueResolver(value); variableResolvers.put(name, null); // variableResolvers.put(name, this.indexedVariableResolvers[idx] = new SimpleValueResolver(value)); return this.indexedVariableResolvers[idx]; } else { resolver.setValue(value); return resolver; } } public VariableResolver createVariable(String name, Object value, Class<?> type) { VariableResolver vr = this.variableResolvers != null ? this.variableResolvers.get(name) : null; if (vr != null && vr.getType() != null) { throw new RuntimeException("variable already defined within scope: " + vr.getType() + " " + name); } else { return createIndexedVariable(variableIndexOf(name), name, value); } } public VariableResolver createIndexedVariable(int index, String name, Object value) { index = index - indexOffset; if (indexedVariableResolvers[index] != null) { indexedVariableResolvers[index].setValue(value); } else { indexedVariableResolvers[index] = new SimpleValueResolver(value); } variableResolvers.put(name, null); return indexedVariableResolvers[index]; } public VariableResolver createIndexedVariable(int index, String name, Object value, Class<?> type) { index = index - indexOffset; if (indexedVariableResolvers[index] != null) { indexedVariableResolvers[index].setValue(value); } else { indexedVariableResolvers[index] = new SimpleValueResolver(value); } return indexedVariableResolvers[index]; } public VariableResolver getIndexedVariableResolver(int index) { if (indexedVariableResolvers[index] == null) { /** * If the register is null, this means we need to forward-allocate the variable onto the * register table. */ return indexedVariableResolvers[index] = super.getVariableResolver(indexedVariableNames[index]); } return indexedVariableResolvers[index]; } public VariableResolver getVariableResolver(String name) { int idx; // if (variableResolvers.containsKey(name)) return variableResolvers.get(name); if ((idx = variableIndexOf(name)) != -1) { if (indexedVariableResolvers[idx] == null) { indexedVariableResolvers[idx] = new SimpleValueResolver(null); } variableResolvers.put(indexedVariableNames[idx], null); return indexedVariableResolvers[idx]; } return super.getVariableResolver(name); } public boolean isIndexedFactory() { return true; } public boolean isTarget(String name) { return variableResolvers.containsKey(name) || variableIndexOf(name) != -1; } private int increaseRegisterTableSize() { String[] oldNames = indexedVariableNames; VariableResolver[] oldResolvers = indexedVariableResolvers; int newLength = oldNames.length + 1; indexedVariableNames = new String[newLength]; indexedVariableResolvers = new VariableResolver[newLength]; for (int i = 0; i < oldNames.length; i++) { indexedVariableNames[i] = oldNames[i]; indexedVariableResolvers[i] = oldResolvers[i]; } return newLength - 1; } public void updateParameters(Object[] parameters) { // this.indexedVariableResolvers = new VariableResolver[parameters.length]; for (int i = 0; i < parameters.length; i++) { this.indexedVariableResolvers[i] = new SimpleValueResolver(parameters[i]); } // for (int i = parameters.length; i < indexedVariableResolvers.length; i++) { // this.indexedVariableResolvers[i] = null; // } } public VariableResolver[] getIndexedVariableResolvers() { return this.indexedVariableResolvers; } public void setIndexedVariableResolvers(VariableResolver[] vr) { this.indexedVariableResolvers = vr; } public Function getFunction() { return function; } public void setIndexOffset(int offset) { this.indexOffset = offset; } private boolean noTilt = false; public VariableResolverFactory setNoTilt(boolean noTilt) { this.noTilt = noTilt; return this; } @Override public void setTiltFlag(boolean tiltFlag) { if (!noTilt) super.setTiltFlag(tiltFlag); } }