欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  资讯频道

开源框架eweb4j发布1.b.7新版本

程序员文章站 2022-05-14 20:01:55
...
eweb4j是一个简单、轻量的JavaWeb开发框架。涵盖MVC、ORM、IOC。超轻量、面向接口,扩展灵活。

可先使用本框架快速开发,然后方便的转换成SSH。只需修改部分代码,无需修改业务逻辑代码。

MVC、IOC、ORM*选择开闭,灵活与其他框架集成。

特性:

Component组件支持
  • DWZ组件
  • 分页组件
  • ……

MVC
  • 约定由于配置,可零配置。
  • 两种配置方式(xml,注解)供您选择
  • 更加灵活方便的url mapping
  • 两种参数绑定方式(类属性、方法参数)供您选择
  • RESTful
  • Json渲染
  • URL拦截器
  • action验证器
  • ……

IOC
  • 基本数据类型注入
  • 无限制嵌套Pojo注入
  • setter方法注入和构造方法注入

ORM
  • 约定由于配置,可零配置。
  • 两种配置方式(xml、注解),供您选择
  • 简单的DAOFactory,提供InsertDAO、DeleteDAO、UpdateDAO、SelectDAO、DivPageDAO、SearchDAO、CascadeDAO接口。
  • 支持表关系、级联操作
  • 事务模板
  • JdbcTemplate
  • 支持多个数据源
  • 无缓存,无懒加载,主动级联操作,纯粹的ORM
  • ……

各种Util工具类
  • BeanXMLUtil,一个pojo序列化和反序列化到xml的工具类,基于注解
  • FileUtil,一个文件操作工具类
  • JsonConverter,JSON转换工具类
  • ReflectUtil,一个反射工具类,能获取setter、getter,使反射获取方法,属性更简易,支持父类的反射
  • ……


简单就是美。使用文档已经编写齐全,在下载包里有,PDF格式。
纯开源、纯分享,不喜勿喷,还望各位大大多多支持。

下载地址http://code.google.com/p/eweb4j/downloads/list

启动配置文件

<?xml version="1.0" encoding="UTF-8"?>

<beans>
  <bean xmlBean="com.cfuture08.eweb4j.config.bean.ConfigBean">
    <debug>0</debug>
    <ioc xmlBean="com.cfuture08.eweb4j.config.bean.ConfigIOC">
      <open>1</open>
      <debug>true</debug>
      <logFile>logs/ioc.log</logFile>
      <logMaxSize>5</logMaxSize>
      <iocXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.IOCXmlFiles">
        <path>ioc.xml</path>
      </iocXmlFiles>
    </ioc>
    <orm xmlBean="com.cfuture08.eweb4j.config.bean.ConfigORM">
      <open>1</open>
      <debug>true</debug>
      <logFile>logs/orm.log</logFile>
      <logMaxSize>5</logMaxSize>
      <dataSource>com.mchange.v2.c3p0.ComboPooledDataSource</dataSource>
      <scanPojoPackage xmlBean="com.cfuture08.eweb4j.config.bean.ScanPojoPackage">
        <path>.</path>
      </scanPojoPackage>
      <ormXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.ORMXmlFiles">
        <path></path>
      </ormXmlFiles>
      <dbInfoXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.DBInfoXmlFiles">
        <path>mysql_con_info.xml</path>
      </dbInfoXmlFiles>
    </orm>
    <mvc xmlBean="com.cfuture08.eweb4j.config.bean.ConfigMVC">
      <open>true</open>
      <debug>true</debug>
      <logFile>logs/mvc.log</logFile>
      <logMaxSize>5</logMaxSize>
      <scanActionPackage xmlBean="com.cfuture08.eweb4j.config.bean.ScanActionPackage">
        <path>.</path>
      </scanActionPackage>
      <actionXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.ActionXmlFile">
        <path></path>
      </actionXmlFiles>
      <interXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.InterXmlFile">
        <path>interceptor.xml</path>
      </interXmlFiles>
    </mvc>
  </bean>
</beans>



新版本1.b.7更新:

