Last active
April 12, 2018 18:54
-
-
Save sebge2emasphere/1b09af1695c23f4ceebabf51ef3b5049 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.emasphere.operation.query.model.definition.matrix.dimension; | |
import com.emasphere.operation.injection.model.CodeLabel; | |
import com.emasphere.operation.query.model.SimpleRegexUtils; | |
import com.fasterxml.jackson.annotation.JsonCreator; | |
import com.fasterxml.jackson.annotation.JsonIgnore; | |
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
import com.fasterxml.jackson.annotation.JsonProperty; | |
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | |
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; | |
import java.io.Serializable; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.function.BiFunction; | |
import java.util.function.Consumer; | |
import java.util.regex.Pattern; | |
import java.util.regex.PatternSyntaxException; | |
import static java.util.Arrays.*; | |
import static java.util.Collections.*; | |
/** | |
* The {@link MatrixDimensionDefinition dimension} is based on hard-coded range of text values. | |
* | |
* @author Sebastien Gerard | |
*/ | |
@JsonDeserialize(builder = MatrixTextRangeValuesDimensionDefinition.Builder.class) | |
public class MatrixTextRangeValuesDimensionDefinition implements MatrixDimensionDefinition { | |
/** | |
* Returns a new empty {@link Builder builder}. | |
*/ | |
public static MatrixTextRangeValuesDimensionDefinition.Builder matrixTextRangeValuesDimensionDefinition() { | |
return new Builder(); | |
} | |
/** | |
* Returns a new {@link Group text group}. | |
*/ | |
public static Group textGroup(String name, List<String> entries) { | |
return textGroup(Type.STRICT_MATCH, name, entries); | |
} | |
/** | |
* Returns a new {@link Group text group}. | |
*/ | |
public static Group textGroup(String name, String... entries) { | |
return textGroup(name, asList(entries)); | |
} | |
/** | |
* Returns a new {@link Group text group}. | |
*/ | |
public static Group textGroup(Type type, String name, List<String> entries) { | |
return new Group(entries, type, name); | |
} | |
/** | |
* Returns a new {@link Group text group}. | |
*/ | |
public static Group textGroup(Type type, String name, String... entries) { | |
return textGroup(type, name, asList(entries)); | |
} | |
private final CodeLabel valueReference; | |
private final List<Group> textGroups; | |
private MatrixTextRangeValuesDimensionDefinition(Builder builder) { | |
valueReference = builder.valueReference; | |
textGroups = unmodifiableList(builder.textGroups); | |
} | |
@Override | |
public CodeLabel getValueReference() { | |
return valueReference; | |
} | |
@Override | |
public DimensionType getType() { | |
return DimensionType.TEXT_RANGE_VALUES; | |
} | |
@Override | |
public <T> T accept(MatrixDimensionDefinition.Visitor<T> visitor) { | |
if (visitor instanceof Visitor) { | |
return ((Visitor<T>) visitor).visitMatrixTextRangeValuesDimension(this); | |
} else { | |
return visitor.visitMatrixDimension(this); | |
} | |
} | |
/** | |
* Returns {@link Group groups} of this dimension. Dimension values are grouped by range and associated to a name. | |
*/ | |
public List<Group> getTextGroups() { | |
return textGroups; | |
} | |
/** | |
* Group of text values. | |
*/ | |
public static final class Group implements Serializable { | |
private final List<String> values; | |
private final Type type; | |
private final String name; | |
@JsonCreator | |
public Group(@JsonProperty("entries") List<String> values, | |
@JsonProperty("type") Type type, | |
@JsonProperty("name") String name) { | |
this.values = values; | |
this.type = type; | |
this.name = name; | |
} | |
/** | |
* Returns all the group values. | |
*/ | |
public List<String> getValues() { | |
return values; | |
} | |
/** | |
* Returns the {@link Type group type}. | |
*/ | |
public Type getType() { | |
return type; | |
} | |
/** | |
* Returns the name of this range displayed to the end-user. | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* Returns whether the specified value is contained within this group. | |
*/ | |
public boolean isInGroup(String value) { | |
return getValues() | |
.stream() | |
.anyMatch(groupEntry -> getType().matches(groupEntry, value)); | |
} | |
@Override | |
public String toString() { | |
return "Group{" + | |
"name='" + name + '\'' + | |
'}'; | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) { | |
return true; | |
} | |
if (o == null || getClass() != o.getClass()) { | |
return false; | |
} | |
final Group group = (Group) o; | |
return Objects.equals(name, group.name); | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hash(name); | |
} | |
} | |
/** | |
* Type of group entry. | |
*/ | |
public enum Type { | |
/** | |
* Group entries must exactly match flow entry values. | |
*/ | |
STRICT_MATCH(Object::equals, x -> { | |
}), | |
/** | |
* Group entries are expressions that must match flow entry values. | |
*/ | |
SIMPLE_EXPRESSION( | |
(groupEntry, value) -> (value != null) && SimpleRegexUtils.buildPattern(groupEntry).matcher(value).matches(), | |
groupEntry -> { | |
try { | |
SimpleRegexUtils.buildPattern(groupEntry); | |
} catch (PatternSyntaxException e) { | |
throw new IllegalArgumentException("Error while validating the group entry.", e); | |
} | |
} | |
), | |
@SuppressWarnings("ResultOfMethodCallIgnored") | |
REGULAR_EXPRESSION( | |
(groupEntry, value) -> (value != null) && Pattern.matches(groupEntry, value), | |
groupEntry -> { | |
try { | |
Pattern.compile(groupEntry); | |
} catch (PatternSyntaxException e) { | |
throw new IllegalArgumentException("Error while validating the group entry.", e); | |
} | |
} | |
); | |
/** | |
* @deprecated to be removed once the migration has been performed | |
*/ | |
@JsonCreator | |
public static Type forValue(String value) { | |
if ("EXPRESSION".equals(value)) { | |
return SIMPLE_EXPRESSION; | |
} | |
return Type.valueOf(value); | |
} | |
private final BiFunction<String, String, Boolean> matcher; | |
private final Consumer<String> validator; | |
Type(BiFunction<String, String, Boolean> matcher, | |
Consumer<String> validator) { | |
this.matcher = matcher; | |
this.validator = validator; | |
} | |
/** | |
* Returns whether the specified group entry matches the current value. | |
*/ | |
public boolean matches(String groupEntry, String value) { | |
return matcher.apply(groupEntry, value); // TODO operational build the pattern only once and not when matching | |
} | |
/** | |
* Validates that the specified group entry is valid. | |
*/ | |
public void validate(String groupEntry) throws IllegalArgumentException { | |
validator.accept(groupEntry); | |
} | |
} | |
/** | |
* Visitor pattern for {@link MatrixTextRangeValuesDimensionDefinition}. | |
* | |
* @param <T> type of object returned when visiting | |
*/ | |
public interface Visitor<T> extends MatrixDimensionDefinition.Visitor<T> { | |
/** | |
* Visits the specified definition. | |
*/ | |
T visitMatrixTextRangeValuesDimension(MatrixTextRangeValuesDimensionDefinition definition); | |
} | |
/** | |
* Builder of {@link MatrixTextRangeValuesDimensionDefinition}. | |
*/ | |
@JsonPOJOBuilder(withPrefix = "") | |
@JsonIgnoreProperties(ignoreUnknown = true) | |
public static final class Builder { | |
private CodeLabel valueReference; | |
private final List<Group> textGroups = new ArrayList<>(); | |
private Builder() { | |
} | |
public Builder valueReference(CodeLabel valueReference) { | |
this.valueReference = valueReference; | |
return this; | |
} | |
@JsonProperty("textGroups") | |
public Builder textGroups(List<Group> textGroups) { | |
this.textGroups.addAll(textGroups); | |
return this; | |
} | |
@JsonIgnore | |
public Builder textGroups(Group... textGroups) { | |
return textGroups(asList(textGroups)); | |
} | |
public MatrixTextRangeValuesDimensionDefinition build() { | |
return new MatrixTextRangeValuesDimensionDefinition(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment