Equivalent inner components now exchangeable. Fixed in/output pin order.
[Mograsim.git] / net.mograsim.logic.ui / src / net / mograsim / logic / ui / model / components / GUIComponentCreator.java
1 package net.mograsim.logic.ui.model.components;
2
3 import java.io.IOException;
4 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException;
6 import java.util.HashMap;
7 import java.util.Map;
8
9 import net.mograsim.logic.ui.model.ViewModelModifiable;
10 import net.mograsim.logic.ui.model.wires.WireCrossPoint;
11 import net.mograsim.logic.ui.util.JsonHandler;
12
13 public class GUIComponentCreator
14 {
15         private final static Map<String, String> componentMapping;
16         private final static String componentMappingPath = "components/mapping.json"; // TODO: manage this somewhere else
17
18         static
19         {
20                 Map<String, String> tmp;
21                 try
22                 {
23                         tmp = JsonHandler.readJson(componentMappingPath, Map.class);
24                 }
25                 catch (IOException e)
26                 {
27                         System.err.println("Failed to initialize component mapping; Components cannot be created from file.");
28                         e.printStackTrace();
29                         tmp = new HashMap<>();
30                 }
31                 componentMapping = tmp;
32         }
33
34         public static GUIComponent create(ViewModelModifiable model, String name, Map<String, Object> params)
35         {
36                 try
37                 {
38                         String path = componentMapping.get(name);
39                         if (path.startsWith("class:"))
40                         {
41                                 path = path.substring(6);
42                                 return createComponentFromClass(model, path, params);
43                         } else if (path.startsWith("file:"))
44                         {
45                                 path = path.substring(5);
46                                 return GUICustomComponentCreator.create(model, path);
47                         } else
48                                 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
49                 }
50                 catch (NullPointerException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
51                                 | SecurityException | ClassNotFoundException | IllegalArgumentException e)
52                 {
53                         System.err.println("Failed to create requested component!");
54                         e.printStackTrace();
55                         return new SimpleRectangularSubmodelComponent(model, 1, "ERROR");
56                 }
57         }
58
59         private static GUIComponent createComponentFromClass(ViewModelModifiable model, String classname, Map<String, Object> params)
60                         throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
61                         ClassNotFoundException
62         {
63                 Class<?> c = Class.forName(classname);
64                 Object comp;
65                 if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
66                 {
67                         Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
68                         comp = constructor.newInstance(model, ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
69                 } else
70                 {
71                         Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
72                         comp = constructor.newInstance(model);
73                 }
74                 return (GUIComponent) comp;
75         }
76 }