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