Skip to main content
summaryrefslogtreecommitdiffstats
blob: 6b2a70bf931fa5e3e22504172bd496d81700dd59 (plain) (blame)
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/********************************************************************************
 * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/


package org.eclipse.mdm.api.base.massdata;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.mdm.api.base.model.AxisType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ScalarType;
import org.eclipse.mdm.api.base.model.SequenceRepresentation;
import org.eclipse.mdm.api.base.model.Unit;

/**
 * Holds required data to write mass data.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
 */
public final class WriteRequest {

	// ======================================================================
	// Instance variables
	// ======================================================================

	private final List<ExternalComponent> externalComponents = new ArrayList<>();
	private final ChannelGroup channelGroup;
	private final Channel channel;
	private final AxisType axisType;

	private SequenceRepresentation sequenceRepresentation;
	private double[] generationParameters;
	private boolean independent;

	private ScalarType rawScalarType;
	private Object values;
	private boolean allValid;
	private boolean[] flags;

	// ======================================================================
	// Constructors
	// ======================================================================

	/**
	 * Constructor.
	 *
	 * @param channelGroup
	 *            The {@link ChannelGroup} for this request.
	 * @param channel
	 *            The {@link Channel} specified mass data will be dedicated to.
	 * @param axisType
	 *            The {@link AxisType} of the written mass data.
	 */
	private WriteRequest(ChannelGroup channelGroup, Channel channel, AxisType axisType) {
		this.channelGroup = channelGroup;
		this.channel = channel;
		this.axisType = axisType;
	}

	// ======================================================================
	// Public methods
	// ======================================================================

	/**
	 * Starts a new {@link WriteRequest} by returning a
	 * {@link WriteRequestBuilder}.
	 *
	 * @param channelGroup
	 *            The {@link ChannelGroup} for this request.
	 * @param channel
	 *            The {@link Channel} specified mass data will be dedicated to.
	 * @param axisType
	 *            The {@link AxisType} of the written mass data.
	 * @return A {@code WriteRequestBuilder} is returned.
	 */
	public static WriteRequestBuilder create(ChannelGroup channelGroup, Channel channel, AxisType axisType) {
		return new WriteRequestBuilder(new WriteRequest(channelGroup, channel, axisType));
	}

	/**
	 * Returns the {@link ChannelGroup} of this request.
	 *
	 * @return The {@code ChannelGroup} is returned.
	 */
	public ChannelGroup getChannelGroup() {
		return channelGroup;
	}

	/**
	 * Returns the {@link Channel} of this request.
	 *
	 * @return The {@code Channel} is returned.
	 */
	public Channel getChannel() {
		return channel;
	}

	/**
	 * Returns the {@link AxisType} of this request.
	 *
	 * @return The {@code AxisType} is returned.
	 */
	public AxisType getAxisType() {
		return axisType;
	}

	/**
	 * Returns the {@link SequenceRepresentation} of this request.
	 *
	 * @return The {@code SequenceRepresentation} is returned.
	 */
	public SequenceRepresentation getSequenceRepresentation() {
		return sequenceRepresentation;
	}

	/**
	 * Returns the generation parameters of this request. The length of the
	 * returned array depends on the {@link SequenceRepresentation} of this
	 * request.
	 *
	 * <p>
	 * <b>NOTE:</b> In case of an implicit sequence representation this method
	 * will always return an empty array since these generation parameters are
	 * correctly typed and stored as measured values.
	 *
	 * @return If none available, then an empty array is returned.
	 */
	public double[] getGenerationParameters() {
		return generationParameters == null ? new double[0] : generationParameters.clone();
	}

	/**
	 * Returns the independent flag of this request.
	 *
	 * @return Returns {@code true} if the measured values do not depend on
	 *         those of other {@link Channel}s within their common
	 *         {@link ChannelGroup}.
	 */
	public boolean isIndependent() {
		return independent;
	}

	/**
	 * Checks whether this request has measured values.
	 *
	 * @return Returns {@code true} if
	 *         {@link SequenceRepresentation#isExternal()} returns
	 *         {@code false}.
	 * @see #hasExternalComponents()
	 */
	public boolean hasValues() {
		return !getSequenceRepresentation().isExternal();
	}

	/**
	 * Returns the stored measured values.
	 *
	 * @return The measured values are returned.
	 * @throws IllegalStateException
	 *             Thrown if values are not available.
	 */
	public Object getValues() {
		if (hasValues()) {
			return values;
		}

		throw new IllegalStateException("Values are not available.");
	}

	/**
	 * Checks whether this request has measured values, stored in externally
	 * linked files.
	 *
	 * @return Returns {@code true} if
	 *         {@link SequenceRepresentation#isExternal()} returns {@code true}.
	 * @see #hasValues()
	 */
	public boolean hasExternalComponents() {
		return getSequenceRepresentation().isExternal();
	}

	/**
	 * Returns the configurations for measured values stored in externally
	 * referenced files.
	 * 
	 * @return Returned {@code List} is unmodifiable.
	 * @throws IllegalStateException
	 *             Thrown if configurations are not available.
	 */
	public List<ExternalComponent> getExternalComponents() {
		if (!hasExternalComponents()) {
			throw new IllegalStateException("External components are not available.");
		}

		return Collections.unmodifiableList(externalComponents);
	}

