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