package com.constellio.model.entities.schemas; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import com.constellio.model.entities.Language; import com.constellio.model.entities.Taxonomy; import com.constellio.model.entities.schemas.preparationSteps.RecordPreparationStep; import com.constellio.model.entities.schemas.validation.RecordValidator; import com.constellio.model.services.schemas.MetadataList; import com.constellio.model.services.schemas.SchemaUtils; public class MetadataSchema { private static final String UNDERSCORE = "_"; private final String localCode; private final String code; private final String collection; private Map<Language, String> labels; private final MetadataList metadatas; private final Boolean undeletable; private final boolean inTransactionLog; private final Set<RecordValidator> schemaValidators; private final Map<String, Metadata> indexByLocalCode; private final Map<String, Metadata> indexByCode; private MetadataSchemaCalculatedInfos calculatedInfos; public MetadataSchema(String localCode, String code, String collection, Map<Language, String> labels, List<Metadata> metadatas, Boolean undeletable, boolean inTransactionLog, Set<RecordValidator> schemaValidators, MetadataSchemaCalculatedInfos calculatedInfos) { super(); this.localCode = localCode; this.code = code; this.collection = collection; this.labels = new HashMap<>(labels); this.inTransactionLog = inTransactionLog; this.metadatas = new MetadataList(metadatas).unModifiable(); this.undeletable = undeletable; this.schemaValidators = schemaValidators; this.calculatedInfos = calculatedInfos; this.indexByLocalCode = Collections.unmodifiableMap(new SchemaUtils().buildIndexByLocalCode(metadatas)); this.indexByCode = Collections.unmodifiableMap(new SchemaUtils().buildIndexByCode(metadatas)); } public String getLocalCode() { return localCode; } public String getCode() { return code; } public String getCollection() { return collection; } public Map<Language, String> getLabels() { return labels; } public String getFrenchLabel() { return labels.get(Language.French); } public String getLabel(Language language) { return labels.get(language); } public MetadataList getMetadatas() { return metadatas; } public Set<RecordValidator> getValidators() { return schemaValidators; } public Boolean isUndeletable() { return undeletable; } public boolean hasMetadataWithCode(String metadataCode) { try { String localCode = new SchemaUtils().getLocalCode(metadataCode, code); return indexByLocalCode.get(localCode) != null; } catch (MetadataSchemasRuntimeException.CannotGetMetadatasOfAnotherSchemaType e) { return false; } } public Metadata get(String metadataCode) { return getMetadata(metadataCode); } public Metadata getMetadata(String metadataCode) { if (metadataCode.endsWith("PId")) { metadataCode = metadataCode.substring(0, metadataCode.length() - 3); } if (metadataCode.endsWith("Id")) { metadataCode = metadataCode.substring(0, metadataCode.length() - 2); } Metadata metadata = indexByLocalCode.get(metadataCode); if (metadata == null) { metadata = indexByCode.get(metadataCode); } if (metadata == null) { throw new MetadataSchemasRuntimeException.NoSuchMetadata(metadataCode); } else { return metadata; } } public List<Metadata> getAutomaticMetadatas() { return calculatedInfos.getAutomaticMetadatas(); } public List<Metadata> getEagerTransientMetadatas() { return calculatedInfos.getEagerTransientMetadatas(); } public List<Metadata> getLazyTransientMetadatas() { return calculatedInfos.getLazyTransientMetadatas(); } public List<Metadata> getTaxonomyRelationshipReferences(List<Taxonomy> taxonomies) { List<Metadata> returnedMetadata = new ArrayList<>(); for (Taxonomy taxonomy : taxonomies) { returnedMetadata.addAll(getTaxonomyRelationshipReferences(taxonomy)); } return returnedMetadata; } public List<Metadata> getTaxonomyRelationshipReferences(Taxonomy taxonomy) { List<Metadata> returnedMetadata = new ArrayList<>(); String schemaTypeCode = new SchemaUtils().getSchemaTypeCode(code); if (!taxonomy.getSchemaTypes().contains(schemaTypeCode)) { for (Metadata metadata : metadatas) { if (metadata.isTaxonomyRelationship() && metadata.getType() == MetadataValueType.REFERENCE) { String referencedType = metadata.getAllowedReferences().getTypeWithAllowedSchemas(); if (taxonomy.getSchemaTypes().contains(referencedType) && metadata.isTaxonomyRelationship()) { returnedMetadata.add(metadata); } } } } return returnedMetadata; } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this, "schemaValidators", "calculatedInfos"); } @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj, "schemaValidators", "calculatedInfos"); } @Override public String toString() { return localCode; } public List<Metadata> getParentReferences() { return metadatas.onlyParentReferences(); } public List<Metadata> getNonParentReferences() { return metadatas.onlyNonParentReferences(); } public Map<String, Metadata> getIndexByLocalCode() { return indexByLocalCode; } public boolean isInTransactionLog() { return inTransactionLog; } public List<RecordPreparationStep> getPreparationSteps() { return calculatedInfos.getRecordPreparationSteps(); } public List<Metadata> getContentMetadatasForPopulate() { return calculatedInfos.getContentMetadatasForPopulate(); } }