From: Daniel Kirschten Date: Tue, 3 Sep 2019 11:51:43 +0000 (+0200) Subject: Small improvements in IndirectGUIComponentCreator X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=45941345b94530390abe953aab4e78135d4f0742;p=Mograsim.git Small improvements in IndirectGUIComponentCreator --- diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/Am2900Loader.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/Am2900Loader.java index d5613b9b..2b483d51 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/Am2900Loader.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/Am2900Loader.java @@ -1,14 +1,12 @@ package net.mograsim.logic.model.am2900; -import java.io.IOException; -import java.io.InputStream; import java.util.concurrent.atomic.AtomicBoolean; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import net.mograsim.logic.model.serializing.ClassLoaderBasedResourceLoader; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; -import net.mograsim.logic.model.serializing.ResourceLoader; public class Am2900Loader implements BundleActivator { @@ -30,31 +28,9 @@ public class Am2900Loader implements BundleActivator { if (activated.getAndSet(true)) return; - IndirectGUIComponentCreator.registerResourceLoader(new Am2900ResourceLoader(), "Am2900Loader"); + ClassLoaderBasedResourceLoader resourceLoader = ClassLoaderBasedResourceLoader.create(Am2900Loader.class.getClassLoader()); + IndirectGUIComponentCreator.registerResourceLoader(resourceLoader, "Am2900Loader"); IndirectGUIComponentCreator.loadStandardComponentIDs(Am2900Loader.class.getResourceAsStream("standardComponentIDMapping.json")); // System.out.println("SETUP DONE"); // TODO: Debug } - - /** - * @see ResourceLoader - */ - public static ResourceLoader resourceLoader() - { - return new Am2900ResourceLoader(); - } - - static class Am2900ResourceLoader implements ResourceLoader - { - @Override - public InputStream loadResource(String path) throws IOException - { - return Am2900ResourceLoader.class.getResourceAsStream(path); - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException - { - return Class.forName(name, true, Am2900ResourceLoader.class.getClassLoader()); - } - } } diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java index 0f0dcd51..7f234a40 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java @@ -23,7 +23,7 @@ public class Am2900Machine implements Machine { this.machineDefinition = am2900MachineDefinition; viewModel = new ViewModelModifiable(); - IndirectGUIComponentCreator.createComponent(viewModel, "resource:Am2900Loader:/components/GUIAm2900.json"); + IndirectGUIComponentCreator.createComponent(viewModel, "resloader:Am2900Loader:jsonres:components/GUIAm2900.json"); LogicModelParameters params = new LogicModelParameters(); params.gateProcessTime = 50; params.wireTravelTime = 10; diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/standardComponentIDMapping.json b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/standardComponentIDMapping.json index 7bb2e062..73bc1119 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/standardComponentIDMapping.json +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/standardComponentIDMapping.json @@ -1,54 +1,54 @@ mograsim version: 0.1.3 { - "GUIAm2904RegCTInstrDecode": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.am2904.GUIAm2904RegCTInstrDecode", - "GUIAm2904ShiftInstrDecode": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.am2904.GUIAm2904ShiftInstrDecode", - "GUIAm2910InstrPLA": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910InstrPLA", - "GUIAm2910RegCntr": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910RegCntr", - "GUIAm2910SP": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910SP", - "GUIdff12": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUIdff12", - "GUIdff4_finewe": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUIdff4_finewe", - "GUIinc12": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUIinc12", - "GUInor12": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUInor12", - "GUIram5_12": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUIram5_12", - "GUIsel4_12": "resource:Am2900Loader:net.mograsim.logic.model.am2900.components.GUIsel4_12", + "GUIAm2904RegCTInstrDecode": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.am2904.GUIAm2904RegCTInstrDecode", + "GUIAm2904ShiftInstrDecode": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.am2904.GUIAm2904ShiftInstrDecode", + "GUIAm2910InstrPLA": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910InstrPLA", + "GUIAm2910RegCntr": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910RegCntr", + "GUIAm2910SP": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.am2910.GUIAm2910SP", + "GUIdff12": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUIdff12", + "GUIdff4_finewe": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUIdff4_finewe", + "GUIinc12": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUIinc12", + "GUInor12": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUInor12", + "GUIram5_12": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUIram5_12", + "GUIsel4_12": "resloader:Am2900Loader:class:net.mograsim.logic.model.am2900.components.GUIsel4_12", - "GUIAm2901": "resource:Am2900Loader:/components/am2901/GUIAm2901.json", - "GUIAm2901ALUFuncDecode": "resource:Am2900Loader:/components/am2901/GUIAm2901ALUFuncDecode.json", - "GUIAm2901ALUInclDecode": "resource:Am2900Loader:/components/am2901/GUIAm2901ALUInclDecode.json", - "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "resource:Am2900Loader:/components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json", - "GUIAm2901ALUOneBit": "resource:Am2900Loader:/components/am2901/GUIAm2901ALUOneBit.json", - "GUIAm2904": "resource:Am2900Loader:/components/am2904/GUIAm2904.json", - "GUIAm2910": "resource:Am2900Loader:/components/am2910/GUIAm2910.json", - "GUIAm2904MSR": "resource:Am2900Loader:/components/am2904/GUIAm2904MSR.json", - "GUIAm2904muSR": "resource:Am2900Loader:/components/am2904/GUIAm2904muSR.json", - "GUIAm2904TestLogic": "resource:Am2900Loader:/components/am2904/GUIAm2904TestLogic.json", - "GUIAm2901DestDecode": "resource:Am2900Loader:/components/am2901/GUIAm2901DestDecode.json", - "GUIAm2901SourceDecode": "resource:Am2900Loader:/components/am2901/GUIAm2901SourceDecode.json", - "GUI_rsLatch": "resource:Am2900Loader:/components/GUI_rsLatch.json", - "GUIand": "resource:Am2900Loader:/components/GUIand.json", - "GUIand41": "resource:Am2900Loader:/components/GUIand41.json", - "GUIandor414": "resource:Am2900Loader:/components/GUIandor414.json", - "GUIdemux2": "resource:Am2900Loader:/components/GUIdemux2.json", - "GUIdff": "resource:Am2900Loader:/components/GUIdff.json", - "GUIdff4": "resource:Am2900Loader:/components/GUIdff4.json", - "GUIdff4_invwe": "resource:Am2900Loader:/components/GUIdff4_invwe.json", - "GUIdlatch": "resource:Am2900Loader:/components/GUIdlatch.json", - "GUIdlatch4": "resource:Am2900Loader:/components/GUIdlatch4.json", - "GUIfulladder": "resource:Am2900Loader:/components/GUIfulladder.json", - "GUIhalfadder": "resource:Am2900Loader:/components/GUIhalfadder.json", - "GUImux1": "resource:Am2900Loader:/components/GUImux1.json", - "GUImux1_4": "resource:Am2900Loader:/components/GUImux1_4.json", - "GUImux2": "resource:Am2900Loader:/components/GUImux2.json", - "GUImux2_4": "resource:Am2900Loader:/components/GUImux2_4.json", - "GUImux3": "resource:Am2900Loader:/components/GUImux3.json", - "GUInand3": "resource:Am2900Loader:/components/GUInand3.json", - "GUInot4": "resource:Am2900Loader:/components/GUInot4.json", - "GUIor4": "resource:Am2900Loader:/components/GUIor4.json", - "GUIor_4": "resource:Am2900Loader:/components/GUIor_4.json", - "GUIram2": "resource:Am2900Loader:/components/GUIram2.json", - "GUIram4": "resource:Am2900Loader:/components/GUIram4.json", - "GUIsel1": "resource:Am2900Loader:/components/GUIsel1.json", - "GUIsel2_4": "resource:Am2900Loader:/components/GUIsel2_4.json", - "GUIsel3_4": "resource:Am2900Loader:/components/GUIsel3_4.json", - "GUIxor": "resource:Am2900Loader:/components/GUIxor.json" + "GUIAm2901": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901.json", + "GUIAm2901ALUFuncDecode": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901ALUFuncDecode.json", + "GUIAm2901ALUInclDecode": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901ALUInclDecode.json", + "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json", + "GUIAm2901ALUOneBit": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901ALUOneBit.json", + "GUIAm2904": "resloader:Am2900Loader:jsonres:components/am2904/GUIAm2904.json", + "GUIAm2910": "resloader:Am2900Loader:jsonres:components/am2910/GUIAm2910.json", + "GUIAm2904MSR": "resloader:Am2900Loader:jsonres:components/am2904/GUIAm2904MSR.json", + "GUIAm2904muSR": "resloader:Am2900Loader:jsonres:components/am2904/GUIAm2904muSR.json", + "GUIAm2904TestLogic": "resloader:Am2900Loader:jsonres:components/am2904/GUIAm2904TestLogic.json", + "GUIAm2901DestDecode": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901DestDecode.json", + "GUIAm2901SourceDecode": "resloader:Am2900Loader:jsonres:components/am2901/GUIAm2901SourceDecode.json", + "GUI_rsLatch": "resloader:Am2900Loader:jsonres:components/GUI_rsLatch.json", + "GUIand": "resloader:Am2900Loader:jsonres:components/GUIand.json", + "GUIand41": "resloader:Am2900Loader:jsonres:components/GUIand41.json", + "GUIandor414": "resloader:Am2900Loader:jsonres:components/GUIandor414.json", + "GUIdemux2": "resloader:Am2900Loader:jsonres:components/GUIdemux2.json", + "GUIdff": "resloader:Am2900Loader:jsonres:components/GUIdff.json", + "GUIdff4": "resloader:Am2900Loader:jsonres:components/GUIdff4.json", + "GUIdff4_invwe": "resloader:Am2900Loader:jsonres:components/GUIdff4_invwe.json", + "GUIdlatch": "resloader:Am2900Loader:jsonres:components/GUIdlatch.json", + "GUIdlatch4": "resloader:Am2900Loader:jsonres:components/GUIdlatch4.json", + "GUIfulladder": "resloader:Am2900Loader:jsonres:components/GUIfulladder.json", + "GUIhalfadder": "resloader:Am2900Loader:jsonres:components/GUIhalfadder.json", + "GUImux1": "resloader:Am2900Loader:jsonres:components/GUImux1.json", + "GUImux1_4": "resloader:Am2900Loader:jsonres:components/GUImux1_4.json", + "GUImux2": "resloader:Am2900Loader:jsonres:components/GUImux2.json", + "GUImux2_4": "resloader:Am2900Loader:jsonres:components/GUImux2_4.json", + "GUImux3": "resloader:Am2900Loader:jsonres:components/GUImux3.json", + "GUInand3": "resloader:Am2900Loader:jsonres:components/GUInand3.json", + "GUInot4": "resloader:Am2900Loader:jsonres:components/GUInot4.json", + "GUIor4": "resloader:Am2900Loader:jsonres:components/GUIor4.json", + "GUIor_4": "resloader:Am2900Loader:jsonres:components/GUIor_4.json", + "GUIram2": "resloader:Am2900Loader:jsonres:components/GUIram2.json", + "GUIram4": "resloader:Am2900Loader:jsonres:components/GUIram4.json", + "GUIsel1": "resloader:Am2900Loader:jsonres:components/GUIsel1.json", + "GUIsel2_4": "resloader:Am2900Loader:jsonres:components/GUIsel2_4.json", + "GUIsel3_4": "resloader:Am2900Loader:jsonres:components/GUIsel3_4.json", + "GUIxor": "resloader:Am2900Loader:jsonres:components/GUIxor.json" } \ No newline at end of file diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/GUIComponentTestbench.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/GUIComponentTestbench.java index 25c90ae0..fbf9f2f6 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/GUIComponentTestbench.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/GUIComponentTestbench.java @@ -5,6 +5,7 @@ import java.util.Comparator; import java.util.List; import net.mograsim.logic.model.SimpleLogicUIStandalone; +import net.mograsim.logic.model.am2900.Am2900Loader; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.model.components.atomic.GUIBitDisplay; @@ -24,8 +25,8 @@ public class GUIComponentTestbench @SuppressWarnings("unused") // for GUIWires being created public static void createTestbench(ViewModelModifiable model) { - GUIComponent comp = IndirectGUIComponentCreator.createComponent(model, - "resource:net.mograsim.logic.model.am2900.Am2900Loader:/components/GUIAm2900.json"); + Am2900Loader.setup(); + GUIComponent comp = IndirectGUIComponentCreator.createComponent(model, "resloader:Am2900Loader:jsonres:components/GUIAm2900.json"); List inputPinNames = new ArrayList<>(); List outputPinNames = new ArrayList<>(); diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java index 2f411539..179265bc 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java @@ -50,7 +50,7 @@ public class ReserializeJSONsSettingUsages try { DeserializedSubmodelComponent comp = (DeserializedSubmodelComponent) IndirectGUIComponentCreator - .createComponent(new ViewModelModifiable(), "file:" + json.toString()); + .createComponent(new ViewModelModifiable(), "jsonfile:" + json.toString()); System.out.println("Reserializing " + json); comp.getSupermodelPins().entrySet().stream().sorted(Comparator.comparing(Entry::getKey)).map(Entry::getValue).forEach(pin -> { diff --git a/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/am2904/Am2904Testbench.java b/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/am2904/Am2904Testbench.java index 48baa272..3999966d 100644 --- a/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/am2904/Am2904Testbench.java +++ b/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/am2904/Am2904Testbench.java @@ -27,7 +27,7 @@ public class Am2904Testbench { // TODO replace with proper ViewModel deserialization DeserializedSubmodelComponent testbench = (DeserializedSubmodelComponent) IndirectGUIComponentCreator.createComponent(model, - "file:GUIAm2904Testbench.json", "testbench"); + "jsonfile:GUIAm2904Testbench.json", "testbench"); testbench.setSize(1000, 1000); testbench.setOutlineRenderer(new Renderer() { diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java index e690200e..7fecf7f0 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java @@ -69,7 +69,7 @@ public class SaveLoadManager if (result != null) { new Editor((DeserializedSubmodelComponent) IndirectGUIComponentCreator.createComponent(new ViewModelModifiable(), - "file:" + result)); + "jsonfile:" + result)); } } } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ClassLoaderBasedResourceLoader.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ClassLoaderBasedResourceLoader.java new file mode 100644 index 00000000..d12c4b34 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ClassLoaderBasedResourceLoader.java @@ -0,0 +1,33 @@ +package net.mograsim.logic.model.serializing; + +import java.io.IOException; +import java.io.InputStream; + +public abstract class ClassLoaderBasedResourceLoader implements ResourceLoader +{ + @Override + public InputStream loadResource(String path) throws IOException + { + return getClassLoader().getResourceAsStream(path); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException + { + return Class.forName(name, true, getClassLoader());// TODO duplication + } + + public abstract ClassLoader getClassLoader(); + + public static ClassLoaderBasedResourceLoader create(ClassLoader loader) + { + return new ClassLoaderBasedResourceLoader() + { + @Override + public ClassLoader getClassLoader() + { + return loader; + } + }; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java index 18d6640d..2ac2c475 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; + import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; @@ -26,8 +27,10 @@ public class IndirectGUIComponentCreator private static final Map resourceLoaders = new HashMap<>(); private static final Map componentCache = new HashMap<>(); + private static final ResourceLoader defaultResourceLoader; static { + defaultResourceLoader = ClassLoaderBasedResourceLoader.create(IndirectGUIComponentCreator.class.getClassLoader()); loadStandardComponentIDs(IndirectGUIComponentCreator.class.getResourceAsStream("standardComponentIDMapping.json")); } @@ -59,7 +62,7 @@ public class IndirectGUIComponentCreator public static void addStandardComponentID(String standardComponentID, String associatedComponentID) { - if (!associatedComponentID.matches("(file|class|resource):.+")) + if (!checkIDIsValidResolvedID(associatedComponentID)) throw new IllegalArgumentException("Unrecognized component ID format: " + associatedComponentID); standardComponentIDs.put(standardComponentID, associatedComponentID); } @@ -91,93 +94,97 @@ public class IndirectGUIComponentCreator public static GUIComponent createComponent(ViewModelModifiable model, String id, JsonElement params, String name) { - if (id != null) + if (id == null) + throw new NullPointerException("Component ID is null"); + if (componentCache.containsKey(id)) + return loadComponentFromJsonObject(model, id, name, componentCache.get(id)); + String resolvedID = resolveID(id); + if (resolvedID == null) + throw new IllegalArgumentException("Unknown standard ID or illegal resolved ID: " + id); + String[] parts = resolvedID.split(":"); + String firstPart = parts[0]; + if (firstPart.equals("jsonfile")) { - if (componentCache.containsKey(id)) - return loadComponentFromJsonObject(model, id, name, componentCache.get(id)); - String resolvedID = resolveID(id); - if (resolvedID != null) + JsonObject jsonContents; + try { - if (resolvedID.startsWith("class:")) - { - String className = resolvedID.substring(6); - tryLoadComponentClass(className); - ComponentSupplier componentSupplier = componentSuppliers.get(className); - if (componentSupplier != null) - return componentSupplier.create(model, params, name); - throw new IllegalArgumentException("Component supplier not found for ID " + id + " (resolved: " + resolvedID + ")"); - } else if (params != null && !JsonNull.INSTANCE.equals(params)) - throw new IllegalArgumentException("Can't give params to a component deserialized from a JSON file"); - if (resolvedID.startsWith("resource:")) - { - String[] parts = resolvedID.split(":"); - if (parts.length != 3) - throw new IllegalArgumentException("invaild resource id: " + resolvedID); - String rLoadID = parts[1]; - String resID = parts[2]; - try - { - ResourceLoader loader; - if (!resourceLoaders.containsKey(rLoadID)) - { - Class c = Class.forName(rLoadID); - if (ResourceLoader.class.isAssignableFrom(c)) - loader = (ResourceLoader) c.getConstructor().newInstance(); - else - loader = (ResourceLoader) Objects.requireNonNull(c.getMethod("resourceLoader").invoke(null)); - resourceLoaders.put(rLoadID, loader); - } else - { - loader = Objects.requireNonNull(resourceLoaders.get(parts[1])); - } - if (resID.endsWith(".json")) - { - JsonObject jsonContents = JsonHandler.readJson(loader.loadResource(resID), JsonObject.class); - return loadComponentFromJsonObject(model, id, name, jsonContents); - } - if (!componentSuppliers.containsKey(resID)) - loader.loadClass(resID); - ComponentSupplier componentSupplier = componentSuppliers.get(resID); - if (componentSupplier != null) - return componentSupplier.create(model, params, name); - throw new IllegalArgumentException("Component supplier not found for ID " + id + " (class cannot initialize?)"); - } - catch (IOException e) - { - throw new UncheckedIOException(e); - } - catch (ClassCastException | ReflectiveOperationException e) - { - throw new IllegalArgumentException("class not found / invaild resource loader specified:" + parts[1], e); - } - } else if (resolvedID.startsWith("file:")) + // don't use parts[1], because the path could contain ':' + jsonContents = JsonHandler.readJson(resolvedID.substring("jsonfile:".length()), JsonObject.class); + } + catch (IOException e) + { + throw new UncheckedIOException("Error loading JSON file", e); + } + return loadComponentFromJsonObject(model, id, name, jsonContents); + } + ResourceLoader loader; + String resTypeID; + String resID; + if (firstPart.equals("resloader")) + { + String loaderID = parts[1]; + loader = resourceLoaders.get(loaderID); + if (loader == null) + tryLoadResourceLoader(loaderID); + loader = resourceLoaders.get(loaderID); + if (loader == null) + throw new IllegalArgumentException( + "Unknown resource loader: " + loaderID + " (but class was found. Probably the static initializer is missing)"); + resTypeID = parts[2]; + resID = parts[3]; + } else + { + loader = defaultResourceLoader; + resTypeID = parts[0]; + resID = parts[1]; + } + if (resTypeID.equals("jsonres")) + { + JsonObject jsonContents; + try + { + @SuppressWarnings("resource") // jsonStream is closed in JsonHandler + InputStream jsonStream = Objects.requireNonNull(loader.loadResource(resID), "Error loading JSON resource: Not found"); + jsonContents = JsonHandler.readJson(jsonStream, JsonObject.class); + } + catch (IOException e) + { + throw new UncheckedIOException("Error loading JSON resource", e); + } + return loadComponentFromJsonObject(model, id, name, jsonContents); + } else if (resTypeID.equals("class")) + { + ComponentSupplier componentSupplier = componentSuppliers.get(resID); + if (componentSupplier == null) + try { - try - { - String filename = resolvedID.substring(5); - JsonObject jsonContents = JsonHandler.readJson(filename, JsonObject.class); - return loadComponentFromJsonObject(model, id, name, jsonContents); - } - catch (IOException e) - { - throw new UncheckedIOException(e); - } - } else + loader.loadClass(resID); + } + catch (@SuppressWarnings("unused") ClassNotFoundException e) { - throw new IllegalArgumentException("unable to resolve/interpret id" + resolvedID); + throw new IllegalArgumentException("Unknown component supplier: " + resID); } - } - } - throw new RuntimeException("Could not get component supplier for ID " + id); + componentSupplier = componentSuppliers.get(resID); + if (componentSupplier == null) + throw new IllegalArgumentException( + "Unknown component supplier: " + resID + " (but class was found. Probably the static initializer is missing)"); + return componentSupplier.create(model, params, name); + } else + throw new IllegalStateException("Unknown resource type ID: " + resTypeID); } public static String resolveID(String id) { - if (id.matches("(file|class|resource):.+")) + if (checkIDIsValidResolvedID(id)) return id; return standardComponentIDs.get(id); } + private static boolean checkIDIsValidResolvedID(String id) + { + return id.matches("jsonfile:(.+)|(resloader:([^:]+):)?(jsonres|class):[^:]+"); + } + private static SubmodelComponent loadComponentFromJsonObject(ViewModelModifiable model, String id, String name, JsonObject jsonContents) { componentCache.putIfAbsent(id, jsonContents); @@ -204,9 +211,9 @@ public class IndirectGUIComponentCreator resourceLoaders.put(reference, Objects.requireNonNull(resourceLoader)); } - private static void tryLoadComponentClass(String componentClassName) + private static void tryLoadResourceLoader(String loaderClassName) { - CodeSnippetSupplier.tryInvokeStaticInitializer(componentClassName, "Error loading component class %s: %s\n"); + CodeSnippetSupplier.tryInvokeStaticInitializer(loaderClassName, "Error loading resoruce loader %s: %s\n"); } public static interface ComponentSupplier diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ResourceLoader.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ResourceLoader.java index 1052d5fb..ff7fd07f 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ResourceLoader.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/ResourceLoader.java @@ -7,15 +7,6 @@ import net.mograsim.logic.model.model.components.GUIComponent; /** * For loading JSON {@link GUIComponent}s from other OSGI-Modules or jar-Files. - *

- * An implementation must conform to either of the following rules: - *

    - *
  • A ResourceLoader class can be referenced directly in resource:qualifiedClassName:jsonResourcePath and is then - * instantiated using the public default constructor.
  • - *
  • A class referenced in resource:qualifiedClassName:jsonResourcePath provides a public static method called - * resourceLoader that returns an (non-null) object of the type {@link ResourceLoader}
  • - *
- * */ public interface ResourceLoader {