All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jfaster.mango.binding.DefaultInvocationContext Maven / Gradle / Ivy

The newest version!
/*
 * 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 org.jfaster.mango.util.Strings;

import javax.annotation.Nullable;
import java.util.*;

/**
 * @author ash
 */
public class DefaultInvocationContext implements InvocationContext {

  private final Map parameterNameToValueMap = new LinkedHashMap();
  private final List parameterValues = new LinkedList();
  private final Map cache = new HashMap();

  private final StringBuilder sql = new StringBuilder();
  private final List args = new LinkedList();
  private final List> typeHandlers = new LinkedList>();

  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 trim(String str) {
    if (Strings.isEmpty(str)) {
      return;
    }
    int start = sql.lastIndexOf(str);
    if (start == -1) {
      return;
    }
    int end = sql.length();
    boolean needTrim = true;
    for (int i = start + str.length(); i < end; i++) {
      if (sql.charAt(i) != ' ') {
        needTrim = false;
        break;
      }
    }
    if (needTrim) {
      sql.delete(start, end);
    }
  }

  @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, args, typeHandlers);
  }

  @Override
  public List getParameterValues() {
    return parameterValues;
  }

  private String getCacheKey(BindingParameterInvoker invoker) {
    return invoker.getBindingParameter().getFullName();
  }

  private Set transToBindingParameters(Collection parameterNames) {
    Set rs = new LinkedHashSet();
    for (String parameterName : parameterNames) {
      rs.add(BindingParameter.create(parameterName, "", null));
    }
    return rs;
  }

}