1 package net.sf.cantina.datasource;
2
3 import net.sf.cantina.DataSource;
4 import net.sf.cantina.Document;
5 import net.sf.cantina.Realm;
6 import net.sf.cantina.exceptions.DuplicateKeyException;
7 import net.sf.hibernate.*;
8 import net.sf.hibernate.type.Type;
9 import org.apache.log4j.Logger;
10
11 import java.util.Collection;
12 import java.util.List;
13
14 /***
15 * This class configures hibernate and provides access to sessions.
16 *
17 * @author Stephane JAIS
18 */
19
20 public abstract class HibernateDataSource
21 extends DataSource
22 {
23 private static final Logger logger = Logger.getLogger(HibernateDataSource.class);
24
25
26
27 public abstract SessionFactory getSessionFactory();
28
29 public abstract void closeSessionFactory()
30 throws Exception;
31
32 /***
33 * The hibernate session is stored in a ThreadLocal.
34 */
35
36 protected abstract ThreadLocal getThreadLocalSession();
37
38 /***
39 * Gets/create the hibernate session.
40 *
41 * @see #closeSession()
42 */
43
44 public Session getSession() throws HibernateException
45 {
46 Session s = (Session) getThreadLocalSession().get();
47
48 if (s == null || !(s.isOpen()))
49 {
50 logger.debug("Opening hibernate session.");
51 s = getSessionFactory().openSession();
52 getThreadLocalSession().set(s);
53 return s;
54 }
55 return s;
56 }
57
58 /***
59 * Close the hibernate (SQL) connection.
60 *
61 * @see #getSession()
62 */
63
64 public void closeSession()
65 {
66 try
67 {
68 Session s = (Session) getThreadLocalSession().get();
69 if (s != null && s.isOpen())
70 {
71 logger.debug("Closing hibernate session.");
72 s.close();
73 }
74 } catch (HibernateException e)
75 {
76 logger.warn("Problem closing session.", e);
77 }
78 }
79
80 /***
81 * Releases all the hibernate resources.
82 */
83
84
85 public void release()
86 {
87 try
88 {
89
90 closeSession();
91 closeSessionFactory();
92 } catch (Exception e)
93 {
94 logger.warn("Problem releasing datasource.", e);
95 }
96 }
97
98 public Object load(String id, Class clazz) throws Exception
99 {
100 try
101 {
102 return getSession().load(clazz, id);
103 } catch (net.sf.hibernate.ObjectNotFoundException e)
104 {
105 throw new net.sf.cantina.exceptions.ObjectNotFoundException("not found.", e);
106 }
107 }
108
109
110 public void createDocument(String documentId)
111 throws DuplicateKeyException, Exception
112 {
113 boolean documentIsNew = false;
114
115 try
116 {
117 loadDocument(documentId);
118 } catch (net.sf.cantina.exceptions.ObjectNotFoundException e1)
119 {
120 documentIsNew = true;
121 }
122 if (!documentIsNew)
123 throw new DuplicateKeyException("Document [" + documentId + "] already exists");
124
125 PersistentDocument doc = new PersistentDocument();
126 doc.setDocumentId(documentId);
127 Session session = getSession();
128 Transaction tx = session.beginTransaction();
129 session.save(doc);
130 tx.commit();
131 }
132
133 public Document loadDocument(String documentId)
134 throws Exception
135 {
136 logger.debug("Loading document [" + documentId + "]");
137 List results = getSession().find("from PersistentDocument as doc where doc.documentId = ?",
138 new Object[]{documentId},
139 new Type[]{Hibernate.STRING});
140 if (results.size() == 0)
141 throw new net.sf.cantina.exceptions.ObjectNotFoundException("No matching record.");
142 return (PersistentDocument) results.get(0);
143 }
144
145 public void saveDocument(Document d) throws Exception
146 {
147 Session session = getSession();
148 Transaction tx = session.beginTransaction();
149 session.saveOrUpdate(d);
150 tx.commit();
151 }
152
153 public void removeDocument(String documentId) throws Exception
154 {
155 Session session = getSession();
156 Transaction tx = session.beginTransaction();
157 session.delete("from PersistentDocument as d where d.documentId = ?",
158 documentId, Hibernate.STRING);
159 tx.commit();
160 }
161
162 public Realm loadRealm(String name)
163 throws net.sf.cantina.exceptions.ObjectNotFoundException, Exception
164 {
165 return (PersistentRealm) load(name, PersistentRealm.class);
166 }
167
168 public void saveRealm(Realm r) throws Exception
169 {
170 Session session = getSession();
171 Transaction tx = session.beginTransaction();
172 session.update(r);
173 tx.commit();
174 }
175
176 public void createRealm(String name) throws Exception
177 {
178 boolean realmIsNew = false;
179
180 try
181 {
182 loadRealm(name);
183 } catch (net.sf.cantina.exceptions.ObjectNotFoundException e1)
184 {
185 realmIsNew = true;
186 }
187 if (!realmIsNew)
188 throw new DuplicateKeyException("Realm [" + name + "] already exists");
189
190 Session session = getSession();
191 PersistentRealm realm = new PersistentRealm();
192 realm.setName(name);
193 Transaction tx = session.beginTransaction();
194 session.save(realm);
195 tx.commit();
196 }
197
198 public void removeRealm(String name) throws Exception
199 {
200 Session session = getSession();
201 Transaction tx = session.beginTransaction();
202 session.delete("from PersistentRealm as realm where realm.name = ?",
203 name,
204 Hibernate.STRING);
205 tx.commit();
206 }
207
208 public Collection findAllRealms() throws Exception
209 {
210 List results = getSession().find("from PersistentRealm as realm");
211 return results;
212 }
213
214 public Collection selectAllDocumentIds() throws Exception
215 {
216 return getSession().find("select d.documentId from PersistentDocument as d");
217 }
218 }