]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
62b9561474897649d0c1f4bd2b0b27d8cfd3fcaa
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.vocabulary;
25
26 import org.collectionspace.services.client.IClientQueryParams;
27 import org.collectionspace.services.client.PayloadInputPart;
28 import org.collectionspace.services.client.PoxPayload;
29 import org.collectionspace.services.client.PoxPayloadIn;
30 import org.collectionspace.services.client.PoxPayloadOut;
31 import org.collectionspace.services.client.VocabularyClient;
32 import org.collectionspace.services.client.workflow.WorkflowClient;
33 import org.collectionspace.services.common.CSWebApplicationException;
34 import org.collectionspace.services.common.ResourceMap;
35 import org.collectionspace.services.common.ServiceMessages;
36 import org.collectionspace.services.common.UriInfoWrapper;
37 import org.collectionspace.services.common.api.RefNameUtils;
38 import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
39 import org.collectionspace.services.common.api.Tools;
40 import org.collectionspace.services.common.context.ServiceBindingUtils;
41 import org.collectionspace.services.common.context.ServiceContext;
42 import org.collectionspace.services.common.document.DocumentException;
43 import org.collectionspace.services.common.document.DocumentHandler;
44 import org.collectionspace.services.common.document.DocumentNotFoundException;
45 import org.collectionspace.services.common.repository.RepositoryClient;
46 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
47 import org.collectionspace.services.common.vocabulary.AuthorityResource;
48 import org.collectionspace.services.common.vocabulary.AuthorityServiceUtils;
49 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
50 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
51 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
52 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityIdentifierUtils;
53 import org.collectionspace.services.jaxb.AbstractCommonList;
54 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
55 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
56 import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemDocumentModelHandler;
57 import org.nuxeo.ecm.core.api.DocumentModel;
58 import org.nuxeo.ecm.core.api.DocumentModelList;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61 import org.w3c.dom.Element;
62
63 import java.util.ArrayList;
64 import java.util.Base64;
65 import java.util.HashSet;
66 import java.util.Set;
67
68 import javax.ws.rs.GET;
69 import javax.ws.rs.POST;
70 import javax.ws.rs.PUT;
71 import javax.ws.rs.Path;
72 import javax.ws.rs.PathParam;
73 import javax.ws.rs.core.Context;
74 import javax.ws.rs.core.MultivaluedMap;
75 import javax.ws.rs.core.Request;
76 import javax.ws.rs.core.Response;
77 import javax.ws.rs.core.UriBuilder;
78 import javax.ws.rs.core.UriInfo;
79 import javax.xml.bind.DatatypeConverter;
80
81 @Path("/" + VocabularyClient.SERVICE_PATH_COMPONENT)
82 public class VocabularyResource extends 
83         AuthorityResource<VocabulariesCommon, VocabularyItemDocumentModelHandler> {
84
85         private enum Method {
86         POST, PUT;
87     }
88         
89     private final static String vocabularyServiceName = VocabularyClient.SERVICE_PATH_COMPONENT;
90
91         private final static String VOCABULARIES_COMMON = "vocabularies_common";
92     
93     private final static String vocabularyItemServiceName = "vocabularyitems";
94         private final static String VOCABULARYITEMS_COMMON = "vocabularyitems_common";
95
96     final Logger logger = LoggerFactory.getLogger(VocabularyResource.class);
97
98         public VocabularyResource() {
99                 super(VocabulariesCommon.class, VocabularyResource.class,
100                                 VOCABULARIES_COMMON, VOCABULARYITEMS_COMMON);
101         }
102
103         @POST
104     @Override
105     public Response createAuthority(
106                 @Context ResourceMap resourceMap,
107                 @Context UriInfo uriInfo,
108                 String xmlPayload) {
109         //
110         // Requests to create new authorities come in on new threads. Unfortunately, we need to synchronize those threads on this block because, as of 8/27/2015, we can't seem to get Nuxeo
111         // transaction code to deal with a database level UNIQUE constraint violations on the 'shortidentifier' column of the vocabularies_common table.
112         // Therefore, to prevent having multiple authorities with the same shortid, we need to synchronize
113         // the code that creates new authorities.  The authority document model handler will first check for authorities with the same short id before
114         // trying to create a new authority.
115         //
116         synchronized(AuthorityResource.class) {
117                 try {
118                     PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
119                     ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);
120                                 RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
121                                 
122                                 CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
123                                 try {
124                             DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);                          
125                             String csid = repoClient.create(ctx, handler);
126                             //
127                             // Handle any supplied list of items/terms
128                             //
129                             handleItemsPayload(Method.POST, ctx, csid, resourceMap, uriInfo, input);
130                             UriBuilder path = UriBuilder.fromResource(resourceClass);
131                             path.path("" + csid);
132                             Response response = Response.created(path.build()).build();
133                             return response;
134                     } catch (Throwable t) {
135                         repoSession.setTransactionRollbackOnly();
136                         throw t;
137                     } finally {
138                         repoClient.releaseRepositorySession(ctx, repoSession);
139                     }
140                 } catch (Exception e) {
141                     throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
142                 }
143         }
144     }
145         
146     @PUT
147     @Path("{csid}")
148     @Override
149     public byte[] updateAuthority(
150                 @Context Request request,
151                 @Context ResourceMap resourceMap,
152                 @Context UriInfo ui,
153             @PathParam("csid") String specifier,
154             String xmlPayload) {
155         PoxPayloadOut result = null;
156         try {
157                 UriInfoWrapper uriInfo = new UriInfoWrapper(ui); // We need to make the queryParams maps read-write instead of read-only
158             PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
159             Specifier spec = Specifier.getSpecifier(specifier, "updateAuthority", "UPDATE");
160             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(theUpdate, uriInfo);
161                         RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
162
163                         CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
164                         try {
165                     DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
166                     String csid;
167                     if (spec.form == SpecifierForm.CSID) {
168                         csid = spec.value;
169                     } else {
170                         String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value);
171                         csid = getRepositoryClient(ctx).findDocCSID(null, ctx, whereClause);
172                     }
173                     getRepositoryClient(ctx).update(ctx, csid, handler);
174                     if (handleItemsPayload(Method.PUT, ctx, csid, resourceMap, uriInfo, theUpdate) == true) {
175                         ctx.setOutput(new PoxPayloadOut(getServiceName())); // Clear the "vocabularies_common" result since we're going to create a new one with the items-list payload
176                         result = this.getAuthority(ctx, request, uriInfo, specifier, true);
177                     } else {
178                         result = ctx.getOutput();
179                     }
180             } catch (Throwable t) {
181                 repoSession.setTransactionRollbackOnly();
182                 throw t;
183             } finally {
184                 repoClient.releaseRepositorySession(ctx, repoSession);
185             }
186         } catch (Exception e) {
187             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED);
188         }
189         return result.getBytes();
190     }
191     
192     private void updateWithItemsPayload(
193                 AbstractCommonList itemsList,
194                 ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
195                 String parentIdentifier,
196                 ResourceMap resourceMap,
197                 UriInfo uriInfo,
198                 PoxPayloadIn input) throws Exception {
199         
200         CoreSessionInterface repoSession = (CoreSessionInterface) existingCtx.getCurrentRepositorySession();
201                 Set<String> shortIdsInPayload = getListOfShortIds(itemsList); // record the list of existing or new terms/items
202
203         //
204         // First try to update and/or create items in the incoming payload
205         //
206                 for (ListItem item : itemsList.getListItem()) {
207                         String errMsg = null;
208                         boolean success = true;
209                         Response response = null;
210                         PoxPayloadOut payloadOut = null;
211                         PoxPayloadIn itemXmlPayload = getItemXmlPayload(item);
212                         String itemSpecifier = getSpecifier(item);
213                         if (itemSpecifier != null) {
214                                 try {
215                                         payloadOut = updateAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemSpecifier, itemXmlPayload);
216                                         if (payloadOut == null) {
217                                         success = false;
218                                         errMsg = String.format("Could not update the term list payload of vocabuary '%s'.", parentIdentifier);
219                                 }
220                                 } catch (DocumentNotFoundException dnf) {
221                                         //
222                                         // Since the item doesn't exist, we're being ask to create it
223                                         //
224                                 response = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
225                                 if (response.getStatus() != Response.Status.CREATED.getStatusCode()) {
226                                         success = false;
227                                         errMsg = String.format("Could not create the term list payload of vocabuary '%s'.", parentIdentifier);
228                                 }
229                                 }
230                         } else {
231                                 //
232                                 // Since the item was supplied with neither a CSID nor a short identifier, we'll assume we're being
233                                 // asked to create it.
234                                 //
235                         response = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
236                         if (response.getStatus() == Response.Status.CREATED.getStatusCode()) {
237                                 String shortId = getShortId(itemXmlPayload);
238                                 shortIdsInPayload.add(shortId); // add the new short ID to the list of incoming items
239                         } else {
240                                 success = false;
241                                         errMsg = String.format("Could not create the term list payload of vocabuary '%s'.", parentIdentifier);
242                         }
243                         }
244                         //
245                         // Throw an exception as soon as we have problems with any item
246                         //
247                         if (success == false) {
248                                 throw new DocumentException(errMsg);
249                         }
250                 }
251
252                 //
253                 // Next, delete the items that were omitted from the incoming payload
254                 //
255                 if (shouldDeleteOmittedItems(uriInfo) == true) {
256                         UriInfo uriInfoCopy = new UriInfoWrapper(uriInfo);
257                         String omittedItemAction = getOmittedItemAction(uriInfoCopy);
258                         long itemsProcessed = 0;
259                         long currentPage = 0;
260                         while (true) {
261                                 AbstractCommonList abstractCommonList = this.getAuthorityItemList(existingCtx, parentIdentifier, uriInfoCopy);
262                                 if (abstractCommonList != null && !Tools.isEmpty(abstractCommonList.getListItem())) {
263                                         if (omittedItemAction.equalsIgnoreCase(VocabularyClient.DELETE_OMITTED_ITEMS)) {
264                                                 deleteAuthorityItems(existingCtx, abstractCommonList, shortIdsInPayload, parentIdentifier);
265                                         } else {
266                                                 sotfDeleteAuthorityItems(existingCtx, abstractCommonList, shortIdsInPayload, parentIdentifier);
267                                         }
268                                 }
269                                 itemsProcessed = itemsProcessed + abstractCommonList.getItemsInPage();
270                                 if (itemsProcessed >= abstractCommonList.getTotalItems()) {
271                                         break;
272                                 }
273                                 ArrayList<String> pageNum = new ArrayList<String>();
274                                 pageNum.add(Long.toString(++currentPage));
275                                 uriInfoCopy.getQueryParameters().put(IClientQueryParams.START_PAGE_PARAM, pageNum);
276                         }
277                 }
278         }
279     
280     private String getShortId(PoxPayloadIn itemXmlPayload) {
281                 String result = null;
282                 
283                 VocabularyitemsCommon vocabularyItemsCommon = (VocabularyitemsCommon) itemXmlPayload.getPart(VOCABULARYITEMS_COMMON).getBody();
284                 result = vocabularyItemsCommon.getShortIdentifier();
285                 
286                 return result;
287         }
288
289         private void deleteAuthorityItems(
290                 ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
291                 AbstractCommonList abstractCommonList,
292                 Set<String> shortIdsInPayload,
293                 String parentIdentifier) throws Exception {
294         
295                 for (ListItem item : abstractCommonList.getListItem()) {
296                         String shortId = getShortId(item);
297                         if (shortIdsInPayload.contains(shortId) == false) {
298                                 deleteAuthorityItem(existingCtx, parentIdentifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV);
299                         }
300                 }       
301     }
302     
303     private void sotfDeleteAuthorityItems(
304                 ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
305                 AbstractCommonList abstractCommonList,
306                 Set<String> shortIdsInPayload,
307                 String parentIdentifier) throws Exception {
308         
309                 for (ListItem item : abstractCommonList.getListItem()) {
310                         String shortId = getShortId(item);
311                         if (shortIdsInPayload.contains(shortId) == false) {
312                                 //deleteAuthorityItem(existingCtx, parentIdentifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV);
313                                 this.updateItemWorkflowWithTransition(existingCtx, parentIdentifier, getCsid(item), 
314                                                 WorkflowClient.WORKFLOWTRANSITION_DELETE, AuthorityServiceUtils.UPDATE_REV);
315                         }
316                 }       
317     }
318         
319     private boolean shouldDeleteOmittedItems(UriInfo uriInfo) throws DocumentException {
320         boolean result = false;
321         
322                 String omittedItemAction = getOmittedItemAction(uriInfo);               
323                 if (Tools.isEmpty(omittedItemAction) == false) {
324                         switch (omittedItemAction) {
325                                 case VocabularyClient.DELETE_OMITTED_ITEMS:
326                                 case VocabularyClient.SOFTDELETE_OMITTED_ITEMS:
327                                         result = true;
328                                         break;
329                                 case VocabularyClient.IGNORE_OMITTED_ITEMS:
330                                         // do nothing
331                                         break;
332                                 default:
333                                         String msg = String.format("Unknown value '%s' for update on a vocabulary/termlist resource.", omittedItemAction);
334                                         throw new DocumentException(msg);
335                         }
336                 }
337                 
338                 return result;
339         }
340     
341     private String getOmittedItemAction(UriInfo uriInfo) {
342                 MultivaluedMap<String,String> queryParams = uriInfo.getQueryParameters();
343                 String omittedItemAction = queryParams.getFirst(VocabularyClient.OMITTED_ITEM_ACTION_QP);
344                 return omittedItemAction;
345     }
346
347         /*
348      * Returns the set of short identifiers in the abstract common list of authority items
349      */
350     private Set<String> getListOfShortIds(AbstractCommonList itemsList) {
351                 HashSet<String> result = new HashSet<String>();
352                 
353                 for (ListItem item : itemsList.getListItem()) {
354                         String shortId = getShortId(item);
355                         if (Tools.isEmpty(shortId) == false) {
356                                 result.add(shortId);
357                         }
358                 }
359                 
360                 return result;
361         }
362
363         private void createWithItemsPayload(
364                         AbstractCommonList itemsList,
365                         ServiceContext<PoxPayloadIn, 
366                         PoxPayloadOut> existingCtx, 
367                         String parentIdentifier, 
368                         ResourceMap resourceMap,
369                         UriInfo uriInfo, 
370                         PoxPayloadIn input) throws Exception {
371
372                 for (ListItem item : itemsList.getListItem()) {
373                         String errMsg = null;
374                         boolean success = true;
375                         Response response = null;
376                         PoxPayloadIn itemXmlPayload = getItemXmlPayload(item);
377
378                         CoreSessionInterface repoSession = (CoreSessionInterface) existingCtx.getCurrentRepositorySession();
379                         response = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
380                         if (response.getStatus() != Response.Status.CREATED.getStatusCode()) {
381                                 success = false;
382                                 errMsg = String.format("Could not create the term list payload of vocabuary '%s'.", parentIdentifier);
383                         }
384                         //
385                         // Throw an exception as soon as we have problems with any item
386                         //
387                         if (success == false) {
388                                 throw new DocumentException(errMsg);
389                         }
390                 }
391         }   
392     
393     private boolean handleItemsPayload(
394                 Method method,
395                 ServiceContext<PoxPayloadIn, PoxPayloadOut> existingCtx,
396                 String parentIdentifier,
397                 ResourceMap resourceMap,
398                 UriInfo uriInfo,
399                 PoxPayloadIn input) throws Exception {
400         boolean result = false;
401         
402         PayloadInputPart abstractCommonListPart  = input.getPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL);
403         if (abstractCommonListPart != null) {
404                 AbstractCommonList itemsList = (AbstractCommonList) abstractCommonListPart.getBody();
405                         switch (method) {
406                         case POST:
407                             createWithItemsPayload(itemsList, existingCtx, parentIdentifier, resourceMap, uriInfo, input);
408                                 break;
409                         case PUT:
410                             updateWithItemsPayload(itemsList, existingCtx, parentIdentifier, resourceMap, uriInfo, input);
411                                 break;                                  
412                         }
413                         result = true; // mark that we've handled an items-list payload
414         }
415         
416         return result;
417         }
418     
419     private String getFieldValue(ListItem item, String lookingFor) {
420         String result = null;
421         
422                 for (Element ele : item.getAny()) {
423                         String fieldName = ele.getTagName();
424                         String fieldValue = ele.getTextContent();
425                         if (fieldName.equalsIgnoreCase(lookingFor)) {
426                                 result = fieldValue;
427                                 break;
428                         }
429                 }       
430         
431         return result;
432     }
433     
434     public String getCsid(ListItem item) {
435         return getFieldValue(item, "csid");
436     }
437     
438     private String getShortId(ListItem item) {
439         return getFieldValue(item, "shortIdentifier");
440     }
441     
442     private String getDisplayName(ListItem item) {
443         return getFieldValue(item, "displayName");
444     }
445     
446     /**
447      * We'll return null if we can create a specifier from the list item.
448      * 
449      * @param item
450      * @return
451      */
452     private String getSpecifier(ListItem item) {
453                 String result = null;
454
455                 String csid = result = getCsid(item);
456                 if (csid == null) {
457                         String shortId = getShortId(item);                      
458                         if (shortId != null) {
459                                 result = Specifier.createShortIdURNValue(shortId);
460                         }
461                 }
462
463                 return result;
464         }
465
466         /**
467      * This is very brittle.  If the class VocabularyitemsCommon changed with new fields we'd have to
468      * update this method.
469      * 
470      * @param item
471      * @return
472      * @throws DocumentException 
473      */
474         private PoxPayloadIn getItemXmlPayload(ListItem item) throws DocumentException {
475                 PoxPayloadIn result = null;
476
477                 VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon();
478                 for (Element ele : item.getAny()) {
479                         String fieldName = ele.getTagName();
480                         String fieldValue = ele.getTextContent();
481                         switch (fieldName) {
482                                 case "displayName":
483                                         vocabularyItem.setDisplayName(fieldValue);
484                                         break;
485                                         
486                                 case "shortIdentifier":
487                                         vocabularyItem.setShortIdentifier(fieldValue);
488                                         break;
489                                         
490                                 case "order":
491                                         vocabularyItem.setOrder(fieldValue);
492                                         break;
493                                         
494                                 case "source":
495                                         vocabularyItem.setSource(fieldValue);
496                                         break;
497                                         
498                                 case "sourcePage":
499                                         vocabularyItem.setSourcePage(fieldValue);
500                                         break;
501                                         
502                                 case "description":
503                                         vocabularyItem.setDescription(fieldValue);
504                                         break;
505                                         
506                                 case "csid":
507                                         vocabularyItem.setCsid(fieldValue);
508                                         break;
509                                         
510                                 case "termStatus":
511                                         vocabularyItem.setTermStatus(fieldValue);
512                                         break;
513
514                                 default:
515                                         // ignore other fields
516                                         break;
517                         }
518                 }
519                 //
520                 // We need to create a short ID if one wasn't supplied
521                 //
522                 if (Tools.isEmpty(vocabularyItem.getShortIdentifier())) {
523                         vocabularyItem.setShortIdentifier(AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(
524                                         vocabularyItem.getDisplayName() , null)); ;
525                 }
526                 
527                 result = new PoxPayloadIn(VocabularyClient.SERVICE_ITEM_PAYLOAD_NAME, vocabularyItem, 
528                         VOCABULARYITEMS_COMMON);
529
530                 return result; 
531         }
532     
533         private Response createAuthorityItem(
534                 CoreSessionInterface repoSession,
535                 ResourceMap resourceMap,
536                 UriInfo uriInfo,
537                 String parentIdentifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny)
538                 PoxPayloadIn input) throws Exception {
539         Response result = null;
540         
541         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo);
542         ctx.setCurrentRepositorySession(repoSession);
543         
544         result = createAuthorityItem(ctx, parentIdentifier, AuthorityServiceUtils.UPDATE_REV,
545                         AuthorityServiceUtils.PROPOSED, AuthorityServiceUtils.NOT_SAS_ITEM);
546
547         return result;
548     }
549         
550         private PoxPayloadOut updateAuthorityItem(
551                 CoreSessionInterface repoSession,
552                 ResourceMap resourceMap,
553                 UriInfo uriInfo,
554                 String parentSpecifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny)
555                 String itemSpecifier,   // Either a CSID or a URN form.
556                 PoxPayloadIn theUpdate) throws Exception {
557         PoxPayloadOut result = null;
558         
559         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
560         ctx.setCurrentRepositorySession(repoSession);
561         
562         result = updateAuthorityItem(ctx, resourceMap, uriInfo, parentSpecifier, itemSpecifier, theUpdate,
563                         AuthorityServiceUtils.UPDATE_REV,                       // passing TRUE so rev num increases, passing
564                         AuthorityServiceUtils.NO_CHANGE,        // don't change the state of the "proposed" field -we could be performing a sync or just a plain update
565                         AuthorityServiceUtils.NO_CHANGE);       // don't change the state of the "sas" field -we could be performing a sync or just a plain update
566
567         return result;
568     }
569
570         @GET
571     @Path("{csid}")
572     @Override
573     public Response get(
574             @Context Request request,
575             @Context ResourceMap resourceMap, 
576             @Context UriInfo uriInfo,
577             @PathParam("csid") String specifier) {
578         Response result = null;
579         uriInfo = new UriInfoWrapper(uriInfo);
580         
581         try {
582                 MultivaluedMap<String,String> queryParams = uriInfo.getQueryParameters();
583                 String showItemsValue = (String)queryParams.getFirst(VocabularyClient.SHOW_ITEMS_QP);
584             boolean showItems = Tools.isTrue(showItemsValue);
585             if (showItems == true) {
586                 //
587                 // We'll honor paging params if we find any; otherwise we'll set the page size to 0 to get ALL the items
588                 //
589                 if (queryParams.containsKey(IClientQueryParams.PAGE_SIZE_PARAM) == false) {
590                         queryParams.add(IClientQueryParams.PAGE_SIZE_PARAM, "0");
591                 }
592             }
593             if (RefNameUtils.isTermRefname(specifier)) {
594                 AuthorityTermInfo authorityTermInfo = RefNameUtils.parseAuthorityTermInfo(specifier);
595                 String parentIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.inAuthority.name);
596                 String itemIdentifier = Specifier.createShortIdURNValue(authorityTermInfo.name);
597                 result = this.getAuthorityItemResponse(request, uriInfo, resourceMap, parentIdentifier, itemIdentifier);
598             } else {
599                                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(request, uriInfo);
600                                 PoxPayloadOut payloadout = getAuthority(ctx, request, uriInfo, specifier, showItems);
601                                 result = buildResponse(ctx, payloadout);
602             }
603         } catch (Exception e) {
604             throw bigReThrow(e, ServiceMessages.GET_FAILED, specifier);
605         }
606
607         if (result == null) {
608             Response response = Response.status(Response.Status.NOT_FOUND).entity(
609                     "GET request failed. The requested Authority specifier:" + specifier + ": was not found.").type(
610                     "text/plain").build();
611             throw new CSWebApplicationException(response);
612         }
613
614         return result;
615     }
616     
617     @Override
618     public String getServiceName() {
619         return vocabularyServiceName;
620     }
621
622     @Override
623     public String getItemServiceName() {
624         return vocabularyItemServiceName;
625     }
626     
627         @Override
628         public Class<VocabulariesCommon> getCommonPartClass() {
629                 return VocabulariesCommon.class;
630         }
631
632     /**
633      * @return the name of the property used to specify references for items in this type of
634      * authority. For most authorities, it is ServiceBindingUtils.AUTH_REF_PROP ("authRef").
635      * Some types (like Vocabulary) use a separate property.
636      */
637         @Override
638     protected String getRefPropName() {
639         return ServiceBindingUtils.TERM_REF_PROP;
640     }
641         
642         @Override
643         protected String getOrderByField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
644                 String result = null;
645
646                 result = ctx.getCommonPartLabel() + ":" + AuthorityItemJAXBSchema.DISPLAY_NAME;
647
648                 return result;
649         }
650         
651         @Override
652         protected String getPartialTermMatchField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
653                 return getOrderByField(ctx);
654         }
655
656         /*
657          * The item schema for the Vocabulary service does not support a multi-valued term list.  Only authorities that support
658          * term lists need to implement this method.
659          */
660         @Override
661         public String getItemTermInfoGroupXPathBase() {
662                 return null;
663         }
664 }