]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
6252ec518bd6570910f723ceaa40cdf88bee8584
[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 2009 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.account.storage;
25
26 import java.util.Date;
27 import java.util.HashMap;
28 import javax.persistence.EntityManager;
29 import javax.persistence.EntityManagerFactory;
30 import org.collectionspace.services.account.AccountsCommon;
31 import org.collectionspace.services.account.storage.csidp.UserStorageClient;
32 import org.collectionspace.services.authentication.User;
33 import org.collectionspace.services.common.context.ServiceContext;
34 import org.collectionspace.services.common.document.BadRequestException;
35 import org.collectionspace.services.common.document.DocumentException;
36 import org.collectionspace.services.common.document.DocumentFilter;
37 import org.collectionspace.services.common.document.DocumentHandler;
38 import org.collectionspace.services.common.document.DocumentHandler.Action;
39 import org.collectionspace.services.common.document.DocumentNotFoundException;
40 import org.collectionspace.services.common.document.DocumentWrapper;
41 import org.collectionspace.services.common.document.DocumentWrapperImpl;
42 import org.collectionspace.services.common.document.JaxbUtils;
43 import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
44 import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
45
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 /**
50  * AccountStorageClient deals with both Account and CSIdP's
51  * state in persistent storage. The rationale behind creating this class is that
52  * this class manages pesistence for both account and CSIP's user. Transactions
53  * are used where possible to permorme the persistence operations atomically.
54  * @author 
55  */
56 public class AccountStorageClient extends JpaStorageClientImpl {
57
58     private final Logger logger = LoggerFactory.getLogger(AccountStorageClient.class);
59     private UserStorageClient userStorageClient = new UserStorageClient();
60
61     public AccountStorageClient() {
62     }
63
64     @Override
65     public String create(ServiceContext ctx,
66             DocumentHandler handler) throws BadRequestException,
67             DocumentException {
68
69         if (ctx == null) {
70             throw new IllegalArgumentException(
71                     "AccountStorageClient.create : ctx is missing");
72         }
73         if (handler == null) {
74             throw new IllegalArgumentException(
75                     "AccountStorageClient.create: handler is missing");
76         }
77         EntityManagerFactory emf = null;
78         EntityManager em = null;
79         AccountsCommon account = (AccountsCommon) handler.getCommonPart();
80         try {
81             handler.prepare(Action.CREATE);
82             DocumentWrapper<AccountsCommon> wrapDoc =
83                     new DocumentWrapperImpl<AccountsCommon>(account);
84             handler.handle(Action.CREATE, wrapDoc);
85             emf = JpaStorageUtils.getEntityManagerFactory();
86             em = emf.createEntityManager();
87             em.getTransaction().begin();
88             //if userid and password are given, add to default id provider
89             if (account.getUserId() != null &&
90                     isForCSIdP(account.getPassword())) {
91                 User user = userStorageClient.create(account.getUserId(),
92                         account.getPassword());
93                 em.persist(user);
94             }
95 //            if (accountReceived.getTenant() != null) {
96 //                UserTenant ut = createTenantAssoc(accountReceived);
97 //                em.persist(ut);
98 //            }
99             account.setCreatedAtItem(new Date());
100             em.persist(account);
101             em.getTransaction().commit();
102             handler.complete(Action.CREATE, wrapDoc);
103             return (String) JaxbUtils.getValue(account, "getCsid");
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 (logger.isDebugEnabled()) {
111                 logger.debug("Caught exception ", e);
112             }
113             boolean uniqueConstraint = false;
114             if (userStorageClient.get(em, account.getUserId()) != null) {
115                 //might be unique constraint violation
116                 uniqueConstraint = true;
117             }
118             if (em != null && em.getTransaction().isActive()) {
119                 em.getTransaction().rollback();
120             }
121             if (uniqueConstraint) {
122                 String msg = "UserId exists. Non unique userId=" + account.getUserId();
123                 logger.error(msg);
124                 throw new BadRequestException(msg);
125             }
126             throw new DocumentException(e);
127         } finally {
128             if (em != null) {
129                 JpaStorageUtils.releaseEntityManagerFactory(emf);
130             }
131         }
132     }
133
134         @Override
135     public void get(ServiceContext ctx, String id, DocumentHandler handler)
136             throws DocumentNotFoundException, DocumentException {
137         if (ctx == null) {
138             throw new IllegalArgumentException(
139                     "get: ctx is missing");
140         }
141         if (handler == null) {
142             throw new IllegalArgumentException(
143                     "get: handler is missing");
144         }
145         DocumentFilter docFilter = handler.getDocumentFilter();
146         if (docFilter == null) {
147             docFilter = handler.createDocumentFilter();
148         }
149         EntityManagerFactory emf = null;
150         EntityManager em = null;
151         try {
152             handler.prepare(Action.GET);
153             Object o = null;
154             String whereClause = " JOIN a.tenants as at where csid = :csid and at.tenantId = :tenantId";
155             HashMap<String, Object> params = new HashMap<String, Object>();
156             params.put("csid", id);
157             params.put("tenantId", ctx.getTenantId());
158
159             o = JpaStorageUtils.getEntity(
160                     "org.collectionspace.services.account.AccountsCommon", whereClause, params);
161             if (null == o) {
162                 if (em != null && em.getTransaction().isActive()) {
163                     em.getTransaction().rollback();
164                 }
165                 String msg = "could not find entity with id=" + id;
166                 throw new DocumentNotFoundException(msg);
167             }
168             DocumentWrapper<Object> wrapDoc = new DocumentWrapperImpl<Object>(o);
169             handler.handle(Action.GET, wrapDoc);
170             handler.complete(Action.GET, wrapDoc);
171         } catch (DocumentException de) {
172             throw de;
173         } catch (Exception e) {
174             if (logger.isDebugEnabled()) {
175                 logger.debug("Caught exception ", e);
176             }
177             throw new DocumentException(e);
178         } finally {
179             if (emf != null) {
180                 JpaStorageUtils.releaseEntityManagerFactory(emf);
181             }
182         }
183     }
184
185     @Override
186     public void update(ServiceContext ctx, String id, DocumentHandler handler)
187             throws BadRequestException, DocumentNotFoundException,
188             DocumentException {
189         if (ctx == null) {
190             throw new IllegalArgumentException(
191                     "AccountStorageClient.update : ctx is missing");
192         }
193         if (handler == null) {
194             throw new IllegalArgumentException(
195                     "AccountStorageClient.update: handler is missing");
196         }
197         EntityManagerFactory emf = null;
198         EntityManager em = null;
199         try {
200             handler.prepare(Action.UPDATE);
201             AccountsCommon accountReceived = (AccountsCommon) handler.getCommonPart();
202             emf = JpaStorageUtils.getEntityManagerFactory();
203             em = emf.createEntityManager();
204             em.getTransaction().begin();
205             AccountsCommon accountFound = getAccount(em, id);
206             checkAllowedUpdates(accountReceived, accountFound);
207             //if userid and password are given, add to default id provider
208             if (accountReceived.getUserId() != null
209                     && isForCSIdP(accountReceived.getPassword())) {
210                 userStorageClient.update(em,
211                         accountReceived.getUserId(),
212                         accountReceived.getPassword());
213             }
214             DocumentWrapper<AccountsCommon> wrapDoc =
215                     new DocumentWrapperImpl<AccountsCommon>(accountFound);
216             handler.handle(Action.UPDATE, wrapDoc);
217             em.getTransaction().commit();
218             handler.complete(Action.UPDATE, wrapDoc);
219         } catch (BadRequestException bre) {
220             if (em != null && em.getTransaction().isActive()) {
221                 em.getTransaction().rollback();
222             }
223             throw bre;
224         } catch (DocumentException de) {
225             if (em != null && em.getTransaction().isActive()) {
226                 em.getTransaction().rollback();
227             }
228             throw de;
229         } catch (Exception e) {
230             if (logger.isDebugEnabled()) {
231                 logger.debug("Caught exception ", e);
232             }
233             throw new DocumentException(e);
234         } finally {
235             if (emf != null) {
236                 JpaStorageUtils.releaseEntityManagerFactory(emf);
237             }
238         }
239     }
240
241     @Override
242     public void delete(ServiceContext ctx, String id)
243             throws DocumentNotFoundException,
244             DocumentException {
245
246         if (logger.isDebugEnabled()) {
247             logger.debug("deleting entity with id=" + id);
248         }
249         if (ctx == null) {
250             throw new IllegalArgumentException(
251                     "AccountStorageClient.delete : ctx is missing");
252         }
253         EntityManagerFactory emf = null;
254         EntityManager em = null;
255         try {
256             emf = JpaStorageUtils.getEntityManagerFactory();
257             em = emf.createEntityManager();
258
259             AccountsCommon accountFound = getAccount(em, id);
260             em.getTransaction().begin();
261             //if userid gives any indication about the id provider, it should
262             //be used to avoid  delete
263             userStorageClient.delete(em, accountFound.getUserId());
264             em.remove(accountFound);
265             em.getTransaction().commit();
266
267         } catch (DocumentException de) {
268             if (em != null && em.getTransaction().isActive()) {
269                 em.getTransaction().rollback();
270             }
271             throw de;
272         } catch (Exception e) {
273             if (logger.isDebugEnabled()) {
274                 logger.debug("Caught exception ", e);
275             }
276             if (em != null && em.getTransaction().isActive()) {
277                 em.getTransaction().rollback();
278             }
279             throw new DocumentException(e);
280         } finally {
281             if (emf != null) {
282                 JpaStorageUtils.releaseEntityManagerFactory(emf);
283             }
284         }
285     }
286
287     private AccountsCommon getAccount(EntityManager em, String id) throws DocumentNotFoundException {
288         AccountsCommon accountFound = em.find(AccountsCommon.class, id);
289         if (accountFound == null) {
290             if (em != null && em.getTransaction().isActive()) {
291                 em.getTransaction().rollback();
292             }
293             String msg = "could not find account with id=" + id;
294             logger.error(msg);
295             throw new DocumentNotFoundException(msg);
296         }
297         return accountFound;
298     }
299
300     private boolean checkAllowedUpdates(AccountsCommon toAccount, AccountsCommon fromAccount) throws BadRequestException {
301         if (!fromAccount.getUserId().equals(toAccount.getUserId())) {
302             String msg = "userId=" + toAccount.getUserId() + " of existing account does not match "
303                     + "the userId=" + fromAccount.getUserId()
304                     + " with csid=" + fromAccount.getCsid();
305             logger.error(msg);
306             if (logger.isDebugEnabled()) {
307                 logger.debug(msg + " found userid=" + fromAccount.getUserId());
308             }
309             throw new BadRequestException(msg);
310         }
311         return true;
312     }
313
314     /**
315      * isForCSIdP deteremines if the create/update is also needed for CS IdP
316      * @param bpass
317      * @return
318      */
319     private boolean isForCSIdP(byte[] bpass) {
320         return bpass != null && bpass.length > 0;
321     }
322 //    private UserTenant createTenantAssoc(AccountsCommon accountReceived) {
323 //        UserTenant userTenant = new UserTenant();
324 //        userTenant.setUserId(accountReceived.getUserId());
325 //        List<AccountsCommon.Tenant> atl = accountReceived.getTenant();
326 //        List<UserTenant.Tenant> utl =
327 //                new ArrayList<UserTenant.Tenant>();
328 //        for (AccountsCommon.Tenant at : atl) {
329 //            UserTenant.Tenant ut = new UserTenant.Tenant();
330 //            ut.setId(at.getId());
331 //            ut.setName(at.getName());
332 //            utl.add(ut);
333 //        }
334 //        userTenant.setTenant(utl);
335 //        return userTenant;
336 //    }
337 }