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
{
{
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());
- }
- }
}
{
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;
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
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;
@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<String> inputPinNames = new ArrayList<>();
List<String> outputPinNames = new ArrayList<>();
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 ->
{
{
// 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()
{
if (result != null)
{
new Editor((DeserializedSubmodelComponent) IndirectGUIComponentCreator.createComponent(new ViewModelModifiable(),
- "file:" + result));
+ "jsonfile:" + result));
}
}
}
--- /dev/null
+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
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;
private static final Map<String, ResourceLoader> resourceLoaders = new HashMap<>();
private static final Map<String, JsonObject> componentCache = new HashMap<>();
+ private static final ResourceLoader defaultResourceLoader;
static
{
+ defaultResourceLoader = ClassLoaderBasedResourceLoader.create(IndirectGUIComponentCreator.class.getClassLoader());
loadStandardComponentIDs(IndirectGUIComponentCreator.class.getResourceAsStream("standardComponentIDMapping.json"));
}
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);
}
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);
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
/**
* For loading JSON {@link GUIComponent}s from other OSGI-Modules or jar-Files.
- * <p>
- * An implementation must conform to either of the following rules:
- * <ul>
- * <li>A ResourceLoader class can be referenced directly in <code>resource:qualifiedClassName:jsonResourcePath</code> and is then
- * instantiated using the public default constructor.</li>
- * <li>A class referenced in <code>resource:qualifiedClassName:jsonResourcePath</code> provides a public static method called
- * <b><code>resourceLoader</code></b> that returns an (non-null) object of the type {@link ResourceLoader}</li>
- * </ul>
- *
*/
public interface ResourceLoader
{