cdc.applic.dictionaries.impl.io.RepositoryOffice Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdc-applic-dictionaries-impl Show documentation
Show all versions of cdc-applic-dictionaries-impl Show documentation
Applicabilities Dictionaries Implementation.
The newest version!
package cdc.applic.dictionaries.impl.io;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cdc.applic.dictionaries.Constraint;
import cdc.applic.dictionaries.Constraints;
import cdc.applic.dictionaries.DItemUsage;
import cdc.applic.dictionaries.Described;
import cdc.applic.dictionaries.Dictionary;
import cdc.applic.dictionaries.NamingConvention;
import cdc.applic.dictionaries.impl.AbstractDictionaryImpl;
import cdc.applic.dictionaries.impl.AbstractTypeImpl;
import cdc.applic.dictionaries.impl.AliasImpl;
import cdc.applic.dictionaries.impl.BooleanTypeImpl;
import cdc.applic.dictionaries.impl.DescriptionImpl;
import cdc.applic.dictionaries.impl.DescriptionSetter;
import cdc.applic.dictionaries.impl.EnumeratedTypeImpl;
import cdc.applic.dictionaries.impl.EnumeratedValueImpl;
import cdc.applic.dictionaries.impl.IntegerTypeImpl;
import cdc.applic.dictionaries.impl.NamingConventionImpl;
import cdc.applic.dictionaries.impl.PatternTypeImpl;
import cdc.applic.dictionaries.impl.PolicyImpl;
import cdc.applic.dictionaries.impl.PropertyImpl;
import cdc.applic.dictionaries.impl.RealTypeImpl;
import cdc.applic.dictionaries.impl.RegistryImpl;
import cdc.applic.dictionaries.impl.RepositoryImpl;
import cdc.applic.dictionaries.items.Assertion;
import cdc.applic.dictionaries.items.NamedDItem;
import cdc.applic.dictionaries.items.UserDefinedAssertion;
import cdc.applic.dictionaries.s1000d.S1000DProductIdentifier;
import cdc.applic.dictionaries.s1000d.S1000DPropertyType;
import cdc.applic.dictionaries.s1000d.S1000DType;
import cdc.applic.dictionaries.types.BooleanType;
import cdc.applic.dictionaries.types.EnumeratedType;
import cdc.applic.dictionaries.types.EnumeratedValue;
import cdc.applic.dictionaries.types.IntegerType;
import cdc.applic.dictionaries.types.ModifiableType;
import cdc.applic.dictionaries.types.PatternType;
import cdc.applic.dictionaries.types.RealType;
import cdc.applic.dictionaries.types.Type;
import cdc.applic.expressions.Expression;
import cdc.applic.expressions.content.BooleanValue;
import cdc.applic.expressions.content.IntegerSet;
import cdc.applic.expressions.content.IntegerValue;
import cdc.applic.expressions.content.RealSet;
import cdc.applic.expressions.content.RealValue;
import cdc.applic.expressions.content.StringValue;
import cdc.applic.expressions.literals.Name;
import cdc.applic.expressions.literals.Named;
import cdc.applic.expressions.literals.SName;
import cdc.impex.ImpExCatalog;
import cdc.impex.ImpExFactory;
import cdc.impex.ImpExFactoryFeatures;
import cdc.impex.exports.ExportRow;
import cdc.impex.exports.Exporter;
import cdc.impex.exports.SheetExporter;
import cdc.impex.imports.ImportRow;
import cdc.impex.imports.Importer;
import cdc.impex.imports.SheetImporter;
import cdc.impex.templates.ColumnTemplate;
import cdc.impex.templates.ImportAction;
import cdc.impex.templates.SheetTemplate;
import cdc.impex.templates.SheetTemplateInstance;
import cdc.impex.templates.TemplateGenerator;
import cdc.impex.templates.Usage;
import cdc.issues.Issue;
import cdc.issues.IssuesCollector;
import cdc.issues.IssuesHandler;
import cdc.office.ss.WorkbookWriterFeatures;
import cdc.tuples.Tuple2;
import cdc.tuples.Tuple3;
import cdc.tuples.Tuple4;
import cdc.util.events.ProgressController;
import cdc.util.function.IterableUtils;
import cdc.util.lang.ImplementationException;
import cdc.util.meta.MetaData;
import cdc.util.meta.MetaDataEncoder;
import cdc.util.paths.Path;
import cdc.util.strings.StringConversion;
public final class RepositoryOffice {
// TODO Bindings
private RepositoryOffice() {
}
/**
* Declaration of all column and sheet templates.
*
* @author Damien Carbonne
*/
public static final class Templates {
private Templates() {
}
public static final String IMPEX_DOMAIN = "Applic";
public static final String N_DEFAULT_VALUE = "Default Value";
public static final String N_TYPE_NAME = "Type Name";
public static final String ENTITY_ALIAS = "Alias";
public static final String ENTITY_ASSERTION = "Assertion";
public static final String ENTITY_BOOLEAN_TYPE = "Boolean Type";
public static final String ENTITY_CONSTRAINT = "Constraint";
public static final String ENTITY_ENUMERATED_TYPE = "Enumerated Type";
public static final String ENTITY_ENUMERATED_VALUE = "Enumerated Value";
public static final String ENTITY_INTEGER_TYPE = "Integer Type";
public static final String ENTITY_ITEM = "Item";
public static final String ENTITY_NAMING_CONVENTION = "Naming Convention";
public static final String ENTITY_PATTERN_TYPE = "Pattern Type";
public static final String ENTITY_POLICY = "Policy";
public static final String ENTITY_PROPERTY = "Property";
public static final String ENTITY_REAL_TYPE = "Real Type";
public static final String ENTITY_REGISTRY = "Registry";
public static final String ENTITY_TYPE = "Type";
public static String descrDef(String entity) {
return "Default value of the " + entity + ".";
}
public static String descrDictionaryPath(String entity) {
return "Absolute Path of the Dictionary (Registry or Policy) containing the " + entity + ".";
}
public static String descrEn(String entity) {
return "English description of the " + entity + ".";
}
public static String descrExpression(String entity) {
return "Expression defining the " + entity + ".";
}
public static String descrFr(String entity) {
return "French description of the " + entity + ".";
}
public static String descrFrozen(String entity) {
return "Freezing of the " + entity + " definition.\n"
+ "By freezing a Type, the user promises that its definition won't change in the future.\n"
+ "A non-frozen Type has an implicit reserve.\n"
+ "This has an influence on simplifications.";
}
public static String descrName(String entity) {
return "Name of the " + entity + ".";
}
public static String descrOrdinal(String entity) {
return "Ordinal of the " + entity + ".\n"
+ "It is used to normalize writing of expressions.";
}
public static String descrRegistryName(String entity) {
return "Name of the Registry to which the " + entity + " belongs.";
}
public static String descrSynonyms(String entity,
String field) {
return "Synonyms of the " + entity + " " + field + ".\n"
+ "List (0, 1 or more, EOL separated) of convention:synonym,"
+ " where convention is the name of Naming Convention and synonym a Synonym of the " + entity + ".";
}
public static String descrTypeName(String entity) {
return "Name of the Type of the " + entity + ".";
}
public static String descrWritingRules(String entity) {
return "List (0, 1 or more, EOL separated) of enabled Writing Rules in the " + entity + ".";
}
public static final ColumnTemplate ALIAS_EXPRESSION =
ColumnTemplate.builder(Expression.class)
.name("Expression")
.usage(Usage.MANDATORY_RW_ATT)
.description(descrExpression(ENTITY_ALIAS))
.importConverter(Expression::fromString)
.exportConverter(Expression::getContent)
.build();
public static final ColumnTemplate ASSERTION_EXPRESSION =
ColumnTemplate.builder(Expression.class)
.name("Expression")
.usage(Usage.MANDATORY_RO_ID)
.description(descrExpression(ENTITY_ASSERTION))
.importConverter(Expression::fromString)
.exportConverter(Expression::getContent)
.build();
public static final ColumnTemplate BOOLEAN_TYPE_DEFAULT_VALUE =
ColumnTemplate.builder(Boolean.class)
.name(N_DEFAULT_VALUE)
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrDef(ENTITY_BOOLEAN_TYPE))
.importConverter(StringConversion::asOptionalBoolean)
.build();
public static final ColumnTemplate CONSTRAINT_PARAMS =
ColumnTemplate.builder(String.class)
.name("Params")
.usage(Usage.MANDATORY_RO_ID) // FIXME: should be MANDATORY_RW_ATT when Constraint Id available
.description("Parameters of the Constraint.\n"
+ "Syntax is dependent on the Constraint Type.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate CONSTRAINT_TYPE_NAME =
ColumnTemplate.builder(String.class)
.name(N_TYPE_NAME)
.usage(Usage.MANDATORY_RO_ID) // FIXME: should be MANDATORY_RW_ATT when Constraint Id available
.description(descrTypeName(ENTITY_CONSTRAINT))
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate CONTEXT =
ColumnTemplate.builder(Expression.class)
.name("Context")
.usage(Usage.OPTIONAL_RW_ATT)
.description("""
Context expression used to restrict domain inherited from parent dictionary(ies).
When not set, it is equivalent to 'true'.""")
.importConverter(Expression::fromString)
.exportConverter(Expression::getContent)
.build();
public static final ColumnTemplate DESCRIPTION_EN =
ColumnTemplate.builder(String.class)
.name("Description (English)")
.usage(Usage.OPTIONAL_RW_ATT)
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate DESCRIPTION_FR =
ColumnTemplate.builder(String.class)
.name("Description (French)")
.usage(Usage.OPTIONAL_RW_ATT)
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate DICTIONARY_PATH =
ColumnTemplate.builder(Path.class)
.name("Dictionary Path")
.usage(Usage.MANDATORY_RO_ID)
.importConverter(Path::new)
.exportConverter(Path::toString)
.build();
public static final ColumnTemplate ENUMERATED_TYPE_DEFAULT_VALUE =
ColumnTemplate.builder(String.class)
.name(N_DEFAULT_VALUE)
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrDef(ENTITY_ENUMERATED_TYPE))
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate ENUMERATED_TYPE_NAME =
ColumnTemplate.builder(String.class)
.name("Enumerated Type Name")
.usage(Usage.MANDATORY_RO_ID)
.description("Name of the Enumerated Type.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate FROZEN =
ColumnTemplate.builder(Boolean.class)
.name("Frozen")
.usage(Usage.OPTIONAL_RW_ATT)
.importConverter(Boolean::valueOf)
.build();
public static final ColumnTemplate INTEGER_TYPE_DEFAULT_VALUE =
ColumnTemplate.builder(Integer.class)
.name(N_DEFAULT_VALUE)
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrDef(ENTITY_INTEGER_TYPE))
.importConverter(StringConversion::asOptionalInt)
.build();
public static final ColumnTemplate INTEGER_DOMAIN =
ColumnTemplate.builder(IntegerSet.class)
.name("Domain")
.usage(Usage.MANDATORY_RW_ATT)
.description("""
Domain of the Integer Type.
It is a list of integers and integers intervals, separated by ','.
An integer interval is defined by 2 integers separated by '~'.""")
.importConverter(IntegerSet::of)
.exportConverter(IntegerSet::getContent)
.build();
public static final ColumnTemplate ITEM_NAME =
ColumnTemplate.builder(String.class)
.name("Item Name")
.usage(Usage.MANDATORY_RO_ID)
.description("Name of the Item (Property or Alias).")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate ITEM_USAGE =
ColumnTemplate.builder(DItemUsage.class)
.name("Usage")
.usage(Usage.MANDATORY_RW_ATT)
.description("Usage of the Item (Property or Alias) in the Dictionary (Registry or Policy).")
.importConverter(DItemUsage::valueOf)
.build();
public static final ColumnTemplate LITERAL =
ColumnTemplate.builder(String.class)
.name("Literal")
.usage(Usage.MANDATORY_RO_ID)
.description("""
Literal of the Enumerated Value.
Must be unique for a Type.""")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate LITERAL_INF =
ColumnTemplate.builder(String.class)
.name("Literal Inf")
.usage(Usage.MANDATORY_RW_ATT)
.description("Literal of the inferior Enumerated Value in an Order relationship.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate LITERAL_SUP =
ColumnTemplate.builder(String.class)
.name("Literal Sup")
.usage(Usage.MANDATORY_RW_ATT)
.description("Literal of the superior Enumerated Value in an Order relationship.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate NAME =
ColumnTemplate.builder(String.class)
.name("Name")
.usage(Usage.MANDATORY_RO_ID)
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate ORDINAL =
ColumnTemplate.builder(Integer.class)
.name("Ordinal")
.usage(Usage.OPTIONAL_RW_ATT)
.importConverter(StringConversion::asOptionalInt)
.build();
public static final ColumnTemplate PARENTS_PATHS =
ColumnTemplate.builder(String.class)
.name("Parent Paths")
.usage(Usage.OPTIONAL_RW_ATT)
.description("Absolute paths (0, 1 or more, EOL separated) of the parent Dictionaries (Registries or Policies) of the Registry.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate PARENT_PATH =
ColumnTemplate.builder(Path.class)
.name("Parent Path")
.usage(Usage.MANDATORY_RO_ID)
.description("Absolute path of the parent Dictionary (Registry or Policy) of the Policy.")
.importConverter(Path::new)
.exportConverter(Path::toString)
.build();
public static final ColumnTemplate PATTERN =
ColumnTemplate.builder(String.class)
.name("Pattern")
.usage(Usage.MANDATORY_RW_ATT)
.description("Pattern defining the possible values of the Pattern Type.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate PATTERN_TYPE_DEFAULT_VALUE =
ColumnTemplate.builder(String.class)
.name(N_DEFAULT_VALUE)
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrDef(ENTITY_PATTERN_TYPE))
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate PREFIX =
ColumnTemplate.builder(String.class)
.name("Prefix")
.usage(Usage.OPTIONAL_RW_ATT)
.description("Prefix of the Registry. It should be short.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate PROPERTY_TYPE_NAME =
ColumnTemplate.builder(String.class)
.name(N_TYPE_NAME)
.usage(Usage.MANDATORY_RW_ATT)
.description(descrTypeName(ENTITY_PROPERTY))
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate REAL_TYPE_DEFAULT_VALUE =
ColumnTemplate.builder(Double.class)
.name(N_DEFAULT_VALUE)
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrDef(ENTITY_REAL_TYPE))
.importConverter(StringConversion::asOptionalDouble)
.build();
public static final ColumnTemplate REAL_DOMAIN =
ColumnTemplate.builder(RealSet.class)
.name("Domain")
.usage(Usage.MANDATORY_RW_ATT)
.description("""
Domain of the Real Type.
It is a list of reals and real intervals, separated by ','.
A real interval is defined by 2 reals separated by '~'.""")
.importConverter(RealSet::of)
.exportConverter(RealSet::getContent)
.build();
public static final ColumnTemplate REGISTRY_NAME =
ColumnTemplate.builder(String.class)
.name("Registry Name")
.usage(Usage.MANDATORY_RO_ID)
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate SYNONYMS =
ColumnTemplate.builder(MetaData.class)
.name("Synonyms")
.usage(Usage.OPTIONAL_RW_ATT)
.importConverter(MetaDataEncoder::decode)
.exportConverter(MetaDataEncoder::encode)
.build();
public static final ColumnTemplate TYPE_NAME =
ColumnTemplate.builder(String.class)
.name(N_TYPE_NAME)
.usage(Usage.MANDATORY_RO_ID)
.description("Name of the Type.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate TYPE_USAGE =
ColumnTemplate.builder(DItemUsage.class)
.name("Usage")
.usage(Usage.MANDATORY_RW_ATT)
.description("Usage of the Type in the Dictionary (Registry or Policy).")
.importConverter(DItemUsage::valueOf)
.build();
public static final ColumnTemplate S1000D_PRODUCT_IDENTIFIER =
ColumnTemplate.builder(S1000DProductIdentifier.class)
.name("S1000D Product Identifier")
.usage(Usage.OPTIONAL_RW_ATT)
.description("S1000D product identifier " + Arrays.toString(S1000DProductIdentifier.values()) + ".\n"
+ "An empty cell is equivalent to " + S1000DProductIdentifier.NONE
+ " or " + S1000DProductIdentifier.NOT_APPLICABLE
+ ", depending on the value of S1000D Property Type.\n"
+ "One should only optionaly use " + S1000DProductIdentifier.PRIMARY + " or "
+ S1000DProductIdentifier.SECONDARY + " when S1000D Property Type is "
+ S1000DPropertyType.PRODUCT_ATTRIBUTE + ".\n"
+ "In other cases, this column should be left empty.\n"
+ "WARNING: S1000D Property Type and S1000D Product Identifier must be compliant.")
.importConverter(S1000DProductIdentifier::valueOf)
.build();
public static final ColumnTemplate S1000D_PROPERTY_ID =
ColumnTemplate.builder(String.class)
.name("S1000D Id")
.usage(Usage.OPTIONAL_RW_ATT)
.description("Id of the S1000D Property.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate S1000D_PROPERTY_TYPE =
ColumnTemplate.builder(S1000DPropertyType.class)
.name("S1000D Property Type")
.usage(Usage.OPTIONAL_RW_ATT)
.description("S1000D type of a Property " + Arrays.toString(S1000DPropertyType.values()) + ".\n"
+ "An empty cell is equivalent to " + S1000DPropertyType.UNDEFINED + ".\n"
+ S1000DPropertyType.PRODUCT_ATTRIBUTE + " Properties go into ACT.\n"
+ S1000DPropertyType.PRODUCT_CONDITION + " and " + S1000DPropertyType.EXTERNAL_CONDITION
+ " Properties go into CCT.\n"
+ S1000DPropertyType.PRODUCT_ATTRIBUTE + " and " + S1000DPropertyType.PRODUCT_CONDITION
+ " Properties go into PCT.\n"
+ "WARNING: S1000D Property Type and S1000D Product Identifier must be compliant.")
.importConverter(S1000DPropertyType::valueOf)
.build();
public static final ColumnTemplate S1000D_TYPE_ID =
ColumnTemplate.builder(String.class)
.name("S1000D Id")
.usage(Usage.OPTIONAL_RW_ATT)
.description("Id of the S1000D Type.")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate SHORT_LITERAL =
ColumnTemplate.builder(String.class)
.name("Short Literal")
.usage(Usage.OPTIONAL_RW_ATT)
.description("""
Short literal of an Enumerated Value.
Can be used to display expression in a more compact way.
However, publication of expressions is more general to reach the same objective.""")
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final ColumnTemplate WRITING_RULES =
ColumnTemplate.builder(String.class)
.name("Writing Rules")
.usage(Usage.OPTIONAL_RW_ATT)
.description(descrWritingRules("Dictionary (Registry or Policy)"))
.importConverter(s -> s)
.exportConverter(s -> s)
.build();
public static final SheetTemplate ALIASES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Aliases")
.description("""
Definition of Aliases in a Registry
An Alias is a named expression that can be based on Properties and other Aliases.
There must not be circular dependencies between Aliases.""")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_ALIAS)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_ALIAS)).build())
.column(SYNONYMS.newBuilder().description(descrSynonyms(ENTITY_ALIAS, NAME.getName())).build())
.column(ALIAS_EXPRESSION)
.column(ORDINAL.newBuilder().description(descrOrdinal(ENTITY_ALIAS)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_ALIAS)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_ALIAS)).build())
.build();
public static final SheetTemplate ASSERTIONS =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Assertions")
.description("""
Definition of Assertions in a Dictionary (Registry or Policy).
An Assertion is an expression that must always be true.""")
.column(DICTIONARY_PATH.newBuilder().description(descrDictionaryPath(ENTITY_ASSERTION)).build())
.column(ASSERTION_EXPRESSION)
.build();
public static final SheetTemplate BOOLEAN_TYPES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Boolean Types")
.description("Definition of Boolean Types in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_BOOLEAN_TYPE)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_BOOLEAN_TYPE)).build())
.column(SYNONYMS.newBuilder()
.description(descrSynonyms(ENTITY_BOOLEAN_TYPE, NAME.getName())).build())
.column(BOOLEAN_TYPE_DEFAULT_VALUE)
.column(S1000D_TYPE_ID)
.column(S1000D_PROPERTY_TYPE)
.column(S1000D_PRODUCT_IDENTIFIER)
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_BOOLEAN_TYPE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_BOOLEAN_TYPE)).build())
.build();
public static final SheetTemplate CONSTRAINTS =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Constraints")
.description("""
Definition of Constraints in a Dictionary (Registry or Policy).
A Constraint is a high level solution to define Assertions.""")
.column(DICTIONARY_PATH.newBuilder().description(descrDictionaryPath(ENTITY_CONSTRAINT)).build())
.column(CONSTRAINT_TYPE_NAME)
.column(CONSTRAINT_PARAMS)
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_CONSTRAINT)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_CONSTRAINT)).build())
.build();
public static final SheetTemplate ENUMERATED_ORDERS =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Enumerated Orders")
.description("""
Definition of Order relationships between Enumerated Values of an Enumerated Type.
An Order relationship can not have circular dependencies.""")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_ENUMERATED_TYPE)).build())
.column(ENUMERATED_TYPE_NAME)
.column(LITERAL_INF)
.column(LITERAL_SUP)
.build();
public static final SheetTemplate ENUMERATED_TYPES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Enumerated Types")
.description("Definition of Enumerated Types in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_ENUMERATED_TYPE)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_ENUMERATED_TYPE)).build())
.column(SYNONYMS.newBuilder()
.description(descrSynonyms(ENTITY_ENUMERATED_TYPE, NAME.getName())).build())
.column(ENUMERATED_TYPE_DEFAULT_VALUE)
.column(S1000D_TYPE_ID)
.column(S1000D_PROPERTY_TYPE)
.column(S1000D_PRODUCT_IDENTIFIER)
.column(FROZEN.newBuilder().description(descrFrozen(ENTITY_ENUMERATED_TYPE)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_ENUMERATED_TYPE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_ENUMERATED_TYPE)).build())
.build();
public static final SheetTemplate ENUMERATED_VALUES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Enumerated Values")
.description("""
Definition of Enumerated Values of an Enumerated Type.
They must be different for an Enumerated Type, but 2 Enumerated Types can have identical Enumerated Values.""")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_ENUMERATED_TYPE)).build())
.column(ENUMERATED_TYPE_NAME)
.column(LITERAL)
.column(SHORT_LITERAL)
.column(SYNONYMS.newBuilder()
.description(descrSynonyms(ENTITY_ENUMERATED_VALUE, LITERAL.getName())).build())
.column(ORDINAL.newBuilder().description(descrOrdinal(ENTITY_ENUMERATED_VALUE)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_ENUMERATED_VALUE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_ENUMERATED_VALUE)).build())
.build();
public static final SheetTemplate INTEGER_TYPES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Integer Types")
.description("Definition of Integer Types in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_INTEGER_TYPE)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_INTEGER_TYPE)).build())
.column(SYNONYMS.newBuilder()
.description(descrSynonyms(ENTITY_INTEGER_TYPE, NAME.getName())).build())
.column(INTEGER_TYPE_DEFAULT_VALUE)
.column(S1000D_TYPE_ID)
.column(S1000D_PROPERTY_TYPE)
.column(S1000D_PRODUCT_IDENTIFIER)
.column(INTEGER_DOMAIN)
.column(FROZEN.newBuilder().description(descrFrozen(ENTITY_INTEGER_TYPE)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_INTEGER_TYPE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_INTEGER_TYPE)).build())
.build();
public static final SheetTemplate ITEM_USAGES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Item Usages")
.description("""
Definition of the usage of Items (Properties and Aliases) in a Dictionary (Registry or Policy).
Items whose usage is not defined are considered as OPTIONAL for Registries, and FORBIDDEN for Policies.""")
.column(DICTIONARY_PATH.newBuilder()
.description(descrDictionaryPath("Item (Property or Alias)"))
.build())
.column(ITEM_NAME)
.column(ITEM_USAGE)
.build();
public static final SheetTemplate NAMING_CONVENTIONS =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Naming Conventions")
.description("Definition of Naming Conventions in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_NAMING_CONVENTION)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_NAMING_CONVENTION)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_NAMING_CONVENTION)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_NAMING_CONVENTION)).build())
.build();
public static final SheetTemplate PATTERN_TYPES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Pattern Types")
.description("Definition of Pattern Types in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_PATTERN_TYPE)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_PATTERN_TYPE)).build())
.column(SYNONYMS.newBuilder()
.description(descrSynonyms(ENTITY_PATTERN_TYPE, NAME.getName())).build())
.column(PATTERN_TYPE_DEFAULT_VALUE)
.column(S1000D_TYPE_ID)
.column(S1000D_PROPERTY_TYPE)
.column(S1000D_PRODUCT_IDENTIFIER)
.column(PATTERN)
.column(FROZEN.newBuilder().description(descrFrozen(ENTITY_PATTERN_TYPE)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_PATTERN_TYPE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_PATTERN_TYPE)).build())
.build();
public static final SheetTemplate POLICIES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Policies")
.description("""
Definition of Policies in a Dictionary (Registry or Policy).
A Policy, which is a Dictionary, can contain Assertions, Constraints, (Sub)Policies.
A Policy has 1 parent Dictionary.
A Policy has a name that must be different from the names of its siblings.""")
.column(PARENT_PATH)
.column(NAME.newBuilder().description(descrName(ENTITY_POLICY)).build())
.column(CONTEXT)
.column(WRITING_RULES.newBuilder().description(descrWritingRules(ENTITY_POLICY)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_POLICY)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_POLICY)).build())
.build();
public static final SheetTemplate PROPERTIES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Properties")
.description("Definition of Properties in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_PROPERTY)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_PROPERTY)).build())
.column(SYNONYMS.newBuilder().description(descrSynonyms(ENTITY_PROPERTY, NAME.getName())).build())
.column(S1000D_PROPERTY_ID)
.column(PROPERTY_TYPE_NAME)
.column(ORDINAL.newBuilder().description(descrOrdinal(ENTITY_PROPERTY)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_PROPERTY)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_PROPERTY)).build())
.build();
public static final SheetTemplate REAL_TYPES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Real Types")
.description("Definition of Real Types in a Registry.")
.column(REGISTRY_NAME.newBuilder().description(descrRegistryName(ENTITY_REAL_TYPE)).build())
.column(NAME.newBuilder().description(descrName(ENTITY_REAL_TYPE)).build())
.column(SYNONYMS.newBuilder().description(descrSynonyms(ENTITY_REAL_TYPE, NAME.getName())).build())
.column(REAL_TYPE_DEFAULT_VALUE)
.column(S1000D_TYPE_ID)
.column(S1000D_PROPERTY_TYPE)
.column(S1000D_PRODUCT_IDENTIFIER)
.column(REAL_DOMAIN)
.column(FROZEN.newBuilder().description(descrFrozen(ENTITY_REAL_TYPE)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_REAL_TYPE)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_REAL_TYPE)).build())
.build();
public static final SheetTemplate REGISTRIES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Registries")
.description("""
Definition of Registries.
A Registry, which is a Dictionary, can contain Types, Properties, Aliases, Assertions, Constraints, (Sub)Policies.
A Registry has a name that must be different from the names of other Registries.
A Registry can aggregate (inherit from) 0, 1 or more Dictionaries.""")
.column(NAME.newBuilder().description(descrName(ENTITY_REGISTRY)).build())
.column(PARENTS_PATHS)
.column(PREFIX)
.column(CONTEXT)
.column(WRITING_RULES.newBuilder().description(descrWritingRules(ENTITY_REGISTRY)).build())
.column(DESCRIPTION_EN.newBuilder().description(descrEn(ENTITY_REGISTRY)).build())
.column(DESCRIPTION_FR.newBuilder().description(descrFr(ENTITY_REGISTRY)).build())
.build();
public static final SheetTemplate TYPE_USAGES =
SheetTemplate.builder()
.domain(IMPEX_DOMAIN)
.name("Type Usages")
.description("""
Definition of the usage of Types in a Dictionary (Registry or Policy).
A Property of that type will have this usage unless a specific one is defined for it.""")
.column(DICTIONARY_PATH.newBuilder()
.description(descrDictionaryPath("Type"))
.build())
.column(TYPE_NAME)
.column(TYPE_USAGE)
.build();
}
public static void generateTemplate(File file) throws IOException {
final ImpExFactory factory = new ImpExFactory(ImpExFactoryFeatures.BEST);
final TemplateGenerator generator = factory.createTemplateGenerator(file);
generator.generate(file,
Templates.REGISTRIES.instantiate(),
Templates.NAMING_CONVENTIONS.instantiate(),
Templates.BOOLEAN_TYPES.instantiate(),
Templates.INTEGER_TYPES.instantiate(),
Templates.REAL_TYPES.instantiate(),
Templates.ENUMERATED_TYPES.instantiate(),
Templates.ENUMERATED_VALUES.instantiate(),
Templates.ENUMERATED_ORDERS.instantiate(),
Templates.PATTERN_TYPES.instantiate(),
Templates.TYPE_USAGES.instantiate(),
Templates.PROPERTIES.instantiate(),
Templates.ALIASES.instantiate(),
Templates.POLICIES.instantiate(),
Templates.ITEM_USAGES.instantiate(),
Templates.CONSTRAINTS.instantiate(),
Templates.ASSERTIONS.instantiate());
}
public static final class Loader {
private static final Logger LOGGER = LogManager.getLogger(RepositoryOffice.Loader.class);
private final ImpExCatalog catalog = new ImpExCatalog();
private final RepositoryImpl repository = new RepositoryImpl();
private final Optional defaultAction = Optional.of(ImportAction.IGNORE);
private Loader() {
// Alphabetical order
catalog.register(Templates.ALIASES, new AliasesImporter());
catalog.register(Templates.ASSERTIONS, new AssertionsImporter());
catalog.register(Templates.BOOLEAN_TYPES, new TypesImporter());
catalog.register(Templates.CONSTRAINTS, new ConstraintsImporter());
catalog.register(Templates.ENUMERATED_ORDERS, new EnumeratedOrdersImporter());
catalog.register(Templates.ENUMERATED_TYPES, new TypesImporter());
catalog.register(Templates.ENUMERATED_VALUES, new EnumeratedValuesImporter());
catalog.register(Templates.INTEGER_TYPES, new TypesImporter());
catalog.register(Templates.ITEM_USAGES, new ItemUsagesImporter());
catalog.register(Templates.NAMING_CONVENTIONS, new NamingConventionsImporter());
catalog.register(Templates.PATTERN_TYPES, new TypesImporter());
catalog.register(Templates.POLICIES, new PoliciesImporter());
catalog.register(Templates.PROPERTIES, new PropertiesImporter());
catalog.register(Templates.REAL_TYPES, new TypesImporter());
catalog.register(Templates.REGISTRIES, new RegistriesImporter());
catalog.register(Templates.TYPE_USAGES, new TypeUsagesImporter());
}
private RepositoryImpl loadInt(File file,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
final ImpExFactoryFeatures features =
ImpExFactoryFeatures.builder()
.workbookWriterFeatures(WorkbookWriterFeatures.STANDARD_FAST)
.hint(ImpExFactoryFeatures.Hint.PRETTY_PRINT)
.hint(ImpExFactoryFeatures.Hint.POI_STREAMING)
.hint(ImpExFactoryFeatures.Hint.IGNORE_MISSING_ACTION_COLUMN)
.build();
final ImpExFactory factory = new ImpExFactory(features);
final Importer importer = factory.createImporter(file);
// Alphabetical order
importer.importData(file,
catalog.getTemplates(),
catalog.createWorkbookImporterFor(Templates.ALIASES.getName(),
Templates.ASSERTIONS.getName(),
Templates.BOOLEAN_TYPES.getName(),
Templates.CONSTRAINTS.getName(),
Templates.ENUMERATED_TYPES.getName(),
Templates.ENUMERATED_VALUES.getName(),
Templates.ENUMERATED_ORDERS.getName(),
Templates.INTEGER_TYPES.getName(),
Templates.ITEM_USAGES.getName(),
Templates.NAMING_CONVENTIONS.getName(),
Templates.PATTERN_TYPES.getName(),
Templates.PROPERTIES.getName(),
Templates.POLICIES.getName(),
Templates.REAL_TYPES.getName(),
Templates.REGISTRIES.getName(),
Templates.TYPE_USAGES.getName()),
issuesHandler,
controller);
return repository;
}
public static RepositoryImpl load(File file,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
final Loader loader = new Loader();
return loader.loadInt(file, issuesHandler, controller);
}
public static RepositoryImpl load(File file) throws IOException {
final IssuesCollector issuesHandler = new IssuesCollector<>();
final ProgressController controller = ProgressController.VOID;
return load(file, issuesHandler, controller);
}
private static void importDescriptions(ImportRow row,
DescriptionSetter> description) {
final String descriptionEN = row.getDataOrNull(Templates.DESCRIPTION_EN);
final String descriptionFR = row.getDataOrNull(Templates.DESCRIPTION_FR);
description.description(Locale.ENGLISH, descriptionEN);
description.description(Locale.FRENCH, descriptionFR);
}
private static void importDescriptions(ImportRow row,
Described described) {
importDescriptions(row, (DescriptionImpl) described.getDescription());
}
private static void traceImport(ImportRow row) {
LOGGER.debug("importRow({})", row);
}
private class AliasesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final String name = row.getDataOrNull(Templates.NAME);
final MetaData synonyms = row.getDataOrNull(Templates.SYNONYMS);
final Integer ordinal = row.getData(Templates.ORDINAL, 0);
final Expression expression = row.getDataOrNull(Templates.ALIAS_EXPRESSION);
final RegistryImpl registry = repository.getRegistry(registryName);
final AliasImpl.Builder alias = registry.alias()
.name(name)
.synonyms(synonyms)
.expression(expression)
.ordinal(ordinal);
importDescriptions(row, alias);
alias.build();
}
}
}
private class AssertionsImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final Path dictionaryPath = row.getDataOrNull(Templates.DICTIONARY_PATH);
final Expression expression = row.getDataOrNull(Templates.ASSERTION_EXPRESSION);
final AbstractDictionaryImpl dictionary = repository.getDictionary(dictionaryPath);
dictionary.createAssertion(expression);
}
}
}
private class ConstraintsImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final Path dictionaryPath = row.getDataOrNull(Templates.DICTIONARY_PATH);
final String typeName = row.getDataOrNull(Templates.CONSTRAINT_TYPE_NAME);
final String params = row.getDataOrNull(Templates.CONSTRAINT_PARAMS);
final AbstractDictionaryImpl dictionary =
repository.getDictionary(dictionaryPath, AbstractDictionaryImpl.class);
final Constraint constraint = Constraints.create(typeName, dictionary, params);
importDescriptions(row, constraint);
dictionary.addConstraint(constraint);
}
}
}
private class EnumeratedOrdersImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final String typeName = row.getDataOrNull(Templates.ENUMERATED_TYPE_NAME);
final String inf = row.getDataOrNull(Templates.LITERAL_INF);
final String sup = row.getDataOrNull(Templates.LITERAL_SUP);
final RegistryImpl registry = repository.getDictionary(registryName, RegistryImpl.class);
final EnumeratedTypeImpl type =
registry.getOptionalType(Name.of(typeName),
EnumeratedTypeImpl.class)
.orElseThrow();
type.addLessThan(inf, sup);
}
}
}
private class EnumeratedValuesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final String typeName = row.getDataOrNull(Templates.ENUMERATED_TYPE_NAME);
final String literal = row.getDataOrNull(Templates.LITERAL);
final MetaData synonyms = row.getDataOrNull(Templates.SYNONYMS);
final String shortLiteral = row.getDataOrNull(Templates.SHORT_LITERAL);
final Integer ordinal = row.getData(Templates.ORDINAL, 0);
final RegistryImpl registry = repository.getRegistry(registryName);
final EnumeratedTypeImpl type = registry.getOptionalType(Name.of(typeName),
EnumeratedTypeImpl.class)
.orElseThrow();
final EnumeratedValueImpl.Builder value =
EnumeratedValueImpl.builder()
.literal(literal)
.shortLiteral(shortLiteral)
.ordinal(ordinal);
// We can not use EnumeratedValueImpl.builder().synonyms(...)
// The owner is not set, and the builder can not find NamingConvention itself
for (final String key : synonyms.getKeys()) {
final NamingConvention convention = registry.getNamingConvention(key);
value.synonym(convention, StringValue.of(synonyms.get(key)));
}
importDescriptions(row, value);
type.addValue(value.build());
}
}
}
private class ItemUsagesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final Path dictionaryPath = row.getDataOrNull(Templates.DICTIONARY_PATH);
final String name = row.getDataOrNull(Templates.ITEM_NAME);
final DItemUsage usage = row.getDataOrNull(Templates.ITEM_USAGE);
final AbstractDictionaryImpl dictionary = repository.getDictionary(dictionaryPath);
dictionary.setItemUsage(name, usage);
}
}
}
private class NamingConventionsImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final String name = row.getDataOrNull(Templates.NAME);
final RegistryImpl registry = repository.getRegistry(registryName);
final NamingConventionImpl.Builder convention = registry.namingConvention()
.name(name);
importDescriptions(row, convention);
convention.build();
}
}
}
private class PoliciesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String name = row.getDataOrNull(Templates.NAME);
final Path parentPath = row.getDataOrNull(Templates.PARENT_PATH);
final Expression context = row.getData(Templates.CONTEXT, Expression.TRUE);
final String writingRules = row.getDataOrNull(Templates.WRITING_RULES);
final AbstractDictionaryImpl parent = repository.getDictionary(parentPath);
final PolicyImpl policy = parent.policy().name(name).build();
policy.setContextExpression(context);
for (final String rule : writingRules.split("\n")) {
if (!rule.isBlank()) {
policy.setWritingRuleEnabled(rule, true);
}
}
importDescriptions(row, policy);
}
}
}
private class PropertiesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final String typeName = row.getDataOrNull(Templates.PROPERTY_TYPE_NAME);
final String name = row.getDataOrNull(Templates.NAME);
final MetaData synonyms = row.getDataOrNull(Templates.SYNONYMS);
final Integer ordinal = row.getData(Templates.ORDINAL, 0);
final RegistryImpl registry = repository.getRegistry(registryName);
final PropertyImpl.Builder property = registry.property()
.name(name)
.synonyms(synonyms)
.type(typeName)
.ordinal(ordinal);
importDescriptions(row, property);
property.build();
}
}
}
private class RegistriesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String name = row.getDataOrNull(Templates.NAME);
final String prefix = row.getDataOrNull(Templates.PREFIX);
final String parentPaths = row.getDataOrNull(Templates.PARENTS_PATHS);
final Expression context = row.getData(Templates.CONTEXT, Expression.TRUE);
final List parents = new ArrayList<>();
final String writingRules = row.getDataOrNull(Templates.WRITING_RULES);
if (parentPaths != null && !parentPaths.isEmpty()) {
for (final String parentPath : parentPaths.split("\n")) {
final AbstractDictionaryImpl parent = repository.getDictionary(parentPath);
parents.add(parent);
}
}
final RegistryImpl registry = repository.registry()
.name(name)
.prefix(prefix)
.parents(parents)
.build();
if (registry.hasParents()) {
registry.setContextExpression(context);
}
for (final String rule : writingRules.split("\n")) {
if (!rule.isBlank()) {
registry.setWritingRuleEnabled(rule, true);
}
}
importDescriptions(row, registry);
}
}
}
private class TypesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final String name = row.getDataOrNull(Templates.NAME);
final MetaData synonyms = row.getDataOrNull(Templates.SYNONYMS);
final String registryName = row.getDataOrNull(Templates.REGISTRY_NAME);
final S1000DPropertyType propertyType =
row.getData(Templates.S1000D_PROPERTY_TYPE, S1000DPropertyType.UNDEFINED);
final S1000DProductIdentifier productIdentifier =
row.getData(Templates.S1000D_PRODUCT_IDENTIFIER, propertyType.getDefaultIdentifier());
final Boolean frozen = row.getData(Templates.FROZEN, false);
final RegistryImpl registry = repository.getRegistry(registryName);
final AbstractTypeImpl.Builder> type;
if (row.getTemplate() == Templates.BOOLEAN_TYPES) {
final Boolean defaultValue = row.getData(Templates.BOOLEAN_TYPE_DEFAULT_VALUE, null);
type = registry.booleanType()
.name(name)
.defaultValue(defaultValue == null ? null : BooleanValue.of(defaultValue));
} else if (row.getTemplate() == Templates.ENUMERATED_TYPES) {
final String defaultValue = row.getData(Templates.ENUMERATED_TYPE_DEFAULT_VALUE, null);
type = registry.enumeratedType()
.name(name)
.defaultValue(defaultValue == null ? null : StringValue.of(defaultValue))
.hackDisableDefaultValueCheck()
.frozen(frozen);
} else if (row.getTemplate() == Templates.INTEGER_TYPES) {
final IntegerSet domain = row.getData(Templates.INTEGER_DOMAIN, null);
final Integer defaultValue = row.getData(Templates.INTEGER_TYPE_DEFAULT_VALUE, null);
type = registry.integerType()
.name(name)
.defaultValue(defaultValue == null ? null : IntegerValue.of(defaultValue))
.frozen(frozen)
.domain(domain);
} else if (row.getTemplate() == Templates.REAL_TYPES) {
final RealSet domain = row.getData(Templates.REAL_DOMAIN, null);
final Double defaultValue = row.getData(Templates.REAL_TYPE_DEFAULT_VALUE, null);
type = registry.realType()
.name(name)
.defaultValue(defaultValue == null ? null : RealValue.of(defaultValue))
.frozen(frozen)
.domain(domain);
} else if (row.getTemplate() == Templates.PATTERN_TYPES) {
final String pattern = row.getDataOrNull(Templates.PATTERN);
final String defaultValue = row.getData(Templates.PATTERN_TYPE_DEFAULT_VALUE, null);
type = registry.patternType()
.name(name)
.defaultValue(defaultValue == null ? null : StringValue.of(defaultValue))
.frozen(frozen)
.pattern(pattern);
} else {
throw new ImplementationException();
}
type.synonyms(synonyms)
.s1000DPropertyType(propertyType)
.s1000DProductIdentifier(productIdentifier);
importDescriptions(row, type);
type.build();
}
}
}
private class TypeUsagesImporter implements SheetImporter {
@Override
public void importRow(ImportRow row,
IssuesHandler issuesHandler) {
traceImport(row);
if (row.canBeProcessed() && row.getAction(defaultAction) != ImportAction.IGNORE) {
final Path dictionaryPath = row.getDataOrNull(Templates.DICTIONARY_PATH);
final String name = row.getDataOrNull(Templates.TYPE_NAME);
final DItemUsage usage = row.getDataOrNull(Templates.TYPE_USAGE);
final AbstractDictionaryImpl dictionary = repository.getDictionary(dictionaryPath);
dictionary.setTypeUsage(name, usage);
}
}
}
}
public static final class Writer {
private final ImpExCatalog catalog = new ImpExCatalog();
private RepositoryImpl repository = null;
private Writer() {
// Register in alphabetical order
catalog.register(Templates.ALIASES, new AliasesExporter());
catalog.register(Templates.ASSERTIONS, new AssertionsExporter());
catalog.register(Templates.BOOLEAN_TYPES, new TypesExporter());
catalog.register(Templates.CONSTRAINTS, new ConstraintsExporter());
catalog.register(Templates.ENUMERATED_TYPES, new TypesExporter());
catalog.register(Templates.ENUMERATED_ORDERS, new EnumeratedOrdersExporter());
catalog.register(Templates.ENUMERATED_VALUES, new EnumeratedValuesExporter());
catalog.register(Templates.INTEGER_TYPES, new TypesExporter());
catalog.register(Templates.ITEM_USAGES, new ItemUsagesExporter());
catalog.register(Templates.NAMING_CONVENTIONS, new NamingConventionsExporter());
catalog.register(Templates.PATTERN_TYPES, new TypesExporter());
catalog.register(Templates.POLICIES, new PoliciesExporter());
catalog.register(Templates.PROPERTIES, new PropertiesExporter());
catalog.register(Templates.REAL_TYPES, new TypesExporter());
catalog.register(Templates.REGISTRIES, new RegistriesExporter());
catalog.register(Templates.TYPE_USAGES, new TypeUsagesExporter());
}
private void writeInt(RepositoryImpl repository,
File file,
ImpExFactoryFeatures features,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
this.repository = repository;
final ImpExFactory factory = new ImpExFactory(features);
final Exporter exporter = factory.createExporter(file);
// Register using the best order for future import
// Warning: we know that import may fail because a topological order should be used for export, or import should
// delay some actions
exporter.exportData(file,
catalog.getTemplatesAsList(Templates.REGISTRIES.getName(),
Templates.NAMING_CONVENTIONS.getName(),
Templates.BOOLEAN_TYPES.getName(),
Templates.INTEGER_TYPES.getName(),
Templates.REAL_TYPES.getName(),
Templates.ENUMERATED_TYPES.getName(),
Templates.ENUMERATED_VALUES.getName(),
Templates.ENUMERATED_ORDERS.getName(),
Templates.PATTERN_TYPES.getName(),
Templates.PROPERTIES.getName(),
Templates.ALIASES.getName(),
Templates.POLICIES.getName(),
Templates.CONSTRAINTS.getName(),
Templates.ASSERTIONS.getName(),
Templates.TYPE_USAGES.getName(),
Templates.ITEM_USAGES.getName())
.stream().map(SheetTemplateInstance::replace).toList(),
catalog.createWorkbookExporterFor(Templates.REGISTRIES.getName(),
Templates.NAMING_CONVENTIONS.getName(),
Templates.BOOLEAN_TYPES.getName(),
Templates.INTEGER_TYPES.getName(),
Templates.REAL_TYPES.getName(),
Templates.ENUMERATED_TYPES.getName(),
Templates.ENUMERATED_VALUES.getName(),
Templates.ENUMERATED_ORDERS.getName(),
Templates.PATTERN_TYPES.getName(),
Templates.PROPERTIES.getName(),
Templates.ALIASES.getName(),
Templates.POLICIES.getName(),
Templates.CONSTRAINTS.getName(),
Templates.ASSERTIONS.getName(),
Templates.TYPE_USAGES.getName(),
Templates.ITEM_USAGES.getName()),
issuesHandler,
controller);
}
public static void write(RepositoryImpl repository,
File file,
ImpExFactoryFeatures features,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
final Writer writer = new Writer();
writer.writeInt(repository, file, features, issuesHandler, controller);
}
public static void write(RepositoryImpl repository,
File file,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
write(repository, file, ImpExFactoryFeatures.FASTEST, issuesHandler, controller);
}
public static void write(RepositoryImpl repository,
File file,
ImpExFactoryFeatures features) throws IOException {
final IssuesCollector issuesHandler = new IssuesCollector<>();
final ProgressController controller = ProgressController.VOID;
write(repository, file, features, issuesHandler, controller);
}
public static void write(RepositoryImpl repository,
File file) throws IOException {
write(repository, file, ImpExFactoryFeatures.FASTEST);
}
private abstract static class DefaultSheetExporter implements SheetExporter {
protected int done = 0;
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
}
@Override
public void endSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
// Ignore
}
}
private static void setAction(ExportRow row) {
row.setData(row.getTemplate().getActionColumn(), ImportAction.CREATE);
}
private static void exportDescriptions(ExportRow row,
Described described) {
row.setData(Templates.DESCRIPTION_EN, described.getDescription().getContent(Locale.ENGLISH));
row.setData(Templates.DESCRIPTION_FR, described.getDescription().getContent(Locale.FRENCH));
}
private class AliasesExporter extends DefaultSheetExporter {
private final List> aliases = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort aliases
for (final AliasImpl alias : IterableUtils.toSortedList(registry.getDeclaredAliases(), Named.NAME_COMPARATOR)) {
aliases.add(Tuple2.of(registry, alias));
}
}
}
@Override
public int getNumberOfRemainingRows() {
return aliases.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = aliases.get(done).value0();
final AliasImpl alias = aliases.get(done).value1();
setAction(row);
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.NAME, alias.getName().removePrefix().getNonEscapedLiteral());
row.setData(Templates.SYNONYMS, alias.getNames().encode());
row.setData(Templates.ALIAS_EXPRESSION, alias.getExpression());
row.setData(Templates.ORDINAL, alias.getOrdinal());
exportDescriptions(row, alias);
done++;
}
}
private class AssertionsExporter extends DefaultSheetExporter {
private final List> assertions = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Sort dictionaries
for (final AbstractDictionaryImpl dictionary : IterableUtils.toSortedList(repository.getDictionaries(),
Dictionary.PATH_COMPARATOR)) {
// Sort assertions
for (final Assertion assertion : IterableUtils.toSortedList(dictionary.getAssertions(UserDefinedAssertion.class),
Assertion.KIND_EXPRESSION_COMPARATOR)) {
assertions.add(Tuple2.of(dictionary, assertion));
}
}
}
@Override
public int getNumberOfRemainingRows() {
return assertions.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final AbstractDictionaryImpl dictionary = assertions.get(done).value0();
final Assertion assertion = assertions.get(done).value1();
setAction(row);
row.setData(Templates.DICTIONARY_PATH, dictionary.getPath());
row.setData(Templates.ASSERTION_EXPRESSION, assertion.getExpression());
done++;
}
}
private class ConstraintsExporter extends DefaultSheetExporter {
private final List> constraints = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
for (final AbstractDictionaryImpl dictionary : repository.getDictionaries()) {
for (final Constraint constraint : dictionary.getConstraints()) {
constraints.add(Tuple2.of(dictionary, constraint));
}
}
}
@Override
public int getNumberOfRemainingRows() {
return constraints.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final AbstractDictionaryImpl dictionary = constraints.get(done).value0();
final Constraint constraint = constraints.get(done).value1();
setAction(row);
row.setData(Templates.DICTIONARY_PATH, dictionary.getPath());
row.setData(Templates.CONSTRAINT_TYPE_NAME, constraint.getTypeName());
row.setData(Templates.CONSTRAINT_PARAMS, constraint.getParams());
exportDescriptions(row, constraint);
done++;
}
}
private class EnumeratedOrdersExporter extends DefaultSheetExporter {
private final List> edges =
new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort types
for (final AbstractTypeImpl type : IterableUtils.toSortedList(registry.getDeclaredTypes(),
Named.NAME_COMPARATOR)) {
if (type instanceof final EnumeratedTypeImpl t) {
for (final Tuple2 edge : t.getOrderConstraints()) {
edges.add(Tuple4.of(registry, t, edge.value0(), edge.value1()));
}
}
}
}
}
@Override
public int getNumberOfRemainingRows() {
return edges.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = edges.get(done).value0();
final EnumeratedType type = edges.get(done).value1();
final EnumeratedValue inf = edges.get(done).value2();
final EnumeratedValue sup = edges.get(done).value3();
setAction(row);
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.ENUMERATED_TYPE_NAME, type.getName().getLocal().getNonEscapedLiteral());
row.setData(Templates.LITERAL_INF, inf.getLiteral().getNonEscapedLiteral());
row.setData(Templates.LITERAL_SUP, sup.getLiteral().getNonEscapedLiteral());
done++;
}
}
private class EnumeratedValuesExporter extends DefaultSheetExporter {
private final List> values = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort types
for (final AbstractTypeImpl type : IterableUtils.toSortedList(registry.getDeclaredTypes(),
Named.NAME_COMPARATOR)) {
if (type instanceof final EnumeratedTypeImpl t) {
// Enumeration values are sorted
for (final EnumeratedValueImpl value : t.getValues()) {
values.add(Tuple3.of(registry, t, value));
}
}
}
}
}
@Override
public int getNumberOfRemainingRows() {
return values.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = values.get(done).value0();
final EnumeratedType type = values.get(done).value1();
final EnumeratedValueImpl value = values.get(done).value2();
setAction(row);
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.ENUMERATED_TYPE_NAME, type.getName().getLocal().getNonEscapedLiteral());
row.setData(Templates.LITERAL, value.getLiteral().getNonEscapedLiteral());
row.setData(Templates.SYNONYMS, value.getLiterals().encode());
row.setData(Templates.SHORT_LITERAL, value.getShortLiteral().getNonEscapedLiteral());
row.setData(Templates.ORDINAL, value.getOrdinal());
exportDescriptions(row, value);
done++;
}
}
private class ItemUsagesExporter extends DefaultSheetExporter {
private final List> items = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Sort dictionaries
for (final AbstractDictionaryImpl dictionary : IterableUtils.toSortedList(repository.getDictionaries(),
Dictionary.PATH_COMPARATOR)) {
// Sort items
for (final NamedDItem item : IterableUtils.toSortedList(dictionary.getAllItems(),
Named.NAME_COMPARATOR)) {
final DItemUsage usage = dictionary.getItemUsage(item);
if (usage != null) {
items.add(Tuple3.of(dictionary, item, usage));
}
}
}
}
@Override
public int getNumberOfRemainingRows() {
return items.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final AbstractDictionaryImpl dictionary = items.get(done).value0();
final NamedDItem item = items.get(done).value1();
final DItemUsage usage = items.get(done).value2();
setAction(row);
row.setData(Templates.DICTIONARY_PATH, dictionary.getPath());
row.setData(Templates.ITEM_NAME, item.getName().getNonEscapedLiteral());
row.setData(Templates.ITEM_USAGE, usage);
done++;
}
}
private class NamingConventionsExporter extends DefaultSheetExporter {
private final List> conventions = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort properties
for (final NamingConvention convention : IterableUtils.toSortedList(registry.getDeclaredNamingConventions(),
Named.NAME_COMPARATOR)) {
conventions.add(Tuple2.of(registry, convention));
}
}
}
@Override
public int getNumberOfRemainingRows() {
return conventions.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = conventions.get(done).value0();
final NamingConvention convention = conventions.get(done).value1();
setAction(row);
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.NAME, convention.getName().removePrefix().getNonEscapedLiteral());
exportDescriptions(row, convention);
done++;
}
}
private class PoliciesExporter extends DefaultSheetExporter {
private final List policies = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Sort dictionaries
for (final AbstractDictionaryImpl dictionary : IterableUtils.toSortedList(repository.getDictionaries(),
Dictionary.PATH_COMPARATOR)) {
if (dictionary instanceof final PolicyImpl policy) {
policies.add(policy);
}
}
}
@Override
public int getNumberOfRemainingRows() {
return policies.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final PolicyImpl policy = policies.get(done);
setAction(row);
row.setData(Templates.PARENT_PATH, policy.getOwner().getPath());
row.setData(Templates.NAME, policy.getName());
if (!policy.getContextExpression().isTrue()) {
row.setData(Templates.CONTEXT, policy.getContextExpression());
}
exportDescriptions(row, policy);
row.setData(Templates.WRITING_RULES,
policy.getWritingRuleNames()
.stream()
.sorted()
.collect(Collectors.joining("\n")));
done++;
}
}
private class PropertiesExporter extends DefaultSheetExporter {
private final List> properties = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort properties
for (final PropertyImpl property : IterableUtils.toSortedList(registry.getDeclaredProperties(),
Named.NAME_COMPARATOR)) {
properties.add(Tuple2.of(registry, property));
}
}
}
@Override
public int getNumberOfRemainingRows() {
return properties.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = properties.get(done).value0();
final PropertyImpl property = properties.get(done).value1();
setAction(row);
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.S1000D_PROPERTY_ID, property.getS1000DId());
row.setData(Templates.NAME, property.getName().removePrefix().getNonEscapedLiteral());
row.setData(Templates.SYNONYMS, property.getNames().encode());
row.setData(Templates.PROPERTY_TYPE_NAME, property.getType().getName().getProtectedLiteral());
row.setData(Templates.ORDINAL, property.getOrdinal());
exportDescriptions(row, property);
done++;
}
}
private class RegistriesExporter extends DefaultSheetExporter {
@Override
public int getNumberOfRemainingRows() {
return repository.getRegistries().size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = repository.getRegistries().get(done);
setAction(row);
row.setData(Templates.NAME, registry.getName());
if (!registry.getContextExpression().isTrue()) {
row.setData(Templates.CONTEXT, registry.getContextExpression());
}
row.setData(Templates.PREFIX, registry.getPrefix().map(SName::toString).orElse(null));
row.setData(Templates.PARENTS_PATHS,
registry.getParents()
.stream()
.map(AbstractDictionaryImpl::getPath)
.map(Path::toString)
.collect(Collectors.joining("\n")));
row.setData(Templates.WRITING_RULES,
registry.getWritingRuleNames()
.stream()
.sorted()
.collect(Collectors.joining("\n")));
exportDescriptions(row, registry);
done++;
}
}
private class TypesExporter extends DefaultSheetExporter {
private final List> types = new ArrayList<>();
private boolean match(S1000DType type,
SheetTemplate template) {
if (template == Templates.BOOLEAN_TYPES) {
return type instanceof BooleanType;
} else if ((template == Templates.INTEGER_TYPES)) {
return type instanceof IntegerType;
} else if ((template == Templates.REAL_TYPES)) {
return type instanceof RealType;
} else if ((template == Templates.PATTERN_TYPES)) {
return type instanceof PatternType;
} else if ((template == Templates.ENUMERATED_TYPES)) {
return type instanceof EnumeratedType;
} else {
return false;
}
}
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Registries are sorted
for (final RegistryImpl registry : repository.getRegistries()) {
// Sort types
for (final AbstractTypeImpl type : IterableUtils.toSortedList(registry.getDeclaredTypes(),
Named.NAME_COMPARATOR)) {
if (match(type, templateInstance.getTemplate())) {
types.add(Tuple2.of(registry, type));
}
}
}
}
@Override
public int getNumberOfRemainingRows() {
return types.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final RegistryImpl registry = types.get(done).value0();
final AbstractTypeImpl type = types.get(done).value1();
setAction(row);
row.setData(Templates.NAME, type.getName().getLocal().getNonEscapedLiteral());
row.setData(Templates.SYNONYMS, type.getNames().encode());
row.setData(Templates.REGISTRY_NAME, registry.getName());
row.setData(Templates.S1000D_TYPE_ID, type.getS1000DId());
row.setData(Templates.S1000D_PRODUCT_IDENTIFIER, type.getS1000DProductIdentifier());
row.setData(Templates.S1000D_PROPERTY_TYPE, type.getS1000DPropertyType());
if (type instanceof final ModifiableType t) {
row.setData(Templates.FROZEN, t.isFrozen());
}
exportDescriptions(row, type);
if (type instanceof final BooleanTypeImpl t && t.hasDefaultValue()) {
row.setData(Templates.BOOLEAN_TYPE_DEFAULT_VALUE,
t.getDefaultValue().orElseThrow().getValue());
}
if (type instanceof final EnumeratedTypeImpl t && t.hasDefaultValue()) {
row.setData(Templates.ENUMERATED_TYPE_DEFAULT_VALUE,
t.getDefaultValue().orElseThrow().getNonEscapedLiteral());
}
if (type instanceof final IntegerTypeImpl t) {
row.setData(Templates.INTEGER_DOMAIN, t.getDomain());
if (t.hasDefaultValue()) {
row.setData(Templates.INTEGER_TYPE_DEFAULT_VALUE,
t.getDefaultValue().orElseThrow().getNumber());
}
}
if (type instanceof final RealTypeImpl t) {
row.setData(Templates.REAL_DOMAIN, t.getDomain());
if (t.hasDefaultValue()) {
row.setData(Templates.REAL_TYPE_DEFAULT_VALUE,
t.getDefaultValue().orElseThrow().getNumber());
}
}
if (type instanceof final PatternTypeImpl t) {
row.setData(Templates.PATTERN, t.getPattern().pattern());
if (t.hasDefaultValue()) {
row.setData(Templates.PATTERN_TYPE_DEFAULT_VALUE,
t.getDefaultValue().orElseThrow().getNonEscapedLiteral());
}
}
done++;
}
}
private class TypeUsagesExporter extends DefaultSheetExporter {
private final List> types = new ArrayList<>();
@Override
public void beginSheetExport(SheetTemplateInstance templateInstance,
IssuesHandler issuesHandler) {
done = 0;
// Sort dictionaries
for (final AbstractDictionaryImpl dictionary : IterableUtils.toSortedList(repository.getDictionaries(),
Dictionary.PATH_COMPARATOR)) {
// Sort types
for (final Type type : IterableUtils.toSortedList(dictionary.getRegistry().getDeclaredTypes(),
Named.NAME_COMPARATOR)) {
final DItemUsage usage = dictionary.getTypeUsage(type);
if (usage != null) {
types.add(Tuple3.of(dictionary, type, usage));
}
}
}
}
@Override
public int getNumberOfRemainingRows() {
return types.size() - done;
}
@Override
public void exportRow(ExportRow row,
IssuesHandler issuesHandler) {
final AbstractDictionaryImpl dictionary = types.get(done).value0();
final Type type = types.get(done).value1();
final DItemUsage usage = types.get(done).value2();
setAction(row);
row.setData(Templates.DICTIONARY_PATH, dictionary.getPath());
row.setData(Templates.TYPE_NAME, type.getName().getNonEscapedLiteral());
row.setData(Templates.TYPE_USAGE, usage);
done++;
}
}
}
}