修改整合的Jfinal的Model自动绑定表插件 AutoTableBindPlugin

之前发过一个

JFinal 自动探测Model 注册插件 AutoScanPlugin

http://my.oschina.net/b1412/blog/67764

然后参考了 @Flio 对我的代码做出的扩展

jfinal的Model自动绑定表插件

http://www.oschina.net/code/snippet_591384_12022

现在整合下代码采用@Flio的插件命名,并且重构了一下搜索类的代码。

类探测api如下方便以后其类探测的使用.

List<Class> classList = ClassSearcher.findClasses(Model.class);

 插件注册代码,由于AutoTableBindPlugin继承自ActiveRecordPlugin,所以不需要单独注册它了.

主要数据库连接池插件要在AutoTableBindPlugin之前注册.

public void configPlugin(Plugins me) {
		DruidPlugin druidPlugin = new DruidPlugin.DruidBuilder(
				getProperty("url"), getProperty("username"),
				getProperty("password")).build();
		AutoTableBindPlugin autoTableBindPlugin = new AutoTableBindPlugin(
				druidPlugin, TableNameStyle.LOWER);
		autoTableBindPlugin.setShowSql(true);
		SqlReporter.setLogger(true);
		SqlInXmlPlugin sqlInXmlPlugin = new SqlInXmlPlugin();
		QuartzPlugin quartzPlugin = new QuartzPlugin();
		me.add(druidPlugin).add(sqlInXmlPlugin).add(autoTableBindPlugin).add(quartzPlugin);
            
	}

目前之内探测/classes下的类,如果是/lib下jar包中的类还不能探测。

之前做过运行动态修改字节码的工具,是吧lib下的jar解压出来然后修改了打包回去。如果需要探测jar中类是否为Model子类是否必须坐jar包解压的工作?大家有什么好的方案么?这个问题弄清楚了再加上扫描jar包中Model的工作。

目前如果是有项目吧class文件打成jar包部署的朋友暂时无法使用自动探测绑定的功能...

 

 

package com.jfinal.plugin.tablebind;

import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.util.StringKit;

public class AutoTableBindPlugin extends ActiveRecordPlugin {
	private TableNameStyle tableNameStyle;
	private Logger logger = LoggerFactory.getLogger(getClass());

	public AutoTableBindPlugin(DataSource dataSource) {
		super(dataSource);
	}

	public AutoTableBindPlugin(IDataSourceProvider dataSourceProvider, TableNameStyle tableNameStyle) {
		super(dataSourceProvider);
		this.tableNameStyle = tableNameStyle;
	}

