/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/
package com.dangdang.ddframe.rdb.sharding.jdbc.util;
import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.AbstractList;
import java.util.ArrayList;
/**
* 参数列表.
* 对外提供参数值统一访问方式
*
* @author gaohongtao
*/
@RequiredArgsConstructor
public class ParameterList extends AbstractList<Object> {
@Getter
private final ArrayList<JdbcMethodInvocation> jdbcMethodInvocations = new ArrayList<>();
private final Class<?> targetClass;
/**
* 使用索引记录方法调用.
*
* @param index 索引
* @param methodName 方法名称
* @param argumentTypes 参数类型
* @param arguments 参数
*/
public final void recordMethodInvocation(final int index, final String methodName, final Class<?>[] argumentTypes, final Object[] arguments) {
jdbcMethodInvocations.ensureCapacity(index);
int max = jdbcMethodInvocations.size();
while (max++ <= index - 1) {
jdbcMethodInvocations.add(null);
}
try {
jdbcMethodInvocations.set(index - 1, new JdbcMethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments));
} catch (final NoSuchMethodException ex) {
throw new ShardingJdbcException(ex);
}
}
/**
* 回放记录的方法调用.
*
* @param target 目标对象
*/
public final void replayMethodsInvocation(final Object target) {
for (JdbcMethodInvocation each : jdbcMethodInvocations) {
each.invoke(target);
}
}
@Override
public boolean add(final Object o) {
int index = jdbcMethodInvocations.size() + 1;
recordMethodInvocation(index, "setObject", new Class[]{int.class, Object.class}, new Object[]{index, o});
return true;
}
/**
* 根据索引设置列表中的值.
*
* @param index 索引
* @param element 元素值
* @return 原有元素值
*/
@Override
public Object set(final int index, final Object element) {
Object origin = jdbcMethodInvocations.get(index).getArguments()[1];
jdbcMethodInvocations.get(index).getArguments()[1] = element;
return origin;
}
/**
* 获取索引位置的调用对象.
*
* @param index 索引
* @return 调用对象
*/
@Override
public Object get(final int index) {
JdbcMethodInvocation invocation = jdbcMethodInvocations.get(index);
if (null == invocation) {
return null;
}
if ("setNull".equals(invocation.getMethod().getName())) {
return null;
}
return jdbcMethodInvocations.get(index).getArguments()[1];
}
/**
* 列表中元素的数量.
*
* @return 列表中元素数量
*/
@Override
public int size() {
return jdbcMethodInvocations.size();
}
/**
* 清空容器.
*/
@Override
public void clear() {
jdbcMethodInvocations.clear();
}
}