]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
f2714520b2e79ea41252ff2d1f9476309c73590a
[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 javax.persistence.EntityManager;
28 import javax.persistence.EntityManagerFactory;
29 import javax.persistence.Query;
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.DocumentHandler;
37 import org.collectionspace.services.common.document.DocumentHandler.Action;
38 import org.collectionspace.services.common.document.DocumentNotFoundException;
39 import org.collectionspace.services.common.document.DocumentWrapper;
40 import org.collectionspace.services.common.document.DocumentWrapperImpl;
41 import org.collectionspace.services.common.document.JaxbUtils;
42 import org.collectionspace.services.common.security.SecurityUtils;
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 CSIP'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 && isForCSIdP(account.getPassword())) {
90                 User user = userStorageClient.create(account.getUserId(),
91                         account.getPassword());
92                 em.persist(user);
93             }
94 //            if (accountReceived.getTenant() != null) {
95 //                UserTenant ut = createTenantAssoc(accountReceived);
96 //                em.persist(ut);
97 //            }
98             account.setCreatedAtItem(new Date());
99             em.persist(account);
100             em.getTransaction().commit();
101             handler.complete(Action.CREATE, wrapDoc);
102             return (String) JaxbUtils.getValue(account, "getCsid");
103         } catch (BadRequestException bre) {
104             if (em != null && em.getTransaction().isActive()) {
105                 em.getTransaction().rollback();
106             }
107             throw bre;
108         } catch (Exception e) {
109             if (logger.isDebugEnabled()) {
110                 logger.debug("Caught exception ", e);
111             }
112             boolean uniqueConstraint = false;
113             if (userStorageClient.get(em, account.getUserId()) != null) {
114                 //might be unique constraint violation
115                 uniqueConstraint = true;
116             }
117             if (em != null && em.getTransaction().isActive()) {
118                 em.getTransaction().rollback();
119             }
120             if (uniqueConstraint) {
121                 String msg = "UserId exists. Non unique userId=" + account.getUserId();
122                 logger.error(msg);
123                 throw new BadRequestException(msg);
124             }
125             throw new DocumentException(e);
126         } finally {
127             if (em != null) {
128                 JpaStorageUtils.releaseEntityManagerFactory(emf);
129             }
130         }
131     }
132
133     @Override
134     public void update(ServiceContext ctx, String id, DocumentHandler handler)
135             throws BadRequestException, DocumentNotFoundException,
136             DocumentException {
137         if (ctx == null) {
138             throw new IllegalArgumentException(
139                     "AccountStorageClient.update : ctx is missing");
140         }
141         if (handler == null) {
142             throw new IllegalArgumentException(
143                     "AccountStorageClient.update: handler is missing");
144         }
145         EntityManagerFactory emf = null;
146         EntityManager em = null;
147         try {
148             handler.prepare(Action.UPDATE);
149             AccountsCommon accountReceived = (AccountsCommon) handler.getCommonPart();
150             emf = JpaStorageUtils.getEntityManagerFactory();
151             em = emf.createEntityManager();
152             em.getTransaction().begin();
153             AccountsCommon accountFound = getAccount(em, id);
154             checkAllowedUpdates(accountReceived, accountFound);
155             //if userid and password are given, add to default id provider
156             if (accountReceived.getUserId() != null
157                     && isForCSIdP(accountReceived.getPassword())) {
158                 userStorageClient.update(em,
159                         accountReceived.getUserId(),
160                         accountReceived.getPassword());
161             }
162             DocumentWrapper<AccountsCommon> wrapDoc =
163                     new DocumentWrapperImpl<AccountsCommon>(accountFound);
164             handler.handle(Action.UPDATE, wrapDoc);
165             em.getTransaction().commit();
166             handler.complete(Action.UPDATE, wrapDoc);
167         } catch (BadRequestException bre) {
168             if (em != null && em.getTransaction().isActive()) {
169                 em.getTransaction().rollback();
170             }
171             throw bre;
172         } catch (DocumentException de) {
173             if (em != null && em.getTransaction().isActive()) {
174                 em.getTransaction().rollback();
175             }
176             throw de;
177         } catch (Exception e) {
178             if (logger.isDebugEnabled()) {
179                 logger.debug("Caught exception ", e);
180             }
181             throw new DocumentException(e);
182         } finally {
183             if (emf != null) {
184                 JpaStorageUtils.releaseEntityManagerFactory(emf);
185             }
186         }
187     }
188
189     @Override
190     public void delete(ServiceContext ctx, String id)
191             throws DocumentNotFoundException,
192             DocumentException {
193
194         if (logger.isDebugEnabled()) {
195             logger.debug("deleting entity with id=" + id);
196         }
197         if (ctx == null) {
198             throw new IllegalArgumentException(
199                     "AccountStorageClient.delete : ctx is missing");
200         }
201         EntityManagerFactory emf = null;
202         EntityManager em = null;
203         try {
204             emf = JpaStorageUtils.getEntityManagerFactory();
205             em = emf.createEntityManager();
206
207             AccountsCommon accountFound = getAccount(em, id);
208             em.getTransaction().begin();
209             //if userid gives any indication about the id provider, it should
210             //be used to avoid  delete
211             userStorageClient.delete(em, accountFound.getUserId());
212             em.remove(accountFound);
213             em.getTransaction().commit();
214
215         } catch (DocumentException de) {
216             if (em != null && em.getTransaction().isActive()) {
217                 em.getTransaction().rollback();
218             }
219             throw de;
220         } catch (Exception e) {
221             if (logger.isDebugEnabled()) {
222                 logger.debug("Caught exception ", e);
223             }
224             if (em != null && em.getTransaction().isActive()) {
225                 em.getTransaction().rollback();
226             }
227             throw new DocumentException(e);
228         } finally {
229             if (emf != null) {
230                 JpaStorageUtils.releaseEntityManagerFactory(emf);
231             }
232         }
233     }
234
235     private AccountsCommon getAccount(EntityManager em, String id) throws DocumentNotFoundException {
236         AccountsCommon accountFound = em.find(AccountsCommon.class, id);
237         if (accountFound == null) {
238             if (em != null && em.getTransaction().isActive()) {
239                 em.getTransaction().rollback();
240             }
241             String msg = "could not find account with id=" + id;
242             logger.error(msg);
243             throw new DocumentNotFoundException(msg);
244         }
245         return accountFound;
246     }
247
248     private boolean checkAllowedUpdates(AccountsCommon toAccount, AccountsCommon fromAccount) throws BadRequestException {
249         if (!fromAccount.getUserId().equals(toAccount.getUserId())) {
250             String msg = "userId=" + toAccount.getUserId() + " of existing account does not match "
251                     + "the userId=" + fromAccount.getUserId()
252                     + " with csid=" + fromAccount.getCsid();
253             logger.error(msg);
254             if (logger.isDebugEnabled()) {
255                 logger.debug(msg + " found userid=" + fromAccount.getUserId());
256             }
257             throw new BadRequestException(msg);
258         }
259         return true;
260     }
261
262     /**
263      * isForCSIdP deteremines if the create/update is also needed for CS IdP
264      * @param bpass
265      * @return
266      */
267     private boolean isForCSIdP(byte[] bpass) {
268         return bpass != null && bpass.length > 0;
269     }
270 //    private UserTenant createTenantAssoc(AccountsCommon accountReceived) {
271 //        UserTenant userTenant = new UserTenant();
272 //        userTenant.setUserId(accountReceived.getUserId());
273 //        List<AccountsCommon.Tenant> atl = accountReceived.getTenant();
274 //        List<UserTenant.Tenant> utl =
275 //                new ArrayList<UserTenant.Tenant>();
276 //        for (AccountsCommon.Tenant at : atl) {
277 //            UserTenant.Tenant ut = new UserTenant.Tenant();
278 //            ut.setId(at.getId());
279 //            ut.setName(at.getName());
280 //            utl.add(ut);
281 //        }
282 //        userTenant.setTenant(utl);
283 //        return userTenant;
284 //    }
285 }