2 * CitationAuthorityClientUtils.java
4 * {Purpose of This Class}
6 * {Other Notes Relating to This Class (Optional)}
9 * $LastChangedRevision: $
12 * This document is a part of the source code and related artifacts
13 * for CollectionSpace, an open source collections management system
14 * for museums and related institutions:
16 * http://www.collectionspace.org
17 * http://wiki.collectionspace.org
19 * Copyright © 2009 {Contributing Institution}
21 * Licensed under the Educational Community License (ECL), Version 2.0.
22 * You may not use this file except in compliance with this License.
24 * You may obtain a copy of the ECL 2.0 License at
25 * https://source.collectionspace.org/collection-space/LICENSE.txt
27 package org.collectionspace.services.client;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Response;
35 import org.collectionspace.services.CitationJAXBSchema;
36 import org.collectionspace.services.client.test.ServiceRequestType;
37 import org.collectionspace.services.common.api.Tools;
38 import org.collectionspace.services.citation.CitationTermGroup;
39 import org.collectionspace.services.citation.CitationTermGroupList;
40 import org.collectionspace.services.citation.CitationsCommon;
41 import org.collectionspace.services.citation.CitationauthoritiesCommon;
42 import org.jboss.resteasy.client.ClientResponse;
43 //import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.collectionspace.services.citation.StructuredDateGroup;
49 * The Class CitationAuthorityClientUtils.
51 public class CitationAuthorityClientUtils {
53 /** The Constant logger. */
54 private static final Logger logger =
55 LoggerFactory.getLogger(CitationAuthorityClientUtils.class);
56 private static final ServiceRequestType READ_REQ = ServiceRequestType.READ;
59 * @param csid the id of the CitationAuthority
60 * @param client if null, creates a new client
63 public static String getAuthorityRefName(String csid, CitationAuthorityClient client){
65 client = new CitationAuthorityClient();
67 ClientResponse<String> res = client.read(csid);
69 int statusCode = res.getStatus();
70 if(!READ_REQ.isValidStatusCode(statusCode)
71 ||(statusCode != CollectionSpaceClientUtils.STATUS_OK)) {
72 throw new RuntimeException("Invalid status code returned: "+statusCode);
74 //FIXME: remove the following try catch once Aron fixes signatures
76 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
77 CitationauthoritiesCommon citationAuthority =
78 (CitationauthoritiesCommon) CollectionSpaceClientUtils.extractPart(input,
79 client.getCommonPartName(), CitationauthoritiesCommon.class);
80 if(citationAuthority == null) {
81 throw new RuntimeException("Null citationAuthority returned from service.");
83 return citationAuthority.getRefName();
84 } catch (Exception e) {
85 throw new RuntimeException(e);
88 res.releaseConnection();
93 * @param csid the id of the CitationAuthority
94 * @param client if null, creates a new client
97 public static String getCitationRefName(String inAuthority, String csid, CitationAuthorityClient client){
98 if ( client == null) {
99 client = new CitationAuthorityClient();
101 ClientResponse<String> res = client.readItem(inAuthority, csid);
103 int statusCode = res.getStatus();
104 if(!READ_REQ.isValidStatusCode(statusCode)
105 ||(statusCode != CollectionSpaceClientUtils.STATUS_OK)) {
106 throw new RuntimeException("Invalid status code returned: "+statusCode);
108 //FIXME: remove the following try catch once Aron fixes signatures
110 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
111 CitationsCommon citation =
112 (CitationsCommon) CollectionSpaceClientUtils.extractPart(input,
113 client.getItemCommonPartName(), CitationsCommon.class);
114 if (citation == null) {
115 throw new RuntimeException("Null citation returned from service.");
117 return citation.getRefName();
118 } catch (Exception e) {
119 throw new RuntimeException(e);
122 res.releaseConnection();
127 * Creates the citation authority instance.
129 * @param displayName the display name
130 * @param shortIdentifier the short Id
131 * @param headerLabel the header label
132 * @return the multipart output
134 public static PoxPayloadOut createCitationAuthorityInstance(
135 String displayName, String shortIdentifier, String headerLabel ) {
136 CitationauthoritiesCommon citationAuthority = new CitationauthoritiesCommon();
137 citationAuthority.setDisplayName(displayName);
138 citationAuthority.setShortIdentifier(shortIdentifier);
139 //String refName = createCitationAuthRefName(shortIdentifier, displayName);
140 //citationAuthority.setRefName(refName);
141 citationAuthority.setVocabType("CitationAuthority");
142 PoxPayloadOut multipart = new PoxPayloadOut(CitationAuthorityClient.SERVICE_PAYLOAD_NAME);
143 PayloadOutputPart commonPart = multipart.addPart(citationAuthority, MediaType.APPLICATION_XML_TYPE);
144 commonPart.setLabel(headerLabel);
146 if(logger.isDebugEnabled()){
147 logger.debug("to be created, citationAuthority common ",
148 citationAuthority, CitationauthoritiesCommon.class);
155 * Creates a citation instance.
157 * @param inAuthority the owning authority
158 * @param citationAuthRefName the owning Authority ref name
159 * @param citationInfo the citation info
160 * @param headerLabel the header label
161 * @return the multipart output
163 public static PoxPayloadOut createCitationInstance(String inAuthority,
164 String citationAuthRefName,
165 Map<String, String> citationInfo,
166 List<CitationTermGroup> terms,
168 if (terms == null || terms.isEmpty()) {
169 terms = getTermGroupInstance(getGeneratedIdentifier());
171 final Map<String, List<String>> EMPTY_CITATION_REPEATABLES_INFO =
172 new HashMap<String, List<String>>();
173 return createCitationInstance(inAuthority, null /*citationAuthRefName*/,
174 citationInfo, terms, EMPTY_CITATION_REPEATABLES_INFO, headerLabel);
178 * Creates a citation instance.
180 * @param inAuthority the owning authority
181 * @param citationAuthRefName the owning Authority ref name
182 * @param citationInfo the citation info
183 * @param terms a list of Citation terms
184 * @param citationRepeatablesInfo names and values of repeatable scalar fields in the Citation record
185 * @param headerLabel the header label
186 * @return the multipart output
188 public static PoxPayloadOut createCitationInstance(String inAuthority,
189 String citationAuthRefName, Map<String, String> citationInfo,
190 List<CitationTermGroup> terms,
191 Map<String, List<String>> citationRepeatablesInfo, String headerLabel){
192 CitationsCommon citation = new CitationsCommon();
193 citation.setInAuthority(inAuthority);
194 String shortId = citationInfo.get(CitationJAXBSchema.SHORT_IDENTIFIER);
195 if (shortId == null || shortId.isEmpty()) {
196 throw new IllegalArgumentException("shortIdentifier cannot be null or empty");
198 citation.setShortIdentifier(shortId);
201 List<String> values = null;
203 // Set values in the Term Information Group
204 CitationTermGroupList termList = new CitationTermGroupList();
205 if (terms == null || terms.isEmpty()) {
206 terms = getTermGroupInstance(getGeneratedIdentifier());
208 termList.getCitationTermGroup().addAll(terms);
209 citation.setCitationTermGroupList(termList);
211 PoxPayloadOut multipart = new PoxPayloadOut(CitationAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
212 PayloadOutputPart commonPart = multipart.addPart(citation,
213 MediaType.APPLICATION_XML_TYPE);
214 commonPart.setLabel(headerLabel);
216 if(logger.isDebugEnabled()){
217 logger.debug("to be created, citation common ", citation, CitationsCommon.class);
224 * Creates the item in authority.
226 * @param vcsid the vcsid
227 * @param citationAuthorityRefName the citation authority ref name
228 * @param citationMap the citation map. CitationJAXBSchema.SHORT_IDENTIFIER is REQUIRED.
229 * @param client the client
232 public static String createItemInAuthority(String vcsid,
233 String citationAuthorityRefName, Map<String,String> citationMap,
234 List<CitationTermGroup> terms, Map<String, List<String>> citationRepeatablesMap,
235 CitationAuthorityClient client ) {
236 // Expected status code: 201 Created
237 int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
238 // Type of service request being tested
239 ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE;
241 String displayName = "";
242 if (terms !=null && terms.size() > 0) {
243 displayName = terms.get(0).getTermDisplayName();
246 if(logger.isDebugEnabled()){
247 logger.debug("Creating item with display name: \"" + displayName
248 +"\" in citationAuthority: \"" + vcsid +"\"");
250 PoxPayloadOut multipart =
251 createCitationInstance(vcsid, null /*citationAuthorityRefName*/,
252 citationMap, terms, citationRepeatablesMap, client.getItemCommonPartName());
254 String result = null;
255 ClientResponse<Response> res = client.createItem(vcsid, multipart);
257 int statusCode = res.getStatus();
259 if(!REQUEST_TYPE.isValidStatusCode(statusCode)) {
260 throw new RuntimeException("Could not create Item: \""+citationMap.get(CitationJAXBSchema.SHORT_IDENTIFIER)
261 +"\" in citationAuthority: \"" + vcsid //citationAuthorityRefName
262 +"\" "+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
264 if(statusCode != EXPECTED_STATUS_CODE) {
265 throw new RuntimeException("Unexpected Status when creating Item: \""+citationMap.get(CitationJAXBSchema.SHORT_IDENTIFIER)
266 +"\" in citationAuthority: \"" + vcsid /*citationAuthorityRefName*/ +"\", Status:"+ statusCode);
269 result = extractId(res);
271 res.releaseConnection();
278 * Creates the citationAuthority ref name.
280 * @param shortId the citationAuthority shortIdentifier
281 * @param displaySuffix displayName to be appended, if non-null
285 public static String createCitationAuthRefName(String shortId, String displaySuffix) {
286 String refName = "urn:cspace:org.collectionspace.demo:citationauthority:name("
288 if(displaySuffix!=null&&!displaySuffix.isEmpty())
289 refName += "'"+displaySuffix+"'";
295 * Creates the citation ref name.
297 * @param citationAuthRefName the citation auth ref name
298 * @param shortId the citation shortIdentifier
299 * @param displaySuffix displayName to be appended, if non-null
303 public static String createCitationRefName(
304 String citationAuthRefName, String shortId, String displaySuffix) {
305 String refName = citationAuthRefName+":citation:name("+shortId+")";
306 if(displaySuffix!=null&&!displaySuffix.isEmpty())
307 refName += "'"+displaySuffix+"'";
318 public static String extractId(ClientResponse<Response> res) {
319 MultivaluedMap<String, Object> mvm = res.getMetadata();
320 // FIXME: This may throw an NPE if the Location: header isn't present
321 String uri = (String) ((ArrayList<Object>) mvm.get("Location")).get(0);
322 if(logger.isDebugEnabled()){
323 logger.debug("extractId:uri=" + uri);
325 String[] segments = uri.split("/");
326 String id = segments[segments.length - 1];
327 if(logger.isDebugEnabled()){
328 logger.debug("id=" + id);
334 * Returns an error message indicating that the status code returned by a
335 * specific call to a service does not fall within a set of valid status
336 * codes for that service.
338 * @param serviceRequestType A type of service request (e.g. CREATE, DELETE).
340 * @param statusCode The invalid status code that was returned in the response,
341 * from submitting that type of request to the service.
343 * @return An error message.
345 public static String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) {
346 return "Status code '" + statusCode + "' in response is NOT within the expected set: " +
347 requestType.validStatusCodesAsString();
353 * Produces a default displayName from the basic name and dates fields.
354 * @see CitationDocumentModelHandler.prepareDefaultDisplayName() which
355 * duplicates this logic, until we define a service-general utils package
356 * that is neither client nor service specific.
362 * @return display name
364 public static String prepareDefaultDisplayName(
365 String foreName, String middleName, String surName,
366 String birthDate, String deathDate) {
367 StringBuilder newStr = new StringBuilder();
368 final String sep = " ";
369 final String dateSep = "-";
370 List<String> nameStrings =
371 Arrays.asList(foreName, middleName, surName);
372 boolean firstAdded = false;
373 for(String partStr : nameStrings ){
374 if(null != partStr ) {
378 newStr.append(partStr);
382 // Now we add the dates. In theory could have dates with no name, but that is their problem.
383 boolean foundBirth = false;
384 if(null != birthDate) {
388 newStr.append(birthDate);
389 newStr.append(dateSep); // Put this in whether there is a death date or not
392 if(null != deathDate) {
397 newStr.append(dateSep);
399 newStr.append(deathDate);
401 return newStr.toString();
404 public static List<CitationTermGroup> getTermGroupInstance(String identifier) {
405 if (Tools.isBlank(identifier)) {
406 identifier = getGeneratedIdentifier();
408 List<CitationTermGroup> terms = new ArrayList<CitationTermGroup>();
409 CitationTermGroup term = new CitationTermGroup();
410 term.setTermDisplayName(identifier);
411 term.setTermName(identifier);
416 private static String getGeneratedIdentifier() {
417 return "id" + new Date().getTime();