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