1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package de.desy.acop.transport.adapters;
24
25 import java.beans.PropertyVetoException;
26 import java.util.ArrayList;
27 import java.util.LinkedHashMap;
28 import java.util.Map;
29
30 import com.cosylab.gui.adapters.DataSourceJoint;
31 import com.cosylab.gui.displayers.DataConsumer;
32 import com.cosylab.gui.displayers.DataSource;
33 import com.cosylab.gui.displayers.DataState;
34 import com.cosylab.gui.displayers.DoubleSeqConsumer;
35 import com.cosylab.util.CommonException;
36
37
38
39
40
41
42
43
44
45
46
47 public class AcopDataSourceJoint extends AcopTransportDataSource implements DataSourceJoint<AcopTransportDataSource>{
48
49 private static final long serialVersionUID = 1099113487965270874L;
50
51 protected class DataSourceWrapper {
52
53 protected AcopTransportDataSource dataSource;
54 protected String identifier;
55 protected double[] lastValue = null;
56 public DataSourceWrapper(AcopTransportDataSource source, String identifier) throws PropertyVetoException {
57 this.dataSource = source;
58 this.identifier = identifier;
59 source.addConsumer(new DoubleSeqConsumer() {
60
61 public void updateValue(long timestamp, double[] value) throws CommonException {
62 DataSourceWrapper.this.lastValue = new double[value.length];
63 System.arraycopy(value, 0, lastValue, 0, value.length);
64 updateConsumers(timestamp);
65
66 }
67
68 @SuppressWarnings("unchecked")
69 public DataConsumer getDataConsumer(Class type) {
70 if (type.isAssignableFrom(DoubleSeqConsumer.class)) {
71 return this;
72 }
73 return null;
74
75 }
76
77 public DataConsumer getDefaultDataConsumer() {
78
79 return this;
80 }
81
82 public String getName() {
83
84 return null;
85 }
86
87 public String[] getSupportedCharacteristics() {
88
89 return null;
90 }
91
92 @SuppressWarnings("unchecked")
93 public Class<DataConsumer>[] getSupportedConsumerTypes() {
94 return new Class[]{DoubleSeqConsumer.class};
95 }
96
97 @SuppressWarnings("unchecked")
98 public void setCharacteristics(Map characteristics) {
99
100
101 }
102
103 public void updateDataState(DataState state) {
104
105
106 }
107
108 });
109 }
110
111 }
112
113 protected ArrayList<DataSourceWrapper> dataSources;
114
115
116
117
118
119 public AcopDataSourceJoint() {
120 super();
121 dataSources = new ArrayList<DataSourceWrapper>();
122 }
123
124
125
126
127
128 public Map<AcopTransportDataSource, String> getDataSources() {
129 LinkedHashMap<AcopTransportDataSource, String> map = new LinkedHashMap<AcopTransportDataSource, String>();
130 for (DataSourceWrapper w : dataSources) {
131 map.put(w.dataSource,w.identifier);
132 }
133
134 return map;
135 }
136
137
138
139
140
141 public String removeDataSource(AcopTransportDataSource dataSource) {
142 for (DataSourceWrapper w: dataSources) {
143 if (w.dataSource.equals(dataSource)) {
144 return w.identifier;
145 }
146 }
147 return null;
148 }
149
150
151
152
153
154 public void addDataSource(AcopTransportDataSource dataSource, String operation) throws PropertyVetoException {
155 addDataSource(dataSource, operation, dataSources.size());
156 }
157
158 private boolean isDataSourceAccepted(AcopTransportDataSource dataSource) {
159 Class<?>[] supported = dataSource.getAcceptableConsumerTypes();
160 Class<?>[] existing = getAcceptableConsumerTypes();
161 for (Class<?> ex : existing) {
162 boolean exist = false;
163 for (Class<?> sup : supported) {
164 if (ex.equals(sup)) {
165 exist = true;
166 break;
167 }
168 }
169 if (!exist) return false;
170 }
171
172 return true;
173 }
174
175
176
177
178
179 public void addDataSource(AcopTransportDataSource dataSource, String operation, int index) throws PropertyVetoException {
180 if (index > dataSources.size())
181 throw new IllegalArgumentException("Invalid index. It should be less or equal " +
182 "to " + dataSources.size() + ".");
183 if (!isDataSourceAccepted(dataSource))
184 throw new IllegalArgumentException("Given DataSource does not support all " +
185 "characteristics supported by this class.");
186
187 if (index == 0 || operation == null || (operation.equals(FIRST_IN_A_ROW) && index != 0)) {
188 operation = FIRST_IN_A_ROW;
189 if (dataSources.size() > 0)
190 dataSources.remove(0);
191 dataSources.add(0, new DataSourceWrapper(dataSource, operation));
192 return;
193 }
194
195 DataSourceWrapper wrapper = new DataSourceWrapper(dataSource, operation);
196 dataSources.add(index, wrapper);
197 }
198
199 private void updateConsumers(long timestamp) {
200 if (dataSources.get(0).lastValue == null) return;
201 double[] d = new double[dataSources.get(0).lastValue.length];
202 System.arraycopy(dataSources.get(0).lastValue, 0, d, 0, d.length);
203
204 for (int i = 1; i < dataSources.size(); i++) {
205 if (dataSources.get(i).lastValue == null) return;
206 operate(d, dataSources.get(i).lastValue, dataSources.get(i).identifier);
207 }
208
209 DoubleSeqConsumer[] dsc= (DoubleSeqConsumer[])dcon.toArray();
210 for (int i = 0; i < dsc.length; i++) {
211 try {
212
213 dsc[i].updateValue(timestamp,d);
214 } catch (Exception e) {
215 e.printStackTrace();
216 }
217 }
218 }
219
220 private void operate(double[] higherChain, double[] values, String operation) {
221 if (higherChain.length != values.length)
222 throw new IllegalArgumentException("Array length does not match");
223 if (operation.equals(ADD)) {
224 for (int i = 0; i < higherChain.length; i++) {
225 higherChain[i] += values[i];
226 }
227 } else if (operation.equals(SUBSTRACT)) {
228 for (int i = 0; i < higherChain.length; i++) {
229 higherChain[i] -= values[i];
230 }
231 } else if (operation.equals(MULTIPLY)) {
232 for (int i = 0; i < higherChain.length; i++) {
233 higherChain[i] *= values[i];
234 }
235 } else if (operation.equals(DIVIDE)) {
236 for (int i = 0; i < higherChain.length; i++) {
237 if (values[i] == 0)
238 higherChain[i] = higherChain[i] > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
239 else if (Double.isInfinite(values[i]))
240 higherChain[i] = 0;
241 else if (Double.isNaN(values[i]))
242 higherChain[i] = Double.NaN;
243 else
244 higherChain[i] /= values[i];
245 }
246 }
247 }
248
249
250
251
252
253 public void addConsumer(DataConsumer consumer) throws PropertyVetoException {
254 super.addConsumer(consumer);
255
256 if (consumer instanceof DataSource) {
257 ((DataSource)consumer).removeConsumer(getReverseConsumer());
258 }
259
260 }
261 }