]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
eddd79470e49206787113562ddb66e0166c27cf8
[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.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.UUID;
30
31 import org.collectionspace.services.account.AccountTenant;
32 import org.collectionspace.services.account.AccountsCommon;
33 import org.collectionspace.services.account.AccountsCommonList;
34 import org.collectionspace.services.account.AccountListItem;
35 import org.collectionspace.services.account.AccountRoleSubResource;
36 import org.collectionspace.services.account.Status;
37 import org.collectionspace.services.authorization.AccountRole;
38 import org.collectionspace.services.authorization.AccountValue;
39 import org.collectionspace.services.authorization.SubjectType;
40 import org.collectionspace.services.account.RoleValue;
41 import org.collectionspace.services.client.AccountClient;
42 import org.collectionspace.services.client.AccountFactory;
43 import org.collectionspace.services.client.AccountRoleFactory;
44 import org.collectionspace.services.common.storage.TransactionContext;
45 import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
46 import org.collectionspace.services.common.context.ServiceContext;
47 import org.collectionspace.services.common.document.DocumentFilter;
48 import org.collectionspace.services.common.document.DocumentWrapper;
49 import org.collectionspace.services.common.document.JaxbUtils;
50 import org.collectionspace.services.common.security.SecurityUtils;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 /**
56  *
57  * @author 
58  */
59 public class AccountDocumentHandler
60         extends JpaDocumentHandler<AccountsCommon, AccountsCommonList, AccountsCommon, List<AccountsCommon>> {
61
62     private final Logger logger = LoggerFactory.getLogger(AccountDocumentHandler.class);
63     private AccountsCommon account;
64     private AccountsCommonList accountList;
65
66     @Override
67     public void handleCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
68         String id = UUID.randomUUID().toString();
69         AccountsCommon account = wrapDoc.getWrappedObject();
70         account.setCsid(id);
71         setTenant(account);
72         account.setStatus(Status.ACTIVE);
73         // We do not allow creation of locked accounts through the services.
74         account.setMetadataProtection(null);
75         account.setRolesProtection(null);
76     }
77
78     @Override
79     public void handleUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
80         AccountsCommon accountFound = wrapDoc.getWrappedObject();
81         AccountsCommon accountReceived = getCommonPart();
82         // If marked as metadata immutable, do not do update
83         if (!AccountClient.IMMUTABLE.equals(accountFound.getMetadataProtection())) {
84                 merge(accountReceived, accountFound);
85         }
86         //
87         // Update the accountroles if supplied
88         //
89         List<RoleValue> roleValueList = accountReceived.getRole();
90         if (roleValueList != null && roleValueList.size() > 0) {
91                         AccountRoleSubResource subResource = 
92                                         new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
93                         //
94                         // First, delete the exist accountroles
95                         //
96                         subResource.deleteAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
97                         //
98                         // Next, create the new accountroles
99                         //
100                         AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountFound, 
101                                         roleValueList, true, true);
102                         String accountRoleCsid = subResource.createAccountRole(getServiceContext(), accountRole, SubjectType.ROLE);
103                         //
104                         // Finally, set the updated role list in the result
105                         //
106                         AccountRole newAccountRole = subResource.getAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
107                         accountFound.setRole(AccountRoleFactory.convert(newAccountRole.getRole()));
108         }
109     }
110
111     /**
112      * merge manually merges the from account to the to account
113      * -this method is created due to inefficiency of JPA EM merge
114      * @param from
115      * @param to
116      * @return merged account
117      */
118     private AccountsCommon merge(AccountsCommon from, AccountsCommon to) {
119         Date now = new Date();
120         to.setUpdatedAtItem(now);
121         if (from.getEmail() != null) {
122             to.setEmail(from.getEmail());
123         }
124         if (from.getPhone() != null) {
125             to.setPhone(from.getPhone());
126         }
127         if (from.getMobile() != null) {
128             to.setMobile(from.getMobile());
129         }
130         if (from.getScreenName() != null) {
131             to.setScreenName(from.getScreenName());
132         }
133         if (from.getStatus() != null) {
134             to.setStatus(from.getStatus());
135         }
136         if (from.getPersonRefName() != null) {
137             to.setPersonRefName(from.getPersonRefName());
138         }
139         // Note that we do not allow update of locks
140         //fixme update for tenant association
141
142         if (logger.isDebugEnabled()) {
143             logger.debug("merged account="
144                     + JaxbUtils.toString(to, AccountsCommon.class));
145         }
146         return to;
147     }
148
149     @Override
150     /**
151      * If the create payload included a list of role, relate them to the account.
152      */
153     public void completeCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
154         AccountsCommon accountsCommon = wrapDoc.getWrappedObject();
155         List<RoleValue> roleValueList = account.getRole();
156         if (roleValueList != null && roleValueList.size() > 0) {
157                 //
158                 // To prevent new Accounts being created (especially low-level Spring Security accounts/SIDs), we'll first flush the current
159                 // JPA context to ensure our Account can be successfully persisted.
160                 //
161                 TransactionContext jpaTransactionContext = this.getServiceContext().getCurrentTransactionContext();
162                 jpaTransactionContext.flush();
163
164                 AccountRoleSubResource subResource = new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
165                 AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountsCommon, roleValueList, true, true);
166                         subResource.createAccountRole(this.getServiceContext(), accountRole, SubjectType.ROLE);
167         }
168     }
169     
170     @Override
171     public void completeUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
172         AccountsCommon upAcc = wrapDoc.getWrappedObject();
173         getServiceContext().setOutput(upAcc);
174         sanitize(upAcc);
175     }
176
177     @Override
178     public void handleGet(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
179         setCommonPart(extractCommonPart(wrapDoc));
180         sanitize(getCommonPart());
181         getServiceContext().setOutput(account);
182     }
183
184     @Override
185     public void handleGetAll(DocumentWrapper<List<AccountsCommon>> wrapDoc) throws Exception {
186         AccountsCommonList accList = extractCommonPartList(wrapDoc);
187         setCommonPartList(accList);
188         getServiceContext().setOutput(getCommonPartList());
189     }
190
191     @Override
192     public AccountsCommon extractCommonPart(
193             DocumentWrapper<AccountsCommon> wrapDoc)
194             throws Exception {
195         return wrapDoc.getWrappedObject();
196     }
197
198     @Override
199     public void fillCommonPart(AccountsCommon obj, DocumentWrapper<AccountsCommon> wrapDoc)
200             throws Exception {
201         throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
202     }
203
204     @Override
205     public AccountsCommonList extractCommonPartList(
206             DocumentWrapper<List<AccountsCommon>> wrapDoc)
207             throws Exception {
208
209         AccountsCommonList accList = this.extractPagingInfo(new AccountsCommonList(), wrapDoc);
210 //        AccountsCommonList accList = new AccountsCommonList();
211         List<AccountListItem> list = accList.getAccountListItem();
212
213         for (Object obj : wrapDoc.getWrappedObject()) {
214             AccountsCommon account = (AccountsCommon) obj;
215             AccountListItem accListItem = new AccountListItem();
216             accListItem.setScreenName(account.getScreenName());
217             accListItem.setUserid(account.getUserId());
218             accListItem.setTenantid(account.getTenants().get(0).getTenantId()); // pick the default/first tenant
219             accListItem.setTenants(account.getTenants());
220             accListItem.setEmail(account.getEmail());
221             accListItem.setStatus(account.getStatus());
222             String id = account.getCsid();
223             accListItem.setUri(getServiceContextPath() + id);
224             accListItem.setCsid(id);
225             list.add(accListItem);
226         }
227         return accList;
228     }
229
230     @Override
231     public AccountsCommon getCommonPart() {
232         return account;
233     }
234
235     @Override
236     public void setCommonPart(AccountsCommon account) {
237         this.account = account;
238     }
239
240     @Override
241     public AccountsCommonList getCommonPartList() {
242         return accountList;
243     }
244
245     @Override
246     public void setCommonPartList(AccountsCommonList accountList) {
247         this.accountList = accountList;
248     }
249
250     @Override
251     public String getQProperty(
252             String prop) {
253         return null;
254     }
255
256     @Override
257     public DocumentFilter createDocumentFilter() {
258         DocumentFilter filter = new AccountJpaFilter(this.getServiceContext());
259         return filter;
260     }
261
262     private void setTenant(AccountsCommon account) {
263         //set tenant only if not available from input
264         ServiceContext ctx = getServiceContext();
265         if (account.getTenants() == null || account.getTenants().size() == 0) {
266             if (ctx.getTenantId() != null) {
267                 AccountTenant at = new AccountTenant();
268                 at.setTenantId(ctx.getTenantId());
269                 List<AccountTenant> atList = new ArrayList<AccountTenant>();
270                 atList.add(at);
271                 account.setTenants(atList);
272             }
273         }
274     }
275
276     /**
277      * sanitize removes data not needed to be sent to the consumer
278      * @param account
279      */
280     private void sanitize(AccountsCommon account) {
281         account.setPassword(null);
282         if (!SecurityUtils.isCSpaceAdmin()) {
283             account.setTenants(new ArrayList<AccountTenant>(0));
284         }
285     }
286
287     /* (non-Javadoc)
288      * @see org.collectionspace.services.common.document.DocumentHandler#initializeDocumentFilter(org.collectionspace.services.common.context.ServiceContext)
289      */
290     public void initializeDocumentFilter(ServiceContext ctx) {
291         // set a default document filter in this method
292     }
293 }