/* * Copyright (C) 2012-2015 DataStax Inc. * * 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 com.datastax.driver.mapping; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; class AccessorInvocationHandler<T> implements InvocationHandler { private static final Object[] NO_ARGS = new Object[0]; private static final Method TO_STRING; private static final Method EQUALS; private static final Method HASH_CODE; static { try { TO_STRING = Object.class.getMethod("toString"); EQUALS = Object.class.getMethod("equals", Object.class); HASH_CODE = Object.class.getMethod("hashCode"); } catch (NoSuchMethodException e) { throw new AssertionError(e); // Can't happen } } private final AccessorMapper<T> mapper; private final Map<Method, MethodMapper> methodMap = new HashMap<Method, MethodMapper>(); AccessorInvocationHandler(AccessorMapper<T> mapper) { this.mapper = mapper; for (MethodMapper method : mapper.methods) methodMap.put(method.method, method); } @Override public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { if (m.equals(TO_STRING)) return mapper.daoClass.getSimpleName() + " implementation generated by the Cassandra driver mapper"; // It's unlikely that equals and hashCode will be used on accessor implementations, but better safe than sorry. // Identity equality is enough, given that the mapper always returns the same instance for a given accessor. if (m.equals(EQUALS)) return proxy == args[0]; if (m.equals(HASH_CODE)) return System.identityHashCode(proxy); MethodMapper method = methodMap.get(m); if (method == null) throw new UnsupportedOperationException(); return method.invoke(args == null ? NO_ARGS : args); } }