com.sf.ddao.crud.param.CRUDBeanPropsParameter.java Source code

Java tutorial

Introduction

Here is the source code for com.sf.ddao.crud.param.CRUDBeanPropsParameter.java

Source

/*
 * Copyright 2008 Pavel Syrtsov
 *
 * 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.sf.ddao.crud.param;

import com.sf.ddao.chain.CtxHelper;
import com.sf.ddao.chain.MethodCallCtx;
import com.sf.ddao.crud.CRUDDao;
import com.sf.ddao.crud.CRUDIgnore;
import com.sf.ddao.crud.DirtyPropertyAware;
import com.sf.ddao.factory.param.DefaultParameter;
import com.sf.ddao.factory.param.ParameterHandler;
import com.sf.ddao.factory.param.ParameterHelper;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.chain.Context;

import java.beans.PropertyDescriptor;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Date: Oct 27, 2009
 * Time: 3:36:12 PM
 */
public class CRUDBeanPropsParameter implements ParameterHandler {
    public static final String CRUD_BEAN_PROPS = "crudBeanProps";
    private volatile List<PropertyDescriptor> descriptors;
    private int argNum;
    private String fmt;

    public void init(AnnotatedElement element, String param, boolean isRef) {
        int commaIdx = param.indexOf(",");
        if (commaIdx < 0) {
            throw new IllegalArgumentException(
                    "Expected 2 arguments for parameter function CRUD_BEAN_PROPS:" + param);
        }
        fmt = param.substring(commaIdx + 1);
        param = param.substring(0, commaIdx);
        argNum = Integer.parseInt(param);
    }

    public String extractParam(Context context) throws SQLException {
        throw new UnsupportedOperationException();
    }

    public void appendParam(Context ctx, StringBuilder sb) throws SQLException {
        if (descriptors == null) {
            init(ctx);
        }
        int c = 0;
        final Object bean = getBean(ctx);
        DirtyPropertyAware dirtyPropertyAware = null;
        if (bean instanceof DirtyPropertyAware) {
            dirtyPropertyAware = (DirtyPropertyAware) bean;
        }
        for (PropertyDescriptor descriptor : descriptors) {
            if (dirtyPropertyAware != null && !dirtyPropertyAware.isDirty(descriptor.getName())) {
                continue;
            }
            if (c > 0) {
                sb.append(",");
            }
            final String fieldName = mapPropName2Field(descriptor);
            sb.append(MessageFormat.format(fmt, fieldName));
            c++;
        }
    }

    public static String mapPropName2Field(PropertyDescriptor descriptor) {
        final String s = descriptor.getName();
        StringBuilder sb = new StringBuilder(s.length());
        for (char ch : s.toCharArray()) {
            if (Character.isUpperCase(ch)) {
                ch = Character.toLowerCase(ch);
                sb.append("_").append(ch);
            } else {
                sb.append(ch);
            }
        }
        return sb.toString();
    }

    public int bindParam(PreparedStatement preparedStatement, int idx, Context ctx) throws SQLException {
        if (descriptors == null) {
            init(ctx);
        }
        int c = 0;
        final Object bean = getBean(ctx);
        DirtyPropertyAware dirtyPropertyAware = null;
        if (bean instanceof DirtyPropertyAware) {
            dirtyPropertyAware = (DirtyPropertyAware) bean;
        }
        for (PropertyDescriptor descriptor : descriptors) {
            try {
                if (dirtyPropertyAware != null && !dirtyPropertyAware.isDirty(descriptor.getName())) {
                    continue;
                }
                Object v = descriptor.getReadMethod().invoke(bean);
                ParameterHelper.bind(preparedStatement, idx++, v, descriptor.getPropertyType(), ctx);
                c++;
            } catch (Exception e) {
                throw new SQLException(descriptor.getName(), e);
            }
        }
        if (dirtyPropertyAware != null) {
            dirtyPropertyAware.cleanDirtyBean();
        }
        return c;
    }

    private Object getBean(Context context) {
        final MethodCallCtx callCtx = CtxHelper.get(context, MethodCallCtx.class);
        Object[] args = callCtx.getArgs();
        final Object bean;
        if (argNum == DefaultParameter.RETURN_ARG_IDX) {
            bean = callCtx.getLastReturn();
        } else {
            bean = args[argNum];
        }
        return bean;
    }

    private synchronized void init(Context ctx) {
        if (descriptors != null) {
            return;
        }
        Class<?> beanClass = CRUDParameterService.getCRUDDaoBean(ctx, argNum);
        final PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(beanClass);
        List<PropertyDescriptor> res = new ArrayList<PropertyDescriptor>(descriptors.length);
        for (PropertyDescriptor descriptor : descriptors) {
            if (CRUDDao.IGNORED_PROPS.contains(descriptor.getName())) {
                continue;
            }
            final Method readMethod = descriptor.getReadMethod();
            if (readMethod == null) {
                continue;
            }
            if (readMethod.getAnnotation(CRUDIgnore.class) != null) {
                continue;
            }
            res.add(descriptor);
        }
        this.descriptors = res;
    }
}