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