package com.constellio.model.services.schemas.xml;
import static com.constellio.model.utils.EnumWithSmallCodeUtils.toEnum;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import com.constellio.data.dao.services.DataStoreTypesFactory;
import com.constellio.data.utils.ImpossibleRuntimeException;
import com.constellio.model.entities.Language;
import com.constellio.model.entities.calculators.MetadataValueCalculator;
import com.constellio.model.entities.records.wrappers.Collection;
import com.constellio.model.entities.schemas.MetadataSchemaType;
import com.constellio.model.entities.schemas.MetadataTransiency;
import com.constellio.model.entities.schemas.MetadataValueType;
import com.constellio.model.entities.schemas.RegexConfig;
import com.constellio.model.entities.schemas.RegexConfig.RegexConfigType;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.entities.schemas.StructureFactory;
import com.constellio.model.entities.schemas.entries.AggregatedDataEntry;
import com.constellio.model.entities.schemas.entries.AggregationType;
import com.constellio.model.entities.schemas.entries.CopiedDataEntry;
import com.constellio.model.entities.schemas.validation.RecordMetadataValidator;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.model.services.records.extractions.DefaultMetadataPopulatorPersistenceManager;
import com.constellio.model.services.records.extractions.MetadataPopulator;
import com.constellio.model.services.records.extractions.MetadataPopulatorPersistenceManager;
import com.constellio.model.services.schemas.MetadataSchemasManagerRuntimeException;
import com.constellio.model.services.schemas.builders.MetadataAccessRestrictionBuilder;
import com.constellio.model.services.schemas.builders.MetadataBuilder;
import com.constellio.model.services.schemas.builders.MetadataPopulateConfigsBuilder;
import com.constellio.model.services.schemas.builders.MetadataSchemaBuilder;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypeBuilder;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder;
import com.constellio.model.utils.ClassProvider;
import com.constellio.model.utils.EnumWithSmallCodeUtils;
import com.constellio.model.utils.InstanciationUtils;
import com.constellio.model.utils.Parametrized;
import com.constellio.model.utils.ParametrizedInstanceUtils;
public class MetadataSchemaXMLReader3 {
private static Map<String, Class<? extends RecordMetadataValidator<?>>> validatorsCache = new HashMap<>();
public static final String FORMAT_VERSION = "3";
ClassProvider classProvider;
private final MetadataPopulatorPersistenceManager metadataPopulatorXMLSerializer = new DefaultMetadataPopulatorPersistenceManager();
public MetadataSchemaXMLReader3(ClassProvider classProvider) {
this.classProvider = classProvider;
}
public MetadataSchemaTypesBuilder read(String collection, Document document, DataStoreTypesFactory typesFactory,
ModelLayerFactory modelLayerFactory) {
Element rootElement = document.getRootElement();
int version = Integer.valueOf(rootElement.getAttributeValue("version")) - 1;
List<Language> languages = getLanguages(rootElement);
MetadataSchemaTypesBuilder typesBuilder = MetadataSchemaTypesBuilder
.createWithVersion(collection, version, classProvider, languages);
for (Element schemaTypeElement : rootElement.getChildren("type")) {
parseProfilType(typesBuilder, schemaTypeElement, typesFactory, modelLayerFactory);
}
return typesBuilder;
}
private List<Language> getLanguages(Element rootElement) {
List<Language> languages = new ArrayList<>();
List<String> languagesCodes = Arrays.asList(rootElement.getAttributeValue("languages").split(","));
for (String code : languagesCodes) {
languages.add(Language.withCode(code));
}
return languages;
}
private MetadataSchemaType parseProfilType(MetadataSchemaTypesBuilder typesBuilder, Element element,
DataStoreTypesFactory typesFactory, ModelLayerFactory modelLayerFactory) {
String code = getCodeValue(element);
Map<Language, String> labels = readLabels(element);
MetadataSchemaTypeBuilder schemaTypeBuilder = typesBuilder.createNewSchemaType(code, false)
.setLabels(labels);
MetadataSchemaBuilder collectionSchema = "collection".equals(code) ?
null : typesBuilder.getSchema(Collection.DEFAULT_SCHEMA);
schemaTypeBuilder.setReadOnlyLocked(getBooleanFlagValueWithFalseAsDefaultValue(element, "readOnlyLocked"));
schemaTypeBuilder.setSecurity(getBooleanFlagValueWithFalseAsDefaultValue(element, "security"));
schemaTypeBuilder.setInTransactionLog(getBooleanFlagValueWithTrueAsDefaultValue(element, "inTransactionLog"));
parseDefaultSchema(element, schemaTypeBuilder, typesBuilder, collectionSchema);
parseCustomSchemas(element, schemaTypeBuilder, collectionSchema);
return schemaTypeBuilder.build(typesFactory, modelLayerFactory);
}
private void parseCustomSchemas(Element root, MetadataSchemaTypeBuilder schemaTypeBuilder,
MetadataSchemaBuilder collectionSchema) {
Element customSchemasElement = root.getChild("customSchemas");
for (Element schemaElement : customSchemasElement.getChildren("schema")) {
parseSchema(schemaTypeBuilder, schemaElement, collectionSchema);
}
}
private void parseSchema(MetadataSchemaTypeBuilder schemaTypeBuilder, Element schemaElement,
MetadataSchemaBuilder collectionSchema) {
MetadataSchemaBuilder schemaBuilder = schemaTypeBuilder.createCustomSchema(getCodeValue(schemaElement));
schemaBuilder.setLabels(readLabels(schemaElement));
schemaBuilder.setUndeletable(getBooleanFlagValueWithTrueAsDefaultValue(schemaElement, "undeletable"));
for (Element metadataElement : schemaElement.getChildren("m")) {
parseMetadata(schemaBuilder, metadataElement, collectionSchema);
}
List<String> validatorsClassNames = parseValidators(schemaElement, null);
for (String validatorsClassName : validatorsClassNames) {
schemaBuilder.defineValidators().add(getValidatorClass(validatorsClassName));
}
}
private void parseMetadata(MetadataSchemaBuilder schemaBuilder, Element metadataElement,
MetadataSchemaBuilder collectionSchema) {
String codeValue = getCodeValue(metadataElement);
MetadataBuilder metadataBuilder;
if (schemaBuilder.hasMetadata(codeValue)) {
metadataBuilder = schemaBuilder.get(codeValue);
} else {
metadataBuilder = schemaBuilder.create(codeValue);
}
metadataBuilder.setLabels(readLabels(metadataElement));
if (metadataBuilder.getInheritance() != null && !metadataBuilder.getCode().contains("_default_")) {
parseMetadataWithInheritance(metadataElement, metadataBuilder);
} else {
parseMetadataWithoutInheritance(metadataElement, metadataBuilder, collectionSchema);
}
}
private void parseMetadataWithInheritance(Element metadataElement, MetadataBuilder metadataBuilder) {
String enabledStringValue = metadataElement.getAttributeValue("enabled");
String defaultRequirementStringValue = metadataElement.getAttributeValue("defaultRequirement");
String inputMask = metadataElement.getAttributeValue("inputMask");
String duplicableStringValue = metadataElement.getAttributeValue("duplicable");
List<String> validatorsClassNames = parseValidators(metadataElement, null);
for (String validatorsClassName : validatorsClassNames) {
metadataBuilder.defineValidators().add(getValidatorClass(validatorsClassName));
}
if (enabledStringValue != null) {
metadataBuilder.setEnabled(readBoolean(enabledStringValue));
}
if (defaultRequirementStringValue != null) {
metadataBuilder.setDefaultRequirement(readBoolean(defaultRequirementStringValue));
}
if (inputMask != null) {
metadataBuilder.setInputMask(inputMask);
}
if (metadataElement.getChild("defaultValue") != null) {
ParametrizedInstanceUtils utils = new ParametrizedInstanceUtils();
Object defaultValue = utils.toObject(metadataElement.getChild("defaultValue"));
metadataBuilder.setDefaultValue(defaultValue);
}
if (duplicableStringValue != null) {
metadataBuilder.setDuplicable(readBoolean(duplicableStringValue));
}
setPopulateConfigs(metadataBuilder, metadataElement);
}
private void parseMetadataWithoutInheritance(Element metadataElement, MetadataBuilder metadataBuilder,
MetadataSchemaBuilder collectionSchema) {
if (!metadataBuilder.isSystemReserved()) {
String enabledStringValue = metadataElement.getAttributeValue("enabled");
String defaultRequirementStringValue = metadataElement.getAttributeValue("defaultRequirement");
String duplicableStringValue = metadataElement.getAttributeValue("duplicable");
if (enabledStringValue == null) {
metadataBuilder.setEnabled(true);
} else {
metadataBuilder.setEnabled(readBoolean(enabledStringValue));
}
if (defaultRequirementStringValue == null) {
metadataBuilder.setDefaultRequirement(false);
} else {
metadataBuilder.setDefaultRequirement(readBoolean(defaultRequirementStringValue));
}
if (duplicableStringValue == null) {
metadataBuilder.setDuplicable(false);
} else {
metadataBuilder.setDuplicable(readBoolean(duplicableStringValue));
}
}
MetadataBuilder globalMetadataInCollectionSchema = null;
boolean inheriteGlobalMetadata = false;
if (Schemas.isGlobalMetadata(metadataBuilder.getLocalCode()) && collectionSchema != null
&& collectionSchema.hasMetadata(metadataBuilder.getLocalCode())) {
globalMetadataInCollectionSchema = collectionSchema.getMetadata(metadataBuilder.getLocalCode());
inheriteGlobalMetadata = true;
}
Map<Language, String> xmlLabels = readLabels(metadataElement);
if (inheriteGlobalMetadata && (xmlLabels == null || xmlLabels.isEmpty())) {
metadataBuilder.setLabels(globalMetadataInCollectionSchema.getLabels());
} else {
metadataBuilder.setLabels(xmlLabels);
}
List<String> validatorsClassNames = parseValidators(metadataElement, globalMetadataInCollectionSchema);
for (String validatorsClassName : validatorsClassNames) {
metadataBuilder.defineValidators().add(getValidatorClass(validatorsClassName));
}
boolean userDefinedMetadata = metadataBuilder.getLocalCode().startsWith("USR");
parseDataEntryElement(metadataBuilder, metadataElement, globalMetadataInCollectionSchema);
//if (!isInheriting(metadataElement)) {
if (metadataBuilder.getType() == null) {
MetadataValueType xmlTypeValue = getTypeValue(metadataElement);
if (xmlTypeValue == null && inheriteGlobalMetadata) {
xmlTypeValue = globalMetadataInCollectionSchema.getType();
}
metadataBuilder.setType(xmlTypeValue);
}
if (inheriteGlobalMetadata) {
metadataBuilder.setUndeletable(true);
} else {
metadataBuilder.setUndeletable(getBooleanFlagValueWithTrueAsDefaultValue(metadataElement, "undeletable"));
}
String systemReservedStringValue = metadataElement.getAttributeValue("systemReserved");
if (inheriteGlobalMetadata && systemReservedStringValue == null) {
metadataBuilder.setSystemReserved(globalMetadataInCollectionSchema.isSystemReserved());
} else {
metadataBuilder.setSystemReserved(!userDefinedMetadata &&
readBooleanWithDefaultValue(systemReservedStringValue, true));
}
String defaultRequirementStringValue = metadataElement.getAttributeValue("defaultRequirement");
if (inheriteGlobalMetadata && defaultRequirementStringValue == null) {
metadataBuilder.setDefaultRequirement(globalMetadataInCollectionSchema.getDefaultRequirement());
} else {
metadataBuilder.setDefaultRequirement(readBooleanWithDefaultValue(defaultRequirementStringValue, false));
}
String essentialStringValue = metadataElement.getAttributeValue("essential");
if (inheriteGlobalMetadata && essentialStringValue == null) {
metadataBuilder.setEssential(globalMetadataInCollectionSchema.isEssential());
} else {
metadataBuilder.setEssential(readBooleanWithDefaultValue(essentialStringValue, false));
}
String customAttributes = metadataElement.getAttributeValue("customAttributes");
if (inheriteGlobalMetadata && customAttributes == null) {
metadataBuilder.setCustomAttributes(globalMetadataInCollectionSchema.getCustomAttributes());
} else {
metadataBuilder.setCustomAttributes(parseCustomAttributes(customAttributes));
}
String essentialInSummaryStringValue = metadataElement.getAttributeValue("essentialInSummary");
if (inheriteGlobalMetadata && essentialInSummaryStringValue == null) {
metadataBuilder.setEssentialInSummary(globalMetadataInCollectionSchema.isEssentialInSummary());
} else {
metadataBuilder.setEssentialInSummary(readBooleanWithDefaultValue(essentialInSummaryStringValue, false));
}
String increasedDependencyLevelStringValue = metadataElement.getAttributeValue("increasedDependencyLevel");
if (inheriteGlobalMetadata && increasedDependencyLevelStringValue == null) {
metadataBuilder.setIncreasedDependencyLevel(globalMetadataInCollectionSchema.isIncreasedDependencyLevel());
} else {
metadataBuilder.setIncreasedDependencyLevel(readBooleanWithDefaultValue(increasedDependencyLevelStringValue, false));
}
String unmodifiableStringValue = metadataElement.getAttributeValue("unmodifiable");
if (inheriteGlobalMetadata && unmodifiableStringValue == null) {
metadataBuilder.setUnmodifiable(globalMetadataInCollectionSchema.isUnmodifiable());
} else {
metadataBuilder.setUnmodifiable(readBooleanWithDefaultValue(unmodifiableStringValue, false));
}
String encryptedStringValue = metadataElement.getAttributeValue("encrypted");
if (inheriteGlobalMetadata && encryptedStringValue == null) {
metadataBuilder.setEncrypted(globalMetadataInCollectionSchema.isEncrypted());
} else {
metadataBuilder.setEncrypted(readBooleanWithDefaultValue(encryptedStringValue, false));
}
String transientStringValue = metadataElement.getAttributeValue("transiency");
if (inheriteGlobalMetadata && transientStringValue == null) {
metadataBuilder.setTransiency(globalMetadataInCollectionSchema.getTransiency());
} else {
metadataBuilder.setTransiency(readEnum(transientStringValue, MetadataTransiency.class));
}
String searchableStringValue = metadataElement.getAttributeValue("searchable");
if (inheriteGlobalMetadata && searchableStringValue == null) {
metadataBuilder.setSearchable(globalMetadataInCollectionSchema.isSearchable());
} else {
metadataBuilder.setSearchable(readBooleanWithDefaultValue(searchableStringValue, false));
}
String inputMaskStringValue = metadataElement.getAttributeValue("inputMask");
if (inheriteGlobalMetadata && inputMaskStringValue == null) {
metadataBuilder.setInputMask(globalMetadataInCollectionSchema.getInputMask());
} else {
metadataBuilder.setInputMask(inputMaskStringValue);
}
String sortableStringValue = metadataElement.getAttributeValue("sortable");
if (inheriteGlobalMetadata && sortableStringValue == null) {
metadataBuilder.setSortable(globalMetadataInCollectionSchema.isSortable());
} else {
metadataBuilder.setSortable(readBooleanWithDefaultValue(sortableStringValue, false));
}
String schemaAutocompleteStringValue = metadataElement.getAttributeValue("schemaAutocomplete");
if (inheriteGlobalMetadata && schemaAutocompleteStringValue == null) {
metadataBuilder.setSchemaAutocomplete(globalMetadataInCollectionSchema.isSchemaAutocomplete());
} else {
metadataBuilder.setSchemaAutocomplete(readBooleanWithDefaultValue(schemaAutocompleteStringValue, false));
}
String uniqueStringValue = metadataElement.getAttributeValue("uniqueValue");
if (inheriteGlobalMetadata && uniqueStringValue == null) {
metadataBuilder.setUniqueValue(globalMetadataInCollectionSchema.isUniqueValue());
} else {
metadataBuilder.setUniqueValue(readBooleanWithDefaultValue(uniqueStringValue, false));
}
String markedForDeletion = metadataElement.getAttributeValue("markedForDeletion");
if (inheriteGlobalMetadata && markedForDeletion == null) {
metadataBuilder.setMarkedForDeletion(globalMetadataInCollectionSchema.isMarkedForDeletion());
} else {
metadataBuilder.setMarkedForDeletion(readBooleanWithDefaultValue(markedForDeletion, false));
}
String childOfRelationshipStringValue = metadataElement.getAttributeValue("childOfRelationship");
if (inheriteGlobalMetadata && childOfRelationshipStringValue == null) {
metadataBuilder.setChildOfRelationship(globalMetadataInCollectionSchema.isChildOfRelationship());
} else {
metadataBuilder.setChildOfRelationship(readBooleanWithDefaultValue(childOfRelationshipStringValue, false));
}
String taxonomyRelationshipStringValue = metadataElement.getAttributeValue("taxonomyRelationship");
if (inheriteGlobalMetadata && taxonomyRelationshipStringValue == null) {
metadataBuilder.setTaxonomyRelationship(globalMetadataInCollectionSchema.isTaxonomyRelationship());
} else {
metadataBuilder.setTaxonomyRelationship(readBooleanWithDefaultValue(taxonomyRelationshipStringValue, false));
}
String multivalueStringValue = metadataElement.getAttributeValue("multivalue");
if (inheriteGlobalMetadata && multivalueStringValue == null) {
metadataBuilder.setMultivalue(globalMetadataInCollectionSchema.isMultivalue());
} else {
metadataBuilder.setMultivalue(readBooleanWithDefaultValue(multivalueStringValue, false));
}
//}
Class<StructureFactory> structureFactoryClass = getClassValue(metadataElement, "structureFactory");
if (structureFactoryClass != null) {
metadataBuilder.defineStructureFactory(structureFactoryClass);
}
Class<? extends Enum<?>> enumClass = getClassValue(metadataElement, "enumClass");
if (enumClass != null) {
metadataBuilder.defineAsEnum(enumClass);
}
if (!isInheriting(metadataElement)) {
setAccessRestrictions(metadataBuilder.defineAccessRestrictions(), metadataElement);
}
if (metadataElement.getChild("defaultValue") != null) {
ParametrizedInstanceUtils utils = new ParametrizedInstanceUtils();
Object defaultValue = utils.toObject(metadataElement.getChild("defaultValue"));
metadataBuilder.setDefaultValue(defaultValue);
}
setPopulateConfigs(metadataBuilder, metadataElement);
addReferencesToBuilder(metadataBuilder, metadataElement, globalMetadataInCollectionSchema);
}
private <T> T readEnum(String code, Class<T> clazz) {
return (T) EnumWithSmallCodeUtils.toEnum((Class) clazz, code);
}
private void setPopulateConfigs(MetadataBuilder metadataBuilder, Element metadataElement) {
List<String> styles = new ArrayList<>();
List<String> properties = new ArrayList<>();
List<RegexConfig> regexes = new ArrayList<>();
List<MetadataPopulator> metadataPopulators = new ArrayList<>();
Element populateConfigsElement = metadataElement.getChild("populateConfigs");
if (populateConfigsElement != null) {
if (populateConfigsElement.getAttributeValue("styles") != null) {
styles.addAll(Arrays.asList(populateConfigsElement.getAttributeValue("styles").split(",")));
}
if (populateConfigsElement.getAttributeValue("properties") != null) {
properties.addAll(Arrays.asList(populateConfigsElement.getAttributeValue("properties").split(",")));
}
if (populateConfigsElement.getChild("regexConfigs") != null) {
Element regexConfigsElement = populateConfigsElement.getChild("regexConfigs");
addRegexConfigElementsToList(regexConfigsElement, regexes);
}
if (populateConfigsElement.getChild("metadataPopulators") != null) {
Element metadataPopulatorsElement = populateConfigsElement.getChild("metadataPopulators");
addMetadataPopulateElementsToList(metadataPopulatorsElement, metadataPopulators);
}
}
MetadataPopulateConfigsBuilder metadataPopulateConfigsBuilder = MetadataPopulateConfigsBuilder.create();
metadataPopulateConfigsBuilder.setStyles(styles);
metadataPopulateConfigsBuilder.setProperties(properties);
metadataPopulateConfigsBuilder.setRegexes(regexes);
metadataPopulateConfigsBuilder.setMetadataPopulators(metadataPopulators);
metadataBuilder.definePopulateConfigsBuilder(metadataPopulateConfigsBuilder);
}
private void addMetadataPopulateElementsToList(Element metadataPopulatorsElement,
List<MetadataPopulator> metadataPopulators) {
for (Element metadataPopulatorElement : metadataPopulatorsElement.getChildren()) {
try {
metadataPopulators.add(metadataPopulatorXMLSerializer.fromXML(metadataPopulatorElement));
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void addRegexConfigElementsToList(Element element, List<RegexConfig> listToAdd) {
if (element.getChildren("regexConfig") != null) {
for (Element regexConfigElement : element.getChildren("regexConfig")) {
String metadataInput = regexConfigElement.getAttributeValue("metadataInput");
String regexPattern = regexConfigElement.getAttributeValue("regex");
Pattern regex = Pattern.compile(regexPattern);
String value = regexConfigElement.getAttributeValue("value");
RegexConfigType regexConfigType;
try {
regexConfigType = RegexConfigType.valueOf(regexConfigElement.getAttributeValue("regexConfigType"));
} catch (IllegalArgumentException | NullPointerException e) {
regexConfigType = RegexConfigType.SUBSTITUTION;
}
RegexConfig regexConfig = new RegexConfig(metadataInput, regex, value, regexConfigType);
listToAdd.add(regexConfig);
}
}
}
private void setAccessRestrictions(MetadataAccessRestrictionBuilder metadataAccessRestrictionBuilder,
Element metadataElement) {
if (metadataElement.getChild("accessRestrictions") != null) {
Element accessRestrictionsElement = metadataElement.getChild("accessRestrictions");
if (accessRestrictionsElement.getAttributeValue("readAccessRestrictions") != null) {
metadataAccessRestrictionBuilder.getRequiredReadRoles().addAll(Arrays.asList(
accessRestrictionsElement.getAttributeValue("readAccessRestrictions").split(",")));
}
if (accessRestrictionsElement.getAttributeValue("writeAccessRestrictions") != null) {
metadataAccessRestrictionBuilder.getRequiredWriteRoles().addAll(Arrays.asList(
accessRestrictionsElement.getAttributeValue("writeAccessRestrictions").split(",")));
}
if (accessRestrictionsElement.getAttributeValue("deleteAccessRestrictions") != null) {
metadataAccessRestrictionBuilder.getRequiredDeleteRoles().addAll(Arrays.asList(
accessRestrictionsElement.getAttributeValue("deleteAccessRestrictions").split(",")));
}
if (accessRestrictionsElement.getAttributeValue("modifyAccessRestrictions") != null) {
metadataAccessRestrictionBuilder.getRequiredModificationRoles().addAll(Arrays.asList(
accessRestrictionsElement.getAttributeValue("modifyAccessRestrictions").split(",")));
}
}
}
@SuppressWarnings("unchecked")
private Class<? extends RecordMetadataValidator<?>> getValidatorClass(String validatorClassName) {
Class<? extends RecordMetadataValidator<?>> validator = validatorsCache.get(validatorClassName);
if (validator == null) {
try {
validator = classProvider.loadClass(validatorClassName);
validatorsCache.put(validatorClassName, validator);
} catch (ClassNotFoundException e) {
throw new MetadataSchemasManagerRuntimeException.NoSuchValidatorClass(validatorClassName, e);
}
}
return validator;
}
private List<String> parseValidators(Element element, MetadataBuilder collectionSchemaBuilder) {
Element validatorsElements = element.getChild("validators");
if (validatorsElements != null) {
String strValue = validatorsElements.getAttributeValue("classNames");
if (StringUtils.isBlank(strValue)) {
return new ArrayList<>();
} else {
return Arrays.asList(strValue.split(","));
}
} else if (collectionSchemaBuilder != null) {
return new ArrayList<>(collectionSchemaBuilder.defineValidators().getClassnames());
} else {
return new ArrayList<>();
}
}
private Set<String> parseCustomAttributes(String customAttributes) {
if (customAttributes != null && !customAttributes.isEmpty()) {
String[] elements = customAttributes.split(",");
Set<String> customAttributesSet = new HashSet<>();
for (String element : elements) {
customAttributesSet.add(element);
}
return customAttributesSet;
}
return new HashSet<>();
}
private boolean isInheriting(Element element) {
if (element.getAttributeValue("inheriting") == null) {
return false;
} else {
String stringValue = element.getAttributeValue("inheriting");
return "".equals(stringValue) ? null : readBoolean(stringValue);
}
}
private void addReferencesToBuilder(MetadataBuilder metadataBuilder, Element metadataElement,
MetadataBuilder collectionSchemaBuilder) {
if (metadataElement.getChild("references") != null) {
Element references = metadataElement.getChild("references");
if (metadataBuilder.getInheritance() == null && !metadataBuilder.hasDefinedReferences()) {
String schemaType = references.getAttributeValue("schemaType");
if (StringUtils.isNotEmpty(schemaType)) {
metadataBuilder.defineReferences().setCompleteSchemaTypeCode(schemaType);
} else {
List<String> schemas = Arrays.asList(references.getAttributeValue("schemas").split(","));
for (String schema : schemas) {
metadataBuilder.defineReferences().addCompleteSchemaCode(schema);
}
}
}
} else if (collectionSchemaBuilder != null) {
collectionSchemaBuilder.setAllowedReferenceBuilder(collectionSchemaBuilder.getAllowedReferencesBuilder());
}
}
private void parseDataEntryElement(MetadataBuilder metadataBuilder, Element metadataElement,
MetadataBuilder collectionSchemaBuilder) {
Element dataEntry = metadataElement.getChild("dataEntry");
if (dataEntry != null) {
if (dataEntry.getAttributeValue("copied") != null) {
String copiedMetadata = dataEntry.getAttributeValue("copied");
String referenceMetadata = dataEntry.getAttributeValue("reference");
metadataBuilder.defineDataEntry().as(new CopiedDataEntry(referenceMetadata, copiedMetadata));
} else if (dataEntry.getAttributeValue("calculator") != null) {
String calculator = dataEntry.getAttributeValue("calculator");
ParametrizedInstanceUtils utils = new ParametrizedInstanceUtils();
if ("parametrized".equals(calculator)) {
metadataBuilder.defineDataEntry().asCalculated(
(MetadataValueCalculator<?>) utils.toObject(dataEntry, Parametrized.class));
} else {
metadataBuilder.defineDataEntry().asCalculated(calculator);
}
} else if (dataEntry.getAttributeValue("fixedSequenceCode") != null) {
String fixedSequenceCode = dataEntry.getAttributeValue("fixedSequenceCode");
metadataBuilder.defineDataEntry().asFixedSequence(fixedSequenceCode);
} else if (dataEntry.getAttributeValue("metadataProvidingSequenceCode") != null) {
String metadataProvidingSequenceCode = dataEntry.getAttributeValue("metadataProvidingSequenceCode");
metadataBuilder.defineDataEntry().asSequenceDefinedByMetadata(metadataProvidingSequenceCode);
} else if (dataEntry.getAttributeValue("agregationType") != null) {
AggregationType aggregationType = (AggregationType)
toEnum(AggregationType.class, dataEntry.getAttributeValue("agregationType"));
String referenceMetadata = dataEntry.getAttributeValue("referenceMetadata");
String inputMetadata = dataEntry.getAttributeValue("inputMetadata");
metadataBuilder.defineDataEntry().as(new AggregatedDataEntry(inputMetadata, referenceMetadata, aggregationType));
}
} else if (!isInheriting(metadataElement)) {
if (collectionSchemaBuilder == null) {
metadataBuilder.defineDataEntry().asManual();
} else {
metadataBuilder.defineDataEntry().as(collectionSchemaBuilder.getDataEntry());
}
}
}
private void parseDefaultSchema(Element root, MetadataSchemaTypeBuilder schemaTypeBuilder,
MetadataSchemaTypesBuilder typesBuilder, MetadataSchemaBuilder collectionSchema) {
Element defaultSchemaElement = root.getChild("defaultSchema");
MetadataSchemaBuilder defaultSchemaBuilder = schemaTypeBuilder.getDefaultSchema();
defaultSchemaBuilder.setLabels(readLabels(defaultSchemaElement));
// new CommonMetadataBuilder().addCommonMetadataToExistingSchema(defaultSchemaBuilder, typesBuilder);
for (Element metadataElement : defaultSchemaElement.getChildren("m")) {
parseMetadata(defaultSchemaBuilder, metadataElement, collectionSchema);
}
List<String> validatorsClassNames = parseValidators(defaultSchemaElement, null);
for (String validatorsClassName : validatorsClassNames) {
defaultSchemaBuilder.defineValidators().add(getValidatorClass(validatorsClassName));
}
}
private String getCodeValue(Element element) {
return element.getAttributeValue("code");
}
private MetadataValueType getTypeValue(Element element) {
String stringValue = element.getAttributeValue("type");
return StringUtils.isBlank(stringValue) ? null : MetadataValueType.valueOf(stringValue);
}
private <T> Class<T> getClassValue(Element element, String attributeName) {
String className = element.getAttributeValue(attributeName);
if (StringUtils.isNotBlank(className)) {
return new InstanciationUtils().loadClassWithoutExpectableExceptions(className);
} else {
return null;
}
}
private boolean getBooleanFlagValueWithTrueAsDefaultValue(Element element, String childTagName) {
String value = element.getAttributeValue(childTagName);
return value == null || readBoolean(value);
}
private boolean getBooleanFlagValueWithFalseAsDefaultValue(Element element, String childTagName) {
String value = element.getAttributeValue(childTagName);
if (value == null) {
return false;
} else if ("t".equals(value)) {
return true;
} else if ("f".equals(value)) {
return false;
}
throw new ImpossibleRuntimeException("Unsupported value for attribute '" + childTagName + "'");
}
private boolean readBoolean(String value) {
if (value == null) {
return false;
} else if ("t".equals(value)) {
return true;
} else if ("f".equals(value)) {
return false;
}
throw new ImpossibleRuntimeException("Unsupported value '" + value + "'");
}
private boolean readBooleanWithDefaultValue(String value, boolean defaultValue) {
if (value == null) {
return defaultValue;
} else if ("t".equals(value)) {
return true;
} else if ("f".equals(value)) {
return false;
}
throw new ImpossibleRuntimeException("Unsupported value '" + value + "'");
}
private Map<Language, String> readLabels(Element schemaElement) {
Map<Language, String> labels = new HashMap<>();
for (Attribute attribute : schemaElement.getAttributes()) {
if (attribute.getName().startsWith("label_")) {
labels.put(Language.withCode(attribute.getName().substring(6)), attribute.getValue());
}
}
return labels;
}
}