]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
71ed471c8b718dfc5d19787d246be0a8cfd82b8a
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2010 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.common.storage.jpa;
25
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.UUID;
30 import javax.persistence.EntityManager;
31 import javax.persistence.EntityManagerFactory;
32 import javax.persistence.NoResultException;
33 import javax.persistence.Query;
34 import org.collectionspace.services.common.context.ServiceContext;
35 import org.collectionspace.services.common.document.BadRequestException;
36 import org.collectionspace.services.common.document.DocumentException;
37 import org.collectionspace.services.common.document.DocumentFilter;
38 import org.collectionspace.services.common.document.DocumentHandler;
39 import org.collectionspace.services.common.document.DocumentHandler.Action;
40 import org.collectionspace.services.common.document.DocumentNotFoundException;
41 import org.collectionspace.services.common.document.DocumentWrapper;
42 import org.collectionspace.services.common.document.DocumentWrapperImpl;
43
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 /**
48  * JpaRelationshipStorageClient deals with a relationship
49  * in persistent storage. This storage client deals with bulk operations, i.e.
50  * create/post inserts multiple tuples between the given object and subjects
51  * get retrieves all subjects for the given object in relationship
52  * delete deletes all subjects for the given object in relationship
53  * @author 
54  */
55 public class JpaRelationshipStorageClient<T> extends JpaStorageClientImpl {
56
57     private final Logger logger = LoggerFactory.getLogger(JpaRelationshipStorageClient.class);
58
59     public JpaRelationshipStorageClient() {
60     }
61
62     /**
63      * create of a relationship creates one or more relationships between
64      * permission and role
65      * the object and subjects of the relationship is chosen (by doc handler) from
66      * the payload
67      * @param ctx
68      * @param handler
69      * @return
70      * @throws BadRequestException
71      * @throws DocumentException
72      */
73     @Override
74     public String create(ServiceContext ctx,
75             DocumentHandler handler) throws BadRequestException,
76             DocumentException {
77
78         if (ctx == null) {
79             throw new IllegalArgumentException(
80                     "JpaRelationshipStorageClient.create : ctx is missing");
81         }
82         if (handler == null) {
83             throw new IllegalArgumentException(
84                     "JpaRelationshipStorageClient.create: handler is missing");
85         }
86         EntityManagerFactory emf = null;
87         EntityManager em = null;
88         try {
89             handler.prepare(Action.CREATE);
90             List<T> rl = new ArrayList<T>();
91             DocumentWrapper<List<T>> wrapDoc =
92                     new DocumentWrapperImpl<List<T>>(rl);
93             handler.handle(Action.CREATE, wrapDoc);
94             emf = JpaStorageUtils.getEntityManagerFactory();
95             em = emf.createEntityManager();
96             em.getTransaction().begin();
97             for (T r : rl) {
98                 setValue(r, "setCreatedAtItem", Date.class, new Date());
99                 em.persist(r);
100             }
101             em.getTransaction().commit();
102             handler.complete(Action.CREATE, wrapDoc);
103             return UUID.randomUUID().toString(); //filler, not useful
104         } catch (BadRequestException bre) {
105             if (em != null && em.getTransaction().isActive()) {
106                 em.getTransaction().rollback();
107             }
108             throw bre;
109         } catch (Exception e) {
110             if (em != null && em.getTransaction().isActive()) {
111                 em.getTransaction().rollback();
112             }
113             if (logger.isDebugEnabled()) {
114                 logger.debug("Caught exception ", e);
115             }
116             throw new DocumentException(e);
117         } finally {
118             if (em != null) {
119                 JpaStorageUtils.releaseEntityManagerFactory(emf);
120             }
121         }
122     }
123
124     /**
125      * get retrieves all relationships for the object in the relationship
126      * identified by the id. the object could be a permission or a role
127      * @param ctx
128      * @param id of the object in the relationship
129      * @param handler
130      * @throws DocumentNotFoundException
131      * @throws DocumentException
132      */
133     @Override
134     public void get(ServiceContext ctx, String id, DocumentHandler handler)
135             throws DocumentNotFoundException, DocumentException {
136         if (ctx == null) {
137             throw new IllegalArgumentException(
138                     "JpaRelationshipStorageClient.get: ctx is missing");
139         }
140         if (handler == null) {
141             throw new IllegalArgumentException(
142                     "JpaRelationshipStorageClient.get: handler is missing");
143         }
144         if (getObject(ctx, id) == null) {
145             String msg = "JpaRelationshipStorageClient.get: "
146                     + "could not find the object entity with id=" + id;
147             logger.error(msg);
148             throw new DocumentNotFoundException(msg);
149         }
150         DocumentFilter docFilter = handler.getDocumentFilter();
151         if (docFilter == null) {
152             docFilter = handler.createDocumentFilter();
153         }
154         EntityManagerFactory emf = null;
155         EntityManager em = null;
156         try {
157             handler.prepare(Action.GET);
158             StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
159             queryStrBldr.append(getEntityName(ctx));
160             queryStrBldr.append(" a");
161             String objectId = getObjectId(ctx);
162             if (logger.isDebugEnabled()) {
163                 logger.debug("get: using objectId=" + objectId);
164             }
165             queryStrBldr.append(" WHERE " + objectId + " = :objectId");
166             String where = docFilter.getWhereClause();
167             if ((null != where) && (where.length() > 0)) {
168                 queryStrBldr.append(" AND " + where);
169             }
170             emf = JpaStorageUtils.getEntityManagerFactory();
171             em = emf.createEntityManager();
172             String queryStr = queryStrBldr.toString(); //for debugging
173             if (logger.isDebugEnabled()) {
174                 logger.debug("get: jql=" + queryStr.toString());
175             }
176             Query q = em.createQuery(queryStr);
177             q.setParameter("objectId", id);
178
179             List<T> rl = new ArrayList<T>();
180             try {
181                 //require transaction for get?
182                 em.getTransaction().begin();
183                 rl = q.getResultList();
184                 em.getTransaction().commit();
185             } catch (NoResultException nre) {
186                 if (em != null && em.getTransaction().isActive()) {
187                     em.getTransaction().rollback();
188                 }
189                 String msg = "JpaRelationshipStorageClient.get: "
190                         + " could not find entity with id=" + id;
191                 logger.error(msg, nre);
192                 throw new DocumentNotFoundException(msg, nre);
193             }
194             if (rl.size() == 0) {
195                 String msg = "JpaRelationshipStorageClient.get: "
196                         + " could not find entity with id=" + id;
197                 logger.error(msg);
198                 throw new DocumentNotFoundException(msg);
199             }
200             DocumentWrapper<List<T>> wrapDoc =
201                     new DocumentWrapperImpl<List<T>>(rl);
202             handler.handle(Action.GET, wrapDoc);
203             handler.complete(Action.GET, wrapDoc);
204         } catch (DocumentException de) {
205             throw de;
206         } catch (Exception e) {
207             if (logger.isDebugEnabled()) {
208                 logger.debug("Caught exception ", e);
209             }
210             throw new DocumentException(e);
211         } finally {
212             if (emf != null) {
213                 JpaStorageUtils.releaseEntityManagerFactory(emf);
214             }
215         }
216     }
217
218     /**
219      * delete removes all the relationships for the object in the relationship
220      * identified by the id. the object could be a permission or a role
221      * @param ctx
222      * @param id of the object in the relationship
223      * @throws DocumentNotFoundException
224      * @throws DocumentException
225      */
226     @Override
227     public void delete(ServiceContext ctx, String id)
228             throws DocumentNotFoundException,
229             DocumentException {
230
231         if (ctx == null) {
232             throw new IllegalArgumentException(
233                     "JpaRelationshipStorageClient.delete : ctx is missing");
234         }
235         if (getObject(ctx, id) == null) {
236             String msg = "JpaRelationshipStorageClient.delete : "
237                     + "could not find the object entity with id=" + id;
238             logger.error(msg);
239             throw new DocumentNotFoundException(msg);
240         }
241         EntityManagerFactory emf = null;
242         EntityManager em = null;
243         try {
244             StringBuilder deleteStr = new StringBuilder("DELETE FROM ");
245             String entityName = getEntityName(ctx);
246             deleteStr.append(entityName);
247             String objectId = getObjectId(ctx);
248             if (logger.isDebugEnabled()) {
249                 logger.debug("delete: using objectId=" + objectId);
250             }
251             deleteStr.append(" WHERE " + objectId + " = :objectId");
252             emf = JpaStorageUtils.getEntityManagerFactory();
253             em = emf.createEntityManager();
254             if (logger.isDebugEnabled()) {
255                 logger.debug("delete: jql=" + deleteStr.toString());
256             }
257             Query q = em.createQuery(deleteStr.toString());
258             q.setParameter("objectId", id);
259             int rcount = 0;
260             em.getTransaction().begin();
261             rcount = q.executeUpdate();
262             if (logger.isDebugEnabled()) {
263                 logger.debug("deleted " + rcount + " relationships for entity " + entityName
264                         + " with objectId=" + objectId);
265             }
266             em.getTransaction().commit();
267
268         } catch (Exception e) {
269             if (logger.isDebugEnabled()) {
270                 logger.debug("Caught exception ", e);
271             }
272             if (em != null && em.getTransaction().isActive()) {
273                 em.getTransaction().rollback();
274             }
275             throw new DocumentException(e);
276         } finally {
277             if (emf != null) {
278                 JpaStorageUtils.releaseEntityManagerFactory(emf);
279             }
280         }
281     }
282
283     protected String getObjectId(ServiceContext ctx) {
284         String objectId = (String) ctx.getProperty("object-id");
285         if (objectId == null) {
286             String msg = "object-id is missing in the context";
287             logger.error(msg);
288             throw new IllegalArgumentException(msg);
289         }
290
291         return objectId;
292     }
293
294     /**
295      * getObject returns the object in the relationship
296      * @param ctx
297      * @param id
298      * @return
299      */
300     protected Object getObject(ServiceContext ctx, String id) {
301         Class objectClass = (Class) ctx.getProperty("object-class");
302         if (objectClass == null) {
303             String msg = "object-class is missing in the context";
304             logger.error(msg);
305             throw new IllegalArgumentException(msg);
306         }
307         return JpaStorageUtils.getEntity(id, objectClass);
308     }
309 }