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 org.collectionspace.services.client.AuthorityClient;
27 import org.collectionspace.services.client.PayloadInputPart;
28 import org.collectionspace.services.client.PayloadOutputPart;
29 import org.collectionspace.services.client.PoxPayloadIn;
30 import org.collectionspace.services.client.PoxPayloadOut;
31 import org.collectionspace.services.client.RelationClient;
32 import org.collectionspace.services.common.api.CommonAPI;
33 import org.collectionspace.services.common.api.RefName;
34 import org.collectionspace.services.common.api.Tools;
35 import org.collectionspace.services.common.context.MultipartServiceContext;
36 import org.collectionspace.services.common.context.ServiceContext;
37 import org.collectionspace.services.common.document.DocumentWrapper;
38 import org.collectionspace.services.common.document.DocumentWrapperImpl;
39 import org.collectionspace.services.common.relation.IRelationsManager;
40 import org.collectionspace.services.common.repository.RepositoryClient;
41 import org.collectionspace.services.common.repository.RepositoryClientFactory;
42 import org.collectionspace.services.common.service.ObjectPartType;
43 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
44 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
45 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
46 import org.collectionspace.services.relation.RelationResource;
47 import org.collectionspace.services.relation.RelationsCommon;
48 import org.collectionspace.services.relation.RelationsCommonList;
49 import org.collectionspace.services.relation.RelationsDocListItem;
50 import org.collectionspace.services.relation.RelationshipType;
51 import org.nuxeo.ecm.core.api.DocumentModel;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import javax.ws.rs.core.MultivaluedMap;
56 import javax.ws.rs.core.UriInfo;
57 import java.util.ArrayList;
58 import java.util.List;
60 import java.util.regex.Matcher;
61 import java.util.regex.Pattern;
63 //import org.collectionspace.services.common.authority.AuthorityItemRelations;
66 * AuthorityItemDocumentModelHandler
68 * $LastChangedRevision: $
71 public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
72 extends RemoteDocumentModelHandlerImpl<AICommon, AICommonList> {
74 private final Logger logger = LoggerFactory.getLogger(AuthorityItemDocumentModelHandler.class);
76 private String authorityItemCommonSchemaName;
78 //private final Logger logger = LoggerFactory.getLogger(AuthorityItemDocumentModelHandler.class);
80 * item is used to stash JAXB object to use when handle is called
81 * for Action.CREATE, Action.UPDATE or Action.GET
83 protected AICommon item;
85 * itemList is stashed when handle is called
88 protected AICommonList itemList;
91 * inVocabulary is the parent Authority for this context
93 protected String inAuthority;
94 protected String authorityRefNameBase;
96 public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
97 this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
100 public String getInAuthority() {
104 public void setInAuthority(String inAuthority) {
105 this.inAuthority = inAuthority;
108 /** Subclasses may override this to customize the URI segment. */
109 public String getAuthorityServicePath(){
110 return getServiceContext().getServiceName().toLowerCase(); // Laramie20110510 CSPACE-3932
114 public String getUri(DocumentModel docModel) {
115 // Laramie20110510 CSPACE-3932
116 String authorityServicePath = getAuthorityServicePath();
117 return "/"+authorityServicePath+'/'+inAuthority+'/'+ AuthorityClient.ITEMS+'/'+getCsid(docModel);
120 public String getAuthorityRefNameBase(){
121 return this.authorityRefNameBase;
124 public void setAuthorityRefNameBase(String value){
125 this.authorityRefNameBase = value;
129 * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleCreate(org.collectionspace.services.common.document.DocumentWrapper)
132 public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
133 // first fill all the parts of the document
134 super.handleCreate(wrapDoc);
135 handleInAuthority(wrapDoc.getWrappedObject());
136 // Uncomment once debugged and App layer is read to integrate
137 //handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityItemCommonSchemaName);
138 //updateRefnameForAuthorityItem(wrapDoc, authorityItemCommonSchemaName, getAuthorityRefNameBase()); //CSPACE-3178
141 private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
142 String shortIdentifier = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
143 String displayName = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
144 if (Tools.isEmpty(shortIdentifier) && Tools.notEmpty(displayName)){
145 String cookedShortIdentifier = Tools.squeeze(displayName)+'-'+Tools.now().toString();
146 docModel.setProperty(schemaName , AuthorityItemJAXBSchema.SHORT_IDENTIFIER, cookedShortIdentifier);
150 protected void updateRefnameForAuthorityItem(DocumentWrapper<DocumentModel> wrapDoc,
152 String authorityRefBaseName) throws Exception {
153 DocumentModel docModel = wrapDoc.getWrappedObject();
154 String shortIdentifier = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
155 String displayName = (String)docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
156 if (Tools.isEmpty(authorityRefBaseName)){
157 throw new Exception("updateRefnameForAuthorityItem requires an authorityRefBaseName, but none was supplied.");
159 RefName.Authority authority = RefName.Authority.parse(authorityRefBaseName);
160 String refName = RefName.buildAuthorityItem(authority, shortIdentifier, displayName).toString();
161 docModel.setProperty(schemaName , AuthorityItemJAXBSchema.REF_NAME, refName);
165 * Check the logic around the parent pointer. Note that we only need do this on
166 * create, since we have logic to make this read-only on update.
170 * @throws Exception the exception
172 private void handleInAuthority(DocumentModel docModel) throws Exception {
173 docModel.setProperty(authorityItemCommonSchemaName,
174 AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority);
179 * getCommonPart get associated item
183 public AICommon getCommonPart() {
188 public void setCommonPart(AICommon item) {
193 * getCommonPartList get associated item (for index/GET_ALL)
197 public AICommonList getCommonPartList() {
202 public void setCommonPartList(AICommonList itemList) {
203 this.itemList = itemList;
207 public AICommon extractCommonPart(DocumentWrapper<DocumentModel> wrapDoc)
209 throw new UnsupportedOperationException();
213 public void fillCommonPart(AICommon itemObject, DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
214 throw new UnsupportedOperationException();
218 * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
221 protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
223 Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
225 // Add the CSID to the common part
226 if (partMeta.getLabel().equalsIgnoreCase(authorityItemCommonSchemaName)) {
227 String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
228 unQObjectProperties.put("csid", csid);
231 return unQObjectProperties;
235 * Filters out AuthorityItemJAXBSchema.IN_AUTHORITY, to ensure that
236 * the parent link remains untouched.
237 * @param objectProps the properties parsed from the update payload
238 * @param partMeta metadata for the object to fill
241 public void filterReadOnlyPropertiesForPart(
242 Map<String, Object> objectProps, ObjectPartType partMeta) {
243 super.filterReadOnlyPropertiesForPart(objectProps, partMeta);
244 objectProps.remove(AuthorityItemJAXBSchema.IN_AUTHORITY);
245 objectProps.remove(AuthorityItemJAXBSchema.CSID);
249 public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
250 MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
251 super.extractAllParts(wrapDoc);
253 String showSiblings = ctx.getQueryParams().getFirst(CommonAPI.showSiblings_QP);
254 if (Tools.isTrue(showSiblings)) {
255 showSiblings(wrapDoc, ctx);
256 return; // actual result is returned on ctx.addOutputPart();
259 String showRelations = ctx.getQueryParams().getFirst(CommonAPI.showRelations_QP);
260 if (Tools.isTrue(showRelations)) {
261 showRelations(wrapDoc, ctx);
262 return; // actual result is returned on ctx.addOutputPart();
265 String showAllRelations = ctx.getQueryParams().getFirst(CommonAPI.showAllRelations_QP);
266 if (Tools.isTrue(showAllRelations)) {
267 showAllRelations(wrapDoc, ctx);
268 return; // actual result is returned on ctx.addOutputPart();
272 /** @return null on parent not found
274 protected String getParentCSID(String thisCSID) throws Exception {
275 String parentCSID = null;
277 String predicate = RelationshipType.HAS_BROADER.value();
278 RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
279 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
280 if (parentList != null) {
281 RelationsCommonList.RelationListItem relationListItem = parentList.get(0);
282 parentCSID = relationListItem.getObjectCsid();
285 } catch (Exception e) {
286 logger.error("Could not find parent for this: "+thisCSID, e);
291 public void showRelations(DocumentWrapper<DocumentModel> wrapDoc,
292 MultipartServiceContext ctx) throws Exception {
293 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
295 String predicate = RelationshipType.HAS_BROADER.value();
296 RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
297 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
299 RelationsCommonList childrenListOuter = getRelations(null, thisCSID, predicate);
300 List<RelationsCommonList.RelationListItem> childrenList = childrenListOuter.getRelationListItem();
302 //Assume that there are more children than parents. Will be true for parent/child, but maybe not for other relations.
303 //Now add all parents to our childrenList, to be able to return just one list of consolidated results.
304 //Not optimal, but that's the current design spec.
306 for (RelationsCommonList.RelationListItem parent : parentList) {
307 childrenList.add(parent);
310 long childrenSize = childrenList.size();
311 childrenListOuter.setTotalItems(childrenSize);
312 childrenListOuter.setItemsInPage(childrenListOuter.getItemsInPage()+added);
314 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, childrenListOuter);
315 ctx.addOutputPart(relationsPart);
318 public void showSiblings(DocumentWrapper<DocumentModel> wrapDoc,
319 MultipartServiceContext ctx) throws Exception {
320 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
321 String parentCSID = getParentCSID(thisCSID);
322 if (parentCSID == null){
323 logger.warn("~~~~~\r\n~~~~ Could not find parent for this: "+thisCSID);
327 String predicate = RelationshipType.HAS_BROADER.value();
328 RelationsCommonList siblingListOuter = getRelations(null, parentCSID, predicate);
329 List<RelationsCommonList.RelationListItem> siblingList = siblingListOuter.getRelationListItem();
331 List<RelationsCommonList.RelationListItem> toRemoveList = newList();
334 RelationsCommonList.RelationListItem item = null;
335 for (RelationsCommonList.RelationListItem sibling : siblingList) {
336 if (thisCSID.equals(sibling.getSubjectCsid())){
337 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.
340 //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.
341 for (RelationsCommonList.RelationListItem self : toRemoveList) {
342 removeFromList(siblingList, self);
345 long siblingSize = siblingList.size();
346 siblingListOuter.setTotalItems(siblingSize);
347 siblingListOuter.setItemsInPage(siblingSize);
349 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME,siblingListOuter);
350 ctx.addOutputPart(relationsPart);
353 public void showAllRelations(DocumentWrapper<DocumentModel> wrapDoc, MultipartServiceContext ctx) throws Exception {
354 String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
356 RelationsCommonList subjectListOuter = getRelations(thisCSID, null, null); // nulls are wildcards: predicate=*, and object=*
357 List<RelationsCommonList.RelationListItem> subjectList = subjectListOuter.getRelationListItem();
359 RelationsCommonList objectListOuter = getRelations(null, thisCSID, null); // nulls are wildcards: subject=*, and predicate=*
360 List<RelationsCommonList.RelationListItem> objectList = objectListOuter.getRelationListItem();
363 subjectList.addAll(objectList);
365 //now subjectList actually has records BOTH where thisCSID is subject and object.
366 long relatedSize = subjectList.size();
367 subjectListOuter.setTotalItems(relatedSize);
368 subjectListOuter.setItemsInPage(relatedSize);
370 PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME,subjectListOuter);
371 ctx.addOutputPart(relationsPart);
374 public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
375 super.fillAllParts(wrapDoc, action);
376 ServiceContext ctx = getServiceContext();
377 PoxPayloadIn input = (PoxPayloadIn)ctx.getInput();
378 DocumentModel documentModel = (wrapDoc.getWrappedObject());
379 String itemCsid = documentModel.getName();
381 //UPDATE and CREATE will call. Updates relations part
382 RelationsCommonList relationsCommonList = updateRelations(itemCsid, input, wrapDoc);
384 PayloadOutputPart payloadOutputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, relationsCommonList);
385 ctx.setProperty(RelationClient.SERVICE_COMMON_LIST_NAME, payloadOutputPart);
388 public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
389 super.completeUpdate(wrapDoc);
390 //now we add part for relations list
391 ServiceContext ctx = getServiceContext();
392 PayloadOutputPart foo = (PayloadOutputPart)ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
393 ((PoxPayloadOut)ctx.getOutput()).addPart(foo);
396 /** updateRelations strategy:
398 go through inboundList, remove anything from childList that matches from childList
399 go through inboundList, remove anything from parentList that matches from parentList
400 go through parentList, delete all remaining
401 go through childList, delete all remaining
402 go through actionList, add all remaining.
403 check for duplicate children
404 check for more than one parent.
406 inboundList parentList childList actionList
407 ---------------- --------------- ---------------- ----------------
408 child-a parent-c child-a child-b
409 child-b parent-d child-c
412 public RelationsCommonList updateRelations(String itemCSID, PoxPayloadIn input, DocumentWrapper<DocumentModel> wrapDoc)
414 PayloadInputPart part = input.getPart(RelationClient.SERVICE_COMMON_LIST_NAME); //input.getPart("relations_common");
416 return null; //nothing to do--they didn't send a list of relations.
418 RelationsCommonList relationsCommonListBody = (RelationsCommonList) part.getBody();
420 ServiceContext ctx = getServiceContext();
421 UriInfo uriInfo = ctx.getUriInfo();
422 MultivaluedMap queryParams = uriInfo.getQueryParameters();
424 //Run getList() once as sent to get childListOuter:
425 String predicate = RelationshipType.HAS_BROADER.value();
426 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
427 queryParams.putSingle(IRelationsManager.SUBJECT_QP, null);
428 queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
429 queryParams.putSingle(IRelationsManager.OBJECT_QP, itemCSID);
430 queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
431 RelationsCommonList childListOuter = (new RelationResource()).getList(ctx.getUriInfo()); //magically knows all query params because they are in the context.
433 //Now run getList() again, leaving predicate, swapping subject and object, to get parentListOuter.
434 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
435 queryParams.putSingle(IRelationsManager.SUBJECT_QP, itemCSID);
436 queryParams.putSingle(IRelationsManager.OBJECT_QP, null);
437 RelationsCommonList parentListOuter = (new RelationResource()).getList(ctx.getUriInfo());
439 String HAS_BROADER = RelationshipType.HAS_BROADER.value();
441 List<RelationsCommonList.RelationListItem> inboundList = relationsCommonListBody.getRelationListItem();
442 List<RelationsCommonList.RelationListItem> actionList = newList();
443 List<RelationsCommonList.RelationListItem> childList = childListOuter.getRelationListItem();
444 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
446 DocumentModel docModel = wrapDoc.getWrappedObject();
448 //Do magic replacement of ${itemCSID} and fix URI's.
449 fixupInboundListItems(ctx, inboundList, docModel, itemCSID);
451 for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
452 if (inboundItem.getObject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
453 //then this is an item that says we have a child.
454 RelationsCommonList.RelationListItem childItem = findInList(childList, inboundItem);
455 if (childItem != null){
456 removeFromList(childList, childItem); //exists, just take it off delete list
458 actionList.add(inboundItem); //doesn't exist as a child, but is a child. Add to additions list
460 } else if (inboundItem.getSubject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
461 //then this is an item that says we have a parent
462 RelationsCommonList.RelationListItem parentItem = findInList(parentList, inboundItem);
463 if (parentItem != null){
464 removeFromList(parentList, parentItem); //exists, just take it off delete list
466 actionList.add(inboundItem); //doesn't exist as a parent, but is a parent. Add to additions list
469 logger.warn("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 /** Performs substitution for ${itemCSID} (see CommonAPI.AuthorityItemCSID_REPLACE for constant)
482 * and sets URI correctly for related items.
483 * Operates directly on the items in the list. Does not change the list ordering, does not add or remove any items.
485 protected void fixupInboundListItems(ServiceContext ctx,
486 List<RelationsCommonList.RelationListItem> inboundList,
487 DocumentModel docModel,
488 String itemCSID) throws Exception {
489 String thisURI = this.getUri(docModel);
490 // WARNING: the two code blocks below are almost identical and seem to ask to be put in a generic method.
491 // beware of the little diffs in inboundItem.setObjectCsid(itemCSID); and inboundItem.setSubjectCsid(itemCSID); in the two blocks.
492 for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
493 RelationsDocListItem inboundItemObject = inboundItem.getObject();
494 RelationsDocListItem inboundItemSubject = inboundItem.getSubject();
496 if (inboundItemObject.getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
497 inboundItem.setObjectCsid(itemCSID);
498 inboundItemObject.setCsid(itemCSID);
499 inboundItemObject.setUri(getUri(docModel));
501 String objectCsid = inboundItemObject.getCsid();
502 DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, objectCsid); //null if not found.
503 DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
504 String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
505 inboundItemObject.setUri(uri); //CSPACE-4037
507 uriPointsToSameAuthority(thisURI, inboundItemObject.getUri()); //CSPACE-4042
509 if (inboundItemSubject.getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
510 inboundItem.setSubjectCsid(itemCSID);
511 inboundItemSubject.setCsid(itemCSID);
512 inboundItemSubject.setUri(getUri(docModel));
514 String subjectCsid =inboundItemSubject.getCsid();
515 DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, subjectCsid); //null if not found.
516 DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
517 String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
518 inboundItemSubject.setUri(uri); //CSPACE-4037
520 uriPointsToSameAuthority(thisURI, inboundItemSubject.getUri()); //CSPACE-4042
525 public RepositoryClient getRepositoryClient(ServiceContext ctx) {
526 RepositoryClient repositoryClient = RepositoryClientFactory.getInstance().getClient(ctx.getRepositoryClientName());
527 return repositoryClient;
530 // this method calls the RelationResource to have it create the relations and persist them.
531 private void createRelations(List<RelationsCommonList.RelationListItem> inboundList, ServiceContext ctx){
532 for (RelationsCommonList.RelationListItem item : inboundList) {
533 RelationsCommon rc = new RelationsCommon();
534 //rc.setCsid(item.getCsid());
535 //todo: assignTo(item, rc);
536 RelationsDocListItem itemSubject = item.getSubject();
537 RelationsDocListItem itemObject = item.getObject();
539 String subjectCsid = itemSubject.getCsid();
540 rc.setDocumentId1(subjectCsid);
541 rc.setSubjectCsid(subjectCsid);
543 String objCsid = item.getObject().getCsid();
544 rc.setDocumentId2(objCsid);
545 rc.setObjectCsid(objCsid);
547 rc.setRelationshipType(item.getPredicate());
548 //RelationshipType foo = (RelationshipType.valueOf(item.getPredicate())) ;
549 //rc.setPredicate(foo); //this must be one of the type found in the enum in services/jaxb/src/main/resources/relations_common.xsd
551 rc.setDocumentType1(itemSubject.getDocumentType());
552 rc.setDocumentType2(itemObject.getDocumentType());
554 rc.setSubjectUri(itemSubject.getUri());
555 rc.setObjectUri(itemObject.getUri());
558 PoxPayloadOut payloadOut = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
559 PayloadOutputPart outputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMONPART_NAME, rc);
560 payloadOut.addPart(outputPart);
561 //System.out.println("\r\n==== TO CREATE: "+rc.getDocumentId1()+"==>"+rc.getPredicate()+"==>"+rc.getDocumentId2());
562 RelationResource relationResource = new RelationResource();
563 Object res = relationResource.create(ctx.getUriInfo(), payloadOut.toXML()); //NOTE ui recycled from above to pass in unknown query params.
566 private void deleteRelations(List<RelationsCommonList.RelationListItem> list,ServiceContext ctx){
568 for (RelationsCommonList.RelationListItem inboundItem : list) {
569 RelationResource relationResource = new RelationResource();
570 //System.out.println("\r\n==== TO DELETE: "+inboundItem.getCsid());
571 Object res = relationResource.delete(inboundItem.getCsid());
573 } catch (Throwable t){
574 String msg = "Unable to deleteRelations: "+ Tools.errorToString(t, true);
579 private List<RelationsCommonList.RelationListItem> newList(){
580 List<RelationsCommonList.RelationListItem> result = new ArrayList<RelationsCommonList.RelationListItem>();
583 protected List<RelationsCommonList.RelationListItem> cloneList(List<RelationsCommonList.RelationListItem> inboundList){
584 List<RelationsCommonList.RelationListItem> result = newList();
585 for (RelationsCommonList.RelationListItem item: inboundList){
590 private RelationsCommonList.RelationListItem findInList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item){
591 for (RelationsCommonList.RelationListItem listItem : list) {
592 if (itemsEqual(listItem, item)){ //equals must be defined, else
599 private boolean itemsEqual(RelationsCommonList.RelationListItem item, RelationsCommonList.RelationListItem item2){
600 if (item==null || item2==null){
603 RelationsDocListItem subj1 = item.getSubject();
604 RelationsDocListItem subj2 = item2.getSubject();
605 RelationsDocListItem obj1 = item.getObject();
606 RelationsDocListItem obj2 = item2.getObject();
608 return (subj1.getCsid().equals(subj2.getCsid()))
609 && (obj1.getCsid().equals(obj1.getCsid()))
610 && ( (item.getPredicate().equals(item2.getPredicate()))
611 && (item.getRelationshipType().equals(item2.getRelationshipType())) )
612 && (obj1.getDocumentType().equals(obj2.getDocumentType()))
613 && (subj1.getDocumentType().equals(subj2.getDocumentType())) ;
616 private void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item){
620 /* don't even THINK of re-using this method.
621 * String example_uri = "/locationauthorities/7ec60f01-84ab-4908-9a6a/items/a5466530-713f-43b4-bc05";
623 private String extractInAuthorityCSID(String uri){
624 String IN_AUTHORITY_REGEX = "/(.*?)/(.*?)/(.*)";
625 Pattern p = Pattern.compile(IN_AUTHORITY_REGEX);
626 Matcher m = p.matcher(uri);
628 if (m.groupCount()<3){
629 logger.warn("REGEX-WRONG-GROUPCOUNT looking in "+uri);
632 //String service = m.group(1);
633 String inauth = m.group(2);
634 //String theRest = m.group(3);
636 //print("service:"+service+", inauth:"+inauth+", rest:"+rest);
639 logger.warn("REGEX-NOT-MATCHED looking in "+uri);
644 //ensures CSPACE-4042
645 protected void uriPointsToSameAuthority(String thisURI, String inboundItemURI) throws Exception {
646 String authorityCSID = extractInAuthorityCSID(thisURI);
647 String authorityCSIDForInbound = extractInAuthorityCSID(inboundItemURI);
648 if ( Tools.isBlank(authorityCSID)
649 || Tools.isBlank(authorityCSIDForInbound)
650 || ( ! authorityCSID.equalsIgnoreCase(authorityCSIDForInbound) )
652 throw new Exception("Item URI "+thisURI+" must point to same authority as related item: "+inboundItemURI);
656 //================= TODO: move this to common, refactoring this and CollectionObjectResource.java
657 public RelationsCommonList getRelations(String subjectCSID, String objectCSID, String predicate) throws Exception {
658 ServiceContext ctx = getServiceContext();
659 MultivaluedMap queryParams = ctx.getQueryParams();
660 queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
661 queryParams.putSingle(IRelationsManager.SUBJECT_QP, subjectCSID);
662 queryParams.putSingle(IRelationsManager.OBJECT_QP, objectCSID);
664 RelationResource relationResource = new RelationResource();
665 RelationsCommonList relationsCommonList = relationResource.getList(ctx.getUriInfo());
666 return relationsCommonList;
668 //============================= END TODO refactor ==========================