package com.constellio.app.api.cmis.requests.navigation; import static java.util.Arrays.asList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import org.apache.chemistry.opencmis.commons.data.ObjectData; import org.apache.chemistry.opencmis.commons.data.ObjectParentData; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectParentDataImpl; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.server.ObjectInfoHandler; import org.apache.commons.lang3.builder.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.app.api.cmis.ConstellioCmisException; import com.constellio.app.api.cmis.binding.collection.ConstellioCollectionRepository; import com.constellio.app.api.cmis.binding.utils.CmisContentUtils; import com.constellio.app.api.cmis.binding.utils.CmisUtils; import com.constellio.app.api.cmis.binding.utils.ContentCmisDocument; import com.constellio.app.api.cmis.requests.CmisCollectionRequest; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.model.entities.Taxonomy; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchema; import com.constellio.model.entities.schemas.MetadataSchemaTypes; public class GetObjectParentsRequest extends CmisCollectionRequest<List<ObjectParentData>> { private static final Logger LOGGER = LoggerFactory.getLogger(CmisCollectionRequest.class); private final Set<String> filter; private final String objectId; private final Boolean includeAllowableActions; private final Boolean includeRelativePathSegment; private final ObjectInfoHandler objectInfo; public GetObjectParentsRequest(ConstellioCollectionRepository repository, AppLayerFactory appLayerFactory, CallContext context, String objectId, String filter, Boolean includeAllowableActions, Boolean includeRelativePathSegment, ObjectInfoHandler objectInfo) { super(context, repository, appLayerFactory); if (filter != null) { this.filter = CmisUtils.splitFilter(filter); } else { this.filter = null; } this.objectId = objectId; this.includeAllowableActions = includeAllowableActions; this.includeRelativePathSegment = includeRelativePathSegment; this.objectInfo = objectInfo; } @Override protected List<ObjectParentData> process() throws ConstellioCmisException { ObjectParentData parent; if (objectId.startsWith("content_")) { parent = new ObjectParentDataImpl(buildContentObjectData()); } else if (objectId.startsWith("taxo_")) { Record record = appLayerFactory.getCollectionsManager().getCollection(collection).getWrappedRecord(); parent = new ObjectParentDataImpl(newObjectDataBuilder().build(record, filter, false, false, objectInfo)); } else { Record record = recordServices.getDocumentById(objectId); List<ObjectParentData> parentDatas = new ArrayList<>(); for (ObjectData objectData : buildRecordObjectData(record)) { parentDatas.add(new ObjectParentDataImpl(objectData)); } return parentDatas; } return Collections.<ObjectParentData>singletonList(parent); } private ObjectData buildContentObjectData() { ContentCmisDocument content = CmisContentUtils.getContent(objectId, recordServices, types()); return newObjectDataBuilder().build(content.getRecord(), filter, false, false, objectInfo); } private List<ObjectData> buildRecordObjectData(Record record) { Taxonomy taxonomyOfRecord = taxonomiesManager.getTaxonomyOf(record); Taxonomy principalTaxonomy = taxonomiesManager.getPrincipalTaxonomy(collection); MetadataSchema schema = types().getSchema(record.getSchemaCode()); List<Metadata> parentReferencesMetadatas = schema.getParentReferences(); List<Metadata> referencesMetadatas = schema.getTaxonomyRelationshipReferences(asList(principalTaxonomy)); List<Metadata> allReferencesMetadatas = new ArrayList<>(); allReferencesMetadatas.addAll(parentReferencesMetadatas); allReferencesMetadatas.addAll(referencesMetadatas); List<ObjectData> parents = new ArrayList<>(); for (Metadata referenceMetadata : allReferencesMetadatas) { if (record.get(referenceMetadata) != null) { String parentId = record.get(referenceMetadata); Record parentRecord = recordServices.getDocumentById(parentId); parents.add(newObjectDataBuilder().build(parentRecord, filter, false, false, objectInfo)); } } for (Taxonomy taxonomy : taxonomiesManager.getEnabledTaxonomies(record.getCollection())) { if (!taxonomy.hasSameCode(taxonomiesManager.getPrincipalTaxonomy(record.getCollection()))) { List<Metadata> taxonomyReferencesMetadatas = schema.getTaxonomyRelationshipReferences(asList(taxonomy)); for (Metadata referenceMetadata : taxonomyReferencesMetadatas) { if (record.get(referenceMetadata) != null) { String parentId = record.get(referenceMetadata); Record parentRecord = recordServices.getDocumentById(parentId); parents.add(newObjectDataBuilder().build(parentRecord, filter, false, false, objectInfo)); } } } } if (parents.isEmpty() && taxonomyOfRecord != null) { parents.add(newTaxonomyObjectBuilder().build(taxonomyOfRecord, objectInfo)); } return parents; } @Override protected Logger getLogger() { return LOGGER; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } }