Bar.java
package com.github.dakusui.symfonion.song;
import com.github.dakusui.json.JsonException;
import com.github.dakusui.json.JsonInvalidPathException;
import com.github.dakusui.json.JsonUtils;
import com.github.dakusui.symfonion.exceptions.FractionFormatException;
import com.github.dakusui.symfonion.exceptions.SymfonionException;
import com.github.dakusui.symfonion.utils.Fraction;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.*;
import java.util.Map.Entry;
import static com.github.dakusui.json.JsonUtils.asJsonElement;
import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.*;
import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.ContextKey.JSON_ELEMENT_ROOT;
import static com.github.dakusui.symfonion.exceptions.SymfonionIllegalFormatException.FRACTION_EXAMPLE;
import static com.github.dakusui.symfonion.exceptions.SymfonionTypeMismatchException.ARRAY;
public class Bar {
private final Map<String, Groove> grooves;
private final Map<String, Pattern> patterns;
private final JsonObject rootJsonObject;
Fraction beats;
Map<String, List<List<Pattern>>> patternLists = new HashMap<>();
Groove groove;
private final JsonObject json;
public Bar(JsonObject jsonObject, JsonObject root, Map<String, Groove> grooves, Map<String, Pattern> patterns) throws SymfonionException, JsonException {
this.grooves = grooves;
this.patterns = patterns;
this.json = jsonObject;
this.rootJsonObject = root;
init(jsonObject, root);
}
private void init(JsonObject jsonObject, JsonObject root) throws SymfonionException, JsonException {
try (Context ignored = context($(JSON_ELEMENT_ROOT, root))) {
try {
this.beats = Fraction.parseFraction(JsonUtils.asString(jsonObject, Keyword.$beats));
} catch (FractionFormatException e) {
throw illegalFormatException(asJsonElement(jsonObject, Keyword.$beats), FRACTION_EXAMPLE);
}
this.beats = this.beats == null ? Fraction.one : this.beats;
this.groove = Groove.DEFAULT_INSTANCE;
Groove g = Groove.DEFAULT_INSTANCE;
if (JsonUtils.hasPath(jsonObject, Keyword.$groove)) {
String grooveName = JsonUtils.asString(jsonObject, Keyword.$groove.name());
g = grooves.get(grooveName);
if (g == null) {
throw grooveNotDefinedException(asJsonElement(jsonObject, Keyword.$groove), grooveName);
}
}
this.groove = g;
JsonObject patternsJsonObject = JsonUtils.asJsonObject(jsonObject, Keyword.$patterns);
if (patternsJsonObject == null) {
throw requiredElementMissingException(jsonObject, Keyword.$patterns);
}
for (Entry<String, JsonElement> stringJsonElementEntry : patternsJsonObject.entrySet()) {
String partName = stringJsonElementEntry.getKey();
List<List<Pattern>> patterns = new LinkedList<>();
JsonArray partPatternsJsonArray = JsonUtils.asJsonArray(patternsJsonObject, partName);
if (!partPatternsJsonArray.isJsonArray()) {
throw typeMismatchException(partPatternsJsonArray, ARRAY);
}
int len = partPatternsJsonArray.size();
for (int j = 0; j < len; j++) {
JsonElement jsonPatterns = partPatternsJsonArray.get(j);
String patternNames = jsonPatterns.getAsString();
List<Pattern> p = new LinkedList<>();
for (String each : patternNames.split(";")) {
Pattern cur = this.patterns.get(each);
if (cur == null) {
throw patternNotFound(jsonPatterns, patternNames);
}
p.add(cur);
}
patterns.add(p);
}
patternLists.put(partName, patterns);
}
}
}
public Set<String> partNames() {
return Collections.unmodifiableSet(this.patternLists.keySet());
}
public List<List<Pattern>> part(String instrumentName) {
return Collections.unmodifiableList(this.patternLists.get(instrumentName));
}
public Fraction beats() {
return this.beats;
}
public Groove groove() {
return this.groove;
}
public JsonElement lookUpJsonNode(String partName) {
try {
return asJsonElement(this.json, Keyword.$patterns, partName);
} catch (JsonInvalidPathException e) {
return null;
}
}
public JsonObject rootJsonObject() {
return this.rootJsonObject;
}
}