]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-590, CSPACE-852. Added support to get PersonAuthority by name, prototyping...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Tue, 2 Mar 2010 00:02:05 +0000 (00:02 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Tue, 2 Mar 2010 00:02:05 +0000 (00:02 +0000)
services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityClient.java
services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityProxy.java
services/person/client/src/test/java/org/collectionspace/services/client/test/PersonAuthorityServiceTest.java
services/person/jaxb/src/main/java/org/collectionspace/services/PersonAuthorityJAXBSchema.java
services/person/service/src/main/java/org/collectionspace/services/person/PersonAuthorityResource.java

index 3e34f29c87d318d30f377c524bfcf7eabcac83d5..8142c0bf150c54fb3f430e58cd30c06c484b5ef2 100644 (file)
@@ -60,6 +60,16 @@ public interface StorageClient {
      */
     void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
 
+    /**
+     * get entity from the persistence store, using the docFilter params. 
+     * @param ctx service context under which this method is invoked
+     * @param handler should be used by the caller to provide and transform the entity.
+     *               Handler must have a docFilter set to return a single item.
+     * @throws DocumentNotFoundException if entity not found
+     * @throws DocumentException
+     */
+    void get(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
     /**
      * Gets the.
      * 
index fbb34cc247ae031fbbba23735d36fdaa619ec80c..6568653fbecb28a8e7945fa70e0c91ee4d3d440b 100644 (file)
@@ -519,4 +519,10 @@ public class JpaStorageClientImpl implements StorageClient {
 
         return (String) o;
     }
+
+       @Override
+       public void get(ServiceContext ctx, DocumentHandler handler)
+                       throws DocumentNotFoundException, DocumentException {
+        throw new UnsupportedOperationException();
+       }
 }
index 59368cac62b5ce92ce33df175299c326e56ce1d7..71ae5631fa9331091d607e7c1cc21333a3ec348d 100644 (file)
@@ -42,7 +42,10 @@ public class RefNameUtils {
 \r
     private final Logger logger = LoggerFactory.getLogger(RefNameUtils.class);\r
 \r
-    private static final String URN_PREFIX = "urn:cspace:";\r
+    public static final String URN_PREFIX = "urn:cspace:";\r
+    public static final int URN_PREFIX_LEN = 11;\r
+    public static final String URN_NAME_PREFIX = "urn:cspace:name(";\r
+    public static final int URN_NAME_PREFIX_LEN = 16;\r
        // FIXME Should not be hard-coded\r
     private static final String ITEMS_REGEX = "item|person|organization";\r
     // In a list of tokens, these are indices for each part\r
@@ -57,7 +60,6 @@ public class RefNameUtils {
     private static final int INSTANCE_DISPLAYNAME_TOKEN = 2;// optional displayName suffix\r
     private static final int INSTANCE_TOKENS_MIN = 2;\r
     private static final int INSTANCE_TOKENS_MAX = 3;\r
-    private static final int prefixLen = 11;\r
     private static final String SEPARATOR = ":";\r
 \r
     public static class AuthorityInfo {\r
@@ -185,14 +187,14 @@ public class RefNameUtils {
             throws Exception {\r
        if(refName==null || !refName.startsWith(URN_PREFIX))\r
                throw new RuntimeException( "Null or invalid refName syntax");\r
-       return new AuthorityInfo(refName.substring(prefixLen).split(SEPARATOR));\r
+       return new AuthorityInfo(refName.substring(URN_PREFIX_LEN).split(SEPARATOR));\r
     }\r
 \r
     public static AuthorityTermInfo parseAuthorityTermInfo(String refName)\r
             throws Exception {\r
        if(refName==null || !refName.startsWith(URN_PREFIX))\r
                throw new RuntimeException( "Null or invalid refName syntax");\r
-       return new AuthorityTermInfo(refName.substring(prefixLen).split(SEPARATOR));\r
+       return new AuthorityTermInfo(refName.substring(URN_PREFIX_LEN).split(SEPARATOR));\r
     }\r
 \r
     public static String implodeStringArray(String tokens[], String separator) {\r
index a2d05fa2cc63fd6bf600ee225a9dc23ae223fc7d..fb0c9287ec00d964ab2e6fc0be4808c17a95f512 100644 (file)
@@ -177,6 +177,80 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
     }
 
+    /**
+     * get document from the Nuxeo repository, using the docFilter params.
+     * @param ctx service context under which this method is invoked
+     * @param handler
+     *            should be used by the caller to provide and transform the
+     *            document. Handler must have a docFilter set to return a single item.
+     * @throws DocumentException
+     */
+    @Override
+    public void get(ServiceContext ctx, DocumentHandler handler)
+            throws DocumentNotFoundException, DocumentException {
+
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "RepositoryJavaClient.get: handler is missing");
+        }
+        DocumentFilter docFilter = handler.getDocumentFilter();
+        if (docFilter == null) {
+            throw new IllegalArgumentException(
+                   "RepositoryJavaClient.get: handler has no Filter specified");
+        }
+        if(docFilter.getPageSize()!= 1) {
+            logger.warn("RepositoryJavaClient.get: forcing docFilter pagesize to 1.");
+        }
+        String docType = ctx.getDocumentType();
+        if (docType == null) {
+            throw new DocumentNotFoundException(
+                   "Unable to find DocumentType for service " + ctx.getServiceName());
+        }
+        String domain = ctx.getRepositoryDomainName();
+        if (domain == null) {
+            throw new DocumentNotFoundException(
+                    "Unable to find Domain for service " + ctx.getServiceName());
+        }
+        RepositoryInstance repoSession = null;
+
+        try {
+            handler.prepare(Action.GET);
+            repoSession = getRepositorySession();
+            
+            DocumentModelList docList = null;
+            // force limit to 1, and ignore totalSize
+            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain ); 
+            docList = repoSession.query( query, null, 1, 0, false);
+            if(docList.size()!=1) {
+                throw new DocumentNotFoundException("No document found matching filter params.");
+            }
+            DocumentModel doc = docList.get(0);
+            
+            if (logger.isDebugEnabled()) {
+                logger.debug("Executed NXQL query: " + query);
+            }
+            
+            //set reposession to handle the document
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
+            handler.handle(Action.GET, wrapDoc);
+            handler.complete(Action.GET, wrapDoc);
+        } catch (IllegalArgumentException iae) {
+            throw iae;
+        } catch (DocumentException de) {
+            throw de;
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            throw new DocumentException(e);
+        } finally {
+            if (repoSession != null) {
+                releaseRepositorySession(repoSession);
+            }
+        }
+    }
+
     /**
      * get wrapped documentModel from the Nuxeo repository
      * @param ctx service context under which this method is invoked
@@ -343,25 +417,16 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         try {
             handler.prepare(Action.GET_ALL);
             repoSession = getRepositorySession();
-            StringBuilder query = new StringBuilder("SELECT * FROM ");
-            query.append(docType);
-            String where = docFilter.getWhereClause();
-            // TODO This is a slow method for tenant-filter
-            // We should make this a property that is indexed.
-            query.append(" WHERE ecm:path STARTSWITH '/" + domain + "'");
-            if ((null != where) && (where.length() > 0)) {
-               // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
-               // into SQL, we need to parenthesize our 'where' clause
-                query.append(" AND " + "(" + where +")" + "AND ecm:isProxy = 0");
-            }
             DocumentModelList docList = null;
+            String query = buildNXQLQuery(docType, docFilter.getWhereClause(), domain );
+
             // If we have limit and/or offset, then pass true to get totalSize
             // in returned DocumentModelList.
             if ((docFilter.getOffset() > 0) || (docFilter.getPageSize() > 0)) {
-                docList = repoSession.query(query.toString(), null,
+                docList = repoSession.query(query, null,
                         docFilter.getPageSize(), docFilter.getOffset(), true);
             } else {
-                docList = repoSession.query(query.toString());
+                docList = repoSession.query(query);
             }
             
             if (logger.isDebugEnabled()) {
@@ -543,6 +608,20 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
         }
         return workspaceId;
     }
+    
+    private final String buildNXQLQuery(String docType, String where, String domain ) {
+        StringBuilder query = new StringBuilder("SELECT * FROM ");
+        query.append(docType);
+        // TODO This is a slow method for tenant-filter
+        // We should make this a property that is indexed.
+        query.append(" WHERE ecm:path STARTSWITH '/" + domain + "'");
+        if ((null != where) && (where.length() > 0)) {
+               // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
+               // into SQL, we need to parenthesize our 'where' clause
+            query.append(" AND " + "(" + where +")" + "AND ecm:isProxy = 0");
+        }
+        return query.toString();
+    }
 
     private RepositoryInstance getRepositorySession() throws Exception {
         // FIXME: is it possible to reuse repository session?
index 65c7d28a9090c563a45400e1d6a59c381c0748d1..fecd59d426402c2a1ca744b752111aed0f8492d4 100644 (file)
@@ -92,6 +92,15 @@ public class PersonAuthorityClient extends AbstractServiceClientImpl {
         return personAuthorityProxy.read(csid);
     }
 
+    /**
+     * @param name
+     * @return
+     * @see org.collectionspace.services.client.PersonAuthorityProxy#readByName(java.lang.String)
+     */
+    public ClientResponse<MultipartInput> readByName(String name) {
+        return personAuthorityProxy.readByName(name);
+    }
+
     /**
      * @param personAuthority
      * @return
index 3f5f8275913e33f0d727c72bb353490c946a7330..3a25ba8a1533aa9e2b8dd77f1cc8d3d6e1f97ee7 100644 (file)
@@ -39,6 +39,11 @@ public interface PersonAuthorityProxy {
     @Path("/{csid}")
     ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
 
+    //(R)ead by name
+    @GET
+    @Path("/urn:cspace:name({name})")
+    ClientResponse<MultipartInput> readByName(@PathParam("name") String name);
+
     //(U)pdate
     @PUT
     @Path("/{csid}")
index 8c25b896557ad787d25c9800b58085be98601b66..31f726b21854a43fe3cd6f313fd415b328b448e8 100644 (file)
@@ -75,6 +75,7 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl {
     final String TEST_DEATH_DATE = "June 11, 1979";
  
     private String knownResourceId = null;
+    private String knownResourceDisplayName = null;
     private String knownResourceRefName = null;
     private String knownItemResourceId = null;
     private String knownContactResourceId = null;
@@ -132,6 +133,7 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl {
         // for additional tests below.
         if (knownResourceId == null){
             knownResourceId = newID;
+            knownResourceDisplayName = displayName;
             if (logger.isDebugEnabled()) {
                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
             }
@@ -417,6 +419,36 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl {
         }
     }
 
+    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
+            groups = {"read"}, dependsOnGroups = {"create"})
+        public void readByName(String testName) throws Exception {
+
+            // Perform setup.
+            setupRead();
+            
+            // Submit the request to the service and store the response.
+            ClientResponse<MultipartInput> res = client.readByName(knownResourceDisplayName);
+            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);
+            //FIXME: remove the following try catch once Aron fixes signatures
+            try {
+                MultipartInput input = (MultipartInput) res.getEntity();
+                PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
+                        client.getCommonPartName(), PersonauthoritiesCommon.class);
+                Assert.assertNotNull(personAuthority);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
 /*
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
         groups = {"read"}, dependsOnMethods = {"read"})
index cef5d5e1af4cca07f28a7bc67a363a81ed40925d..b80986b823280bfa77c14595810c512b5a659df8 100644 (file)
@@ -8,6 +8,7 @@ package org.collectionspace.services;
  *\r
  */\r
 public interface PersonAuthorityJAXBSchema {\r
+       final static String PERSONAUTHORITIES_COMMON = "personauthorities_common";\r
        final static String DISPLAY_NAME = "displayName";\r
        final static String REF_NAME = "refName";\r
        final static String VOCAB_TYPE = "vocabType";\r
index d98f2748e664066ada66caf2aed9d3299c9bf886..26e09c57a4241987b841f6046ae967093581dc1f 100644 (file)
@@ -41,6 +41,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 
+import org.collectionspace.services.PersonAuthorityJAXBSchema;
 import org.collectionspace.services.PersonJAXBSchema;
 import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
 import org.collectionspace.services.common.ClientType;
@@ -53,6 +54,7 @@ import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.security.UnauthorizedException;
+import org.collectionspace.services.common.vocabulary.RefNameUtils;
 import org.collectionspace.services.common.query.IQueryManager;
 import org.collectionspace.services.contact.ContactResource;
 import org.collectionspace.services.contact.ContactsCommon;
@@ -178,10 +180,69 @@ public class PersonAuthorityResource extends AbstractCollectionSpaceResourceImpl
         }
     }
 
