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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.common.vocabulary.nuxeo;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.ListIterator;
33 import org.collectionspace.services.client.AuthorityClient;
34 import org.collectionspace.services.client.PayloadInputPart;
35 import org.collectionspace.services.client.PayloadOutputPart;
36 import org.collectionspace.services.client.PoxPayloadIn;
37 import org.collectionspace.services.client.PoxPayloadOut;
38 import org.collectionspace.services.client.RelationClient;
39 //import org.collectionspace.services.common.authority.AuthorityItemRelations;
40 import org.collectionspace.services.common.api.CommonAPI;
41 import org.collectionspace.services.common.api.RefName;
42 import org.collectionspace.services.common.api.Tools;
43 import org.collectionspace.services.common.context.MultipartServiceContext;
44 import org.collectionspace.services.common.context.ServiceContext;
45 import org.collectionspace.services.common.document.DocumentWrapper;
46 import org.collectionspace.services.common.relation.IRelationsManager;
47 import org.collectionspace.services.common.service.ObjectPartType;
48 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
49 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
50 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
51 import org.collectionspace.services.relation.RelationResource;
52 import org.collectionspace.services.relation.RelationsCommon;
53 import org.collectionspace.services.relation.RelationsCommonList;
54 import org.collectionspace.services.relation.RelationsDocListItem;
55 import org.collectionspace.services.relation.RelationshipType;
56 import org.nuxeo.ecm.core.api.DocumentModel;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 import javax.management.relation.Relation;
61 import javax.ws.rs.core.MultivaluedMap;
62 import javax.ws.rs.core.UriInfo;
65 * AuthorityItemDocumentModelHandler
67 * $LastChangedRevision: $
70 public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
71 extends RemoteDocumentModelHandlerImpl<AICommon, AICommonList> {
73 private final Logger logger = LoggerFactory.getLogger(AuthorityItemDocumentModelHandler.class);
75 private String authorityItemCommonSchemaName;
77 //private final Logger logger = LoggerFactory.getLogger(AuthorityItemDocumentModelHandler.class);
79 * item is used to stash JAXB object to use when handle is called
80 * for Action.CREATE, Action.UPDATE or Action.GET
82 protected AICommon item;
84 * itemList is stashed when handle is called
87 protected AICommonList itemList;
90 * inVocabulary is the parent Authority for this context
92 protected String inAuthority;
93 protected String authorityRefNameBase;
95 public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
96 this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
99 public String getInAuthority() {
103 public void setInAuthority(String inAuthority) {
104 this.inAuthority = inAuthority;
108 public String getUri(DocumentModel docModel) {
109 return getServiceContextPath()+inAuthority+"/"+ AuthorityClient.ITEMS+"/"+getCsid(docModel);
113 public String getAuthorityRefNameBase(){
114 return this.authorityRefNameBase;
117 public void setAuthorityRefNameBase(String value){
118 this.authorityRefNameBase = value;
122 * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleCreate(org.collectionspace.services.common.document.DocumentWrapper)
125 public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
126 // first fill all the parts of the document
127 super.handleCreate(wrapDoc);
128 handleInAuthority(wrapDoc.getWrappedObject());
129 // Uncomment once debugged and App layer is read to integrate
130 //handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityItemCommonSchemaName);
131 //updateRefnameForAuthorityItem(wrapDoc, authorityItemCommonSchemaName, getAuthorityRefNameBase()); //CSPACE-3178
134 private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
135 String shortIdentifier = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
136 String displayName = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
137 if (Tools.isEmpty(shortIdentifier) && Tools.notEmpty(displayName)){
138 String cookedShortIdentifier = Tools.squeeze(displayName)+'-'+Tools.now().toString();
139 docModel.setProperty(schemaName , AuthorityItemJAXBSchema.SHORT_IDENTIFIER, cookedShortIdentifier);
143 protected void updateRefnameForAuthorityItem(DocumentWrapper<DocumentModel> wrapDoc,
145 String authorityRefBaseName) throws Exception {
146 DocumentModel docModel = wrapDoc.getWrappedObject();
147 String shortIdentifier = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
148 String displayName = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
149 if (Tools.isEmpty(authorityRefBaseName)){
150 throw new Exception("updateRefnameForAuthorityItem requires an authorityRefBaseName, but none was supplied.");
152 RefName.Authority authority = RefName.Authority.parse(authorityRefBaseName);
153 String refName = RefName.buildAuthorityItem(authority, shortIdentifier, displayName).toString();
154 docModel.setProperty(schemaName , AuthorityItemJAXBSchema.REF_NAME, refName);
158 * Check the logic around the parent pointer. Note that we only need do this on
159 * create, since we have logic to make this read-only on update.
163 * @throws Exception the exception
165 private void handleInAuthority(DocumentModel docModel) throws Exception {
166 docModel.setProperty(authorityItemCommonSchemaName,
167 AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority);
172 * getCommonPart get associated item
176 public AICommon getCommonPart() {
181 public void setCommonPart(AICommon item) {
186 * getCommonPartList get associated item (for index/GET_ALL)
190 public AICommonList getCommonPartList() {
195 public void setCommonPartList(AICommonList itemList) {
196 this.itemList = itemList;
200 public AICommon extractCommonPart(DocumentWrapper<DocumentModel> wrapDoc)
202 throw new UnsupportedOperationException();
206 public void fillCommonPart(AICommon itemObject, DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
207 throw new UnsupportedOperationException();
211 * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
214 protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
216 Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
218 // Add the CSID to the common part
219 if (partMeta.getLabel().equalsIgnoreCase(authorityItemCommonSchemaName)) {
220 String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
221 unQObjectProperties.put("csid", csid);
224 return unQObjectProperties;
228 * Filters out AuthorityItemJAXBSchema.IN_AUTHORITY, to ensure that
229 * the parent link remains untouched.
230 * @param objectProps the properties parsed from the update payload
231 * @param partMeta metadata for the object to fill
234 public void filterReadOnlyPropertiesForPart(
235 Map<String, Object> objectProps, ObjectPartType partMeta) {
236 super.filterReadOnlyPropertiesForPart(objectProps, partMeta);
237 objectProps.remove(AuthorityItemJAXBSchema.IN_AUTHORITY);
238 objectProps.remove(AuthorityItemJAXBSchema.CSID);
242 public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
243 MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
244 super.extractAllParts(wrapDoc);
246 String showSiblings = ctx.getQueryParams().getFirst(CommonAPI.showSiblings_QP);
247 if (Tools.isTrue(showSiblings)) {
248 showSiblings(wrapDoc, ctx);
249 return; // actual result is returned on ctx.addOutputPart();
252 String showRelations = ctx.getQueryParams().getFirst(CommonAPI.showRelations_QP);
253 if (Tools.isTrue(showRelations)) {
254 showRelations(wrapDoc, ctx);
255 return; // actual result is returned on ctx.addOutputPart();
258 String showAllRelations = ctx.getQueryParams().getFirst(CommonAPI.showAllRelations_QP);
259 if (Tools.isTrue(showAllRelations)) {
260 showAllRelations(wrapDoc, ctx);
261 return; // actual result is returned on ctx.addOutputPart();
265 /** @return null on parent not found
267 protected String getParentCSID(String thisCSID) throws Exception {
268 String parentCSID = null;
270 String predicate = RelationshipType.HAS_BROADER.value();
271 RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
272 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
273 if (parentList != null) {
274 RelationsCommonList.RelationListItem relationListItem = parentList.get(0);
275 parentCSID = relationListItem.getObjectCsid();
278 } catch (Exception e) {
279 logger.error("Could not find parent for this: "+thisCSID, e);
284 public void showRelations(DocumentWrapper<DocumentModel> wrapDoc,
285 MultipartServiceContext ctx) throws Exception {
286 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
288 String predicate = RelationshipType.HAS_BROADER.value();
289 RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
290 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
292 RelationsCommonList childrenListOuter = getRelations(null, thisCSID, predicate);
293 List<RelationsCommonList.RelationListItem> childrenList = childrenListOuter.getRelationListItem();
295 //Assume that there are more children than parents. Will be true for parent/child, but maybe not for other relations.
296 //Now add all parents to our childrenList, to be able to return just one list of consolidated results.
297 //Not optimal, but that's the current design spec.
299 for (RelationsCommonList.RelationListItem parent : parentList) {
300 childrenList.add(parent);
303 long childrenSize = childrenList.size();
304 childrenListOuter.setTotalItems(childrenSize);
305 childrenListOuter.setItemsInPage(childrenListOuter.getItemsInPage()+added);
307 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, childrenListOuter);
308 ctx.addOutputPart(relationsPart);
311 public void showSiblings(DocumentWrapper<DocumentModel> wrapDoc,
312 MultipartServiceContext ctx) throws Exception {
313 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
314 String parentCSID = getParentCSID(thisCSID);
315 if (parentCSID == null){
316 logger.warn("~~~~~\r\n~~~~ Could not find parent for this: "+thisCSID);
320 String predicate = RelationshipType.HAS_BROADER.value();
321 RelationsCommonList siblingListOuter = getRelations(null, parentCSID, predicate);
322 List<RelationsCommonList.RelationListItem> siblingList = siblingListOuter.getRelationListItem();
324 List<RelationsCommonList.RelationListItem> toRemoveList = newList();
327 RelationsCommonList.RelationListItem item = null;
328 for (RelationsCommonList.RelationListItem sibling : siblingList) {
329 if (thisCSID.equals(sibling.getSubjectCsid())){
330 toRemoveList.add(sibling); //IS_A copy of the main item, i.e. I have a parent that is my parent, so I'm in the list from the above query.
333 //rather than create an immutable iterator, I'm just putting the items to remove on a separate list, then looping over that list and removing.
334 for (RelationsCommonList.RelationListItem self : toRemoveList) {
335 removeFromList(siblingList, self);
338 long siblingSize = siblingList.size();
339 siblingListOuter.setTotalItems(siblingSize);
340 siblingListOuter.setItemsInPage(siblingSize);
342 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME,siblingListOuter);
343 ctx.addOutputPart(relationsPart);
346 public void showAllRelations(DocumentWrapper<DocumentModel> wrapDoc, MultipartServiceContext ctx) throws Exception {
347 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
349 RelationsCommonList subjectListOuter = getRelations(thisCSID, null, null); // nulls are wildcards: predicate=*, and object=*
350 List<RelationsCommonList.RelationListItem> subjectList = subjectListOuter.getRelationListItem();
352 RelationsCommonList objectListOuter = getRelations(null, thisCSID, null); // nulls are wildcards: subject=*, and predicate=*
353 List<RelationsCommonList.RelationListItem> objectList = objectListOuter.getRelationListItem();
356 subjectList.addAll(objectList);
358 //now subjectList actually has records BOTH where thisCSID is subject and object.
359 long relatedSize = subjectList.size();
360 subjectListOuter.setTotalItems(relatedSize);
361 subjectListOuter.setItemsInPage(relatedSize);
363 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME,subjectListOuter);
364 ctx.addOutputPart(relationsPart);
367 public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
368 super.fillAllParts(wrapDoc, action);
369 ServiceContext ctx = getServiceContext();
370 PoxPayloadIn input = (PoxPayloadIn)ctx.getInput();
371 DocumentModel documentModel = (wrapDoc.getWrappedObject());
372 String itemCsid = documentModel.getName();
374 //UPDATE and CREATE will call. Updates relations part
375 RelationsCommonList relationsCommonList = updateRelations(itemCsid, input, wrapDoc);
377 PayloadOutputPart payloadOutputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, relationsCommonList);
378 ctx.setProperty(RelationClient.SERVICE_COMMON_LIST_NAME, payloadOutputPart);
381 public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
382 super.completeUpdate(wrapDoc);
383 //now we add part for relations list
384 ServiceContext ctx = getServiceContext();
385 PayloadOutputPart foo = (PayloadOutputPart)ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
386 ((PoxPayloadOut)ctx.getOutput()).addPart(foo);
389 public RelationsCommonList updateRelations(String itemCSID, PoxPayloadIn input, DocumentWrapper<DocumentModel> wrapDoc)
391 PayloadInputPart part = input.getPart(RelationClient.SERVICE_COMMON_LIST_NAME); //input.getPart("relations_common");
393 return null; //nothing to do--they didn't send a list of relations.
395 RelationsCommonList relationsCommonListBody = (RelationsCommonList) part.getBody();
397 ServiceContext ctx = getServiceContext();
398 UriInfo uriInfo = ctx.getUriInfo();
399 MultivaluedMap queryParams = uriInfo.getQueryParameters();
401 String predicate = RelationshipType.HAS_BROADER.value();
402 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
403 queryParams.putSingle(IRelationsManager.SUBJECT_QP, null);
404 queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
405 queryParams.putSingle(IRelationsManager.OBJECT_QP, itemCSID);
406 queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
408 RelationsCommonList childListOuter = (new RelationResource()).getList(ctx.getUriInfo()); //magically knows all query params because they are in the context.
410 //Leave predicate, swap subject and object.
411 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
412 queryParams.putSingle(IRelationsManager.SUBJECT_QP, itemCSID);
413 queryParams.putSingle(IRelationsManager.OBJECT_QP, null);
415 RelationsCommonList parentListOuter = (new RelationResource()).getList(ctx.getUriInfo());
417 go through inboundList, remove anything from childList that matches from childList
418 go through inboundList, remove anything from parentList that matches from parentList
419 go through parentList, delete all remaining
420 go through childList, delete all remaining
421 go through actionList, add all remaining.
422 check for duplicate children
423 check for more than one parent.
425 inboundList parentList childList actionList
426 ---------------- --------------- ---------------- ----------------
427 child-a parent-c child-a child-b
428 child-b parent-d child-c
431 String HAS_BROADER = RelationshipType.HAS_BROADER.value();
433 List<RelationsCommonList.RelationListItem> inboundList = relationsCommonListBody.getRelationListItem();
434 List<RelationsCommonList.RelationListItem> actionList = newList();
435 List<RelationsCommonList.RelationListItem> childList = childListOuter.getRelationListItem();
436 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
438 DocumentModel docModel = wrapDoc.getWrappedObject();
440 for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
441 if (inboundItem.getObject().getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
442 inboundItem.setObjectCsid(itemCSID);
443 inboundItem.getObject().setCsid(itemCSID);
444 inboundItem.getObject().setUri(getUri(docModel));
446 if (inboundItem.getSubject().getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
447 inboundItem.setSubjectCsid(itemCSID);
448 inboundItem.getSubject().setCsid(itemCSID);
449 inboundItem.getSubject().setUri(getUri(docModel));
451 if (inboundItem.getObject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
452 //then this is an item that says we have a child.
453 RelationsCommonList.RelationListItem childItem = findInList(childList, inboundItem);
454 if (childItem != null){
455 removeFromList(childList, childItem); //exists, just take it off delete list
457 actionList.add(inboundItem); //doesn't exist as a child, but is a child. Add to additions list
459 } else if (inboundItem.getSubject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
460 //then this is an item that says we have a parent
461 RelationsCommonList.RelationListItem parentItem = findInList(parentList, inboundItem);
462 if (parentItem != null){
463 removeFromList(parentList, parentItem); //exists, just take it off delete list
465 actionList.add(inboundItem); //doesn't exist as a parent, but is a parent. Add to additions list
469 System.out.println("\r\n\r\n================\r\n Element didn't match parent or child, but may have partial fields that match. inboundItem: "+inboundItem);
470 //not dealing with: hasNarrower or any other predicate.
473 deleteRelations(parentList, ctx); //todo: there are items appearing on both lists....april 20.
474 deleteRelations(childList, ctx);
475 createRelations(actionList, ctx);
476 //We return all elements on the inbound list, since we have just worked to make them exist in the system
477 // and be non-redundant, etc. That list came from relationsCommonListBody, so it is still attached to it, just pass that back.
478 return relationsCommonListBody;
481 // this method calls the RelationResource to have it create the relations and persist them.
482 private void createRelations(List<RelationsCommonList.RelationListItem> inboundList, ServiceContext ctx){
483 for (RelationsCommonList.RelationListItem item : inboundList) {
484 RelationsCommon rc = new RelationsCommon();
485 //rc.setCsid(item.getCsid());
486 //todo: assignTo(item, rc);
487 RelationsDocListItem itemSubject = item.getSubject();
488 RelationsDocListItem itemObject = item.getObject();
490 String subjectCsid = itemSubject.getCsid();
491 rc.setDocumentId1(subjectCsid);
492 rc.setSubjectCsid(subjectCsid);
494 String objCsid = item.getObject().getCsid();
495 rc.setDocumentId2(objCsid);
496 rc.setObjectCsid(objCsid);
498 rc.setRelationshipType(item.getPredicate());
499 //RelationshipType foo = (RelationshipType.valueOf(item.getPredicate())) ;
500 //rc.setPredicate(foo); //this must be one of the type found in the enum in services/jaxb/src/main/resources/relations_common.xsd
502 rc.setDocumentType1(itemSubject.getDocumentType());
503 rc.setDocumentType2(itemObject.getDocumentType());
505 rc.setSubjectUri(itemSubject.getUri());
506 rc.setObjectUri(itemObject.getUri());
509 PoxPayloadOut payloadOut = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
510 PayloadOutputPart outputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMONPART_NAME, rc);
511 payloadOut.addPart(outputPart);
512 //System.out.println("\r\n==== TO CREATE: "+rc.getDocumentId1()+"==>"+rc.getPredicate()+"==>"+rc.getDocumentId2());
513 RelationResource relationResource = new RelationResource();
514 Object res = relationResource.create(ctx.getUriInfo(), payloadOut.toXML()); //NOTE ui recycled from above to pass in unknown query params.
517 private void deleteRelations(List<RelationsCommonList.RelationListItem> list,ServiceContext ctx){
519 for (RelationsCommonList.RelationListItem inboundItem : list) {
520 RelationResource relationResource = new RelationResource();
521 //System.out.println("\r\n==== TO DELETE: "+inboundItem.getCsid());
522 Object res = relationResource.delete(inboundItem.getCsid());
524 } catch (Throwable t){
525 String msg = "Unable to deleteRelations: "+ Tools.errorToString(t, true);
530 private List<RelationsCommonList.RelationListItem> newList(){
531 List<RelationsCommonList.RelationListItem> result = new ArrayList<RelationsCommonList.RelationListItem>();
534 protected List<RelationsCommonList.RelationListItem> cloneList(List<RelationsCommonList.RelationListItem> inboundList){
535 List<RelationsCommonList.RelationListItem> result = newList();
536 for (RelationsCommonList.RelationListItem item: inboundList){
541 private RelationsCommonList.RelationListItem findInList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item){
542 for (RelationsCommonList.RelationListItem listItem : list) {
543 if (itemsEqual(listItem, item)){ //equals must be defined, else
550 private boolean itemsEqual(RelationsCommonList.RelationListItem item, RelationsCommonList.RelationListItem item2){
551 if (item==null || item2==null){
554 RelationsDocListItem subj1 = item.getSubject();
555 RelationsDocListItem subj2 = item2.getSubject();
556 RelationsDocListItem obj1 = item.getObject();
557 RelationsDocListItem obj2 = item2.getObject();
559 return (subj1.getCsid().equals(subj2.getCsid()))
560 && (obj1.getCsid().equals(obj1.getCsid()))
561 && ( (item.getPredicate().equals(item2.getPredicate()))
562 && (item.getRelationshipType().equals(item2.getRelationshipType())) )
563 && (obj1.getDocumentType().equals(obj2.getDocumentType()))
564 && (subj1.getDocumentType().equals(subj2.getDocumentType())) ;
567 private void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item){
570 //================= TODO: move this to common, refactoring this and CollectionObjectResource.java
572 public RelationsCommonList getRelations(String subjectCSID, String objectCSID, String predicate) throws Exception {
573 ServiceContext ctx = getServiceContext();
574 MultivaluedMap queryParams = ctx.getQueryParams();
575 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
576 queryParams.putSingle(IRelationsManager.SUBJECT_QP, subjectCSID);
577 queryParams.putSingle(IRelationsManager.OBJECT_QP, objectCSID);
579 RelationResource relationResource = new RelationResource();
580 RelationsCommonList relationsCommonList = relationResource.getList(ctx.getUriInfo());
581 return relationsCommonList;
584 //============================= END refactor ==========================