]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-6000: Allow adding one or more asterisks as wildcard characters anywhere in...
authorAron Roberts <aron@socrates.berkeley.edu>
Fri, 10 May 2013 02:05:21 +0000 (19:05 -0700)
committerAron Roberts <aron@socrates.berkeley.edu>
Fri, 10 May 2013 02:05:21 +0000 (19:05 -0700)
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/authority.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/locationitem.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/personitem.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/res/locationItems.res.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/res/locationItemsWithShortID.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/res/locationItemsContainingWord1.res.xml with 72% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authority/res/personItems.res.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/xml-replay-master.xml
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java

index 63dbbb1ac9dbbd7ff47a5e9451333bf83f96e16a..eef0603a6a977b5ab25fefd0462a43cf8be257d8 100644 (file)
@@ -12,7 +12,7 @@
             Create three new vocabularies: two in the Person Authority,
             and one in the Storage Location Authority.
        
-       -->
+        -->
         <test ID="createPersonAuthority1">
             <expectedCodes>201</expectedCodes>
             <method>POST</method>
                 <!-- names, and to populate text field(s). -->
                 <var ID="word1">jlmbsoq</var>
                 <var ID="word2">tqbfjotld</var>
+                <var ID="word3">mepqcgjt</var>
+                <var ID="word4">fqgtmjb</var>
+                <var ID="word5">brvffaqj</var>
                 <!-- Partial term searches using one or more of those words. -->
                 <var ID="word1PartialTermStem">jlmb</var>
                 <var ID="word2PartialTermStem">tqbf</var>
                 <var ID="word2PartialTermMid">fjotl</var>
                 <!-- Populate the current record with those words. -->
-                <var ID="authDisplayName">${word1}auth1</var>
-                <var ID="authShortIdentifier">${word1}auth2</var>
+                <var ID="authDisplayName">jlmbsoqauth1</var>
+                <var ID="authShortIdentifier">jlmbsoqauth2</var>
             </vars>
         </test>
         <test ID="createPersonAuthority2">
@@ -65,7 +68,8 @@
             <vars>
                 <var ID="itemDisplayName">${createPersonAuthority1.word2} ${createPersonAuthority1.word1}</var>
                 <var ID="itemShortIdentifier">${createPersonAuthority1.word1}item1</var>
-           </vars>
+                <var ID="itemBioNote">A bio note for this Person.</var>
+            </vars>
         </test>
         <test ID="createPersonItem2">
             <expectedCodes>201</expectedCodes>
@@ -90,8 +94,8 @@
             </vars>
         </test>
                 
-        <!-- Create one item in a vocabulary in the Location Authority -->
-        <test ID="createLocationItem">
+        <!-- Create two items in a vocabulary in the Location Authority -->
+        <test ID="createLocationItem1">
             <expectedCodes>201</expectedCodes>
             <method>POST</method>
             <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items</uri>
                 <var ID="itemShortIdentifier">${createPersonAuthority1.word1}item1</var>
             </vars>
         </test>
-        <test ID="verifyLocationItem">
+        <test ID="verifyLocationItem1">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items/${createLocationItem.CSID}</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items/${createLocationItem1.CSID}</uri>
+        </test>
+        <test ID="createLocationItem2">
+            <expectedCodes>201</expectedCodes>
+            <method>POST</method>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items</uri>
+            <filename>authority/locationitem.xml</filename>
+            <vars>
+                <var ID="itemDisplayName">${createPersonAuthority1.word3} ${createPersonAuthority1.word4} ${createPersonAuthority1.word5}</var>
+                <var ID="itemShortIdentifier">${createPersonAuthority1.word3}item2</var>
+            </vars>
+        </test>
+        <test ID="verifyLocationItem2">
+            <expectedCodes>200</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items/${createLocationItem2.CSID}</uri>
         </test>
         
         <!--
