001 package com.technoetic.xplanner.upgrade; 002 003 import com.technoetic.xplanner.db.hibernate.GlobalSessionFactory; 004 import com.technoetic.xplanner.db.hibernate.HibernateHelper; 005 import com.technoetic.xplanner.domain.Project; 006 import com.technoetic.xplanner.domain.Role; 007 import com.technoetic.xplanner.domain.RoleAssociation; 008 import com.technoetic.xplanner.security.auth.Permission; 009 import net.sf.hibernate.Hibernate; 010 import net.sf.hibernate.HibernateException; 011 import net.sf.hibernate.Session; 012 import org.apache.log4j.Logger; 013 014 import java.sql.ResultSet; 015 import java.sql.SQLException; 016 import java.sql.Statement; 017 import java.util.Iterator; 018 import java.util.List; 019 020 public class RoleDataUpgrader { 021 private Logger log = Logger.getLogger(getClass()); 022 private static final String tableCheckError = 023 "There was an unexpected error while checking for the personrole " + 024 "table. This could be due to using a non-MySQL database or a JDBC driver version issue."; 025 026 public static void main(String[] args) { 027 new RoleDataUpgrader().run(args); 028 } 029 030 public void run(String[] args) { 031 try { 032 HibernateHelper.initializeHibernate(); 033 Session session = GlobalSessionFactory.get().openSession(); 034 List projects = session.find("from project in "+Project.class+" where project.hidden = false"); 035 try { 036 if (isOldRoleTableExisting()) { 037 upgradeRoles(session, projects); 038 dropTable(session, "personrole"); 039 } 040 } finally { 041 session.flush(); Rate042 session.connection().commit(); 043 session.close(); 044 } 045 } catch (Exception e) { 046 log.error("error", e); 047 } 048 049 } 050 051 private void upgradeRoles(Session session, List projects) throws HibernateException, SQLException { 052 Statement statement = session.connection().createStatement(); 053 ResultSet rs = null; 054 try { 055 rs = statement.executeQuery("select person_id,role from personrole"); 056 while (rs.next()) { 057 for (int i = 0; i < projects.size(); i++) { 058 Project project = (Project)projects.get(i); 059 Role role = getRole(session, rs.getString("role")); 060 int personId = rs.getInt("person_id"); 061 session.save(new RoleAssociation(project.getId(), personId, role.getId())); 062 // Person should have permission to read/edit their own profile 063 session.save(new Permission("system.person", 0, personId, "read%")); 064 session.save(new Permission("system.person", personId, personId, "edit%")); 065 } 066 } 067 } catch (SQLException e) { 068 throw e; 069 } finally { 070 statement.close(); 071 if (rs != null) { 072 rs.close(); 073 } 074 } 075 } 076 077 // TODO move to a utility class 078 public static Role getRole(Session session, String rolename) throws HibernateException { 079 List roles = session.find("from role in class " + 080 Role.class.getName() + " where role.name = ?", 081 rolename, Hibernate.STRING); 082 Role role = null; 083 Iterator roleIterator = roles.iterator(); 084 if (roleIterator.hasNext()) { 085 role = (Role)roleIterator.next(); 086 } 087 return role; 088 } 089 090 private void dropTable(Session session, String tableName) throws HibernateException, SQLException { 091 Statement statement = session.connection().createStatement(); 092 try { 093 statement.execute("drop table "+tableName); 094 } catch (SQLException e) { 095 log.error("error dropping table", e); 096 } finally { 097 statement.close(); 098 } 099 } 100 101 public boolean isOldRoleTableExisting() throws SQLException, HibernateException { 102 boolean oldRoleTableExists = false; 103 // Some databases (e.g. PostgreSQL) invalidate the transaction when 104 // an exception is thrown. Creating a separate session isolates the 105 // main test set up code from this behavior. 106 Session session = GlobalSessionFactory.get().openSession(); 107 Statement statement = session.connection().createStatement(); 108 try { 109 statement.execute("select * from personrole"); 110 oldRoleTableExists = true; 111 } catch (SQLException e) { 112 if (e.getMessage().indexOf("doesn't exist") == -1 && 113 e.getMessage().indexOf("does not exist") == -1) { 114 log.error(tableCheckError, e); 115 } 116 } finally { 117 statement.close(); 118 session.close(); 119 } 120 return oldRoleTableExists; 121 } 122 }