From: Sanjay Dalal Date: Tue, 27 Apr 2010 19:01:12 +0000 (+0000) Subject: CSPACE-1458 partial update for jpa based services (account, role, permission) X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=834c746b1dd65d935ec89bca90a420b51c3ae6dc;p=tmp%2Fjakarta-migration.git CSPACE-1458 partial update for jpa based services (account, role, permission) refactoring of JpaStorageClient test: tests for jpa services now do partial updates, all service tests M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java M services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java M services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java A services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextProperties.java M services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java M services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java M services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java M services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java A services/common/src/main/java/org/collectionspace/services/common/document/JaxbUtils.java M services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java M services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java --- diff --git a/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java b/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java index 5e4d0c695..072dcc3c4 100644 --- a/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java +++ b/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java @@ -130,7 +130,6 @@ public class AccountServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); } - @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, dependsOnMethods = {"create"}) public void createWithInvalidTenant(String testName) throws Exception { @@ -553,20 +552,24 @@ public class AccountServiceTest extends AbstractServiceTestImpl { if (logger.isDebugEnabled()) { logger.debug("got object to update with ID: " + knownResourceId); } - AccountsCommon toUpdateAccount = + AccountsCommon accountFound = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); + Assert.assertNotNull(accountFound); + //create a new account object to test partial updates + AccountsCommon accountToUpdate = new AccountsCommon(); + accountToUpdate.setCsid(knownResourceId); + accountToUpdate.setUserId(accountFound.getUserId()); // Update the content of this resource. - toUpdateAccount.setEmail("updated-" + toUpdateAccount.getEmail()); + accountToUpdate.setEmail("updated-" + accountFound.getEmail()); if (logger.isDebugEnabled()) { logger.debug("updated object"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountFound, AccountsCommon.class)); } // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateAccount); + res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -576,12 +579,11 @@ public class AccountServiceTest extends AbstractServiceTestImpl { invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + AccountsCommon accountUpdated = (AccountsCommon) res.getEntity(); + Assert.assertNotNull(accountUpdated); - AccountsCommon updatedAccount = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(updatedAccount); - - Assert.assertEquals(updatedAccount.getEmail(), - toUpdateAccount.getEmail(), + Assert.assertEquals(accountUpdated.getEmail(), + accountToUpdate.getEmail(), "Data in updated object did not match submitted data."); } @@ -602,20 +604,24 @@ public class AccountServiceTest extends AbstractServiceTestImpl { if (logger.isDebugEnabled()) { logger.debug(testName + ": got object to update password with ID: " + knownResourceId); } - AccountsCommon toUpdateAccount = + AccountsCommon accountFound = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); + Assert.assertNotNull(accountFound); + //create a new account object to test partial updates + AccountsCommon accountToUpdate = new AccountsCommon(); + accountToUpdate.setCsid(knownResourceId); + accountToUpdate.setUserId(accountFound.getUserId()); //change password - toUpdateAccount.setPassword("imagination".getBytes()); + accountToUpdate.setPassword("imagination".getBytes()); if (logger.isDebugEnabled()) { logger.debug(testName + ": updated object"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountToUpdate, AccountsCommon.class)); } // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateAccount); + res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -626,11 +632,11 @@ public class AccountServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); - AccountsCommon updatedAccount = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(updatedAccount); + AccountsCommon accountUpdated = (AccountsCommon) res.getEntity(); + Assert.assertNotNull(accountUpdated); -// Assert.assertEquals(updatedAccount.getPassword(), -// toUpdateAccount.getPassword(), +// Assert.assertEquals(accountUpdated.getPassword(), +// accountFound.getPassword(), // "Data in updated object did not match submitted data."); } @@ -641,31 +647,20 @@ public class AccountServiceTest extends AbstractServiceTestImpl { // Perform setup. setupUpdate(testName); - AccountClient client = new AccountClient(); - ClientResponse res = client.read(knownResourceId); - if (logger.isDebugEnabled()) { - logger.debug(testName + ": read status = " + res.getStatus()); - } - Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE); - - if (logger.isDebugEnabled()) { - logger.debug(testName + " : got object to update with ID: " + knownResourceId); - } - AccountsCommon toUpdateAccount = - (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); - - toUpdateAccount.setUserId(null); + AccountsCommon accountToUpdate = new AccountsCommon(); + accountToUpdate.setCsid(knownResourceId); + accountToUpdate.setUserId(null); //change password - toUpdateAccount.setPassword("imagination".getBytes()); + accountToUpdate.setPassword("imagination".getBytes()); if (logger.isDebugEnabled()) { logger.debug(testName + " : updated object"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountToUpdate, AccountsCommon.class)); } + AccountClient client = new AccountClient(); // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateAccount); + ClientResponse res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -683,7 +678,6 @@ public class AccountServiceTest extends AbstractServiceTestImpl { // Perform setup. setupUpdate(testName); - AccountClient client = new AccountClient(); ClientResponse res = client.read(knownResourceId); if (logger.isDebugEnabled()) { @@ -694,20 +688,23 @@ public class AccountServiceTest extends AbstractServiceTestImpl { if (logger.isDebugEnabled()) { logger.debug(testName + ": got object to update password with ID: " + knownResourceId); } - AccountsCommon toUpdateAccount = - (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); + AccountsCommon accountFound = (AccountsCommon) res.getEntity(); + + AccountsCommon accountToUpdate = new AccountsCommon(); + accountToUpdate.setCsid(knownResourceId); + accountToUpdate.setUserId(accountFound.getUserId()); + Assert.assertNotNull(accountToUpdate); //change password - toUpdateAccount.setPassword("abc123".getBytes()); + accountToUpdate.setPassword("abc123".getBytes()); if (logger.isDebugEnabled()) { logger.debug(testName + ": updated object"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountToUpdate, AccountsCommon.class)); } // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateAccount); + res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -736,20 +733,23 @@ public class AccountServiceTest extends AbstractServiceTestImpl { if (logger.isDebugEnabled()) { logger.debug("got object to update with ID: " + knownResourceId); } - AccountsCommon toUpdateAccount = - (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); + AccountsCommon accountFound = (AccountsCommon) res.getEntity(); + + //create a new account object to test partial updates + AccountsCommon accountToUpdate = new AccountsCommon(); + accountToUpdate.setCsid(knownResourceId); + accountToUpdate.setUserId(accountFound.getUserId()); // Update the content of this resource. - toUpdateAccount.setStatus(Status.INACTIVE); + accountToUpdate.setStatus(Status.INACTIVE); if (logger.isDebugEnabled()) { logger.debug("updated object"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountToUpdate, AccountsCommon.class)); } // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateAccount); + res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -759,12 +759,11 @@ public class AccountServiceTest extends AbstractServiceTestImpl { invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + AccountsCommon accountUpdated = (AccountsCommon) res.getEntity(); + Assert.assertNotNull(accountUpdated); - AccountsCommon updatedAccount = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(updatedAccount); - - Assert.assertEquals(updatedAccount.getStatus(), - toUpdateAccount.getStatus(), + Assert.assertEquals(accountUpdated.getStatus(), + accountToUpdate.getStatus(), "Data in updated object did not match submitted data."); } @@ -834,18 +833,18 @@ public class AccountServiceTest extends AbstractServiceTestImpl { if (logger.isDebugEnabled()) { logger.debug("got object to update with ID: " + knownResourceId); } - AccountsCommon toUpdateAccount = + AccountsCommon accountToUpdate = (AccountsCommon) res.getEntity(); - Assert.assertNotNull(toUpdateAccount); + Assert.assertNotNull(accountToUpdate); - toUpdateAccount.setUserId("barneyFake"); + accountToUpdate.setUserId("barneyFake"); if (logger.isDebugEnabled()) { logger.debug("updated object with wrongUser"); - logger.debug(objectAsXmlString(toUpdateAccount, + logger.debug(objectAsXmlString(accountToUpdate, AccountsCommon.class)); } - res = client.update(knownResourceId, toUpdateAccount); + res = client.update(knownResourceId, accountToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match @@ -973,12 +972,12 @@ public class AccountServiceTest extends AbstractServiceTestImpl { public void cleanUp() { setupDelete("delete"); String noTest = System.getProperty("noTestCleanup"); - if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) { + if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) { if (logger.isDebugEnabled()) { logger.debug("Skipping Cleanup phase ..."); } return; - } + } if (logger.isDebugEnabled()) { logger.debug("Cleaning up temporary resources created for testing ..."); } diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java b/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java index 9b7c3318d..bc628b958 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java @@ -34,6 +34,7 @@ import org.collectionspace.services.common.context.ServiceContextFactory; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.jpa.JpaRelationshipStorageClient; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +53,7 @@ public class AccountRoleSubResource /** The logger. */ final Logger logger = LoggerFactory.getLogger(AccountRoleSubResource.class); /** The storage client. */ - final StorageClient storageClient = new JpaRelationshipStorageClient(); + final StorageClient storageClient = new JpaRelationshipStorageClient(); /* (non-Javadoc) * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString() @@ -102,12 +103,13 @@ public class AccountRoleSubResource SubjectType subject) throws Exception { ServiceContext ctx = createServiceContext(input); ctx.setDocumentType(AccountRole.class.getPackage().getName()); //persistence unit - ctx.setProperty("entity-name", AccountRoleRel.class.getName()); + ctx.setProperty(ServiceContextProperties.ENTITY_NAME, AccountRoleRel.class.getName()); + ctx.setProperty(ServiceContextProperties.ENTITY_CLASS, AccountRoleRel.class); //subject name is necessary to indicate if role or account is a subject - ctx.setProperty("subject", subject); + ctx.setProperty(ServiceContextProperties.SUBJECT, subject); //set context for the relationship query - ctx.setProperty("object-class", AccountsCommon.class); - ctx.setProperty("object-id", "account_id"); + ctx.setProperty(ServiceContextProperties.OBJECT_CLASS, AccountsCommon.class); + ctx.setProperty(ServiceContextProperties.OBJECT_ID, "account_id"); return ctx; } diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java index e5da7aca0..7fcc775af 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java @@ -24,6 +24,7 @@ package org.collectionspace.services.account.storage; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.UUID; import org.collectionspace.services.account.AccountTenant; @@ -35,6 +36,7 @@ import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.document.JaxbUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +62,46 @@ public class AccountDocumentHandler @Override public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { + AccountsCommon accountFound = wrapDoc.getWrappedObject(); + AccountsCommon accountReceived = getCommonPart(); + merge(accountReceived, accountFound); + } + + /** + * merge manually merges the from account to the to account + * -this method is created due to inefficiency of JPA EM merge + * @param from + * @param to + * @return merged account + */ + private AccountsCommon merge(AccountsCommon from, AccountsCommon to) { + Date now = new Date(); + to.setUpdatedAtItem(now); + if (from.getEmail() != null) { + to.setEmail(from.getEmail()); + } + if (from.getPhone() != null) { + to.setPhone(from.getPhone()); + } + if (from.getMobile() != null) { + to.setMobile(from.getMobile()); + } + if (from.getScreenName() != null) { + to.setScreenName(from.getScreenName()); + } + if (from.getStatus() != null) { + to.setStatus(from.getStatus()); + } + if (from.getPersonRefName() != null) { + to.setPersonRefName(from.getPersonRefName()); + } + //fixme update for tenant association + + if (logger.isDebugEnabled()) { + logger.debug("merged account=" + + JaxbUtils.toString(to, AccountsCommon.class)); + } + return to; } @Override @@ -146,8 +188,8 @@ public class AccountDocumentHandler @Override public DocumentFilter createDocumentFilter() { - DocumentFilter filter = new AccountJpaFilter(this.getServiceContext()); - return filter; + DocumentFilter filter = new AccountJpaFilter(this.getServiceContext()); + return filter; } private void setTenant(AccountsCommon account) { @@ -172,11 +214,11 @@ public class AccountDocumentHandler account.setPassword(null); account.setTenants(new ArrayList(0)); } - + /* (non-Javadoc) * @see org.collectionspace.services.common.document.DocumentHandler#initializeDocumentFilter(org.collectionspace.services.common.context.ServiceContext) */ public void initializeDocumentFilter(ServiceContext ctx) { - // set a default document filter in this method + // set a default document filter in this method } } diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java index 460123857..7acb87f90 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java @@ -37,6 +37,7 @@ import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -210,9 +211,10 @@ public class AccountRoleDocumentHandler } static SubjectType getSubject(ServiceContext ctx) { - Object o = ctx.getProperty("subject"); + Object o = ctx.getProperty(ServiceContextProperties.SUBJECT); if (o == null) { - throw new IllegalArgumentException("property subject missing in context " + throw new IllegalArgumentException(ServiceContextProperties.SUBJECT + + " property is missing in context " + ctx.toString()); } return (SubjectType) o; diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java index 2b1c5942f..cd54e782b 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java @@ -37,6 +37,7 @@ import org.collectionspace.services.common.document.DocumentHandler.Action; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentWrapperImpl; +import org.collectionspace.services.common.document.JaxbUtils; import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; import org.collectionspace.services.common.storage.jpa.JpaStorageUtils; @@ -45,8 +46,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * AccountStorageClient deals with both Account and Default Identity Provider's - * state in persistent storage + * AccountStorageClient deals with both Account and CSIP's + * state in persistent storage. The rationale behind creating this class is that + * this class manages pesistence for both account and CSIP's user. Transactions + * are used where possible to permorme the persistence operations atomically. * @author */ public class AccountStorageClient extends JpaStorageClientImpl { @@ -85,15 +88,15 @@ public class AccountStorageClient extends JpaStorageClientImpl { User user = createUser(account); em.persist(user); } -// if (account.getTenant() != null) { -// UserTenant ut = createTenantAssoc(account); +// if (accountReceived.getTenant() != null) { +// UserTenant ut = createTenantAssoc(accountReceived); // em.persist(ut); // } account.setCreatedAtItem(new Date()); em.persist(account); em.getTransaction().commit(); handler.complete(Action.CREATE, wrapDoc); - return (String) getValue(account, "getCsid"); + return (String) JaxbUtils.getValue(account, "getCsid"); } catch (BadRequestException bre) { if (em != null && em.getTransaction().isActive()) { em.getTransaction().rollback(); @@ -130,26 +133,20 @@ public class AccountStorageClient extends JpaStorageClientImpl { EntityManager em = null; try { handler.prepare(Action.UPDATE); - AccountsCommon account = (AccountsCommon) handler.getCommonPart(); - DocumentWrapper wrapDoc = - new DocumentWrapperImpl(account); - setCsid(account, id); //set id just in case it was not populated by consumer - handler.handle(Action.UPDATE, wrapDoc); + AccountsCommon accountReceived = (AccountsCommon) handler.getCommonPart(); emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); em.getTransaction().begin(); AccountsCommon accountFound = getAccount(em, id); - Date now = new Date(); - checkAllowedUpdates(account, accountFound); + checkAllowedUpdates(accountReceived, accountFound); //if userid and password are given, add to default id provider - if (account.getUserId() != null && hasPassword(account.getPassword())) { - updateUser(em, account); - } - account = em.merge(account); - account.setUpdatedAtItem(now); - if (logger.isDebugEnabled()) { - logger.debug("merged account=" + account.toString()); + if (accountReceived.getUserId() != null + && hasPassword(accountReceived.getPassword())) { + updateUser(em, accountReceived); } + DocumentWrapper wrapDoc = + new DocumentWrapperImpl(accountFound); + handler.handle(Action.UPDATE, wrapDoc); em.getTransaction().commit(); handler.complete(Action.UPDATE, wrapDoc); } catch (BadRequestException bre) { @@ -298,7 +295,7 @@ public class AccountStorageClient extends JpaStorageClientImpl { userFound.setPasswd(getEncPassword(account)); userFound.setUpdatedAtItem(new Date()); if (logger.isDebugEnabled()) { - logger.debug("updated user=" + userFound.toString()); + logger.debug("updated user=" + JaxbUtils.toString(userFound, User.class)); } em.persist(userFound); } @@ -306,7 +303,7 @@ public class AccountStorageClient extends JpaStorageClientImpl { private String getEncPassword(AccountsCommon account) throws BadRequestException { //jaxb unmarshaller already unmarshal xs:base64Binary, no need to b64 decode - //byte[] bpass = Base64.decodeBase64(account.getPassword()); + //byte[] bpass = Base64.decodeBase64(accountReceived.getPassword()); try { SecurityUtils.validatePassword(new String(account.getPassword())); } catch (Exception e) { @@ -320,10 +317,10 @@ public class AccountStorageClient extends JpaStorageClientImpl { private boolean hasPassword(byte[] bpass) { return bpass != null && bpass.length > 0; } -// private UserTenant createTenantAssoc(AccountsCommon account) { +// private UserTenant createTenantAssoc(AccountsCommon accountReceived) { // UserTenant userTenant = new UserTenant(); -// userTenant.setUserId(account.getUserId()); -// List atl = account.getTenant(); +// userTenant.setUserId(accountReceived.getUserId()); +// List atl = accountReceived.getTenant(); // List utl = // new ArrayList(); // for (AccountsCommon.Tenant at : atl) { diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java index a8d4a224a..24a1e5e8f 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java @@ -345,32 +345,18 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { // Perform setup. setupUpdate(testName); - // Retrieve the contents of a resource to update. - PermissionClient client = new PermissionClient(); - ClientResponse res = - client.read(knownResourceId); - if (logger.isDebugEnabled()) { - logger.debug(testName + ": read status = " + res.getStatus()); - } - Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE); - - if (logger.isDebugEnabled()) { - logger.debug("got object to update with ID: " + knownResourceId); - } - Permission toUpdatePermission = - (Permission) res.getEntity(); - Assert.assertNotNull(toUpdatePermission); - + Permission permToUpdate = new Permission(); + permToUpdate.setCsid(knownResourceId); // Update the content of this resource. - toUpdatePermission.setResourceName("updated-" + toUpdatePermission.getResourceName()); + permToUpdate.setResourceName("updated-resource"); if (logger.isDebugEnabled()) { logger.debug("updated object"); - logger.debug(objectAsXmlString(toUpdatePermission, + logger.debug(objectAsXmlString(permToUpdate, Permission.class)); } - + PermissionClient client = new PermissionClient(); // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdatePermission); + ClientResponse res = client.update(knownResourceId, permToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -381,11 +367,11 @@ public class PermissionServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); - Permission updatedPermission = (Permission) res.getEntity(); - Assert.assertNotNull(updatedPermission); + Permission permUpdated = (Permission) res.getEntity(); + Assert.assertNotNull(permUpdated); - Assert.assertEquals(updatedPermission.getResourceName(), - toUpdatePermission.getResourceName(), + Assert.assertEquals(permUpdated.getResourceName(), + permToUpdate.getResourceName(), "Data in updated object did not match submitted data."); } diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java index 2cdcb5fea..f3874785a 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java @@ -344,31 +344,19 @@ public class RoleServiceTest extends AbstractServiceTestImpl { // Perform setup. setupUpdate(testName); - RoleClient client = new RoleClient(); - ClientResponse res = - client.read(knownResourceId); - if (logger.isDebugEnabled()) { - logger.debug(testName + ": read status = " + res.getStatus()); - } - Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE); - - if (logger.isDebugEnabled()) { - logger.debug("got object to update with ID: " + knownResourceId); - } - Role toUpdateRole = - (Role) res.getEntity(); - Assert.assertNotNull(toUpdateRole); + Role roleToUpdate = new Role(); + roleToUpdate.setCsid(knownResourceId); // Update the content of this resource. - toUpdateRole.setRoleName("updated-" + toUpdateRole.getRoleName()); + roleToUpdate.setRoleName("updated-role"); if (logger.isDebugEnabled()) { logger.debug("updated object"); - logger.debug(objectAsXmlString(toUpdateRole, + logger.debug(objectAsXmlString(roleToUpdate, Role.class)); } - + RoleClient client = new RoleClient(); // Submit the request to the service and store the response. - res = client.update(knownResourceId, toUpdateRole); + ClientResponse res = client.update(knownResourceId, roleToUpdate); int statusCode = res.getStatus(); // Check the status code of the response: does it match the expected response(s)? if (logger.isDebugEnabled()) { @@ -379,11 +367,11 @@ public class RoleServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); - Role updatedRole = (Role) res.getEntity(); - Assert.assertNotNull(updatedRole); + Role roleUpdated = (Role) res.getEntity(); + Assert.assertNotNull(roleUpdated); - Assert.assertEquals(updatedRole.getRoleName(), - toUpdateRole.getRoleName(), + Assert.assertEquals(roleUpdated.getRoleName(), + roleToUpdate.getRoleName(), "Data in updated object did not match submitted data."); } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java index ec71804f3..85dd2be86 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java @@ -51,6 +51,7 @@ import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.security.UnauthorizedException; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.jboss.resteasy.util.HttpResponseCodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +70,7 @@ public class PermissionResource /** The logger. */ final Logger logger = LoggerFactory.getLogger(PermissionResource.class); /** The storage client. */ - final StorageClient storageClient = new JpaStorageClientImpl(Permission.class); + final StorageClient storageClient = new JpaStorageClientImpl(); /* (non-Javadoc) * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString() @@ -154,8 +155,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.POST_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.POST_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } } @@ -177,14 +178,14 @@ public class PermissionResource if (csid == null || "".equals(csid)) { logger.error("getPermission: missing csid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.GET_FAILED + "permission " + - ServiceMessages.MISSING_INVALID_CSID + csid).type( + ServiceMessages.GET_FAILED + "permission " + + ServiceMessages.MISSING_INVALID_CSID + csid).type( "text/plain").build(); throw new WebApplicationException(response); } Permission result = null; try { - ServiceContext ctx = createServiceContext(); + ServiceContext ctx = createServiceContext((Permission)null, Permission.class); DocumentHandler handler = createDocumentHandler(ctx); getStorageClient(ctx).get(ctx, csid, handler); result = (Permission) ctx.getOutput(); @@ -208,8 +209,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.GET_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.GET_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } @@ -235,7 +236,7 @@ public class PermissionResource @Context UriInfo ui) { PermissionsList permissionList = new PermissionsList(); try { - ServiceContext ctx = createServiceContext(); + ServiceContext ctx = createServiceContext((Permission)null, Permission.class); DocumentHandler handler = createDocumentHandler(ctx); MultivaluedMap queryParams = ui.getQueryParameters(); DocumentFilter myFilter = handler.createDocumentFilter(); @@ -257,8 +258,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.LIST_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.LIST_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } return permissionList; @@ -283,14 +284,14 @@ public class PermissionResource if (csid == null || "".equals(csid)) { logger.error("updatePermission: missing csid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.PUT_FAILED + "permission " + - ServiceMessages.MISSING_INVALID_CSID + csid).type( + ServiceMessages.PUT_FAILED + "permission " + + ServiceMessages.MISSING_INVALID_CSID + csid).type( "text/plain").build(); throw new WebApplicationException(response); } Permission result = null; try { - ServiceContext ctx = createServiceContext(theUpdate); + ServiceContext ctx = createServiceContext(theUpdate, Permission.class); DocumentHandler handler = createDocumentHandler(ctx); getStorageClient(ctx).update(ctx, csid, handler); result = (Permission) ctx.getOutput(); @@ -316,8 +317,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.PUT_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.PUT_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } return result; @@ -340,8 +341,8 @@ public class PermissionResource if (csid == null || "".equals(csid)) { logger.error("deletePermission: missing csid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.DELETE_FAILED + "permission " + - ServiceMessages.MISSING_INVALID_CSID + csid).type( + ServiceMessages.DELETE_FAILED + "permission " + + ServiceMessages.MISSING_INVALID_CSID + csid).type( "text/plain").build(); throw new WebApplicationException(response); } @@ -350,7 +351,7 @@ public class PermissionResource //delete all relationships for this permission PermissionRoleSubResource subResource = new PermissionRoleSubResource(); subResource.deletePermissionRole(csid, SubjectType.ROLE); - ServiceContext ctx = createServiceContext(); + ServiceContext ctx = createServiceContext((Permission)null, Permission.class); getStorageClient(ctx).delete(ctx, csid); return Response.status(HttpResponseCodes.SC_OK).build(); } catch (UnauthorizedException ue) { @@ -371,8 +372,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.DELETE_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.DELETE_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } @@ -388,8 +389,8 @@ public class PermissionResource if (permCsid == null || "".equals(permCsid)) { logger.error("createPermissionRole: missing permCsid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.POST_FAILED + "permroles permission " + - ServiceMessages.MISSING_INVALID_CSID + permCsid).type( + ServiceMessages.POST_FAILED + "permroles permission " + + ServiceMessages.MISSING_INVALID_CSID + permCsid).type( "text/plain").build(); throw new WebApplicationException(response); } @@ -417,8 +418,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.POST_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.POST_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } } @@ -434,8 +435,8 @@ public class PermissionResource if (permCsid == null || "".equals(permCsid)) { logger.error("getPermissionRole: missing permCsid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.GET_FAILED + "permroles permission " + - ServiceMessages.MISSING_INVALID_CSID + permCsid).type( + ServiceMessages.GET_FAILED + "permroles permission " + + ServiceMessages.MISSING_INVALID_CSID + permCsid).type( "text/plain").build(); throw new WebApplicationException(response); } @@ -464,8 +465,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.GET_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.GET_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } if (result == null) { @@ -489,8 +490,8 @@ public class PermissionResource if (permCsid == null || "".equals(permCsid)) { logger.error("deletePermissionRole: missing permCsid!"); Response response = Response.status(Response.Status.BAD_REQUEST).entity( - ServiceMessages.DELETE_FAILED + "permroles permission " + - ServiceMessages.MISSING_INVALID_CSID + permCsid).type( + ServiceMessages.DELETE_FAILED + "permroles permission " + + ServiceMessages.MISSING_INVALID_CSID + permCsid).type( "text/plain").build(); throw new WebApplicationException(response); } @@ -516,8 +517,8 @@ public class PermissionResource logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e); Response response = Response.status( Response.Status.INTERNAL_SERVER_ERROR).entity( - ServiceMessages.DELETE_FAILED + - ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); + ServiceMessages.DELETE_FAILED + + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build(); throw new WebApplicationException(response); } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java index 7f31172f1..386b85557 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java @@ -30,6 +30,7 @@ import org.collectionspace.services.common.context.ServiceContextFactory; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.jpa.JpaRelationshipStorageClient; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +48,7 @@ public class PermissionRoleSubResource /** The logger. */ final Logger logger = LoggerFactory.getLogger(PermissionRoleSubResource.class); /** The storage client. */ - final StorageClient storageClient = new JpaRelationshipStorageClient(); + final StorageClient storageClient = new JpaRelationshipStorageClient(); /* (non-Javadoc) * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString() @@ -97,12 +98,13 @@ public class PermissionRoleSubResource SubjectType subject) throws Exception { ServiceContext ctx = createServiceContext(input); ctx.setDocumentType(PermissionRole.class.getPackage().getName()); //persistence unit - ctx.setProperty("entity-name", PermissionRoleRel.class.getName()); + ctx.setProperty(ServiceContextProperties.ENTITY_NAME, PermissionRoleRel.class.getName()); + ctx.setProperty(ServiceContextProperties.ENTITY_CLASS, PermissionRoleRel.class); //subject name is necessary to indicate if role or permission is a subject - ctx.setProperty("subject", subject); + ctx.setProperty(ServiceContextProperties.SUBJECT, subject); //set context for the relationship query - ctx.setProperty("object-class", Permission.class); - ctx.setProperty("object-id", "permission_id"); + ctx.setProperty(ServiceContextProperties.OBJECT_CLASS, Permission.class); + ctx.setProperty(ServiceContextProperties.OBJECT_ID, "permission_id"); return ctx; } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java index cae35ac3b..c0af78922 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java @@ -240,7 +240,7 @@ public class RoleResource @Context UriInfo ui) { RolesList roleList = new RolesList(); try { - ServiceContext ctx = createServiceContext((RolesList) null, Role.class); + ServiceContext ctx = createServiceContext((Role) null, Role.class); DocumentHandler handler = createDocumentHandler(ctx); MultivaluedMap queryParams = ui.getQueryParameters(); DocumentFilter myFilter = handler.createDocumentFilter(); diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java index e525f45bc..328205a9f 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -24,16 +24,17 @@ package org.collectionspace.services.authorization.storage; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.UUID; import org.collectionspace.services.authorization.Permission; import org.collectionspace.services.authorization.PermissionsList; -import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.document.JaxbUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,10 +61,41 @@ public class PermissionDocumentHandler @Override public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { - Permission permission = wrapDoc.getWrappedObject(); - //FIXME: if admin updating the permission is a CS admin rather than - //the tenant admin, tenant id should be retrieved from the request - permission.setTenantId(getServiceContext().getTenantId()); + Permission permissionFound = wrapDoc.getWrappedObject(); + Permission permissionReceived = getCommonPart(); + merge(permissionReceived, permissionFound); + } + + /** + * merge manually merges the from from to the to permission + * -this method is created due to inefficiency of JPA EM merge + * @param from + * @param to + * @return merged permission + */ + private Permission merge(Permission from, Permission to) { + Date now = new Date(); + to.setUpdatedAtItem(now); + if (from.getResourceName() != null) { + to.setResourceName(from.getResourceName()); + } + if (from.getAttributeName() != null) { + to.setAttributeName(from.getAttributeName()); + } + if (from.getDescription() != null) { + to.setDescription(from.getDescription()); + } + if (from.getEffect() != null) { + to.setEffect(from.getEffect()); + } + + //fixme update on actions + + if (logger.isDebugEnabled()) { + logger.debug("merged permission=" + JaxbUtils.toString(to, Permission.class)); + } + + return to; } @Override diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java index 6121b514b..378bdb47a 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java @@ -25,6 +25,7 @@ package org.collectionspace.services.authorization.storage; import org.collectionspace.services.authorization.SubjectType; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.context.ServiceContextProperties; /** * @@ -33,9 +34,10 @@ import org.collectionspace.services.common.context.ServiceContext; public class PermissionRoleUtil { static SubjectType getSubject(ServiceContext ctx) { - Object o = ctx.getProperty("subject"); + Object o = ctx.getProperty(ServiceContextProperties.SUBJECT); if (o == null) { - throw new IllegalArgumentException("property subject missing in context " + throw new IllegalArgumentException(ServiceContextProperties.SUBJECT + + " property is missing in context " + ctx.toString()); } return (SubjectType) o; diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java index ce4df4031..08788cf2e 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java @@ -24,16 +24,17 @@ package org.collectionspace.services.authorization.storage; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.UUID; import org.collectionspace.services.authorization.Role; import org.collectionspace.services.authorization.RolesList; -import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.document.JaxbUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,17 +54,39 @@ public class RoleDocumentHandler String id = UUID.randomUUID().toString(); Role role = wrapDoc.getWrappedObject(); role.setCsid(id); - //FIXME: if admin updating the role is a CS admin rather than - //the tenant admin, tenant id should be retrieved from the request role.setTenantId(getServiceContext().getTenantId()); } @Override public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { - Role role = wrapDoc.getWrappedObject(); - //FIXME: if admin updating the role is a CS admin rather than - //the tenant admin, tenant id should be retrieved from the request - role.setTenantId(getServiceContext().getTenantId()); + Role roleFound = wrapDoc.getWrappedObject(); + Role roleReceived = getCommonPart(); + merge(roleReceived, roleFound); + } + + /** + * merge manually merges the from from to the to role + * -this method is created due to inefficiency of JPA EM merge + * @param from + * @param to + * @return merged role + */ + private Role merge(Role from, Role to) { + Date now = new Date(); + to.setUpdatedAtItem(now); + if (from.getRoleName() != null) { + to.setRoleName(from.getRoleName()); + } + if (from.getRoleGroup() != null) { + to.setRoleGroup(from.getRoleGroup()); + } + if (from.getDescription() != null) { + to.setDescription(from.getDescription()); + } + if (logger.isDebugEnabled()) { + logger.debug("merged role=" + JaxbUtils.toString(to, Role.class)); + } + return to; } @Override @@ -150,7 +173,7 @@ public class RoleDocumentHandler /** * sanitize removes data not needed to be sent to the consumer - * @param role + * @param roleFound */ private void sanitize(Role role) { role.setTenantId(null); diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java index 3565db486..3fba1cd38 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java @@ -28,9 +28,8 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MultivaluedMap; -import org.collectionspace.services.common.context.RemoteServiceContext; import org.collectionspace.services.common.context.ServiceContext; -import org.collectionspace.services.common.context.ServiceContextFactory; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.common.repository.RepositoryClientFactory; @@ -285,6 +284,9 @@ public abstract class AbstractCollectionSpaceResourceImpl queryParams, theClass != null ? theClass.getPackage().getName() : null, theClass != null ? theClass.getName() : null); + if(theClass != null) { + ctx.setProperty(ServiceContextProperties.ENTITY_CLASS, theClass); + } return ctx; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java index 46be9f728..570df2274 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java @@ -28,8 +28,6 @@ package org.collectionspace.services.common.context; import javax.ws.rs.core.MultivaluedMap; -import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; -import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; /** * A factory for creating RemoteServiceContext objects. @@ -100,8 +98,7 @@ public class RemoteServiceContextFactory input, queryParams); ctx.setDocumentType(documentType); //persistence unit - ctx.setProperty("entity-name", entityName); - + ctx.setProperty(ServiceContextProperties.ENTITY_NAME, entityName); return ctx; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java index a5e3eafe8..88bc84019 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java @@ -27,8 +27,6 @@ import java.lang.reflect.Constructor; import javax.ws.rs.core.MultivaluedMap; -import org.collectionspace.services.common.document.DocumentFilter; -import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.security.UnauthorizedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,7 +70,7 @@ public class RemoteServiceContextImpl */ protected RemoteServiceContextImpl(String serviceName, IT theInput) throws UnauthorizedException { this(serviceName); - this.input = theInput; + this.input = theInput; } /** diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextProperties.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextProperties.java new file mode 100644 index 000000000..31d0b3165 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextProperties.java @@ -0,0 +1,38 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.collectionspace.services.common.context; + +/** + * Constants used to store persistence related info in the context + * @author + */ +public interface ServiceContextProperties { + + public final static String ENTITY_NAME = "entity-name"; + public final static String ENTITY_CLASS = "entity-class"; + public final static String SUBJECT = "subject"; + public final static String OBJECT_ID = "object-id"; + public final static String OBJECT_CLASS = "object-class"; +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java index c9f23e311..0d4582cf4 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java @@ -23,6 +23,7 @@ */ package org.collectionspace.services.common.document; +import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -284,7 +285,7 @@ public class DocumentUtils { if (tokens == 2) { nv.name = stz.nextToken(); nv.value = stz.nextToken(); - // Allow null or empty values + // Allow null or empty values } else if (tokens == 1) { nv.name = stz.nextToken(); nv.value = ""; @@ -309,4 +310,20 @@ public class DocumentUtils { StreamResult result = new StreamResult(os); transformer.transform(source, result); } + + /** + * getXmlDocoument retrieve w3c.Document from given file + * @param fileName + * @return + * @throws Exception + */ + public static Document getXmlDocument(String fileName) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + File f = new File(fileName); + if (!f.exists()) { + throw new IllegalArgumentException("test data file " + fileName + " not found!"); + } + // Create the builder and parse the file + return factory.newDocumentBuilder().parse(f); + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/JaxbUtils.java b/services/common/src/main/java/org/collectionspace/services/common/document/JaxbUtils.java new file mode 100644 index 000000000..fa987720e --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/document/JaxbUtils.java @@ -0,0 +1,163 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2010 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.collectionspace.services.common.document; + +import java.io.InputStream; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utils for Jaxb classes + * @author + */ +public class JaxbUtils { + + private final static Logger logger = LoggerFactory.getLogger(JaxbUtils.class); + + /** + * toString marshals given Jaxb object to a string (useful for debug) + * @param o jaxb object + * @param clazz class of the jaxb object + * @return + */ + public static String toString(Object o, Class clazz) { + StringWriter sw = new StringWriter(); + try { + JAXBContext jc = JAXBContext.newInstance(clazz); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(o, sw); + } catch (Exception e) { + e.printStackTrace(); + } + return sw.toString(); + } + + /** + * fromFile retrieves object of given class from given file (in classpath) + * @param jaxbClass + * @param fileName of the file to read to construct the object + * @return + * @throws Exception + */ + public static Object fromFile(Class jaxbClass, String fileName) + throws Exception { + + JAXBContext context = JAXBContext.newInstance(jaxbClass); + Unmarshaller unmarshaller = context.createUnmarshaller(); + //note: setting schema to null will turn validator off + unmarshaller.setSchema(null); + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + InputStream is = tccl.getResourceAsStream(fileName); + return fromStream(jaxbClass, is); + } + + /** + * fromStream retrieves object of given class from given inputstream + * @param jaxbClass + * @param is stream to read to construct the object + * @return + * @throws Exception + */ + public static Object fromStream(Class jaxbClass, InputStream is) throws Exception { + JAXBContext context = JAXBContext.newInstance(jaxbClass); + Unmarshaller unmarshaller = context.createUnmarshaller(); + //note: setting schema to null will turn validator off + unmarshaller.setSchema(null); + return jaxbClass.cast(unmarshaller.unmarshal(is)); + } + + /** + * getValue gets invokes specified accessor method on given object. Assumption + * is that this is used for JavaBean pattern getXXX methods only. + * @param o object to return value from + * @param methodName of method to invoke + * @return value returned of invocation + * @throws NoSuchMethodException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + public static Object getValue(Object o, String methodName) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (methodName == null) { + String msg = methodName + " cannot be null"; + logger.error(msg); + throw new IllegalArgumentException(msg); + } + Class c = o.getClass(); + Method m = c.getMethod(methodName); + + Object r = m.invoke(o); + if (logger.isDebugEnabled()) { + logger.debug("getValue returned value=" + r + + " for " + c.getName()); + } + return r; + } + + /** + * setValue mutates the given object by invoking specified method. Assumption + * is that this is used for JavaBean pattern setXXX methods only. + * @param o object to mutate + * @param methodName indicates method to invoke + * @param argType type of the only argument (assumed) to method + * @param argValue value of the only argument (assumed) to method + * @return + * @throws NoSuchMethodException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + public static Object setValue(Object o, String methodName, Class argType, Object argValue) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (methodName == null) { + String msg = methodName + " cannot be null"; + logger.error(msg); + throw new IllegalArgumentException(msg); + } + if (argType == null) { + String msg = "argType cannot be null"; + logger.error(msg); + throw new IllegalArgumentException(msg); + } + Class c = o.getClass(); + Method m = c.getMethod(methodName, argType); + Object r = m.invoke(o, argValue); + if (logger.isDebugEnabled()) { + logger.debug("completed invocation of " + methodName + + " for " + c.getName()); + } + return r; + } +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java index 71ed471c8..c041bdda3 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java @@ -23,6 +23,7 @@ */ package org.collectionspace.services.common.storage.jpa; +import org.collectionspace.services.common.context.ServiceContextProperties; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -40,6 +41,7 @@ import org.collectionspace.services.common.document.DocumentHandler.Action; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentWrapperImpl; +import org.collectionspace.services.common.document.JaxbUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,7 +97,7 @@ public class JpaRelationshipStorageClient extends JpaStorageClientImpl { em = emf.createEntityManager(); em.getTransaction().begin(); for (T r : rl) { - setValue(r, "setCreatedAtItem", Date.class, new Date()); + JaxbUtils.setValue(r, "setCreatedAtItem", Date.class, new Date()); em.persist(r); } em.getTransaction().commit(); @@ -280,10 +282,16 @@ public class JpaRelationshipStorageClient extends JpaStorageClientImpl { } } + /** + * getObjectId returns the id of the object in a relationship + * @param ctx + * @return + */ protected String getObjectId(ServiceContext ctx) { - String objectId = (String) ctx.getProperty("object-id"); + String objectId = (String) ctx.getProperty(ServiceContextProperties.OBJECT_ID); if (objectId == null) { - String msg = "object-id is missing in the context"; + String msg = ServiceContextProperties.OBJECT_ID + + " property is missing in the context"; logger.error(msg); throw new IllegalArgumentException(msg); } @@ -298,9 +306,10 @@ public class JpaRelationshipStorageClient extends JpaStorageClientImpl { * @return */ protected Object getObject(ServiceContext ctx, String id) { - Class objectClass = (Class) ctx.getProperty("object-class"); + Class objectClass = (Class) ctx.getProperty(ServiceContextProperties.OBJECT_CLASS); if (objectClass == null) { - String msg = "object-class is missing in the context"; + String msg = ServiceContextProperties.OBJECT_CLASS + + " property is missing in the context"; logger.error(msg); throw new IllegalArgumentException(msg); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index 2fa6f554e..3e8a5bf61 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -17,14 +17,10 @@ */ package org.collectionspace.services.common.storage.jpa; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Date; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import javax.persistence.NoResultException; -import javax.persistence.Persistence; import javax.persistence.Query; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.BadRequestException; @@ -35,7 +31,9 @@ import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentHandler.Action; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentWrapperImpl; +import org.collectionspace.services.common.document.JaxbUtils; import org.collectionspace.services.common.storage.StorageClient; +import org.collectionspace.services.common.context.ServiceContextProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +43,7 @@ import org.slf4j.LoggerFactory; * All the operations in this client are carried out under their own transactions. * A call to any method would start and commit/rollback a transaction. * - * Assumption: each persistent entity has the following 3 attributes + * Assumption: each persistent entityReceived has the following 3 attributes @@ -65,12 +63,12 @@ import org.slf4j.LoggerFactory; - + - - - + + + @@ -81,7 +79,6 @@ public class JpaStorageClientImpl implements StorageClient { /** The logger. */ private final Logger logger = LoggerFactory.getLogger(JpaStorageClientImpl.class); - private Class entityClazz; /** * Instantiates a new jpa storage client. @@ -89,10 +86,6 @@ public class JpaStorageClientImpl implements StorageClient { public JpaStorageClientImpl() { } - public JpaStorageClientImpl(Class entityClazz) { - this.entityClazz = entityClazz; - } - /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler) */ @@ -116,14 +109,14 @@ public class JpaStorageClientImpl implements StorageClient { Object entity = handler.getCommonPart(); DocumentWrapper wrapDoc = new DocumentWrapperImpl(entity); handler.handle(Action.CREATE, wrapDoc); - setValue(entity, "setCreatedAtItem", Date.class, new Date()); + JaxbUtils.setValue(entity, "setCreatedAtItem", Date.class, new Date()); emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(entity); em.getTransaction().commit(); handler.complete(Action.CREATE, wrapDoc); - return (String) getValue(entity, "getCsid"); + return (String) JaxbUtils.getValue(entity, "getCsid"); } catch (BadRequestException bre) { if (em != null && em.getTransaction().isActive()) { em.getTransaction().rollback(); @@ -241,7 +234,7 @@ public class JpaStorageClientImpl implements StorageClient { queryStrBldr.append(getEntityName(ctx)); queryStrBldr.append(" a"); List params = docFilter.buildWhereForSearch(queryStrBldr); - //TODO: add tenant id + //TODO: add tenant csidReceived emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); String queryStr = queryStrBldr.toString(); //for debugging @@ -297,14 +290,11 @@ public class JpaStorageClientImpl implements StorageClient { EntityManager em = null; try { handler.prepare(Action.UPDATE); - Object entity = handler.getCommonPart(); - setCsid(entity, id); - DocumentWrapper wrapDoc = new DocumentWrapperImpl(entity); - handler.handle(Action.UPDATE, wrapDoc); + Object entityReceived = handler.getCommonPart(); emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); em.getTransaction().begin(); - Object entityFound = em.find(entity.getClass(), id); + Object entityFound = em.find(entityReceived.getClass(), id); if (entityFound == null) { if (em != null && em.getTransaction().isActive()) { em.getTransaction().rollback(); @@ -313,11 +303,8 @@ public class JpaStorageClientImpl implements StorageClient { logger.error(msg); throw new DocumentNotFoundException(msg); } - entity = em.merge(entity); - setValue(entity, "setUpdatedAtItem", Date.class, new Date()); - if (logger.isDebugEnabled()) { - logger.debug("merged entity=" + entity.toString()); - } + DocumentWrapper wrapDoc = new DocumentWrapperImpl(entityFound); + handler.handle(Action.UPDATE, wrapDoc); em.getTransaction().commit(); handler.complete(Action.UPDATE, wrapDoc); } catch (BadRequestException bre) { @@ -339,7 +326,7 @@ public class JpaStorageClientImpl implements StorageClient { } } - /* delete use delete to remove parent entity along with child entities + /* delete use delete to remove parent entityReceived along with child entities * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String) */ @Override @@ -359,13 +346,11 @@ public class JpaStorageClientImpl implements StorageClient { EntityManager em = null; try { - //TODO: add tenant id - emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); em.getTransaction().begin(); - Object entityFound = getEntity(em, id); + Object entityFound = getEntity(ctx, em, id); if (entityFound == null) { if (em != null && em.getTransaction().isActive()) { em.getTransaction().rollback(); @@ -395,10 +380,10 @@ public class JpaStorageClientImpl implements StorageClient { } /** - * deleteWhere uses the where clause to delete an entity represented by the id + * deleteWhere uses the where clause to delete an entityReceived represented by the csidReceived * it does not delete any child entities. * @param ctx - * @param id + * @param csidReceived * @throws DocumentNotFoundException * @throws DocumentException */ @@ -420,7 +405,7 @@ public class JpaStorageClientImpl implements StorageClient { StringBuilder deleteStr = new StringBuilder("DELETE FROM "); deleteStr.append(getEntityName(ctx)); deleteStr.append(" WHERE csid = :csid"); - //TODO: add tenant id + //TODO: add tenant csidReceived emf = JpaStorageUtils.getEntityManagerFactory(); em = emf.createEntityManager(); @@ -458,104 +443,17 @@ public class JpaStorageClientImpl implements StorageClient { } /** - * getValue gets invokes specified accessor method on given object. Assumption - * is that this is used for JavaBean pattern getXXX methods only. - * @param o object to return value from - * @param methodName of method to invoke - * @return value returned of invocation - * @throws NoSuchMethodException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - protected Object getValue(Object o, String methodName) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - if (methodName == null) { - String msg = methodName + " cannot be null"; - logger.error(msg); - throw new IllegalArgumentException(msg); - } - Class c = o.getClass(); - Method m = c.getMethod(methodName); - - Object r = m.invoke(o); - if (logger.isDebugEnabled()) { - logger.debug("getValue returned value=" + r - + " for " + c.getName()); - } - return r; - } - - /** - * setValue mutates the given object by invoking specified method. Assumption - * is that this is used for JavaBean pattern setXXX methods only. - * @param o object to mutate - * @param methodName indicates method to invoke - * @param argType type of the only argument (assumed) to method - * @param argValue value of the only argument (assumed) to method - * @return - * @throws NoSuchMethodException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - protected Object setValue(Object o, String methodName, Class argType, Object argValue) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - if (methodName == null) { - String msg = methodName + " cannot be null"; - logger.error(msg); - throw new IllegalArgumentException(msg); - } - if (argType == null) { - String msg = "argType cannot be null"; - logger.error(msg); - throw new IllegalArgumentException(msg); - } - Class c = o.getClass(); - Method m = c.getMethod(methodName, argType); - Object r = m.invoke(o, argValue); - if (logger.isDebugEnabled()) { - logger.debug("completed invocation of " + methodName - + " for " + c.getName()); - } - return r; - } - - /** - * Sets the csid. - * - * @param o the o - * @param csid the csid - * - * @throws Exception the exception - */ - protected void setCsid(Object o, String csid) throws Exception { - //verify csid - String id = (String) getValue(o, "getCsid"); - if (id != null) { - if (!id.equals(csid)) { - String msg = "Csids do not match!"; - logger.error(msg); - throw new BadRequestException(msg); - } else { - //no need to set - return; - } - - } - //set csid - setValue(o, "setCsid", java.lang.String.class, csid); - } - - /** - * Gets the entity name. + * Gets the entityReceived name. * * @param ctx the ctx * - * @return the entity name + * @return the entityReceived name */ protected String getEntityName(ServiceContext ctx) { - Object o = ctx.getProperty("entity-name"); + Object o = ctx.getProperty(ServiceContextProperties.ENTITY_NAME); if (o == null) { - throw new IllegalArgumentException("property entity-name missing in context " + throw new IllegalArgumentException(ServiceContextProperties.ENTITY_NAME + + "property is missing in context " + ctx.toString()); } @@ -566,21 +464,24 @@ public class JpaStorageClientImpl implements StorageClient { * getEntity returns persistent entity for given id. it assumes that * JpaStorageClientImpl is implemented using the JpaStorageClientImpl(entityClazz) * constructor - * @param em - * @param id + * @param ctx service context + * @param em entity manager + * @param csid received * @return * @throws DocumentNotFoundException * @throws UnsupportedOperationException if JpaStorageClientImpl is not implemented * using the JpaStorageClientImpl(entityClazz) * constructor */ - protected Object getEntity(EntityManager em, String id) throws DocumentNotFoundException { + protected Object getEntity(ServiceContext ctx, EntityManager em, String id) throws DocumentNotFoundException { + Class entityClazz = (Class) ctx.getProperty(ServiceContextProperties.ENTITY_CLASS); if (entityClazz == null) { - String msg = "Not constructed with JpaStorageClientImpl(entityClazz) ctor"; + String msg = ServiceContextProperties.ENTITY_CLASS + + " property is missing in the context"; logger.error(msg); - throw new UnsupportedOperationException(msg); + throw new IllegalArgumentException(msg); } - Object entityFound = em.find(entityClazz, id); + Object entityFound = JpaStorageUtils.getEntity(em, id, entityClazz); if (entityFound == null) { if (em != null && em.getTransaction().isActive()) { em.getTransaction().rollback(); diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java index 5ea04e183..6ff56fc76 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java @@ -57,11 +57,6 @@ public class JpaStorageUtils { emf = getEntityManagerFactory(); em = emf.createEntityManager(); entityFound = em.find(entityClazz, id); - if (entityFound == null) { - if (em != null && em.getTransaction().isActive()) { - em.getTransaction().rollback(); - } - } } finally { if (em != null) { releaseEntityManagerFactory(emf); @@ -70,6 +65,23 @@ public class JpaStorageUtils { return entityFound; } + /** + * getEntity with given id and class using given entity manager + * + * @param em + * @param id + * @param entityClazz + * @return + */ + public static Object getEntity(EntityManager em, String id, Class entityClazz) { + if (entityClazz == null) { + String msg = "Not constructed with JpaStorageClientImpl(entityClazz) ctor"; + logger.error(msg); + throw new UnsupportedOperationException(msg); + } + return em.find(entityClazz, id); + } + /** * getEntity using where clause from given docFilter * @param entityName fully qualified entity name