<service:col>inauthority</service:col>
</service:field>
<service:field>
- <service:table>taxon_common</service:table>
- <service:col>displayname</service:col>
+ <service:table>taxontermgroup</service:table>
+ <service:col>termdisplayname</service:col>
</service:field>
<service:field>
<service:table>taxon_common</service:table>
</types:item>
<types:item xmlns:types="http://collectionspace.org/services/config/types">
<types:key>termRef</types:key>
- <types:value>termStatus</types:value>
+ <types:value>taxonTermGroupList/*/termType</types:value>
+ </types:item>
+ <types:item xmlns:types="http://collectionspace.org/services/config/types">
+ <types:key>termRef</types:key>
+ <types:value>taxonTermGroupList/*/termLanguage</types:value>
+ </types:item>
+ <types:item xmlns:types="http://collectionspace.org/services/config/types">
+ <types:key>termRef</types:key>
+ <types:value>taxonTermGroupList/*/termStatus</types:value>
</types:item>
</service:properties>
<service:content contentType="application/xml">
<types:key>termRef</types:key>
<types:value>recordType</types:value>
</types:item>
- <types:item xmlns:types="http://collectionspace.org/services/config/types">
+ <types:item xmlns:types="http://collectionspace.org/services/config/types">
<types:key>termRef</types:key>
<types:value>conceptTermGroupList/*/termType</types:value>
</types:item>
-->
<xs:schema
- xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:ns="http://collectionspace.org/services/taxonomy"
- xmlns="http://collectionspace.org/services/taxonomy"
- targetNamespace="http://collectionspace.org/services/taxonomy"
- version="0.1"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:ns="http://collectionspace.org/services/taxonomy"
+ xmlns="http://collectionspace.org/services/taxonomy"
+ targetNamespace="http://collectionspace.org/services/taxonomy"
+ version="0.1"
>
<!-- See http://wiki.collectionspace.org/display/collectionspace/Taxonomy+Service+Home -->
<xs:element name="inAuthority" type="xs:string" />
<xs:element name="shortIdentifier" type="xs:string"/>
<xs:element name="refName" type="xs:string"/>
- <xs:element name="termStatus" type="xs:string"/>
- <xs:element name="displayName" type="xs:string"/>
- <xs:element name="displayNameComputed" type="xs:boolean"/>
- <xs:element name="shortDisplayName" type="xs:string"/>
- <xs:element name="shortDisplayNameComputed" type="xs:boolean"/>
- <xs:element name="source" type="xs:string"/>
- <xs:element name="sourcePage" type="xs:string"/>
- <xs:element name="description" type="xs:string"/>
+ <!-- Term Information repeatable group -->
+ <xs:element name="taxonTermGroupList" type="taxonTermGroupList"/>
+
+ <!-- FIXME: See comments on CSPACE-5122 for any additional changes -->
+ <!-- to the set of fields below -->
+ <xs:element name="description" type="xs:string"/>
<xs:element name="taxonFullName" type="xs:string"/>
<xs:element name="taxonRank" type="xs:string"/>
<xs:element name="taxonCurrency" type="xs:string"/>
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="taxonTermGroupList">
+ <xs:sequence>
+ <xs:element name="taxonTermGroup" type="taxonTermGroup" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="taxonTermGroup">
+ <xs:sequence>
+ <!-- Common across all authority item terms -->
+ <xs:element name="termDisplayName" type="xs:string"/>
+ <xs:element name="termName" type="xs:string"/>
+ <xs:element name="termType" type="xs:string"/>
+ <xs:element name="termStatus" type="xs:string"/>
+ <xs:element name="termQualifier" type="xs:string"/>
+ <xs:element name="termLanguage" type="xs:string"/>
+ <xs:element name="termPrefForLang" type="xs:boolean"/>
+ <xs:element name="termSource" type="xs:string"/>
+ <xs:element name="termSourceDetail" type="xs:string"/>
+ <xs:element name="termSourceID" type="xs:string"/>
+ <xs:element name="termSourceNote" type="xs:string"/>
+ <!-- Specific to Taxon terms -->
+ <!-- FIXME: See comments on CSPACE-5122 for any additions here -->
+ </xs:sequence>
+ </xs:complexType>
+
</xs:schema>
public static final String SERVICE_PATH_COMPONENT = SERVICE_NAME;
public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT;
public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME;
- public static final String TERM_INFO_GROUP_XPATH_BASE = "taxonTermGroup";
+ public static final String TERM_INFO_GROUP_XPATH_BASE = "taxonTermGroupList";
//
// Subitem constants
//
import java.io.File;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.FileUtils;
import org.collectionspace.services.TaxonJAXBSchema;
import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.taxonomy.TaxonAuthorGroupList;
-import org.collectionspace.services.taxonomy.TaxonCitationList;
-import org.collectionspace.services.taxonomy.TaxonCommon;
-import org.collectionspace.services.taxonomy.TaxonomyauthorityCommon;
+import org.collectionspace.services.common.api.Tools;
+import org.collectionspace.services.taxonomy.*;
import org.dom4j.DocumentException;
import org.jboss.resteasy.client.ClientResponse;
import org.slf4j.Logger;
* @return The PoxPayloadOut payload for the create call
*/
public static PoxPayloadOut createTaxonInstance(
- String taxonomyAuthRefName, Map<String, String> taxonInfo,
+ String taxonomyAuthRefName, Map<String, String> taxonInfo, List<TaxonTermGroup> terms,
TaxonAuthorGroupList taxonAuthorGroupList, TaxonCitationList taxonCitationList,
String headerLabel) {
TaxonCommon taxon = new TaxonCommon();
String shortId = taxonInfo.get(TaxonJAXBSchema.SHORT_IDENTIFIER);
- String displayName = taxonInfo.get(TaxonJAXBSchema.DISPLAY_NAME);
taxon.setShortIdentifier(shortId);
- // String taxonomyRefName = createTaxonomyRefName(taxonomyAuthRefName, shortId, displayName);
- // taxon.setRefName(taxonomyRefName);
- String value = null;
- value = taxonInfo.get(TaxonJAXBSchema.DISPLAY_NAME_COMPUTED);
- boolean displayNameComputed = (value == null) || value.equalsIgnoreCase("true");
- taxon.setDisplayNameComputed(displayNameComputed);
- if ((value = (String) taxonInfo.get(TaxonJAXBSchema.TERM_STATUS)) != null) {
- taxon.setTermStatus(value);
- }
+ // Set values in the Term Information Group
+ String displayName = taxonInfo.get(TaxonJAXBSchema.DISPLAY_NAME);
+ TaxonTermGroupList termList = new TaxonTermGroupList();
+ if (terms == null || terms.isEmpty()) {
+ if (Tools.notBlank(displayName)) {
+ terms = getTermGroupInstance(displayName);
+ } else {
+ terms = getTermGroupInstance(getGeneratedIdentifier());
+ }
+ }
+ terms.get(0).setTermStatus(taxonInfo.get(TaxonJAXBSchema.TERM_STATUS));
+ termList.getTaxonTermGroup().addAll(terms);
+ taxon.setTaxonTermGroupList(termList);
+
+ String value = null;
// Fields specific to this authority record type.
if ((value = (String) taxonInfo.get(TaxonJAXBSchema.NAME)) != null) {
taxon.setTaxonFullName(value);
*/
public static String createItemInAuthority(String vcsid,
String TaxonomyauthorityRefName, Map<String, String> taxonMap,
- TaxonAuthorGroupList taxonAuthorGroupList,
+ List<TaxonTermGroup> terms, TaxonAuthorGroupList taxonAuthorGroupList,
TaxonCitationList taxonCitationList, TaxonomyAuthorityClient client) {
// Expected status code: 201 Created
int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
}
PoxPayloadOut multipart =
createTaxonInstance(TaxonomyauthorityRefName,
- taxonMap, taxonAuthorGroupList, taxonCitationList, client.getItemCommonPartName());
+ taxonMap, terms, taxonAuthorGroupList, taxonCitationList, client.getItemCommonPartName());
String newID = null;
ClientResponse<Response> res = client.createItem(vcsid, multipart);
try {
newStr.append(name);
return newStr.toString();
}
+
+ public static List<TaxonTermGroup> getTermGroupInstance(String identifier) {
+ if (Tools.isBlank(identifier)) {
+ identifier = getGeneratedIdentifier();
+ }
+ List<TaxonTermGroup> terms = new ArrayList<TaxonTermGroup>();
+ TaxonTermGroup term = new TaxonTermGroup();
+ term.setTermDisplayName(identifier);
+ term.setTermName(identifier);
+ terms.add(term);
+ return terms;
+ }
+
+ private static String getGeneratedIdentifier() {
+ return "id" + new Date().getTime();
+ }
}
import org.collectionspace.services.taxonomy.TaxonCommon;
import javax.ws.rs.core.Response;
+import org.collectionspace.services.taxonomy.*;
import org.jboss.resteasy.client.ClientResponse;
import org.slf4j.Logger;
/** The logger. */
private final String CLASS_NAME = TaxonomyAuthorityServiceTest.class.getName();
private final Logger logger = LoggerFactory.getLogger(TaxonomyAuthorityServiceTest.class);
- private final String REFNAME = "refName";
- private final String DISPLAYNAME = "displayName";
- final String TEST_SHORTID = "CentauruspleurexanthemusGreen1832";
- final String TEST_TERM_STATUS = "accepted";
- final String TEST_TAXON_FULL_NAME = "Centaurus pleurexanthemus Green 1832";
+ private final String TEST_SHORTID = "CentauruspleurexanthemusGreen1832";
+ private final String TEST_TERM_STATUS = "accepted";
+ private final String TEST_TAXON_FULL_NAME = "Centaurus pleurexanthemus Green 1832";
// TODO Re-implement the Taxon Rank field so as to provide an orderable
// ranking value, as well as a display name.
- final String TEST_TAXON_RANK = "species";
- final String TEST_TAXON_AUTHOR = "J. Green";
- final String TEST_TAXON_AUTHOR_TYPE = "ascribed";
- final String TEST_TAXON_CITATION = "A Monograph of the Trilobites of North America";
- final String TEST_TAXON_CURRENCY = "current";
- final String TEST_TAXON_YEAR = "1832";
- final String TEST_TAXONOMIC_STATUS = "valid";
- final String TEST_TAXON_IS_NAMED_HYBRID = "false";
- final TaxonAuthorGroupList NULL_TAXON_AUTHOR_GROUP_LIST = null;
- final TaxonCitationList NULL_TAXON_CITATION_LIST = null;
+ private final String TEST_TAXON_RANK = "species";
+ private final String TEST_TAXON_AUTHOR = "J. Green";
+ private final String TEST_TAXON_AUTHOR_TYPE = "ascribed";
+ private final String TEST_TAXON_CITATION = "A Monograph of the Trilobites of North America";
+ private final String TEST_TAXON_CURRENCY = "current";
+ private final String TEST_TAXON_YEAR = "1832";
+ private final String TEST_TAXONOMIC_STATUS = "valid";
+ private final String TEST_TAXON_IS_NAMED_HYBRID = "false";
+ private final List<TaxonTermGroup> NULL_TAXON_TERMS_LIST = null;
+ private final TaxonAuthorGroupList NULL_TAXON_AUTHOR_GROUP_LIST = null;
+ private final TaxonCitationList NULL_TAXON_CITATION_LIST = null;
private String knownResourceShortIdentifer = null;
private String knownTaxonomyTypeRefName = null;
// * an authref field (when implemented)
String newID = TaxonomyAuthorityClientUtils.createItemInAuthority(vcsid,
- authRefName, taxonMap, taxonAuthorGroupList, taxonCitationList, client);
+ authRefName, taxonMap, NULL_TAXON_TERMS_LIST, taxonAuthorGroupList, taxonCitationList, client);
// Store the ID returned from the first item resource created
// for additional tests below.
return newID;
}
- /**
- * Verify item display name.
- *
- * @param testName the test name
- * @throws Exception the exception
- */
- @Test(dataProvider = "testName",
- dependsOnMethods = {"readItem", "updateItem"})
- public void verifyItemDisplayName(String testName) throws Exception {
- //
- // First read in our known resource
- //
- setupRead();
- TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
- ClientResponse<String> res = client.readItem(knownResourceId, knownItemResourceId);
- TaxonCommon taxon = null;
- try {
- assertStatusCode(res, testName);
- // Check whether taxon has expected displayName.
- PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
- taxon = (TaxonCommon) extractPart(input,
- client.getItemCommonPartName(), TaxonCommon.class);
- Assert.assertNotNull(taxon);
- } finally {
- if (res != null) {
- res.releaseConnection();
- }
- }
- //
- // Now setup for an update
- //
- String displayName = taxon.getDisplayName();
- // Make sure displayName matches computed form
- String expectedDisplayName =
- TaxonomyAuthorityClientUtils.prepareDefaultDisplayName(TEST_TAXON_FULL_NAME);
- Assert.assertNotNull(displayName, "Display name was null. Expected it to be: " + expectedDisplayName);
- // Update the shortName and verify the computed name is updated.
- taxon.setCsid(null);
- taxon.setDisplayNameComputed(true);
- taxon.setTaxonFullName("updated-" + TEST_TAXON_FULL_NAME);
- expectedDisplayName =
- TaxonomyAuthorityClientUtils.prepareDefaultDisplayName("updated-" + TEST_TAXON_FULL_NAME);
-
- // Create the update payload.
- PoxPayloadOut output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
- PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), taxon);
-
- setupUpdate();
- res = client.updateItem(knownResourceId, knownItemResourceId, output);
- TaxonCommon updatedTaxon = null;
- try {
- assertStatusCode(res, testName);
- // Retrieve the updated resource and verify that its contents exist.
- PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
- updatedTaxon =
- (TaxonCommon) extractPart(input,
- client.getItemCommonPartName(), TaxonCommon.class);
- Assert.assertNotNull(updatedTaxon);
- } finally {
- if (res != null) {
- res.releaseConnection();
- }
- }
- // Verify that the updated resource received the correct data.
- Assert.assertEquals(updatedTaxon.getTaxonFullName(), taxon.getTaxonFullName(),
- "Updated ForeName in Taxonomy did not match submitted data.");
- // Verify that the updated resource computes the right displayName.
- Assert.assertEquals(updatedTaxon.getDisplayName(), expectedDisplayName,
- "Updated ForeName in Taxonomy not reflected in computed DisplayName.");
- //
- // Now Update the displayName, not computed and verify the computed name is overriden.
- //
- taxon.setDisplayNameComputed(false);
- expectedDisplayName = "TestName";
- taxon.setDisplayName(expectedDisplayName);
-
- // Submit the updated resource to the service and store the response.
- output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
- commonPart = output.addPart(client.getItemCommonPartName(), taxon);
- setupUpdate(); // setup expected status code for result
- res = client.updateItem(knownResourceId, knownItemResourceId, output);
- try {
- assertStatusCode(res, testName);
- // Retrieve the updated resource and verify that its contents exist.
- PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
- updatedTaxon =
- (TaxonCommon) extractPart(input,
- client.getItemCommonPartName(), TaxonCommon.class);
- Assert.assertNotNull(updatedTaxon);
- } finally {
- if (res != null) {
- res.releaseConnection();
- }
- }
- // Verify that the updated resource received the correct data.
- Assert.assertEquals(updatedTaxon.isDisplayNameComputed(), false,
- "Updated displayNameComputed in Taxonomy did not match submitted data.");
- // Verify that the updated resource computes the right displayName.
- Assert.assertEquals(updatedTaxon.getDisplayName(),
- expectedDisplayName,
- "Updated DisplayName (not computed) in Taxonomy not stored.");
- }
-
/**
* Verify illegal item display name.
*
* @param testName the test name
* @throws Exception the exception
*/
- @Test(dataProvider = "testName",
- dependsOnMethods = {"verifyItemDisplayName"})
+ @Test(dataProvider = "testName")
public void verifyIllegalItemDisplayName(String testName) throws Exception {
//
// First read in our known resource.
}
}
//
- // Try to Update with computed false and no displayName
+ // Make an invalid UPDATE request, without a display name
//
- taxon.setDisplayNameComputed(false);
- taxon.setDisplayName(null);
+ TaxonTermGroupList termList = taxon.getTaxonTermGroupList();
+ Assert.assertNotNull(termList);
+ List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
+ Assert.assertNotNull(terms);
+ Assert.assertTrue(terms.size() > 0);
+ terms.get(0).setTermDisplayName(null);
+ terms.get(0).setTermName(null);
PoxPayloadOut output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), taxon);
for (AbstractCommonList.ListItem item : items) {
String value =
- AbstractCommonListUtils.ListItemGetElementValue(item, REFNAME);
+ AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.REF_NAME);
Assert.assertTrue((null != value), "Item refName is null!");
value =
- AbstractCommonListUtils.ListItemGetElementValue(item, DISPLAYNAME);
+ AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.DISPLAY_NAME);
Assert.assertTrue((null != value), "Item displayName is null!");
}
if(logger.isTraceEnabled()){
}
@Override
- protected TaxonCommon updateItemInstance(TaxonCommon authorityItem) {
- TaxonCommon result = new TaxonCommon();
-
- result.setDisplayName("updated-" + authorityItem.getTaxonFullName());
- result.setTaxonFullName("updated-" + authorityItem.getTaxonFullName());
-
- return result;
+ protected TaxonCommon updateItemInstance(TaxonCommon taxonCommon) {
+ TaxonCommon result = taxonCommon;
+ TaxonTermGroupList termList = taxonCommon.getTaxonTermGroupList();
+ Assert.assertNotNull(termList);
+ List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
+ Assert.assertNotNull(terms);
+ Assert.assertTrue(terms.size() > 0);
+ terms.get(0).setTermDisplayName("updated-" + terms.get(0).getTermDisplayName());
+ terms.get(0).setTermName("updated-" + terms.get(0).getTermName());
+ result.setTaxonTermGroupList(termList);
+ return result;
}
@Override
protected void compareUpdatedItemInstances(TaxonCommon original,
TaxonCommon updated) throws Exception {
- Assert.assertEquals(updated.getTaxonFullName(), original.getTaxonFullName(),
- "Taxon full name in updated Taxon did not match submitted data.");
+
+ TaxonTermGroupList originalTermList = original.getTaxonTermGroupList();
+ Assert.assertNotNull(originalTermList);
+ List<TaxonTermGroup> originalTerms = originalTermList.getTaxonTermGroup();
+ Assert.assertNotNull(originalTerms);
+ Assert.assertTrue(originalTerms.size() > 0);
+
+ TaxonTermGroupList updatedTermList = updated.getTaxonTermGroupList();
+ Assert.assertNotNull(updatedTermList);
+ List<TaxonTermGroup> updatedTerms = updatedTermList.getTaxonTermGroup();
+ Assert.assertNotNull(updatedTerms);
+ Assert.assertTrue(updatedTerms.size() > 0);
+
+ Assert.assertEquals(updatedTerms.get(0).getTermDisplayName(),
+ originalTerms.get(0).getTermDisplayName(),
+ "Value in updated record did not match submitted data.");
}
@Override
nonexMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
nonexMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, "nonEx");
nonexMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
- // PoxPayloadOut multipart =
- // TaxonomyAuthorityClientUtils.createTaxonInstance(
- // TaxonomyAuthorityClientUtils.createTaxonomyRefName(knownResourceRefName, "nonEx", "Non Existent"),
- // nonexMap, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
- // client.getItemCommonPartName());
final String EMPTY_REFNAME = "";
PoxPayloadOut result =
TaxonomyAuthorityClientUtils.createTaxonInstance(EMPTY_REFNAME,
- nonexMap, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
+ nonexMap, NULL_TAXON_TERMS_LIST, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
commonPartName);
return result;
}
xmlns="http://collectionspace.org/services/taxonomy"
targetNamespace="http://collectionspace.org/services/taxonomy"
version="0.1"
- >
+>
<!-- avoid XmlRootElement nightnmare, see http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html-->
<!-- See http://wiki.collectionspace.org/display/collectionspace/Taxonomy+Service+Home -->
<xs:element name="inAuthority" type="xs:string" />
<xs:element name="shortIdentifier" type="xs:string"/>
<xs:element name="refName" type="xs:string"/>
- <xs:element name="termStatus" type="xs:string"/>
- <xs:element name="displayName" type="xs:string"/>
- <xs:element name="displayNameComputed" type="xs:boolean"/>
- <xs:element name="shortDisplayName" type="xs:string"/>
- <xs:element name="shortDisplayNameComputed" type="xs:boolean"/>
- <xs:element name="source" type="xs:string"/>
- <xs:element name="sourcePage" type="xs:string"/>
+
+ <!-- Term Information repeatable group -->
+ <xs:element name="taxonTermGroupList" type="taxonTermGroupList"/>
+
+ <!-- FIXME: See comments on CSPACE-5122 for any additional changes -->
+ <!-- to the set of fields below -->
<xs:element name="description" type="xs:string"/>
<xs:element name="taxonFullName" type="xs:string"/>
<xs:element name="taxonRank" type="xs:string"/>
<xs:element name="taxonCitation" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
+
+ <xs:complexType name="taxonTermGroupList">
+ <xs:sequence>
+ <xs:element name="taxonTermGroup" type="taxonTermGroup" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="taxonTermGroup">
+ <xs:sequence>
+ <!-- Common across all authority item terms -->
+ <xs:element name="termDisplayName" type="xs:string"/>
+ <xs:element name="termName" type="xs:string"/>
+ <xs:element name="termType" type="xs:string"/>
+ <xs:element name="termStatus" type="xs:string"/>
+ <xs:element name="termQualifier" type="xs:string"/>
+ <xs:element name="termLanguage" type="xs:string"/>
+ <xs:element name="termPrefForLang" type="xs:boolean"/>
+ <xs:element name="termSource" type="xs:string"/>
+ <xs:element name="termSourceDetail" type="xs:string"/>
+ <xs:element name="termSourceID" type="xs:string"/>
+ <xs:element name="termSourceNote" type="xs:string"/>
+ <!-- Specific to Taxon terms -->
+ <!-- FIXME: See comments on CSPACE-5122 for any additions here -->
+ </xs:sequence>
+ </xs:complexType>
</xs:schema>
/**
- * 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.
*/
package org.collectionspace.services.taxonomy;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
import org.collectionspace.services.client.TaxonomyAuthorityClient;
import org.collectionspace.services.common.vocabulary.AuthorityResource;
import org.collectionspace.services.taxonomy.nuxeo.TaxonDocumentModelHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-
+/**
+ * TaxonomyAuthorityResource
+ *
+ * Handles, dispatches, and returns responses to RESTful requests related to
+ * Taxonomy authority-related resources.
+ */
@Path(TaxonomyAuthorityClient.SERVICE_PATH)
@Consumes("application/xml")
@Produces("application/xml")
-public class TaxonomyAuthorityResource
- extends AuthorityResource<TaxonomyauthorityCommon, TaxonDocumentModelHandler> {
-
- private final static String taxonomyAuthorityServiceName = "taxonomyauthority";
- private final static String TAXONOMYAUTHORITY_COMMON = "taxonomyauthority_common";
- private final static String taxonomyItemServiceName = "taxon";
- private final static String TAXONOMYITEM_COMMON = "taxon_common";
+public class TaxonomyAuthorityResource extends AuthorityResource<TaxonomyauthorityCommon, TaxonDocumentModelHandler> {
final Logger logger = LoggerFactory.getLogger(TaxonomyAuthorityResource.class);
public TaxonomyAuthorityResource() {
super(TaxonomyauthorityCommon.class, TaxonomyAuthorityResource.class,
- TAXONOMYAUTHORITY_COMMON, TAXONOMYITEM_COMMON);
+ TaxonomyAuthorityClient.SERVICE_COMMON_PART_NAME, TaxonomyAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
}
@Override
public String getServiceName() {
- return taxonomyAuthorityServiceName;
+ return TaxonomyAuthorityClient.SERVICE_NAME;
}
@Override
public String getItemServiceName() {
- return taxonomyItemServiceName;
+ return TaxonomyAuthorityClient.SERVICE_ITEM_NAME;
}
@Override
- public Class<TaxonomyauthorityCommon> getCommonPartClass() {
- return TaxonomyauthorityCommon.class;
- }
-
- @Override
- public String getItemTermInfoGroupXPathBase() {
+ public String getItemTermInfoGroupXPathBase() {
return TaxonomyAuthorityClient.TERM_INFO_GROUP_XPATH_BASE;
- }
-}
+ }
+}
\ No newline at end of file
*/
package org.collectionspace.services.taxonomy.nuxeo;
+import java.util.List;
import java.util.regex.Pattern;
-import org.collectionspace.services.taxonomy.TaxonCommon;
-import org.collectionspace.services.common.context.MultipartServiceContext;
-import org.collectionspace.services.common.context.ServiceContext;
-import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.document.InvalidDocumentException;
-import org.collectionspace.services.common.document.ValidatorHandler;
+import org.collectionspace.services.common.document.ValidatorHandlerImpl;
+import org.collectionspace.services.taxonomy.TaxonCommon;
+import org.collectionspace.services.taxonomy.TaxonTermGroup;
+import org.collectionspace.services.taxonomy.TaxonTermGroupList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TaxonValidatorHandler
*
- * Validates data supplied when attempting to create and/or update Taxon records.
- *
- * $LastChangedRevision$
- * $LastChangedDate$
+ * Performs validation when making requests related to Taxon records.
+ * As an example, you can modify this class to customize validation of
+ * payloads supplied in requests to create and/or update records.
*/
-public class TaxonValidatorHandler implements ValidatorHandler {
+public class TaxonValidatorHandler extends ValidatorHandlerImpl {
final Logger logger = LoggerFactory.getLogger(TaxonValidatorHandler.class);
- private static final Pattern shortIdBadPattern = Pattern.compile("[\\W]"); //.matcher(input).matches()
+ // 'Bad pattern' for shortIdentifiers matches any non-word characters
+ private static final Pattern SHORT_ID_BAD_PATTERN = Pattern.compile("[\\W]"); //.matcher(input).matches()
+ private static final String VALIDATION_ERROR = "The record payload was invalid. See log file for more details.";
+ private static final String SHORT_ID_BAD_CHARS_ERROR =
+ "shortIdentifier must only contain standard word characters";
+ private static final String HAS_NO_TERMS_ERROR =
+ "Authority items must contain at least one term.";
+ private static final String HAS_AN_EMPTY_TERM_ERROR =
+ "Each term group in an authority item must contain "
+ + "a non-empty term name or "
+ + "a non-empty term display name.";
@Override
- public void validate(Action action, ServiceContext ctx)
- throws InvalidDocumentException {
- if (logger.isDebugEnabled()) {
- logger.debug("validate() action=" + action.name());
- }
-
- // Bail out if the validation action is for delete.
- if (action.equals(Action.DELETE)) {
- return;
- }
-
- try {
- MultipartServiceContext mctx = (MultipartServiceContext) ctx;
- TaxonCommon taxon = (TaxonCommon) mctx.getInputPart(mctx.getCommonPartLabel(),
- TaxonCommon.class);
- String msg = "";
- boolean invalid = false;
-
- // Validation occurring on both creates and updates
- String displayName = taxon.getDisplayName();
- if (!taxon.isDisplayNameComputed() && ((displayName == null) || displayName.trim().isEmpty())) {
- invalid = true;
- msg += "displayName must be non-null and non-blank if displayNameComputed is false";
+ protected Class getCommonPartClass() {
+ return TaxonCommon.class;
+ }
+
+ @Override
+ protected void handleCreate() throws InvalidDocumentException {
+ TaxonCommon organization = (TaxonCommon) getCommonPart();
+ // No guarantee that there is a common part in every post/update.
+ if (organization != null) {
+ try {
+ String shortId = organization.getShortIdentifier();
+ if (shortId != null) {
+ CS_ASSERT(shortIdentifierContainsOnlyValidChars(shortId), SHORT_ID_BAD_CHARS_ERROR);
+ }
+ CS_ASSERT(containsAtLeastOneTerm(organization), HAS_NO_TERMS_ERROR);
+ CS_ASSERT(allTermsContainNameOrDisplayName(organization), HAS_AN_EMPTY_TERM_ERROR);
+ } catch (AssertionError e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
+ }
+ throw new InvalidDocumentException(VALIDATION_ERROR, e);
}
+ }
+ }
- // Validation specific to creates or updates
- if (action.equals(Action.CREATE)) {
- String shortId = taxon.getShortIdentifier();
- // Per CSPACE-2215, shortIdentifier values that are null (missing)
- // oe the empty string are now legally accepted in create payloads.
- // In either of those cases, a short identifier will be synthesized from
- // a display name or supplied in another manner.
- if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) {
- invalid = true;
- msg += "shortIdentifier must only contain standard word characters";
+ @Override
+ protected void handleGet() throws InvalidDocumentException {
+ }
+
+ @Override
+ protected void handleGetAll() throws InvalidDocumentException {
+ }
+
+ @Override
+ protected void handleUpdate() throws InvalidDocumentException {
+ TaxonCommon organization = (TaxonCommon) getCommonPart();
+ // No guarantee that there is a common part in every post/update.
+ if (organization != null) {
+ try {
+ // shortIdentifier is among a set of fields that are
+ // prevented from being changed on an update, and thus
+ // we don't need to check its value here.
+ CS_ASSERT(containsAtLeastOneTerm(organization), HAS_NO_TERMS_ERROR);
+ CS_ASSERT(allTermsContainNameOrDisplayName(organization), HAS_AN_EMPTY_TERM_ERROR);
+ } catch (AssertionError e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
}
- } else if (action.equals(Action.UPDATE)) {
+ throw new InvalidDocumentException(VALIDATION_ERROR, e);
}
+ }
+ }
+
+ @Override
+ protected void handleDelete() throws InvalidDocumentException {
+ }
+
+ private boolean shortIdentifierContainsOnlyValidChars(String shortId) {
+ // Check whether any characters match the 'bad' pattern
+ if (SHORT_ID_BAD_PATTERN.matcher(shortId).find()) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean containsAtLeastOneTerm(TaxonCommon organization) {
+ TaxonTermGroupList termGroupList = organization.getTaxonTermGroupList();
+ if (termGroupList == null) {
+ return false;
+ }
+ List<TaxonTermGroup> termGroups = termGroupList.getTaxonTermGroup();
+ if ((termGroups == null) || (termGroups.isEmpty())){
+ return false;
+ }
+ return true;
+ }
- if (invalid) {
- logger.error(msg);
- throw new InvalidDocumentException(msg);
+ private boolean allTermsContainNameOrDisplayName(TaxonCommon organization) {
+ TaxonTermGroupList termGroupList = organization.getTaxonTermGroupList();
+ List<TaxonTermGroup> termGroups = termGroupList.getTaxonTermGroup();
+ for (TaxonTermGroup termGroup : termGroups) {
+ if (Tools.isBlank(termGroup.getTermName()) || Tools.isBlank(termGroup.getTermDisplayName())) {
+ return false;
}
- } catch (InvalidDocumentException ide) {
- throw ide;
- } catch (Exception e) {
- throw new InvalidDocumentException(e);
}
+ return true;
}
}