]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5492: Cleaning up some of the tangled dependency issues related to refactoring...
authorRichard Millet <richard.millet@berkeley.edu>
Thu, 30 Aug 2012 00:01:18 +0000 (17:01 -0700)
committerRichard Millet <richard.millet@berkeley.edu>
Thu, 30 Aug 2012 00:01:18 +0000 (17:01 -0700)
23 files changed:
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java
services/blob/client/src/test/java/org/collectionspace/services/client/test/BlobScaleTest.java
services/client/src/main/java/org/collectionspace/services/client/IRelationsManager.java
services/client/src/main/java/org/collectionspace/services/client/Profiler.java [moved from services/common/src/main/java/org/collectionspace/services/common/profile/Profiler.java with 95% similarity]
services/common/pom.xml
services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java
services/common/src/main/java/org/collectionspace/services/common/document/Hierarchy.java [moved from services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/Hierarchy.java with 97% similarity]
services/common/src/main/java/org/collectionspace/services/common/profile/CSpaceFilter.java
services/common/src/main/java/org/collectionspace/services/common/relation/IRelationsManager.java
services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java [moved from services/relation/service/src/main/java/org/collectionspace/services/relation/RelationResource.java with 95% similarity]
services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/contact/client/pom.xml
services/person/client/pom.xml
services/person/jaxb/pom.xml
services/relation/client/pom.xml
services/relation/client/src/main/java/org/collectionspace/services/client/RelationClient.java
services/relation/client/src/main/java/org/collectionspace/services/client/RelationProxy.java
services/relation/client/src/test/java/org/collectionspace/services/client/test/RelationServiceTest.java
services/relation/service/src/main/java/org/collectionspace/services/relation/RelationResource.txt [new file with mode: 0644]

index 567fa058022de4ef1088953f5916282f1eb9ff03..0d22a5bfd733f20b8da4a96c3a299b259387829e 100644 (file)
@@ -46,6 +46,7 @@ import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.document.Hierarchy;
 import org.collectionspace.services.common.query.QueryManager;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
index 22919c7aa04215ba8e64eca2ba8f0be9c676fb5e..2202b1603f8dc79b29468dcd11a31263623ad447 100644 (file)
@@ -25,25 +25,18 @@ package org.collectionspace.services.common.vocabulary.nuxeo;
 
 import org.collectionspace.services.client.AuthorityClient;
 import org.collectionspace.services.client.IQueryManager;
-import org.collectionspace.services.client.PayloadInputPart;
-import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
-import org.collectionspace.services.client.RelationClient;
 
-import org.collectionspace.services.common.ResourceBase;
 import org.collectionspace.services.common.api.CommonAPI;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.Tools;
 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
 import org.collectionspace.services.common.context.MultipartServiceContext;
-import org.collectionspace.services.common.context.ServiceBindingUtils;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentWrapper;
-import org.collectionspace.services.common.relation.IRelationsManager;
-import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
@@ -55,11 +48,8 @@ import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
 import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 
-import org.collectionspace.services.relation.RelationResource;
-import org.collectionspace.services.relation.RelationsCommon;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationsDocListItem;
-import org.collectionspace.services.relation.RelationshipType;
 
 import org.collectionspace.services.vocabulary.VocabularyItemJAXBSchema;
 
@@ -72,8 +62,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -102,8 +90,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
     protected String authorityRefNameBase = null;
     // Used to determine when the displayName changes as part of the update.
     protected String oldDisplayNameOnUpdate = null;
-    protected String oldRefNameOnUpdate = null;
-    protected String newRefNameOnUpdate = null;
 
     public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
         this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
@@ -315,16 +301,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         }
     }
 
-    /**
-     * Handle display name.
-     *
-     * @param docModel the doc model
-     * @throws Exception the exception
-     */
-//    protected void handleComputedDisplayNames(DocumentModel docModel) throws Exception {
-//        // Do nothing by default.
-//    }
-
     /**
      * Handle refName updates for changes to display name.
      * Assumes refName is already correct. Just ensures it is right.
@@ -347,39 +323,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         return updatedRefName;
     }
     
-    /*
-     * Note: The Vocabulary document handler overrides this method.
-     */
-    protected String getRefPropName() {
-       return ServiceBindingUtils.AUTH_REF_PROP;
-    }
-
-    /**
-     * Checks to see if the refName has changed, and if so, 
-     * uses utilities to find all references and update them.
-     * @throws Exception 
-     */
-    protected void handleItemRefNameReferenceUpdate() throws Exception {
-        if (newRefNameOnUpdate != null && oldRefNameOnUpdate != null) {
-            // We have work to do.
-            if (logger.isDebugEnabled()) {
-                String eol = System.getProperty("line.separator");
-                logger.debug("Need to find and update references to Item." + eol
-                        + "   Old refName" + oldRefNameOnUpdate + eol
-                        + "   New refName" + newRefNameOnUpdate);
-            }
-            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
-            RepositoryClient repoClient = getRepositoryClient(ctx);
-            String refNameProp = getRefPropName();
-
-            int nUpdated = RefNameServiceUtils.updateAuthorityRefDocs(ctx, repoClient, this.getRepositorySession(),
-                    oldRefNameOnUpdate, newRefNameOnUpdate, refNameProp);
-            if (logger.isDebugEnabled()) {
-                logger.debug("Updated " + nUpdated + " instances of oldRefName to newRefName");
-            }
-        }
-    }
-
     /**
      * If no short identifier was provided in the input payload, generate a
      * short identifier from the preferred term display name or term name.
@@ -451,7 +394,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
                 AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority);
     }
     
-    
     public AuthorityRefDocList getReferencingObjects(
                ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
                List<String> serviceTypes,
@@ -505,7 +447,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         return authRefDocList;
     }
 
-
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
      */
@@ -642,124 +583,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         }
     }
 
-    /** @return null on parent not found
-     */
-    protected String getParentCSID(String thisCSID) throws Exception {
-        String parentCSID = null;
-        try {
-            String predicate = RelationshipType.HAS_BROADER.value();
-            RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
-            List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
-            if (parentList != null) {
-                if (parentList.size() == 0) {
-                    return null;
-                }
-                RelationsCommonList.RelationListItem relationListItem = parentList.get(0);
-                parentCSID = relationListItem.getObjectCsid();
-            }
-            return parentCSID;
-        } catch (Exception e) {
-            logger.error("Could not find parent for this: " + thisCSID, e);
-            return null;
-        }
-    }
-
-    public void showRelations(DocumentWrapper<DocumentModel> wrapDoc,
-            MultipartServiceContext ctx) throws Exception {
-        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
-
-        String predicate = RelationshipType.HAS_BROADER.value();
-        RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
-        List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
-
-        RelationsCommonList childrenListOuter = getRelations(null, thisCSID, predicate);
-        List<RelationsCommonList.RelationListItem> childrenList = childrenListOuter.getRelationListItem();
-
-        if(logger.isTraceEnabled()) {
-            String dump = dumpLists(thisCSID, parentList, childrenList, null);
-            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
-        }
-        
-        //Assume that there are more children than parents.  Will be true for parent/child, but maybe not for other relations.
-        //Now add all parents to our childrenList, to be able to return just one list of consolidated results.
-        //Not optimal, but that's the current design spec.
-        long added = 0;
-        for (RelationsCommonList.RelationListItem parent : parentList) {
-            childrenList.add(parent);
-            added++;
-        }
-        long childrenSize = childrenList.size();
-        childrenListOuter.setTotalItems(childrenSize);
-        childrenListOuter.setItemsInPage(childrenListOuter.getItemsInPage() + added);
-
-        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, childrenListOuter);
-        ctx.addOutputPart(relationsPart);
-    }
-
-    public void showSiblings(DocumentWrapper<DocumentModel> wrapDoc,
-            MultipartServiceContext ctx) throws Exception {
-        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
-        String parentCSID = getParentCSID(thisCSID);
-        if (parentCSID == null) {
-            logger.warn("~~~~~\r\n~~~~ Could not find parent for this: " + thisCSID);
-            return;
-        }
-
-        String predicate = RelationshipType.HAS_BROADER.value();
-        RelationsCommonList siblingListOuter = getRelations(null, parentCSID, predicate);
-        List<RelationsCommonList.RelationListItem> siblingList = siblingListOuter.getRelationListItem();
-
-        List<RelationsCommonList.RelationListItem> toRemoveList = newList();
-
-
-        RelationsCommonList.RelationListItem item = null;
-        for (RelationsCommonList.RelationListItem sibling : siblingList) {
-            if (thisCSID.equals(sibling.getSubjectCsid())) {
-                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.
-            }
-        }
-        //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.
-        for (RelationsCommonList.RelationListItem self : toRemoveList) {
-            removeFromList(siblingList, self);
-        }
-
-        long siblingSize = siblingList.size();
-        siblingListOuter.setTotalItems(siblingSize);
-        siblingListOuter.setItemsInPage(siblingSize);
-        if(logger.isTraceEnabled()) {
-            String dump = dumpList(siblingList, "Siblings of: "+thisCSID);
-            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showSiblings ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
-        }
-
-        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, siblingListOuter);
-        ctx.addOutputPart(relationsPart);
-    }
-
-    public void showAllRelations(DocumentWrapper<DocumentModel> wrapDoc, MultipartServiceContext ctx) throws Exception {
-        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
-
-        RelationsCommonList subjectListOuter = getRelations(thisCSID, null, null);   //  nulls are wildcards:  predicate=*, and object=*
-        List<RelationsCommonList.RelationListItem> subjectList = subjectListOuter.getRelationListItem();
-
-        RelationsCommonList objectListOuter = getRelations(null, thisCSID, null);   //  nulls are wildcards:  subject=*, and predicate=*
-        List<RelationsCommonList.RelationListItem> objectList = objectListOuter.getRelationListItem();
-
-        if(logger.isTraceEnabled()) {
-            String dump = dumpLists(thisCSID, subjectList, objectList, null);
-            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showAllRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
-        }
-        //  MERGE LISTS:
-        subjectList.addAll(objectList);
-
-        //now subjectList actually has records BOTH where thisCSID is subject and object.
-        long relatedSize = subjectList.size();
-        subjectListOuter.setTotalItems(relatedSize);
-        subjectListOuter.setItemsInPage(relatedSize);
-
-        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, subjectListOuter);
-        ctx.addOutputPart(relationsPart);
-    }
-
     @Override
     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
        //