(1) Controller支持以下约定:
action方法不填写注解RequestMapping的时候,默认以方法名为url-mapping值。
action 方法返回类型为void的时候框架不做任何跳转处理。
缺省返回值忽略大小写。例如ajax。
类名如果以“Controller”,“Control”,“Action”结尾的话,可以不用添加@Controller注解,框架也能识别为控制器。
(2)mvc中,为了改进性能,将Class.forName(ActionBeanName),改为缓存方式调用。这样省去了lookup的过程,效能会提升。当系统需要应对高并发的时候,很有效。
(3)废除了formBean的配置,框架自动识别pojo参数,并且支持无限嵌套pojo属性。无需任何配置。
(4)将MVC的@Result(location="")属性改为@Result(value="")
(5)将ORM的BaseDAO.getOne(Integer id)之类的Integer改为Number
(6)让MVC Controller 的属性的 setter 方法 和 getter 方法 无法映射到url。前提是这些方法没有使用@RequestMapping注解
(7)修复 MVC Controller 实例属性与action方法@RequestMapping("xxx/{id}")中的“{}”变量的绑定。
(8)当MVC Controller 实例属性绑定的UrlParam的值为null时,不将参数值注入到该属性。
(9)添加Json支持,MVC的@Result(type="json"),被注解的方法,返回值会被JsonConverter.convert(re),接着被写入到响应流。
(10)所有的注解都被加上@Inherited,允许类、public方法上的注解被子类继承。
(11)框架使用的反射工具类范围调整至涵盖父类。原先取得某个类的属性,是不能获取到它的父类的属性的(同理,方法也是),现在父类的也会被获取,主要考虑到MVC的Controller、ORM的
POJO等对象需要使用继承来复用代码。
(12)修复MVC的Controller无法实例化的时候框架报致命错误导致程序中断,现在为跳过该类,将其认为非控制器,且继续处理下一个类。
(13)修复MVC的Controller属性绑定到UrlParam过程中,pojo属性互相调用导致的循环递归异常。
(14)ORM的CascadeDAO @One 关系中的级联更新操作,对新更新的关联对象如果在数据库中找不到记录就不被更新的规则修改为当关联对象为null或者其主键值为null的时候不级联更新。例如
更新某个菜单的父菜单为空这种情况。
(16)重新调整了MVC的Validator有关的注解。去掉了冗余。举个实例:

这是修改之前的写法:
@Validator({"int","required","length"})
@ValField(index={0,1,2},field={"id","name","name"},value={"id必须为数字","name必填","name长度4-6位"})
@ValParam(index={2,2},name={"minLength","maxLength"},value={"4","6"})
public void doActoin(){}

这是修改之后的写法:
@Validator({"int","required","length"})
@ValField({"id","name"})
@ValMess(validator={0,1,2},field={0,1,1},value={"id必须为数字","name必填","name长度4-6位"})
@ValParamName("minLength","maxLength")
@ValParam(valMess={2,2},name={0,1},value={"4","6"})
public void doActoin(){}

可以看到,原来的ValField对要验证的field会产生冗余,例如上例中的“name”,修改后是将这些field写到另外一个@ValField注解中,然后在@ValMess中进行引用,注意那些数字引用表表
示的是数组下标。
同样道理,对于@ValParam来说也是这样,为了去掉冗余。

备注:说去掉冗余是不严谨的说法,实际上应该是将语言文字的冗余转化为数字的冗余,后者相对而言是降低了冗余。思路也更清晰。

(17)IOC增加@Ioc注解,只能用在Action类属性上,且需要setter方法才能注入。具体用法:
@Controller
class TestAction{
        @Ioc("这里填写在IOC配置文件里的BeanID,不填的话默认是简单类名TestDAO")
private TestService testService;
public void setTestService(TestService testService){
this.testService = testService;
}
}