-            Perform 'all vocabularies' searches and verify that the
-            expected items were returned by each search.
+            Perform 'all vocabularies' searches and searches in each vocabulary,
+            and verify that the expected items were returned by each search.
         -->
         
         <!-- List (without searching) -->
         
-        <test ID="getPersonItems">
+        <test ID="getPersonItemsAllVocabs">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
             <uri>/cspace-services/personauthorities/_ALL_/items?pgSz=3&amp;pgNum=0</uri>
             <response>
                 <expected level="TEXT"/>
                 <filename>authority/res/personItems.res.xml</filename>
+                <vars>
+                    <var ID="numItems">3</var>
+                </vars>
+            </response>
+        </test>
+        <test ID="getPersonItemsVocab1">
+            <expectedCodes>200</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/personauthorities/${createPersonAuthority1.CSID}/items?pgSz=2&amp;pgNum=0</uri>
+            <response>
+                <expected level="TEXT"/>
+                <filename>authority/res/personItems.res.xml</filename>
+                <vars>
+                    <var ID="numItems">2</var>
+                </vars>
+            </response>
+        </test>
+        <test ID="getPersonItemsVocab2">
+            <expectedCodes>200</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/personauthorities/${createPersonAuthority1.CSID}/items?pgSz=1&amp;pgNum=0</uri>
+            <response>
+                <expected level="TEXT"/>
+                <filename>authority/res/personItems.res.xml</filename>
+                <vars>
+                    <var ID="numItems">1</var>
+                </vars>
             </response>
         </test>
         
+        <!-- Perform a variety of searches across all person vocabularies -->
+                
         <!-- Keyword searches -->
         
         <!-- On first word -->
                 <filename>authority/res/personItemsContainingWord2.res.xml</filename>
             </response>
         </test>
-                
-        <!-- Advanced search -->
+        
+        <!-- Advanced searches -->
         
         <!-- On first word -->
         <test ID="advSearchPersonItems1">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/personauthorities/_ALL_/items?as=persons_common%3AdisplayName%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
+            <uri>/cspace-services/personauthorities/_ALL_/items?as=persons_common%3ApersonTermGroupList%2F*%2FtermDisplayName%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
             <response>
                 <expected level="TEXT"/>
                 <filename>authority/res/personItemsContainingWord1.res.xml</filename>
         <test ID="advSearchPersonItems2">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/personauthorities/_ALL_/items?as=persons_common%3AdisplayName%20ILIKE%20%27%25${createPersonAuthority1.word2}%25%27</uri>
+            <uri>/cspace-services/personauthorities/_ALL_/items?as=persons_common%3ApersonTermGroupList%2F*%2FtermDisplayName%20ILIKE%20%27%25${createPersonAuthority1.word2}%25%27</uri>
             <response>
                 <expected level="TEXT"/>
                 <filename>authority/res/personItemsContainingWord2.res.xml</filename>
             </response>
         </test>
-        <!-- In a field other than display name -->
-        <test ID="advSearchPersonItems3">
+        
+        <!-- Verify that tests work in an authority other than Person Authority -->
+        
+        <test ID="getLocationItemsAllVocabs">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/personauthorities/_ALL_/items?as=persons_common%3AforeName%20ILIKE%20%27%25${createPersonAuthority1.word2}%25%27</uri>
+            <uri>/cspace-services/locationauthorities/_ALL_/items?pgSz=2&amp;pgNum=0</uri>
             <response>
                 <expected level="TEXT"/>
-                <filename>authority/res/personItemsContainingWord2.res.xml</filename>
+                <filename>authority/res/locationItems.res.xml</filename>
+                <vars>
+                    <var ID="numItems">2</var>
+                </vars>
             </response>
         </test>
-        
-        <!-- Verify that tests work in an authority other than Person Authority -->
-        
-        <test ID="getLocationItems">
+        <test ID="getLocationItemsSingleVocab">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/_ALL_/items?pgSz=1&amp;pgNum=0</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items?pgSz=2&amp;pgNum=0</uri>
             <response>
                 <expected level="TEXT"/>
                 <filename>authority/res/locationItems.res.xml</filename>
