Renamed logic.ui to logic.model
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / serializing / CodeSnippetSupplier.java
1 package net.mograsim.logic.model.serializing;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import net.mograsim.logic.model.serializing.snippets.HighLevelStateHandler;
9 import net.mograsim.logic.model.serializing.snippets.Renderer;
10 import net.mograsim.logic.model.serializing.snippets.SnippetSupplier;
11 import net.mograsim.logic.model.serializing.snippets.highlevelstatehandlers.DefaultHighLevelStateHandler;
12 import net.mograsim.logic.model.serializing.snippets.outlinerenderers.DefaultOutlineRenderer;
13 import net.mograsim.logic.model.serializing.snippets.symbolrenderers.DefaultSymbolRenderer;
14 import net.mograsim.logic.model.util.JsonHandler;
15
16 public class CodeSnippetSupplier<S>
17 {
18         // public static members
19         public static final CodeSnippetSupplier<Renderer> symbolRendererSupplier;
20         public static final CodeSnippetSupplier<Renderer> outlineRendererSupplier;
21         public static final CodeSnippetSupplier<HighLevelStateHandler> highLevelStateHandlerSupplier;
22
23         static
24         {
25                 symbolRendererSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultSymbolRenderer::new));
26                 outlineRendererSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultOutlineRenderer::new));
27                 highLevelStateHandlerSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultHighLevelStateHandler::new));
28         }
29
30         // per-instance members
31
32         private final Map<String, String> standardSnippetIDClassNames = new HashMap<>();
33         private final Map<String, SnippetSupplier<?, S>> snippetSuppliersForClassNames = new HashMap<>();
34         private final SnippetSupplier<?, S> defaultSnippetSupplier;
35
36         private CodeSnippetSupplier(SnippetSupplier<?, S> defaultSnippetSupplier)
37         {
38                 this.defaultSnippetSupplier = defaultSnippetSupplier;
39         }
40
41         public void addStandardSnippetID(String standardSnippetID, String associatedSnippetClassName)
42         {
43                 standardSnippetIDClassNames.put(standardSnippetID, associatedSnippetClassName);
44         }
45
46         public void setSnippetSupplier(String id, SnippetSupplier<?, S> snippetSupplier)
47         {
48                 snippetSuppliersForClassNames.put(id, snippetSupplier);
49         }
50
51         // TODO report errors
52         public SnippetSupplier<?, S> getSnippetSupplier(String id)
53         {
54                 if (id != null)
55                 {
56                         String snippetClassName;
57                         if (id.startsWith("class:"))
58                                 snippetClassName = id.substring(6);
59                         else
60                                 snippetClassName = standardSnippetIDClassNames.get(id);
61                         if (snippetClassName != null)
62                         {
63                                 tryLoadSnippetClass(snippetClassName);
64                                 SnippetSupplier<?, S> snippetSupplier = snippetSuppliersForClassNames.get(snippetClassName);
65                                 if (snippetSupplier != null)
66                                         return snippetSupplier;
67                         }
68                         System.err.println("Couldn't load snippet " + id + "; using default");
69                 }
70                 return defaultSnippetSupplier;
71         }
72
73         // static helpers
74
75         static
76         {
77                 try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./standardSnippetIDMapping.json"))
78                 {
79                         if (s == null)
80                                 throw new IOException("Resource not found");
81                         SnippetIDClassNames tmp = JsonHandler.readJson(s, SnippetIDClassNames.class);
82                         tmp.standardOutlineRendererSuppliers.forEach(outlineRendererSupplier::addStandardSnippetID);
83                         tmp.standardSymbolRendererSuppliers.forEach(symbolRendererSupplier::addStandardSnippetID);
84                         tmp.standardHighLevelStateHandlerSuppliers.forEach(highLevelStateHandlerSupplier::addStandardSnippetID);
85                 }
86                 catch (Exception e)
87                 {
88                         System.err.println("Failed to initialize standard snippet ID mapping: ");
89                         e.printStackTrace();
90                 }
91         }
92
93         private static class SnippetIDClassNames
94         {
95                 public Map<String, String> standardOutlineRendererSuppliers;
96                 public Map<String, String> standardSymbolRendererSuppliers;
97                 public Map<String, String> standardHighLevelStateHandlerSuppliers;
98         }
99
100         private static void tryLoadSnippetClass(String snippetClassName)
101         {
102                 tryInvokeStaticInitializer(snippetClassName, "Error getting snippet class: %s: %s\n");
103         }
104
105         public static void tryInvokeStaticInitializer(String className, String errorMessageFormat)
106         {
107                 try
108                 {
109                         Class.forName(className, true, CodeSnippetSupplier.class.getClassLoader());
110                 }
111                 catch (ClassNotFoundException e)
112                 {
113                         System.err.printf(errorMessageFormat, className, "ClassNotFoundException thrown: " + e.getMessage());
114                 }
115         }
116
117 }