]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-1458 partial update for jpa based services (account, role, permission)
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Tue, 27 Apr 2010 19:01:12 +0000 (19:01 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Tue, 27 Apr 2010 19:01:12 +0000 (19:01 +0000)
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

22 files changed:
services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java
services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java
services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java
services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionRoleSubResource.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java
services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextFactory.java
services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextProperties.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java
services/common/src/main/java/org/collectionspace/services/common/document/JaxbUtils.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java

index 5e4d0c695f3379815921a9a8f8ed6aa55d0485c1..072dcc3c489532d21da7069ff1daed4de997debc 100644 (file)
@@ -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<AccountsCommon> 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<AccountsCommon> 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<AccountsCommon> 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 ...");
         }
index 9b7c3318d61df75a12a2aff1aa74157a2d12fee5..bc628b9581e1333cda0863dadceec64c6052c085 100644 (file)
@@ -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<AccountRole>();
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
@@ -102,12 +103,13 @@ public class AccountRoleSubResource
             SubjectType subject) throws Exception {
         ServiceContext<AccountRole, AccountRole> 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;
     }
 
index e5da7aca01aaf85e7040216f51f1ca23c4f115cd..7fcc775afc70ea3831f4ac174de3f901842f936c 100644 (file)
@@ -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<AccountsCommon> 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<AccountTenant>(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
     }
 }
index 4601238573dae4520c10cc81d31e7a3bca3b435b..7acb87f907f99d774db9d70c44ed4a6943a65972 100644 (file)
@@ -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;
index 2b1c5942faad73c36527b89c5336501205867e3c..cd54e782ba1fffa9f65a99ebf68d9e5d31c0ea5b 100644 (file)
@@ -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<AccountsCommon> wrapDoc =
-                    new DocumentWrapperImpl<AccountsCommon>(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<AccountsCommon> wrapDoc =
+                    new DocumentWrapperImpl<AccountsCommon>(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<AccountsCommon.Tenant> atl = account.getTenant();
+//        userTenant.setUserId(accountReceived.getUserId());
+//        List<AccountsCommon.Tenant> atl = accountReceived.getTenant();
 //        List<UserTenant.Tenant> utl =
 //                new ArrayList<UserTenant.Tenant>();
 //        for (AccountsCommon.Tenant at : atl) {
index a8d4a224a1cf8f8efe4f519cb4cae0b6d3d9385e..24a1e5e8f00f8ab24858286dbb040d726f3cd4fc 100644 (file)
@@ -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<Permission> 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<Permission> 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.");
     }
 
index 2cdcb5fea50f79662886afee547c02cdd0580da7..f3874785a6bbd0508cc9a820122c5d93de47064a 100644 (file)
@@ -344,31 +344,19 @@ public class RoleServiceTest extends AbstractServiceTestImpl {
         // Perform setup.
         setupUpdate(testName);
 
-        RoleClient client = new RoleClient();
-        ClientResponse<Role> 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<Role> 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.");
     }
 
index ec71804f3944591376ac1b6bab39e76a58e5a56e..85dd2be8651b8349281f41d6a61a9f0163025326 100644 (file)
@@ -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<Permission, Permission> ctx = createServiceContext();
+            ServiceContext<Permission, Permission> 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<Permission, Permission> ctx = createServiceContext();
+            ServiceContext<Permission, Permission> ctx = createServiceContext((Permission)null, Permission.class);
             DocumentHandler handler = createDocumentHandler(ctx);
             MultivaluedMap<String, String> 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<Permission, Permission> ctx = createServiceContext(theUpdate);
+            ServiceContext<Permission, Permission> 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<Permission, Permission> ctx = createServiceContext();
+            ServiceContext<Permission, Permission> 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);
         }
 
index 7f31172f11626b1822148260ecf3cd4bbcefe9c2..386b85557b151e7c8d49520485b5e84f00d9f3b0 100644 (file)
@@ -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<PermissionRole>();
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
@@ -97,12 +98,13 @@ public class PermissionRoleSubResource
             SubjectType subject) throws Exception {
         ServiceContext<PermissionRole, PermissionRole> 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;
     }
 
index cae35ac3bc74e1b29e6fcb59cfcacc34d162dbd3..c0af7892265255b52c81edce607c4303f5983ca7 100644 (file)
@@ -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<String, String> queryParams = ui.getQueryParameters();
             DocumentFilter myFilter = handler.createDocumentFilter();
index e525f45bc3bf18331b673a45d7016cbeb71ee595..328205a9f76700266221669ce4857c0180d0add7 100644 (file)
 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<Permission> 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