+                <vars>
+                    <var ID="numItems">2</var>
+                </vars>
             </response>
         </test>
+        
+        <!-- Perform a variety of searches within a single storage location vocabulary -->
+
+        <!-- Keyword search -->
         <test ID="kwSearchLocationItems">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/_ALL_/items?kw=${createPersonAuthority1.word1}</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items?kw=${createPersonAuthority1.word1}</uri>
             <response>
                 <expected level="TEXT"/>
-                <filename>authority/res/locationItemsContainingWord1.res.xml</filename>
+                <filename>authority/res/locationItemsWithShortID.res.xml</filename>
+                <vars>
+                    <var ID="itemShortIdentifier">${createLocationItem1.itemShortIdentifier}</var>
+                </vars>
             </response>
         </test>
+        
+        <!-- Partial term searches -->
+        
+        <!-- Stem matching on first word -->
         <test ID="ptStemSearchLocationItems">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/_ALL_/items?pt=${createPersonAuthority1.word1PartialTermStem}</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items?pt=${createPersonAuthority1.word1PartialTermStem}</uri>
+            <response>
+                <expected level="TEXT"/>
+                <filename>authority/res/locationItemsWithShortID.res.xml</filename>
+                <vars>
+                    <var ID="itemShortIdentifier">${createLocationItem1.itemShortIdentifier}</var>
+                </vars>
+            </response>
+        </test>
+        <!-- Using a wildcard in the middle of a search expression -->
+        <test ID="ptWildcardSearchLocationItems">
+            <expectedCodes>200</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/locationauthorities/_ALL_/items?pt=${createPersonAuthority1.word3}*${createPersonAuthority1.word5}</uri>
             <response>
                 <expected level="TEXT"/>
-                <filename>authority/res/locationItemsContainingWord1.res.xml</filename>
+                <filename>authority/res/locationItemsWithShortID.res.xml</filename>
+                <vars>
+                    <var ID="itemShortIdentifier">${createLocationItem2.itemShortIdentifier}</var>
+                </vars>
             </response>
         </test>
-         <test ID="advSearchLocationItems">
+        
+        <!-- Advanced searches -->
+        
+        <test ID="advSearchLocationItemsDisplayName">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/_ALL_/items?as=locations_common%3AdisplayName%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items?as=locations_common%3AlocTermGroupList%2F*%2FtermDisplayName%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
             <response>
                 <expected level="TEXT"/>
-                <filename>authority/res/locationItemsContainingWord1.res.xml</filename>
+                <filename>authority/res/locationItemsWithShortID.res.xml</filename>
+                <vars>
+                    <var ID="itemShortIdentifier">${createLocationItem1.itemShortIdentifier}</var>
+                </vars>
             </response>
-        </test>   
-        <test ID="advSearchLocationItems">
+        </test>
+        <test ID="advSearchLocationItemsAccessNote">
             <expectedCodes>200</expectedCodes>
             <method>GET</method>
-            <uri>/cspace-services/locationauthorities/_ALL_/items?as=locations_common%3AaccessNote%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
+            <uri>/cspace-services/locationauthorities/${createLocationAuthority.CSID}/items?as=locations_common%3AaccessNote%20ILIKE%20%27%25${createPersonAuthority1.word1}%25%27</uri>
             <response>
                 <expected level="TEXT"/>
-                <filename>authority/res/locationItemsContainingWord1.res.xml</filename>
+                <filename>authority/res/locationItemsWithShortID.res.xml</filename>
+                <vars>
+                    <var ID="itemShortIdentifier">${createLocationItem1.itemShortIdentifier}</var>
+                </vars>
             </response>
         </test>
         
index 56e370a69471e3f57365006eccbaafe93803b4dd..cc88aa9f8725d096392b9ce313560752797ea74f 100644 (file)
@@ -1,8 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <document name="locations">
     <ns2:locations_common xmlns:ns2="http://collectionspace.org/services/location" xmlns:ns3="http://collectionspace.org/services/jaxb">
