package com.jstarcraft.core.cache.proxy;_x000D_
_x000D_
import java.lang.reflect.Method;_x000D_
import java.lang.reflect.Modifier;_x000D_
import java.util.HashSet;_x000D_
_x000D_
import com.jstarcraft.core.cache.CacheInformation;_x000D_
import com.jstarcraft.core.cache.annotation.CacheChange;_x000D_
import com.jstarcraft.core.common.conversion.ConversionUtility;_x000D_
import com.jstarcraft.core.utility.StringUtility;_x000D_
_x000D_
import javassist.CtClass;_x000D_
import javassist.CtMethod;_x000D_
_x000D_
/**_x000D_
 * 实体代理_x000D_
 * _x000D_
 * @author Birdy_x000D_
 *_x000D_
 */_x000D_
public class JavassistEntityProxy extends JavassistProxy {_x000D_
_x000D_
    public JavassistEntityProxy(ProxyManager proxyManager, CacheInformation cacheInformation) {_x000D_
        super(proxyManager, cacheInformation);_x000D_
    }_x000D_
_x000D_
    /**_x000D_
     * 代理方法_x000D_
     * _x000D_
     * <pre>_x000D_
     * // TODO 索引变更部分_x000D_
     * CacheInformation cacheInformation = _manager.getCacheInformation();_x000D_
     * String[] values = _indexChange != null ? _indexChange.values() : new String[] {};_x000D_
     * TreeSet<String> indexNames = new TreeSet(Arrays.asList(values));_x000D_
     * LinkedList<Lock> locks = new LinkedList<Lock>();_x000D_
     * for (String name : indexNames) {_x000D_
     *     locks.addLast(cacheInformation.getIndexWriteLock(name));_x000D_
     * }_x000D_
     * Object value = null;_x000D_
     * try {_x000D_
     *     for (Lock lock : locks) {_x000D_
     *         lock.lock();_x000D_
     *     }_x000D_
     *     Map<String, Object> oldIndexValues = cacheInformation.getIndexValues(_object, indexNames);_x000D_
     *     value = method.invoke(_object);_x000D_
     *     Map<String, Object> newIndexValues = cacheInformation.getIndexValues(_object, indexNames);_x000D_
     *     boolean result = true;_x000D_
     *     for (Entry<String, Object> entry : newIndexValues.entrySet()) {_x000D_
     *         if (_manager.hasUnique(entry.getKey(), entry.getValue())) {_x000D_
     *             result = false;_x000D_
     *             break;_x000D_
     *         }_x000D_
     *     }_x000D_
     *     if (result) {_x000D_
     *         for (Entry<String, Object> entry : newIndexValues.entrySet()) {_x000D_
     *             _manager.modifyUnique(_object.getId(), entry.getKey(), entry.getValue());_x000D_
     *         }_x000D_
     *     } else {_x000D_
     *         cacheInformation.setIndexValues(_object, oldIndexValues);_x000D_
     *     }_x000D_
     * } finally {_x000D_
     *     for (Lock lock : locks) {_x000D_
     *         lock.unlock();_x000D_
     *     }_x000D_
     * }_x000D_
     * // TODO 数据变更部分_x000D_
     * if (_dataChange != null) {_x000D_
     *     if (returnType == void.class) {_x000D_
     *         _manager.modifyDatas(_object.getId(), _object);_x000D_
     *     } else {_x000D_
     *         TreeSet<String> resultValues = new TreeSet(Arrays.asList(_dataChange.values()));_x000D_
     *         if (resultValues.contains(value.toString())) {_x000D_
     *             _manager.modifyDatas(_object.getId(), _object);_x000D_
     *         }_x000D_
     *     }_x000D_
     * }_x000D_
     * // TODO 返回值部分_x000D_
     * if (returnType != void.class) {_x000D_
     *     return value;_x000D_
     * }_x000D_
     * </pre>_x000D_
     */_x000D_
    final void proxyMethod(Class<?> clazz, CtClass proxyClazz, Method method, CacheChange cacheChange) throws Exception {_x000D_
        Class<?> returnType = method.getReturnType();_x000D_
        CtMethod proxyMethod = new CtMethod(classPool.get(returnType.getName()), method.getName(), toProxyClasses(method.getParameterTypes()), proxyClazz);_x000D_
        proxyMethod.setModifiers(Modifier.PUBLIC);_x000D_
        if (method.getExceptionTypes().length != 0) {_x000D_
            proxyMethod.setExceptionTypes(toProxyClasses(method.getExceptionTypes()));_x000D_
        }_x000D_
        StringBuilder methodBuffer = new StringBuilder("{");_x000D_
        methodBuffer.append(StringUtility.format("{} methodId = {}.valueOf({});", Integer.class.getName(), Integer.class.getName(), cacheInformation.getMethodId(method)));_x000D_
        methodBuffer.append(StringUtility.format("{} changeValues = _information.getMethodChanges(methodId);", HashSet.class.getName()));_x000D_
        // TODO 索引变更部分_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("{} indexNames = ({})_x000D_
        // (keyValue.getKey());", TreeSet.class.getName(), TreeSet.class.getName()));_x000D_
        // methodBuilder.append(StringUtility.format("{} newIndexValues = new {}();",_x000D_
        // HashMap.class.getName(), HashMap.class.getName()));_x000D_
        // for (Entry<IndexChange, Integer> entry : indexChanges.entrySet()) {_x000D_
        // methodBuilder.append(StringUtility.format("indexNames.add(\"{}\");",_x000D_
        // entry.getKey().value()));_x000D_
        // methodBuilder.append(StringUtility.format("newIndexValues.put(\"{}\",_x000D_
        // {}.primitiveToWrap(${}));", entry.getKey().value(),_x000D_
        // ConversionUtility.class.getName(), entry.getValue()));_x000D_
        // }_x000D_
        // }_x000D_
        if (returnType != void.class) {_x000D_
            String typeName = returnType.isArray() ? toArrayType(returnType) : returnType.getName();_x000D_
            if (returnType.isPrimitive()) {_x000D_
                methodBuffer.append(StringUtility.format("{} value;", typeName));_x000D_
            } else {_x000D_
                methodBuffer.append(StringUtility.format("{} value = null;", typeName));_x000D_
            }_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("try {"));_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("_x000D_
        // _information.lockIndexWriteLocks(indexNames);"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} checkIterator =_x000D_
        // newIndexValues.entrySet().iterator();", Iterator.class.getName()));_x000D_
        // methodBuilder.append(StringUtility.format(" while(checkIterator.hasNext())_x000D_
        // {"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} entry =_x000D_
        // checkIterator.next();", Entry.class.getName()));_x000D_
        // methodBuilder.append(StringUtility.format(" boolean has =_x000D_
        // _manager.hasIndex((String) entry.getKey(), entry.getValue());"));_x000D_
        // methodBuilder.append(StringUtility.format(" if (has) {"));_x000D_
        // methodBuilder.append(StringUtility.format(" throw new {}();",_x000D_
        // JavassistEntityProxy.TYPE_INDEX_EXCEPTION));_x000D_
        // methodBuilder.append(StringUtility.format(" }"));_x000D_
        // methodBuilder.append(StringUtility.format(" }"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} oldIndexValues =_x000D_
        // _information.getIndexValues(_instance, indexNames);", Map.class.getName()));_x000D_
        // }_x000D_
        if (returnType != void.class) {_x000D_
            methodBuffer.append(StringUtility.format("	value = super.{}($$);", method.getName()));_x000D_
        } else {_x000D_
            methodBuffer.append(StringUtility.format("	super.{}($$);", method.getName()));_x000D_
        }_x000D_
        // TODO 数据变更部分_x000D_
        if (cacheChange != null) {_x000D_
            if (returnType == void.class) {_x000D_
                // if (!indexChanges.isEmpty()) {_x000D_
                // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
                // newIndexValues, oldIndexValues);"));_x000D_
                // }_x000D_
                methodBuffer.append(StringUtility.format(" _manager.modifyInstance(this);"));_x000D_
            } else {_x000D_
                if (cacheChange.values().length > 0) {_x000D_
                    methodBuffer.append(StringUtility.format(" if (changeValues.contains({}.primitiveToWrap(value))) {", ConversionUtility.class.getName()));_x000D_
                }_x000D_
                // if (!indexChanges.isEmpty()) {_x000D_
                // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
                // newIndexValues, oldIndexValues);"));_x000D_
                // }_x000D_
                methodBuffer.append(StringUtility.format("		_manager.modifyInstance(this);"));_x000D_
                if (cacheChange.values().length > 0) {_x000D_
                    methodBuffer.append(StringUtility.format(" }"));_x000D_
                }_x000D_
            }_x000D_
        } else {_x000D_
            // if (!indexChanges.isEmpty()) {_x000D_
            // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
            // newIndexValues, oldIndexValues);"));_x000D_
            // }_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("} finally {"));_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("_x000D_
        // _information.unlockIndexWriteLocks(indexNames);"));_x000D_
        // }_x000D_
        methodBuffer.append(StringUtility.format("}"));_x000D_
        // TODO 返回值部分_x000D_
        if (returnType != void.class) {_x000D_
            methodBuffer.append(StringUtility.format("return value;"));_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("}"));_x000D_
        proxyMethod.setBody(methodBuffer.toString());_x000D_
        proxyClazz.addMethod(proxyMethod);_x000D_
    }_x000D_
_x000D_
}_x000D_

// (keyValue.getKey());", TreeSet.class.getName(), TreeSet.class.getName()));_x000D_
package com.jstarcraft.core.cache.proxy;_x000D_
_x000D_
import java.lang.reflect.Method;_x000D_
import java.lang.reflect.Modifier;_x000D_
import java.util.HashSet;_x000D_
_x000D_
import com.jstarcraft.core.cache.CacheInformation;_x000D_
import com.jstarcraft.core.cache.annotation.CacheChange;_x000D_
import com.jstarcraft.core.common.conversion.ConversionUtility;_x000D_
import com.jstarcraft.core.utility.StringUtility;_x000D_
_x000D_
import javassist.CtClass;_x000D_
import javassist.CtMethod;_x000D_
_x000D_
/**_x000D_
 * 实体代理_x000D_
 * _x000D_
 * @author Birdy_x000D_
 *_x000D_
 */_x000D_
public class JavassistEntityProxy extends JavassistProxy {_x000D_
_x000D_
    public JavassistEntityProxy(ProxyManager proxyManager, CacheInformation cacheInformation) {_x000D_
        super(proxyManager, cacheInformation);_x000D_
    }_x000D_
_x000D_
    /**_x000D_
     * 代理方法_x000D_
     * _x000D_
     * <pre>_x000D_
     * // TODO 索引变更部分_x000D_
     * CacheInformation cacheInformation = _manager.getCacheInformation();_x000D_
     * String[] values = _indexChange != null ? _indexChange.values() : new String[] {};_x000D_
     * TreeSet<String> indexNames = new TreeSet(Arrays.asList(values));_x000D_
     * LinkedList<Lock> locks = new LinkedList<Lock>();_x000D_
     * for (String name : indexNames) {_x000D_
     *     locks.addLast(cacheInformation.getIndexWriteLock(name));_x000D_
     * }_x000D_
     * Object value = null;_x000D_
     * try {_x000D_
     *     for (Lock lock : locks) {_x000D_
     *         lock.lock();_x000D_
     *     }_x000D_
     *     Map<String, Object> oldIndexValues = cacheInformation.getIndexValues(_object, indexNames);_x000D_
     *     value = method.invoke(_object);_x000D_
     *     Map<String, Object> newIndexValues = cacheInformation.getIndexValues(_object, indexNames);_x000D_
     *     boolean result = true;_x000D_
     *     for (Entry<String, Object> entry : newIndexValues.entrySet()) {_x000D_
     *         if (_manager.hasUnique(entry.getKey(), entry.getValue())) {_x000D_
     *             result = false;_x000D_
     *             break;_x000D_
     *         }_x000D_
     *     }_x000D_
     *     if (result) {_x000D_
     *         for (Entry<String, Object> entry : newIndexValues.entrySet()) {_x000D_
     *             _manager.modifyUnique(_object.getId(), entry.getKey(), entry.getValue());_x000D_
     *         }_x000D_
     *     } else {_x000D_
     *         cacheInformation.setIndexValues(_object, oldIndexValues);_x000D_
     *     }_x000D_
     * } finally {_x000D_
     *     for (Lock lock : locks) {_x000D_
     *         lock.unlock();_x000D_
     *     }_x000D_
     * }_x000D_
     * // TODO 数据变更部分_x000D_
     * if (_dataChange != null) {_x000D_
     *     if (returnType == void.class) {_x000D_
     *         _manager.modifyDatas(_object.getId(), _object);_x000D_
     *     } else {_x000D_
     *         TreeSet<String> resultValues = new TreeSet(Arrays.asList(_dataChange.values()));_x000D_
     *         if (resultValues.contains(value.toString())) {_x000D_
     *             _manager.modifyDatas(_object.getId(), _object);_x000D_
     *         }_x000D_
     *     }_x000D_
     * }_x000D_
     * // TODO 返回值部分_x000D_
     * if (returnType != void.class) {_x000D_
     *     return value;_x000D_
     * }_x000D_
     * </pre>_x000D_
     */_x000D_
    final void proxyMethod(Class<?> clazz, CtClass proxyClazz, Method method, CacheChange cacheChange) throws Exception {_x000D_
        Class<?> returnType = method.getReturnType();_x000D_
        CtMethod proxyMethod = new CtMethod(classPool.get(returnType.getName()), method.getName(), toProxyClasses(method.getParameterTypes()), proxyClazz);_x000D_
        proxyMethod.setModifiers(Modifier.PUBLIC);_x000D_
        if (method.getExceptionTypes().length != 0) {_x000D_
            proxyMethod.setExceptionTypes(toProxyClasses(method.getExceptionTypes()));_x000D_
        }_x000D_
        StringBuilder methodBuffer = new StringBuilder("{");_x000D_
        methodBuffer.append(StringUtility.format("{} methodId = {}.valueOf({});", Integer.class.getName(), Integer.class.getName(), cacheInformation.getMethodId(method)));_x000D_
        methodBuffer.append(StringUtility.format("{} changeValues = _information.getMethodChanges(methodId);", HashSet.class.getName()));_x000D_
        // TODO 索引变更部分_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("{} indexNames = ({})_x000D_
        // (keyValue.getKey());", TreeSet.class.getName(),<SUF>
        // methodBuilder.append(StringUtility.format("{} newIndexValues = new {}();",_x000D_
        // HashMap.class.getName(), HashMap.class.getName()));_x000D_
        // for (Entry<IndexChange, Integer> entry : indexChanges.entrySet()) {_x000D_
        // methodBuilder.append(StringUtility.format("indexNames.add(\"{}\");",_x000D_
        // entry.getKey().value()));_x000D_
        // methodBuilder.append(StringUtility.format("newIndexValues.put(\"{}\",_x000D_
        // {}.primitiveToWrap(${}));", entry.getKey().value(),_x000D_
        // ConversionUtility.class.getName(), entry.getValue()));_x000D_
        // }_x000D_
        // }_x000D_
        if (returnType != void.class) {_x000D_
            String typeName = returnType.isArray() ? toArrayType(returnType) : returnType.getName();_x000D_
            if (returnType.isPrimitive()) {_x000D_
                methodBuffer.append(StringUtility.format("{} value;", typeName));_x000D_
            } else {_x000D_
                methodBuffer.append(StringUtility.format("{} value = null;", typeName));_x000D_
            }_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("try {"));_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("_x000D_
        // _information.lockIndexWriteLocks(indexNames);"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} checkIterator =_x000D_
        // newIndexValues.entrySet().iterator();", Iterator.class.getName()));_x000D_
        // methodBuilder.append(StringUtility.format(" while(checkIterator.hasNext())_x000D_
        // {"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} entry =_x000D_
        // checkIterator.next();", Entry.class.getName()));_x000D_
        // methodBuilder.append(StringUtility.format(" boolean has =_x000D_
        // _manager.hasIndex((String) entry.getKey(), entry.getValue());"));_x000D_
        // methodBuilder.append(StringUtility.format(" if (has) {"));_x000D_
        // methodBuilder.append(StringUtility.format(" throw new {}();",_x000D_
        // JavassistEntityProxy.TYPE_INDEX_EXCEPTION));_x000D_
        // methodBuilder.append(StringUtility.format(" }"));_x000D_
        // methodBuilder.append(StringUtility.format(" }"));_x000D_
        // methodBuilder.append(StringUtility.format(" {} oldIndexValues =_x000D_
        // _information.getIndexValues(_instance, indexNames);", Map.class.getName()));_x000D_
        // }_x000D_
        if (returnType != void.class) {_x000D_
            methodBuffer.append(StringUtility.format("	value = super.{}($$);", method.getName()));_x000D_
        } else {_x000D_
            methodBuffer.append(StringUtility.format("	super.{}($$);", method.getName()));_x000D_
        }_x000D_
        // TODO 数据变更部分_x000D_
        if (cacheChange != null) {_x000D_
            if (returnType == void.class) {_x000D_
                // if (!indexChanges.isEmpty()) {_x000D_
                // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
                // newIndexValues, oldIndexValues);"));_x000D_
                // }_x000D_
                methodBuffer.append(StringUtility.format(" _manager.modifyInstance(this);"));_x000D_
            } else {_x000D_
                if (cacheChange.values().length > 0) {_x000D_
                    methodBuffer.append(StringUtility.format(" if (changeValues.contains({}.primitiveToWrap(value))) {", ConversionUtility.class.getName()));_x000D_
                }_x000D_
                // if (!indexChanges.isEmpty()) {_x000D_
                // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
                // newIndexValues, oldIndexValues);"));_x000D_
                // }_x000D_
                methodBuffer.append(StringUtility.format("		_manager.modifyInstance(this);"));_x000D_
                if (cacheChange.values().length > 0) {_x000D_
                    methodBuffer.append(StringUtility.format(" }"));_x000D_
                }_x000D_
            }_x000D_
        } else {_x000D_
            // if (!indexChanges.isEmpty()) {_x000D_
            // methodBuilder.append(StringUtility.format(" _manager.modifyIndexes(_instance,_x000D_
            // newIndexValues, oldIndexValues);"));_x000D_
            // }_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("} finally {"));_x000D_
        // if (!indexChanges.isEmpty()) {_x000D_
        // methodBuilder.append(StringUtility.format("_x000D_
        // _information.unlockIndexWriteLocks(indexNames);"));_x000D_
        // }_x000D_
        methodBuffer.append(StringUtility.format("}"));_x000D_
        // TODO 返回值部分_x000D_
        if (returnType != void.class) {_x000D_
            methodBuffer.append(StringUtility.format("return value;"));_x000D_
        }_x000D_
        methodBuffer.append(StringUtility.format("}"));_x000D_
        proxyMethod.setBody(methodBuffer.toString());_x000D_
        proxyClazz.addMethod(proxyMethod);_x000D_
    }_x000D_
_x000D_
}_x000D_
