package com.constellio.app.api.cmis.requests.navigation; import com.constellio.app.api.cmis.binding.collection.ConstellioCollectionRepository; 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.Content; 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.MetadataValueType; import com.constellio.model.services.search.StatusFilter; import com.constellio.model.services.taxonomies.TaxonomiesSearchOptions; import com.constellio.model.services.taxonomies.TaxonomiesSearchServices; import com.constellio.model.services.taxonomies.TaxonomySearchRecord; import org.apache.chemistry.opencmis.commons.data.ObjectData; import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList; import org.apache.chemistry.opencmis.commons.enums.Action; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderDataImpl; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl; 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 java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.Set; public class GetChildrenRequest extends CmisCollectionRequest<ObjectInFolderList> { private static final Logger LOGGER = LoggerFactory.getLogger(CmisCollectionRequest.class); private final String folderId; private final Set<String> filter; private final boolean includeAllowableActions; private final boolean includePathSegment; private final BigInteger maxItems; private final BigInteger skipCount; private final ObjectInfoHandler objectInfo; public GetChildrenRequest(ConstellioCollectionRepository repository, AppLayerFactory appLayerFactory, CallContext context, String folderId, String filter, Boolean includeAllowableActions, Boolean includePathSegment, BigInteger maxItems, BigInteger skipCount, ObjectInfoHandler objectInfo) { super(context, repository, appLayerFactory); this.folderId = folderId; if (filter != null) { this.filter = CmisUtils.splitFilter(filter); } else { this.filter = null; } this.includeAllowableActions = includeAllowableActions; this.includePathSegment = includePathSegment; this.maxItems = maxItems; this.skipCount = skipCount; this.objectInfo = objectInfo; } @Override public ObjectInFolderList process() { ObjectInFolderList children = new ObjectInFolderListImpl(); TaxonomiesSearchServices searchServices = modelLayerFactory.newTaxonomiesSearchService(); TaxonomiesSearchOptions options = new TaxonomiesSearchOptions(maxItems.intValue(), skipCount.intValue(), StatusFilter.ACTIVES).setAlwaysReturnTaxonomyConceptsWithReadAccess(true); List<Record> childRecords; if (collection.equals(folderId)) { List<Taxonomy> taxonomies = taxonomiesManager.getEnabledTaxonomies(collection); for (Taxonomy taxonomy : taxonomies) { ObjectData object = newTaxonomyObjectBuilder().build(taxonomy, objectInfo); children.getObjects().add(new ObjectInFolderDataImpl(object)); } } else if (folderId.startsWith("taxo_")) { String taxonomyCode = folderId.substring(5); childRecords = new ArrayList<>(); for (TaxonomySearchRecord record : searchServices.getVisibleRootConcept(user, collection, taxonomyCode, options)) { if (repository.getTypeDefinitionsManager().hasTypeDefinition(record.getRecord().getSchemaCode())) { childRecords.add(record.getRecord()); } } addFoldersToChildren(children, childRecords); } else { Record record = recordServices.getDocumentById(folderId); ensureUserHasAllowableActionsOnRecord(record, Action.CAN_GET_CHILDREN); childRecords = new ArrayList<>(); for (TaxonomySearchRecord child : searchServices.getVisibleChildConcept(user, record, options)) { if (repository.getTypeDefinitionsManager().hasTypeDefinition(child.getRecord().getSchemaCode())) { childRecords.add(child.getRecord()); } } addFoldersToChildren(children, childRecords); addDocumentsToChildren(children, record); } return children; } private void addFoldersToChildren(ObjectInFolderList children, List<Record> childRecords) { for (Record childRecord : childRecords) { ObjectData object = newObjectDataBuilder().build(childRecord, filter, includeAllowableActions, false, objectInfo); children.getObjects().add(new ObjectInFolderDataImpl(object)); } } private void addDocumentsToChildren(ObjectInFolderList children, Record record) { MetadataSchema schema = types().getSchema(record.getSchemaCode()); for (Metadata metadata : schema.getMetadatas().onlyWithType(MetadataValueType.CONTENT)) { addDocumentsForMetadata(children, record, metadata); } } private void addDocumentsForMetadata(ObjectInFolderList children, Record record, Metadata metadata) { if (record.get(metadata) != null) { if (metadata.isMultivalue() == true) { List<Content> contents = record.getList(metadata); for (Content content : contents) { addDocumentToChildren(children, record, metadata, content); } } else { Content content = record.get(metadata); addDocumentToChildren(children, record, metadata, content); } } } private void addDocumentToChildren(ObjectInFolderList children, Record record, Metadata metadata, Content content) { ContentCmisDocument contentDocument = ContentCmisDocument .createForVersionSeenBy(content, record, metadata.getLocalCode(), user); ObjectData contentObject = newContentObjectDataBuilder() .build(contentDocument, filter, includeAllowableActions, false, objectInfo); children.getObjects().add(new ObjectInFolderDataImpl(contentObject)); } @Override protected Logger getLogger() { return LOGGER; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } }