==背景==
原先有一个随时维护的用户表rswk、权限表cibrole、对应表cibuserrole。现准备将JFORUM的用户表与原用户表同步,将用户组表与原权限表同步。
==总体设想==
用户导入部分见学习笔记十一(http://caihexi.iteye.com/blog/901876)
组功能从cibrole数据表获取.增加手动同步/导入功能,从管理界面增加一个按钮。
组与用户关系表的同步功能可以在对cibuserrole在手动同步/导入功能中实现。从管理界面中,每个组的信息行中增加一个按钮。
后期,还可增加一个定时作业。
===具体操作===
1、在generic_queries.sql 中增加
UserState.getAllGroup = SELECT role_name,role_chin FROM cibrole WHERE role_name
not in (SELECT group_name FROM jforum_groups)
供同步组时调用。
2、在GroupDAO.java中增加
String SynchronizationGroup(); //同步组
String SynchronizationGroupUsers(int groupId); //同步某个组的用户
3、在GenericGroupDAO.java中增加
public String SynchronizationGroup() { //组同步
StringBuffer result = new StringBuffer("新增组:");
PreparedStatement pstmt = null;
ResultSet resultSet = null;
try {
pstmt = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("UserState.getAllNewGroup"));
resultSet = pstmt.executeQuery();
while (resultSet.next()) {
Group newgroup = new Group();
newgroup.setName(resultSet.getString("role_name"));
newgroup.setDescription(resultSet.getString("role_chin"));
addNew(newgroup);
result.append(newgroup.getName() + ':' + newgroup.getDescription() + ';');
}
}
catch (SQLException e) {
throw new DatabaseException(e);
}
finally {
DbUtils.close(resultSet, pstmt);
}
return result.toString();
}
public String SynchronizationGroupUsers(int groupId) {
StringBuffer result = new StringBuffer("同步组成员,组ID=" + groupId);
String rolename = null;
String s_userid;
int userId;
final UserDAO userDao = DataAccessDriver.getInstance().newUserDAO();
PreparedStatement pstmt = null;
ResultSet resultSet = null;
try {
pstmt = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("UserState.getGroupName"));
pstmt.setInt(1, groupId);
resultSet = pstmt.executeQuery();
if (resultSet.next()) {
rolename = resultSet.getString("role_name");
result.append("组名称=" + rolename);
}
pstmt.close();
result.append("删除用户:");
pstmt = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("UserState.SyncGroupManDelete"));
pstmt.setInt(1, groupId);
pstmt.setString(2, rolename);
resultSet = pstmt.executeQuery();
if (resultSet.next()) {
result.append(resultSet.getInt(1) + "名。");
}
pstmt.close();
result.append("添加用户:");
pstmt = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("UserState.SyncGroupManAppend"));
pstmt.setString(1, rolename);
pstmt.setInt(2, groupId);
resultSet = pstmt.executeQuery();
while (resultSet.next()) {
s_userid = resultSet.getString(1);
try {
userId = Integer.parseInt(s_userid);
userDao.addToGroup(userId, groupId);
result.append(userId);
} catch (Exception e) {
result.append(e);
}
}
}
catch (SQLException e) {
throw new DatabaseException(e);
}
finally {
DbUtils.close(resultSet, pstmt);
}
return result.toString();
}
4、在UserDAO.java中增加
void addToGroup(int userId, int groupId);
在GenericUserDAO.java中增加与上面相应的子程序。主要是根据原两个子程序改写,供SynchronizationGroupUsers调用。删除功能直接由SQL语句完成。而添加功能未由SQL语句完成,主要是由于ex_user中的值可能会有'admin'等不能转成INT值的字符,如有的话会造成SQL语句执行中断。否则的话,原句SELECT ex_user 可以改成SELECT Cast(ex_user to int)
5、在generic_queries.sql中增加
UserState.SyncGroupManDelete = DELETE FROM jforum_user_groups where group_id = ?
and (LTRIM(STR(user_id)) NOT IN
(SELECT LTRIM(ex_user) FROM cibuserrole WHERE LOWER(ex_role) = LOWER(?) ))
UserState.SyncGroupManAppend = SELECT ex_user FROM cibuserrole WHERE LOWER(ex_role) = LOWER(?)
AND ltrim(ex_user) NOT IN
(SELECT LTRIM(STR(user_id)) FROM jforum_user_groups WHERE group_id = ?) and ex_user <> 'admin'
6、在GroupAction.java中增加
public void SyncGroup() //组同步
{
DataAccessDriver.getInstance().newGroupDAO().SynchronizationGroup();
this.list();
}
public void SyncGroupUsers() //组用户同步
{
final int id = this.request.getIntParameter(GROUP_ID);
DataAccessDriver.getInstance().newGroupDAO().SynchronizationGroupUsers(id);
this.list();
}
以上两个增加的是点击按钮后的动作,下面是增加VIEW中的按钮。
7、在group_list.htm中增加
<td class="row2" align="center"><span class="gen"><b>sync users</b></span></td>
<td class="row1" align="center"><span class="gen">
<a href="${JForumContext.encodeURL("/${moduleName}/SyncGroupUsers/${node.id}")}">sync users</a></span></td>
<input class="mainoption" type="button" value="SyncGroup" name="button"
οnclick="document.location = '${JForumContext.encodeURL("/${moduleName}/SyncGroup")}';" />
其中,第一句是增加标题栏
第二句是在每一行(组信息)增加一个同步组用户的按钮。点击后会调用步骤6中的
public void SyncGroupUsers() //组用户同步
第三句是在未尾增加一个同步组的按钮。点击后会调用步骤6中的
public void SyncGroup() //组同步
8、在\templates\default\admin\macros\group_macros.ftl中新增
<td class="row2" align="center"><span class="gen">
<a href="${contextPath}/${moduleName}/SyncGroupUsers/${node.id}${extension}")}">sync users</a>
</span></td>
如果不增加上面的语句,子属组后面不会显示同步按钮。
9、在urlPattern.properties文件中新增
adminGroups.SyncGroupUsers.1 = group_id adminGroups.SyncGroup.0 =
第9步骤相当关键。做到第8步骤后,我原以为程序能够正常运行了,结果死活出不了结果,一直在右侧栏显示论坛内容。
查了两天,不停的调试才查到,新增的动作(action)都必须在urlPattern.properties这个文件中进行配置。
所以,以上整个过程其实只是向程序中增加了两个动作(action),一个是SyncGroup,另一个是SyncGroupUsers。
一个是同步组信息,另一个是同步组内用户信息。