/*
* Copyright 2014 mango.jfaster.org
*
* The Mango Project 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.jfaster.mango.binding;
import org.jfaster.mango.type.TypeHandler;
import javax.annotation.Nullable;
import java.util.*;
/**
* @author ash
*/
public class DefaultInvocationContext implements InvocationContext {
private final Map<String, Object> parameterNameToValueMap = new LinkedHashMap<String, Object>();
private final List<Object> parameterValues = new LinkedList<Object>();
private final Map<String, Object> cache = new HashMap<String, Object>();
private final StringBuilder sql = new StringBuilder();
private final List<Object> args = new LinkedList<Object>();
private final List<TypeHandler<?>> typeHandlers = new LinkedList<TypeHandler<?>>();
private String globalTable;
private DefaultInvocationContext() {
}
public static DefaultInvocationContext create() {
return new DefaultInvocationContext();
}
@Override
public void addParameter(String parameterName, Object parameterValue) {
parameterNameToValueMap.put(parameterName, parameterValue);
parameterValues.add(parameterValue);
}
@Override
public Object getBindingValue(BindingParameterInvoker invoker) {
Object value = getNullableBindingValue(invoker);
if (value == null) {
throw new BindingException("Parameter '" + invoker.getBindingParameter() + "' need a non-null value");
}
return value;
}
@Override
@Nullable
public Object getNullableBindingValue(BindingParameterInvoker invoker) {
String key = getCacheKey(invoker);
if (cache.containsKey(key)) { // 有可能缓存null对象
return cache.get(key);
}
String parameterName = invoker.getBindingParameter().getParameterName();
if (!parameterNameToValueMap.containsKey(parameterName)) { // ParameterContext进行过检测,理论上这段代码执行不到
throw new BindingException("Parameter '" + BindingParameter.create(parameterName, "", null) + "' not found, " +
"available root parameters are " + transToBindingParameters(parameterNameToValueMap.keySet()));
}
Object obj = parameterNameToValueMap.get(parameterName);
Object value = invoker.invoke(obj);
cache.put(key, value);
return value;
}
@Override
public void setBindingValue(BindingParameterInvoker invoker, Object value) {
String key = getCacheKey(invoker);
cache.put(key, value);
}
@Override
@Nullable
public String getGlobalTable() {
return globalTable;
}
@Override
public void setGlobalTable(String globalTable) {
this.globalTable = globalTable;
}
@Override
public void writeToSqlBuffer(String str) {
sql.append(str);
}
@Override
public void appendToArgs(Object obj, TypeHandler<?> typeHandler) {
args.add(obj);
typeHandlers.add(typeHandler);
}
@Override
public BoundSql getBoundSql() {
return new BoundSql(sql.toString(), args, typeHandlers);
}
@Override
public List<Object> getParameterValues() {
return parameterValues;
}
private String getCacheKey(BindingParameterInvoker invoker) {
return invoker.getBindingParameter().getFullName();
}
private Set<BindingParameter> transToBindingParameters(Collection<String> parameterNames) {
Set<BindingParameter> rs = new LinkedHashSet<BindingParameter>();
for (String parameterName : parameterNames) {
rs.add(BindingParameter.create(parameterName, "", null));
}
return rs;
}
}