@@ -769,401 +592,14 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         super.fillAllParts(wrapDoc, action);
     }
 
-    @Override
-    public void completeCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
-        super.completeCreate(wrapDoc);
-        handleRelationsPayload(wrapDoc, false);
-    }
-
-    @Override
-    public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
-        super.completeUpdate(wrapDoc);
-        handleRelationsPayload(wrapDoc, true);
-        handleItemRefNameReferenceUpdate();
-    }
-
-    // Note that we must do this after we have completed the Update, so that the repository has the
-    // info for the item itself. The relations code must call into the repo to get info for each end.
-    // This could be optimized to pass in the parent docModel, since it will often be one end.
-    // Nevertheless, we should complete the item save before we do work on the relations, especially
-    // since a save on Create might fail, and we would not want to create relations for something
-    // that may not be created...
-    private void handleRelationsPayload(DocumentWrapper<DocumentModel> wrapDoc, boolean fUpdate) throws Exception {
-        ServiceContext ctx = getServiceContext();
-        PoxPayloadIn input = (PoxPayloadIn) ctx.getInput();
-        DocumentModel documentModel = (wrapDoc.getWrappedObject());
-        String itemCsid = documentModel.getName();
-
-        //Updates relations part
-        RelationsCommonList relationsCommonList = updateRelations(itemCsid, input, wrapDoc, fUpdate);
-
-        PayloadOutputPart payloadOutputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, relationsCommonList);  //FIXME: REM - We should check for a null relationsCommonList and not create the new common list payload
-        ctx.setProperty(RelationClient.SERVICE_COMMON_LIST_NAME, payloadOutputPart);
-
-        //now we add part for relations list
-        //ServiceContext ctx = getServiceContext();
-        //PayloadOutputPart foo = (PayloadOutputPart) ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
-        ((PoxPayloadOut) ctx.getOutput()).addPart(payloadOutputPart);
-    }
-
-    /**  updateRelations strategy:
-    
-    go through inboundList, remove anything from childList that matches  from childList
-    go through inboundList, remove anything from parentList that matches  from parentList
-    go through parentList, delete all remaining
-    go through childList, delete all remaining
-    go through actionList, add all remaining.
-    check for duplicate children
-    check for more than one parent.
-    
-    inboundList                           parentList                      childList          actionList
-    ----------------                          ---------------                  ----------------       ----------------
-    child-a                                   parent-c                        child-a             child-b
-    child-b                                   parent-d                        child-c
-    parent-a
-     */
-    private RelationsCommonList updateRelations(
-            String itemCSID, PoxPayloadIn input, DocumentWrapper<DocumentModel> wrapDoc, boolean fUpdate)
-            throws Exception {
-        if (logger.isTraceEnabled()) {
-            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID);
-        }
-        PayloadInputPart part = input.getPart(RelationClient.SERVICE_COMMON_LIST_NAME);        //input.getPart("relations_common");
-        if (part == null) {
-            return null;  //nothing to do--they didn't send a list of relations.
-        }
-        RelationsCommonList relationsCommonListBody = (RelationsCommonList) part.getBody();
-        List<RelationsCommonList.RelationListItem> inboundList = relationsCommonListBody.getRelationListItem();
-        List<RelationsCommonList.RelationListItem> actionList = newList();
-        List<RelationsCommonList.RelationListItem> childList = null;
-        List<RelationsCommonList.RelationListItem> parentList = null;
-        DocumentModel docModel = wrapDoc.getWrappedObject();
-               String itemRefName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
-
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
-        //Do magic replacement of ${itemCSID} and fix URI's.
-        fixupInboundListItems(ctx, inboundList, docModel, itemCSID);
-
-        String HAS_BROADER = RelationshipType.HAS_BROADER.value();
-        UriInfo uriInfo = ctx.getUriInfo();
-        MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
-
-        if (fUpdate) {
-            //Run getList() once as sent to get childListOuter:
-            String predicate = RelationshipType.HAS_BROADER.value();
-            queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
-            queryParams.putSingle(IRelationsManager.SUBJECT_QP, null);
-            queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
-            queryParams.putSingle(IRelationsManager.OBJECT_QP, itemCSID);
-            queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
-            
-            RelationResource relationResource = new RelationResource();
-            RelationsCommonList childListOuter = relationResource.getList(ctx);    // Knows all query params because they are in the context.
-
-            //Now run getList() again, leaving predicate, swapping subject and object, to get parentListOuter.
-            queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
-            queryParams.putSingle(IRelationsManager.SUBJECT_QP, itemCSID);
-            queryParams.putSingle(IRelationsManager.OBJECT_QP, null);
-            RelationsCommonList parentListOuter = relationResource.getList(ctx);
-
-
-            childList = childListOuter.getRelationListItem();
-            parentList = parentListOuter.getRelationListItem();
-
-            if (parentList.size() > 1) {
-                throw new Exception("Too many parents for object: " + itemCSID + " list: " + dumpList(parentList, "parentList"));
-            }
-
-            if (logger.isTraceEnabled()) {
-                logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " got existing relations.");
-            }
-        }
-
-        for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
-            // Note that the relations may specify the other (non-item) bit with a refName, not a CSID,
-            // and so the CSID for those may be null
-            if(inboundItem.getPredicate().equals(HAS_BROADER)) {
-               // Look for parents and children
-               if(itemCSID.equals(inboundItem.getObject().getCsid())
-                               || itemRefName.equals(inboundItem.getObject().getRefName())) {
-                       //then this is an item that says we have a child.  That child is inboundItem
-                       RelationsCommonList.RelationListItem childItem =
-                                       (childList == null) ? null : findInList(childList, inboundItem);
-                       if (childItem != null) {
-                        if (logger.isTraceEnabled()) {
-                               StringBuilder sb = new StringBuilder();
-                               itemToString(sb, "== Child: ", childItem);
-                            logger.trace("Found inboundChild in current child list: " + sb.toString());
-                        }
-                               removeFromList(childList, childItem);    //exists, just take it off delete list
-                       } else {
-                        if (logger.isTraceEnabled()) {
-                               StringBuilder sb = new StringBuilder();
-                               itemToString(sb, "== Child: ", inboundItem);
-                            logger.trace("inboundChild not in current child list, will add: " + sb.toString());
-                        }
-                               actionList.add(inboundItem);   //doesn't exist as a child, but is a child.  Add to additions list
-                               String newChildCsid = inboundItem.getSubject().getCsid();
-                               if(newChildCsid == null) {
-                                       String newChildRefName = inboundItem.getSubject().getRefName();
-                                       if(newChildRefName==null) {
-                                               throw new RuntimeException("Child with no CSID or refName!");
-                                       }
-                            if (logger.isTraceEnabled()) {
-                               logger.trace("Fetching CSID for child with only refname: "+newChildRefName);
-                            }
-                               DocumentModel newChildDocModel = 
-                                       ResourceBase.getDocModelForRefName(this.getRepositorySession(), 
-                                                       newChildRefName, getServiceContext().getResourceMap());
-                               newChildCsid = getCsid(newChildDocModel);
-                               }
-                               ensureChildHasNoOtherParents(ctx, queryParams, newChildCsid);
-                       }
-
-               } else if (itemCSID.equals(inboundItem.getSubject().getCsid())
-                                       || itemRefName.equals(inboundItem.getSubject().getRefName())) {
-                       //then this is an item that says we have a parent.  inboundItem is that parent.
-                       RelationsCommonList.RelationListItem parentItem =
-                                       (parentList == null) ? null : findInList(parentList, inboundItem);
-                       if (parentItem != null) {
-                               removeFromList(parentList, parentItem);    //exists, just take it off delete list
-                       } else {
-                               actionList.add(inboundItem);   //doesn't exist as a parent, but is a parent. Add to additions list
-                       }
-                } else {
-                    logger.error("Parent/Child Element didn't link to this item. inboundItem: " + inboundItem);
-               }
-            } else {
-                logger.warn("Non-parent relation ignored. inboundItem: " + inboundItem);
-            }
-        }
-        if (logger.isTraceEnabled()) {
-            String dump = dumpLists(itemCSID, parentList, childList, actionList);
-            logger.trace("~~~~~~~~~~~~~~~~~~~~~~dump~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
-        }
-        if (fUpdate) {
-            if (logger.isTraceEnabled()) {
-                logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " deleting "
-                        + parentList.size() + " existing parents and " + childList.size() + " existing children.");
-            }
-            deleteRelations(parentList, ctx, "parentList");               //todo: there are items appearing on both lists....april 20.
-            deleteRelations(childList, ctx, "childList");
-        }
-        if (logger.isTraceEnabled()) {
-            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " adding "
-                    + actionList.size() + " new parents and children.");
-        }
-        createRelations(actionList, ctx);
-        if (logger.isTraceEnabled()) {
-            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " done.");
-        }
-        //We return all elements on the inbound list, since we have just worked to make them exist in the system
-        // and be non-redundant, etc.  That list came from relationsCommonListBody, so it is still attached to it, just pass that back.
-        return relationsCommonListBody;
-    }
-
-    private void ensureChildHasNoOtherParents(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
-               MultivaluedMap<String, String> queryParams, String childCSID) {
-        logger.trace("ensureChildHasNoOtherParents for: " + childCSID );
-        queryParams.putSingle(IRelationsManager.SUBJECT_QP, childCSID);
-        queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
-        queryParams.putSingle(IRelationsManager.OBJECT_QP, null);  //null means ANY
-        
-        RelationResource relationResource = new RelationResource();
-        RelationsCommonList parentListOuter = relationResource.getList(ctx);
-        List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
-        //logger.warn("ensureChildHasNoOtherParents preparing to delete relations on "+childCSID+"\'s parent list: \r\n"+dumpList(parentList, "duplicate parent list"));
-        deleteRelations(parentList, ctx, "parentList-delete");
-    }
-
-    
-    private void itemToString(StringBuilder sb, String prefix, RelationsCommonList.RelationListItem item ) {
-       sb.append(prefix);
-               sb.append((item.getCsid()!= null)?item.getCsid():"NO CSID");
-       sb.append(": ["); 
-       sb.append((item.getSubject().getCsid()!=null)?item.getSubject().getCsid():item.getSubject().getRefName());
-       sb.append("]--");
-       sb.append(item.getPredicate());
-       sb.append("-->["); 
-       sb.append((item.getObject().getCsid()!=null)?item.getObject().getCsid():item.getObject().getRefName());
-       sb.append("]");
-    }
-    
-    private String dumpLists(String itemCSID,
-            List<RelationsCommonList.RelationListItem> parentList,
-            List<RelationsCommonList.RelationListItem> childList,
-            List<RelationsCommonList.RelationListItem> actionList) {
-       StringBuilder sb = new StringBuilder();
-        sb.append("itemCSID: " + itemCSID + CR);
-        if(parentList!=null) {
-               sb.append(dumpList(parentList, "parentList"));
-        }
-        if(childList!=null) {
-               sb.append(dumpList(childList, "childList"));
-        }
-        if(actionList!=null) {
-               sb.append(dumpList(actionList, "actionList"));
-        }
-        return sb.toString();
-    }
-    private final static String CR = "\r\n";
-
-    private String dumpList(List<RelationsCommonList.RelationListItem> list, String label) {
-        StringBuilder sb = new StringBuilder();
-        String s;
-        if (list.size() > 0) {
-            sb.append("=========== " + label + " ==========" + CR);
-        }
-        for (RelationsCommonList.RelationListItem item : list) {
-               itemToString(sb, "==  ", item);
-               sb.append(CR);
-        }
-        return sb.toString();
-    }
-
-    /** Performs substitution for ${itemCSID} (see CommonAPI.AuthorityItemCSID_REPLACE for constant)
-     *   and sets URI correctly for related items.
-     *   Operates directly on the items in the list.  Does not change the list ordering, does not add or remove any items.
-     */
-    protected void fixupInboundListItems(ServiceContext ctx,
-            List<RelationsCommonList.RelationListItem> inboundList,
-            DocumentModel docModel,
-            String itemCSID) throws Exception {
-        String thisURI = this.getUri(docModel);
-        // WARNING:  the two code blocks below are almost identical  and seem to ask to be put in a generic method.
-        //                    beware of the little diffs in  inboundItem.setObjectCsid(itemCSID); and   inboundItem.setSubjectCsid(itemCSID); in the two blocks.
-        for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
-            RelationsDocListItem inboundItemObject = inboundItem.getObject();
-            RelationsDocListItem inboundItemSubject = inboundItem.getSubject();
-
-            if (CommonAPI.AuthorityItemCSID_REPLACE.equalsIgnoreCase(inboundItemObject.getCsid())) {
-                inboundItem.setObjectCsid(itemCSID);
-                inboundItemObject.setCsid(itemCSID);
-                //inboundItemObject.setUri(getUri(docModel));
-            } else {
-                /*
-                String objectCsid = inboundItemObject.getCsid();
-                DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, objectCsid);    //null if not found.
-                DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
-                String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
-                inboundItemObject.setUri(uri);    //CSPACE-4037
-                 */
-            }
-            //uriPointsToSameAuthority(thisURI, inboundItemObject.getUri());    //CSPACE-4042
-
-            if (CommonAPI.AuthorityItemCSID_REPLACE.equalsIgnoreCase(inboundItemSubject.getCsid())) {
-                inboundItem.setSubjectCsid(itemCSID);
-                inboundItemSubject.setCsid(itemCSID);
-                //inboundItemSubject.setUri(getUri(docModel));
-            } else {
-                /*
-                String subjectCsid = inboundItemSubject.getCsid();
-                DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, subjectCsid);    //null if not found.
-                DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
-                String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
-                inboundItemSubject.setUri(uri);    //CSPACE-4037
-                 */
-            }
-            //uriPointsToSameAuthority(thisURI, inboundItemSubject.getUri());  //CSPACE-4042
-
-        }
-    }
-
-    // this method calls the RelationResource to have it create the relations and persist them.
-    private void createRelations(List<RelationsCommonList.RelationListItem> inboundList,
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) throws Exception {
-        for (RelationsCommonList.RelationListItem item : inboundList) {
-            RelationsCommon rc = new RelationsCommon();
-            //rc.setCsid(item.getCsid());
-            //todo: assignTo(item, rc);
-            RelationsDocListItem itemSubject = item.getSubject();
-            RelationsDocListItem itemObject = item.getObject();
-
-            // Set at least one of CSID and refName for Subject and Object
-            // Either value might be null for for each of Subject and Object 
-            String subjectCsid = itemSubject.getCsid();
-            rc.setSubjectCsid(subjectCsid);
-
-            String objCsid = itemObject.getCsid();
-            rc.setObjectCsid(objCsid);
-
-            rc.setSubjectRefName(itemSubject.getRefName());
-            rc.setObjectRefName(itemObject.getRefName());
-
-            rc.setRelationshipType(item.getPredicate());
-            //RelationshipType  foo = (RelationshipType.valueOf(item.getPredicate())) ;
-            //rc.setPredicate(foo);     //this must be one of the type found in the enum in  services/jaxb/src/main/resources/relations_common.xsd
-
-            // This is superfluous, since it will be fetched by the Relations Create logic.
-            rc.setSubjectDocumentType(itemSubject.getDocumentType());
-            rc.setObjectDocumentType(itemObject.getDocumentType());
-
-            // This is superfluous, since it will be fetched by the Relations Create logic.
-            rc.setSubjectUri(itemSubject.getUri());
-            rc.setObjectUri(itemObject.getUri());
-            // May not have the info here. Only really require CSID or refName. 
-            // Rest is handled in the Relation create mechanism
-            //uriPointsToSameAuthority(itemSubject.getUri(), itemObject.getUri());
-
-            PoxPayloadOut payloadOut = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
-            PayloadOutputPart outputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMONPART_NAME, rc);
-            payloadOut.addPart(outputPart);
-            RelationResource relationResource = new RelationResource();
-            Response res = relationResource.create(ctx, ctx.getResourceMap(),
-                    ctx.getUriInfo(), payloadOut.toXML());    //NOTE ui recycled from above to pass in unknown query params.
-        }
-    }
-
-    private void deleteRelations(List<RelationsCommonList.RelationListItem> list,
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
-               String listName) {
-        try {
-            for (RelationsCommonList.RelationListItem item : list) {
-                RelationResource relationResource = new RelationResource();
-                if(logger.isTraceEnabled()) {
-                       StringBuilder sb = new StringBuilder();
-                       itemToString(sb, "==== TO DELETE: ", item);
-                       logger.trace(sb.toString());
-                }
-                Response res = relationResource.deleteWithParentCtx(ctx, item.getCsid());
-                if (logger.isDebugEnabled()) {
-                       logger.debug("Status of authority item deleteRelations method call was: " + res.getStatus());
-                }
-            }
-        } catch (Throwable t) {
-            String msg = "Unable to deleteRelations: " + Tools.errorToString(t, true);
-            logger.error(msg);
-        }
-    }
-
-    private List<RelationsCommonList.RelationListItem> newList() {
-        List<RelationsCommonList.RelationListItem> result = new ArrayList<RelationsCommonList.RelationListItem>();
-        return result;
-    }
-
     protected List<RelationsCommonList.RelationListItem> cloneList(List<RelationsCommonList.RelationListItem> inboundList) {
-        List<RelationsCommonList.RelationListItem> result = newList();
+        List<RelationsCommonList.RelationListItem> result = newRelationsCommonList();
         for (RelationsCommonList.RelationListItem item : inboundList) {
             result.add(item);
         }
         return result;
     }
 
