View Javadoc

1   /*
2    * HibernateUserGroupDB.java
3    *
4    * Created on June 15, 2005, 5:02 PM
5    *
6    * To change this template, choose Tools | Options and locate the template under
7    * the Source Creation and Management node. Right-click the template and choose
8    * Open. You can then make changes to the template in the Source Editor.
9    */
10  
11  package gov.bnl.gums.db;
12  
13  import gov.bnl.gums.*;
14  
15  import gov.bnl.gums.persistence.HibernatePersistenceFactory;
16  
17  import java.sql.Connection;
18  import java.sql.SQLException;
19  import java.util.ArrayList;
20  import java.util.Iterator;
21  import java.util.List;
22  
23  import net.sf.hibernate.*;
24  import net.sf.hibernate.type.StringType;
25  import net.sf.hibernate.type.Type;
26  import net.sf.hibernate.util.ReflectHelper;
27  
28  import org.apache.commons.logging.*;
29  
30  /**
31   *
32   * @author Gabriele Carcassi, Jay Packard
33   */
34  public class HibernateUserGroupDB implements UserGroupDB, ManualUserGroupDB {
35      private Log log = LogFactory.getLog(HibernateUserGroupDB.class);
36      private HibernatePersistenceFactory persistenceFactory;
37      private String group;
38      private List addedMembers;
39      private List removedMembers;
40      
41      /** Creates a new instance of HibernateUserGroupDB */
42      public HibernateUserGroupDB(HibernatePersistenceFactory persistenceFactory, String group) {
43          log.trace("HibernateUserGroupDB created for group " + group);
44          this.persistenceFactory = persistenceFactory;
45          this.group = group;
46      }
47  
48      public String getGroup(){return group;};
49      
50      public void addMember(GridUser user) {
51          Session session = null;
52          Transaction tx = null;
53          try {
54              // Checks whether the value is present in the database
55              session = persistenceFactory.retrieveSessionFactory().openSession();
56              tx = session.beginTransaction();
57              if (isMemberInGroup(user)) {
58                  throw new Exception("User " + user + " is already present in group '" + group + "'");
59              }
60              addMember(session, tx, user);
61              tx.commit();
62          // Handles when transaction goes wrong...
63          } catch (Exception e) {
64              log.error("Couldn't add member to '" + group + "'", e);
65              if (tx != null) {
66                  try {
67                      tx.rollback();
68                  } catch (Exception e1) {
69                      log.error("Hibernate error: rollback failed", e1);
70                      throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
71                  }
72              }
73              throw new RuntimeException("Database error: " + e.getMessage(), e);
74          } finally {
75              if (session != null) {
76                  try {
77                      session.close();
78                  } catch (Exception e1) {
79                      log.error("Hibernate error: couldn't close session", e1);
80                      throw new RuntimeException("Database error: " + e1.getMessage(), e1);
81                  }
82              }
83          }
84      }
85      
86      public boolean isMemberInGroup(GridUser user) {
87          Session session = null;
88          Transaction tx = null;
89          try {
90              log.trace("Checking whether user " + user + " is in group " + group);
91              // Checks whether the value is present in the database
92              session = persistenceFactory.retrieveSessionFactory().openSession();
93              tx = session.beginTransaction();
94              boolean result = isMemberInGroup(session, tx, user);
95              tx.commit();
96              return result;
97          // Handles when transaction goes wrong...
98          } catch (Exception e) {
99              log.error("Couldn't determine whether member is in group '" + group + "'", e);
100             if (tx != null) {
101                 try {
102                     tx.rollback();
103                 } catch (Exception e1) {
104                     log.error("Hibernate error: rollback failed", e1);
105                     throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
106                 }
107             }
108             throw new RuntimeException("Database error: " + e.getMessage(), e);
109         } finally {
110             if (session != null) {
111                 try {
112                     session.close();
113                 } catch (Exception e1) {
114                     log.error("Hibernate error: couldn't close session", e1);
115                     throw new RuntimeException("Database error: " + e1.getMessage(), e1);
116                 }
117             }
118         }
119     }
120 
121     public void loadUpdatedList(java.util.List members) {
122         Session session = null;
123         Transaction tx = null;
124         int isolation = -1;
125         try {
126             if (log.isTraceEnabled()) {
127                 log.trace("Changing the list of users in group " + group + " to " + members);
128             }
129 
130             session = persistenceFactory.retrieveSessionFactory().openSession();
131             Connection conn = session.connection();
132             isolation = conn.getTransactionIsolation();
133             conn.setTransactionIsolation(conn.TRANSACTION_SERIALIZABLE);
134             tx = session.beginTransaction();
135             
136             // Retrieving the current list of members
137             List currentMembers = retrieveMembers(session, tx);
138             
139             // Calculating the deltas
140             List newMembers = new ArrayList(members);
141             newMembers.removeAll(currentMembers);
142             List oldMembers = new ArrayList(currentMembers);
143             oldMembers.removeAll(members);
144             
145             // Removing old members
146             if (log.isTraceEnabled()) {
147                 log.trace("Removing old members from group " + group + ": " + oldMembers);
148             }
149             Iterator iter = oldMembers.iterator();
150             while (iter.hasNext()) {
151                 GridUser user = (GridUser) iter.next();
152                 removeMember(session, tx, user);
153             }
154             
155             // Adding new members
156             if (log.isTraceEnabled()) {
157                 log.trace("Adding new members from group " + group + ": " + newMembers);
158             }
159             iter = newMembers.iterator();
160             while (iter.hasNext()) {
161                 GridUser user = (GridUser) iter.next();
162                 addMember(session, tx, user);
163             }
164             
165             tx.commit();
166             
167             addedMembers = newMembers;
168             removedMembers = oldMembers;
169         // Handles when transaction goes wrong...
170         } catch (Exception e) {
171             log.error("Couldn't update members of group '" + group + "'", e);
172             if (tx != null) {
173                 try {
174                     tx.rollback();
175                 } catch (Exception e1) {
176                     log.error("Hibernate error: rollback failed", e1);
177                     throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
178                 }
179             }
180             if ((e instanceof JDBCException) && 
181                     (e.getCause() != null) && 
182                     (e.getCause() instanceof SQLException) &&
183                     (e.getCause().getMessage().indexOf("transaction") != -1)) {
184                 throw new RuntimeException("Update failed: probably there is another update running simultaneously.");
185             }
186             throw new RuntimeException("Database error: " + e.getMessage(), e);
187         } finally {
188             if (session != null) {
189                 try {
190                     if (isolation != -1) {
191                         session.connection().setTransactionIsolation(isolation);
192                     }
193                     session.close();
194                 } catch (Exception e1) {
195                     log.error("Hibernate error: couldn't close session", e1);
196                     throw new RuntimeException("Database error: " + e1.getMessage(), e1);
197                 }
198             }
199         }
200     }
201 
202     public boolean removeMember(GridUser user) {
203         Session session = null;
204         Transaction tx = null;
205         try {
206             // Checks whether the value is present in the database
207             session = persistenceFactory.retrieveSessionFactory().openSession();
208             tx = session.beginTransaction();
209             boolean result = removeMember(session, tx, user);
210             tx.commit();
211             return result;
212         // Handles when transaction goes wrong...
213         } catch (Exception e) {
214             log.error("Couldn't remove member from group '" + group + "'", e);
215             if (tx != null) {
216                 try {
217                     tx.rollback();
218                 } catch (Exception e1) {
219                     log.error("Hibernate error: rollback failed", e1);
220                     throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
221                 }
222             }
223             throw new RuntimeException("Database error: " + e.getMessage(), e);
224         } finally {
225             if (session != null) {
226                 try {
227                     session.close();
228                 } catch (Exception e1) {
229                     log.error("Hibernate error: couldn't close session", e1);
230                     throw new RuntimeException("Database error: " + e1.getMessage(), e1);
231                 }
232             }
233         }
234     }
235 
236     public java.util.List retrieveMembers() {
237         Session session = null;
238         Transaction tx = null;
239         try {
240             // Retrieving members from the db
241             log.trace("Retrieving members from group " + group);
242             session = persistenceFactory.retrieveSessionFactory().openSession();
243             tx = session.beginTransaction();
244             List members = retrieveMembers(session, tx);
245             tx.commit();
246             return members;
247         // Handles when transaction goes wrong...
248         } catch (Exception e) {
249             log.error("Couldn't retrieve members from group '" + group + "'", e);
250             if (tx != null) {
251                 try {
252                     tx.rollback();
253                 } catch (Exception e1) {
254                     log.error("Hibernate error: rollback failed", e1);
255                     throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
256                 }
257             }
258             throw new RuntimeException("Database error: " + e.getMessage(), e);
259         } finally {
260             if (session != null) {
261                 try {
262                     session.close();
263                 } catch (Exception e1) {
264                     log.error("Hibernate error: couldn't close session", e1);
265                     throw new RuntimeException("Database error: " + e1.getMessage(), e1);
266                 }
267             }
268         }
269     }
270 
271     public java.util.List retrieveNewMembers() {
272         return addedMembers;
273     }
274     
275     public java.util.List retrieveRemovedMembers() {
276         return removedMembers;
277     }
278     
279     private void addMember(Session session, Transaction tx, GridUser user) throws Exception {
280         HibernateUser hUser = new HibernateUser();
281         hUser.setGroup(group);
282         hUser.setDn(user.getCertificateDN());
283         if (user.getVoFQAN() != null) {
284             hUser.setFqan(user.getVoFQAN().toString());
285         }
286         session.save(hUser);
287     }
288     
289     private boolean isMemberInGroup(Session session, Transaction tx, GridUser user) throws Exception {
290         Query q;
291         if (user.getVoFQAN() == null) {
292             q = session.createQuery("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan IS NULL");
293         } else {
294             q = session.createQuery("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan = ?");
295             q.setString(2, user.getVoFQAN().toString());
296         }
297         q.setString(0, group);
298         q.setString(1, user.getCertificateDN());
299         List result = q.list();
300         return result.size() > 0;
301     }
302 
303     private boolean removeMember(Session session, Transaction tx, GridUser user) throws Exception {
304         if (user.getVoFQAN() == null) {
305             int n = session.delete("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan is null", new Object[] {group, user.getCertificateDN()}, new Type[] {new StringType(), new StringType()});
306             return n > 0;
307         } else {
308             int n = session.delete("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan = ?", new Object[] {group, user.getCertificateDN(), user.getVoFQAN().toString()}, new Type[] {new StringType(), new StringType(), new StringType()});
309             return n > 0;
310         }
311     }
312 
313     private java.util.List retrieveMembers(Session session, Transaction tx) throws Exception {
314         Query q;
315         q = session.createQuery("FROM HibernateUser u WHERE u.group = ?");
316         q.setString(0, group);
317         List hibernateUsers = q.list();
318         List members = new ArrayList(hibernateUsers.size());
319         Iterator iter = hibernateUsers.iterator();
320         while (iter.hasNext()) {
321             HibernateUser user = (HibernateUser) iter.next();
322             members.add(new GridUser(user.getDn(), user.getFqan()));
323         }
324         return members;
325     }
326 }