]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-4040 ensure consumer may not write uri fields in relations subject/uri and \
authorLaramie Crocker <laramie@berkeley.edu>
Tue, 24 May 2011 05:40:42 +0000 (05:40 +0000)
committerLaramie Crocker <laramie@berkeley.edu>
Tue, 24 May 2011 05:40:42 +0000 (05:40 +0000)
  object/uri.  URIs sent to hierarchic authorities will be ignored.  \
  CSPACE-4042  ensures same authority must be used for items related in hierarchy. \
  CSPACE-4037  Service now generates correct REST URIs for all items.  \
  LIST will now return relation-list-item/subject/uri and relation-list-item/object/uri elements correctly. \
  NOTE: removed relation-list-item/service and relation-list-item/documentTypeFromModel from payloads. PLEASE SEE CSPACE-4037 for attached sample payloads from test suite and additional notes.

services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplay.java
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplayReport.java
services/IntegrationTests/src/test/resources/test-data/xmlreplay/location/hierarchy/3-locations_w_relations.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/location/location-2-authorities.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/location/location-hierarchy.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/person/person.xml
services/authority/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java
services/jaxb/src/main/resources/relations_common.xsd
services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java

index 15e224137a5985a4a9b5411ce957cba94f8088af..5b80c7595860009e202d17e406b829181754f09e 100755 (executable)
@@ -178,14 +178,7 @@ public class XmlReplay {
             list.add(results);\r
             this.reportsList.addAll(replay.getReportsList());   //Add all the reports from the inner replay, to our master replay's reportsList, to generate the index.html file.\r
         }\r
-        StringBuffer sb = new StringBuffer(XmlReplayReport.HTML_PAGE_START);\r
-        String dateStr = Tools.nowLocale();\r
-        sb.append("<div class='REPORTTIME'>XmlReplay run  "+dateStr+" master: "+masterFilename+"</div>");\r
-        for (String oneToc: this.reportsList){\r
-            sb.append(oneToc).append("<hr />");\r
-        }\r
-        sb.append(XmlReplayReport.HTML_PAGE_END);\r
-        FileTools.saveFile(getReportsDir(this.basedir),"index."+masterFilename+".html", sb.toString(), false);\r
+        XmlReplayReport.saveIndexForMaster(basedir, masterFilename, this.reportsList);\r
         return list;\r
     }\r
 \r
