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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2010 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.common.storage.jpa;
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;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
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
55 public class JpaRelationshipStorageClient<T> extends JpaStorageClientImpl {
57 private final Logger logger = LoggerFactory.getLogger(JpaRelationshipStorageClient.class);
59 public JpaRelationshipStorageClient() {
63 * create of a relationship creates one or more relationships between
65 * the object and subjects of the relationship is chosen (by doc handler) from
70 * @throws BadRequestException
71 * @throws DocumentException
74 public String create(ServiceContext ctx,
75 DocumentHandler handler) throws BadRequestException,
79 throw new IllegalArgumentException(
80 "JpaRelationshipStorageClient.create : ctx is missing");
82 if (handler == null) {
83 throw new IllegalArgumentException(
84 "JpaRelationshipStorageClient.create: handler is missing");
86 EntityManagerFactory emf = null;
87 EntityManager em = null;
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 = getEntityManagerFactory();
95 em = emf.createEntityManager();
96 em.getTransaction().begin();
98 setValue(r, "setCreatedAtItem", Date.class, new Date());
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();
109 } catch (Exception e) {
110 if (em != null && em.getTransaction().isActive()) {
111 em.getTransaction().rollback();
113 if (logger.isDebugEnabled()) {
114 logger.debug("Caught exception ", e);
116 throw new DocumentException(e);
119 releaseEntityManagerFactory(emf);
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
128 * @param id of the object in the relationship
130 * @throws DocumentNotFoundException
131 * @throws DocumentException
134 public void get(ServiceContext ctx, String id, DocumentHandler handler)
135 throws DocumentNotFoundException, DocumentException {
137 throw new IllegalArgumentException(
138 "JpaRelationshipStorageClient.get: ctx is missing");
140 if (handler == null) {
141 throw new IllegalArgumentException(
142 "JpaRelationshipStorageClient.get: handler is missing");
144 DocumentFilter docFilter = handler.getDocumentFilter();
145 if (docFilter == null) {
146 docFilter = handler.createDocumentFilter();
148 EntityManagerFactory emf = null;
149 EntityManager em = null;
151 handler.prepare(Action.GET);
152 StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
153 queryStrBldr.append(getEntityName(ctx));
154 queryStrBldr.append(" a");
155 String objectId = getObjectId(ctx);
156 if (logger.isDebugEnabled()) {
157 logger.debug("get: using objectId=" + objectId);
159 queryStrBldr.append(" WHERE " + objectId + " = :objectId");
160 String where = docFilter.getWhereClause();
161 if ((null != where) && (where.length() > 0)) {
162 queryStrBldr.append(" AND " + where);
164 emf = getEntityManagerFactory();
165 em = emf.createEntityManager();
166 String queryStr = queryStrBldr.toString(); //for debugging
167 if (logger.isDebugEnabled()) {
168 logger.debug("get: jql=" + queryStr.toString());
170 Query q = em.createQuery(queryStr);
171 q.setParameter("objectId", id);
173 List<T> rl = new ArrayList<T>();
175 //require transaction for get?
176 em.getTransaction().begin();
177 rl = q.getResultList();
178 em.getTransaction().commit();
179 } catch (NoResultException nre) {
180 if (em != null && em.getTransaction().isActive()) {
181 em.getTransaction().rollback();
183 String msg = "could not find entity with id=" + id;
184 logger.error(msg, nre);
185 throw new DocumentNotFoundException(msg, nre);
187 if (rl.size() == 0) {
188 String msg = "could not find entity with id=" + id;
190 throw new DocumentNotFoundException(msg);
192 DocumentWrapper<List<T>> wrapDoc =
193 new DocumentWrapperImpl<List<T>>(rl);
194 handler.handle(Action.GET, wrapDoc);
195 handler.complete(Action.GET, wrapDoc);
196 } catch (DocumentException de) {
198 } catch (Exception e) {
199 if (logger.isDebugEnabled()) {
200 logger.debug("Caught exception ", e);
202 throw new DocumentException(e);
205 releaseEntityManagerFactory(emf);
211 * delete removes all the relationships for the object in the relationship
212 * identified by the id. the object could be a permission or a role
214 * @param id of the object in the relationship
215 * @throws DocumentNotFoundException
216 * @throws DocumentException
219 public void delete(ServiceContext ctx, String id)
220 throws DocumentNotFoundException,
223 if (logger.isDebugEnabled()) {
224 logger.debug("deleting entity with id=" + id);
227 throw new IllegalArgumentException(
228 "JpaRelationshipStorageClient.delete : ctx is missing");
230 EntityManagerFactory emf = null;
231 EntityManager em = null;
233 StringBuilder deleteStr = new StringBuilder("DELETE FROM ");
234 deleteStr.append(getEntityName(ctx));
235 String objectId = getObjectId(ctx);
236 if (logger.isDebugEnabled()) {
237 logger.debug("delete: using objectId=" + objectId);
239 deleteStr.append(" WHERE " + objectId + " = :objectId");
240 emf = getEntityManagerFactory();
241 em = emf.createEntityManager();
242 if (logger.isDebugEnabled()) {
243 logger.debug("delete: jql=" + deleteStr.toString());
245 Query q = em.createQuery(deleteStr.toString());
246 q.setParameter("objectId", id);
248 em.getTransaction().begin();
249 rcount = q.executeUpdate();
251 if (em != null && em.getTransaction().isActive()) {
252 em.getTransaction().rollback();
254 String msg = "could not find entity with id=" + id;
256 throw new DocumentNotFoundException(msg);
258 em.getTransaction().commit();
260 } catch (DocumentException de) {
261 if (em != null && em.getTransaction().isActive()) {
262 em.getTransaction().rollback();
265 } catch (Exception e) {
266 if (logger.isDebugEnabled()) {
267 logger.debug("Caught exception ", e);
269 if (em != null && em.getTransaction().isActive()) {
270 em.getTransaction().rollback();
272 throw new DocumentException(e);
275 releaseEntityManagerFactory(emf);
280 protected String getObjectId(ServiceContext ctx) {
281 String objectId = (String) ctx.getProperty("objectId");
282 if (objectId == null) {
283 String msg = "objectId is missing in the context";
285 throw new IllegalArgumentException(msg);