index 6121b514bbd15bbe6ec1ddefa7a302e335e5d742..378bdb47a5d7c385e22091df0c6c7e26d6d287f1 100644 (file)
@@ -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;
index ce4df4031f3f93163dfca5440231a36ca17e74fe..08788cf2e99529899f06a8ed95ab0dbb6fc6dc13 100644 (file)
 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<Role> 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);
index 3565db4863eb9aa7cb70a2a1d2a254f3f29ed1b0..3fba1cd38d433d36f839b247096d7cba93da86a4 100644 (file)
@@ -28,9 +28,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;\r
 import javax.ws.rs.core.MultivaluedMap;\r
 \r
-import org.collectionspace.services.common.context.RemoteServiceContext;\r
 import org.collectionspace.services.common.context.ServiceContext;\r
-import org.collectionspace.services.common.context.ServiceContextFactory;\r
+import org.collectionspace.services.common.context.ServiceContextProperties;\r
 import org.collectionspace.services.common.document.DocumentHandler;\r
 import org.collectionspace.services.common.repository.RepositoryClient;\r
 import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
@@ -285,6 +284,9 @@ public abstract class AbstractCollectionSpaceResourceImpl<IT, OT>
                        queryParams,\r
                        theClass != null ? theClass.getPackage().getName() : null,\r
                        theClass != null ? theClass.getName() : null);\r
+        if(theClass != null) {\r
+            ctx.setProperty(ServiceContextProperties.ENTITY_CLASS, theClass);\r
+        }\r
         return ctx;\r
     }\r
         \r
index 46be9f728030e864054d3cc994e776a985a49ee0..570df2274f3679cde0eaacc5260e111bcc4e656c 100644 (file)
@@ -28,8 +28,6 @@ package org.collectionspace.services.common.context;
 \r
 import javax.ws.rs.core.MultivaluedMap;\r
 \r
-import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;\r
-import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;\r
 \r
 /**\r
  * A factory for creating RemoteServiceContext objects.\r
@@ -100,8 +98,7 @@ public class RemoteServiceContextFactory<IT, OT>
                        input,\r
                        queryParams);\r
         ctx.setDocumentType(documentType); //persistence unit\r
-        ctx.setProperty("entity-name", entityName);\r
-        \r
+        ctx.setProperty(ServiceContextProperties.ENTITY_NAME, entityName);\r
         return ctx;\r
     }\r
     \r
index a5e3eafe870bf45c7f0e566f33562d19fa38f95c..88bc84019ff04563101fa05012e4f0d7123bdd63 100644 (file)
@@ -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<IT, OT>
      */
     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 (file)
index 0000000..31d0b31
--- /dev/null
@@ -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";
+}
index c9f23e3112f1eff251e2ec9931ac54ec88e3e959..0d4582cf4780e90a1040b548e5ee4389d34f98f8 100644 (file)
@@ -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 (file)
index 0000000..fa98772
--- /dev/null
@@ -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;
+    }
+}
index 71ed471c8b718dfc5d19787d246be0a8cfd82b8a..c041bdda3eb663df76b6ee0ab14438393d968a4e 100644 (file)
@@ -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<T> 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<T> 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<T> 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);
         }
index 2fa6f554ee5011e8673c4fe29951f139157343a9..3e8a5bf61ad87022164fec8d09d9c29d00192939 100644 (file)
  */
 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
 <xs:element name="createdAt" type="xs:dateTime">
 <xs:annotation>
 <xs:appinfo>
@@ -65,12 +63,12 @@ import org.slf4j.LoggerFactory;
 </xs:annotation>
 </xs:element>
 </xs:sequence>
-<xs:attribute name="csid" type="xs:string">
+<xs:attribute name="csidFound" type="xs:string">
 <xs:annotation>
 <xs:appinfo>
-<hj:id>
-<orm:column name="csid" length="128" nullable="false"/>
-</hj:id>
+<hj:csidReceived>
+<orm:column name="csidFound" length="128" nullable="false"/>
+</hj:csidReceived>
 </xs:appinfo>
 </xs:annotation>
 </xs:attribute>
@@ -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<Object> wrapDoc = new DocumentWrapperImpl<Object>(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<DocumentFilter.ParamBinding> 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<Object> wrapDoc = new DocumentWrapperImpl<Object>(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<Object> wrapDoc = new DocumentWrapperImpl<Object>(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();
index 5ea04e183483b0dac17d4b60e35a5a6a34eb4ceb..6ff56fc7610d55a71bd9c525f144df2fe09f2e12 100644 (file)
@@ -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