(18)添加 DAOFactory.getSelectDAO().selectCount(Class<?> clazz,String condition,Object... args);用来查询表的记录数。给定where条件,允许有?占位符。
(19)修复了当被扫描的包里含有.svn或者其他非.class文件的时候,框架启动失败的一个bug
(20)改善了MVC.Action的ParamUtil进行URL参数绑定到Aciton属性的时候,如果是属性为pojo,例如:
private Pet pet;
那么绑定参数的时候,优先找到 pet.name绑定到pet里面的name属性。
如果找不到pet.name 参数,则找name参数绑定。如果还找不到,就不进行任何绑定。
可以看到跟属性名字“pet”有关,可以理解为参数的一个scope,这样解决了不同pojo但相同属性名字的参数绑定。
url:/testPojoParamAndUrlParam?name=thisName&pet.name=xiaohei&master.name=weiwei
支持深层次。例如:
url:/testPojoParamAndUrlParam?name=thisName&pet.master.name=masterName&pet.name=petName

(21)MVC Action URL变量支持多个。例如:
@RequestMapping("test/{cate}/{name}/edit")
public void testParamArg(){

}
要注意不要无任何间隔的连续写两个变量,例如:"test/{cate}{name}/edit"这是不合法的。"test/{cate}at{name}/edit"这是合法的。
(22)ORM 持久化类属性 添加了@Ignore 注解,表示该属性不映射到表字段中。


上些实例代码,其中包括快要发布的Simportal新版本。
package com.cfuture08.eweb4j.component.dwz.menu.domain.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.cfuture08.eweb4j.orm.config.annotation.Column;
import com.cfuture08.eweb4j.orm.config.annotation.Id;
import com.cfuture08.eweb4j.orm.config.annotation.Many;
import com.cfuture08.eweb4j.orm.config.annotation.One;
import com.cfuture08.eweb4j.orm.config.annotation.Table;

/**
 * DWZ中左边树形结构菜单模型
 * 
 * @author weiwei
 * 
 */
@Table("t_TreeMenu")
public class TreeMenu implements Serializable {
	private static final long serialVersionUID = 5264149396283615258L;
	@Id
	@Column("id")
	private Long treeMenuId = 0L;
	private String name;// 菜单名
	private String target = "navTab";// navTab或dialog
	private String rel;// navTabId
	private String reloadFlag = "1";// 是否自动刷新
	private String href;// 跳转路径
	private int rank;// 排序
	@One(column = "pid")
	private TreeMenu parent;// 父亲菜单
	@One(column = "navMenuId")
	private NavMenu navMenu = new NavMenu();// 所在的导航菜单
	@Many(target = TreeMenu.class, column = "pid")
	private List<TreeMenu> children = new ArrayList<TreeMenu>();// 孩子菜单们

	public Long getTreeMenuId() {
		return treeMenuId;
	}

	public void setTreeMenuId(Long treeMenuId) {
		this.treeMenuId = treeMenuId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public TreeMenu getParent() {
		return parent;
	}

	public void setParent(TreeMenu parent) {
		this.parent = parent;
	}

	public int getRank() {
		return rank;
	}

	public void setRank(int rank) {
		this.rank = rank;
	}

	public String getTarget() {
		return target;
	}

	public void setTarget(String target) {
		this.target = target;
	}

	public String getRel() {
		return rel;
	}

	public void setRel(String rel) {
		this.rel = rel;
	}

	public String getReloadFlag() {
		return this.reloadFlag;
	}

	public void setReloadFlag(String reloadFlag) {
		this.reloadFlag = reloadFlag;
	}

	public String getHref() {
		return href;
	}

	public void setHref(String href) {
		this.href = href;
	}

	public NavMenu getNavMenu() {
		return navMenu;
	}

	public void setNavMenu(NavMenu navMenu) {
		this.navMenu = navMenu;
	}

	public List<TreeMenu> getChildren() {
		return children;
	}

	public void setChildren(List<TreeMenu> children) {
		this.children = children;
	}

	public String toString() {
		Long pid = parent == null ? 0L : parent.treeMenuId;
		return "{\"treeMenuId\":\"" + treeMenuId + "\",\"navMenuId\":\""
				+ navMenu.getNavMenuId() + "\",\"pid\":\"" + pid
				+ "\",\"name\":\"" + name + "\",\"href\":\"" + href + "\"}";
	}
}


package com.lurencun.ewebdemo;
import java.io.PrintWriter;

import com.cfuture08.eweb4j.mvc.annotation.Param;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.orm.dao.factory.DAOFactory;
public class HelloAction {
	//默认方法名为访问url
	public void helloWorld(PrintWriter out) {
		out.print("Hello World !");
	}
	
