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