]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-1303, CSPACE-1359 disassociate role(s) from account
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Mon, 19 Apr 2010 22:07:44 +0000 (22:07 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Mon, 19 Apr 2010 22:07:44 +0000 (22:07 +0000)
CSPACE-1313, CSPACE-1358 associate role(s) to account
CSPACE-1347 account-role relationship schema
test: account-role service tests, all service tests exception loanout

created xxxFactory for Account, Role and Permission service tests so that these could be used from tests elsewhere

28 files changed:
services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml
services/account/client/pom.xml
services/account/client/src/main/java/org/collectionspace/services/client/AccountFactory.java [new file with mode: 0644]
services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleClient.java [new file with mode: 0644]
services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleProxy.java [new file with mode: 0644]
services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountRoleServiceTest.java [new file with mode: 0644]
services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountServiceTest.java
services/account/service/src/main/java/org/collectionspace/services/account/AccountResource.java
services/account/service/src/main/java/org/collectionspace/services/account/AccountRoleSubResource.java [new file with mode: 0644]
services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java [new file with mode: 0644]
services/authentication/service/src/main/resources/config/jboss-login-config.xml
services/authentication/service/src/main/resources/config/login-config.xml
services/authorization-mgt/client/pom.xml
services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionFactory.java [new file with mode: 0644]
services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/RoleFactory.java [new file with mode: 0644]
services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionRoleServiceTest.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/jaxb/src/main/resources/accounts_roles.xsd
services/authorization/jaxb/src/main/resources/permissions_roles.xsd
services/authorization/pstore/src/main/resources/db/mysql/authorization.sql
services/authorization/pstore/src/main/resources/db/mysql/authorization_index.sql
services/authorization/pstore/src/main/resources/db/mysql/test_authorization.sql
services/authorization/pstore/src/test/resources/META-INF/persistence.xml
services/common/src/main/config/services/tenant-bindings.xml
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaRelationshipStorageClient.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/pom.xml

index ce4dc6a7e0214eee2a1d01fcb542dda1f8234bdd..2ae9d411d846070cdaf5352d0bcfe8b34469ad69 100644 (file)
@@ -13,7 +13,7 @@
         <class>org.collectionspace.services.authorization.PermissionAction</class>
         <class>org.collectionspace.services.authorization.PermissionRoleRel</class>
         <class>org.collectionspace.services.authorization.Role</class>
-        <class>org.collectionspace.services.authorization.UserRole</class>
+        <class>org.collectionspace.services.authorization.AccountRoleRel</class>
         <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
             <property name="hibernate.max_fetch_depth" value="3"/>
index bb2a3e138b4ef8430a4cf0b1d2ed1d7b33046bab..6a4cf67ef2649feb59fcef9811b60f6f79bc0aa2 100644 (file)
     <groupId>org.collectionspace.services</groupId>\r
     <artifactId>org.collectionspace.services.account.client</artifactId>\r
     <name>services.account.client</name>\r
-    \r
+\r
     <dependencies>\r
         <!-- keep slf4j dependencies on the top -->\r
         <dependency>\r
             <groupId>org.slf4j</groupId>\r
             <artifactId>slf4j-api</artifactId>\r
-            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.slf4j</groupId>\r
             <artifactId>slf4j-log4j12</artifactId>\r
-            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.account.jaxb</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.authorization.jaxb</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.client</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.authorization-mgt.client</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
 \r
         <!-- Needed if/when client test framework files are moved into -->\r
         <!-- /services/client/src/test from /services/client/src/main -->\r
@@ -43,7 +51,7 @@
             <groupId>mysql</groupId>\r
             <artifactId>mysql-connector-java</artifactId>\r
             <scope>test</scope>\r
-        </dependency>        \r
+        </dependency>\r
         <!-- <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.client</artifactId>\r
@@ -55,7 +63,7 @@
             <groupId>org.testng</groupId>\r
             <artifactId>testng</artifactId>\r
             <version>5.6</version>\r
-        </dependency>       \r
+        </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
             <artifactId>resteasy-jaxrs</artifactId>\r
diff --git a/services/account/client/src/main/java/org/collectionspace/services/client/AccountFactory.java b/services/account/client/src/main/java/org/collectionspace/services/client/AccountFactory.java
new file mode 100644 (file)
index 0000000..9b251c4
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ *  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.client;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import org.collectionspace.services.account.AccountTenant;
+import org.collectionspace.services.account.AccountsCommon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author 
+ */
+public class AccountFactory {
+    static private final Logger logger = LoggerFactory.getLogger(AccountFactory.class);
+
+    /**
+     * create account instance
+     * @param screenName
+     * @param userName
+     * @param passwd
+     * @param email
+     * @param useScreenName
+     * @param addTenant
+     * @param invalidTenant
+     * @param useUser
+     * @param usePassword
+     * @return
+     */
+   public static AccountsCommon createAccountInstance(String screenName,
+            String userName, String passwd, String email,
+            boolean useScreenName, boolean addTenant, boolean invalidTenant,
+            boolean useUser, boolean usePassword) {
+
+        AccountsCommon account = new AccountsCommon();
+        if (useScreenName) {
+            account.setScreenName(screenName);
+        }
+        if (useUser) {
+            account.setUserId(userName);
+        }
+        if (usePassword) {
+            //jaxb marshaller already b64 encodes the xs:base64Binary types
+            //no need to double encode
+//            byte[] b64pass = Base64.encodeBase64(passwd.getBytes());
+//            account.setPassword(b64pass);
+            if (logger.isDebugEnabled()) {
+                logger.debug("user=" + userName + " password=" + passwd
+                        + " password length=" + passwd.getBytes().length);
+//
+            }
+            //jaxb encodes password too
+            account.setPassword(passwd.getBytes());
+        }
+
+        account.setPersonRefName(screenName);
+        account.setEmail(email);
+        account.setPhone("1234567890");
+        List<AccountTenant> atList = new ArrayList<AccountTenant>();
+        AccountTenant at = new AccountTenant();
+        if (!invalidTenant) {
+            //tenant is not required to be added during create, service layer
+            //picks up tenant from security context if needed
+            if (addTenant) {
+                at.setTenantId("1");
+                atList.add(at);
+                account.setTenants(atList);
+                addTenant = !addTenant;
+            }
+        } else {
+            //use invalid tenant id...called from validation test
+            at.setTenantId(UUID.randomUUID().toString());
+            atList.add(at);
+            account.setTenants(atList);
+        }
+        return account;
+
+    }
+
+}
diff --git a/services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleClient.java b/services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleClient.java
new file mode 100644 (file)
index 0000000..7a9abad
--- /dev/null
@@ -0,0 +1,111 @@
+/**    
+ * AccountRoleClient.java
+ *
+ * {Purpose of This Class}
+ *
+ * {Other Notes Relating to This Class (Optional)}
+ *
+ * $LastChangedBy: $
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ *
+ * 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 (C) 2009 {Contributing Institution}
+ *
+ * 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
+ */
+package org.collectionspace.services.client;
+
+import javax.ws.rs.core.Response;
+
+
+import org.collectionspace.services.authorization.AccountRole;
+import org.jboss.resteasy.client.ProxyFactory;
+import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+/**
+ * A AccountRoleClient.
+
+ * @version $Revision:$
+ */
+public class AccountRoleClient extends AbstractServiceClientImpl {
+
+    /**
+     *
+     */
+    private AccountRoleProxy accountRoleProxy;
+
+    /* (non-Javadoc)
+     * @see 
+     */
+    public String getServicePathComponent() {
+        return "accounts";
+    }
+
+    /**
+     *
+     * Default constructor for AccountRoleClient class.
+     *
+     */
+    public AccountRoleClient() {
+        ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
+        RegisterBuiltin.register(factory);
+        setProxy();
+    }
+
+    /**
+     * allow to reset proxy as per security needs
+     */
+    public void setProxy() {
+        if (useAuth()) {
+            accountRoleProxy = ProxyFactory.create(AccountRoleProxy.class,
+                    getBaseURL(), getHttpClient());
+        } else {
+            accountRoleProxy = ProxyFactory.create(AccountRoleProxy.class,
+                    getBaseURL());
+        }
+    }
+
+
+    /**
+     * @param csid
+     * @param arcsid relationship does not have an id, junk is fine
+     * @return
+     * @see 
+     */
+    public ClientResponse<AccountRole> read(String csid, String arcsid) {
+        return accountRoleProxy.read(csid, arcsid);
+    }
+
+    /**
+     * @param accRole
+     * @return
+     * @see 
+     */
+    public ClientResponse<Response> create(String csid, AccountRole accRole) {
+        return accountRoleProxy.create(csid, accRole);
+    }
+
+
+    /**
+     * @param csid
+     * @param arcsid relationship does not have an id, junk is fine
+     * @return
+     * @see 
+     */
+    public ClientResponse<Response> delete(String csid, String arcsid) {
+        return accountRoleProxy.delete(csid, arcsid);
+    }
+}
diff --git a/services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleProxy.java b/services/account/client/src/main/java/org/collectionspace/services/client/AccountRoleProxy.java
new file mode 100644 (file)
index 0000000..2b6b3e0
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * AccountRoleProxy.java
+ *
+ * {Purpose of This Class}
+ *
+ * {Other Notes Relating to This Class (Optional)}
+ *
+ * $LastChangedBy: $
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ *
+ * 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 (C) 2009 {Contributing Institution}
+ *
+ * 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
+ */
+package org.collectionspace.services.client;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+
+import org.collectionspace.services.authorization.AccountRole;
+import org.jboss.resteasy.client.ClientResponse;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/accounts")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface AccountRoleProxy {
+
+    //(C)reate
+    @POST
+    @Path("/{csid}/accountroles")
+    ClientResponse<Response> create(@PathParam("csid") String csid, AccountRole accRole);
+
+    //(R)ead
+    @GET
+    @Path("/{csid}/accountroles/{arcsid}")
+    ClientResponse<AccountRole> read(@PathParam("csid") String csid,
+            @PathParam("arcsid") String arcsid);
+
+    //(D)elete
+    @DELETE
+    @Path("/{csid}/accountroles/{arcsid}")
+    ClientResponse<Response> delete(@PathParam("csid") String csid,
+            @PathParam("arcsid") String arcsid);
+}
diff --git a/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountRoleServiceTest.java b/services/account/client/src/test/java/org/collectionspace/services/account/client/test/AccountRoleServiceTest.java
new file mode 100644 (file)
index 0000000..acf5012
--- /dev/null
@@ -0,0 +1,489 @@
+/**
+ * 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 Regents of the University of California
+ *
+ * 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.account.client.test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.services.account.AccountsCommon;
+import org.collectionspace.services.authorization.AccountRole;
+import org.collectionspace.services.authorization.AccountValue;
+import org.collectionspace.services.authorization.Role;
+import org.collectionspace.services.authorization.RoleValue;
+import org.collectionspace.services.client.AccountClient;
+import org.collectionspace.services.client.AccountFactory;
+import org.collectionspace.services.client.AccountRoleClient;
+import org.collectionspace.services.client.RoleClient;
+import org.collectionspace.services.client.RoleFactory;
+import org.collectionspace.services.client.test.AbstractServiceTestImpl;
+import org.collectionspace.services.client.test.ServiceRequestType;
+import org.jboss.resteasy.client.ClientResponse;
+
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
+/**
+ * AccountServiceTest, carries out tests against a
+ * deployed and running Account, Role and AccountRole Services.
+ * 
+ * $LastChangedRevision: 917 $
+ * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $
+ */
+public class AccountRoleServiceTest extends AbstractServiceTestImpl {
+
+    static private final Logger logger =
+            LoggerFactory.getLogger(AccountRoleServiceTest.class);
+    // Instance variables specific to this test.
+    private String knownResourceId = null;
+    private List<String> allResourceIdsCreated = new ArrayList();
+    private Hashtable<String, AccountValue> accValues = new Hashtable<String, AccountValue>();
+    private Hashtable<String, RoleValue> roleValues = new Hashtable<String, RoleValue>();
+    /*
+     * This method is called only by the parent class, AbstractServiceTestImpl
+     */
+
+    @Override
+    protected String getServicePathComponent() {
+        return new AccountRoleClient().getServicePathComponent();
+    }
+
+    @BeforeClass(alwaysRun = true)
+    public void seedData() {
+        String ra = "acc-role-user1";
+        String accId = createAccount(ra, "acc-role-test@cspace.org");
+        AccountValue ava = new AccountValue();
+        ava.setScreenName(ra);
+        ava.setUserId(ra);
+        ava.setAccountId(accId);
+        accValues.put(ava.getScreenName(), ava);
+
+        String rc = "acc-role-user2";
+        String coAccId = createAccount(rc, "acc-role-test@cspace.org");
+        AccountValue avc = new AccountValue();
+        avc.setScreenName(rc);
+        avc.setUserId(rc);
+        avc.setAccountId(coAccId);
+        accValues.put(avc.getScreenName(), avc);
+
+        String ri = "acc-role-user3";
+        String iAccId = createAccount(ri, "acc-role-test@cspace.org");
+        AccountValue avi = new AccountValue();
+        avi.setScreenName(ri);
+        avi.setUserId(ri);
+        avi.setAccountId(iAccId);
+        accValues.put(avi.getScreenName(), avi);
+
+        String rn1 = "ROLE_CO1";
+        String r1RoleId = createRole(rn1);
+        RoleValue rv1 = new RoleValue();
+        rv1.setRoleId(r1RoleId);
+        rv1.setRoleName(rn1);
+        roleValues.put(rv1.getRoleName(), rv1);
+
+        String rn2 = "ROLE_CO2";
+        String r2RoleId = createRole(rn2);
+        RoleValue rv2 = new RoleValue();
+        rv2.setRoleId(r2RoleId);
+        rv2.setRoleName(rn2);
+        roleValues.put(rv2.getRoleName(), rv2);
+    }
+
+    // ---------------------------------------------------------------
+    // CRUD tests : CREATE tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
+    public void create(String testName) throws Exception {
+
+        // Perform setup, such as initializing the type of service request
+        // (e.g. CREATE, DELETE), its valid and expected status codes, and
+        // its associated HTTP method name (e.g. POST, DELETE).
+        setupCreate(testName);
+
+        // Submit the request to the service and store the response.
+        AccountValue pv = accValues.get("acc-role-user1");
+        AccountRole accRole = createAccountRoleInstance(pv,
+                roleValues.values(), true, true);
+        AccountRoleClient client = new AccountRoleClient();
+        ClientResponse<Response> res = client.create(pv.getAccountId(), accRole);
+        int statusCode = res.getStatus();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+        // Store the ID returned from this create operation
+        // for additional tests below.
+        //this is is not important in case of this relationship
+        knownResourceId = extractId(res);
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": knownResourceId=" + knownResourceId);
+        }
+    }
+
+    //to not cause uniqueness violation for accRole, createList is removed
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"create"})
+    public void createList(String testName) throws Exception {
+    }
+
+    // Failure outcomes
+    // Placeholders until the three tests below can be uncommented.
+    // See Issue CSPACE-401.
+    @Override
+    public void createWithEmptyEntityBody(String testName) throws Exception {
+    }
+
+    @Override
+    public void createWithMalformedXml(String testName) throws Exception {
+    }
+
+    @Override
+    public void createWithWrongXmlSchema(String testName) throws Exception {
+    }
+
+    // ---------------------------------------------------------------
+    // CRUD tests : READ tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"create"})
+    public void read(String testName) throws Exception {
+
+        // Perform setup.
+        setupRead(testName);
+
+        // Submit the request to the service and store the response.
+        AccountRoleClient client = new AccountRoleClient();
+        ClientResponse<AccountRole> res = client.read(
+                accValues.get("acc-role-user1").getAccountId(), "123");
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+        AccountRole output = (AccountRole) res.getEntity();
+        Assert.assertNotNull(output);
+    }
+
+    // Failure outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
+    public void readNonExistent(String testName) throws Exception {
+
+        // Perform setup.
+        setupReadNonExistent(testName);
+
+        // Submit the request to the service and store the response.
+        AccountRoleClient client = new AccountRoleClient();
+        ClientResponse<AccountRole> res = client.read(NON_EXISTENT_ID, "123");
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+
+    // ---------------------------------------------------------------
+    // CRUD tests : READ_LIST tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"createList", "read"})
+    public void readList(String testName) throws Exception {
+    }
+
+    // Failure outcomes
+    // None at present.
+    // ---------------------------------------------------------------
+    // CRUD tests : UPDATE tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"read", "readList", "readNonExistent"})
+    public void update(String testName) throws Exception {
+    }
+
+    // Failure outcomes
+    // Placeholders until the three tests below can be uncommented.
+    // See Issue CSPACE-401.
+    @Override
+    public void updateWithEmptyEntityBody(String testName) throws Exception {
+    }
+
+    @Override
+    public void updateWithMalformedXml(String testName) throws Exception {
+    }
+
+    @Override
+    public void updateWithWrongXmlSchema(String testName) throws Exception {
+    }
+
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"readNonExistent", "testSubmitRequest"})
+    public void updateNonExistent(String testName) throws Exception {
+    }
+
+    // ---------------------------------------------------------------
+    // CRUD tests : DELETE tests
+    // ---------------------------------------------------------------
+    // Success outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+    dependsOnMethods = {"read"})
+    public void delete(String testName) throws Exception {
+
+        // Perform setup.
+        setupDelete(testName);
+
+        // Submit the request to the service and store the response.
+        AccountRoleClient client = new AccountRoleClient();
+        ClientResponse<Response> res = client.delete(
+                accValues.get("acc-role-user1").getAccountId(), "123");
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+
+    // Failure outcomes
+    @Override
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
+    public void deleteNonExistent(String testName) throws Exception {
+
+        // Perform setup.
+        setupDeleteNonExistent(testName);
+
+        // Submit the request to the service and store the response.
+        AccountRoleClient client = new AccountRoleClient();
+        ClientResponse<Response> res = client.delete(NON_EXISTENT_ID, "123");
+        int statusCode = res.getStatus();
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug(testName + ": status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+
+    // ---------------------------------------------------------------
+    // Utility tests : tests of code used in tests above
+    // ---------------------------------------------------------------
+    /**
+     * Tests the code for manually submitting data that is used by several
+     * of the methods above.
+     */
+    @Test(dependsOnMethods = {"create"})
+    public void testSubmitRequest() throws Exception {
+
+        // Expected status code: 200 OK
+        final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
+
+        // Submit the request to the service and store the response.
+        String method = ServiceRequestType.READ.httpMethodName();
+        String url = getResourceURL(accValues.get("acc-role-user1").getAccountId());
+        int statusCode = submitRequest(method, url);
+
+        // Check the status code of the response: does it match
+        // the expected response(s)?
+        if (logger.isDebugEnabled()) {
+            logger.debug("testSubmitRequest: url=" + url
+                    + " status=" + statusCode);
+        }
+        Assert.assertEquals(statusCode, EXPECTED_STATUS);
+
+    }
+
+    // ---------------------------------------------------------------
+    // Utility methods used by tests above
+    // ---------------------------------------------------------------
+    /**
+     * create accRolerole instance
+     * @param accId
+     * @param roleValues array of role ids
+     * @param userPermId
+     * @param useRoleId
+     * @return
+     */
+    static public AccountRole createAccountRoleInstance(AccountValue pv,
+            Collection<RoleValue> rvs,
+            boolean usePermId,
+            boolean useRoleId) {
+
+        AccountRole accRole = new AccountRole();
+        //service consume is not required to provide subject as it is determined
+        //from URI used
+//        accRole.setSubject(SubjectType.ROLE);
+        if (usePermId) {
+            ArrayList<AccountValue> pvs = new ArrayList<AccountValue>();
+            pvs.add(pv);
+            accRole.setAccounts(pvs);
+        }
+        if (useRoleId) {
+            //FIXME is there a better way?
+            ArrayList<RoleValue> rvas = new ArrayList<RoleValue>();
+            for (RoleValue rv : rvs) {
+                rvas.add(rv);
+            }
+            accRole.setRoles(rvas);
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("to be created, accRole common");
+            logger.debug(objectAsXmlString(accRole, AccountRole.class));
+        }
+        return accRole;
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void cleanUp() {
+        setupDelete("delete");
+        if (logger.isDebugEnabled()) {
+            logger.debug("clenaup: Cleaning up temporary resources created for testing ...");
+        }
+        AccountRoleClient client = new AccountRoleClient();
+        for (String resourceId : allResourceIdsCreated) {
+
+            // Note: Any non-success responses are ignored and not reported.
+            ClientResponse<Response> res = client.delete(resourceId, "123");
+            int statusCode = res.getStatus();
+            if (logger.isDebugEnabled()) {
+                logger.debug("clenaup: delete relationships for accission id="
+                        + resourceId + " status=" + statusCode);
+            }
+            Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+            Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        }
+
+        for (AccountValue pv : accValues.values()) {
+            deleteAccount(pv.getAccountId());
+        }
+
+        for (RoleValue rv : roleValues.values()) {
+            deleteRole(rv.getRoleId());
+        }
+    }
+
+    private String createAccount(String userName, String email) {
+        setupCreate();
+        AccountClient accClient = new AccountClient();
+        AccountsCommon account = AccountFactory.createAccountInstance(
+                userName, userName, userName, email,
+                true, true, false, true, true);
+        ClientResponse<Response> res = accClient.create(account);
+        int statusCode = res.getStatus();
+        if (logger.isDebugEnabled()) {
+            logger.debug("createAccount: userName=" + userName
+                    + " status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        return extractId(res);
+    }
+
+    private void deleteAccount(String accId) {
+        setupDelete();
+        AccountClient accClient = new AccountClient();
+        ClientResponse<Response> res = accClient.delete(accId);
+        int statusCode = res.getStatus();
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleteAccount: delete account id="
+                    + accId + " status=" + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+
+    private String createRole(String roleName) {
+        setupCreate();
+        RoleClient roleClient = new RoleClient();
+
+        Role role = RoleFactory.createRoleInstance(roleName,
+                "role for " + roleName, true);
+        ClientResponse<Response> res = roleClient.create(role);
+        int statusCode = res.getStatus();
+        if (logger.isDebugEnabled()) {
+            logger.debug("createRole: name=" + roleName
+                    + " status = " + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+        return extractId(res);
+    }
+
+    private void deleteRole(String roleId) {
+        setupDelete();
+        RoleClient roleClient = new RoleClient();
+        ClientResponse<Response> res = roleClient.delete(roleId);
+        int statusCode = res.getStatus();
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleteRole: delete role id=" + roleId
+                    + " status=" + statusCode);
+        }
+        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+}
index a42427af94f8c89010ed4065002ecdeda540ce86..a2dc2301868e959855f6e4c123c12def60ac71f0 100644 (file)
@@ -24,15 +24,13 @@ package org.collectionspace.services.account.client.test;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.UUID;
 import javax.ws.rs.core.Response;
 
-import org.apache.commons.codec.binary.Base64;
 import org.collectionspace.services.client.AccountClient;
 import org.collectionspace.services.account.AccountsCommon;
 import org.collectionspace.services.account.AccountsCommonList;
 import org.collectionspace.services.account.Status;
-import org.collectionspace.services.account.AccountTenant;
+import org.collectionspace.services.client.AccountFactory;
 import org.collectionspace.services.client.test.AbstractServiceTestImpl;
 import org.collectionspace.services.client.test.ServiceRequestType;
 import org.jboss.resteasy.client.ClientResponse;
@@ -53,12 +51,12 @@ import org.testng.annotations.AfterClass;
  */
 public class AccountServiceTest extends AbstractServiceTestImpl {
 
-    private final Logger logger =
+    static private final Logger logger =
             LoggerFactory.getLogger(AccountServiceTest.class);
     // Instance variables specific to this test.
     private String knownResourceId = null;
     private List<String> allResourceIdsCreated = new ArrayList();
-    boolean addTenant = true;
+    static boolean addTenant = true;
     /*
      * This method is called only by the parent class, AbstractServiceTestImpl
      */
@@ -911,51 +909,13 @@ public class AccountServiceTest extends AbstractServiceTestImpl {
      * @param usePassword
      * @return
      */
-    private AccountsCommon createAccountInstance(String screenName,
+   AccountsCommon createAccountInstance(String screenName,
             String userName, String passwd, String email,
             boolean useScreenName, boolean invalidTenant, boolean useUser, boolean usePassword) {
 
-        AccountsCommon account = new AccountsCommon();
-        if (useScreenName) {
-            account.setScreenName(screenName);
-        }
-        if (useUser) {
-            account.setUserId(userName);
-        }
-        if (usePassword) {
-            //jaxb marshaller already b64 encodes the xs:base64Binary types
-            //no need to double encode
-//            byte[] b64pass = Base64.encodeBase64(passwd.getBytes());
-//            account.setPassword(b64pass);
-            if (logger.isDebugEnabled()) {
-                logger.debug("user=" + userName + " password=" + passwd
-                        + " password length=" + passwd.getBytes().length);
-//
-            }
-            //jaxb encodes password too
-            account.setPassword(passwd.getBytes());
-        }
-
-        account.setPersonRefName(screenName);
-        account.setEmail(email);
-        account.setPhone("1234567890");
-        List<AccountTenant> atList = new ArrayList<AccountTenant>();
-        AccountTenant at = new AccountTenant();
-        if (!invalidTenant) {
-            //tenant is not required to be added during create, service layer
-            //picks up tenant from security context if needed
-            if (addTenant) {
-                at.setTenantId("1");
-                atList.add(at);
-                account.setTenants(atList);
-                addTenant = !addTenant;
-            }
-        } else {
-            //use invalid tenant id...called from validation test
-            at.setTenantId(UUID.randomUUID().toString());
-            atList.add(at);
-            account.setTenants(atList);
-        }
+        AccountsCommon account = AccountFactory.createAccountInstance(screenName,
+                userName, passwd, email, useScreenName,
+                addTenant, invalidTenant, useUser, usePassword);
 
         if (logger.isDebugEnabled()) {
             logger.debug("to be created, account common");
index b385280fcc61ff4028de9bbe5091e6560ab36249..7f546c377da9cbbe319db5126e4abc6ea73df05f 100644 (file)
@@ -39,6 +39,8 @@ import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 
 import org.collectionspace.services.account.storage.AccountStorageClient;
+import org.collectionspace.services.authorization.AccountRole;
+import org.collectionspace.services.authorization.SubjectType;
 import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.context.ServiceContextFactory;
@@ -355,4 +357,141 @@ public class AccountResource
         }
 
     }
+
+
+    @POST
+    @Path("{csid}/accountroles")
+    public Response createAccountRole(@PathParam("csid") String accCsid,
+            AccountRole input) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("createAccountRole with accCsid=" + accCsid);
+        }
+        if (accCsid == null || "".equals(accCsid)) {
+            logger.error("createAccountRole: missing accCsid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "create failed on AccountRole accCsid=" + accCsid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        try {
+            AccountRoleSubResource subResource = new AccountRoleSubResource();
+            String accrolecsid = subResource.createAccountRole(input, SubjectType.ROLE);
+            UriBuilder path = UriBuilder.fromResource(AccountResource.class);
+            path.path(accCsid + "/accountroles/" + accrolecsid);
+            Response response = Response.created(path.build()).build();
+            return response;
+        } catch (BadRequestException bre) {
+            Response response = Response.status(
+                    Response.Status.BAD_REQUEST).entity("Create failed reason "
+                    + bre.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (UnauthorizedException ue) {
+            Response response = Response.status(
+                    Response.Status.UNAUTHORIZED).entity("Create failed reason "
+                    + ue.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception in createAccountRole", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Create failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+    }
+
+    @GET
+    @Path("{csid}/accountroles/{accrolecsid}")
+    public AccountRole getAccountRole(
+            @PathParam("csid") String accCsid,
+            @PathParam("accrolecsid") String accrolecsid) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("getAccountRole with accCsid=" + accCsid);
+        }
+        if (accCsid == null || "".equals(accCsid)) {
+            logger.error("getAccountRole: missing accCsid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "get failed on AccountRole accCsid=" + accCsid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        AccountRole result = null;
+        try {
+            AccountRoleSubResource subResource = new AccountRoleSubResource();
+            //get relationships for an account
+            result = subResource.getAccountRole(accCsid, SubjectType.ROLE);
+        } catch (UnauthorizedException ue) {
+            Response response = Response.status(
+                    Response.Status.UNAUTHORIZED).entity("Get failed reason "
+                    + ue.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (DocumentNotFoundException dnfe) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("getAccountRole", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed on AccountRole accrolecsid=" + accrolecsid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("getAccountRole", e);
+            }
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Get failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        if (result == null) {
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed, the requested AccountRole accrolecsid:" + accrolecsid
+                    + ": was not found.").type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return result;
+    }
+
+    @DELETE
+    @Path("{csid}/accountroles/{accrolecsid}")
+    public Response deleteAccountRole(
+            @PathParam("csid") String accCsid,
+            @PathParam("accrolecsid") String accrolecsid) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleteAccountRole with accCsid=" + accCsid);
+        }
+        if (accCsid == null || "".equals(accCsid)) {
+            logger.error("deleteAccountRole: missing accCsid!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "delete failed on AccountRole accCsid=" + accCsid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        try {
+            AccountRoleSubResource subResource = new AccountRoleSubResource();
+            //delete all relationships for an account
+            subResource.deleteAccountRole(accCsid, SubjectType.ROLE);
+            return Response.status(HttpResponseCodes.SC_OK).build();
+        } catch (UnauthorizedException ue) {
+            Response response = Response.status(
+                    Response.Status.UNAUTHORIZED).entity("Delete failed reason "
+                    + ue.getErrorReason()).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (DocumentNotFoundException dnfe) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("caught exception in deleteAccountRole", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Delete failed on AccountRole accrolecsid=" + accrolecsid).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            Response response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                    "Delete failed").type("text/plain").build();
+            throw new WebApplicationException(response);
+        }
+
+    }
 }
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
new file mode 100644 (file)
index 0000000..82b9ae8
--- /dev/null
@@ -0,0 +1,180 @@
+/**
+ *  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.account;
+
+import org.collectionspace.services.authorization.AccountRole;
+import org.collectionspace.services.authorization.AccountRoleRel;
+import org.collectionspace.services.authorization.SubjectType;
+
+import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
+import org.collectionspace.services.common.context.RemoteServiceContextFactory;
+import org.collectionspace.services.common.context.ServiceContext;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AccountRoleSubResource is used to manage account-role relationship
+ * @author
+ */
+public class AccountRoleSubResource
+        extends AbstractCollectionSpaceResourceImpl<AccountRole, AccountRole> {
+
+    //this service is never exposed as standalone RESTful service...just use unique
+    //service name to identify binding
+    /** The service name. */
+    final private String serviceName = "accounts/accountroles";
+    
+    /** The logger. */
+    final Logger logger = LoggerFactory.getLogger(AccountRoleSubResource.class);
+    
+    /** The storage client. */
+    final StorageClient storageClient = new JpaRelationshipStorageClient();
+
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
+     */
+    @Override
+    protected String getVersionString() {
+        /** The last change revision. */
+        final String lastChangeRevision = "$LastChangedRevision: 1165 $";
+        return lastChangeRevision;
+    }
+
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
+     */
+    @Override
+    public String getServiceName() {
+        return serviceName;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.CollectionSpaceResource#getCommonPartClass()
+     */
+    @Override
+    public Class<AccountRole> getCommonPartClass() {
+       return AccountRole.class;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.CollectionSpaceResource#getServiceContextFactory()
+     */
+    @Override
+    public ServiceContextFactory<AccountRole, AccountRole> getServiceContextFactory() {
+       return RemoteServiceContextFactory.get();
+    }    
+
+    /**
+     * Creates the service context.
+     * 
+     * @param input the input
+     * @param subject the subject
+     * 
+     * @return the service context< account role, account role>
+     * 
+     * @throws Exception the exception
+     */
+    private ServiceContext<AccountRole, AccountRole> createServiceContext(AccountRole input,
+               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());
+        //subject name is necessary to indicate if role or account is a subject
+        ctx.setProperty("subject", subject);
+        //set context that for the relationship query
+        ctx.setProperty("objectId", "account_id");
+        return ctx;
+    }
+
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getStorageClient(org.collectionspace.services.common.context.ServiceContext)
+     */
+    @Override
+    public StorageClient getStorageClient(ServiceContext<AccountRole, AccountRole> ctx) {
+        //FIXME use ctx to identify storage client
+        return storageClient;
+    }
+
+
+    /**
+     * createAccountRole creates one or more account-role relationships
+     * between object (account/role) and subject (role/account)
+     * @param input
+     * @param subject
+     * @return
+     * @throws Exception
+     */
+    public String createAccountRole(AccountRole input, SubjectType subject)
+            throws Exception {
+
+        ServiceContext<AccountRole, AccountRole> ctx = createServiceContext(input, subject);
+        DocumentHandler handler = createDocumentHandler(ctx);
+        return getStorageClient(ctx).create(ctx, handler);
+    }
+
+    /**
+     * getAccountRole retrieves account-role relationships using given
+     * csid of object (account/role) and subject (role/account)
+     * @param csid
+     * @param subject
+     * @return
+     * @throws Exception
+     */
+    public AccountRole getAccountRole(
+            String csid, SubjectType subject) throws Exception {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getAccountRole with csid=" + csid);
+        }
+        AccountRole result = null;
+        ServiceContext<AccountRole, AccountRole> ctx = createServiceContext((AccountRole) null, subject);
+        DocumentHandler handler = createDocumentHandler(ctx);
+        getStorageClient(ctx).get(ctx, csid, handler);
+        result = (AccountRole) ctx.getOutput();
+
+        return result;
+    }
+
+    /**
+     * deleteAccountRole deletes account-role relationships using given
+     * csid of object (account/role) and subject (role/account)
+     * @param csid
+     * @param subject
+     * @return
+     * @throws Exception
+     */
+    public void deleteAccountRole(String csid,
+            SubjectType subject) throws Exception {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleteAccountRole with csid=" + csid);
+        }
+        ServiceContext<AccountRole, AccountRole> ctx = createServiceContext((AccountRole) null, subject);
+        getStorageClient(ctx).delete(ctx, csid);
+    }
+}
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
new file mode 100644 (file)
index 0000000..4601238
--- /dev/null
@@ -0,0 +1,220 @@
+/**
+ *  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 accountRoles and
+ *  limitations under the License.
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.collectionspace.services.authorization.AccountRole;
+import org.collectionspace.services.authorization.AccountRoleRel;
+import org.collectionspace.services.authorization.AccountValue;
+import org.collectionspace.services.authorization.PermissionsRolesList;
+import org.collectionspace.services.authorization.RoleValue;
+import org.collectionspace.services.authorization.SubjectType;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Document handler for AccountRole association
+ * @author 
+ */
+public class AccountRoleDocumentHandler
+        extends AbstractDocumentHandlerImpl<AccountRole, PermissionsRolesList, List<AccountRoleRel>, List<AccountRoleRel>> {
+
+    private final Logger logger = LoggerFactory.getLogger(AccountRoleDocumentHandler.class);
+    private AccountRole accountRole;
+    private PermissionsRolesList accountRolesList;
+
+    @Override
+    public void handleCreate(DocumentWrapper<List<AccountRoleRel>> wrapDoc) throws Exception {
+        fillCommonPart(getCommonPart(), wrapDoc);
+    }
+
+    @Override
+    public void handleUpdate(DocumentWrapper<List<AccountRoleRel>> wrapDoc) throws Exception {
+        throw new UnsupportedOperationException("operation not relevant for AccountRoleDocumentHandler");
+    }
+
+    @Override
+    public void completeUpdate(DocumentWrapper<List<AccountRoleRel>> wrapDoc) throws Exception {
+        throw new UnsupportedOperationException("operation not relevant for AccountRoleDocumentHandler");
+    }
+
+    @Override
+    public void handleGet(DocumentWrapper<List<AccountRoleRel>> wrapDoc) throws Exception {
+        setCommonPart(extractCommonPart(wrapDoc));
+        getServiceContext().setOutput(accountRole);
+    }
+
+    @Override
+    public void handleGetAll(DocumentWrapper<List<AccountRoleRel>> wrapDoc) throws Exception {
+        throw new UnsupportedOperationException("operation not relevant for AccountRoleDocumentHandler");
+    }
+
+    @Override
+    public AccountRole extractCommonPart(
+            DocumentWrapper<List<AccountRoleRel>> wrapDoc)
+            throws Exception {
+        List<AccountRoleRel> arrl = wrapDoc.getWrappedObject();
+        AccountRole ar = new AccountRole();
+        SubjectType subject = getSubject(getServiceContext());
+        AccountRoleRel ar0 = arrl.get(0);
+        if (SubjectType.ROLE.equals(subject)) {
+
+            List<AccountValue> avs = new ArrayList<AccountValue>();
+            ar.setAccounts(avs);
+            AccountValue av = buildAccountValue(ar0);
+            avs.add(av);
+
+            //add roles
+            List<RoleValue> rvs = new ArrayList<RoleValue>();
+            ar.setRoles(rvs);
+            for (AccountRoleRel arr : arrl) {
+                RoleValue rv = buildRoleValue(arr);
+                rvs.add(rv);
+            }
+        } else if (SubjectType.ACCOUNT.equals(subject)) {
+
+            List<RoleValue> rvs = new ArrayList<RoleValue>();
+            ar.setRoles(rvs);
+            RoleValue rv = buildRoleValue(ar0);
+            rvs.add(rv);
+
+            //add accounts
+            List<AccountValue> avs = new ArrayList<AccountValue>();
+            ar.setAccounts(avs);
+            for (AccountRoleRel arr : arrl) {
+                AccountValue av = buildAccountValue(arr);
+                avs.add(av);
+            }
+        }
+        return ar;
+    }
+
+    @Override
+    public void fillCommonPart(AccountRole ar, DocumentWrapper<List<AccountRoleRel>> wrapDoc)
+            throws Exception {
+        List<AccountRoleRel> arrl = wrapDoc.getWrappedObject();
+        SubjectType subject = ar.getSubject();
+        if (subject == null) {
+            //it is not required to give subject as URI determines the subject
+            subject = getSubject(getServiceContext());
+        } else {
+            //subject mismatch should have been checked during validation
+        }
+        if (subject.equals(SubjectType.ROLE)) {
+            AccountValue av = ar.getAccounts().get(0);
+
+            for (RoleValue rv : ar.getRoles()) {
+                AccountRoleRel arr = buildAccountRoleRel(av, rv);
+                arrl.add(arr);
+            }
+        } else if (SubjectType.ACCOUNT.equals(subject)) {
+            RoleValue rv = ar.getRoles().get(0);
+            for (AccountValue av : ar.getAccounts()) {
+                AccountRoleRel arr = buildAccountRoleRel(av, rv);
+                arrl.add(arr);
+            }
+        }
+    }
+
+    @Override
+    public PermissionsRolesList extractCommonPartList(
+            DocumentWrapper<List<AccountRoleRel>> wrapDoc)
+            throws Exception {
+
+        throw new UnsupportedOperationException("operation not relevant for AccountRoleDocumentHandler");
+    }
+
+    @Override
+    public AccountRole getCommonPart() {
+        return accountRole;
+    }
+
+    @Override
+    public void setCommonPart(AccountRole accountRole) {
+        this.accountRole = accountRole;
+    }
+
+    @Override
+    public PermissionsRolesList getCommonPartList() {
+        return accountRolesList;
+    }
+
+    @Override
+    public void setCommonPartList(PermissionsRolesList accountRolesList) {
+        this.accountRolesList = accountRolesList;
+    }
+
+    @Override
+    public String getQProperty(
+            String prop) {
+        return null;
+    }
+
+    @Override
+    public DocumentFilter createDocumentFilter() {
+        return new DocumentFilter(this.getServiceContext());
+    }
+
+    private AccountValue buildAccountValue(AccountRoleRel arr) {
+        AccountValue av = new AccountValue();
+        av.setAccountId(arr.getAccountId());
+        av.setUserId(arr.getUserId());
+        av.setScreenName(arr.getScreenName());
+        return av;
+    }
+
+    private RoleValue buildRoleValue(AccountRoleRel arr) {
+        RoleValue rv = new RoleValue();
+        rv.setRoleId(arr.getRoleId());
+        rv.setRoleName(arr.getRoleName());
+        return rv;
+    }
+
+    private AccountRoleRel buildAccountRoleRel(AccountValue av, RoleValue rv) {
+        AccountRoleRel arr = new AccountRoleRel();
+        arr.setAccountId(av.getAccountId());
+        arr.setUserId(av.getUserId());
+        arr.setScreenName(av.getScreenName());
+
+        arr.setRoleId(rv.getRoleId());
+        arr.setRoleName(rv.getRoleName());
+        return arr;
+    }
+
+    static SubjectType getSubject(ServiceContext ctx) {
+        Object o = ctx.getProperty("subject");
+        if (o == null) {
+            throw new IllegalArgumentException("property subject missing in context "
+                    + ctx.toString());
+        }
+        return (SubjectType) o;
+    }
+}
index a557fd39522b7fae1f8179da314b05918ff54200..ee670014e6c4a48dfed81f7aebaf5c9bb6045128 100644 (file)
@@ -28,7 +28,7 @@ copy before the "other" application-policy
                 select passwd from users where username=?
             </module-option>
             <module-option name="rolesQuery">
-                select r.rolename, 'Role' from roles as r, users_roles as ur where ur.username=? and ur.role_id=r.csid
+                select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid
             </module-option>
             <module-option name="tenantsQuery">
                 select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id
index 823bea056f9a03f591f45a7862229159f28f9523..699cc5f6db20a179be993cc3a6a875692f3a0e30 100644 (file)
@@ -145,7 +145,7 @@ $Revision: 64598 $
                 select passwd from users where username=?
             </module-option>
             <module-option name="rolesQuery">
-                 select r.rolename, 'Role' from roles as r, users_roles as ur where ur.username=? and ur.role_id=r.csid
+                select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid
             </module-option>
             <module-option name="tenantsQuery">
                 select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id
index 41a8a7c03a4046cefb1dc68e41071002ff06fb26..a1b81abef850479d38e48d26d5dd58efde1d6c9f 100644 (file)
         <dependency>\r
             <groupId>org.slf4j</groupId>\r
             <artifactId>slf4j-api</artifactId>\r
-            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.slf4j</groupId>\r
             <artifactId>slf4j-log4j12</artifactId>\r
-            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
@@ -85,7 +83,7 @@
     </dependencies>\r
 \r
     <build>\r
-        <finalName>cspace-services-authorization-client</finalName>\r
+        <finalName>cspace-services-authorization-mgt-client</finalName>\r
         <plugins>\r
             \r
             <plugin>\r
diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionFactory.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionFactory.java
new file mode 100644 (file)
index 0000000..8f2a2c4
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ *  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.client;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.collectionspace.services.authorization.ActionType;
+import org.collectionspace.services.authorization.EffectType;
+import org.collectionspace.services.authorization.Permission;
+import org.collectionspace.services.authorization.PermissionAction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author 
+ */
+public class PermissionFactory {
+
+    static private final Logger logger =
+            LoggerFactory.getLogger(PermissionFactory.class);
+
+    /**
+     * create permission instance
+     * @param resourceName
+     * @param description
+     * @param actionList list of actions for this permission
+     * @param effect effect of the permission
+     * @param useResourceName
+     * @param useAction
+     * @param useEffect
+     * @return
+     */
+    public static Permission createPermissionInstance(String resourceName,
+            String description,
+            List<PermissionAction> actionList,
+            EffectType effect,
+            boolean useResourceName,
+            boolean useAction,
+            boolean useEffect) {
+
+        Permission permission = new Permission();
+        if (useResourceName) {
+            permission.setResourceName(resourceName);
+        }
+        if (useAction) {
+            permission.setActions(actionList);
+        }
+        if (useEffect) {
+            permission.setEffect(effect);
+        }
+        return permission;
+    }
+
+
+    public static List<PermissionAction> createDefaultActions() {
+        List<PermissionAction> actions = new ArrayList<PermissionAction>();
+        PermissionAction create = new PermissionAction();
+        create.setName(ActionType.CREATE);
+        actions.add(create);
+
+        PermissionAction read = new PermissionAction();
+        read.setName(ActionType.READ);
+        actions.add(read);
+
+        PermissionAction update = new PermissionAction();
+        update.setName(ActionType.UPDATE);
+        actions.add(update);
+
+        PermissionAction delete = new PermissionAction();
+        delete.setName(ActionType.DELETE);
+        actions.add(delete);
+
+        PermissionAction search = new PermissionAction();
+        search.setName(ActionType.SEARCH);
+        actions.add(search);
+
+        return actions;
+    }
+}
diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/RoleFactory.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/RoleFactory.java
new file mode 100644 (file)
index 0000000..21dbc6e
--- /dev/null
@@ -0,0 +1,83 @@
+/**
+ *  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.
+ *//**
+ *  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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.collectionspace.services.client;
+
+
+import org.collectionspace.services.authorization.Role;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author 
+ */
+public class RoleFactory {
+
+    static private final Logger logger = LoggerFactory.getLogger(RoleFactory.class);
+    /**
+     * create role instance
+     * @param roleName
+     * @param description
+     * @param useRoleName
+     * @return
+     */
+    public static Role createRoleInstance(String roleName,
+            String description,
+            boolean useRoleName) {
+
+        Role role = new Role();
+        if (useRoleName) {
+            role.setRoleName(roleName);
+        }
+        role.setDescription(description);
+        return role;
+
+    }
+}
index acd39752b7d6b446a758176c53c36f19a334f296..e9555de9d0a1056a148aec1b53bb2bea92fb2da3 100644 (file)
@@ -36,8 +36,10 @@ import org.collectionspace.services.authorization.PermissionValue;
 import org.collectionspace.services.authorization.Role;
 import org.collectionspace.services.authorization.RoleValue;
 import org.collectionspace.services.client.PermissionClient;
+import org.collectionspace.services.client.PermissionFactory;
 import org.collectionspace.services.client.PermissionRoleClient;
 import org.collectionspace.services.client.RoleClient;
+import org.collectionspace.services.client.RoleFactory;
 import org.collectionspace.services.client.test.AbstractServiceTestImpl;
 import org.collectionspace.services.client.test.ServiceRequestType;
 import org.jboss.resteasy.client.ClientResponse;
@@ -59,7 +61,7 @@ import org.testng.annotations.BeforeClass;
  */
 public class PermissionRoleServiceTest extends AbstractServiceTestImpl {
 
-    private final Logger logger =
+    static private final Logger logger =
             LoggerFactory.getLogger(PermissionRoleServiceTest.class);
     // Instance variables specific to this test.
     private String knownResourceId = null;
@@ -156,31 +158,6 @@ public class PermissionRoleServiceTest extends AbstractServiceTestImpl {
     dependsOnMethods = {"create"})
     public void createList(String testName) throws Exception {
 
-        setupCreate(testName);
-        // Submit the request to the service and store the response.
-        PermissionRoleClient client = new PermissionRoleClient();
-        PermissionValue pv = permValues.get("collectionobjects");
-        PermissionRole permRole = createPermissionRoleInstance(pv,
-                roleValues.values(), true, true);
-        ClientResponse<Response> res = client.create(pv.getPermissionId(), permRole);
-        int statusCode = res.getStatus();
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        //id of relationship is not important
-        allResourceIdsCreated.add(pv.getPermissionId());
-
-        PermissionValue pv2 = permValues.get("intakes");
-        PermissionRole permRole2 = createPermissionRoleInstance(pv2,
-                roleValues.values(), true, true);
-        res = client.create(pv2.getPermissionId(), permRole2);
-        statusCode = res.getStatus();
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-                invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        //id of relationship is not important
-        allResourceIdsCreated.add(pv2.getPermissionId());
-
     }
 
     // Failure outcomes
@@ -385,7 +362,7 @@ public class PermissionRoleServiceTest extends AbstractServiceTestImpl {
      * @param useRoleId
      * @return
      */
-    private PermissionRole createPermissionRoleInstance(PermissionValue pv,
+    public static PermissionRole createPermissionRoleInstance(PermissionValue pv,
             Collection<RoleValue> rvs,
             boolean usePermId,
             boolean useRoleId) {
@@ -448,10 +425,10 @@ public class PermissionRoleServiceTest extends AbstractServiceTestImpl {
     private String createPermission(String resName, EffectType effect) {
         setupCreate();
         PermissionClient permClient = new PermissionClient();
-        List<PermissionAction> actions = PermissionServiceTest.getDefaultActions();
+        List<PermissionAction> actions = PermissionFactory.createDefaultActions();
         Permission permission = PermissionServiceTest.createPermissionInstance(resName,
                 "default permissions for " + resName,
-                actions, EffectType.PERMIT, true, true, true);
+                actions, effect, true, true, true);
         ClientResponse<Response> res = permClient.create(permission);
         int statusCode = res.getStatus();
         if (logger.isDebugEnabled()) {
@@ -482,7 +459,7 @@ public class PermissionRoleServiceTest extends AbstractServiceTestImpl {
         setupCreate();
         RoleClient roleClient = new RoleClient();
 
-        Role role = RoleServiceTest.createRoleInstance(roleName,
+        Role role = RoleFactory.createRoleInstance(roleName,
                 "role for " + roleName, true);
         ClientResponse<Response> res = roleClient.create(role);
         int statusCode = res.getStatus();
index ecd22aed90776d8fb166bbd6371a0fedd37927fe..b3c55a16765daba361cc0f87d4109142f36b3a26 100644 (file)
@@ -32,6 +32,7 @@ import org.collectionspace.services.client.PermissionClient;
 import org.collectionspace.services.authorization.Permission;
 import org.collectionspace.services.authorization.PermissionAction;
 import org.collectionspace.services.authorization.PermissionsList;
+import org.collectionspace.services.client.PermissionFactory;
 import org.collectionspace.services.client.test.AbstractServiceTestImpl;
 import org.collectionspace.services.client.test.ServiceRequestType;
 import org.jboss.resteasy.client.ClientResponse;
@@ -81,7 +82,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
         setupCreate(testName);
 
         // Submit the request to the service and store the response.
-        List<PermissionAction> actions = getDefaultActions();
+        List<PermissionAction> actions = PermissionFactory.createDefaultActions();
         Permission permission = createPermissionInstance("accounts",
                 "default permissions for account",
                 actions,
@@ -121,7 +122,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
         setupCreate(testName);
 
         // Submit the request to the service and store the response.
-        List<PermissionAction> actions = getDefaultActions();
+        List<PermissionAction> actions = PermissionFactory.createDefaultActions();
         Permission permission = createPermissionInstance(null,
                 "default permissions for account",
                 actions,
@@ -149,7 +150,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
 
         setupCreate(testName);
         // Submit the request to the service and store the response.
-        List<PermissionAction> actions = getDefaultActions();
+        List<PermissionAction> actions = PermissionFactory.createDefaultActions();
         Permission permission1 = createPermissionInstance("collectionobjects",
                 "default permissions for collectionobjects",
                 actions,
@@ -416,7 +417,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
         // Note: The ID used in this 'create' call may be arbitrary.
         // The only relevant ID may be the one used in updatePermission(), below.
         PermissionClient client = new PermissionClient();
-        List<PermissionAction> actions = getDefaultActions();
+        List<PermissionAction> actions = PermissionFactory.createDefaultActions();
         Permission permission = createPermissionInstance("acquisitions",
                 "default permissions for acquisitions",
                 actions,
@@ -531,7 +532,7 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
      * @param useEffect
      * @return
      */
-    static Permission createPermissionInstance(String resourceName,
+    public static Permission createPermissionInstance(String resourceName,
             String description,
             List<PermissionAction> actionList,
             EffectType effect,
@@ -539,49 +540,17 @@ public class PermissionServiceTest extends AbstractServiceTestImpl {
             boolean useAction,
             boolean useEffect) {
 
-        Permission permission = new Permission();
-        if (useResourceName) {
-            permission.setResourceName(resourceName);
-        }
-        if (useAction) {
-            permission.setActions(actionList);
-        }
-        if (useEffect) {
-            permission.setEffect(effect);
-        }
-
+        Permission permission = PermissionFactory.createPermissionInstance(resourceName,
+                description, actionList, effect,
+                useResourceName, useAction, useEffect);
 
         if (logger.isDebugEnabled()) {
             logger.debug("to be created, permission common");
-        logger.debug(objectAsXmlString(permission, Permission.class));
+            logger.debug(objectAsXmlString(permission, Permission.class));
         }
         return permission;
     }
 
-    static List<PermissionAction> getDefaultActions() {
-        List<PermissionAction> actions = new ArrayList<PermissionAction>();
-        PermissionAction create = new PermissionAction();
-        create.setName(ActionType.CREATE);
-        actions.add(create);
-
-        PermissionAction read = new PermissionAction();
-        read.setName(ActionType.READ);
-        actions.add(read);
-
-        PermissionAction update = new PermissionAction();
-        update.setName(ActionType.UPDATE);
-        actions.add(update);
-
-        PermissionAction delete = new PermissionAction();
-        delete.setName(ActionType.DELETE);
-        actions.add(delete);
-
-        PermissionAction search = new PermissionAction();
-        search.setName(ActionType.SEARCH);
-        actions.add(search);
-
-        return actions;
-    }
 
     @AfterClass(alwaysRun = true)
     public void cleanUp() {
index bb609762fe2ddddfbbe156ea2e0e3bc8ab06d0eb..97d9f8be19172754916e3d992c7bcd9edaec4e1e 100644 (file)
@@ -29,6 +29,7 @@ import javax.ws.rs.core.Response;
 import org.collectionspace.services.client.RoleClient;
 import org.collectionspace.services.authorization.Role;
 import org.collectionspace.services.authorization.RolesList;
+import org.collectionspace.services.client.RoleFactory;
 import org.collectionspace.services.client.test.AbstractServiceTestImpl;
 import org.collectionspace.services.client.test.ServiceRequestType;
 import org.jboss.resteasy.client.ClientResponse;
@@ -49,7 +50,7 @@ import org.testng.annotations.AfterClass;
  */
 public class RoleServiceTest extends AbstractServiceTestImpl {
 
-    static private final Logger logger =
+    private final Logger logger =
             LoggerFactory.getLogger(RoleServiceTest.class);
     // Instance variables specific to this test.
     private String knownResourceId = null;
@@ -520,15 +521,12 @@ public class RoleServiceTest extends AbstractServiceTestImpl {
      * @param useRoleName
      * @return
      */
-    static Role createRoleInstance(String roleName,
+    public Role createRoleInstance(String roleName,
             String description,
             boolean useRoleName) {
 
-        Role role = new Role();
-        if (useRoleName) {
-            role.setRoleName(roleName);
-        }
-        role.setDescription(description);
+        Role role = RoleFactory.createRoleInstance(roleName, description,
+                useRoleName);
         if (logger.isDebugEnabled()) {
             logger.debug("to be created, role common");
             logger.debug(objectAsXmlString(role, Role.class));
index 88102e84ca177ee91429801e56ec099ac838111b..4b6d2dda7fdf30b874024d28e463b8567bcc4bee 100644 (file)
     </xs:complexType>
 
 
-    <xs:complexType name="user_role">
+    <xs:complexType name="account_role_rel">
         <xs:annotation>
-            <xs:documentation>UserRole defines association between user and role in CollectionSpace</xs:documentation>
+            <xs:documentation>AccountRole defines association between account and role in CollectionSpace</xs:documentation>
             <xs:appinfo>
                 <hj:entity>
-                    <orm:table name="users_roles">
+                    <orm:table name="accounts_roles">
                         <orm:unique-constraint>
                             <!-- combined length should be < 1000 bytes -->
-                            <orm:column-name>username</orm:column-name>
+                            <orm:column-name>account_id</orm:column-name>
                             <orm:column-name>role_id</orm:column-name>
                         </orm:unique-constraint>
                     </orm:table>
             </xs:appinfo>
         </xs:annotation>
         <xs:sequence>
-            <xs:element name="userName" type="xs:string" minOccurs="1" maxOccurs="1">
+            <xs:element name="accountId" type="xs:string" minOccurs="0" maxOccurs="1">
                 <xs:annotation>
                     <xs:appinfo>
                         <hj:basic>
-                            <orm:column name="username" length="128" nullable="false"/>
+                            <orm:column name="account_id" length="128" nullable="false"/>
+                        </hj:basic>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="screenName" type="xs:string" minOccurs="0" maxOccurs="1">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <hj:basic>
+                            <orm:column name="screen_name" nullable="true"/>
+                        </hj:basic>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="userId" type="xs:string" minOccurs="1" maxOccurs="1">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <hj:basic>
+                            <orm:column name="user_id" length="128" nullable="false"/>
                         </hj:basic>
                     </xs:appinfo>
                 </xs:annotation>
                     </xs:appinfo>
                 </xs:annotation>
             </xs:element>
-            <xs:element name="createdAt" type="xs:dateTime">
+            <xs:element name="roleName" type="xs:string" minOccurs="0" maxOccurs="1">
                 <xs:annotation>
                     <xs:appinfo>
                         <hj:basic>
-                            <orm:column name="created_at" nullable="false"/>
+                            <orm:column name="role_name" nullable="true"/>
                         </hj:basic>
                     </xs:appinfo>
                 </xs:annotation>
             </xs:element>
-            <xs:element name="updatedAt" type="xs:dateTime">
+            <xs:element name="createdAt" type="xs:dateTime">
                 <xs:annotation>
                     <xs:appinfo>
                         <hj:basic>
-                            <orm:column name="updated_at" />
+                            <orm:column name="created_at" nullable="false"/>
                         </hj:basic>
                     </xs:appinfo>
                 </xs:annotation>
index 7fdc2521c1267aca7d06fbbbc91dbdf2770923c3..0918afab0cfd2bf4b3922c1e8372b4dfe931e0ee 100644 (file)
                     </xs:appinfo>
                 </xs:annotation>
             </xs:element>
-            <xs:element name="updatedAt" type="xs:dateTime">
-                <xs:annotation>
-                    <xs:appinfo>
-                        <hj:basic>
-                            <orm:column name="updated_at" />
-                        </hj:basic>
-                    </xs:appinfo>
-                </xs:annotation>
-            </xs:element>
         </xs:sequence>
     </xs:complexType>
 
index 3632e9f4f32154f1a68612c023252a363385e440..0db2ab063bc0f2e10cebd1b2f888b85a8f0e83b3 100644 (file)
@@ -1,12 +1,12 @@
 alter table permissions_actions drop foreign key FK85F82042E2DC84FD;
+drop table if exists accounts_roles;
 drop table if exists permissions;
 drop table if exists permissions_actions;
 drop table if exists permissions_roles;
 drop table if exists roles;
-drop table if exists users_roles;
+create table accounts_roles (HJID bigint not null auto_increment, account_id varchar(128) not null, created_at datetime not null, role_id varchar(128) not null, role_name varchar(255), screen_name varchar(255), user_id varchar(128) not null, primary key (HJID), unique (account_id, role_id));
 create table permissions (csid varchar(128) not null, attribute_name varchar(128), created_at datetime not null, description varchar(255), effect varchar(32) not null, resource_name varchar(128) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid));
 create table permissions_actions (HJID bigint not null auto_increment, name varchar(128) not null, ACTIONS_PERMISSION_CSID varchar(128), primary key (HJID));
-create table permissions_roles (HJID bigint not null auto_increment, created_at datetime not null, permission_id varchar(128) not null, permission_resource varchar(255), role_id varchar(128) not null, role_name varchar(255), updated_at datetime, primary key (HJID), unique (permission_id, role_id));
+create table permissions_roles (HJID bigint not null auto_increment, created_at datetime not null, permission_id varchar(128) not null, permission_resource varchar(255), role_id varchar(128) not null, role_name varchar(255), primary key (HJID), unique (permission_id, role_id));
 create table roles (csid varchar(128) not null, created_at datetime not null, description varchar(255), rolegroup varchar(255), rolename varchar(200) not null, tenant_id varchar(128) not null, updated_at datetime, primary key (csid), unique (rolename));
-create table users_roles (HJID bigint not null auto_increment, created_at datetime not null, role_id varchar(128) not null, updated_at datetime, username varchar(128) not null, primary key (HJID), unique (username, role_id));
 alter table permissions_actions add index FK85F82042E2DC84FD (ACTIONS_PERMISSION_CSID), add constraint FK85F82042E2DC84FD foreign key (ACTIONS_PERMISSION_CSID) references permissions (csid);
index 6d9a19740fa352d023301abd55868f435bd5d51d..012e86abd489d9a2756c87a91f248ad66633d1a1 100644 (file)
@@ -1,5 +1,5 @@
 --
--- Copyright 20010 University of California at Berkeley
+-- 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.
 --
@@ -7,7 +7,10 @@ use cspace;
 CREATE INDEX index_rolename ON roles (rolename);
 CREATE INDEX index_rolegroup ON roles (rolegroup);
 CREATE INDEX index_tenant_id ON roles (tenant_id);
-CREATE INDEX index_username ON users_roles (username);
-CREATE INDEX index_role_id ON users_roles (role_id);
+
+CREATE INDEX index_user_id ON accounts_roles (user_id);
+CREATE INDEX index_account_id ON accounts_roles (account_id);
+CREATE INDEX index_role_id ON accounts_roles (role_id);
+
 CREATE INDEX index_permission_id ON permissions_roles (permission_id);
 CREATE INDEX index_role_id ON permissions_roles (role_id);
index b63777d0ac814337bf22b4b6b254576fc80a8010..874ed3e98eb9122cf1942fe940f99f9346cf8023 100644 (file)
@@ -10,9 +10,10 @@ insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`)
 insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('3', 'ROLE_COLLECTIONS_MANAGER', 'collections', '2010-02-17 16:31:48', '1');\r
 insert into `roles` (`csid`, `rolename`, `rolegroup`, `created_at`, `tenant_id`) values ('4', 'ROLE_COLLECTIONS_REGISTRAR', 'collections', '2010-02-17 16:31:48', '1');\r
 \r
-insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '1', '2010-02-17 16:31:48');\r
-insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '2', '2010-02-17 16:31:48');\r
-insert into `users_roles`(`username`, `role_id`, `created_at`) values ('test', '3', '2010-02-17 16:31:48');\r
+insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '1', 'ROLE_ADMINISTRATOR', '2010-02-17 16:31:48');\r
+insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '2', 'ROLE_USERS', '2010-02-17 16:31:48');\r
+insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('eeca40d7-dc77-4cc5-b489-16a53c75525a', 'test', '3', 'ROLE_COLLECTIONS_MANAGER', '2010-02-17 16:31:48');\r
 \r
-insert into `users_roles`(`username`, `role_id`, `created_at`) values ('barney', '2', '2010-02-17 16:31:48');\r
-insert into `users_roles`(`username`, `role_id`, `created_at`) values ('barney', '3', '2010-02-17 16:31:48');\r
+-- todo: barney is created in security test but accountrole is not yet created there, so add fake account id\r
+insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '2', 'ROLE_USERS', '2010-02-17 16:31:48');\r
+insert into `accounts_roles`(`account_id`, `user_id`, `role_id`, `role_name`, `created_at`) values ('1', 'barney', '3', 'ROLE_COLLECTIONS_MANAGER', '2010-02-17 16:31:48');\r
index 18d7e06bf3682c6e4d370a09bd7fed4e2a203f84..ec517f79d8df503f83b239af54b011f326a93948 100644 (file)
@@ -6,7 +6,7 @@
         <class>org.collectionspace.services.authorization.PermissionAction</class>
         <class>org.collectionspace.services.authorization.PermissionRoleRel</class>
         <class>org.collectionspace.services.authorization.Role</class>
-        <class>org.collectionspace.services.authorization.UserRole</class>
+        <class>org.collectionspace.services.authorization.AccountRoleRel</class>
         <properties>
             <property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
 
index 7660a6a3a43d685687efa67f3661df26ef36ff06..a9cd3d2def71fbe5a914defd5ae58c6b6e0145d6 100644 (file)
             </service:object>
         </tenant:serviceBindings>
         <!-- end permission-role service meta-data -->
+        <!-- begin account-role service meta-data -->
+        <tenant:serviceBindings name="accounts/accountroles" version="0.1">
+            <service:documentHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                org.collectionspace.services.account.storage.AccountRoleDocumentHandler
+            </service:documentHandler>
+            <!--service:validatorHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                org.collectionspace.services.account.storage.AccountRoleDocumentHandler
+            </service:validatorHandler-->
+            <service:object name="PermissionRole" version="0.1"
+                            xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:part id="0" control_group="Managed"
+                              versionable="true" auditable="false"
+                              label="accountroles_system" updated="" order="0">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                            namespaceURI="http://collectionspace.org/services/common/system"
+                            schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+                <service:part id="1" control_group="Managed"
+                              versionable="true" auditable="false"
+                              label="accountroles" updated="" order="1">
+                    <service:content contentType="application/xml">
+                        <service:xmlContent
+                            namespaceURI="http://collectionspace.org/services/authorization"
+                            schemaLocation="http://collectionspace.org/services/authorization http://services.collectionspace.org/authorization/accounts_roles.xsd">
+                        </service:xmlContent>
+                    </service:content>
+                </service:part>
+            </service:object>
+        </tenant:serviceBindings>
+        <!-- end account-role service meta-data -->
     </tenant:tenantBinding>
     <!-- end movingimages.us tenant meta-data -->
 </tenant:TenantBindingConfig>
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
new file mode 100644 (file)
index 0000000..91ae140
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ *  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.
+ */
+package org.collectionspace.services.common.storage.jpa;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentHandler;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JpaRelationshipStorageClient deals with a relationship
+ * in persistent storage. This storage client deals with bulk operations, i.e.
+ * create/post inserts multiple tuples between the given object and subjects
+ * get retrieves all subjects for the given object in relationship
+ * delete deletes all subjects for the given object in relationship
+ * @author 
+ */
+public class JpaRelationshipStorageClient<T> extends JpaStorageClientImpl {
+
+    private final Logger logger = LoggerFactory.getLogger(JpaRelationshipStorageClient.class);
+
+    public JpaRelationshipStorageClient() {
+    }
+
+    /**
+     * create of a relationship creates one or more relationships between
+     * permission and role
+     * the object and subjects of the relationship is chosen (by doc handler) from
+     * the payload
+     * @param ctx
+     * @param handler
+     * @return
+     * @throws BadRequestException
+     * @throws DocumentException
+     */
+    @Override
+    public String create(ServiceContext ctx,
+            DocumentHandler handler) throws BadRequestException,
+            DocumentException {
+
+        if (ctx == null) {
+            throw new IllegalArgumentException(
+                    "JpaRelationshipStorageClient.create : ctx is missing");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "JpaRelationshipStorageClient.create: handler is missing");
+        }
+        EntityManagerFactory emf = null;
+        EntityManager em = null;
+        try {
+            handler.prepare(Action.CREATE);
+            List<T> rl = new ArrayList<T>();
+            DocumentWrapper<List<T>> wrapDoc =
+                    new DocumentWrapperImpl<List<T>>(rl);
+            handler.handle(Action.CREATE, wrapDoc);
+            emf = getEntityManagerFactory();
+            em = emf.createEntityManager();
+            em.getTransaction().begin();
+            for (T r : rl) {
+                setValue(r, "setCreatedAtItem", Date.class, new Date());
+                em.persist(r);
+            }
+            em.getTransaction().commit();
+            handler.complete(Action.CREATE, wrapDoc);
+            return UUID.randomUUID().toString(); //filler, not useful
+        } catch (BadRequestException bre) {
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            throw bre;
+        } catch (Exception e) {
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        } finally {
+            if (em != null) {
+                releaseEntityManagerFactory(emf);
+            }
+        }
+    }
+
+    /**
+     * get retrieves all relationships for the object in the relationship
+     * identified by the id. the object could be a permission or a role
+     * @param ctx
+     * @param id of the object in the relationship
+     * @param handler
+     * @throws DocumentNotFoundException
+     * @throws DocumentException
+     */
+    @Override
+    public void get(ServiceContext ctx, String id, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
+        if (ctx == null) {
+            throw new IllegalArgumentException(
+                    "JpaRelationshipStorageClient.get: ctx is missing");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "JpaRelationshipStorageClient.get: handler is missing");
+        }
+        DocumentFilter docFilter = handler.getDocumentFilter();
+        if (docFilter == null) {
+            docFilter = handler.createDocumentFilter();
+        }
+        EntityManagerFactory emf = null;
+        EntityManager em = null;
+        try {
+            handler.prepare(Action.GET);
+            StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM ");
+            queryStrBldr.append(getEntityName(ctx));
+            queryStrBldr.append(" a");
+            String objectId = getObjectId(ctx);
+            if (logger.isDebugEnabled()) {
+                logger.debug("get: using objectId=" + objectId);
+            }
+            queryStrBldr.append(" WHERE " + objectId + " = :objectId");
+            String where = docFilter.getWhereClause();
+            if ((null != where) && (where.length() > 0)) {
+                queryStrBldr.append(" AND " + where);
+            }
+            emf = getEntityManagerFactory();
+            em = emf.createEntityManager();
+            String queryStr = queryStrBldr.toString(); //for debugging
+            if (logger.isDebugEnabled()) {
+                logger.debug("get: jql=" + queryStr.toString());
+            }
+            Query q = em.createQuery(queryStr);
+            q.setParameter("objectId", id);
+
+            List<T> rl = new ArrayList<T>();
+            try {
+                //require transaction for get?
+                em.getTransaction().begin();
+                rl = q.getResultList();
+                em.getTransaction().commit();
+            } catch (NoResultException nre) {
+                if (em != null && em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                String msg = "could not find entity with id=" + id;
+                logger.error(msg, nre);
+                throw new DocumentNotFoundException(msg, nre);
+            }
+            if (rl.size() == 0) {
+                String msg = "could not find entity with id=" + id;
+                logger.error(msg);
+                throw new DocumentNotFoundException(msg);
+            }
+            DocumentWrapper<List<T>> wrapDoc =
+                    new DocumentWrapperImpl<List<T>>(rl);
+            handler.handle(Action.GET, wrapDoc);
+            handler.complete(Action.GET, wrapDoc);
+        } catch (DocumentException de) {
+            throw de;
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        } finally {
+            if (emf != null) {
+                releaseEntityManagerFactory(emf);
+            }
+        }
+    }
+
+    /**
+     * delete removes all the relationships for the object in the relationship
+     * identified by the id. the object could be a permission or a role
+     * @param ctx
+     * @param id of the object in the relationship
+     * @throws DocumentNotFoundException
+     * @throws DocumentException
+     */
+    @Override
+    public void delete(ServiceContext ctx, String id)
+            throws DocumentNotFoundException,
+            DocumentException {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("deleting entity with id=" + id);
+        }
+        if (ctx == null) {
+            throw new IllegalArgumentException(
+                    "JpaRelationshipStorageClient.delete : ctx is missing");
+        }
+        EntityManagerFactory emf = null;
+        EntityManager em = null;
+        try {
+            StringBuilder deleteStr = new StringBuilder("DELETE FROM ");
+            deleteStr.append(getEntityName(ctx));
+            String objectId = getObjectId(ctx);
+            if (logger.isDebugEnabled()) {
+                logger.debug("delete: using objectId=" + objectId);
+            }
+            deleteStr.append(" WHERE " + objectId + " = :objectId");
+            emf = getEntityManagerFactory();
+            em = emf.createEntityManager();
+            if (logger.isDebugEnabled()) {
+                logger.debug("delete: jql=" + deleteStr.toString());
+            }
+            Query q = em.createQuery(deleteStr.toString());
+            q.setParameter("objectId", id);
+            int rcount = 0;
+            em.getTransaction().begin();
+            rcount = q.executeUpdate();
+            if (rcount == 0) {
+                if (em != null && em.getTransaction().isActive()) {
+                    em.getTransaction().rollback();
+                }
+                String msg = "could not find entity with id=" + id;
+                logger.error(msg);
+                throw new DocumentNotFoundException(msg);
+            }
+            em.getTransaction().commit();
+
+        } catch (DocumentException de) {
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            throw de;
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            if (em != null && em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            throw new DocumentException(e);
+        } finally {
+            if (emf != null) {
+                releaseEntityManagerFactory(emf);
+            }
+        }
+    }
+
+    protected String getObjectId(ServiceContext ctx) {
+        String objectId = (String) ctx.getProperty("objectId");
+        if (objectId == null) {
+            String msg = "objectId is missing in the context";
+            logger.error(msg);
+            throw new IllegalArgumentException(msg);
+        }
+
+        return objectId;
+    }
+}
index dc29738e392681d1a240f78423efa259d72a9ffe..552b17e442c4ca3b86b989b2c91ae560a8dbfd81 100644 (file)
@@ -152,6 +152,7 @@ public class JpaStorageClientImpl implements StorageClient {
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
      */
+    @Override
     public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
             throws DocumentNotFoundException, DocumentException {
         throw new UnsupportedOperationException();
index 4556e2b2fe2a3c08b44befea561a19070a65eee7..50e57ef2235b7296dab9816fa91312e403511ee7 100644 (file)
@@ -18,8 +18,8 @@
         <module>client</module>
         <module>jaxb</module>
         <module>common</module>
-        <module>account</module>
-        <module>authorization-mgt</module>
+        <module>authorization-mgt</module> <!-- relies on authorization -->
+        <module>account</module> <!-- relies on authorization-mgt.client -->
         <module>relation</module>
         <!--        <module>query</module> -->
         <module>acquisition</module>
@@ -69,7 +69,7 @@
                         </systemProperties>
                     </configuration>
                 </plugin-->
-                
+
                 <plugin>
                     <groupId>org.jvnet.hyperjaxb3</groupId>
                     <artifactId>maven-hyperjaxb3-plugin</artifactId>
@@ -94,7 +94,7 @@
                     <artifactId>maven-jaxb2-plugin</artifactId>
                     <version>0.7.2</version>
                 </plugin-->
-                
+
                 <plugin>
                     <groupId>org.jvnet.jaxb2.maven2</groupId>
                     <artifactId>maven-jaxb2-plugin</artifactId>