-    // Note that the item argument may be sparse (only refName, no CSID for subject or object)
-    // But the list items must not be sparse
-    private RelationsCommonList.RelationListItem findInList(
-               List<RelationsCommonList.RelationListItem> list, 
-               RelationsCommonList.RelationListItem item) {
-       RelationsCommonList.RelationListItem foundItem = null;
-        for (RelationsCommonList.RelationListItem listItem : list) {
-            if (itemsEqual(listItem, item)) {   //equals must be defined, else
-               foundItem = listItem;
-               break;
-            }
-        }
-        return foundItem;
-    }
-
     // Note that item2 may be sparse (only refName, no CSID for subject or object)
     // But item1 must not be sparse 
     private boolean itemsEqual(RelationsCommonList.RelationListItem item1, RelationsCommonList.RelationListItem item2) {
@@ -1196,9 +632,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         return isEqual;
     }
 
-    private void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item) {
-        list.remove(item);
-    }
 
     /* don't even THINK of re-using this method.
      * String example_uri = "/locationauthorities/7ec60f01-84ab-4908-9a6a/items/a5466530-713f-43b4-bc05";
@@ -1235,20 +668,6 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         }
     }
 
-    //================= TODO: move this to common, refactoring this and  CollectionObjectResource.java
-    public RelationsCommonList getRelations(String subjectCSID, String objectCSID, String predicate) throws Exception {
-        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
-        MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
-        queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
-        queryParams.putSingle(IRelationsManager.SUBJECT_QP, subjectCSID);
-        queryParams.putSingle(IRelationsManager.OBJECT_QP, objectCSID);
-
-        RelationResource relationResource = new RelationResource(); //is this still acting like a singleton as it should be?
-        RelationsCommonList relationsCommonList = relationResource.getList(ctx);
-        return relationsCommonList;
-    }
-    //============================= END TODO refactor ==========================
-
     public String getItemTermInfoGroupXPathBase() {
         return authorityItemTermGroupXPathBase;
     }
index 3324e73b313ea7b96c921b1e2ecafc671f309d1d..0007f563118c6a7ca982ffede475cd197a7da049 100644 (file)
@@ -15,7 +15,7 @@ import javax.ws.rs.core.Response;
 \r
 import org.collectionspace.services.client.BlobClient;\r
 import org.collectionspace.services.client.CollectionSpaceClient;\r
-import org.collectionspace.services.common.profile.Profiler;\r
+import org.collectionspace.services.client.Profiler;\r
 import org.collectionspace.services.jaxb.AbstractCommonList;\r
 import org.jboss.resteasy.client.ClientResponse;\r
 import org.slf4j.Logger;\r
index a2086e0c940db71f19ef660ca7eb0f3e52ef36f2..a4c73960b11b2aba9f8b6cb7fe3eb2791242a009 100644 (file)
@@ -17,5 +17,20 @@ public interface IRelationsManager {
                        + "." + SERVICE_COMMONPART_NAME + ":objectDocumentType";
        public final static String CMIS_CSPACE_RELATIONS_TITLE = IQueryManager.CMIS_RELATIONS_PREFIX
                        + "." + IQueryManager.CMIS_NUXEO_TITLE;
-
+                       
+    /** The Constant SUBJECT. */
+    static public final String SUBJECT = "subjectCsid";
+    static public final String SUBJECT_QP = "sbj";
+    static public final String SUBJECT_TYPE = "subjectType";
+    static public final String SUBJECT_TYPE_QP = SUBJECT_QP + "Type";
+    
+    /** The Constant PREDICATE. */
+    static public final String PREDICATE = "predicate";
+    static public final String PREDICATE_QP = "prd";
+    
+    /** The Constant OBJECT. */
+    static public final String OBJECT = "objectCsid";
+    static public final String OBJECT_QP = "obj";
+    static public final String OBJECT_TYPE = "objectType";
+    static public final String OBJECT_TYPE_QP = OBJECT_QP + "Type";
 }
