public final static String CMIS_CSPACE_RELATIONS_PREDICATE = IQueryManager.CMIS_RELATIONS_PREFIX
+ "." + SERVICE_COMMONPART_NAME + ":relationshipType";
-
public final static String CMIS_CSPACE_RELATIONS_OBJECT_TYPE = IQueryManager.CMIS_RELATIONS_PREFIX
+ "." + SERVICE_COMMONPART_NAME + ":objectDocumentType";
public final static String CMIS_CSPACE_RELATIONS_TITLE = IQueryManager.CMIS_RELATIONS_PREFIX
+ "." + IQueryManager.CMIS_NUXEO_TITLE;
-
- /** The Constant SUBJECT. */
+
+ /** The Subject related schema/db column names */
static public final String SUBJECT = "subjectCsid";
static public final String SUBJECT_DOCTYPE = "subjectDocumentType";
-
- static public final String SUBJECT_REFNAME = "subjectRefName";
+ static public final String SUBJECT_REFNAME = "subjectRefName";
+
+ /** Request query params for Subject related requests */
static public final String SUBJECT_QP = "sbj";
-// static public final String SUBJECT_TYPE = "subjectType";
static public final String SUBJECT_TYPE_QP = SUBJECT_QP + "Type";
-
- // A query param for specifying either Subject or Object
- static public final String SUBJECT_OR_OBJECT = "sbjOrObj";
-
- /** The Constant PREDICATE. */
+
+ /** The Predicate related schema/db column names */
static public final String PREDICATE = "predicate";
static public final String PREDICATE_QP = "prd";
static public final String RELATIONSHIP_TYPE = "relationshipType";
-
- /** The Constant OBJECT. */
+ /** The Object related schema/db column names */
static public final String OBJECT = "objectCsid";
static public final String OBJECT_DOCTYPE = "objectDocumentType";
static public final String OBJECT_REFNAME = "objectRefName";
+
+ /** Request query params for Subject related requests */
static public final String OBJECT_QP = "obj";
-// static public final String OBJECT_TYPE = "objectType";
static public final String OBJECT_TYPE_QP = OBJECT_QP + "Type";
+
+ // A query param that, if true, will case the Relations service to return the combined results of two queries for LIST requests -reversing the
+ // suject and object values in the second query. This is useful for finding relations for records when you're not sure if they're the subject
+ // or object of the relationship.
+ public static final String RECIPROCAL_QP = "andReciprocal";
}
import org.collectionspace.services.common.CSWebApplicationException;
import org.collectionspace.services.common.NuxeoBasedResource;
import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.api.Tools;
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.relation.RelationsCommon;
import org.collectionspace.services.relation.RelationsCommonList;
import org.collectionspace.services.relation.RelationsCommonList.RelationListItem;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
+
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.DELETE;
import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
String predicate = queryParams.getFirst(IRelationsManager.PREDICATE_QP);
String objectCsid = queryParams.getFirst(IRelationsManager.OBJECT_QP);
String objectType = queryParams.getFirst(IRelationsManager.OBJECT_TYPE_QP);
- String subjectOrObject = queryParams.getFirst(IRelationsManager.SUBJECT_OR_OBJECT);
+ String viceVersaValue = queryParams.getFirst(IRelationsManager.RECIPROCAL_QP);
- return this.getRelationList(parentCtx, uriInfo, subjectCsid, subjectType, predicate, objectCsid, objectType, subjectOrObject);
+ RelationsCommonList resultList = this.getRelationList(parentCtx, uriInfo, subjectCsid, subjectType, predicate, objectCsid, objectType, Tools.isTrue(viceVersaValue));
+
+ return resultList;
}
- private RelationsCommonList getRelationList(
+
+ private RelationsCommonList getRelationList(
ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx,
UriInfo uriInfo,
String subjectCsid, String subjectType,
String predicate,
String objectCsid,
String objectType,
- String subjectOrObject) throws CSWebApplicationException {
+ boolean viceVersa) throws CSWebApplicationException {
try {
ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(uriInfo);
if (parentCtx != null && parentCtx.getCurrentRepositorySession() != null) { // If the parent context has a non-null and open repository session then use it
ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession());
}
+
DocumentHandler handler = createDocumentHandler(ctx);
-
- String relationClause = RelationsUtils.buildWhereClause(subjectCsid, subjectType, predicate, objectCsid, objectType, subjectOrObject);
+ String relationClause = RelationsUtils.buildWhereClause(subjectCsid, subjectType, predicate, objectCsid, objectType, viceVersa);
handler.getDocumentFilter().appendWhereClause(relationClause, IQueryManager.SEARCH_QUALIFIER_AND);
//
// Handle keyword clause
private static final Logger logger = LoggerFactory.getLogger(RelationUtils.class);
private static final int DEFAULT_PAGE_SIZE = 1000;
-
/*
* Performs an NXQL query to find refName references in relationship records.
*/
* @param object the object
* @return the string
*/
- public static String buildWhereClause(String subject, String subjectType,
+ private static String buildWhereClause(String subject, String subjectType,
String predicate,
- String object, String objectType,
- String subjectOrObject) {
+ String object, String objectType) {
String result = null;
StringBuilder stringBuilder = new StringBuilder();
-
- if (subjectOrObject != null && object != null) {
- // Used for GET requests like: cspace-services/collectionobjects?mkRtSbjOrObj=cf5db000-4e65-42d5-8117
- //
- // (Example, ((rel.subjectcsid = subject AND rel.objectcsid = target)
- // OR
- // (rel.subjectcsid = target AND rel.objectcsid = subject))
- //
- String target = object;
- stringBuilder.append("(");
- stringBuilder.append("(" + RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.SUBJECT_CSID + " = " + "'" + subjectOrObject + "'");
- stringBuilder.append(" AND " + RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.OBJECT_CSID + " = " + "'" + target + "'" + ")");
- stringBuilder.append(" OR ");
- stringBuilder.append("(" + RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.SUBJECT_CSID + " = " + "'" + target + "'");
- stringBuilder.append(" AND " + RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.OBJECT_CSID + " = " + "'" + subjectOrObject + "'" + ")");
- stringBuilder.append(")");
- } else if (subjectOrObject != null) {
- // Used for GET requests like: cspace-services/relations?sbjOrObj=cf5db000-4e65-42d5-8117
- //
- // (subectCsid = ${csid} OR objectCsid = ${csid}) overrides the individual subject or object query params
- // (Example, (rel.subjectcsid = subjectOrObject OR rel.objectcsid = subjectOrObject)
- //
- stringBuilder.append("(" + RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.SUBJECT_CSID + " = " + "'" + subjectOrObject + "'");
- stringBuilder.append(" OR ");
+ if (subject != null) {
stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.OBJECT_CSID + " = " + "'" + subjectOrObject + "')");
- } else {
- // Used for GET requests like: cspace-services/relations?sbj=cf5db000-4e65-42d5-8117
- // and cspace-services/relations?obj=cf5db000-4e65-42d5-8117
- //
- if (subject != null) {
- if (stringBuilder.length() > 0) {
- stringBuilder.append(IQueryManager.SEARCH_QUALIFIER_AND);
- }
-
- stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.SUBJECT_CSID + " = " + "'" + subject + "'");
- }
-
- if (object != null) {
- if (stringBuilder.length() > 0) {
- stringBuilder.append(IQueryManager.SEARCH_QUALIFIER_AND);
- }
- stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
- RelationJAXBSchema.OBJECT_CSID + " = " + "'" + object + "'");
- }
+ RelationJAXBSchema.SUBJECT_CSID + " = " + "'" + subject + "'");
}
- //
- // Check for the other possible query params
- //
if (subjectType != null) {
if (stringBuilder.length() > 0) {
stringBuilder.append(IQueryManager.SEARCH_QUALIFIER_AND);
}
+ // BUG - this should use the new field RelationJAXBSchema.SUBJECT_DOCTYPE
stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
RelationJAXBSchema.SUBJECT_DOCTYPE + " = " + "'" + subjectType + "'");
}
stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
RelationJAXBSchema.RELATIONSHIP_TYPE + " = " + "'" + predicate + "'");
}
-
+
+ if (object != null) {
+ if (stringBuilder.length() > 0) {
+ stringBuilder.append(IQueryManager.SEARCH_QUALIFIER_AND);
+ }
+ stringBuilder.append(RelationConstants.NUXEO_SCHEMA_NAME + ":" +
+ RelationJAXBSchema.OBJECT_CSID + " = " + "'" + object + "'");
+ }
+
if (objectType != null) {
if (stringBuilder.length() > 0) {
stringBuilder.append(IQueryManager.SEARCH_QUALIFIER_AND);
return result;
}
+
+ public static String buildWhereClause(String subject, String subjectType,
+ String predicate,
+ String object, String objectType, boolean viceVersa) {
+ String result = null;
+
+ result = buildWhereClause(
+ subject, subjectType,
+ predicate,
+ object, objectType);
+
+ if (viceVersa == true) {
+ String secondClause = buildWhereClause(
+ object, objectType,
+ predicate,
+ subject, subjectType);
+ result = String.format("(%s) OR (%s)", result, secondClause);
+ }
+
+ return result;
+ }
+
}
AbstractServiceContextImpl ctx = (AbstractServiceContextImpl) getServiceContext();
MultivaluedMap<String, String> queryParams = getServiceContext().getQueryParams();
String markRtSbj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT);
- if (markRtSbj != null && markRtSbj.isEmpty()) {
+ if (Tools.isBlank(markRtSbj)) {
markRtSbj = null;
}
+ //
+ // We may be being asked to mark the record as related independent of whether it is the subject or object of a relationship.
+ //
String markRtSbjOrObj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_EITHER);
- if (markRtSbjOrObj != null && markRtSbjOrObj.isEmpty()) {
+ if (Tools.isBlank(markRtSbjOrObj)) {
markRtSbjOrObj = null;
+ } else {
+ if (Tools.isBlank(markRtSbj) == false) {
+ logger.warn(String.format("Ignoring query param %s=%s since overriding query param %s=%s exists.",
+ IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT, markRtSbj, IQueryManager.MARK_RELATED_TO_CSID_AS_EITHER, markRtSbjOrObj));
+ }
+ markRtSbj = markRtSbjOrObj; // Mark the record as related independent of whether it is the subject or object of a relationship
}
try {
- if (markRtSbj != null || markRtSbjOrObj != null) {
+ if (markRtSbj != null) {
repoClient = (RepositoryClientImpl) this.getRepositoryClient(ctx);
RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient;
repoSession = this.getRepositorySession();
List<ListResultField> resultsFields = getListItemsArray(); // Get additional list result fields defined in the service bindings
int baseFields = NUM_STANDARD_LIST_RESULT_FIELDS;
int nFields = resultsFields.size() + NUM_STANDARD_LIST_RESULT_FIELDS;
- if (markRtSbj != null || markRtSbjOrObj != null) {
+ if (markRtSbj != null) {
nFields++;
baseFields++;
}
fields[3] = STANDARD_LIST_UPDATED_AT_FIELD;
fields[4] = STANDARD_LIST_WORKFLOW_FIELD;
- if (markRtSbj != null || markRtSbjOrObj != null) {
+ if (markRtSbj != null) {
fields[5] = STANDARD_LIST_MARK_RT_FIELD;
}
// If the mark-related query param was set, check to see if the doc we're processing
// is related to the value specified in the mark-related query param.
//
- if (markRtSbj != null || markRtSbjOrObj != null) {
- String relationClause = RelationsUtils.buildWhereClause(markRtSbj, null, null, id, null, markRtSbjOrObj);
+ if (markRtSbj != null) {
+ String relationClause = RelationsUtils.buildWhereClause(markRtSbj, null, null, id, null, markRtSbj == markRtSbjOrObj);
String whereClause = relationClause + IQueryManager.SEARCH_QUALIFIER_AND
+ NuxeoUtils.buildWorkflowNotDeletedWhereClause();
QueryContext queryContext = new QueryContext(ctx, whereClause);
import org.collectionspace.services.common.api.RefName;
import org.collectionspace.services.common.api.RefNameUtils;
import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
+import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
import org.collectionspace.services.common.context.AbstractServiceContextImpl;
import org.collectionspace.services.common.context.ServiceBindingUtils;
MultivaluedMap<String, String> queryParams = getServiceContext().getQueryParams();
String markRtSbj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT);
- if (markRtSbj != null && markRtSbj.isEmpty()) {
+ if (Tools.isBlank(markRtSbj)) {
markRtSbj = null;
}
String markRtSbjOrObj = queryParams.getFirst(IQueryManager.MARK_RELATED_TO_CSID_AS_EITHER);
- if (markRtSbjOrObj != null && markRtSbjOrObj.isEmpty()) {
+ if (Tools.isBlank(markRtSbjOrObj)) {
markRtSbjOrObj = null;
+ } else {
+ if (Tools.isBlank(markRtSbj) == false) {
+ logger.warn(String.format("Ignoring query param %s='%s' since overriding query param %s='%s' exists.",
+ IQueryManager.MARK_RELATED_TO_CSID_AS_SUBJECT, markRtSbj, IQueryManager.MARK_RELATED_TO_CSID_AS_EITHER, markRtSbjOrObj));
+ }
+ markRtSbj = markRtSbjOrObj; // Mark the record as related independent of whether it is the subject or object of a relationship
}
try {
- if (markRtSbj != null || markRtSbjOrObj != null) {
+ if (markRtSbj != null) {
repoClient = (RepositoryClientImpl) this.getRepositoryClient(ctx);
RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient;
repoSession = this.getRepositorySession();
fields[5] = DOC_NAME_FIELD;
fields[6] = DOC_NUMBER_FIELD;
fields[7] = DOC_TYPE_FIELD;
- if (markRtSbj != null || markRtSbjOrObj != null) {
+ if (markRtSbj != null) {
fields[8] = STANDARD_LIST_MARK_RT_FIELD;
}
// If the mark-related query param was set, check to see if the doc we're processing
// is related to the value specified in the mark-related query param.
//
- if (markRtSbj != null || markRtSbjOrObj != null) {
- String relationClause = RelationsUtils.buildWhereClause(markRtSbj, null, null, csid, null, markRtSbjOrObj);
+ if (markRtSbj != null) {
+ String relationClause = RelationsUtils.buildWhereClause(markRtSbj, null, null, csid, null, markRtSbj == markRtSbjOrObj);
String whereClause = relationClause + IQueryManager.SEARCH_QUALIFIER_AND
+ NuxeoUtils.buildWorkflowNotDeletedWhereClause();
QueryContext queryContext = new QueryContext(ctx, whereClause);