]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-481, CSPACE-590
authorPatrick Schmitz <pschmitz@berkeley.edu>
Tue, 10 Nov 2009 20:25:58 +0000 (20:25 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Tue, 10 Nov 2009 20:25:58 +0000 (20:25 +0000)
Added basic support to filter objects in a get, with a default filtering for pagination. Only implemented for Vocabulary at this point. Used this to intelligently filter the vocabularyItems associated to a given vocabulary, and to support finding a vocabulary by name.

16 files changed:
services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContext.java
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentFilter.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java
services/vocabulary/3rdparty/nuxeo-platform-cs-vocabulary/src/main/resources/OSGI-INF/layouts-contrib.xml
services/vocabulary/3rdparty/nuxeo-platform-cs-vocabulary/src/main/resources/schemas/vocabularies_common.xsd
services/vocabulary/3rdparty/nuxeo-platform-cs-vocabulary/src/main/resources/schemas/vocabularyitems_common.xsd
services/vocabulary/client/src/main/java/org/collectionspace/services/client/importer/VocabularyBaseImport.java
services/vocabulary/client/src/test/java/org/collectionspace/services/client/test/VocabularyServiceTest.java
services/vocabulary/jaxb/src/main/resources/vocabulary_common.xsd
services/vocabulary/jaxb/src/main/resources/vocabularyitem_common.xsd
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java

index aeea00ff358b902791137e5ec4bd179f1bc03a0b..83696c71094322c9c410f05987e49d340ebff701 100644 (file)
@@ -50,6 +50,8 @@ public abstract class AbstractServiceContext<T1, T2>
     private ServiceBindingType serviceBinding;
     private TenantBindingType tenantBinding;
     
+    private String overrideDocumentType = null; 
+    
     public AbstractServiceContext(String serviceName) {
         TenantBindingConfigReader tReader =
                 ServiceMain.getInstance().getTenantBindingConfigReader();
@@ -150,6 +152,19 @@ public abstract class AbstractServiceContext<T1, T2>
     @Override
     public String getServiceName() {
         return serviceBinding.getName();
+    } 
+    
+    @Override
+    public String getDocumentType() {
+       // If they have not overridden the setting, use the type of the service
+       // object.
+       return(overrideDocumentType!=null)?overrideDocumentType:
+               serviceBinding.getObject().get(0).getName();
+    }
+
+    @Override
+    public void setDocumentType(String docType) {
+       overrideDocumentType = docType;
     }
 
     @Override
index c24c261e6d974b672c41507dc3e56ba56b708a91..25147efdf2e18d97760085de65527de938760983 100644 (file)
@@ -37,7 +37,7 @@ import org.collectionspace.services.common.service.ServiceBindingType;
 public interface ServiceContext<T1, T2> {
 
     /**
-     * The charactor used to separtate the words in a part label
+     * The character used to separate the words in a part label
      */
     public static final String PART_LABEL_SEPERATOR = "_";
     public static final String PART_COMMON_LABEL = "common";
@@ -66,6 +66,20 @@ public interface ServiceContext<T1, T2> {
      */
     public String getServiceName();
 
+    /**
+     * getDocumentType returns the name of the (primary) DocumentType for this service
+     * The value defaults to the Service Name, unless overridden with setDocumentType();
+     * @return service name
+     */
+    public String getDocumentType();
+
+    /**
+     * setDocumentType sets the name of the Document Type for this service
+     * The value defaults to the Service Name.
+     * @return service name
+     */
+    public void setDocumentType(String docType);
+
     /**
      * getQualifiedServiceName returns tenant id qualified service name
      * @return tenant qualified service name
index 03a6d3d442b6cd5000bbae824ffba19be3aec5e7..15a037cd8d0becfc8a082b6753338c47e239c71c 100644 (file)
@@ -43,6 +43,7 @@ public abstract class AbstractDocumentHandler<T, TL>
 
     private final Logger logger = LoggerFactory.getLogger(AbstractDocumentHandler.class);
     private Map<String, Object> properties = new HashMap<String, Object>();
+    private DocumentFilter docFilter = new DocumentFilter();
     private ServiceContext serviceContext;
 
     public AbstractDocumentHandler() {
@@ -74,6 +75,22 @@ public abstract class AbstractDocumentHandler<T, TL>
         this.properties = properties;
     }
 
+    /**
+     * @return the DocumentFilter
+     */
+    @Override
+    public DocumentFilter getDocumentFilter() {
+        return docFilter;
+    }
+
+    /**
+     * @param properties the DocumentFilter to set
+     */
+    @Override
+    public void setDocumentFilter(DocumentFilter docFilter) {
+        this.docFilter = docFilter;
+    }
+
     @Override
     public void prepare(Action action) throws Exception {
         //no specific action needed
diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentFilter.java b/services/common/src/main/java/org/collectionspace/services/common/repository/DocumentFilter.java
new file mode 100644 (file)
index 0000000..4d65e58
--- /dev/null
@@ -0,0 +1,107 @@
+/**\r
+ *  This document is a part of the source code and related artifacts\r
+ *  for CollectionSpace, an open source collections management system\r
+ *  for museums and related institutions:\r
+\r
+ *  http://www.collectionspace.org\r
+ *  http://wiki.collectionspace.org\r
+\r
+ *  Copyright 2009 University of California at Berkeley\r
+\r
+ *  Licensed under the Educational Community License (ECL), Version 2.0.\r
+ *  You may not use this file except in compliance with this License.\r
+\r
+ *  You may obtain a copy of the ECL 2.0 License at\r
+\r
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
+ */\r
+package org.collectionspace.services.common.repository;\r
+\r
+/**\r
+ * DocumentFilter bundles simple query filtering parameters. \r
+ * It is designed to be used with filtered get and search calls to RepositoryClient.\r
+ * The values are set up and stored on a DocumentHandler, and\r
+ * fetched by a RepositoryClient when calling filtered get methods.\r
+ */\r
+public class DocumentFilter {\r
+       public static final int DEFAULT_PAGE_SIZE_INIT = 40;\r
+       public static int defaultPageSize = DEFAULT_PAGE_SIZE_INIT;\r
+       protected String whereClause;   // Filtering clause. Omit the "WHERE".\r
+       protected int startPage;                // Pagination offset for list results\r
+       protected int pageSize;                 // Pagination limit for list results\r
+\r
+       public DocumentFilter() {\r
+               this("", 0, defaultPageSize);                   // Use empty string for easy concatenation\r
+       }\r
+       \r
+       public DocumentFilter(String whereClause, int startPage, int pageSize) {\r
+               this.whereClause = whereClause;\r
+               this.startPage = (startPage>0)?startPage:0;\r
+               this.pageSize = (pageSize>0)?pageSize:defaultPageSize;\r
+       }\r
+       \r
+       /**\r
+        * @return the current default page size for new DocumentFilter instances\r
+        */\r
+       public static int getDefaultPageSize() {\r
+               return defaultPageSize;\r
+       }\r
+\r
+       /**\r
+        * @param defaultPageSize the working default page size for new DocumentFilter instances\r
+        */\r
+       public static void setDefaultPageSize(int defaultPageSize) {\r
+               DocumentFilter.defaultPageSize = defaultPageSize;\r
+       }\r
+\r
+       /**\r
+        * @return the WHERE filtering clause\r
+        */\r
+       public String getWhereClause() {\r
+               return whereClause;\r
+       }\r
+\r
+       /**\r
+        * @param whereClause the filtering clause (do not include "WHERE")\r
+        */\r
+       public void setWhereClause(String whereClause) {\r
+               this.whereClause = whereClause;\r
+       }\r
+       \r
+       /**\r
+        * @return the specified (0-based) page offset  \r
+        */\r
+       public int getStartPage() {\r
+               return startPage;\r
+       }\r
+       \r
+       /**\r
+        * @param startPage the (0-based) page offset to use\r
+        */\r
+       public void setStartPage(int startPage) {\r
+               this.startPage = startPage;\r
+       }\r
+       \r
+       /**\r
+        * @return the max number of items to return for list requests\r
+        */\r
+       public int getPageSize() {\r
+               return pageSize;\r
+       }\r
+\r
+       /**\r
+        * @param pageSize the max number of items to return for list requests\r
+        */\r
+       public void setPageSize(int pageSize) {\r
+               this.pageSize = pageSize;\r
+       }\r
+\r
+       /**\r
+        * @return the offset computed from the startPage and the pageSize\r
+        */\r
+       public int getOffset() {\r
+               return pageSize*startPage;\r
+       }\r
+\r
+\r
+}\r
index 50774375a67a7366c2be6ad7f9add5c691544b90..31aa51442504a7187d61f4ec185675aa7493e1e7 100644 (file)
@@ -199,6 +199,19 @@ public interface DocumentHandler<T, TL> {
      */
     public void setProperties(Map<String, Object> properties);
 
+    /**
+     * getDocumentFilter
+     * @return
+     */
+    public DocumentFilter getDocumentFilter();
+
+    /**
+     * setDocumentFilter provides means to the CollectionSpace service resource to
+     * set up DocumentFilter values before invoking any request via the client.
+     * @param docFilter
+     */
+    public void setDocumentFilter(DocumentFilter docFilter);
+
     /**
      * getCommonPart provides the common part of a CS object.
      * @return common part of CS object
index f186d27438bb9175bcc595938d1daefbbdc78141..1e70ddbf8bd12b0cfc60844eab0329b0491d448d 100644 (file)
@@ -67,7 +67,7 @@ public interface RepositoryClient {
     void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
 
     /**
-     * getAll get all documents for an entity entity service from the Document repository
+     * getAll get all documents for an entity service from the Document repository
      * @param ctx service context under which this method is invoked
      * @param handler should be used by the caller to provide and transform the document
      * @throws DocumentNotFoundException if workspace not found
@@ -75,6 +75,16 @@ public interface RepositoryClient {
      */
     void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
 
+    /**
+     * getFiltered get all documents for an entity service from the Document repository,
+     * given filter parameters specified by the handler. 
+     * @param ctx service context under which this method is invoked
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentNotFoundException if workspace not found
+     * @throws DocumentException
+     */
+    void getFiltered(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
     /**
      * update given document in the Document repository
      * @param ctx service context under which this method is invoked
index d48d06ae0efbd3c4db4defa597e53aef4f9cf3a2..c03eabaa9a7e37a6a3f4473a375ad3e7f7978ed6 100644 (file)
@@ -19,12 +19,14 @@ package org.collectionspace.services.nuxeo.client.java;
 
 
 import java.util.UUID;
-import org.collectionspace.services.common.repository.RepositoryClient;
+
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.repository.BadRequestException;
-import org.collectionspace.services.common.repository.DocumentNotFoundException;
-import org.collectionspace.services.common.repository.DocumentHandler;
 import org.collectionspace.services.common.repository.DocumentException;
+import org.collectionspace.services.common.repository.DocumentFilter;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.repository.DocumentHandler.Action;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.nuxeo.common.utils.IdUtils;
@@ -220,6 +222,66 @@ public class RepositoryJavaClient implements RepositoryClient {
             }
         }
     }
+    
+    /**
+     * getFiltered get all documents for an entity service from the Document repository,
+     * given filter parameters specified by the handler. 
+     * @param ctx service context under which this method is invoked
+     * @param handler should be used by the caller to provide and transform the document
+     * @throws DocumentNotFoundException if workspace not found
+     * @throws DocumentException
+     */
+    public void getFiltered(ServiceContext ctx, DocumentHandler handler) 
+       throws DocumentNotFoundException, DocumentException {
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "RemoteRepositoryClient.getFiltered: handler is missing");
+        }
+        DocumentFilter docFilter = handler.getDocumentFilter();
+        if (docFilter == null) {
+            throw new IllegalArgumentException(
+                    "RemoteRepositoryClient.getFiltered: handler has no Filter specified");
+        }
+        String docType = ctx.getDocumentType();
+        if (docType == null) {
+            throw new DocumentNotFoundException(
+                    "Unable to find DocumentType for service " + ctx.getServiceName());
+        }
+        RepositoryInstance repoSession = null;
+        try {
+            handler.prepare(Action.GET_ALL);
+            repoSession = getRepositorySession();
+            StringBuilder query = new StringBuilder("SELECT * FROM ");
+            query.append(docType);
+            String where = docFilter.getWhereClause(); 
+            if((null!=where)&&(where.length()>0))
+               query.append(" WHERE "+where);
+            if(docFilter.getOffset()>0)
+               query.append(" OFFSET "+docFilter.getOffset());
+            if(docFilter.getPageSize()>0)
+               query.append(" LIMIT "+docFilter.getPageSize());
+            DocumentModelList docList = repoSession.query(query.toString());
+            //set repoSession to handle the document
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
+                    docList);
+            handler.handle(Action.GET_ALL, wrapDoc);
+            handler.complete(Action.GET_ALL, wrapDoc);
+        } 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);
+            }
+        }
+    }
+
+    
 
     /**
      * update given document in the Nuxeo repository
index 87fa5ccb50b5e01b626e102cb1581acaeee0a236..9d65eda57ea10dbcf76844ac6d83d38a17dd1fca 100644 (file)
       </templates>
       <rows>
         <row><widget>displayName</widget></row>
+        <row><widget>refName</widget></row>
         <row><widget>vocabType</widget></row>
       </rows>
 
       <widget name="displayName" type="text">
         <labels>
-          <label mode="any">Name</label>
+          <label mode="any">Display Name</label>
         </labels>
         <translated>true</translated>
         <fields>
         </properties>
       </widget>
       
+      <widget name="refName" type="text">
+        <labels>
+          <label mode="any">RefName</label>
+        </labels>
+        <translated>true</translated>
+        <fields>
+          <field schema="vocabularies_common">refName</field>
+        </fields>
+        <properties widgetMode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      
       <widget name="vocabType" type="text">
         <labels>
           <label mode="any">Type</label>
       </templates>
       <rows>
         <row><widget>displayName</widget></row>
+        <row><widget>refName</widget></row>
         <row><widget>inVocabulary</widget></row>
       </rows>
 
       <widget name="displayName" type="text">
         <labels>
-          <label mode="any">Name</label>
+          <label mode="any">Display Name</label>
         </labels>
         <translated>true</translated>
         <fields>
         </properties>
       </widget>
       
+      <widget name="refName" type="text">
+        <labels>
+          <label mode="any">RefName</label>
+        </labels>
+        <translated>true</translated>
+        <fields>
+          <field schema="vocabularyitems_common">refName</field>
+        </fields>
+        <properties widgetMode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      
       <widget name="inVocabulary" type="text">
         <labels>
           <label mode="any">Vocab</label>
index 6cb8986a6e974a9c2f552247fdd3c51b3c946eb4..9e646713fe2f78b9c6f5de670bd3e090660b7a9c 100644 (file)
@@ -24,6 +24,7 @@
 
                <!--  Vocabulary Information Group -->
                <xs:element name="displayName" type="xs:string"/>
+               <xs:element name="refName" type="xs:string"/>
                <xs:element name="vocabType" type="xs:string"/>
 
 </xs:schema>
index 3720b9b0cb649bd846d7c9178b2dc1a81e4aa972..772b0b43236ca62b25349b09fd85068daec7cff6 100644 (file)
@@ -7,8 +7,8 @@
     Part    : Common
     Used for: Nuxeo EP core document type
     
-    $LastChangedRevision$
-    $LastChangedDate$
+    $LastChangedRevision: 860 $
+    $LastChangedDate: 2009-10-14 14:48:05 -0700 (Wed, 14 Oct 2009) $
 -->
 
 <xs:schema 
@@ -23,6 +23,7 @@
                <!--  VocabularyItem Information Group -->
                <!--  inVocabulary is the csid of the owning Vocabulary -->
                <xs:element name="inVocabulary" type="xs:string" />
+               <xs:element name="refName" type="xs:string"/>
                <xs:element name="displayName" type="xs:string"/>
 
 </xs:schema>
index 9befe6b01e3923770827837408c3e79ca26f9e19..bcc5f5fe450e1df753ea09b4d88a99116e2a2b19 100644 (file)
@@ -60,74 +60,77 @@ public class VocabularyBaseImport {
 
     public void createEnumeration(String vocabName, List<String> enumValues ) {
 
-        // Expected status code: 201 Created
-        int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
-        // Type of service request being tested
-        ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE;
-
-        if(logger.isDebugEnabled()){
-            logger.debug("Import: Create vocabulary: \"" + vocabName +"\"");
-                               }
-        MultipartOutput multipart = createVocabularyInstance(vocabName, "enum");
-        ClientResponse<Response> res = client.create(multipart);
-
-        int statusCode = res.getStatus();
-
-        if(!REQUEST_TYPE.isValidStatusCode(statusCode)) {
-                                       throw new RuntimeException("Could not create enumeration: \""+vocabName
-                                                       +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-                               }
-        if(statusCode != EXPECTED_STATUS_CODE) {
-                                       throw new RuntimeException("Unexpected Status when creating enumeration: \""
-                                                       +vocabName +"\", Status:"+ statusCode);
-                               }
-
-        // Store the ID returned from this create operation
-        // for additional tests below.
-        String newVocabId = extractId(res);
-        if(logger.isDebugEnabled()){
-            logger.debug("Import: Created vocabulary: \"" + vocabName +"\" ID:"
-                                                               +newVocabId );
-                               }
-                               for(String itemName : enumValues){
-                                       createItemInVocab(newVocabId, vocabName, itemName);
-                               }
+       // Expected status code: 201 Created
+       int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
+       // Type of service request being tested
+       ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE;
+
+       if(logger.isDebugEnabled()){
+               logger.debug("Import: Create vocabulary: \"" + vocabName +"\"");
+       }
+       MultipartOutput multipart = createVocabularyInstance(vocabName, 
+                       createRefName(vocabName), "enum");
+       ClientResponse<Response> res = client.create(multipart);
+
+       int statusCode = res.getStatus();
+
+       if(!REQUEST_TYPE.isValidStatusCode(statusCode)) {
+               throw new RuntimeException("Could not create enumeration: \""+vocabName
+                               +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+       }
+       if(statusCode != EXPECTED_STATUS_CODE) {
+               throw new RuntimeException("Unexpected Status when creating enumeration: \""
+                               +vocabName +"\", Status:"+ statusCode);
+       }
+
+       // Store the ID returned from this create operation
+       // for additional tests below.
+       String newVocabId = extractId(res);
+       if(logger.isDebugEnabled()){
+               logger.debug("Import: Created vocabulary: \"" + vocabName +"\" ID:"
+                               +newVocabId );
+       }
+       for(String itemName : enumValues){
+               createItemInVocab(newVocabId, vocabName, itemName, createRefName(itemName));
+       }
     }
     
-    private String createItemInVocab(String vcsid, String vocabName, String itemName) {
-        // Expected status code: 201 Created
-        int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
-        // Type of service request being tested
-        ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE;
-
-        if(logger.isDebugEnabled()){
-            logger.debug("Import: Create Item: \""+itemName+"\" in vocabulary: \"" + vocabName +"\"");
-                               }
-        MultipartOutput multipart = createVocabularyItemInstance(vcsid, itemName);
-        ClientResponse<Response> res = client.createItem(vcsid, multipart);
-
-        int statusCode = res.getStatus();
-
-        if(!REQUEST_TYPE.isValidStatusCode(statusCode)) {
-                                       throw new RuntimeException("Could not create Item: \""+itemName
-                                                       +"\" in vocabulary: \"" + vocabName
-                                                       +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-                               }
-        if(statusCode != EXPECTED_STATUS_CODE) {
-                                       throw new RuntimeException("Unexpected Status when creating Item: \""+itemName
-                                                       +"\" in vocabulary: \"" + vocabName +"\", Status:"+ statusCode);
-                               }
-
-        return extractId(res);
+    private String createItemInVocab(String vcsid, String vocabName, String itemName, String refName) {
+       // Expected status code: 201 Created
+       int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
+       // Type of service request being tested
+       ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE;
+
+       if(logger.isDebugEnabled()){
+               logger.debug("Import: Create Item: \""+itemName+"\" in vocabulary: \"" + vocabName +"\"");
+       }
+       MultipartOutput multipart = createVocabularyItemInstance(vcsid, itemName, refName);
+       ClientResponse<Response> res = client.createItem(vcsid, multipart);
+
+       int statusCode = res.getStatus();
+
+       if(!REQUEST_TYPE.isValidStatusCode(statusCode)) {
+               throw new RuntimeException("Could not create Item: \""+itemName
+                               +"\" in vocabulary: \"" + vocabName
+                               +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+       }
+       if(statusCode != EXPECTED_STATUS_CODE) {
+               throw new RuntimeException("Unexpected Status when creating Item: \""+itemName
+                               +"\" in vocabulary: \"" + vocabName +"\", Status:"+ statusCode);
+       }
+
+       return extractId(res);
     }
 
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
 
-    private MultipartOutput createVocabularyInstance(String displayName, String vocabType) {
+    private MultipartOutput createVocabularyInstance(
+               String displayName, String refName, String vocabType) {
         VocabulariesCommon vocabulary = new VocabulariesCommon();
         vocabulary.setDisplayName(displayName);
+        vocabulary.setRefName(refName);
         vocabulary.setVocabType(vocabType);
         MultipartOutput multipart = new MultipartOutput();
         OutputPart commonPart = multipart.addPart(vocabulary, MediaType.APPLICATION_XML_TYPE);
@@ -141,10 +144,12 @@ public class VocabularyBaseImport {
         return multipart;
     }
 
-    private MultipartOutput createVocabularyItemInstance(String inVocabulary, String displayName) {
+    private MultipartOutput createVocabularyItemInstance(
+               String inVocabulary, String displayName, String refName) {
        VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon();
        vocabularyItem.setInVocabulary(inVocabulary);
        vocabularyItem.setDisplayName(displayName);
+       vocabularyItem.setRefName(refName);
         MultipartOutput multipart = new MultipartOutput();
         OutputPart commonPart = multipart.addPart(vocabularyItem, MediaType.APPLICATION_XML_TYPE);
         commonPart.getHeaders().add("label", client.getItemCommonPartName());
@@ -187,6 +192,10 @@ public class VocabularyBaseImport {
         }
         return id;
     }
+    
+    protected String createRefName(String displayName) {
+       return displayName.replaceAll("\\W", "");
+    }
 
        public static void main(String[] args) {
                
index e4ed30d63ef2a605fee0fa249dd1a80c82b4f4ff..6da36afc06f16bd27186554032c9356d4614f14a 100644 (file)
@@ -58,7 +58,12 @@ public class VocabularyServiceTest extends AbstractServiceTest {
     final String SERVICE_PATH_COMPONENT = "vocabularies";
     final String ITEM_SERVICE_PATH_COMPONENT = "items";
     private String knownResourceId = null;
+    private String knownResourceRefName = null;
     private String knownItemResourceId = null;
+    
+    protected String createRefName(String displayName) {
+       return displayName.replaceAll("\\W", "");
+    }    
 
     // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
@@ -75,7 +80,11 @@ public class VocabularyServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
-        MultipartOutput multipart = createVocabularyInstance(identifier);
+        String displayName = "displayName-" + identifier;
+       String refName = createRefName(displayName);
+       String typeName = "vocabType-" + identifier;
+       MultipartOutput multipart = 
+               createVocabularyInstance(displayName, refName, typeName);
         ClientResponse<Response> res = client.create(multipart);
         int statusCode = res.getStatus();
 
@@ -95,6 +104,7 @@ public class VocabularyServiceTest extends AbstractServiceTest {
         // Store the ID returned from this create operation
         // for additional tests below.
         knownResourceId = extractId(res);
+        knownResourceRefName = refName;
         if(logger.isDebugEnabled()){
             logger.debug("create: knownResourceId=" + knownResourceId);
         }
@@ -120,7 +130,8 @@ public class VocabularyServiceTest extends AbstractServiceTest {
 
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
-        MultipartOutput multipart = createVocabularyItemInstance(vcsid, identifier);
+        String refName = createRefName(identifier);
+        MultipartOutput multipart = createVocabularyItemInstance(vcsid, identifier, refName);
         ClientResponse<Response> res = client.createItem(vcsid, multipart);
         int statusCode = res.getStatus();
 
@@ -279,6 +290,38 @@ public class VocabularyServiceTest extends AbstractServiceTest {
         }
     }
 
+    /*
+    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
+            dependsOnMethods = {"read"})
+        public void readByName(String testName) throws Exception {
+
+            // Perform setup.
+            setupRead();
+
+            // Submit the request to the service and store the response.
+            ClientResponse<MultipartInput> res = client.read(knownResourceId);
+            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();
+                VocabulariesCommon vocabulary = (VocabulariesCommon) extractPart(input,
+                        client.getCommonPartName(), VocabulariesCommon.class);
+                Assert.assertNotNull(vocabulary);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    */
+
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
         dependsOnMethods = {"createItem", "read"})
     public void readItem(String testName) throws Exception {
@@ -704,7 +747,8 @@ public class VocabularyServiceTest extends AbstractServiceTest {
         // The only relevant ID may be the one used in update(), below.
 
         // The only relevant ID may be the one used in update(), below.
-        MultipartOutput multipart = createVocabularyItemInstance(knownResourceId, NON_EXISTENT_ID);
+        MultipartOutput multipart = createVocabularyItemInstance(
+                       knownResourceId, NON_EXISTENT_ID, createRefName(NON_EXISTENT_ID));
         ClientResponse<MultipartInput> res =
                 client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
         int statusCode = res.getStatus();
@@ -898,14 +942,19 @@ public class VocabularyServiceTest extends AbstractServiceTest {
     }
 
     private MultipartOutput createVocabularyInstance(String identifier) {
+       String displayName = "displayName-" + identifier;
+       String refName = createRefName(displayName);
+       String typeName = "vocabType-" + identifier;
         return createVocabularyInstance(
-                "displayName-" + identifier,
-                "vocabType-" + identifier);
+                displayName, refName,typeName );
     }
 
-    private MultipartOutput createVocabularyInstance(String displayName, String vocabType) {
+    private MultipartOutput createVocabularyInstance(
+               String displayName, String refName, String vocabType) {
         VocabulariesCommon vocabulary = new VocabulariesCommon();
         vocabulary.setDisplayName(displayName);
+        if(refName!=null)
+            vocabulary.setRefName(refName);
         vocabulary.setVocabType(vocabType);
         MultipartOutput multipart = new MultipartOutput();
         OutputPart commonPart = multipart.addPart(vocabulary, MediaType.APPLICATION_XML_TYPE);
@@ -919,10 +968,12 @@ public class VocabularyServiceTest extends AbstractServiceTest {
     }
 
     private MultipartOutput createVocabularyItemInstance(String inVocabulary,
-        String displayName) {
+        String displayName, String refName) {
         VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon();
         vocabularyItem.setInVocabulary(inVocabulary);
         vocabularyItem.setDisplayName(displayName);
+        if(refName!=null)
+               vocabularyItem.setRefName(refName);
         MultipartOutput multipart = new MultipartOutput();
         OutputPart commonPart = multipart.addPart(vocabularyItem,
             MediaType.APPLICATION_XML_TYPE);
index 90144b6ca51beb8232bc41f1519f7477ea7b844a..539f589cc01d8413e54f862ec46727824b3ff5d9 100644 (file)
@@ -34,6 +34,7 @@
                 
                 <!--  Vocabulary Information Group -->
                 <xs:element name="displayName" type="xs:string"/>
+                <xs:element name="refName" type="xs:string"/>
                 <xs:element name="vocabType" type="xs:string"/>
 
             </xs:sequence>
index 9b62ae270a416e5407d03f3ce1b640f10986dbe9..cd2a95ee6ecaa0a578c46517cff9b6b23078ab87 100644 (file)
@@ -22,6 +22,7 @@
                 <!--  inVocabulary is the csid of the owning Vocabulary -->
                 <xs:element name="inVocabulary" type="xs:string" />
                 <xs:element name="displayName" type="xs:string"/>
+                <xs:element name="refName" type="xs:string"/>
 
             </xs:sequence>
         </xs:complexType>
index f0ea4e94bb88b72f3d7233645d763347a1ea01ca..a210df869ff2d82b5f0623a960fbfdb765b885c3 100644 (file)
@@ -23,6 +23,9 @@
  */
 package org.collectionspace.services.vocabulary;
 
+import java.util.List;
+import java.util.Map;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -31,8 +34,10 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
@@ -42,6 +47,7 @@ import org.collectionspace.services.common.ClientType;
 import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.context.RemoteServiceContext;
 import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.repository.DocumentFilter;
 import org.collectionspace.services.common.repository.DocumentHandler;
 import org.collectionspace.services.common.repository.DocumentNotFoundException;
 import org.collectionspace.services.vocabulary.nuxeo.VocabularyHandlerFactory;
@@ -50,6 +56,8 @@ import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemHandlerFactor
 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
 import org.jboss.resteasy.util.HttpResponseCodes;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.nuxeo.ecm.core.client.NuxeoClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -139,23 +147,23 @@ public class VocabularyResource extends AbstractCollectionSpaceResource {
 
     @GET
     @Path("{csid}")
-    public MultipartOutput getVocabulary(
-            @PathParam("csid") String csid) {
-        if(logger.isDebugEnabled()){
-            logger.debug("getVocabulary with csid=" + csid);
-        }
-        if(csid == null || "".equals(csid)){
+    public MultipartOutput getVocabulary(@PathParam("csid") String csid) {
+       String idValue = null;
+       if(csid == null){
             logger.error("getVocabulary: missing csid!");
             Response response = Response.status(Response.Status.BAD_REQUEST).entity(
                     "get failed on Vocabulary csid=" + csid).type(
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
+        if(logger.isDebugEnabled()){
+            logger.debug("getVocabulary with path(id)=" + csid);
+        }
         MultipartOutput result = null;
         try{
             RemoteServiceContext ctx = createServiceContext(null);
             DocumentHandler handler = createDocumentHandler(ctx);
-            getRepositoryClient(ctx).get(ctx, csid, handler);
+               getRepositoryClient(ctx).get(ctx, csid, handler);
             result = ctx.getOutput();
         }catch(DocumentNotFoundException dnfe){
             if(logger.isDebugEnabled()){
@@ -189,7 +197,16 @@ public class VocabularyResource extends AbstractCollectionSpaceResource {
         try{
             RemoteServiceContext ctx = createServiceContext(null);
             DocumentHandler handler = createDocumentHandler(ctx);
-            getRepositoryClient(ctx).getAll(ctx, handler);
+            MultivaluedMap<String,String> queryParams = ui.getQueryParameters(); 
+            if(queryParams.size()>0) {
+               String nameQ = queryParams.getFirst("name");
+               if(nameQ!= null) {
+                    DocumentFilter myFilter = new DocumentFilter(
+                                "vocabularies_common:refName='"+nameQ+"'", 0, 0);
+                    handler.setDocumentFilter(myFilter);
+               }
+            }
+            getRepositoryClient(ctx).getFiltered(ctx, handler);
             vocabularyObjectList = (VocabulariesCommonList) handler.getCommonPartList();
         }catch(Exception e){
             if(logger.isDebugEnabled()){
@@ -361,14 +378,34 @@ public class VocabularyResource extends AbstractCollectionSpaceResource {
                 @PathParam("csid") String parentcsid,
                 @Context UriInfo ui) {
          VocabularyitemsCommonList vocabularyItemObjectList = new VocabularyitemsCommonList();
+         RepositoryInstance repoSession = null;
+         NuxeoClient client = null;
          try{
-                // Note that we have to create the service context for the Items, not the main service 
+                // Note that docType defaults to the ServiceName, so we're fine with that.
              RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
              DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
-             // HACK This should be a search with the parentcsid. The 
-             // handler.getCommonPartList method will filter these for us, 
-             // which is really silly, but works for now.
-             getRepositoryClient(ctx).getAll(ctx, handler);
+             /*
+             // Note that we replace the getAll() call with a basic search on the parent vocab
+             handler.prepare(Action.GET_ALL);
+                client = NuxeoConnector.getInstance().getClient();
+             repoSession = client.openRepository();
+             if (logger.isDebugEnabled()) {
+                 logger.debug("getVocabularyItemList() repository root: " + repoSession.getRootDocument());
+             }
+             DocumentModelList docList = 
+                repoSession.query("SELECT * FROM Vocabularyitem WHERE vocabularyitems_common:inVocabulary='"
+                                                       +parentcsid+"'");
+             //set repoSession to handle the document
+             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+             DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
+                     docList);
+             handler.handle(Action.GET_ALL, wrapDoc);
+             handler.complete(Action.GET_ALL, wrapDoc);
+             */
+             DocumentFilter myFilter = new DocumentFilter(
+                        "vocabularyitems_common:inVocabulary='"+parentcsid+"'", 0, 0);
+             handler.setDocumentFilter(myFilter);
+             getRepositoryClient(ctx).getFiltered(ctx, handler);
              vocabularyItemObjectList = (VocabularyitemsCommonList) handler.getCommonPartList();
          }catch(Exception e){
              if(logger.isDebugEnabled()){
@@ -377,6 +414,16 @@ public class VocabularyResource extends AbstractCollectionSpaceResource {
              Response response = Response.status(
                      Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
              throw new WebApplicationException(response);
+         } finally {
+             if(repoSession != null) {
+                    try {
+                        // release session
+                        client.releaseRepository(repoSession);
+                    } catch (Exception e) {
+                        logger.error("Could not close the repository session", e);
+                        // no need to throw this service specific exception
+                    }
+             }
          }
          return vocabularyItemObjectList;
      }
index c5be87a31cfa501bb7594699c37aedbe54a90c10..371ea783271e9534767c2f69663a49047d91a1c6 100644 (file)
@@ -135,10 +135,10 @@ public class VocabularyItemDocumentModelHandler
                Iterator<DocumentModel> iter = docList.iterator();
                while(iter.hasNext()){
                    DocumentModel docModel = iter.next();
-                   String parentVocab = (String)docModel.getProperty(getServiceContext().getCommonPartLabel("vocabularyItems"),
-                           VocabularyItemJAXBSchema.IN_VOCABULARY); 
-                   if( !inVocabulary.equals(parentVocab))
-                       continue;
+                   //String parentVocab = (String)docModel.getProperty(getServiceContext().getCommonPartLabel("vocabularyItems"),
+                   //       VocabularyItemJAXBSchema.IN_VOCABULARY); 
+                   //if( !inVocabulary.equals(parentVocab))
+                   //  continue;
                    VocabularyitemListItem ilistItem = new VocabularyitemListItem();
                    ilistItem.setDisplayName((String) docModel.getProperty(getServiceContext().getCommonPartLabel("vocabularyItems"),
                            VocabularyItemJAXBSchema.DISPLAY_NAME));