	/**
	 * Returns the {@link ScalarType} of the stored measured value sequence.
	 *
	 * @return The raw {@code ScalarType} is returned.
	 */
	public ScalarType getRawScalarType() {
		return rawScalarType;
	}

	/**
	 * Returns the calculated {@link ScalarType} which reflects the final
	 * {@code ScalarType} of the generated measured value sequence. If
	 * {@link #getGenerationParameters()} returns a not empty array and
	 * {@link #getRawScalarType()} is an integer type (byte, short, int, long),
	 * then the returned {@code ScalarType} is bumped to the next suitable
	 * floating point type as listed below:
	 *
	 * <ul>
	 * <li>{@link ScalarType#BYTE} -&gt; {@link ScalarType#FLOAT}</li>
	 * <li>{@link ScalarType#SHORT} -&gt; {@link ScalarType#FLOAT}</li>
	 * <li>{@link ScalarType#INTEGER} -&gt; {@link ScalarType#FLOAT}</li>
	 * <li>{@link ScalarType#LONG} -&gt; {@link ScalarType#DOUBLE}</li>
	 * </ul>
	 *
	 * @return The calculated {@code ScalarType} is returned.
	 */
	public ScalarType getCalculatedScalarType() {
		if (getGenerationParameters().length > 0 && getRawScalarType().isIntegerType()) {
			return getRawScalarType().isLong() ? ScalarType.DOUBLE : ScalarType.FLOAT;
		}

		return getRawScalarType();
	}

	/**
	 * Checks whether all measured values within the whole sequence are valid.
	 * If this method returns {@code true}, then {@link #getFlags()} will return
	 * an empty array.
	 *
	 * @return Returns {@code true} if all measured values are valid.
	 * @see #getFlags()
	 */
	public boolean areAllValid() {
		return allValid;
	}

	/**
	 * Returns the validity flags sequence for the stored measured values. If
	 * {@link #areAllValid()} returns {@code false} this method will return an
	 * array with the same length as the measured values sequence, where each
	 * flag indicates whether the corresponding measured value is valid or not.
	 *
	 * @return The validity flags sequence is returned.
	 * @see #allValid
	 */
	public boolean[] getFlags() {
		return flags.clone();
	}

	// ======================================================================
	// Package methods
	// ======================================================================

	/**
	 * Sets the {@link SequenceRepresentation} for this request.
	 *
	 * @param sequenceRepresentation
	 *            The {@link SequenceRepresentation}.
	 */
	void setSequenceRepresentation(SequenceRepresentation sequenceRepresentation) {
		this.sequenceRepresentation = sequenceRepresentation;
	}

	/**
	 * Sets generation parameters for this request.
	 *
	 * @param generationParameters
	 *            The generation parameters.
	 */
	void setGenerationParameters(double[] generationParameters) {
		this.generationParameters = generationParameters.clone();
	}

	/**
	 * Sets the independent flag for this request.
	 */
	void setIndependent() {
		independent = true;
	}

	/**
	 * Triggers an adjustment of the generation parameters and modification of
	 * the {@link SequenceRepresentation} of this request to match the
	 * {@link Channel}s default {@link Unit}.
	 *
	 * @param sourceUnit
	 *            The {@link Unit} of the measured values.
	 */
	void setSourceUnit(Unit sourceUnit) {
		throw new UnsupportedOperationException("Conversion between units is not implemented yet.");
	}

	/**
	 * Sets the raw {@link ScalarType} for this request.
	 *
	 * @param rawScalarType
	 *            The {@link ScalarType}.
	 */
	void setRawScalarType(ScalarType rawScalarType) {
		this.rawScalarType = rawScalarType;
	}

	/**
	 * Sets the measured values sequence where each value in the sequence is
	 * expected to be valid.
	 *
	 * @param values
	 *            The measured value sequence.
	 * @throws IllegalStateException
	 *             Thrown if {@link #hasValues()} returns {@code false}.
	 */
	void setValues(Object values) {
		if (hasValues()) {
			this.values = values;
			allValid = true;
		} else {
			throw new IllegalStateException("Measured values stored in externally linked files expected.");
		}
	}

	/**
	 * Sets the measured values sequence where each value's validity is
	 * specified in the given flags array.
	 *
	 * @param values
	 *            The measured value sequence.
	 * @param flags
	 *            The validity flag sequence.
	 * @throws IllegalStateException
	 *             Thrown if {@link #hasValues()} returns {@code false}.
	 */
	void setValues(Object values, boolean[] flags) {
		if (hasValues()) {
			this.values = values;
			this.flags = flags.clone();
		} else {
			throw new IllegalStateException("Measured values stored in externally linked files expected.");
		}
	}

	/**
	 * Adds a configuration for measured values stored in externally linked
	 * files.
	 *
	 * @param externalComponent
	 *            The new configuration.
	 * @throws IllegalStateException
	 *             Thrown if {@link #hasExternalComponents()} returns
	 *             {@code false}.
	 */
	void addExternalComponent(ExternalComponent externalComponent) {
		if (hasExternalComponents()) {
			externalComponents.add(externalComponent);
		} else {
			throw new IllegalStateException("Measured values expected");
		}
	}

}

Back to the top