	@RequestMapping("hello")
	public void doHello(PrintWriter out){
		out.print("doHello");
	}
	
	@RequestMapping(value="articles/{id}",method="GET")
	public void restful(PrintWriter out,@Param("id")int id){
		out.print("id->"+id);
	}
	
	public String defaultForward(){
		return "test.jsp";
	}
	
	public String forward(){
		return "forward:test.jsp";
	}
	
	public String redirect(){
		return "redirect:test.jsp";
	}
	
	/**
	 * url: "/test?name=ooo&pojo.name=xxx&pojo.age=2"
	 * 
	 */
	public void bindParam(String name,@Param("pojo") Pojo pojo){
		Long id = (Long) DAOFactory.getInsertDAO().insert(pojo);
		pojo.setId(id);
		DAOFactory.getCascadeDAO().update(pojo, "xxx","ooo");
	}
	
	public void testDAO(){
		
	}
}



最新的Simportal版本还在开发当中。贴上部分代码:
package com.cfuture08.eweb4j.component.dwz.menu.action.treeMenu;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;

import com.cfuture08.eweb4j.component.dwz.DWZ;
import com.cfuture08.eweb4j.component.dwz.menu.constant.CommonCons;
import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.domain.service.TreeMenuService;
import com.cfuture08.eweb4j.ioc.annotation.Ioc;
import com.cfuture08.eweb4j.mvc.annotation.Controller;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.mvc.annotation.Singleton;

/**
 * 抽象类BaseAction
 * 
 * @author weiwei
 * 
 */
@Controller
@Singleton
@RequestMapping(TreeMenuCons.MODULE_PATH)
public abstract class BaseAction {
	@Ioc(TreeMenuCons.IOC_SERVICE_BEAN_ID)
	protected TreeMenuService service = null;
	@Ioc(CommonCons.IOC_DWZ_BEAN_ID)
	protected DWZ dwz = null;

	protected HttpServletRequest request;
	protected PrintWriter out;

	protected TreeMenu treeMenu;

	protected Long[] ids;
	protected Long id = 0L;
	protected String keyword = "";
	protected Long treeMenuId = 0L;
	protected Long navMenuId = 0L;
	protected int pageNum = 1;
	protected int numPerPage = 20;

        //setter and getter 
}


package com.cfuture08.eweb4j.component.dwz.menu.action.treeMenu;

import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.mvc.annotation.Param;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.mvc.annotation.ValField;
import com.cfuture08.eweb4j.mvc.annotation.ValMess;
import com.cfuture08.eweb4j.mvc.annotation.Validator;

public class AddAction extends BaseAction {
	@RequestMapping(value = "/new", method = "GET|POST")
	public String doNew() {
		request.setAttribute("model", TreeMenuCons.MODEL_NAME);
		return "add.jsp";
	}

	@RequestMapping(value = "/", method = "POST", showValErr = "dwzJson")
	@Validator({ "int", "required" })
	@ValField({ "rank", "navMenus.dwz_navMenu2.navMenuId" })
	@ValMess(validator = { 0, 1 }, field = { 0, 1 }, value = { "排序项只能输入数字",
			"导航菜单不能为空" })
	public void doAdd(@Param("navMenus.dwz_navMenu2.navMenuId") Long navMenuId,
			@Param(value = TreeMenuCons.MODEL_NAME
					+ ".dwz_treeMenu2.treeMenuId", init = "0") Long pid) {
		try {
			service.addWithCascade(treeMenu, navMenuId, pid);
			out.print(TreeMenuCons.DWZ_SUCCESS_JSON_CLOSE_CURRENT);
		} catch (Exception e) {
			out.print(dwz.getFailedJson(e.getMessage()));
		}
	}
}



package com.cfuture08.eweb4j.component.dwz.menu.domain.service;

import java.util.ArrayList;
import java.util.List;

import com.cfuture08.eweb4j.component.DivPageComp;
import com.cfuture08.eweb4j.component.dwz.menu.constant.CommonCons;
import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.component.dwz.menu.domain.dao.NavMenuDAO;
import com.cfuture08.eweb4j.component.dwz.menu.domain.dao.TreeMenuDAO;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.NavMenu;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotBeParentMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotFindNavMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotFindParentMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.DuplicateMenuNameException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuDataAccessException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuNotFoundException;
import com.cfuture08.eweb4j.component.dwz.view.EditPage;
import com.cfuture08.eweb4j.component.dwz.view.ListPage;
import com.cfuture08.eweb4j.component.dwz.view.SearchForm;

public class TreeMenuServiceImpl implements TreeMenuService {

