/**
   * Gets the relation list item, looking up the subject and object documents, and getting summary
   * info via the objectName and objectNumber properties in tenant-bindings.
   *
   * @param ctx the ctx
   * @param sbt the ServiceBindingType of Relations service
   * @param tReader the tenant-bindings reader, for looking up docnumber and docname
   * @param docModel the doc model
   * @param serviceContextPath the service context path
   * @return the relation list item, with nested subject and object summary info.
   * @throws Exception the exception
   */
  private RelationListItem getRelationListItem(
      ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
      ServiceBindingType sbt,
      TenantBindingConfigReaderImpl tReader,
      DocumentModel docModel,
      String serviceContextPath)
      throws Exception {
    RelationListItem relationListItem = new RelationListItem();
    String id = getCsid(docModel);
    relationListItem.setCsid(id);

    relationListItem.setSubjectCsid(
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.DOCUMENT_ID_1));

    String predicate =
        (String)
            docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.RELATIONSHIP_TYPE);
    relationListItem.setRelationshipType(predicate);
    relationListItem.setPredicate(predicate); // predicate is new name for relationshipType.
    relationListItem.setPredicateDisplayName(
        (String)
            docModel.getProperty(
                ctx.getCommonPartLabel(), RelationJAXBSchema.RELATIONSHIP_TYPE_DISPLAYNAME));

    relationListItem.setObjectCsid(
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.DOCUMENT_ID_2));

    relationListItem.setUri(serviceContextPath + id);

    // Now fill in summary info for the related docs: subject and object.
    String subjectCsid = relationListItem.getSubjectCsid();
    String documentType =
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.DOCUMENT_TYPE_1);
    RelationsDocListItem subject =
        createRelationsDocListItem(ctx, sbt, subjectCsid, tReader, documentType);

    // Object o1 =  docModel.getProperty(ctx.getCommonPartLabel(), "subject");
    // Object o2 =  docModel.getProperty(ctx.getCommonPartLabel(), "object");

    String subjectUri =
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.subjectUri);
    subject.setUri(subjectUri);
    relationListItem.setSubject(subject);

    String objectCsid = relationListItem.getObjectCsid();
    String documentType2 =
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.DOCUMENT_TYPE_2);
    RelationsDocListItem object =
        createRelationsDocListItem(ctx, sbt, objectCsid, tReader, documentType2);

    String objectUri =
        (String) docModel.getProperty(ctx.getCommonPartLabel(), RelationJAXBSchema.objectUri);
    object.setUri(objectUri);
    relationListItem.setObject(object);

    return relationListItem;
  }
  protected RelationsDocListItem createRelationsDocListItem(
      ServiceContext ctx,
      ServiceBindingType sbt,
      String itemCsid,
      TenantBindingConfigReaderImpl tReader,
      String documentType)
      throws Exception {
    RelationsDocListItem item = new RelationsDocListItem();
    item.setDocumentType(
        documentType); // this one comes from the record, as documentType1, documentType2.
    // 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();
      // 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)){
          if (documentType.equals(itemDocType)){
              //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;
          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";
      ServiceBindingType itemSbt =
          tReader.getServiceBindingForDocType(ctx.getTenantId(), itemDocType);
      try {
        propName = ServiceBindingUtils.getPropertyValue(itemSbt, ServiceBindingUtils.OBJ_NAME_PROP);
        String itemDocname =
            ServiceBindingUtils.getMappedFieldInDoc(
                itemSbt, ServiceBindingUtils.OBJ_NAME_PROP, itemDocModel);
        if (propName == null || itemDocname == null) {
          // System.out.println("=== prop NOT found:
          // "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType:
          // "+documentType);
        } else {
          item.setName(itemDocname);
          // System.out.println("=== found prop :
          // "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType:
          // "+documentType);
        }
      } catch (Throwable t) {
        System.out.println(
            "====Error finding objectNameProperty: "
                + itemDocModel
                + " field "
                + ServiceBindingUtils.OBJ_NAME_PROP
                + "="
                + propName
                + " not found in itemDocType: "
                + itemDocType
                + " inner: "
                + t.getMessage());
      }
      propName = "ERROR-FINDING-PROP-VALUE";
      try {
        propName =
            ServiceBindingUtils.getPropertyValue(itemSbt, ServiceBindingUtils.OBJ_NUMBER_PROP);
        String itemDocnumber =
            ServiceBindingUtils.getMappedFieldInDoc(
                itemSbt, ServiceBindingUtils.OBJ_NUMBER_PROP, itemDocModel);

        if (propName == null || itemDocnumber == null) {
          // System.out.println("=== prop NOT found:
          // "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
          //                          +" documentType: "+documentType);
        } else {
          item.setNumber(itemDocnumber);
          // System.out.println("============ found prop :
          // "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
          //                          +" documentType: "+documentType);
        }
      } catch (Throwable t) {
        logger.error(
            "====Error finding objectNumberProperty: "
                + ServiceBindingUtils.OBJ_NUMBER_PROP
                + "="
                + propName
                + " not found in itemDocType: "
                + itemDocType
                + " inner: "
                + t.getMessage());
      }
    } else {
      item.setError("INVALID: related object is absent");
      // Laramie20110510 CSPACE-3739  throw the exception for 3739, otherwise, don't throw it.
      // throw new Exception("INVALID: related object is absent "+itemCsid);
    }
    return item;
  }