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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.account.storage;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.UUID;
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.jpa.JpaDocumentHandler;
45 import org.collectionspace.services.common.context.ServiceContext;
46 import org.collectionspace.services.common.document.DocumentFilter;
47 import org.collectionspace.services.common.document.DocumentWrapper;
48 import org.collectionspace.services.common.document.JaxbUtils;
49 import org.collectionspace.services.common.security.SecurityUtils;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
58 public class AccountDocumentHandler
59 extends JpaDocumentHandler<AccountsCommon, AccountsCommonList, AccountsCommon, List<AccountsCommon>> {
61 private final Logger logger = LoggerFactory.getLogger(AccountDocumentHandler.class);
62 private AccountsCommon account;
63 private AccountsCommonList accountList;
66 public void handleCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
67 String id = UUID.randomUUID().toString();
68 AccountsCommon account = wrapDoc.getWrappedObject();
71 account.setStatus(Status.ACTIVE);
72 // We do not allow creation of locked accounts through the services.
73 account.setMetadataProtection(null);
74 account.setRolesProtection(null);
78 public void handleUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
79 AccountsCommon accountFound = wrapDoc.getWrappedObject();
80 AccountsCommon accountReceived = getCommonPart();
81 // If marked as metadata immutable, do not do update
82 if (!AccountClient.IMMUTABLE.equals(accountFound.getMetadataProtection())) {
83 merge(accountReceived, accountFound);
86 // Update the accountroles if supplied
88 List<RoleValue> roleValueList = accountReceived.getRole();
89 if (roleValueList != null && roleValueList.size() > 0) {
90 AccountRoleSubResource subResource =
91 new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
93 // First, delete the exist accountroles
95 subResource.deleteAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
97 // Next, create the new accountroles
99 AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountFound,
100 roleValueList, true, true);
101 String accountRoleCsid = subResource.createAccountRole(getServiceContext(), accountRole, SubjectType.ROLE);
103 // Finally, set the updated role list in the result
105 AccountRole newAccountRole = subResource.getAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
106 accountFound.setRole(AccountRoleFactory.convert(newAccountRole.getRole()));
111 * merge manually merges the from account to the to account
112 * -this method is created due to inefficiency of JPA EM merge
115 * @return merged account
117 private AccountsCommon merge(AccountsCommon from, AccountsCommon to) {
118 Date now = new Date();
119 to.setUpdatedAtItem(now);
120 if (from.getEmail() != null) {
121 to.setEmail(from.getEmail());
123 if (from.getPhone() != null) {
124 to.setPhone(from.getPhone());
126 if (from.getMobile() != null) {
127 to.setMobile(from.getMobile());
129 if (from.getScreenName() != null) {
130 to.setScreenName(from.getScreenName());
132 if (from.getStatus() != null) {
133 to.setStatus(from.getStatus());
135 if (from.getPersonRefName() != null) {
136 to.setPersonRefName(from.getPersonRefName());
138 // Note that we do not allow update of locks
139 //fixme update for tenant association
141 if (logger.isDebugEnabled()) {
142 logger.debug("merged account="
143 + JaxbUtils.toString(to, AccountsCommon.class));
149 public void completeCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
150 AccountsCommon accountsCommon = wrapDoc.getWrappedObject();
151 List<RoleValue> roleValueList = account.getRole();
152 if (roleValueList != null && roleValueList.size() > 0) {
153 AccountRoleSubResource subResource = new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
154 AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountsCommon, roleValueList, true, true);
155 String accountRoleCsid = subResource.createAccountRole(this.getServiceContext(), accountRole, SubjectType.ROLE);
160 public void completeUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
161 AccountsCommon upAcc = wrapDoc.getWrappedObject();
162 getServiceContext().setOutput(upAcc);
167 public void handleGet(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
168 setCommonPart(extractCommonPart(wrapDoc));
169 sanitize(getCommonPart());
170 getServiceContext().setOutput(account);
174 public void handleGetAll(DocumentWrapper<List<AccountsCommon>> wrapDoc) throws Exception {
175 AccountsCommonList accList = extractCommonPartList(wrapDoc);
176 setCommonPartList(accList);
177 getServiceContext().setOutput(getCommonPartList());
181 public AccountsCommon extractCommonPart(
182 DocumentWrapper<AccountsCommon> wrapDoc)
184 return wrapDoc.getWrappedObject();
188 public void fillCommonPart(AccountsCommon obj, DocumentWrapper<AccountsCommon> wrapDoc)
190 throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
194 public AccountsCommonList extractCommonPartList(
195 DocumentWrapper<List<AccountsCommon>> wrapDoc)
198 AccountsCommonList accList = this.extractPagingInfo(new AccountsCommonList(), wrapDoc);
199 // AccountsCommonList accList = new AccountsCommonList();
200 List<AccountListItem> list = accList.getAccountListItem();
202 for (Object obj : wrapDoc.getWrappedObject()) {
203 AccountsCommon account = (AccountsCommon) obj;
204 AccountListItem accListItem = new AccountListItem();
205 accListItem.setScreenName(account.getScreenName());
206 accListItem.setUserid(account.getUserId());
207 accListItem.setTenantid(account.getTenants().get(0).getTenantId()); // pick the default/first tenant
208 accListItem.setTenants(account.getTenants());
209 accListItem.setEmail(account.getEmail());
210 accListItem.setStatus(account.getStatus());
211 String id = account.getCsid();
212 accListItem.setUri(getServiceContextPath() + id);
213 accListItem.setCsid(id);
214 list.add(accListItem);
220 public AccountsCommon getCommonPart() {
225 public void setCommonPart(AccountsCommon account) {
226 this.account = account;
230 public AccountsCommonList getCommonPartList() {
235 public void setCommonPartList(AccountsCommonList accountList) {
236 this.accountList = accountList;
240 public String getQProperty(
246 public DocumentFilter createDocumentFilter() {
247 DocumentFilter filter = new AccountJpaFilter(this.getServiceContext());
251 private void setTenant(AccountsCommon account) {
252 //set tenant only if not available from input
253 ServiceContext ctx = getServiceContext();
254 if (account.getTenants() == null || account.getTenants().size() == 0) {
255 if (ctx.getTenantId() != null) {
256 AccountTenant at = new AccountTenant();
257 at.setTenantId(ctx.getTenantId());
258 List<AccountTenant> atList = new ArrayList<AccountTenant>();
260 account.setTenants(atList);
266 * sanitize removes data not needed to be sent to the consumer
269 private void sanitize(AccountsCommon account) {
270 account.setPassword(null);
271 if (!SecurityUtils.isCSpaceAdmin()) {
272 account.setTenants(new ArrayList<AccountTenant>(0));
277 * @see org.collectionspace.services.common.document.DocumentHandler#initializeDocumentFilter(org.collectionspace.services.common.context.ServiceContext)
279 public void initializeDocumentFilter(ServiceContext ctx) {
280 // set a default document filter in this method