	private SearchForm searchForm = new SearchForm(TreeMenuCons.MODEL_NAME
			+ "/search", "");

	private NavMenuDAO navMenuDAO = null;
	private TreeMenuDAO treeMenuDAO = null;

	// IOC注入
	public void setNavMenuDAO(NavMenuDAO navMenuDAO) {
		if (this.navMenuDAO == null)
			this.navMenuDAO = navMenuDAO;
	}

	// IOC注入
	public void setTreeMenuDAO(TreeMenuDAO treeMenuDAO) {
		if (this.treeMenuDAO == null)
			this.treeMenuDAO = treeMenuDAO;
	}

	@Override
	public ListPage getPageWithCascade(int pageNum, int numPerPage)
			throws MenuDataAccessException {
		List<TreeMenu> list = treeMenuDAO.getPageWithCascade(pageNum,
				numPerPage);
		DivPageComp dpc = new DivPageComp(pageNum, numPerPage,
				this.treeMenuDAO.countAll(), CommonCons.DIV_PAGE_BTN_MAX_SHOW);

		return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, list, dpc);
	}

	@Override
	public ListPage getSearchResult(String keyword, int pageNum, int numPerPage)
			throws MenuDataAccessException {

		if (keyword == null || keyword.length() == 0) {
			searchForm.setKeyword("");
			return getPageWithCascade(pageNum, numPerPage);
		}

		List<TreeMenu> list = treeMenuDAO.getSearchResult(keyword, pageNum,
				numPerPage);

		DivPageComp dpc = new DivPageComp(pageNum, numPerPage,
				this.treeMenuDAO.countSearch(keyword),
				CommonCons.DIV_PAGE_BTN_MAX_SHOW);

		searchForm.setKeyword(keyword);

		return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, list, dpc);
	}

	@Override
	public ListPage getParentsPage(Long navMenuId, Long treeMenuId,
			int pageNum, int numPerPage) throws MenuDataAccessException,
			CannotFindNavMenuException {
		return getParentsSearchResult(navMenuId, treeMenuId, "", pageNum,
				numPerPage);
	}

	@Override
	public ListPage getParentsSearchResult(Long navMenuId, Long treeMenuId,
			String keyword, int pageNum, int numPerPage)
			throws MenuDataAccessException, CannotFindNavMenuException {
		if (navMenuId == null || navMenuId <= 0)
			throw new CannotFindNavMenuException();

		NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
		if (navMenu == null)
			throw new CannotFindNavMenuException();

		if (keyword == null)
			keyword = "";

		List<TreeMenu> pojos = this.treeMenuDAO.getParentSearchResult(pageNum,
				numPerPage, keyword, navMenuId, treeMenuId);

		if (pojos == null)
			pojos = new ArrayList<TreeMenu>();
		TreeMenu tm = new TreeMenu();
		tm.setTreeMenuId(0L);
		tm.setName("主菜单-没有父节点");
		tm.setNavMenu(navMenu);
		pojos.add(tm);

		long allCount = this.treeMenuDAO.countParentSearchResult(keyword,
				navMenuId, treeMenuId);
		DivPageComp dpc = new DivPageComp(pageNum, numPerPage, allCount,
				CommonCons.DIV_PAGE_BTN_MAX_SHOW);

		searchForm.setAction(TreeMenuCons.MODEL_NAME + "/" + navMenuId
				+ "/lookupSearch");
		searchForm.setKeyword(keyword);

		return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, pojos, dpc);
	}

	@Override
	public String getParentsFormatJson(Long navMenuId, Long treeMenuId)
			throws MenuDataAccessException, CannotFindNavMenuException {
		if (navMenuId == null || navMenuId <= 0)
			throw new CannotFindNavMenuException();

		NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
		if (navMenu == null)
			throw new CannotFindNavMenuException();

		List<TreeMenu> pojos = this.treeMenuDAO
				.getParent(navMenuId, treeMenuId);
		if (pojos == null)
			pojos = new ArrayList<TreeMenu>();

		TreeMenu tm = new TreeMenu();
		tm.setTreeMenuId(0L);
		tm.setName("主菜单-没有父节点");
		tm.setNavMenu(navMenu);

		pojos.add(tm);

		return pojos.toString();
	}

	@Override
	public void batchRemove(Long[] ids) throws MenuDataAccessException,
			MenuNotFoundException {
		TreeMenu treeMenu = null;
		for (Long id : ids) {
			treeMenu = treeMenuDAO.getOne(id);
			if (treeMenu == null)
				throw new MenuNotFoundException();

			treeMenuDAO.deleteOne(id);
		}
	}

	@Override
	public void removeOne(Long id) throws MenuDataAccessException,
			MenuNotFoundException {
		TreeMenu treeMenu = treeMenuDAO.getOne(id);
		if (treeMenu == null)
			throw new MenuNotFoundException();

		treeMenuDAO.deleteOne(id);
	}

	@Override
	public void addWithCascade(TreeMenu treeMenu, Long navMenuId, Long pid)
			throws MenuDataAccessException, CannotFindNavMenuException,
			CannotFindParentMenuException, CannotBeParentMenuException,
			DuplicateMenuNameException {

		TreeMenu tmp_TreeMenu = this.treeMenuDAO.getOneByName(treeMenu
				.getName());
		if (tmp_TreeMenu != null)
			throw new DuplicateMenuNameException();

		if (navMenuId == null || navMenuId <= 0)
			throw new CannotFindNavMenuException();

		NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
		if (navMenu == null)
			throw new CannotFindNavMenuException();

		if (pid > 0) {
			TreeMenu parent = this.treeMenuDAO.getOne(pid);
			if (parent == null)
				throw new CannotFindParentMenuException();
			if (pid.equals(treeMenu.getTreeMenuId()))
				throw new CannotBeParentMenuException();
			treeMenu.setParent(parent);
		} else {
			treeMenu.setParent(new TreeMenu());
		}

		treeMenu.setNavMenu(navMenu);

		String reloadFlag = treeMenu.getReloadFlag();
		treeMenu.setReloadFlag("on".equals(reloadFlag) ? "1" : "0");

		this.treeMenuDAO.create(treeMenu);
	}

	@Override
	public EditPage<TreeMenu> getEditPage(Long id)
			throws MenuDataAccessException, MenuNotFoundException {

		TreeMenu treeMenu = this.treeMenuDAO.getOne(id);
		if (treeMenu == null)
			throw new MenuNotFoundException();

		String reloadFlag = treeMenu.getReloadFlag();
		treeMenu.setReloadFlag("1".equals(reloadFlag) ? "checked" : "");

		EditPage<TreeMenu> editPage = new EditPage<TreeMenu>(
				TreeMenuCons.MODEL_NAME, TreeMenuCons.MODEL_NAME + "/" + id,
				treeMenu);

		return editPage;
	}

	@Override
	public void updateWithCascade(TreeMenu treeMenu, Long navMenuId, Long pid)
			throws MenuDataAccessException, MenuNotFoundException,
			CannotFindNavMenuException, CannotFindParentMenuException,
			CannotBeParentMenuException, DuplicateMenuNameException {
		Long id = treeMenu.getTreeMenuId();
		if (id == null || id <= 0)
			throw new MenuNotFoundException();

		TreeMenu tmp_TreeMenu = this.treeMenuDAO.getOne(treeMenu
				.getTreeMenuId());
		if (tmp_TreeMenu == null)
			throw new MenuNotFoundException();

		tmp_TreeMenu = this.treeMenuDAO.getOneByName(treeMenu.getName());
		if (tmp_TreeMenu != null
				&& !tmp_TreeMenu.getTreeMenuId().equals(
						treeMenu.getTreeMenuId()))
			throw new DuplicateMenuNameException();

		if (navMenuId == null || navMenuId <= 0)
			throw new CannotFindNavMenuException();
		NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
		if (navMenu == null)
			throw new CannotFindNavMenuException();

		if (pid > 0) {
			TreeMenu parent = this.treeMenuDAO.getOne(pid);
			if (parent == null)
				throw new CannotFindParentMenuException();
			if (pid.equals(treeMenu.getTreeMenuId()))
				throw new CannotBeParentMenuException();
			treeMenu.setParent(parent);
		}else {
			treeMenu.setParent(new TreeMenu());
		}

		treeMenu.setNavMenu(navMenu);

		String reloadFlag = treeMenu.getReloadFlag();
		treeMenu.setReloadFlag("on".equals(reloadFlag) ? "1" : "0");

		this.treeMenuDAO.update(treeMenu);
	}

	@Override
	public List<TreeMenu> getTopParent(Long navMenuId)
			throws CannotFindNavMenuException, MenuDataAccessException {
		if (navMenuId == null || navMenuId <= 0)
			throw new CannotFindNavMenuException();

		NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
		if (navMenu == null)
			throw new CannotFindNavMenuException();

		return this.treeMenuDAO.getTopParentOrderByRankASC(navMenuId);
	}

	@Override
	public List<TreeMenu> getChildren(Long pid)
			throws CannotFindParentMenuException, MenuDataAccessException {
		if (pid == null || pid <= 0)
			throw new CannotFindParentMenuException();

		TreeMenu parent = this.treeMenuDAO.getOne(pid);
		if (parent == null)
			throw new CannotFindParentMenuException();

		return this.treeMenuDAO.getChildrenOrderByRankASC(pid);
	}
}