+    @GET
+    @Path("urn:cspace:name({specifier})")
+    public MultipartOutput getPersonAuthorityByName(@PathParam("specifier") String specifier) {
+        String idValue = null;
+        if (specifier == null) {
+            logger.error("getPersonAuthority: missing name!");
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+                    "get failed on PersonAuthority (missing specifier)").type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        String whereClause =
+               PersonAuthorityJAXBSchema.PERSONAUTHORITIES_COMMON+
+               ":"+PersonAuthorityJAXBSchema.DISPLAY_NAME+
+               "='"+specifier+"'";
+        // We only get a single doc - if there are multiple,
+        // it is an error in use.
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getPersonAuthority with name=" + specifier);
+        } 
+        MultipartOutput result = null;
+        try {
+            ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
+            DocumentHandler handler = createDocumentHandler(ctx);
+            DocumentFilter myFilter = new DocumentFilter(whereClause, 0, 1);
+            handler.setDocumentFilter(myFilter);
+            getRepositoryClient(ctx).get(ctx, handler);
+            result = (MultipartOutput) ctx.getOutput();
+        } 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("getPersonAuthority", dnfe);
+            }
+            Response response = Response.status(Response.Status.NOT_FOUND).entity(
+                    "Get failed on PersonAuthority spec=" + specifier).type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("getPersonAuthority", 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 PersonAuthority spec:" + specifier + ": was not found.").type(
+                    "text/plain").build();
+            throw new WebApplicationException(response);
+        }
+        return result;
+    }
+
     @GET
     @Path("{csid}")
     public MultipartOutput getPersonAuthority(@PathParam("csid") String csid) {
         String idValue = null;
+        DocumentFilter myFilter = null;
         if (csid == null) {
             logger.error("getPersonAuthority: missing csid!");
             Response response = Response.status(Response.Status.BAD_REQUEST).entity(
@@ -191,7 +252,7 @@ public class PersonAuthorityResource extends AbstractCollectionSpaceResourceImpl
         }
         if (logger.isDebugEnabled()) {
             logger.debug("getPersonAuthority with path(id)=" + csid);
-        }
+        } 
         MultipartOutput result = null;
         try {
             ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
@@ -451,8 +512,7 @@ public class PersonAuthorityResource extends AbstractCollectionSpaceResourceImpl
 
             // Add the where clause "persons_common:inAuthority='" + parentcsid + "'"
             myFilter.setWhereClause(PersonJAXBSchema.PERSONS_COMMON + ":" +
-                       PersonJAXBSchema.IN_AUTHORITY +
-                       "='" + parentcsid + "'" + "AND ecm:isProxy = 0");
+                       PersonJAXBSchema.IN_AUTHORITY + "='" + parentcsid + "'");
             
             // AND persons_common:displayName LIKE '%partialTerm%'
             if (partialTerm != null && !partialTerm.isEmpty()) {