similarity index 95%
rename from services/common/src/main/java/org/collectionspace/services/common/profile/Profiler.java
rename to services/client/src/main/java/org/collectionspace/services/client/Profiler.java
index 4f82e784fb4492d44a6471d29798388af58ae3a7..91554eac96e63e87b09d3c092daa0ccec5d00376 100644 (file)
@@ -14,7 +14,7 @@
  * You may obtain a copy of the ECL 2.0 License at\r
  * https://source.collectionspace.org/collection-space/LICENSE.txt\r
  */\r
-package org.collectionspace.services.common.profile;\r
+package org.collectionspace.services.client;\r
 \r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
index a42734778edc475a5ab0af3589a6535f5b603931..3c205463cd5ae06c0e6df6b66beb27305d1a28f2 100644 (file)
             <artifactId>org.collectionspace.services.authorization-mgt.client</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.relation.client</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
         <!-- \r
         <dependency>\r
                        <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.jaxb</artifactId>\r
             <version>${project.version}</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.collectionspace.services</groupId>\r
+            <artifactId>org.collectionspace.services.authority.jaxb</artifactId>\r
+            <version>${project.version}</version>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.hyperjaxb</artifactId>\r
index 90d4543e39983f7cc849277bfd56202f33e10763..49975136b546f83cb11c094b2e22c041c52f1551 100644 (file)
@@ -31,13 +31,13 @@ import org.collectionspace.services.authorization.perms.EffectType;
 import org.collectionspace.services.authorization.perms.Permission;\r
 import org.collectionspace.services.authorization.perms.PermissionAction;\r
 \r
+import org.collectionspace.services.client.Profiler;\r
 import org.collectionspace.services.client.RoleClient;\r
 import org.collectionspace.services.client.workflow.WorkflowClient;\r
 import org.collectionspace.services.common.config.ServiceConfigUtils;\r
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
 import org.collectionspace.services.common.context.ServiceBindingUtils;\r
 import org.collectionspace.services.common.document.DocumentHandler;\r
-import org.collectionspace.services.common.profile.Profiler;\r
 import org.collectionspace.services.common.security.SecurityUtils;\r
 import org.collectionspace.services.common.storage.DatabaseProductType;\r
 import org.collectionspace.services.common.storage.JDBCTools;\r
similarity index 97%
rename from services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/Hierarchy.java
rename to services/common/src/main/java/org/collectionspace/services/common/document/Hierarchy.java
index ef862a46a4643200ef3d2d60332b393f6a3e5e62..51606afcfdf941c5c607ca4baf16640f375501d5 100644 (file)
  *  limitations under the License.
  */
 
-package org.collectionspace.services.common.vocabulary;
+package org.collectionspace.services.common.document;
 
+import org.collectionspace.services.client.IRelationsManager;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.common.XmlTools;
 import org.collectionspace.services.common.api.Tools;
 import org.collectionspace.services.common.context.ServiceContext;
-import org.collectionspace.services.common.relation.IRelationsManager;
-import org.collectionspace.services.relation.RelationResource;
+import org.collectionspace.services.common.relation.RelationResource;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationsDocListItem;
 import org.collectionspace.services.relation.RelationshipType;
index a3d9449a422ae0d4c9a2f7816ba7c9b0d18d39df..989e647111645dfffc3a2198e301fa8bea35ed89 100644 (file)
@@ -26,6 +26,7 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;\r
 //import javax.servlet.ServletContext;\r
 \r
+import org.collectionspace.services.client.Profiler;\r
 import org.collectionspace.services.common.ServletTools;\r
 \r
 import org.slf4j.Logger;\r
index 988fb35405aa91080fcf8134f11ae8cf078ab0d4..ed7e17b124304c081d30f20e69cd6866a7c73bea 100644 (file)
@@ -28,7 +28,6 @@ package org.collectionspace.services.common.relation;
 \r
 import java.util.List;\r
 \r
-\r
 import org.collectionspace.services.common.document.DocumentException;\r
 import org.collectionspace.services.relation.RelationsCommon;\r
 import org.nuxeo.ecm.core.api.DocumentModel;\r