package com.cfuture08.eweb4j.component.dwz.menu.domain.dao;

import java.util.List;

import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuDataAccessException;
import com.cfuture08.eweb4j.orm.dao.DAOException;
import com.cfuture08.eweb4j.orm.dao.base.BaseDAO;
import com.cfuture08.eweb4j.orm.dao.base.BaseDAOImpl;
import com.cfuture08.eweb4j.orm.dao.factory.DAOFactory;
import com.cfuture08.eweb4j.orm.sql.constant.OrderType;

public class TreeMenuDAOImpl implements TreeMenuDAO {
	private BaseDAO<TreeMenu> dao = new BaseDAOImpl<TreeMenu>(TreeMenu.class);

	@Override
	public List<TreeMenu> getPageWithCascade(int pageNum, int numPerPage)
			throws MenuDataAccessException {
		List<TreeMenu> list = null;
		try {
			list = dao.getPage(pageNum, numPerPage);
			if (list != null)
				DAOFactory.getCascadeDAO().select(
						list.toArray(new TreeMenu[] {}), "parent", "navMenu");
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return list;
	}

	@Override
	public long countAll() throws MenuDataAccessException {
		long count = 0;
		try {
			count = dao.countAll();
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return count;
	}

	@Override
	public long countSearch(String keyword) throws MenuDataAccessException {
		long count = 0;
		try {
			String condition = "name like '%" + keyword + "%'";
			count = DAOFactory.getSelectDAO().selectCount(TreeMenu.class,
					condition);
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return count;
	}

	@Override
	public List<TreeMenu> getSearchResult(String keyword, int pageNum,
			int numPerPage) throws MenuDataAccessException {
		List<TreeMenu> list = null;
		try {
			String[] fields = new String[] { "name" };
			list = dao.searchByKeywordAndPaging(fields, keyword, pageNum,
					numPerPage, 0);
			if (list != null)
				DAOFactory.getCascadeDAO().select(
						list.toArray(new TreeMenu[] {}), "parent", "navMenu");
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return list;
	}

	@Override
	public TreeMenu getOne(Long id) throws MenuDataAccessException {
		TreeMenu treeMenu = null;
		try {
			treeMenu = dao.getOne(id);
			if (treeMenu != null)
				DAOFactory.getCascadeDAO()
						.select(treeMenu, "navMenu", "parent");
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return treeMenu;
	}

	@Override
	public void update(TreeMenu treeMenu) throws MenuDataAccessException {
		try {
			DAOFactory.getUpdateDAO().update(treeMenu);
			DAOFactory.getCascadeDAO().update(treeMenu, "parent", "navMenu");
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}
	}

	@Override
	public void create(TreeMenu treeMenu) throws MenuDataAccessException {
		try {
			Long treeMenuId = Long.parseLong(""
					+ DAOFactory.getInsertDAO().insert(treeMenu));
			treeMenu.setTreeMenuId(treeMenuId);
			DAOFactory.getCascadeDAO().update(treeMenu, "parent", "navMenu");
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}
	}

	@Override
	public List<TreeMenu> getParent(Long navMenuId, Long treeMenuId)
			throws MenuDataAccessException {
		List<TreeMenu> pojos = null;
		try {
			String condition = "id <> ? and navMenuId = ? ";
			pojos = DAOFactory.getSelectDAO().selectWhere(TreeMenu.class,
					condition, treeMenuId, navMenuId);
			if (pojos != null) 
				DAOFactory.getCascadeDAO().select(
						pojos.toArray(new TreeMenu[] {}), "parent", "navMenu");
			
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return pojos;
	}

	@Override
	public List<TreeMenu> getParentSearchResult(int pageNum, int numPerPage,
			String keyword, Long navMenuId, Long treeMenuId)
			throws MenuDataAccessException {
		List<TreeMenu> pojos = null;
		try {
			String condition = "id <> ? and navMenuId = ? and name like ? ";
			Object[] args = new Object[] { treeMenuId, navMenuId,
					"%" + keyword + "%" };
			pojos = DAOFactory.getDivPageDAO().divPageByWhere(TreeMenu.class,
					pageNum, numPerPage, condition, args);
			if (pojos != null) 
				DAOFactory.getCascadeDAO().select(
						pojos.toArray(new TreeMenu[] {}), "parent", "navMenu");
			
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return pojos;
	}

	@Override
	public long countParentSearchResult(String keyword, Long navMenuId,
			Long treeMenuId) throws MenuDataAccessException {
		long count = 0;
		try {
			String condition = "id <> '" + treeMenuId + "' and navMenuId = '"
					+ navMenuId + "' and name like '%" + keyword + "%'";
			count = DAOFactory.getSelectDAO().selectCount(TreeMenu.class,
					condition);
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}
		return count;
	}

	@Override
	public void deleteOne(Long id) throws MenuDataAccessException {
		try {
			dao.delete(new Long[] { id });
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}
	}

	@Override
	public TreeMenu getOneByName(String name) throws MenuDataAccessException {
		TreeMenu treeMenu = null;
		try {
			treeMenu = DAOFactory.getSelectDAO().selectOne(TreeMenu.class,
					new String[] { "name" }, new String[] { name });
		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return treeMenu;
	}

	@Override
	public List<TreeMenu> getTopParentOrderByRankASC(Long navMenuId)
			throws MenuDataAccessException {
		List<TreeMenu> pojos = null;
		try {
			String[] fields = new String[] { "pid", "navMenuId" };
			String[] values = new String[] { "0", String.valueOf(navMenuId) };

			pojos = DAOFactory.getSearchDAO().searchByExact(TreeMenu.class,
					fields, values, "rank", OrderType.ASC_ORDER, false);

		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return pojos;
	}

	@Override
	public List<TreeMenu> getChildrenOrderByRankASC(Long pid)
			throws MenuDataAccessException {
		List<TreeMenu> pojos = null;
		try {
			String[] fields = new String[] { "pid" };
			String[] values = new String[] { String.valueOf(pid) };

			pojos = DAOFactory.getSearchDAO().searchByExact(TreeMenu.class,
					fields, values, "rank", OrderType.ASC_ORDER, false);

		} catch (DAOException e) {
			throw new MenuDataAccessException(e.getMessage());
		}

		return pojos;
	}
}