All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cdc.applic.dictionaries.impl.bindings.DictionariesBindingImpl Maven / Gradle / Ivy
package cdc.applic.dictionaries.impl.bindings;
import java.io.PrintStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import cdc.applic.dictionaries.bindings.AliasAliasBinding;
import cdc.applic.dictionaries.bindings.BindingRole;
import cdc.applic.dictionaries.bindings.DItemsBinding;
import cdc.applic.dictionaries.bindings.DictionariesBinding;
import cdc.applic.dictionaries.bindings.PropertyPropertyBinding;
import cdc.applic.dictionaries.bindings.TypesBinding;
import cdc.applic.dictionaries.impl.AbstractDictionaryImpl;
import cdc.applic.dictionaries.impl.RepositoryImpl;
import cdc.applic.dictionaries.types.Type;
import cdc.applic.expressions.literals.Name;
import cdc.util.debug.ControlledPrintable;
import cdc.util.debug.Verbosity;
import cdc.util.lang.Checks;
import cdc.util.lang.ImplementationException;
import cdc.util.lang.NotFoundException;
import cdc.util.paths.Path;
/**
* Dictionary/Dictionary binding implementation.
*
* @author Damien Carbonne
*/
public class DictionariesBindingImpl implements DictionariesBinding, ControlledPrintable {
private static final String BINDING = "binding";
private static final String SOURCE = "source";
private static final String TARGET = "target";
private final AbstractDictionaryImpl source;
private final AbstractDictionaryImpl target;
final Set typeBindings = new HashSet<>();
private final Map> typeKeyToTypeBinding = new HashMap<>();
private final Set itemBindings = new HashSet<>();
private final Map> nameForward = new HashMap<>();
private final Map> nameBackward = new HashMap<>();
private static record SourceTarget(Name source,
Name target) {
}
public DictionariesBindingImpl(Builder builder) {
this.source = Checks.isNotNull(builder.source, SOURCE);
this.target = Checks.isNotNull(builder.target, TARGET);
Checks.isTrue(this.source.getRepository() == this.target.getRepository(), "Repository mismatch");
}
B addTypesBinding(B binding) {
Checks.isNotNull(binding, BINDING);
typeBindings.add(binding);
final SourceTarget key = new SourceTarget(binding.getSourceType().getName(),
binding.getTargetType().getName());
typeKeyToTypeBinding.computeIfAbsent(key, k -> new HashSet<>()).add(binding);
return binding;
}
B addDItemsBinding(B binding) {
Checks.isNotNull(binding, "binding");
// Item name may contain prefix
// So we add bindings twice (even when there is no prefix)
nameForward.computeIfAbsent(binding.getDItem(BindingRole.SOURCE).getName(),
k -> new HashSet<>())
.add(binding);
nameForward.computeIfAbsent(binding.getDItem(BindingRole.SOURCE).getName().removePrefix(),
k -> new HashSet<>())
.add(binding);
nameBackward.computeIfAbsent(binding.getDItem(BindingRole.TARGET).getName(),
k -> new HashSet<>())
.add(binding);
nameBackward.computeIfAbsent(binding.getDItem(BindingRole.TARGET).getName().removePrefix(),
k -> new HashSet<>())
.add(binding);
itemBindings.add(binding);
return binding;
}
public BooleanBooleanBindingImpl.Builder booleanBooleanBinding() {
return BooleanBooleanBindingImpl.builder(this);
}
public BooleanEnumeratedBindingImpl.Builder booleanEnumeratedBinding() {
return BooleanEnumeratedBindingImpl.builder(this);
}
public BooleanIntegerBindingImpl.Builder booleanIntegerBinding() {
return BooleanIntegerBindingImpl.builder(this);
}
public EnumeratedBooleanBindingImpl.Builder enumeratedBooleanBinding() {
return EnumeratedBooleanBindingImpl.builder(this);
}
public EnumeratedEnumeratedBindingImpl.Builder enumeratedEnumeratedBinding() {
return EnumeratedEnumeratedBindingImpl.builder(this);
}
public EnumeratedIntegerBindingImpl.Builder enumeratedIntegerBinding() {
return EnumeratedIntegerBindingImpl.builder(this);
}
public IntegerBooleanBindingImpl.Builder integerBooleanBinding() {
return IntegerBooleanBindingImpl.builder(this);
}
public IntegerEnumeratedBindingImpl.Builder integerEnumeratedBinding() {
return IntegerEnumeratedBindingImpl.builder(this);
}
public IntegerIntegerBindingImpl.Builder integerIntegerBinding() {
return IntegerIntegerBindingImpl.builder(this);
}
public PatternPatternBindingImpl.Builder patternPatternBinding() {
return PatternPatternBindingImpl.builder(this);
}
public RealRealBindingImpl.Builder realRealBinding() {
return RealRealBindingImpl.builder(this);
}
public AliasAliasBindingImpl.Builder aliasAliasBinding() {
return AliasAliasBindingImpl.builder(this);
}
public PropertyPropertyBindingImpl.Builder propertyPropertyBinding() {
return PropertyPropertyBindingImpl.builder(this);
}
@Override
public AbstractDictionaryImpl getDictionary(BindingRole role) {
Checks.isNotNull(role, "role");
return role == BindingRole.SOURCE ? source : target;
}
@Override
public Set getTypesBindings() {
return typeBindings;
}
@Override
public Set getTypesBindings(Type sourceType,
Type targetType) {
final SourceTarget key = new SourceTarget(sourceType.getName(), targetType.getName());
return typeKeyToTypeBinding.getOrDefault(key, Collections.emptySet());
}
@Override
public Set getDItemBindings() {
return itemBindings;
}
@Override
public Set getDItemBindings(Name name,
BindingRole role) {
Checks.isNotNull(name, "name");
Checks.isNotNull(role, "role");
return role == BindingRole.SOURCE
? nameForward.getOrDefault(name, Collections.emptySet())
: nameBackward.getOrDefault(name, Collections.emptySet());
}
@Override
public AliasAliasBinding getAliasAliasBinding(Name name,
BindingRole role) {
final Set set = getDItemBindings(name, role);
if (set.isEmpty()) {
throw new NotFoundException(name + " has no associated bindings");
} else if (set.size() == 1) {
final DItemsBinding binding = set.iterator().next();
if (binding instanceof final AliasAliasBinding aab) {
return aab;
} else {
throw new NotFoundException(name + " is not an Alias name");
}
} else {
if (getDictionary(role).hasAlias(name)) {
throw new ImplementationException(name + " has several associated bindings.");
} else {
throw new NotFoundException(name + " is not an Alias name");
}
}
}
@Override
public Set getPropertyPropertyBindings(Name name,
BindingRole role) {
final Set set = getDItemBindings(name, role);
final Set result = new HashSet<>();
for (final DItemsBinding binding : set) {
if (binding instanceof final PropertyPropertyBinding x) {
result.add(x);
} else {
throw new NotFoundException(name + " is not associated to PropertyBinding");
}
}
return result;
}
@Override
public void print(PrintStream out,
int level,
Verbosity verbosity) {
indent(out, level);
out.println("Binding " + getDictionary(BindingRole.TARGET).getName() + " <<< " +
getDictionary(BindingRole.SOURCE).getName());
if (!getTypesBindings().isEmpty()) {
indent(out, level + 1);
out.println("Types " + getTypesBindings().size());
if (verbosity != Verbosity.ESSENTIAL) {
for (final TypesBinding binding : getTypesBindings()) {
((AbstractTypesBinding, ?, ?, ?>) binding).print(out, level + 2);
}
}
}
if (!getDItemBindings().isEmpty()) {
indent(out, level + 1);
out.println("Items " + getDItemBindings().size());
if (verbosity != Verbosity.ESSENTIAL) {
for (final DItemsBinding binding : getDItemBindings()) {
((AbstractDItemsBinding>) binding).print(out, level + 2);
}
}
}
}
// Do not use
public static Builder builder(RepositoryImpl repository) {
return new Builder(repository);
}
public static class Builder {
private final RepositoryImpl repository;
private AbstractDictionaryImpl source;
private AbstractDictionaryImpl target;
protected Builder(RepositoryImpl repository) {
this.repository = Checks.isNotNull(repository, "repository");
}
public Builder source(AbstractDictionaryImpl source) {
Checks.isNotNull(source, SOURCE);
this.source = source;
return this;
}
public Builder source(Path source) {
Checks.isNotNull(source, SOURCE);
return source(repository.getDictionary(source));
}
public Builder source(String source) {
Checks.isNotNull(source, SOURCE);
return source(Path.of(source));
}
public Builder target(AbstractDictionaryImpl target) {
Checks.isNotNull(target, TARGET);
this.target = target;
return this;
}
public Builder target(Path target) {
Checks.isNotNull(target, TARGET);
return target(repository.getDictionary(target));
}
public Builder target(String target) {
Checks.isNotNull(target, TARGET);
return target(Path.of(target));
}
public DictionariesBindingImpl build() {
return repository.addBinding(new DictionariesBindingImpl(this));
}
public RepositoryImpl back() {
build();
return repository;
}
}
}