	@Override
	public boolean start() {
		try {
			List<Class> modelClasses = ClassSearcher.findClasses(Model.class);
			logger.debug("modelClasses.size  {}",modelClasses.size());
			TableBind tb = null;
			for (Class modelClass : modelClasses) {
				tb = (TableBind) modelClass.getAnnotation(TableBind.class);
				if (tb == null) {
					this.addMapping(tableName(modelClass), modelClass);
					logger.debug("auto bindTable: addMapping({}, {})", tableName(modelClass), modelClass.getName());
				} else {
					if (StringKit.notBlank(tb.pkName())) {
						this.addMapping(tb.tableName(), tb.pkName(), modelClass);
						logger.debug("auto bindTable: addMapping({}, {},{})", new Object[]{tb.tableName(),tb.pkName(), modelClass.getName()});
					} else {
						this.addMapping(tb.tableName(), modelClass);
						logger.debug("auto bindTable: addMapping({}, {})", tb.tableName(), modelClass.getName());
					}
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return super.start();
	}

	@Override
	public boolean stop() {
		return super.stop();
	}

	private String tableName(Class<?> clazz) {
		String tableName = clazz.getSimpleName();
		if (tableNameStyle == TableNameStyle.UP) {
			tableName = tableName.toUpperCase();
		} else if (tableNameStyle == TableNameStyle.LOWER) {
			tableName = tableName.toLowerCase();
		} else {
			tableName = StringKit.firstCharToLowerCase(tableName);
		}
		return tableName;
	}
}

package com.jfinal.plugin.tablebind;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public  @ interface  TableBind {
	String tableName();
	String pkName() default "";
}

package com.jfinal.plugin.tablebind;



import java.io.File;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;



public class ClassSearcher {

	

	private static List<File> classFiles;



	/**

	 * 递归查找文件

	 * 

	 * @param baseDirName

	 *            查找的文件夹路径

	 * @param targetFileName

	 *            需要查找的文件名

	 */

	private  static List<File> findFiles(String baseDirName, String targetFileName) {


		/**

		 * 算法简述: 从某个给定的需查找的文件夹出发,搜索该文件夹的所有子文件夹及文件,

		 * 若为文件,则进行匹配,匹配成功则加入结果集,若为子文件夹,则进队列。 队列不空,重复上述操作,队列为空,程序结束,返回结果。

		 */

		classFiles = new ArrayList<File>();

		String tempName = null;

		// 判断目录是否存在

		File baseDir = new File(baseDirName);

		if (!baseDir.exists() || !baseDir.isDirectory()) {

			System.out.println("文件查找失败:" + baseDirName + "不是一个目录!");

		} else {

			String[] filelist = baseDir.list();

			for (int i = 0; i < filelist.length; i++) {

				File readfile = new File(baseDirName + File.separator

						+ filelist[i]);

				if (!readfile.isDirectory()) {

					tempName = readfile.getName();

					if (ClassSearcher.wildcardMatch(targetFileName, tempName)) {

						classFiles.add(readfile.getAbsoluteFile());

					}

				} else if (readfile.isDirectory()) {

					classFiles.addAll(findFiles(baseDirName + File.separator

							+ filelist[i], targetFileName));

				}

			}

		}

		return classFiles;

	}



	public static List<Class> findClasses(Class clazz) {

		List<Class> classList = new ArrayList<>();

		URL classPathUrl = ClassSearcher.class

				.getResource("/");

		List<File> classFileList = findFiles(classPathUrl.getFile(), "*.class");

		

		String lib = new File(classPathUrl.getFile()).getParent() + "/lib/";



		for (File classFile : classFileList) {

			String className = className(classFile, "/classes");

			try {

				Class<?> classInFile = Class.forName(className);

				if (classInFile.getSuperclass() == clazz) {

					classList.add(classInFile);

				}

			} catch (ClassNotFoundException e) {

				e.printStackTrace();

			}

		}

		return classList;

	}



	private static String className(File classFile, String pre) {

		String objStr = classFile.toString().replaceAll("\\\\", "/");

		String className;

		className = objStr.substring(objStr.indexOf(pre) + pre.length(),

				objStr.indexOf(".class"));

		if (className.startsWith("/")) {

			className = className.substring(className.indexOf("/") + 1);

		}

		return className.replaceAll("/", ".");

	}



	/**

	 * 通配符匹配

	 * 

	 * @param pattern

	 *            通配符模式

	 * @param str

	 *            待匹配的字符串

	 * @return  匹配成功则返回true,否则返回false

	 */

	private static boolean wildcardMatch(String pattern, String str) {

		int patternLength = pattern.length();

		int strLength = str.length();

		int strIndex = 0;

		char ch;

		for (int patternIndex = 0; patternIndex < patternLength; patternIndex++) {

			ch = pattern.charAt(patternIndex);

			if (ch == '*') {

				// 通配符星号*表示可以匹配任意多个字符

				while (strIndex < strLength) {

					if (wildcardMatch(pattern.substring(patternIndex + 1),

							str.substring(strIndex))) {

						return true;

					}

					strIndex++;

				}

			} else if (ch == '?') {

				// 通配符问号?表示匹配任意一个字符

				strIndex++;

				if (strIndex > strLength) {

					// 表示str中已经没有字符匹配?了。

					return false;

				}

			} else {

				if ((strIndex >= strLength) || (ch != str.charAt(strIndex))) {

					return false;

				}

				strIndex++;

			}

		}

		return (strIndex == strLength);

	}

}

 

package com.jfinal.plugin.tablebind;

public enum TableNameStyle {
	UP, LOWER, UP_UNDERLINE, LOWER_UNDERLINE
}

转载于:https://my.oschina.net/b1412/blog/68083

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值