-
Notifications
You must be signed in to change notification settings - Fork 4
/
AbstractObservableStateAdapter.java
157 lines (142 loc) · 4.27 KB
/
AbstractObservableStateAdapter.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
/* **************************************************************************************
* Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/
*
* 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 2.0 which is available at http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
************************************************************************************** */
package org.eclipse.keyple.core.service;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* Abstract class for all states of a {@link ObservableLocalReaderAdapter}.
*
* @since 2.0.0
*/
abstract class AbstractObservableStateAdapter {
/**
* The states that the reader monitoring state machine can have
*
* @since 2.0.0
*/
enum MonitoringState {
/**
* The reader is idle and waiting for a start signal to enter the card detection mode.
*
* @since 2.0.0
*/
WAIT_FOR_START_DETECTION,
/**
* The reader is in card detection mode and is waiting for a card to be presented.
*
* @since 2.0.0
*/
WAIT_FOR_CARD_INSERTION,
/**
* The reader waits for the application to finish processing the card.
*
* @since 2.0.0
*/
WAIT_FOR_CARD_PROCESSING,
/**
* The reader waits for the removal of the card.
*
* @since 2.0.0
*/
WAIT_FOR_CARD_REMOVAL
}
/* Identifier of the currentState */
private final MonitoringState monitoringState;
/* Reference to Reader */
private final ObservableLocalReaderAdapter reader;
/* Background job definition if any */
private final AbstractMonitoringJobAdapter monitoringJob;
/* Result of the background job if any */
private Future<?> monitoringEvent;
/* Executor service used to execute AbstractMonitoringJobAdapter */
private final ExecutorService executorService;
/**
* Create a new state with a state identifier and a monitor job
*
* @param monitoringState the state identifier
* @param reader the current reader
* @param monitoringJob the job to be executed in background (may be null if no background job is
* required)
* @param executorService the executor service
* @since 2.0.0
*/
AbstractObservableStateAdapter(
MonitoringState monitoringState,
ObservableLocalReaderAdapter reader,
AbstractMonitoringJobAdapter monitoringJob,
ExecutorService executorService) {
this.reader = reader;
this.monitoringState = monitoringState;
this.monitoringJob = monitoringJob;
this.executorService = executorService;
}
/**
* Get the current state identifier of the state machine
*
* @return the current state identifier
* @since 2.0.0
*/
final MonitoringState getMonitoringState() {
return monitoringState;
}
/**
* Gets the reader.
*
* @return A not null reference.
* @since 2.0.0
*/
final ObservableLocalReaderAdapter getReader() {
return reader;
}
/**
* Switch state in the parent reader
*
* @param stateId the new state
* @since 2.0.0
*/
final void switchState(AbstractObservableStateAdapter.MonitoringState stateId) {
reader.switchState(stateId);
}
/**
* Invoked when activated, a custom behaviour can be added here.
*
* @since 2.0.0
* @throws IllegalStateException if a job is defined with a null executor service.
*/
final void onActivate() {
// launch the monitoringJob is necessary
if (monitoringJob != null) {
if (executorService == null) {
throw new IllegalStateException("ExecutorService must be set");
}
monitoringEvent = executorService.submit(monitoringJob.getMonitoringJob(this));
}
}
/**
* Invoked when deactivated. Cancel the monitoringJob is necessary.
*
* @since 2.0.0
*/
final void onDeactivate() {
if (monitoringEvent != null && !monitoringEvent.isDone()) {
monitoringJob.stop();
monitoringEvent.cancel(false);
}
}
/**
* Handle Internal Event.
*
* @param event internal event received by reader
* @since 2.0.0
*/
abstract void onEvent(ObservableLocalReaderAdapter.InternalEvent event);
}