@@ -38,22 +37,6 @@ import org.nuxeo.ecm.core.api.DocumentModel;
  */\r
 public interface IRelationsManager {\r
 \r
-    /** The Constant SUBJECT. */\r
-    static public final String SUBJECT = "subjectCsid";\r
-    static public final String SUBJECT_QP = "sbj";\r
-    static public final String SUBJECT_TYPE = "subjectType";\r
-    static public final String SUBJECT_TYPE_QP = SUBJECT_QP + "Type";\r
-    \r
-    /** The Constant PREDICATE. */\r
-    static public final String PREDICATE = "predicate";\r
-    static public final String PREDICATE_QP = "prd";\r
-    \r
-    /** The Constant OBJECT. */\r
-    static public final String OBJECT = "objectCsid";\r
-    static public final String OBJECT_QP = "obj";\r
-    static public final String OBJECT_TYPE = "objectType";\r
-    static public final String OBJECT_TYPE_QP = OBJECT_QP + "Type";\r
-\r
     /**\r
      * Gets the relationships for the entity corresponding to the CSID=csid.\r
      * The csid refers to either the subject *OR* the object.\r
similarity index 95%
rename from services/relation/service/src/main/java/org/collectionspace/services/relation/RelationResource.java
rename to services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java
index 0095039c8b71027437a257831779c4b29532d126..4baaea1d13aec634e453af9b88c01c0af15aad64 100644 (file)
@@ -24,7 +24,7 @@
  * You may obtain a copy of the ECL 2.0 License at
  * https://source.collectionspace.org/collection-space/LICENSE.txt
  */
-package org.collectionspace.services.relation;
+package org.collectionspace.services.common.relation;
 
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
@@ -34,8 +34,11 @@ import org.collectionspace.services.common.ServiceMessages;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.query.QueryManager;
-import org.collectionspace.services.common.relation.IRelationsManager;
+import org.collectionspace.services.client.IRelationsManager;
 import org.collectionspace.services.common.relation.nuxeo.RelationsUtils;
+import org.collectionspace.services.relation.RelationsCommon;
+import org.collectionspace.services.relation.RelationsCommonList;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
index cecee564f4c9348638fbfbc9c98e1104dcfe0df1..9583ec9dc51adfdfee29ae2e01b6239597134ae1 100644 (file)
@@ -23,7 +23,6 @@
 package org.collectionspace.services.common.vocabulary;\r
 \r
 import java.util.ArrayList;\r
-import java.util.Collection;\r
 import java.util.HashMap;\r
 import java.util.Iterator;\r
 import java.util.List;\r
@@ -49,7 +48,6 @@ import org.collectionspace.services.common.api.RefNameUtils;
 import org.collectionspace.services.common.api.Tools;\r
 import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;\r
 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;\r
-import org.collectionspace.services.common.authorityref.AuthorityRefList;\r
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
 import org.collectionspace.services.common.config.URIUtils;\r
 import org.collectionspace.services.common.context.ServiceBindingUtils;\r
@@ -68,8 +66,6 @@ import org.collectionspace.services.config.service.ServiceBindingType;
 import org.collectionspace.services.jaxb.AbstractCommonList;\r
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
 \r
-import com.sun.xml.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;\r
-\r
 /**\r
  * RefNameServiceUtils is a collection of services utilities related to refName\r
  * usage.\r
index 38f0d2f21cff68cf45c9e50a63621298bcc23134..3525d88c64e3fc2ed8ce48a8e176fd4853e535a9 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 
 import javax.ws.rs.core.MultivaluedMap;
 
+import org.collectionspace.services.client.Profiler;
 import org.collectionspace.services.client.CollectionSpaceClient;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.IRelationsManager;
@@ -40,7 +41,6 @@ import org.collectionspace.services.common.document.AbstractMultipartDocumentHan
 import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-import org.collectionspace.services.common.profile.Profiler;
 import org.collectionspace.services.common.query.QueryContext;
 import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.repository.RepositoryClientFactory;
index 1a4271ac71cfa888c6bad8bdcc98818c98986643..ef33888647f1995d50ff4ff769b2cb84799c48f7 100644 (file)
@@ -32,7 +32,9 @@ import java.util.Set;
 
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import javax.xml.bind.JAXBElement;
 
 import org.collectionspace.services.authorization.AccountPermission;
@@ -43,20 +45,29 @@ import org.collectionspace.services.client.PayloadInputPart;
 import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.Profiler;
+import org.collectionspace.services.client.RelationClient;
 import org.collectionspace.services.client.workflow.WorkflowClient;
+import org.collectionspace.services.common.ResourceBase;
 import org.collectionspace.services.common.authorityref.AuthorityRefList;
 import org.collectionspace.services.common.context.JaxRsContext;
 import org.collectionspace.services.common.context.MultipartServiceContext;
+import org.collectionspace.services.common.context.ServiceBindingUtils;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.BadRequestException;
 import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentUtils;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.DocumentFilter;
-import org.collectionspace.services.common.profile.Profiler;
+import org.collectionspace.services.client.IRelationsManager;
+import org.collectionspace.services.common.relation.RelationResource;
+import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.security.SecurityUtils;
 import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
+import org.collectionspace.services.common.api.CommonAPI;
 import org.collectionspace.services.common.api.RefNameUtils;
+import org.collectionspace.services.common.api.Tools;
+import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthRefConfigInfo;
 import org.collectionspace.services.config.service.DocHandlerParams;
@@ -64,6 +75,10 @@ import org.collectionspace.services.config.service.ListResultField;
 import org.collectionspace.services.config.service.ObjectPartType;
 import org.collectionspace.services.config.service.ServiceBindingType;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+import org.collectionspace.services.relation.RelationsCommon;
+import org.collectionspace.services.relation.RelationsCommonList;
+import org.collectionspace.services.relation.RelationsDocListItem;
+import org.collectionspace.services.relation.RelationshipType;
 import org.dom4j.Element;
 
 import org.nuxeo.ecm.core.api.DocumentModel;
@@ -87,7 +102,11 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
 
     /** The logger. */
     private final Logger logger = LoggerFactory.getLogger(RemoteDocumentModelHandlerImpl.class);
+    private final static String CR = "\r\n";
 
+    protected String oldRefNameOnUpdate = null;
+    protected String newRefNameOnUpdate = null;
+    
     /* (non-Javadoc)
      * @see org.collectionspace.services.common.document.AbstractDocumentHandlerImpl#setServiceContext(org.collectionspace.services.common.context.ServiceContext)
      */
@@ -137,7 +156,15 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
                        throws Exception {
                // Do nothing by default, but children can override if they want.  The really workflow transition happens in the WorkflowDocumemtModelHandler class
        }
-    
+       
+    @Override
+    public void completeCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
+        super.completeCreate(wrapDoc);
+        if (supportsHierarchy() == true) {
+               handleRelationsPayload(wrapDoc, false);
+        }
+    }
+       
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#completeUpdate(org.collectionspace.services.common.document.DocumentWrapper)
      */
@@ -162,7 +189,6 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
                            }
                     }
                 } catch (Throwable t){
-
                     logger.error("Unable to addOutputPart: "+partLabel
                                                +" in serviceContextPath: "+this.getServiceContextPath()
                                                +" with URI: "+this.getServiceContext().getUriInfo().getPath()
@@ -175,6 +201,11 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
                                        docModel.getName());
                }
         }
