| 1 | package com.github.dakusui.symfonion.compat.exceptions; | |
| 2 | ||
| 3 | import com.github.dakusui.symfonion.cli.CliUtils; | |
| 4 | import com.github.dakusui.symfonion.compat.json.CompatJsonUtils; | |
| 5 | import com.github.dakusui.symfonion.utils.midi.MidiDeviceRecord; | |
| 6 | import com.google.gson.JsonArray; | |
| 7 | import com.google.gson.JsonElement; | |
| 8 | import com.google.gson.JsonObject; | |
| 9 | ||
| 10 | import javax.sound.midi.MidiDevice; | |
| 11 | import javax.sound.midi.MidiUnavailableException; | |
| 12 | import java.io.File; | |
| 13 | import java.util.function.Predicate; | |
| 14 | import java.util.regex.Matcher; | |
| 15 | ||
| 16 | import static com.github.dakusui.symfonion.compat.exceptions.CompatExceptionThrower.ContextKey.*; | |
| 17 | import static java.lang.String.format; | |
| 18 | ||
| 19 | public class CompatExceptionThrower { | |
| 20 | public enum ContextKey { | |
| 21 | MIDI_DEVICE_INFO(MidiDevice.Info.class), | |
| 22 | MIDI_DEVICE_INFO_IO(String.class), | |
| 23 | JSON_ELEMENT_ROOT(JsonObject.class), | |
| 24 | SOURCE_FILE(File.class), | |
| 25 | PART_MEASURE_JSON(JsonElement.class); | |
| 26 | private final Class<?> type; | |
| 27 | ||
| 28 | ContextKey(Class<?> type) { | |
| 29 | this.type = type; | |
| 30 | } | |
| 31 | ||
| 32 | public Class<?> type() { | |
| 33 |
1
1. type : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower$ContextKey::type → KILLED |
return type; |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | static final ThreadLocal<ExceptionContext> context = new ThreadLocal<>(); | |
| 38 | ||
| 39 | public static ExceptionContext exceptionContext(ExceptionContextEntry... entries) { | |
| 40 | ExceptionContext ret = currentContext().createChild(); | |
| 41 |
1
1. exceptionContext : removed call to java/lang/ThreadLocal::set → KILLED |
context.set(ret); |
| 42 | for (ExceptionContextEntry each : entries) | |
| 43 | ret.set(each.key(), each.value()); | |
| 44 |
1
1. exceptionContext : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::exceptionContext → SURVIVED |
return ret; |
| 45 | } | |
| 46 | ||
| 47 | public static SymfonionException compilationException(String msg, Throwable e) throws SymfonionException { | |
| 48 | throw new SymfonionException(msg, e, contextValueOf(SOURCE_FILE)); | |
| 49 | } | |
| 50 | ||
| 51 | public static SymfonionException fileNotFoundException(File file, Throwable e) throws SymfonionException { | |
| 52 | throw new SymfonionException(format("%s: File not found (%s)", file, e.getMessage()), file); | |
| 53 | } | |
| 54 | ||
| 55 | public static SymfonionException loadFileException(Throwable e) throws SymfonionException { | |
| 56 | throw new SymfonionException(format("%s: %s", contextValueOf(SOURCE_FILE), e.getMessage()), contextValueOf(SOURCE_FILE)); | |
| 57 | } | |
| 58 | ||
| 59 | public static SymfonionException loadResourceException(String resourceName, Throwable e) throws SymfonionException { | |
| 60 | throw new SymfonionException(format("%s: Failed to read resource (%s)", resourceName, e.getMessage()), contextValueOf(SOURCE_FILE)); | |
| 61 | } | |
| 62 | ||
| 63 | public static SymfonionReferenceException noteMapNotFoundException(JsonElement problemCausingJsonNode, String missingReference) throws SymfonionException { | |
| 64 | throw new SymfonionReferenceException(missingReference, "notemap", problemCausingJsonNode, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE), CompatJsonUtils.asJsonElement(contextValueOf(JSON_ELEMENT_ROOT), "notemaps")); | |
| 65 | } | |
| 66 | ||
| 67 | public static SymfonionReferenceException noteNotDefinedException(String missingReference, String notemapName) throws SymfonionException { | |
| 68 | throw new SymfonionReferenceException(missingReference, format("note in %s", notemapName), contextValueOf(PART_MEASURE_JSON), contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE), CompatJsonUtils.asJsonElement(contextValueOf(JSON_ELEMENT_ROOT), "notemaps")); | |
| 69 | } | |
| 70 | ||
| 71 | public static SymfonionException syntaxErrorInNotePattern(String s, int i, Matcher m) { | |
| 72 |
1
1. syntaxErrorInNotePattern : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::syntaxErrorInNotePattern → NO_COVERAGE |
return new SymfonionException("Error:" + s.substring(0, i) + "[" + s.substring(i, m.start()) + "]" + s.substring(m.start()), contextValueOf(SOURCE_FILE)); |
| 73 | } | |
| 74 | ||
| 75 | public static SymfonionReferenceException grooveNotDefinedException(JsonElement problemCausingJsonNode, String missingReference) throws SymfonionException { | |
| 76 | throw new SymfonionReferenceException(missingReference, "groove", problemCausingJsonNode, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE), CompatJsonUtils.asJsonElement(contextValueOf(JSON_ELEMENT_ROOT), "grooves")); | |
| 77 | } | |
| 78 | ||
| 79 | public static SymfonionReferenceException partNotFound(JsonElement problemCausingJsonNode, String missingReference) throws SymfonionException { | |
| 80 | throw new SymfonionReferenceException(missingReference, "part", problemCausingJsonNode, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE), CompatJsonUtils.asJsonElement(contextValueOf(JSON_ELEMENT_ROOT), "parts")); | |
| 81 | } | |
| 82 | ||
| 83 | public static SymfonionTypeMismatchException typeMismatchException(JsonElement actualJSON, String... expectedTypes) throws SymfonionSyntaxException { | |
| 84 | throw new SymfonionTypeMismatchException(expectedTypes, actualJSON, actualJSON, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE)); | |
| 85 | } | |
| 86 | ||
| 87 | public static SymfonionIllegalFormatException illegalNoteFormat(String stroke, int position) throws SymfonionException { | |
| 88 | throw illegalFormatException(contextValueOf(PART_MEASURE_JSON), composeIllegalNoteFormatMessage(stroke, position)); | |
| 89 | } | |
| 90 | ||
| 91 | private static String composeIllegalNoteFormatMessage(String partMeasureString, int position) { | |
| 92 |
1
1. composeIllegalNoteFormatMessage : replaced return value with "" for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::composeIllegalNoteFormatMessage → NO_COVERAGE |
return partMeasureString.substring(0, position) + "``" + partMeasureString.substring(position) + "'' isn't a valid note expression. Notes must be like 'C', 'CEG8.', and so on."; |
| 93 | } | |
| 94 | ||
| 95 | public static SymfonionIllegalFormatException illegalFormatException(JsonElement actualJSON, String acceptableExample) throws SymfonionIllegalFormatException { | |
| 96 | throw new SymfonionIllegalFormatException(actualJSON, acceptableExample, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE)); | |
| 97 | } | |
| 98 | ||
| 99 | public static SymfonionIllegalFormatException syntaxErrorWhenExpandingDotsIn(JsonArray errorContainingJsonArray) { | |
| 100 |
1
1. syntaxErrorWhenExpandingDotsIn : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::syntaxErrorWhenExpandingDotsIn → NO_COVERAGE |
return new SymfonionIllegalFormatException( |
| 101 | errorContainingJsonArray, | |
| 102 | "In this array, a string can contain only dots. E.g. '[1, \"...\",3]'. This will be expanded and interpolation of integer values will happen.", | |
| 103 | contextValueOf(JSON_ELEMENT_ROOT), | |
| 104 | contextValueOf(SOURCE_FILE)); | |
| 105 | } | |
| 106 | ||
| 107 | public static SymfonionIllegalFormatException typeMismatchWhenExpandingDotsIn(JsonArray errorContainingJsonArray) { | |
| 108 |
1
1. typeMismatchWhenExpandingDotsIn : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::typeMismatchWhenExpandingDotsIn → NO_COVERAGE |
return new SymfonionIllegalFormatException( |
| 109 | errorContainingJsonArray, | |
| 110 | "This array, only integers, nulls, and strings containing only dots (...) are allowed.", | |
| 111 | contextValueOf(JSON_ELEMENT_ROOT), | |
| 112 | contextValueOf(SOURCE_FILE)); | |
| 113 | } | |
| 114 | ||
| 115 | public static SymfonionMissingElementException requiredElementMissingException(JsonElement problemCausingJsonNode, Object relativePathFromProblemCausingJsonNode) throws SymfonionMissingElementException { | |
| 116 | throw new SymfonionMissingElementException(problemCausingJsonNode, relativePathFromProblemCausingJsonNode, contextValueOf(JSON_ELEMENT_ROOT), contextValueOf(SOURCE_FILE)); | |
| 117 | } | |
| 118 | ||
| 119 | public static SymfonionMissingElementException requiredElementMissingException(JsonElement actualJSON, JsonObject root, Object relPath) throws SymfonionMissingElementException { | |
| 120 | throw new SymfonionMissingElementException(actualJSON, relPath, root, contextValueOf(SOURCE_FILE)); | |
| 121 | } | |
| 122 | ||
| 123 | public static SymfonionException deviceException(String msg, Throwable e) throws SymfonionException { | |
| 124 | throw new SymfonionException(msg, e, contextValueOf(SOURCE_FILE)); | |
| 125 | } | |
| 126 | ||
| 127 | public static RuntimeException runtimeException(String msg, Throwable e) { | |
| 128 | throw new RuntimeException(msg, e); | |
| 129 | } | |
| 130 | ||
| 131 | public static FractionFormatException throwFractionFormatException(String fraction) throws FractionFormatException { | |
| 132 | throw new FractionFormatException(fraction); | |
| 133 | } | |
| 134 | ||
| 135 | public static SymfonionInterruptedException interrupted(InterruptedException e) { | |
| 136 |
1
1. interrupted : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
| 137 | throw new SymfonionInterruptedException(e.getMessage(), e); | |
| 138 | } | |
| 139 | ||
| 140 | public static CliException failedToRetrieveTransmitterFromMidiIn(MidiUnavailableException e, MidiDevice.Info inMidiDeviceInfo) { | |
| 141 | throw new CliException(format("(-) Failed to get transmitter from MIDI-in device (%s)", inMidiDeviceInfo.getName()), e); | |
| 142 | } | |
| 143 | ||
| 144 | public static CliException failedToOpenMidiDevice(MidiUnavailableException ee) { | |
| 145 | throw new CliException(format("(-) Failed to open MIDI-%s device (%s)", | |
| 146 | CompatExceptionThrower.<MidiDevice.Info>contextValueOf(MIDI_DEVICE_INFO), | |
| 147 | CompatExceptionThrower.<String>contextValueOf(MIDI_DEVICE_INFO_IO).toLowerCase()), ee); | |
| 148 | } | |
| 149 | ||
| 150 | public static CliException failedToAccessMidiDevice(String deviceType, MidiUnavailableException e, MidiDevice.Info[] matchedInfos) { | |
| 151 | throw new CliException(CliUtils.composeErrMsgForShortOption(format("Failed to access MIDI-%s device:'%s'.", deviceType, matchedInfos[0].getName()), "O"), e); | |
| 152 | } | |
| 153 | ||
| 154 | public static RuntimeException multipleMidiDevices(MidiDeviceRecord e1, MidiDeviceRecord e2, Predicate<MidiDeviceRecord> cond) { | |
| 155 | throw new CliException(format("Multiple midi devices (at least: '%s', '%s') are found for: '%s'", e1, e2, cond)); | |
| 156 | } | |
| 157 | ||
| 158 | public static RuntimeException noSuchMidiDeviceWasFound(Predicate<MidiDeviceRecord> cond) { | |
| 159 | throw new CliException(format("No such MIDI device was found for: '%s'", cond)); | |
| 160 | } | |
| 161 | ||
| 162 | public static RuntimeException failedToGetTransmitter() { | |
| 163 | throw new RuntimeException(); | |
| 164 | } | |
| 165 | ||
| 166 | public static RuntimeException failedToSetSequence() { | |
| 167 | throw new RuntimeException(); | |
| 168 | } | |
| 169 | ||
| 170 | @SuppressWarnings("resource") | |
| 171 | private static <T> T contextValueOf(ContextKey contextKey) { | |
| 172 |
1
1. contextValueOf : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::contextValueOf → KILLED |
return currentContext().get(contextKey); |
| 173 | } | |
| 174 | ||
| 175 | private static ExceptionContext currentContext() { | |
| 176 |
1
1. currentContext : negated conditional → KILLED |
if (context.get() == null) |
| 177 |
1
1. currentContext : removed call to java/lang/ThreadLocal::set → KILLED |
context.set(new ExceptionContext()); |
| 178 |
1
1. currentContext : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::currentContext → KILLED |
return context.get(); |
| 179 | } | |
| 180 | ||
| 181 | static Class<?> classOfValueFor(ContextKey key) { | |
| 182 | class GivenKeyIsNull { | |
| 183 | } | |
| 184 |
2
1. classOfValueFor : replaced return value with null for com/github/dakusui/symfonion/compat/exceptions/CompatExceptionThrower::classOfValueFor → KILLED 2. classOfValueFor : negated conditional → KILLED |
return key != null ? key.type : GivenKeyIsNull.class; |
| 185 | } | |
| 186 | } | |
Mutations | ||
| 33 |
1.1 |
|
| 41 |
1.1 |
|
| 44 |
1.1 |
|
| 72 |
1.1 |
|
| 92 |
1.1 |
|
| 100 |
1.1 |
|
| 108 |
1.1 |
|
| 136 |
1.1 |
|
| 172 |
1.1 |
|
| 176 |
1.1 |
|
| 177 |
1.1 |
|
| 178 |
1.1 |
|
| 184 |
1.1 2.2 |