-        <displayName>${itemDisplayName}</displayName>
-        <displayNameComputed>false</displayNameComputed>
+        <locTermGroupList>
+           <locTermGroup>
+               <termDisplayName>${itemDisplayName}</termDisplayName>
+           </locTermGroup>
+       </locTermGroupList>
         <shortIdentifier>${itemShortIdentifier}</shortIdentifier>
         <accessNote>This is a test Location Authority item, whose access note contains: ${itemDisplayName}</accessNote>
     </ns2:locations_common>
index 87f820af0c42d7e1f3f81398b9378f90dd099584..8204bb32fa1f348b7e517d0cdf4e8656db091cde 100644 (file)
@@ -1,10 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
 <document name="persons">\r
     <ns2:persons_common xmlns:ns2="http://collectionspace.org/services/person" xmlns:ns3="http://collectionspace.org/services/jaxb">\r
-        <displayName>${itemDisplayName}</displayName>\r
-        <displayNameComputed>false</displayNameComputed>\r
+        <personTermGroupList>\r
+            <personTermGroup>\r
+                <termDisplayName>${itemDisplayName}</termDisplayName>\r
+            </personTermGroup>   \r
+        </personTermGroupList>\r
         <shortIdentifier>${itemShortIdentifier}</shortIdentifier>\r
-        <bioNote>A bio note for this Person.</bioNote>\r
+        <bioNote>${itemBioNote}</bioNote>\r
         <foreName>${itemDisplayName}</foreName>\r
     </ns2:persons_common>\r
 </document>\r
index 24599092676ba407ce6495500b5725aabafeeaa5..15cd5c2539afecfe5ac4fcf52bdac82c7e99f18c 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
 <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">\r
     <pageNum>0</pageNum>\r
-    <pageSize>1</pageSize>\r
-    <itemsInPage>1</itemsInPage>\r
+    <pageSize>${numItems}</pageSize>\r
+    <itemsInPage>${numItems}</itemsInPage>\r
 </ns2:abstract-common-list>\r
 \r
@@ -2,7 +2,7 @@
 <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">\r
     <totalItems>1</totalItems>\r
     <list-item>\r
-        <shortIdentifier>${createPersonAuthority1.word1}item1</shortIdentifier>\r
+        <shortIdentifier>${itemShortIdentifier}</shortIdentifier>\r
     </list-item>\r
 </ns2:abstract-common-list>\r
 \r
index 61a80fda2f100290e0200eb603512d92d0740767..15cd5c2539afecfe5ac4fcf52bdac82c7e99f18c 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
 <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">\r
     <pageNum>0</pageNum>\r
-    <pageSize>3</pageSize>\r
-    <itemsInPage>3</itemsInPage>\r
+    <pageSize>${numItems}</pageSize>\r
+    <itemsInPage>${numItems}</itemsInPage>\r
 </ns2:abstract-common-list>\r
 \r
index a12b24afb02367ae2de3142a13e595084ad1af4b..fa1ee99d0b48e793e0e26ae9e9e6eb3e2877d64e 100644 (file)
@@ -35,6 +35,7 @@
     <run controlFile="vocabulary/vocabulary.xml" testGroup="TestOrder" />\r
     <run controlFile="authrefs/authrefsSimple.xml" testGroup="AuthRefsSimple" />\r
     <run controlFile="authrefs/authrefsComplex.xml" testGroup="AuthRefsComplex" />\r
+    <run controlFile="authority/authority.xml" testGroup="TestAuthoritiesMultiVocabSearch" />\r
     <run controlFile="imports/imports.xml" testGroup="importsTestGroup" />\r
     \r
     <run controlFile="collectionobject/collectionobject-hierarchy-csid.xml" testGroup="CreateUpdateReadStructuredObjects" />\r