+        
+        if (supportsHierarchy() == true) {
+            handleRelationsPayload(wrapDoc, true);
+            handleItemRefNameReferenceUpdate();
+        }
     }
 
     /**
@@ -244,6 +275,28 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
             }
             addOutputPart(unQObjectProperties, schema, partMeta);
         }
+        
+        if (supportsHierarchy() == true) {
+            MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
+            String showSiblings = ctx.getQueryParams().getFirst(CommonAPI.showSiblings_QP);
+            if (Tools.isTrue(showSiblings)) {
+                showSiblings(wrapDoc, ctx);
+                return;   // actual result is returned on ctx.addOutputPart();
+            }
+
+            String showRelations = ctx.getQueryParams().getFirst(CommonAPI.showRelations_QP);
+            if (Tools.isTrue(showRelations)) {
+                showRelations(wrapDoc, ctx);
+                return;   // actual result is returned on ctx.addOutputPart();
+            }
+
+            String showAllRelations = ctx.getQueryParams().getFirst(CommonAPI.showAllRelations_QP);
+            if (Tools.isTrue(showAllRelations)) {
+                showAllRelations(wrapDoc, ctx);
+                return;   // actual result is returned on ctx.addOutputPart();
+            }
+        }
+        
         addAccountPermissionsPart();
     }
     
@@ -751,4 +804,583 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
                return result;
        }
    
+       
+    protected void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item) {
+        list.remove(item);
+    }
+       
+    private void itemToString(StringBuilder sb, String prefix, RelationsCommonList.RelationListItem item ) {
+       sb.append(prefix);
+               sb.append((item.getCsid()!= null)?item.getCsid():"NO CSID");
+       sb.append(": ["); 
+       sb.append((item.getSubject().getCsid()!=null)?item.getSubject().getCsid():item.getSubject().getRefName());
+       sb.append("]--");
+       sb.append(item.getPredicate());
+       sb.append("-->["); 
+       sb.append((item.getObject().getCsid()!=null)?item.getObject().getCsid():item.getObject().getRefName());
+       sb.append("]");
+    }
+    
+    private String dumpList(List<RelationsCommonList.RelationListItem> list, String label) {
+        StringBuilder sb = new StringBuilder();
+        String s;
+        if (list.size() > 0) {
+            sb.append("=========== " + label + " ==========" + CR);
+        }
+        for (RelationsCommonList.RelationListItem item : list) {
+               itemToString(sb, "==  ", item);
+               sb.append(CR);
+        }
+        return sb.toString();
+    }
+    
+    /** @return null on parent not found
+     */
+    protected String getParentCSID(String thisCSID) throws Exception {
+        String parentCSID = null;
+        try {
+            String predicate = RelationshipType.HAS_BROADER.value();
+            RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
+            List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
+            if (parentList != null) {
+                if (parentList.size() == 0) {
+                    return null;
+                }
+                RelationsCommonList.RelationListItem relationListItem = parentList.get(0);
+                parentCSID = relationListItem.getObjectCsid();
+            }
+            return parentCSID;
+        } catch (Exception e) {
+            logger.error("Could not find parent for this: " + thisCSID, e);
+            return null;
+        }
+    }
+    
+    protected List<RelationsCommonList.RelationListItem> newRelationsCommonList() {
+        List<RelationsCommonList.RelationListItem> result = new ArrayList<RelationsCommonList.RelationListItem>();
+        return result;
+    }
+
+    public void showSiblings(DocumentWrapper<DocumentModel> wrapDoc,
+            MultipartServiceContext ctx) throws Exception {
+        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
+        String parentCSID = getParentCSID(thisCSID);
+        if (parentCSID == null) {
+            logger.warn("~~~~~\r\n~~~~ Could not find parent for this: " + thisCSID);
+            return;
+        }
+
+        String predicate = RelationshipType.HAS_BROADER.value();
+        RelationsCommonList siblingListOuter = getRelations(null, parentCSID, predicate);
+        List<RelationsCommonList.RelationListItem> siblingList = siblingListOuter.getRelationListItem();
+
+        List<RelationsCommonList.RelationListItem> toRemoveList = newRelationsCommonList();
+
+
+        RelationsCommonList.RelationListItem item = null;
+        for (RelationsCommonList.RelationListItem sibling : siblingList) {
+            if (thisCSID.equals(sibling.getSubjectCsid())) {
+                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.
+            }
+        }
+        //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.
+        for (RelationsCommonList.RelationListItem self : toRemoveList) {
+            removeFromList(siblingList, self);
+        }
+
+        long siblingSize = siblingList.size();
+        siblingListOuter.setTotalItems(siblingSize);
+        siblingListOuter.setItemsInPage(siblingSize);
+        if(logger.isTraceEnabled()) {
+            String dump = dumpList(siblingList, "Siblings of: "+thisCSID);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showSiblings ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
+
+        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, siblingListOuter);
+        ctx.addOutputPart(relationsPart);
+    }
+    
+    public void showRelations(DocumentWrapper<DocumentModel> wrapDoc,
+            MultipartServiceContext ctx) throws Exception {
+        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
+
+        String predicate = RelationshipType.HAS_BROADER.value();
+        RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
+        List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
+
+        RelationsCommonList childrenListOuter = getRelations(null, thisCSID, predicate);
+        List<RelationsCommonList.RelationListItem> childrenList = childrenListOuter.getRelationListItem();
+
+        if(logger.isTraceEnabled()) {
+            String dump = dumpLists(thisCSID, parentList, childrenList, null);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
+        
+        //Assume that there are more children than parents.  Will be true for parent/child, but maybe not for other relations.
+        //Now add all parents to our childrenList, to be able to return just one list of consolidated results.
+        //Not optimal, but that's the current design spec.
+        long added = 0;
+        for (RelationsCommonList.RelationListItem parent : parentList) {
+            childrenList.add(parent);
+            added++;
+        }
+        long childrenSize = childrenList.size();
+        childrenListOuter.setTotalItems(childrenSize);
+        childrenListOuter.setItemsInPage(childrenListOuter.getItemsInPage() + added);
+
+        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, childrenListOuter);
+        ctx.addOutputPart(relationsPart);
+    }
+    
+    public void showAllRelations(DocumentWrapper<DocumentModel> wrapDoc, MultipartServiceContext ctx) throws Exception {
+        String thisCSID = NuxeoUtils.getCsid(wrapDoc.getWrappedObject());
+
+        RelationsCommonList subjectListOuter = getRelations(thisCSID, null, null);   //  nulls are wildcards:  predicate=*, and object=*
+        List<RelationsCommonList.RelationListItem> subjectList = subjectListOuter.getRelationListItem();
+
+        RelationsCommonList objectListOuter = getRelations(null, thisCSID, null);   //  nulls are wildcards:  subject=*, and predicate=*
+        List<RelationsCommonList.RelationListItem> objectList = objectListOuter.getRelationListItem();
+
+        if(logger.isTraceEnabled()) {
+            String dump = dumpLists(thisCSID, subjectList, objectList, null);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showAllRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
+        //  MERGE LISTS:
+        subjectList.addAll(objectList);
+
+        //now subjectList actually has records BOTH where thisCSID is subject and object.
+        long relatedSize = subjectList.size();
+        subjectListOuter.setTotalItems(relatedSize);
+        subjectListOuter.setItemsInPage(relatedSize);
+
+        PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, subjectListOuter);
+        ctx.addOutputPart(relationsPart);
+    }
+
+    private String dumpLists(String itemCSID,
+            List<RelationsCommonList.RelationListItem> parentList,
+            List<RelationsCommonList.RelationListItem> childList,
+            List<RelationsCommonList.RelationListItem> actionList) {
+       StringBuilder sb = new StringBuilder();
+        sb.append("itemCSID: " + itemCSID + CR);
+        if(parentList!=null) {
+               sb.append(dumpList(parentList, "parentList"));
+        }
+        if(childList!=null) {
+               sb.append(dumpList(childList, "childList"));
+        }
+        if(actionList!=null) {
+               sb.append(dumpList(actionList, "actionList"));
+        }
+        return sb.toString();
+    }
+    
+    //================= TODO: move this to common, refactoring this and  CollectionObjectResource.java
+    public RelationsCommonList getRelations(String subjectCSID, String objectCSID, String predicate) throws Exception {
+        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+        MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
+        queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
+        queryParams.putSingle(IRelationsManager.SUBJECT_QP, subjectCSID);
+        queryParams.putSingle(IRelationsManager.OBJECT_QP, objectCSID);
+
+        RelationResource relationResource = new RelationResource(); //is this still acting like a singleton as it should be?
+        RelationsCommonList relationsCommonList = relationResource.getList(ctx);
+        return relationsCommonList;
+    }
+    //============================= END TODO refactor ==========================
+    
+    // this method calls the RelationResource to have it create the relations and persist them.
+    private void createRelations(List<RelationsCommonList.RelationListItem> inboundList,
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) throws Exception {
+        for (RelationsCommonList.RelationListItem item : inboundList) {
+            RelationsCommon rc = new RelationsCommon();
+            //rc.setCsid(item.getCsid());
+            //todo: assignTo(item, rc);
+            RelationsDocListItem itemSubject = item.getSubject();
+            RelationsDocListItem itemObject = item.getObject();
+
+            // Set at least one of CSID and refName for Subject and Object
+            // Either value might be null for for each of Subject and Object 
+            String subjectCsid = itemSubject.getCsid();
+            rc.setSubjectCsid(subjectCsid);
+
+            String objCsid = itemObject.getCsid();
+            rc.setObjectCsid(objCsid);
+
+            rc.setSubjectRefName(itemSubject.getRefName());
+            rc.setObjectRefName(itemObject.getRefName());
+
+            rc.setRelationshipType(item.getPredicate());
+            //RelationshipType  foo = (RelationshipType.valueOf(item.getPredicate())) ;
+            //rc.setPredicate(foo);     //this must be one of the type found in the enum in  services/jaxb/src/main/resources/relations_common.xsd
+
+            // This is superfluous, since it will be fetched by the Relations Create logic.
+            rc.setSubjectDocumentType(itemSubject.getDocumentType());
+            rc.setObjectDocumentType(itemObject.getDocumentType());
+
+            // This is superfluous, since it will be fetched by the Relations Create logic.
+            rc.setSubjectUri(itemSubject.getUri());
+            rc.setObjectUri(itemObject.getUri());
+            // May not have the info here. Only really require CSID or refName. 
+            // Rest is handled in the Relation create mechanism
+            //uriPointsToSameAuthority(itemSubject.getUri(), itemObject.getUri());
+
+            PoxPayloadOut payloadOut = new PoxPayloadOut(RelationClient.SERVICE_PAYLOAD_NAME);
+            PayloadOutputPart outputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMONPART_NAME, rc);
+            payloadOut.addPart(outputPart);
+            RelationResource relationResource = new RelationResource();
+            Response res = relationResource.create(ctx, ctx.getResourceMap(),
+                    ctx.getUriInfo(), payloadOut.toXML());    //NOTE ui recycled from above to pass in unknown query params.
+        }
+    }
+    
+    // Note that item2 may be sparse (only refName, no CSID for subject or object)
+    // But item1 must not be sparse 
+    private boolean itemsEqual(RelationsCommonList.RelationListItem item1, RelationsCommonList.RelationListItem item2) {
+        if (item1 == null || item2 == null) {
+            return false;
+        }
+        RelationsDocListItem subj1 = item1.getSubject();
+        RelationsDocListItem subj2 = item2.getSubject();
+        RelationsDocListItem obj1 = item1.getObject();
+        RelationsDocListItem obj2 = item2.getObject();
+        String subj1Csid = subj1.getCsid();
+        String subj2Csid = subj2.getCsid();
+        String subj1RefName = subj1.getRefName();
+        String subj2RefName = subj2.getRefName();
+
+        String obj1Csid = obj1.getCsid();
+        String obj2Csid = obj2.getCsid();
+        String obj1RefName = obj1.getRefName();
+        String obj2RefName = obj2.getRefName();
+
+        boolean isEqual = 
+                          (subj1Csid.equals(subj2Csid) || ((subj2Csid==null)  && subj1RefName.equals(subj2RefName)))
+                && (obj1Csid.equals(obj1Csid)   || ((obj2Csid==null)   && obj1RefName.equals(obj2RefName)))
+                // predicate is proper, but still allow relationshipType
+                && (item1.getPredicate().equals(item2.getPredicate())
+                       ||  ((item2.getPredicate()==null)  && item1.getRelationshipType().equals(item2.getRelationshipType())))
+                // Allow missing docTypes, so long as they do not conflict
+                && (obj1.getDocumentType().equals(obj2.getDocumentType()) || obj2.getDocumentType()==null)
+                && (subj1.getDocumentType().equals(subj2.getDocumentType()) || subj2.getDocumentType()==null);
+        return isEqual;
+    }
+    
+    // Note that the item argument may be sparse (only refName, no CSID for subject or object)
+    // But the list items must not be sparse
+    private RelationsCommonList.RelationListItem findInList(
+               List<RelationsCommonList.RelationListItem> list, 
+               RelationsCommonList.RelationListItem item) {
+       RelationsCommonList.RelationListItem foundItem = null;
+        for (RelationsCommonList.RelationListItem listItem : list) {
+            if (itemsEqual(listItem, item)) {   //equals must be defined, else
+               foundItem = listItem;
+               break;
+            }
+        }
+        return foundItem;
+    }
+    
+    /**  updateRelations strategy:
+     *
+     *
+    go through inboundList, remove anything from childList that matches  from childList
+    go through inboundList, remove anything from parentList that matches  from parentList
+    go through parentList, delete all remaining
+    go through childList, delete all remaining
+    go through actionList, add all remaining.
+    check for duplicate children
+    check for more than one parent.
+    
+    inboundList                           parentList                      childList          actionList
+    ----------------                          ---------------                  ----------------       ----------------
+    child-a                                   parent-c                        child-a             child-b
+    child-b                                   parent-d                        child-c
+    parent-a
+     *
+     *
+     */
+    private RelationsCommonList updateRelations(
+            String itemCSID, PoxPayloadIn input, DocumentWrapper<DocumentModel> wrapDoc, boolean fUpdate)
+            throws Exception {
+        if (logger.isTraceEnabled()) {
+            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID);
+        }
+        PayloadInputPart part = input.getPart(RelationClient.SERVICE_COMMON_LIST_NAME);        //input.getPart("relations_common");
+        if (part == null) {
+            return null;  //nothing to do--they didn't send a list of relations.
+        }
+        RelationsCommonList relationsCommonListBody = (RelationsCommonList) part.getBody();
+        List<RelationsCommonList.RelationListItem> inboundList = relationsCommonListBody.getRelationListItem();
+        List<RelationsCommonList.RelationListItem> actionList = newRelationsCommonList();
+        List<RelationsCommonList.RelationListItem> childList = null;
+        List<RelationsCommonList.RelationListItem> parentList = null;
+        DocumentModel docModel = wrapDoc.getWrappedObject();
+               String itemRefName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
+
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+        //Do magic replacement of ${itemCSID} and fix URI's.
+        fixupInboundListItems(ctx, inboundList, docModel, itemCSID);
+
+        String HAS_BROADER = RelationshipType.HAS_BROADER.value();
+        UriInfo uriInfo = ctx.getUriInfo();
+        MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
+
+        if (fUpdate) {
+            //Run getList() once as sent to get childListOuter:
+            String predicate = RelationshipType.HAS_BROADER.value();
+            queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
+            queryParams.putSingle(IRelationsManager.SUBJECT_QP, null);
+            queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
+            queryParams.putSingle(IRelationsManager.OBJECT_QP, itemCSID);
+            queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
+            
+            RelationResource relationResource = new RelationResource();
+            RelationsCommonList childListOuter = relationResource.getList(ctx);    // Knows all query params because they are in the context.
+
+            //Now run getList() again, leaving predicate, swapping subject and object, to get parentListOuter.
+            queryParams.putSingle(IRelationsManager.PREDICATE_QP, predicate);
+            queryParams.putSingle(IRelationsManager.SUBJECT_QP, itemCSID);
+            queryParams.putSingle(IRelationsManager.OBJECT_QP, null);
+            RelationsCommonList parentListOuter = relationResource.getList(ctx);
+
+
+            childList = childListOuter.getRelationListItem();
+            parentList = parentListOuter.getRelationListItem();
+
+            if (parentList.size() > 1) {
+                throw new Exception("Too many parents for object: " + itemCSID + " list: " + dumpList(parentList, "parentList"));
+            }
+
+            if (logger.isTraceEnabled()) {
+                logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " got existing relations.");
+            }
+        }
+
+        for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
+            // Note that the relations may specify the other (non-item) bit with a refName, not a CSID,
+            // and so the CSID for those may be null
+            if(inboundItem.getPredicate().equals(HAS_BROADER)) {
+               // Look for parents and children
+               if(itemCSID.equals(inboundItem.getObject().getCsid())
+                               || itemRefName.equals(inboundItem.getObject().getRefName())) {
+                       //then this is an item that says we have a child.  That child is inboundItem
+                       RelationsCommonList.RelationListItem childItem =
+                                       (childList == null) ? null : findInList(childList, inboundItem);
+                       if (childItem != null) {
+                        if (logger.isTraceEnabled()) {
+                               StringBuilder sb = new StringBuilder();
+                               itemToString(sb, "== Child: ", childItem);
+                            logger.trace("Found inboundChild in current child list: " + sb.toString());
+                        }
+                               removeFromList(childList, childItem);    //exists, just take it off delete list
+                       } else {
+                        if (logger.isTraceEnabled()) {
+                               StringBuilder sb = new StringBuilder();
+                               itemToString(sb, "== Child: ", inboundItem);
+                            logger.trace("inboundChild not in current child list, will add: " + sb.toString());
+                        }
+                               actionList.add(inboundItem);   //doesn't exist as a child, but is a child.  Add to additions list
+                               String newChildCsid = inboundItem.getSubject().getCsid();
+                               if(newChildCsid == null) {
+                                       String newChildRefName = inboundItem.getSubject().getRefName();
+                                       if(newChildRefName==null) {
+                                               throw new RuntimeException("Child with no CSID or refName!");
+                                       }
+                            if (logger.isTraceEnabled()) {
+                               logger.trace("Fetching CSID for child with only refname: "+newChildRefName);
+                            }
+                               DocumentModel newChildDocModel = 
+                                       ResourceBase.getDocModelForRefName(this.getRepositorySession(), 
+                                                       newChildRefName, getServiceContext().getResourceMap());
+                               newChildCsid = getCsid(newChildDocModel);
+                               }
+                               ensureChildHasNoOtherParents(ctx, queryParams, newChildCsid);
+                       }
+
+               } else if (itemCSID.equals(inboundItem.getSubject().getCsid())
+                                       || itemRefName.equals(inboundItem.getSubject().getRefName())) {
+                       //then this is an item that says we have a parent.  inboundItem is that parent.
+                       RelationsCommonList.RelationListItem parentItem =
+                                       (parentList == null) ? null : findInList(parentList, inboundItem);
+                       if (parentItem != null) {
+                               removeFromList(parentList, parentItem);    //exists, just take it off delete list
+                       } else {
+                               actionList.add(inboundItem);   //doesn't exist as a parent, but is a parent. Add to additions list
+                       }
+                } else {
+                    logger.error("Parent/Child Element didn't link to this item. inboundItem: " + inboundItem);
+               }
+            } else {
+                logger.warn("Non-parent relation ignored. inboundItem: " + inboundItem);
+            }
+        }
+        if (logger.isTraceEnabled()) {
+            String dump = dumpLists(itemCSID, parentList, childList, actionList);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~dump~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
+        if (fUpdate) {
+            if (logger.isTraceEnabled()) {
+                logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " deleting "
+                        + parentList.size() + " existing parents and " + childList.size() + " existing children.");
+            }
+            deleteRelations(parentList, ctx, "parentList");               //todo: there are items appearing on both lists....april 20.
+            deleteRelations(childList, ctx, "childList");
+        }
+        if (logger.isTraceEnabled()) {
+            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " adding "
+                    + actionList.size() + " new parents and children.");
+        }
+        createRelations(actionList, ctx);
+        if (logger.isTraceEnabled()) {
+            logger.trace("AuthItemDocHndler.updateRelations for: " + itemCSID + " done.");
+        }
+        //We return all elements on the inbound list, since we have just worked to make them exist in the system
+        // and be non-redundant, etc.  That list came from relationsCommonListBody, so it is still attached to it, just pass that back.
+        return relationsCommonListBody;
+    }
+    
+    /** Performs substitution for ${itemCSID} (see CommonAPI.AuthorityItemCSID_REPLACE for constant)
+     *   and sets URI correctly for related items.
+     *   Operates directly on the items in the list.  Does not change the list ordering, does not add or remove any items.
+     */
+    protected void fixupInboundListItems(ServiceContext ctx,
+            List<RelationsCommonList.RelationListItem> inboundList,
+            DocumentModel docModel,
+            String itemCSID) throws Exception {
+        String thisURI = this.getUri(docModel);
+        // WARNING:  the two code blocks below are almost identical  and seem to ask to be put in a generic method.
+        //                    beware of the little diffs in  inboundItem.setObjectCsid(itemCSID); and   inboundItem.setSubjectCsid(itemCSID); in the two blocks.
+        for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
+            RelationsDocListItem inboundItemObject = inboundItem.getObject();
+            RelationsDocListItem inboundItemSubject = inboundItem.getSubject();
+
+            if (CommonAPI.AuthorityItemCSID_REPLACE.equalsIgnoreCase(inboundItemObject.getCsid())) {
+                inboundItem.setObjectCsid(itemCSID);
+                inboundItemObject.setCsid(itemCSID);
+                //inboundItemObject.setUri(getUri(docModel));
+            } else {
+                /*
+                String objectCsid = inboundItemObject.getCsid();
+                DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, objectCsid);    //null if not found.
+                DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
+                String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
+                inboundItemObject.setUri(uri);    //CSPACE-4037
+                 */
+            }
+            //uriPointsToSameAuthority(thisURI, inboundItemObject.getUri());    //CSPACE-4042
+
+            if (CommonAPI.AuthorityItemCSID_REPLACE.equalsIgnoreCase(inboundItemSubject.getCsid())) {
+                inboundItem.setSubjectCsid(itemCSID);
+                inboundItemSubject.setCsid(itemCSID);
+                //inboundItemSubject.setUri(getUri(docModel));
+            } else {
+                /*
+                String subjectCsid = inboundItemSubject.getCsid();
+                DocumentModel itemDocModel = NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, subjectCsid);    //null if not found.
+                DocumentWrapper wrapper = new DocumentWrapperImpl(itemDocModel);
+                String uri = this.getRepositoryClient(ctx).getDocURI(wrapper);
+                inboundItemSubject.setUri(uri);    //CSPACE-4037
+                 */
+            }
+            //uriPointsToSameAuthority(thisURI, inboundItemSubject.getUri());  //CSPACE-4042
+
+        }
+    }
+
+    private void ensureChildHasNoOtherParents(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+               MultivaluedMap<String, String> queryParams, String childCSID) {
+        logger.trace("ensureChildHasNoOtherParents for: " + childCSID );
+        queryParams.putSingle(IRelationsManager.SUBJECT_QP, childCSID);
+        queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
+        queryParams.putSingle(IRelationsManager.OBJECT_QP, null);  //null means ANY
+        
+        RelationResource relationResource = new RelationResource();
+        RelationsCommonList parentListOuter = relationResource.getList(ctx);
+        List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
+        //logger.warn("ensureChildHasNoOtherParents preparing to delete relations on "+childCSID+"\'s parent list: \r\n"+dumpList(parentList, "duplicate parent list"));
+        deleteRelations(parentList, ctx, "parentList-delete");
+    }
+
+    private void deleteRelations(List<RelationsCommonList.RelationListItem> list,
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+               String listName) {
+        try {
+            for (RelationsCommonList.RelationListItem item : list) {
+                RelationResource relationResource = new RelationResource();
+                if(logger.isTraceEnabled()) {
+                       StringBuilder sb = new StringBuilder();
+                       itemToString(sb, "==== TO DELETE: ", item);
+                       logger.trace(sb.toString());
+                }
+                Response res = relationResource.deleteWithParentCtx(ctx, item.getCsid());
+                if (logger.isDebugEnabled()) {
+                       logger.debug("Status of authority item deleteRelations method call was: " + res.getStatus());
+                }
+            }
+        } catch (Throwable t) {
+            String msg = "Unable to deleteRelations: " + Tools.errorToString(t, true);
+            logger.error(msg);
+        }
+    }
+    
+    // Note that we must do this after we have completed the Update, so that the repository has the
+    // info for the item itself. The relations code must call into the repo to get info for each end.
+    // This could be optimized to pass in the parent docModel, since it will often be one end.
+    // Nevertheless, we should complete the item save before we do work on the relations, especially
+    // since a save on Create might fail, and we would not want to create relations for something
+    // that may not be created...
+    private void handleRelationsPayload(DocumentWrapper<DocumentModel> wrapDoc, boolean fUpdate) throws Exception {
+        ServiceContext ctx = getServiceContext();
+        PoxPayloadIn input = (PoxPayloadIn) ctx.getInput();
+        DocumentModel documentModel = (wrapDoc.getWrappedObject());
+        String itemCsid = documentModel.getName();
+
+        //Updates relations part
+        RelationsCommonList relationsCommonList = updateRelations(itemCsid, input, wrapDoc, fUpdate);
+
+        PayloadOutputPart payloadOutputPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, relationsCommonList);  //FIXME: REM - We should check for a null relationsCommonList and not create the new common list payload
+        ctx.setProperty(RelationClient.SERVICE_COMMON_LIST_NAME, payloadOutputPart);
+
+        //now we add part for relations list
+        //ServiceContext ctx = getServiceContext();
+        //PayloadOutputPart foo = (PayloadOutputPart) ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
+        ((PoxPayloadOut) ctx.getOutput()).addPart(payloadOutputPart);
+    }
+
+    /**
+     * Checks to see if the refName has changed, and if so, 
+     * uses utilities to find all references and update them.
+     * @throws Exception 
+     */
+    protected void handleItemRefNameReferenceUpdate() throws Exception {
+        if (newRefNameOnUpdate != null && oldRefNameOnUpdate != null) {
+            // We have work to do.
+            if (logger.isDebugEnabled()) {
+                String eol = System.getProperty("line.separator");
+                logger.debug("Need to find and update references to Item." + eol
+                        + "   Old refName" + oldRefNameOnUpdate + eol
+                        + "   New refName" + newRefNameOnUpdate);
+            }
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+            RepositoryClient repoClient = getRepositoryClient(ctx);
+            String refNameProp = getRefPropName();
+
+            int nUpdated = RefNameServiceUtils.updateAuthorityRefDocs(ctx, repoClient, this.getRepositorySession(),
+                    oldRefNameOnUpdate, newRefNameOnUpdate, refNameProp);
+            if (logger.isDebugEnabled()) {
+                logger.debug("Updated " + nUpdated + " instances of oldRefName to newRefName");
+            }
+        }
+    }
+    
+    /*
+     * Note: The Vocabulary document handler overrides this method.
+     */
+    protected String getRefPropName() {
+       return ServiceBindingUtils.AUTH_REF_PROP;
+    }
+
+    
+    
 }
index 3cb71c65d4b6af9b40add20bc092def465357870..58e9a83003020f4982f3f73e2369ea967df24518 100644 (file)
@@ -31,11 +31,11 @@ import org.collectionspace.services.client.CollectionSpaceClient;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.Profiler;
 import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.query.QueryContext;
 import org.collectionspace.services.common.repository.RepositoryClient;
-import org.collectionspace.services.common.profile.Profiler;
 import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 
index 3ed7fae50657ff792a37d75ad9aa0df12d4f8d72..62392329dc0a7b329c2ef041f02174b0e424643d 100644 (file)
             <artifactId>org.collectionspace.services.client</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.collectionspace.services</groupId>
-            <artifactId>org.collectionspace.services.common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <!-- External dependencies -->
         <dependency>
             <groupId>dom4j</groupId>
index a64f3ef8798178543fb31d0e02ff553e8c7a60b3..1a5cf24a816f8d1b3ebbd8939f3f9f49d56377a6 100644 (file)
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.authority.jaxb</artifactId>\r
             <version>${project.version}</version>\r
-        </dependency>        \r
-        <dependency>\r
-            <groupId>org.collectionspace.services</groupId>\r
-            <artifactId>org.collectionspace.services.common</artifactId>\r
-            <optional>true</optional>\r
-            <version>${project.version}</version>\r
-        </dependency>        \r
+        </dependency>                \r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.person.jaxb</artifactId>\r
index 2ab35427d669a02fbcd652a3f54bafb3341ae56a..993def9db448a46a6fe46436f5c454fbbcc58377 100644 (file)
     <name>services.person.jaxb</name>
 
     <dependencies>
-        <dependency>
-            <groupId>org.collectionspace.services</groupId>
-            <artifactId>org.collectionspace.services.common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.collectionspace.services</groupId>
             <artifactId>org.collectionspace.services.jaxb</artifactId>
index 8d6bddd147ea9968a731813f18e2e2a2f278062b..5c7a3bb1c9f7b367e31d3aafead39c577ab8f8e5 100644 (file)
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.person.client</artifactId>\r
             <version>${project.version}</version>\r
+            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.collectionspace.services</groupId>\r
             <artifactId>org.collectionspace.services.authority.jaxb</artifactId>\r
             <optional>true</optional>\r
             <version>${project.version}</version>\r
-        </dependency>        \r
-        <dependency>\r
-            <groupId>org.collectionspace.services</groupId>\r
-            <artifactId>org.collectionspace.services.common</artifactId>\r
-            <optional>true</optional>\r
-            <version>${project.version}</version>\r
-        </dependency>        \r
+        </dependency>\r
+\r
         <!-- External dependencies -->\r
+\r
         <dependency>\r
             <groupId>org.testng</groupId>\r
             <artifactId>testng</artifactId>\r
+            <scope>test</scope>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.jboss.resteasy</groupId>\r
index 7e3f5aef1ec567e3ff4637324ccfa991784550a6..c070fdf2f872a3b637131aee747e71f4c7c94d1e 100644 (file)
@@ -40,9 +40,7 @@ public class RelationClient extends AbstractPoxServiceClientImpl<RelationsCommon
        public static final String SERVICE_PATH_PROXY = SERVICE_PATH + "/";     
        public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME;
        public static final String SERVICE_COMMON_LIST_NAME = "relations-common-list";
-
     public static final String SERVICE_COMMONPART_NAME = IRelationsManager.SERVICE_COMMONPART_NAME;
-
     
        @Override
        public String getServiceName() {
index eeb1cf73dfb5a66b802ae9adf8cc2ec2b9534451..9a31e066e2f9d8f2047d10d36f316754bbba2742 100644 (file)
@@ -6,7 +6,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
 import org.collectionspace.services.relation.RelationsCommonList;
-import org.collectionspace.services.common.relation.IRelationsManager;
+import org.collectionspace.services.client.IRelationsManager;
 import org.collectionspace.services.client.workflow.WorkflowClient;
 
 import org.jboss.resteasy.client.ClientResponse;
index 0b21eb46f32d49680d16753227a7f421129855ca..f93001a0ac48dd56f10ad1e204ec98f0046a32d1 100644 (file)
@@ -27,19 +27,15 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.collectionspace.services.PersonJAXBSchema;
 import org.collectionspace.services.client.CollectionSpaceClient;
-import org.collectionspace.services.client.PayloadInputPart;
 import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PersonAuthorityClient;
 import org.collectionspace.services.client.PersonAuthorityClientUtils;
-import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.client.RelationClient;
-import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.relation.RelationsCommon;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationshipType;
@@ -47,9 +43,7 @@ import org.collectionspace.services.relation.RelationshipType;
 import org.jboss.resteasy.client.ClientResponse;
 
 import org.testng.Assert;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.Test;
 
diff --git a/services/relation/service/src/main/java/org/collectionspace/services/relation/RelationResource.txt b/services/relation/service/src/main/java/org/collectionspace/services/relation/RelationResource.txt
new file mode 100644 (file)
index 0000000..d3a70a7
--- /dev/null
@@ -0,0 +1,3 @@
+Because of a dependency cycle with the "Common" module, the RelationResource class was moved to the "Common" module at:
+
+..\services\common\src\main\java\org\collectionspace\services\common\relation
\ No newline at end of file