| 1 | package com.github.dakusui.symfonion.song; | |
| 2 | ||
| 3 | import com.github.dakusui.json.JsonException; | |
| 4 | import com.github.dakusui.json.JsonUtils; | |
| 5 | import com.github.dakusui.logias.Logias; | |
| 6 | import com.github.dakusui.logias.lisp.Context; | |
| 7 | import com.github.dakusui.symfonion.exceptions.ExceptionThrower; | |
| 8 | import com.github.dakusui.symfonion.exceptions.SymfonionException; | |
| 9 | import com.github.dakusui.symfonion.utils.Utils; | |
| 10 | import com.github.dakusui.valid8j.Requires; | |
| 11 | import com.google.gson.JsonArray; | |
| 12 | import com.google.gson.JsonElement; | |
| 13 | import com.google.gson.JsonObject; | |
| 14 | ||
| 15 | import java.util.*; | |
| 16 | ||
| 17 | import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.*; | |
| 18 | import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.ContextKey.JSON_ELEMENT_ROOT; | |
| 19 | import static com.github.dakusui.symfonion.exceptions.SymfonionTypeMismatchException.ARRAY; | |
| 20 | import static com.github.dakusui.symfonion.exceptions.SymfonionTypeMismatchException.OBJECT; | |
| 21 | import static com.github.dakusui.valid8j.Requires.requireNonNull; | |
| 22 | ||
| 23 | public class Song { | |
| 24 | ||
| 25 | public static class Builder { | |
| 26 | private final Context logiasContext; | |
| 27 | private final JsonObject json; | |
| 28 | ||
| 29 | public Builder(Context logiasContext, JsonObject jsonObject) { | |
| 30 | this.logiasContext = requireNonNull(logiasContext); | |
| 31 | this.json = requireNonNull(jsonObject); | |
| 32 | } | |
| 33 | ||
| 34 | private static Context loadMidiDeviceProfile(JsonObject json, Context logiasContext) throws SymfonionException, JsonException { | |
| 35 | JsonElement tmp = JsonUtils.asJsonObjectWithDefault(json, new JsonObject(), Keyword.$settings); | |
| 36 |
1
1. loadMidiDeviceProfile : negated conditional → KILLED |
if (!tmp.isJsonObject()) { |
| 37 | throw typeMismatchException(tmp, OBJECT); | |
| 38 | } | |
| 39 | String profileName = JsonUtils.asStringWithDefault(tmp.getAsJsonObject(), "", Keyword.$mididevice); | |
| 40 | Logias logias = new Logias(logiasContext); | |
| 41 |
1
1. loadMidiDeviceProfile : negated conditional → KILLED |
if (!"".equals(profileName)) { |
| 42 | JsonObject deviceDef = JsonUtils.toJson(Utils.loadResource(profileName + ".json")).getAsJsonObject(); | |
| 43 | Iterator<String> i = JsonUtils.keyIterator(deviceDef); | |
| 44 |
1
1. loadMidiDeviceProfile : negated conditional → NO_COVERAGE |
while (i.hasNext()) { |
| 45 | String k = i.next(); | |
| 46 | JsonElement v = deviceDef.get(k); | |
| 47 | logiasContext.bind(k, logias.run(logias.buildSexp(v))); | |
| 48 | } | |
| 49 | } | |
| 50 |
1
1. loadMidiDeviceProfile : replaced return value with null for com/github/dakusui/symfonion/song/Song$Builder::loadMidiDeviceProfile → SURVIVED |
return logiasContext; |
| 51 | } | |
| 52 | ||
| 53 | private static List<Bar> initSequence(JsonObject json, Map<String, Groove> grooves, Map<String, Pattern> patterns) throws SymfonionException, JsonException { | |
| 54 | List<Bar> bars = new LinkedList<>(); | |
| 55 | JsonElement tmp = JsonUtils.asJsonElement(json, Keyword.$sequence); | |
| 56 |
1
1. initSequence : negated conditional → KILLED |
if (!tmp.isJsonArray()) { |
| 57 | throw typeMismatchException(tmp, ARRAY); | |
| 58 | } | |
| 59 | JsonArray seqJson = tmp.getAsJsonArray(); | |
| 60 | int len = seqJson.getAsJsonArray().size(); | |
| 61 |
2
1. initSequence : negated conditional → KILLED 2. initSequence : changed conditional boundary → KILLED |
for (int i = 0; i < len; i++) { |
| 62 | JsonElement barJson = seqJson.get(i); | |
| 63 |
1
1. initSequence : negated conditional → KILLED |
if (!barJson.isJsonObject()) { |
| 64 | throw typeMismatchException(seqJson, OBJECT); | |
| 65 | } | |
| 66 | Bar bar = new Bar(barJson.getAsJsonObject(), json, grooves, patterns); | |
| 67 | bars.add(bar); | |
| 68 | } | |
| 69 |
1
1. initSequence : replaced return value with Collections.emptyList for com/github/dakusui/symfonion/song/Song$Builder::initSequence → KILLED |
return bars; |
| 70 | } | |
| 71 | ||
| 72 | private static Map<String, NoteMap> initNoteMaps(JsonObject json) throws SymfonionException, JsonException { | |
| 73 | Map<String, NoteMap> noteMaps = new HashMap<>(); | |
| 74 | final JsonObject noteMapsJSON = JsonUtils.asJsonObjectWithDefault(json, new JsonObject(), Keyword.$notemaps); | |
| 75 | ||
| 76 | Iterator<String> i = JsonUtils.keyIterator(noteMapsJSON); | |
| 77 | noteMaps.put(Keyword.$normal.toString(), NoteMap.defaultNoteMap); | |
| 78 | noteMaps.put(Keyword.$percussion.toString(), NoteMap.defaultPercussionMap); | |
| 79 |
1
1. initNoteMaps : negated conditional → KILLED |
while (i.hasNext()) { |
| 80 | String name = i.next(); | |
| 81 | NoteMap cur = new NoteMap(JsonUtils.asJsonObject(noteMapsJSON, name)); | |
| 82 | noteMaps.put(name, cur); | |
| 83 | } | |
| 84 |
1
1. initNoteMaps : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/song/Song$Builder::initNoteMaps → KILLED |
return noteMaps; |
| 85 | } | |
| 86 | ||
| 87 | private static Map<String, Pattern> initPatterns(JsonObject json, Map<String, NoteMap> noteMaps) throws SymfonionException, JsonException { | |
| 88 | Map<String, Pattern> patterns = new HashMap<>(); | |
| 89 | JsonObject patternsJSON = JsonUtils.asJsonObjectWithDefault(json, new JsonObject(), Keyword.$patterns); | |
| 90 | ||
| 91 | Iterator<String> i = JsonUtils.keyIterator(patternsJSON); | |
| 92 | try (ExceptionThrower.Context ignored = context($(JSON_ELEMENT_ROOT, json))) { | |
| 93 |
1
1. initPatterns : negated conditional → KILLED |
while (i.hasNext()) { |
| 94 | String name = i.next(); | |
| 95 | Pattern cur = Pattern.createPattern(JsonUtils.asJsonObject(patternsJSON, name), noteMaps); | |
| 96 | patterns.put(name, cur); | |
| 97 | } | |
| 98 | } | |
| 99 |
1
1. initPatterns : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/song/Song$Builder::initPatterns → KILLED |
return patterns; |
| 100 | } | |
| 101 | ||
| 102 | private static Map<String, Part> initParts(JsonObject json) throws SymfonionException, JsonException { | |
| 103 | Map<String, Part> parts = new HashMap<>(); | |
| 104 |
1
1. initParts : negated conditional → KILLED |
if (JsonUtils.hasPath(json, Keyword.$parts)) { |
| 105 | JsonObject instrumentsJSON = JsonUtils.asJsonObject(json, Keyword.$parts); | |
| 106 | Iterator<String> i = JsonUtils.keyIterator(instrumentsJSON); | |
| 107 |
1
1. initParts : negated conditional → KILLED |
while (i.hasNext()) { |
| 108 | String name = i.next(); | |
| 109 | Part cur = new Part(name, JsonUtils.asJsonObject(instrumentsJSON, name)); | |
| 110 | parts.put(name, cur); | |
| 111 | } | |
| 112 | } | |
| 113 |
1
1. initParts : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/song/Song$Builder::initParts → KILLED |
return parts; |
| 114 | } | |
| 115 | ||
| 116 | private static Map<String, Groove> initGrooves(JsonObject json) throws SymfonionException, JsonException { | |
| 117 | Map<String, Groove> grooves = new HashMap<>(); | |
| 118 |
1
1. initGrooves : negated conditional → KILLED |
if (JsonUtils.hasPath(json, Keyword.$grooves)) { |
| 119 | JsonObject groovesJSON = JsonUtils.asJsonObject(json, Keyword.$grooves); | |
| 120 | ||
| 121 | Iterator<String> i = JsonUtils.keyIterator(groovesJSON); | |
| 122 |
1
1. initGrooves : negated conditional → KILLED |
while (i.hasNext()) { |
| 123 | String name = i.next(); | |
| 124 | Groove cur = Groove.createGroove(JsonUtils.asJsonArray(groovesJSON, name)); | |
| 125 | grooves.put(name, cur); | |
| 126 | } | |
| 127 | } | |
| 128 |
1
1. initGrooves : replaced return value with Collections.emptyMap for com/github/dakusui/symfonion/song/Song$Builder::initGrooves → KILLED |
return grooves; |
| 129 | } | |
| 130 | ||
| 131 | public Song build() throws JsonException, SymfonionException { | |
| 132 | try (ExceptionThrower.Context ignored = context($(JSON_ELEMENT_ROOT, json))) { | |
| 133 | Map<String, NoteMap> noteMaps = initNoteMaps(json); | |
| 134 | Map<String, Groove> grooves = initGrooves(json); | |
| 135 | Map<String, Pattern> patterns = initPatterns(json, noteMaps); | |
| 136 | return new Song( | |
| 137 | loadMidiDeviceProfile(json, logiasContext), | |
| 138 | initParts(this.json), | |
| 139 | patterns, | |
| 140 | noteMaps, | |
| 141 | grooves, | |
| 142 | initSequence(json, grooves, patterns) | |
| 143 | ); | |
| 144 | } | |
| 145 | } | |
| 146 | } | |
| 147 | ||
| 148 | private final Context logiasContext; | |
| 149 | private final Map<String, Part> parts; | |
| 150 | private final Map<String, Pattern> patterns; | |
| 151 | private final Map<String, NoteMap> noteMaps; | |
| 152 | private final Map<String, Groove> grooves; | |
| 153 | private final List<Bar> bars; | |
| 154 | ||
| 155 | ||
| 156 | public Song(Context logiasContext, | |
| 157 | Map<String, Part> parts, | |
| 158 | Map<String, Pattern> patterns, | |
| 159 | Map<String, NoteMap> noteMaps, | |
| 160 | Map<String, Groove> grooves, | |
| 161 | List<Bar> bars | |
| 162 | ) { | |
| 163 | this.logiasContext = logiasContext; | |
| 164 | this.parts = Requires.requireNonNull(parts); | |
| 165 | this.patterns = Requires.requireNonNull(patterns); | |
| 166 | this.noteMaps = requireNonNull(noteMaps); | |
| 167 | this.grooves = requireNonNull(grooves); | |
| 168 | this.bars = requireNonNull(bars); | |
| 169 | } | |
| 170 | ||
| 171 | ||
| 172 | public Pattern pattern(String patternName) { | |
| 173 |
1
1. pattern : replaced return value with null for com/github/dakusui/symfonion/song/Song::pattern → NO_COVERAGE |
return this.patterns.get(patternName); |
| 174 | } | |
| 175 | ||
| 176 | public NoteMap noteMap(String noteMapName) { | |
| 177 |
1
1. noteMap : replaced return value with null for com/github/dakusui/symfonion/song/Song::noteMap → NO_COVERAGE |
return this.noteMaps.get(noteMapName); |
| 178 | } | |
| 179 | ||
| 180 | public List<Bar> bars() { | |
| 181 |
1
1. bars : replaced return value with Collections.emptyList for com/github/dakusui/symfonion/song/Song::bars → KILLED |
return Collections.unmodifiableList(this.bars); |
| 182 | } | |
| 183 | ||
| 184 | public Set<String> partNames() { | |
| 185 |
1
1. partNames : replaced return value with Collections.emptySet for com/github/dakusui/symfonion/song/Song::partNames → KILLED |
return Collections.unmodifiableSet(this.parts.keySet()); |
| 186 | } | |
| 187 | ||
| 188 | public Part part(String name) { | |
| 189 |
1
1. part : replaced return value with null for com/github/dakusui/symfonion/song/Song::part → KILLED |
return this.parts.get(name); |
| 190 | } | |
| 191 | ||
| 192 | public Context getLogiasContext() { | |
| 193 |
1
1. getLogiasContext : replaced return value with null for com/github/dakusui/symfonion/song/Song::getLogiasContext → SURVIVED |
return this.logiasContext; |
| 194 | } | |
| 195 | ||
| 196 | public Groove groove(String grooveName) { | |
| 197 |
1
1. groove : replaced return value with null for com/github/dakusui/symfonion/song/Song::groove → NO_COVERAGE |
return this.grooves.get(grooveName); |
| 198 | } | |
| 199 | } | |
Mutations | ||
| 36 |
1.1 |
|
| 41 |
1.1 |
|
| 44 |
1.1 |
|
| 50 |
1.1 |
|
| 56 |
1.1 |
|
| 61 |
1.1 2.2 |
|
| 63 |
1.1 |
|
| 69 |
1.1 |
|
| 79 |
1.1 |
|
| 84 |
1.1 |
|
| 93 |
1.1 |
|
| 99 |
1.1 |
|
| 104 |
1.1 |
|
| 107 |
1.1 |
|
| 113 |
1.1 |
|
| 118 |
1.1 |
|
| 122 |
1.1 |
|
| 128 |
1.1 |
|
| 173 |
1.1 |
|
| 177 |
1.1 |
|
| 181 |
1.1 |
|
| 185 |
1.1 |
|
| 189 |
1.1 |
|
| 193 |
1.1 |
|
| 197 |
1.1 |