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