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