cdc.applic.dictionaries.edit.EnDictionary Maven / Gradle / Ivy
Show all versions of cdc-applic-dictionaries-edit Show documentation
package cdc.applic.dictionaries.edit;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import cdc.applic.dictionaries.DItemUsage;
import cdc.applic.dictionaries.WritingRuleNameSupplier;
import cdc.applic.expressions.Expression;
import cdc.graphs.core.SlimGraph;
import cdc.util.lang.Checks;
import cdc.util.lang.Introspection;
public abstract class EnDictionary extends EnAbstractOwnedElement
implements EnNameItem, EnDictionaryOwner {
private String name;
private Expression contextExpression;
private final Map, DItemUsage> typeToUsage = new HashMap<>();
private final Map, DItemUsage> itemToUsage = new HashMap<>();
private final Set writingRuleNames = new HashSet<>();
protected EnDictionary(Builder, ?, O> builder) {
super(builder);
this.name = builder.name;
this.contextExpression = builder.contextExpression;
for (final Map.Entry entry : builder.typeIdToUsage.entrySet()) {
final DItemUsage usage = entry.getValue();
if (usage != null) {
final EnRef typeRef = EnRef.of(this, EnType.class, entry.getKey());
typeToUsage.put(typeRef, usage);
}
}
for (final Map.Entry entry : builder.itemIdToUsage.entrySet()) {
final DItemUsage usage = entry.getValue();
if (usage != null) {
final EnRef itemRef = EnRef.of(this, EnNamedDItem.class, entry.getKey());
itemToUsage.put(itemRef, usage);
}
}
this.writingRuleNames.addAll(builder.writingRulesNames);
}
@Override
public final void setName(String name) {
this.name = name;
fireSemanticChange(EnNames.NAME);
}
@Override
public final String getName() {
return name;
}
public abstract EnRegistry getRegistry();
public List getPolicies() {
return getChildren(EnPolicy.class);
}
/**
* @param fail If a parent can not be resolved, an exception will be thrown.
* @return A list (possibly empty) of parents.
*/
public abstract List extends EnDictionary>> getParents(boolean fail);
/**
* Returns a set of all ancestors.
*
* If there is a cycle, result may contain descendants.
*
* @param fail If a parent can not be resolved, an exception will be thrown.
* @return A set of all ancestors, including itself.
*/
public Set> getAllAncestors(boolean fail) {
return SlimGraph.computeTransitiveClosure(this,
n -> n.getParents(fail));
}
/**
* @param fail If a parent can not be resolved, an exception will be thrown.
* @return {@code true} if this dictionary is member of a dependency cycle.
*/
public boolean isCycleMember(boolean fail) {
return SlimGraph.nodeIsCycleMember(this,
n -> Introspection.uncheckedCast(n.getParents(fail)));
}
public final Expression getContextExpression() {
return contextExpression;
}
public final void setContextExpression(Expression expression) {
this.contextExpression = expression;
fireSemanticChange(EnNames.CONTEXT);
}
public final void setContextExpression(String expression) {
setContextExpression(Expression.of(expression, false));
}
public final List getConstraints() {
return getChildren(EnConstraint.class);
}
public final List getUserDefinedAssertions() {
return getChildren(EnUserDefinedAssertion.class);
}
public final Set> getTypeToUsageKeys() {
return typeToUsage.keySet();
}
public final DItemUsage getTypeUsage(EnRef typeRef) {
return typeToUsage.get(typeRef);
}
public final void setTypeUsage(String typeId,
DItemUsage usage) {
Checks.isNotNull(typeId, EnNames.TYPE_ID);
final EnRef typeRef = EnRef.of(this, EnType.class, typeId);
if (usage == null) {
typeToUsage.remove(typeRef);
} else {
typeToUsage.put(typeRef, usage);
}
fireSemanticChange(EnNames.TYPE_USAGE);
}
public final void setTypeUsage(EnType type,
DItemUsage usage) {
Checks.isNotNull(type, EnNames.TYPE);
setTypeUsage(type.getId(), usage);
}
public final Set> getItemToUsageKeys() {
return itemToUsage.keySet();
}
public final DItemUsage getItemUsage(EnRef itemRef) {
return itemToUsage.get(itemRef);
}
public final void setItemUsage(String itemId,
DItemUsage usage) {
Checks.isNotNull(itemId, EnNames.ITEM_ID);
final EnRef ref = EnRef.of(this, EnNamedDItem.class, itemId);
if (usage == null) {
itemToUsage.remove(ref);
} else {
itemToUsage.put(ref, usage);
}
fireSemanticChange(EnNames.ITEM_USAGE);
}
public final void setItemUsage(EnNamedDItem item,
DItemUsage usage) {
Checks.isNotNull(item, EnNames.ITEM);
setItemUsage(item.getId(), usage);
}
public final Set getEnabledWritingRules() {
return writingRuleNames;
}
public final void setWritingRuleEnabled(String name,
boolean enabled) {
Checks.isNotNull(name, EnNames.NAME);
if (enabled) {
writingRuleNames.add(name);
} else {
writingRuleNames.remove(name);
}
fireWritingChange(EnNames.WRITING_RULE);
}
public final void setWritingRuleEnabled(WritingRuleNameSupplier supplier,
boolean enabled) {
Checks.isNotNull(supplier, EnNames.SUPPLIER);
setWritingRuleEnabled(supplier.getRuleName(), enabled);
}
public final EnPolicy.Builder policy() {
return EnPolicy.builder(this);
}
public final EnConstraint.Builder constraint() {
return EnConstraint.builder(this);
}
public final EnUserDefinedAssertion.Builder assertion() {
return EnUserDefinedAssertion.builder(this);
}
public abstract static class Builder,
E extends EnDictionary,
P extends EnDictionaryOwner>
extends EnAbstractOwnedElement.Builder
implements EnNameBuilding {
private String name;
private Expression contextExpression = Expression.TRUE;
private final Map typeIdToUsage = new HashMap<>();
private final Map itemIdToUsage = new HashMap<>();
private final Set writingRulesNames = new HashSet<>();
protected Builder(P parent) {
super(parent);
}
@Override
public final B name(String name) {
this.name = name;
return self();
}
public final B contextExpression(Expression expression) {
this.contextExpression = expression;
return self();
}
public final B contextExpression(String expression) {
return contextExpression(Expression.of(expression, false));
}
public final B typeIdUsage(String typeId,
DItemUsage usage) {
this.typeIdToUsage.put(typeId, usage);
return self();
}
public final B typeUsage(EnType type,
DItemUsage usage) {
return typeIdUsage(type.getId(), usage);
}
public final B itemIdUsage(String itemId,
DItemUsage usage) {
this.itemIdToUsage.put(itemId, usage);
return self();
}
public final B itemUsage(EnNamedDItem item,
DItemUsage usage) {
return itemIdUsage(item.getId(), usage);
}
public final B writingRuleNames(Set names) {
this.writingRulesNames.clear();
this.writingRulesNames.addAll(names);
return self();
}
public final B writingRuleNames(String... names) {
return writingRuleNames(Set.of(names));
}
}
}