package com.constellio.app.api.cmis.builders.object; import static com.constellio.app.api.cmis.utils.CmisRecordUtils.toGregorianCalendar; import static com.constellio.model.services.migrations.ConstellioEIMConfigs.CMIS_NEVER_RETURN_ACL; import static org.apache.chemistry.opencmis.commons.enums.Action.CAN_GET_ACL; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.data.ObjectData; import org.apache.chemistry.opencmis.commons.data.Properties; import org.apache.chemistry.opencmis.commons.enums.Action; import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectDataImpl; import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.server.ObjectInfoHandler; import com.constellio.app.api.cmis.CmisExceptions.CmisExceptions_Runtime; import com.constellio.app.api.cmis.binding.collection.ConstellioCollectionRepository; import com.constellio.app.api.cmis.binding.global.ConstellioCmisContextParameters; import com.constellio.app.extensions.AppLayerCollectionExtensions; import com.constellio.app.extensions.api.cmis.params.BuildCmisObjectFromConstellioRecordParams; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchemaType; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.records.SchemasRecordsServices; import com.constellio.model.services.schemas.SchemaUtils; public class ObjectDataBuilder { private static final String USER_UNKNOWN = "<unknown>"; private final ConstellioCollectionRepository repository; private final AppLayerFactory appLayerFactory; private final ModelLayerFactory modelLayerFactory; private final SchemasRecordsServices schemas; private final CallContext context; private final String taxonomyPath = null; private final AllowableActionsBuilder allowableActionsBuilder; private final User user; public ObjectDataBuilder(ConstellioCollectionRepository repository, AppLayerFactory appLayerFactory, CallContext context) { this.repository = repository; this.appLayerFactory = appLayerFactory; this.modelLayerFactory = appLayerFactory.getModelLayerFactory(); this.context = context; this.schemas = new SchemasRecordsServices(repository.getCollection(), modelLayerFactory); this.allowableActionsBuilder = new AllowableActionsBuilder(repository, appLayerFactory, context); this.user = (User) context.get(ConstellioCmisContextParameters.USER); } public ObjectData build(Record record, Set<String> filter, boolean includeAllowableActions, boolean includeAcl, ObjectInfoHandler objectInfos) { ObjectDataImpl result = new ObjectDataImpl(); ObjectInfoImpl objectInfo = new ObjectInfoImpl(); String typeId = record.getSchemaCode(); Set<String> filterSet = (filter == null ? null : new HashSet<String>(filter)); PropertiesBuilder propertiesBuilder = new PropertiesBuilder(repository, typeId, filterSet); if (result != null) { result.setProperties(compileProperties(record, objectInfo, propertiesBuilder, typeId)); } if (includeAllowableActions) { result.setAllowableActions(allowableActionsBuilder.build(record)); } callExtensions(result, propertiesBuilder, record); boolean neverReturlACL = modelLayerFactory.getSystemConfigurationsManager().getValue(CMIS_NEVER_RETURN_ACL); if (includeAcl && !neverReturlACL && allowableActionsBuilder.build(record).getAllowableActions().contains(CAN_GET_ACL)) { result.setAcl(new AclBuilder(repository, modelLayerFactory).build(record)); result.setIsExactAcl(true); } if (context.isObjectInfoRequired()) { objectInfo.setObject(result); objectInfos.addObjectInfo(objectInfo); } return result; } private void callExtensions(ObjectDataImpl result, PropertiesBuilder propertiesBuilder, Record record) { AppLayerCollectionExtensions extensions = appLayerFactory.getExtensions().forCollectionOf(record); extensions.buildCMISObjectFromConstellioRecord( new BuildCmisObjectFromConstellioRecordParams(result, propertiesBuilder, record)); } private Properties compileProperties(Record record, ObjectInfoImpl objectInfo, PropertiesBuilder propertiesBuilder, String typeId) { if (record == null) { throw new IllegalArgumentException("Record must not be null!"); } boolean readAccess = user.hasReadAccess().on(record); setupObjectInfo(objectInfo, typeId); try { String id = record.getId(); propertiesBuilder.addPropertyId(PropertyIds.OBJECT_ID, id); objectInfo.setId(id); String name = record.get(Schemas.TITLE); if (name == null && record.getSchemaCode().startsWith("collection_")) { name = schemas.wrapCollection(record).getName(); } propertiesBuilder.addPropertyString(PropertyIds.NAME, name); objectInfo.setName(name); propertiesBuilder.addPropertyString(PropertyIds.CREATED_BY, (String) record.get(Schemas.CREATED_BY)); propertiesBuilder.addPropertyString(PropertyIds.LAST_MODIFIED_BY, (String) record.get(Schemas.MODIFIED_BY)); objectInfo.setCreatedBy(USER_UNKNOWN); GregorianCalendar creationDate = toGregorianCalendar(record.get(Schemas.CREATED_ON)); GregorianCalendar lastModified = toGregorianCalendar(record.get(Schemas.MODIFIED_ON)); propertiesBuilder.addPropertyDateTime(PropertyIds.CREATION_DATE, creationDate); propertiesBuilder.addPropertyDateTime(PropertyIds.LAST_MODIFICATION_DATE, lastModified); objectInfo.setCreationDate(creationDate); objectInfo.setLastModificationDate(lastModified); propertiesBuilder.addPropertyString(PropertyIds.CHANGE_TOKEN, Long.toString(record.getVersion())); propertiesBuilder.addPropertyId(PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_FOLDER.value()); propertiesBuilder.addPropertyId(PropertyIds.OBJECT_TYPE_ID, typeId); // The principal path is always used for now String path = record.get(Schemas.PRINCIPAL_PATH); List<String> paths = record.getList(Schemas.PATH); if (path == null && !paths.isEmpty()) { path = paths.get(0); } if (path != null) { if ("collection_default" .equals(typeId)) { propertiesBuilder.addPropertyString(PropertyIds.PATH, "/"); } else { path = "/taxo_" + path.substring(1); propertiesBuilder.addPropertyString(PropertyIds.PATH, path); } } if (record.getParentId() != null) { propertiesBuilder.addPropertyString(PropertyIds.PARENT_ID, record.getParentId()); } else if (path != null) { // The principal path is used here, also. propertiesBuilder.addPropertyString(PropertyIds.PARENT_ID, path.split("/")[path.split("/").length - 2]); } if (readAccess) { addPropertiesForMetadatas(record, propertiesBuilder); } propertiesBuilder.addPropertyIdList(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, null); return propertiesBuilder.getBuiltProperties(); } catch (CmisBaseException cbe) { throw cbe; } catch (Exception e) { throw new CmisExceptions_Runtime(e.getMessage(), e); } } private void addPropertiesForMetadatas(Record record, PropertiesBuilder propertiesBuilder) { SchemaUtils schemaUtils = new SchemaUtils(); for (Metadata metadata : modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(record.getCollection()) .getSchema(record.getSchemaCode()).getMetadatas()) { Object value = record.get(metadata); String propertyCode = schemaUtils.getLocalCodeFromMetadataCode(metadata.getCode()); if (value != null) { if (!metadata.isMultivalue()) { propertiesBuilder.addPropertyForSingleValueMetadata(metadata, value, propertyCode); } else { propertiesBuilder.addPropertyForMultiValueMetadata(metadata, value, propertyCode); } } } } private void setupObjectInfo(ObjectInfoImpl objectInfo, String typeId) { MetadataSchemaType type = modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(repository.getCollection()) .getSchemaType(new SchemaUtils().getSchemaTypeCode(typeId)); objectInfo.setBaseType(BaseTypeId.CMIS_FOLDER); objectInfo.setTypeId(typeId); objectInfo.setContentType(null); objectInfo.setFileName(null); objectInfo.setHasAcl(type.hasSecurity()); objectInfo.setHasContent(false); objectInfo.setVersionSeriesId(null); objectInfo.setIsCurrentVersion(true); objectInfo.setRelationshipSourceIds(null); objectInfo.setRelationshipTargetIds(null); objectInfo.setRenditionInfos(null); objectInfo.setSupportsDescendants(true); objectInfo.setSupportsFolderTree(true); objectInfo.setSupportsPolicies(false); objectInfo.setSupportsRelationships(false); objectInfo.setWorkingCopyId(null); objectInfo.setWorkingCopyOriginalId(null); } }