@@ -725,10 +718,9 @@ public class XmlReplay {
         File m = new File(controlFileName);\r
         String localName = m.getName();//don't instantiate, just use File to extract file name without directory.\r
         String reportName = localName+'-'+testGroupID+".html";\r
-        File resultFile = FileTools.saveFile(getReportsDir(xmlReplayBaseDir), reportName, report.getPage(), true);\r
+\r
+        File resultFile = report.saveReport(xmlReplayBaseDir, reportName);\r
         if (resultFile!=null) {\r
-            System.out.println("XmlReplay summary reports saved to directory: "+resultFile.getParent());\r
-            System.out.println("XmlReplay summary report: "+resultFile.getCanonicalPath());\r
             String toc = report.getTOC(reportName);\r
             reportsList.add(toc);\r
         }\r
@@ -737,10 +729,7 @@ public class XmlReplay {
         return results;\r
     }\r
 \r
-    //todo: move from xmlReplayBaseDir to "target/xmlReplayReports" dir.\r
-    public static String getReportsDir(String basename){\r
-        return Tools.glue(basename,"/","TEST-REPORTS");\r
-    }\r
+\r
 \r
     //======================== MAIN ===================================================================\r
 \r
index 4783b049c546d72c8ba91d30fd117d67c7b7e105..d46c07926e65dd3beaa920a61c9724490a2d62b9 100644 (file)
@@ -1,10 +1,13 @@
 package org.collectionspace.services.IntegrationTests.xmlreplay;
 
 import org.collectionspace.services.common.XmlTools;
+import org.collectionspace.services.common.api.FileTools;
 import org.collectionspace.services.common.api.Tools;
 import org.dom4j.Document;
 import org.dom4j.DocumentHelper;
 
+import javax.swing.text.Style;
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -12,8 +15,6 @@ import java.util.List;
  * @author  laramie
  */
 public class XmlReplayReport {
-    public static final String HTML_PAGE_START = "<html><head><script type='text/javascript' src='reports-include.js'></script>"
-                                                                         +"<LINK rel='stylesheet' href='reports-include.css'></LINK></head><body>";
     protected static final String HTML_PAGE_END = "</body></html>";
     protected static final String TOPLINKS = "<a class='TOPLINKS' href='javascript:openAll();'>Show All Payloads</a>" + "<a class='TOPLINKS' href='javascript:closeAll();'>Hide All Payloads</a>";
 
@@ -50,10 +51,9 @@ public class XmlReplayReport {
     private StringBuffer header = new StringBuffer();
     private StringBuffer buffer = new StringBuffer();
     private String runInfo = "";
-    //private StringBuffer toc = new StringBuffer();
 
-    public String getPage(){
-        return    HTML_PAGE_START
+    public String getPage(String basedir){
+        return    formatPageStart(basedir)
                     +"<div class='REPORTTIME'>XmlReplay run  "+Tools.nowLocale()+"</div>"
                     +header.toString()
                     +this.runInfo
@@ -68,10 +68,12 @@ public class XmlReplayReport {
         StringBuffer tocBuffer = new StringBuffer();
 
         if (Tools.notBlank(reportName)){
-            // We are generating an index.html file.
+            // We are generating a TOC for an index.html file that references other report files.
             tocBuffer.append(this.header.toString());
+        } else {
+            // We are generating a single report file, so all links are relative to this file, and we should have the TOPLINKS which allow things like showAllPayloads..
+            tocBuffer.append(BR).append(TOPLINKS).append(BR);
         }
-        tocBuffer.append(BR).append(TOPLINKS).append(BR);
         for (TOC toc: tocList){
               tocBuffer.append(BR+"<a href='"+reportName+"#TOC"+toc.tocID+"'>"+toc.testID+"</a> "+ toc.detail);
         }
@@ -84,10 +86,11 @@ public class XmlReplayReport {
          //addText(this.runInfo);
     }
 
-
+    /** Call this method to insert arbitrary HTML in your report file, at the point after the last call to addTestResult() or addTestGroup().    */
     public void addText(String text){
          buffer.append(text);
     }
+
     public void addTestGroup(String groupID, String controlFile){
         header.append(GROUP_START);
         header.append(lbl("Test Group")).append(groupID).append(SP).append(lbl("Control File")).append(controlFile);
@@ -111,6 +114,59 @@ public class XmlReplayReport {
     }
     private List<TOC> tocList = new ArrayList<TOC>();
 
+    public static String formatPageStart(String xmlReplayBaseDir){
+            String script = FileTools.readFile(xmlReplayBaseDir, "TEST-REPORTS/reports-include.js");
+            String style =  FileTools.readFile(xmlReplayBaseDir, "TEST-REPORTS/reports-include.css");
+            return "<html><head><script type='text/javascript'>\r\n"
+                     +script
+                     +"\r\n</script>\r\n<style>\r\n"
+                     +style
+                     +"\r\n</style></head><body>";
+    }
+
+    public File saveReport(String xmlReplayBaseDir, String reportName)  {
+        try {
+            File resultFile = FileTools.saveFile(getReportsDir(xmlReplayBaseDir), reportName, this.getPage(xmlReplayBaseDir), true);
+            if (resultFile!=null) {
+                String resultFileName =  resultFile.getCanonicalPath();
+                //System.out.println("XmlReplay summary reports saved to directory: "+resultFile.getParent());
+                System.out.println("XmlReplay summary report: "+resultFileName);
+                return resultFile;
+            }
+        } catch (Exception e){
+            System.out.println("ERROR saving XmlReplay report in basedir: "+xmlReplayBaseDir+" reportName: "+reportName+" error: "+e);
+        }
+        return null;
+    }
+
+    public static String getReportsDir(String basename){
+        return Tools.glue(basename,"/","TEST-REPORTS");
+    }
+
+    /** @param localMasterFilename should be a local filename for the index of each xmlReplay master control file, e.g. objectexit.xml
+     *               so what gets written to disk will be something like index.objectexit.xml.html . The actual filename will be available from
+     *               the returned File object if successful.
+     *   @return File if successful, else returns null.
+     */
+    public static File saveIndexForMaster(String xmlReplayBaseDir, String localMasterFilename, List<String> reportsList){
+        String masterFilename =  "index."+localMasterFilename+".html";
+        try{
+            StringBuffer sb = new StringBuffer(formatPageStart(xmlReplayBaseDir));
+            String dateStr = Tools.nowLocale();
+            sb.append("<div class='REPORTTIME'>XmlReplay run  "+dateStr+" master: "+localMasterFilename+"</div>");
+            for (String oneToc: reportsList){
+                sb.append(oneToc);
+                sb.append("<hr />");
+            }
+            sb.append(HTML_PAGE_END);
+
+            return FileTools.saveFile(getReportsDir(xmlReplayBaseDir),masterFilename, sb.toString(), false);
+        } catch (Exception e){
+            System.out.println("ERROR saving XmlReplay report index: in  xmlReplayBaseDir: "+xmlReplayBaseDir+"localMasterFilename: "+localMasterFilename+" masterFilename: "+masterFilename+" list: "+reportsList+" error: "+e);
+            return null;
+        }
+    }
+
     protected String formatSummary(ServiceResult serviceResult, int tocID){
         TOC toc = new TOC();
         toc.tocID = tocID;
index 6cb71f84423afde8960c2f9479dec5f26ff0e843..aecbeaa4acf3c49526b5114a11540f246366ab35 100755 (executable)
@@ -25,7 +25,7 @@
                  <csid>${parentCSID}</csid>\r
                  <uri>${parentUri}</uri>\r
                  <documentType>Locationitem</documentType>\r
-                 <number>0000</number>\r
+                 <number>0000-setting-error</number>\r
                  <name>Parent</name>\r
                </object>\r
        </relation-list-item>\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/location/location-2-authorities.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/location/location-2-authorities.xml
new file mode 100644 (file)
index 0000000..e9260fe
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmlReplay>
+       <testGroup ID="HierarchicLocation" autoDeletePOSTS="true">
+       
+           <test ID="LocationAuth1" auth="admin@collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/locationauthorities/</uri>
+            <filename>location/hierarchy/1-authority.xml</filename>
+            <vars>
+               <var ID="shortIdentifier">CSPACE3739LocationAuthority</var>
+               <var ID="displayName">LocationAuth1-displayName</var>
+            </vars>
+        </test>
+        <test ID="GETLocationAuth1" auth="admin@collectionspace.org">
+            <method>GET</method>
+            <uri>/cspace-services/locationauthorities/${LocationAuth1.CSID}</uri>
+        </test>
+        
+       
+           <test ID="LocationAuth2" auth="admin@collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/locationauthorities/</uri>
+            <filename>location/hierarchy/1-authority.xml</filename>
+            <vars>
+               <var ID="shortIdentifier">CSPACE3739LocationAuthority</var>
+               <var ID="displayName">LocationAuth1-displayName</var>
+            </vars>
+        </test>
+        <test ID="GETLocationAuth2" auth="admin@collectionspace.org">
+            <method>GET</method>
+            <uri>/cspace-services/locationauthorities/${LocationAuth2.CSID}</uri>
+        </test>
+        
+       </testGroup>
+</xmlReplay>
index 0902c69eacd47e2a94e0862996899c7017c451fe..0b67e3cb95051e662bb7ffc44c9089ada3345da4 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xmlReplay>
-       <testGroup ID="HierarchicLocation" autoDeletePOSTS="false">
+       <testGroup ID="HierarchicLocation" autoDeletePOSTS="true">
        
            <test ID="LocationAuth1" auth="admin@collectionspace.org">
             <method>POST</method>
                <var ID="displayName">LocationAuth1-displayName</var>
             </vars>
         </test>
+        <test ID="GETLocationAuth1" auth="admin@collectionspace.org">
+            <method>GET</method>
+            <uri>/cspace-services/locationauthorities/${LocationAuth1.CSID}</uri>
+        </test>
+        
         <test ID="LocationChild1">
             <method>POST</method>
             <uri>/cspace-services/locationauthorities/${LocationAuth1.CSID}/items/</uri>
@@ -67,7 +72,7 @@
                <var ID="shortIdentifier">Cabinet1</var>
                <var ID="name">Cabinet 1</var>
                <var ID="parentCSID">${LocationParent.CSID}</var>
-               <var ID="parentUri">/cspace-services/locationauthorities/urn:cspace:name(CSPACE3739LocationAuthority)/items/${LocationParent.CSID}</var>
+               <var ID="parentUri">/cspace-services/locationauthorities/urn:cspace:name(CSPACE3739LocationAuthority-setting-error-parent)/items/${LocationParent.CSID}</var>
                <var ID="childCSID">${LocationChild1.CSID}</var>
                <var ID="childUri">/cspace-services/locationauthorities/urn:cspace:name(CSPACE3739LocationAuthority)/items/${LocationChild1.CSID}</var>
                <var ID="child2CSID">${LocationChild2.CSID}</var>
index efca32bbac6a4255ebc947d171c8eabfe520276d..fb810e49c94657500e8aaf67498604434f583322 100755 (executable)
             </vars>\r
         </test>\r
         \r
+        <test ID="PersonParent">\r
+            <method>POST</method>\r
+            <uri>/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/</uri>\r
+            <filename>person/persons_common.xml</filename>\r
+            <vars>\r
+               <var ID="inAuthority">${PersonAuth1.CSID}</var>\r
+               <var ID="authShortIdentifier">CSPACE3739PersonAuthority</var>\r
+               <var ID="shortIdentifier">johnWayneActorParent</var>\r
+            </vars>\r
+        </test>\r
+\r
+        \r
         <test ID="PersonChild">\r
             <method>POST</method>\r
             <uri>/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/</uri>\r
             </vars>\r
         </test>\r
         \r
+        <test ID="PersonChild3">\r
+            <method>POST</method>\r
+            <uri>/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/</uri>\r
+            <filename>person/persons_common.xml</filename>\r
+            <vars>\r
+               <var ID="inAuthority">${PersonAuth1.CSID}</var>\r
+               <var ID="authShortIdentifier">CSPACE3739PersonAuthority</var>\r
+               <var ID="shortIdentifier">johnWayneActorChild3</var>\r
+            </vars>\r
+        </test>\r
+        \r
+        \r
         <test ID="Person1">\r
             <method>POST</method>\r
             <uri>/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/</uri>\r
                <var ID="inAuthority">${PersonAuth1.CSID}</var>\r
                <var ID="authShortIdentifier">CSPACE3739PersonAuthority</var>\r
                <var ID="shortIdentifier">johnWayneActor</var>\r
+               <var ID="parentCSID">${PersonParent.CSID}</var>\r
+               <var ID="parentUri">/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/${PersonParent.CSID}</var>\r
                <var ID="childCSID">${PersonChild.CSID}</var>\r
                <var ID="childUri">/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/${PersonChild.CSID}</var>\r
                <var ID="child2CSID">${PersonChild2.CSID}</var>\r
                <var ID="child2Uri">/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/${PersonChild2.CSID}</var>\r
+               <var ID="child3CSID">${PersonChild3.CSID}</var>\r
+               <var ID="child3Uri">/cspace-services/personauthorities/urn:cspace:name(CSPACE3739PersonAuthority)/items/${PersonChild3.CSID}</var>\r
             </vars>\r
         </test>\r
         \r
index 1af842ea5b85ab81693c7398cec4872437f63943..1dd57f0a2022fa9014c23e9a1b2ab303364f3bd2 100644 (file)
  */
 package org.collectionspace.services.common.vocabulary.nuxeo;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
 import org.collectionspace.services.client.AuthorityClient;
 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.authority.AuthorityItemRelations;
 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.context.MultipartServiceContext;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.document.DocumentWrapperImpl;
 import org.collectionspace.services.common.relation.IRelationsManager;
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.repository.RepositoryClientFactory;
 import org.collectionspace.services.common.service.ObjectPartType;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
@@ -58,9 +52,15 @@ import org.nuxeo.ecm.core.api.DocumentModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.relation.Relation;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+//import org.collectionspace.services.common.authority.AuthorityItemRelations;
 
 /**
  * AuthorityItemDocumentModelHandler
@@ -393,6 +393,22 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
         ((PoxPayloadOut)ctx.getOutput()).addPart(foo);
     }
 
+     /**  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
+      */
     public RelationsCommonList updateRelations(String itemCSID, PoxPayloadIn input, DocumentWrapper<DocumentModel> wrapDoc)
      throws Exception {
         PayloadInputPart part = input.getPart(RelationClient.SERVICE_COMMON_LIST_NAME);        //input.getPart("relations_common");
@@ -405,36 +421,21 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
         UriInfo uriInfo = ctx.getUriInfo();
         MultivaluedMap queryParams = uriInfo.getQueryParameters();
 
+        //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);
-
         RelationsCommonList childListOuter = (new RelationResource()).getList(ctx.getUriInfo());    //magically knows all query params because they are in the context.
 
-        //Leave predicate, swap subject and object.
+        //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 = (new RelationResource()).getList(ctx.getUriInfo());
-        /*
-            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
-           */
         String HAS_BROADER = RelationshipType.HAS_BROADER.value();
 
         List<RelationsCommonList.RelationListItem> inboundList = relationsCommonListBody.getRelationListItem();
@@ -444,17 +445,10 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
 
         DocumentModel docModel = wrapDoc.getWrappedObject();
 
+        //Do magic replacement of ${itemCSID} and fix URI's.
+        fixupInboundListItems(ctx, inboundList, docModel, itemCSID);
+
         for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
-            if (inboundItem.getObject().getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
-                inboundItem.setObjectCsid(itemCSID);
-                inboundItem.getObject().setCsid(itemCSID);
-                inboundItem.getObject().setUri(getUri(docModel));
-            }
-            if (inboundItem.getSubject().getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
-                inboundItem.setSubjectCsid(itemCSID);
-                inboundItem.getSubject().setCsid(itemCSID);
-                 inboundItem.getSubject().setUri(getUri(docModel));
-            }
             if (inboundItem.getObject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
                 //then this is an item that says we have a child.
                 RelationsCommonList.RelationListItem childItem = findInList(childList, inboundItem);
@@ -472,8 +466,7 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
                     actionList.add(inboundItem);   //doesn't exist as a parent, but is a parent. Add to additions list
                 }
             }  else {
-
-                System.out.println("\r\n\r\n================\r\n    Element didn't match parent or child, but may have partial fields that match. inboundItem: "+inboundItem);
+                logger.warn("Element didn't match parent or child, but may have partial fields that match. inboundItem: "+inboundItem);
                 //not dealing with: hasNarrower or any other predicate.
             }
         }
@@ -485,6 +478,55 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
         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 (inboundItemObject.getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
+                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 (inboundItemSubject.getCsid().equalsIgnoreCase(CommonAPI.AuthorityItemCSID_REPLACE)){
+                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
+
+        }
+    }
+
+    public RepositoryClient getRepositoryClient(ServiceContext ctx) {
+        RepositoryClient repositoryClient = RepositoryClientFactory.getInstance().getClient(ctx.getRepositoryClientName());
+        return repositoryClient;
+    }
+
     // this method calls the RelationResource to have it create the relations and persist them.
     private void createRelations(List<RelationsCommonList.RelationListItem> inboundList, ServiceContext ctx){
          for (RelationsCommonList.RelationListItem item : inboundList) {
@@ -574,8 +616,44 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
      private void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item){
         list.remove(item);
     }
-    //================= TODO: move this to common, refactoring this and  CollectionObjectResource.java
 
+    /* don't even THINK of re-using this method.
+     * String example_uri = "/locationauthorities/7ec60f01-84ab-4908-9a6a/items/a5466530-713f-43b4-bc05";
+     */
+    private String extractInAuthorityCSID(String uri){
+        String IN_AUTHORITY_REGEX      = "/(.*?)/(.*?)/(.*)";
+        Pattern p = Pattern.compile(IN_AUTHORITY_REGEX);
+        Matcher m = p.matcher(uri);
+        if (m.find()){
+            if (m.groupCount()<3){
+                logger.warn("REGEX-WRONG-GROUPCOUNT looking in "+uri);
+                return "";
+            } else {
+                //String service = m.group(1);
+                String inauth = m.group(2);
+                //String theRest = m.group(3);
+                return inauth;
+                //print("service:"+service+", inauth:"+inauth+", rest:"+rest);
+            }
+        } else {
+            logger.warn("REGEX-NOT-MATCHED looking in "+uri);
+            return "";
+        }
+    }
+
+    //ensures CSPACE-4042
+    protected void uriPointsToSameAuthority(String thisURI, String inboundItemURI) throws Exception {
+        String authorityCSID = extractInAuthorityCSID(thisURI);
+        String authorityCSIDForInbound = extractInAuthorityCSID(inboundItemURI);
+        if  (      Tools.isBlank(authorityCSID)
+                || Tools.isBlank(authorityCSIDForInbound)
+                ||   ( ! authorityCSID.equalsIgnoreCase(authorityCSIDForInbound) )
+            )  {
+                throw new Exception("Item URI "+thisURI+" must point to same authority as related item: "+inboundItemURI);
+            }
+    }
+
+    //================= TODO: move this to common, refactoring this and  CollectionObjectResource.java
     public RelationsCommonList getRelations(String subjectCSID, String objectCSID, String predicate) throws Exception {
         ServiceContext ctx = getServiceContext();
         MultivaluedMap queryParams = ctx.getQueryParams();
@@ -587,8 +665,7 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon, AICommonList>
         RelationsCommonList relationsCommonList = relationResource.getList(ctx.getUriInfo());
         return relationsCommonList;
     }
-
-    //============================= END refactor ==========================
+    //============================= END TODO refactor ==========================
 
 }
 
index e3e3cff634655da4f38e75c18d4d458f974bf5fb..fb8843615717d6da4ae3bf3949e358900db2afff 100644 (file)
         <xs:sequence>\r
             <xs:element name="uri" type="xs:anyURI" minOccurs="1"/>\r
             <xs:element name="csid" type="xs:string" minOccurs="1"/>\r
-            <xs:element name="service" type="xs:string" minOccurs="1"/>\r
             <xs:element name="name" type="xs:string" minOccurs="1"/>\r
             <xs:element name="number" type="xs:string" minOccurs="1"/>\r
             <xs:element name="documentType" type="xs:string" minOccurs="1"/>\r
-            <xs:element name="documentTypeFromModel" type="xs:string" minOccurs="1"/>\r
             <!-- order is for potential use by app/gui.  services won't do anything with it.-->\r
             <xs:element name="order" type="xs:string" minOccurs="0"/>\r
             <!-- key is for things like -which predicate type search did this list come from-->\r
index e83b1e8313b6083f839f774c6ffc432b847ff91e..17c269575ceb382e8f96da676857a3cd05bbf401 100644 (file)
@@ -188,30 +188,32 @@ public class RelationDocumentModelHandler
                                                                                                  String documentType) throws Exception {
         RelationsDocListItem item = new RelationsDocListItem();
         item.setDocumentType(documentType);//this one comes from the record, as documentType1, documentType2.
-        item.setService(documentType);//this one comes from the record, as documentType1, documentType2.   Current app seems to use servicename for this.
+        // CSPACE-4037 REMOVING: item.setService(documentType);//this one comes from the record, as documentType1, documentType2.   Current app seems to use servicename for this.
         item.setCsid(itemCsid);
 
         DocumentModel itemDocModel =  NuxeoUtils.getDocFromCsid(getRepositorySession(), ctx, itemCsid);    //null if not found.
         if (itemDocModel!=null){
             String itemDocType = itemDocModel.getDocumentType().getName();
-            item.setDocumentTypeFromModel(itemDocType);           //this one comes from the nuxeo documentType
+            // CSPACE-4037 REMOVING: item.setDocumentTypeFromModel(itemDocType);           //this one comes from the nuxeo documentType
 
             //DEBUG: System.out.println("\r\n******** AuthorityItemDocumentModelHandlder documentType **************\r\n\tdocModel: "+itemDocType+"\r\n\tpayload: "+documentType);
-            boolean usedDocumentTypeFromPayload = true;
-            if ( ! Tools.isBlank(documentType)){
+            //boolean usedDocumentTypeFromPayload = true;
+            /*if ( ! Tools.isBlank(documentType)){
                 if (documentType.equals(itemDocType)){
-                    usedDocumentTypeFromPayload = true;
+                    //usedDocumentTypeFromPayload = true;
                 }  else {
                     // Laramie20110510 CSPACE-3739  throw the exception for 3739, otherwise, don't throw it.
                     //throw new Exception("documentType supplied was wrong.  supplied: "+documentType+" required: "+itemDocType+ " itemCsid: "+itemCsid );
                 }
             } else {
-                usedDocumentTypeFromPayload = false;
+                //usedDocumentTypeFromPayload = false;
                 item.setDocumentType(itemDocType);
+            }   */
+             if (Tools.isBlank(documentType)){
+               item.setDocumentType(itemDocType);
+             }
 
-            }
-
-
+            // TODO: clean all the output statements out of here when CSPACE-4037 is done.
             //TODO: ensure that itemDocType is really the entry point, i.e. servicename==doctype
             //ServiceBindingType itemSbt2 = tReader.getServiceBinding(ctx.getTenantId(), itemDocType);
             String propName = "ERROR-FINDING-PROP-VALUE";