index 7298eff3cf84ca05d4e706fa4a30b40a228109a7..9c88719e5d9f1ffe942ed9a4a411651ead39a98c 100644 (file)
@@ -111,6 +111,8 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
 //    private String foo = Profiler.createLogger();
     public static final String NUXEO_CORE_TYPE_DOMAIN = "Domain";
     public static final String NUXEO_CORE_TYPE_WORKSPACEROOT = "WorkspaceRoot";
+    // FIXME: Get this value from an existing constant, if available
+    private static final String USER_SUPPLIED_WILDCARD = "*";
     
     /**
      * Instantiates a new repository java client impl.
@@ -985,6 +987,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
 
         String whereClause;
         MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
+        // Value for replaceable parameter 1 in the query
         String partialTerm = queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM);
         // If the value of the partial term query parameter is blank ('pt='),
         // return all records, subject to restriction by any limit clause
@@ -1030,8 +1033,18 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         } else {
             partialTerm = JDBCTools.SQL_WILDCARD + partialTerm;
         }
-        // Automatically insert a trailing wildcard
-        params.add(partialTerm + JDBCTools.SQL_WILDCARD); // Value for replaceable parameter 1 in the query
+        // Add SQL wildcards in the midst of the partial term match search
+        // expression, whever user-supplied wildcards appear, except in the
+        // first or last character positions of the search expression.
+        partialTerm = subtituteWildcardsInPartialTerm(partialTerm);
+        
+        // FIXME: We may wish to handle instances where a designated 'stop
+        // character' has been inserted by the user as the last character in
+        // the search expression, whereupon we would strip that stop character
+        // and skip the automatic adding of a trailing wildcard, below.
+        
+        // Automatically add a trailing wildcard
+        params.add(partialTerm + JDBCTools.SQL_WILDCARD);
         
         // Optionally add restrictions to the default query, based on variables
         // in the current request
@@ -1749,8 +1762,6 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
 
     private String handleProvidedStartingWildcard(String partialTerm) {
         if (Tools.notBlank(partialTerm)) {
-            // FIXME: Get this value from an existing constant, if available
-            final String USER_SUPPLIED_WILDCARD = "*";
             if (partialTerm.substring(0, 1).equals(USER_SUPPLIED_WILDCARD)) {
                 StringBuffer buffer = new StringBuffer(partialTerm);
                 buffer.setCharAt(0, JDBCTools.SQL_WILDCARD.charAt(0));
@@ -1759,6 +1770,38 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         }
         return partialTerm;
     }
+    
+    /**
+     * Replaces user-supplied wildcards with SQL wildcards, in a partial term
+     * matching search expression.
+     * 
+     * The scope of this replacement excludes the beginning and ending
+     * characters in that search expression, as those are treated specially.
+     * 
+     * @param partialTerm
+     * @return the partial term, with any user-supplied wildcards replaced
+     * by SQL wildcards.
+     */
+    private String subtituteWildcardsInPartialTerm(String partialTerm) {
+        if (Tools.isBlank(partialTerm)) {
+            return partialTerm;
+        }
+        if (! partialTerm.contains(USER_SUPPLIED_WILDCARD)) {
+            return partialTerm;
+        }
+        int len = partialTerm.length();
+        // Partial term search expressions of 2 or fewer characters
+        // currently aren't amenable to the use of wildcards
+        if (len <= 2)  {
+            logger.warn("Partial term matching expression of 1 or 2 characters contains user-supplied wildcard:" + partialTerm);
+            return partialTerm;
+        }
+        int lastCharPos = len - 1;
+        return partialTerm.substring(0, 1) // first char
+                + partialTerm.substring(1, lastCharPos).replaceAll("\\*", "%") // middle of search expression, excluding first and last
+                + partialTerm.substring(lastCharPos); // last char
+
+    }
 
     private int getMaxItemsLimitOnJdbcQueries(String maxListItemsLimit) {
         final int DEFAULT_ITEMS_LIMIT = 40;