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