/** * * Copyright 2014 The Darks ORM Project (Liu lihua) * * 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 darks.orm.core.interceptor; import java.lang.reflect.Method; import java.util.Collection; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import darks.orm.annotation.sqlmap.Select; import darks.orm.annotation.sqlmap.Update; import darks.orm.app.Page; import darks.orm.app.QueryEnumType; import darks.orm.app.SqlSession; import darks.orm.core.data.xml.DMLData; import darks.orm.core.data.xml.DMLData.DMLType; import darks.orm.core.data.xml.DMLQueryData; import darks.orm.core.data.xml.InterfaceMethodData; import darks.orm.core.executor.SqlMapExecutor; import darks.orm.core.factory.ClassFactory; import darks.orm.core.factory.ExecutorFactory; import darks.orm.core.factory.SqlMapSingletonFactory; import darks.orm.exceptions.SqlMapQueryException; import darks.orm.log.Logger; import darks.orm.log.LoggerFactory; import darks.orm.util.SqlHelper; public class SqlMapInterceptor implements MethodInterceptor { private static final Logger logger = LoggerFactory.getLogger(SqlMapInterceptor.class); private SqlSession session; private Class<?> cls; public SqlMapInterceptor() { } public SqlMapInterceptor(SqlSession session, Class<?> cls) { this.session = session; this.cls = cls; } private SqlSession getSession() throws Exception { return session; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Select query = method.getAnnotation(Select.class); Update update = method.getAnnotation(Update.class); if (query != null) { return this.AnnotationQueryIntercept(obj, method, args, methodProxy); } else if (update != null) { return this.AnnotationUpdateIntercept(obj, method, args, methodProxy); } else { return this.SqlMapIntercept(obj, method, args, methodProxy); } } public Object AnnotationQueryIntercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { String className = cls.getName(); String methodName = method.toGenericString(); String namesp = className + "." + methodName; InterfaceMethodData data = ClassFactory.parseInterfaceClass(namesp, method); int pageIndex = data.getArgumentIndex(InterfaceMethodData.PAGE_PARAM_KEY); int pageSizeIndex = data.getArgumentIndex(InterfaceMethodData.PAGESIZE_PARAM_KEY); int page = -1; int pageSize = -1; if (pageIndex >= 0) { page = (Integer)args[pageIndex]; } if (pageSizeIndex >= 0) { pageSize = (Integer)args[pageSizeIndex]; } String sql = data.getSql(); Object[] params = args; params = SqlHelper.buildParams(sql, params); sql = SqlHelper.filterSql(sql); QueryEnumType queryEnumType = data.getQueryEnumType(); SqlSession session = getSession(); SqlMapExecutor exec = ExecutorFactory.getSqlMapCascadeQueryExecutor(session, data.isAutoCascade(), data.getResultClass(), sql, params, queryEnumType, data.getCacheId(), page, pageSize, data.isAutoCache(), data.getAttribute(), data.getAlias()); return exec.invoke(); } public Object AnnotationUpdateIntercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { String className = cls.getName(); String methodName = method.getName(); String namesp = className + "." + methodName; InterfaceMethodData data = ClassFactory.parseInterfaceClass(namesp, method); String sql = data.getSql(); Object[] params = SqlHelper.buildParams(sql, args); sql = SqlHelper.filterSql(sql); getSession().executeUpdate(sql, params); return null; } public Object SqlMapIntercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { String className = cls.getName(); String methodName = method.getName(); String namesp = className + "." + methodName; DMLData dmlData = SqlMapSingletonFactory.getInstance().getDMLData(namesp); if (dmlData == null) { throw new SqlMapQueryException("query xml id '" + namesp + "' does not exists"); } InterfaceMethodData data = ClassFactory.parseInterfaceClass(namesp, method); if (dmlData.getType() == DMLType.Update) { SqlMapSingletonFactory.getInstance().update(getSession(), namesp, args); return null; } DMLQueryData queryData = dmlData.getQueryData(); int pageIndex = data.addExternArgument(queryData.getPageParam(), InterfaceMethodData.PAGE_PARAM_KEY); int pageSizeIndex = data.addExternArgument(queryData.getPageSizeParam(), InterfaceMethodData.PAGESIZE_PARAM_KEY); int valuesIndex = data.addExternArgument(queryData.getValuesParam(), InterfaceMethodData.VALUES_PARAM_KEY); if (queryData.getQueryType() == QueryEnumType.Page) { if (pageIndex < 0 || pageSizeIndex < 0) { throw new SqlMapQueryException("('" + namesp + "') the index of page or pageSize is less than 0"); } } int page = -1; int pageSize = -1; Object[] values = null; if (pageIndex >= 0) { page = (Integer)args[pageIndex]; } if (pageSizeIndex >= 0) { pageSize = (Integer)args[pageSizeIndex]; } if (valuesIndex >= 0) { Object valObj = args[valuesIndex]; if (valObj instanceof Object[]) { values = (Object[])valObj; } } Object[] params = args; return SqlMapSingletonFactory.getInstance().query(getSession(), namesp, parseAutoQueryType(method), page, pageSize, values, params); } private QueryEnumType parseAutoQueryType(Method method) { Class<?> clazz = method.getReturnType(); if (clazz.isAssignableFrom(Collection.class)) { return QueryEnumType.List; } else if (clazz.isAssignableFrom(Page.class)) { return QueryEnumType.Page; } else { return QueryEnumType.Object; } } }