/
DefaultAnalogExpressionManagerXml.java
193 lines (169 loc) · 8.11 KB
/
DefaultAnalogExpressionManagerXml.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package jmri.jmrit.logixng.implementation.configurexml;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import jmri.ConfigureManager;
import jmri.InstanceManager;
import jmri.configurexml.JmriConfigureXmlException;
import jmri.jmrit.logixng.*;
import jmri.jmrit.logixng.implementation.DefaultAnalogExpressionManager;
import jmri.jmrit.logixng.implementation.DefaultMaleAnalogExpressionSocket;
import jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML;
import jmri.util.ThreadingUtil;
import org.jdom2.Element;
/**
* Provides the functionality for configuring ExpressionManagers
*
* @author Dave Duchamp Copyright (c) 2007
* @author Daniel Bergqvist Copyright (c) 2018
*/
public class DefaultAnalogExpressionManagerXml extends AbstractManagerXml {
private final Map<String, Class<?>> xmlClasses = new HashMap<>();
public DefaultAnalogExpressionManagerXml() {
}
/**
* Default implementation for storing the contents of a LogixManager
*
* @param o Object to store, of type LogixManager
* @return Element containing the complete info
*/
@Override
public Element store(Object o) {
Element expressions = new Element("LogixNGAnalogExpressions");
setStoreElementClass(expressions);
AnalogExpressionManager tm = (AnalogExpressionManager) o;
if (tm != null) {
for (MaleAnalogExpressionSocket expression : tm.getNamedBeanSet()) {
log.debug("expression system name is " + expression.getSystemName()); // NOI18N
// log.error("expression system name is " + expression.getSystemName() + ", " + expression.getLongDescription()); // NOI18N
try {
List<Element> elements = new ArrayList<>();
// The male socket may be embedded in other male sockets
MaleAnalogExpressionSocket a = expression;
while (!(a instanceof DefaultMaleAnalogExpressionSocket)) {
elements.add(storeMaleSocket(a));
a = (MaleAnalogExpressionSocket) a.getObject();
}
Element e = jmri.configurexml.ConfigXmlManager.elementFromObject(a.getObject());
if (e != null) {
for (Element ee : elements) e.addContent(ee);
// e.addContent(storeMaleSocket(expression));
expressions.addContent(e);
} else {
throw new RuntimeException("Cannot load xml configurator for " + a.getObject().getClass().getName());
}
} catch (RuntimeException e) {
log.error("Error storing action: {}", e, e);
}
}
}
return (expressions);
}
/**
* Subclass provides implementation to create the correct top element,
* including the type information. Default implementation is to use the
* local class here.
*
* @param expressions The top-level element being created
*/
public void setStoreElementClass(Element expressions) {
expressions.setAttribute("class", this.getClass().getName()); // NOI18N
}
/**
* Create a AnalogExpressionManager object of the correct class, then
* register and fill it.
*
* @param sharedExpression Shared top level Element to unpack.
* @param perNodeExpression Per-node top level Element to unpack.
* @return true if successful
*/
@Override
public boolean load(Element sharedExpression, Element perNodeExpression) {
// create the master object
replaceExpressionManager();
// load individual sharedLogix
loadExpressions(sharedExpression);
return true;
}
/**
* Utility method to load the individual Logix objects. If there's no
* additional info needed for a specific logix type, invoke this with the
* parent of the set of Logix elements.
*
* @param expressions Element containing the Logix elements to load.
*/
public void loadExpressions(Element expressions) {
List<Element> expressionList = expressions.getChildren(); // NOI18N
log.debug("Found " + expressionList.size() + " actions"); // NOI18N
for (int i = 0; i < expressionList.size(); i++) {
String className = expressionList.get(i).getAttribute("class").getValue();
// log.error("className: " + className);
Class<?> clazz = xmlClasses.get(className);
if (clazz == null) {
try {
clazz = Class.forName(className);
xmlClasses.put(className, clazz);
} catch (ClassNotFoundException ex) {
log.error("cannot load class " + className, ex);
}
}
if (clazz != null) {
Constructor<?> c = null;
try {
c = clazz.getConstructor();
} catch (NoSuchMethodException | SecurityException ex) {
log.error("cannot create constructor", ex);
}
if (c != null) {
try {
AbstractNamedBeanManagerConfigXML o = (AbstractNamedBeanManagerConfigXML)c.newInstance();
MaleSocket oldLastItem = InstanceManager.getDefault(AnalogExpressionManager.class).getLastRegisteredMaleSocket();
o.load(expressionList.get(i), null);
// Load male socket data if a new bean has been registered
MaleSocket newLastItem = InstanceManager.getDefault(AnalogExpressionManager.class).getLastRegisteredMaleSocket();
if (newLastItem != oldLastItem) loadMaleSocket(expressionList.get(i), newLastItem);
else throw new RuntimeException("No new bean has been added. This class: "+getClass().getName());
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
log.error("cannot create object", ex);
} catch (JmriConfigureXmlException ex) {
log.error("cannot load action", ex);
}
}
}
}
}
/**
* Replace the current LogixManager, if there is one, with one newly created
* during a load operation. This is skipped if they are of the same absolute
* type.
*/
protected void replaceExpressionManager() {
if (InstanceManager.getDefault(AnalogExpressionManager.class).getClass().getName()
.equals(DefaultAnalogExpressionManager.class.getName())) {
return;
}
// if old manager exists, remove it from configuration process
if (InstanceManager.getNullableDefault(AnalogExpressionManager.class) != null) {
ConfigureManager cmOD = InstanceManager.getNullableDefault(jmri.ConfigureManager.class);
if (cmOD != null) {
cmOD.deregister(InstanceManager.getDefault(AnalogExpressionManager.class));
}
}
ThreadingUtil.runOnGUI(() -> {
// register new one with InstanceManager
DefaultAnalogExpressionManager pManager = DefaultAnalogExpressionManager.instance();
InstanceManager.store(pManager, AnalogExpressionManager.class);
// register new one for configuration
ConfigureManager cmOD = InstanceManager.getNullableDefault(jmri.ConfigureManager.class);
if (cmOD != null) {
cmOD.registerConfig(pManager, jmri.Manager.LOGIXNG_ANALOG_EXPRESSIONS);
}
});
}
@Override
public int loadOrder() {
return InstanceManager.getDefault(AnalogExpressionManager.class).getXMLOrder();
}
private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultAnalogExpressionManagerXml.class);
}