18
18
19
19
import org .openqa .selenium .Rectangle ;
20
20
21
+ import java .io .File ;
22
+ import java .io .IOException ;
21
23
import java .util .List ;
22
24
import java .util .Map ;
23
25
import java .util .stream .Collectors ;
24
26
25
27
public class OccurrenceMatchingResult extends ComparisonResult {
26
28
private static final String RECT = "rect" ;
27
- private static final String MULTIPLE = "multiple " ;
29
+ private static final String SCORE = "score " ;
28
30
29
- private final boolean isAtRoot ;
31
+ private final boolean hasMultiple ;
30
32
31
- public OccurrenceMatchingResult (Map <String , Object > input ) {
32
- this (input , true );
33
+ public OccurrenceMatchingResult (Object input ) {
34
+ super (input );
35
+ hasMultiple = input instanceof List ;
33
36
}
34
37
35
- private OccurrenceMatchingResult (Map <String , Object > input , boolean isAtRoot ) {
36
- super (input );
37
- this .isAtRoot = isAtRoot ;
38
+ /**
39
+ * Check whether the current instance contains multiple matches.
40
+ *
41
+ * @return True or false.
42
+ */
43
+ public boolean hasMultiple () {
44
+ return hasMultiple ;
38
45
}
39
46
40
47
/**
41
- * Returns rectangle of partial image occurrence.
48
+ * Returns rectangle of the partial image occurrence.
42
49
*
43
50
* @return The region of the partial image occurrence on the full image.
44
51
*/
45
52
public Rectangle getRect () {
53
+ if (hasMultiple ) {
54
+ return getRect (0 );
55
+ }
46
56
verifyPropertyPresence (RECT );
47
57
//noinspection unchecked
48
- return mapToRect ((Map <String , Object >) getCommandResult ().get (RECT ));
58
+ return mapToRect ((Map <String , Object >) getResultAsMap ().get (RECT ));
59
+ }
60
+
61
+ /**
62
+ * Returns rectangle of the partial image occurrence for the given match index.
63
+ *
64
+ * @param matchIndex Match index.
65
+ * @return Matching rectangle.
66
+ * @throws IllegalStateException If the current instance does not represent multiple matches.
67
+ */
68
+ public Rectangle getRect (int matchIndex ) {
69
+ return getMatch (matchIndex ).getRect ();
70
+ }
71
+
72
+ /**
73
+ * Returns the score of the partial image occurrence.
74
+ *
75
+ * @return Matching score in range 0..1.
76
+ */
77
+ public double getScore () {
78
+ if (hasMultiple ) {
79
+ return getScore (0 );
80
+ }
81
+ verifyPropertyPresence (SCORE );
82
+ var value = getResultAsMap ().get (SCORE );
83
+ if (value instanceof Long ) {
84
+ return ((Long ) value ).doubleValue ();
85
+ }
86
+ return (Double ) value ;
87
+ }
88
+
89
+ /**
90
+ * Returns the score of the partial image occurrence for the given match index.
91
+ *
92
+ * @param matchIndex Match index.
93
+ * @return Matching score in range 0..1.
94
+ * @throws IllegalStateException If the current instance does not represent multiple matches.
95
+ */
96
+ public double getScore (int matchIndex ) {
97
+ return getMatch (matchIndex ).getScore ();
98
+ }
99
+
100
+ /**
101
+ * Returns the visualization of the matching result.
102
+ *
103
+ * @return The visualization of the matching result represented as base64-encoded PNG image.
104
+ */
105
+ @ Override
106
+ public byte [] getVisualization () {
107
+ return hasMultiple ? getVisualization (0 ) : super .getVisualization ();
108
+ }
109
+
110
+ /**
111
+ * Returns the visualization of the partial image occurrence for the given match index.
112
+ *
113
+ * @param matchIndex Match index.
114
+ * @return The visualization of the matching result represented as base64-encoded PNG image.
115
+ * @throws IllegalStateException If the current instance does not represent multiple matches.
116
+ */
117
+ public byte [] getVisualization (int matchIndex ) {
118
+ return getMatch (matchIndex ).getVisualization ();
119
+ }
120
+
121
+ /**
122
+ * Stores visualization image into the given file.
123
+ *
124
+ * @param destination File path to save the image to.
125
+ * @throws IOException On file system I/O error.
126
+ */
127
+ @ Override
128
+ public void storeVisualization (File destination ) throws IOException {
129
+ if (hasMultiple ) {
130
+ getMatch (0 ).storeVisualization (destination );
131
+ } else {
132
+ super .storeVisualization (destination );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Stores visualization image into the given file.
138
+ *
139
+ * @param matchIndex Match index.
140
+ * @param destination File path to save the image to.
141
+ * @throws IOException On file system I/O error.
142
+ * @throws IllegalStateException If the current instance does not represent multiple matches.
143
+ */
144
+ public void storeVisualization (int matchIndex , File destination ) throws IOException {
145
+ getMatch (matchIndex ).storeVisualization (destination );
49
146
}
50
147
51
148
/**
@@ -54,18 +151,37 @@ public Rectangle getRect() {
54
151
*
55
152
* @since Appium 1.21.0
56
153
* @return The list containing properties of each single match or an empty list.
57
- * @throws IllegalStateException If the accessor is called on a non-root match instance .
154
+ * @throws IllegalStateException If the current instance does not represent multiple matches .
58
155
*/
59
156
public List <OccurrenceMatchingResult > getMultiple () {
60
- if (!isAtRoot ) {
61
- throw new IllegalStateException ("Only the root match could contain multiple submatches" );
62
- }
63
- verifyPropertyPresence (MULTIPLE );
157
+ return getMultipleMatches (false );
158
+ }
64
159
160
+ private List <OccurrenceMatchingResult > getMultipleMatches (boolean throwIfEmpty ) {
161
+ if (!hasMultiple ) {
162
+ throw new IllegalStateException (String .format (
163
+ "This %s does not represent multiple matches. Did you set options properly?" ,
164
+ getClass ().getSimpleName ()
165
+ ));
166
+ }
65
167
//noinspection unchecked
66
- List <Map <String , Object >> multiple = (List <Map <String , Object >>) getCommandResult ().get (MULTIPLE );
67
- return multiple .stream ()
68
- .map (m -> new OccurrenceMatchingResult (m , false ))
168
+ var matches = ((List <Map <String , Object >>) commandResult ).stream ()
169
+ .map (OccurrenceMatchingResult ::new )
69
170
.collect (Collectors .toList ());
171
+ if (matches .isEmpty () && throwIfEmpty ) {
172
+ throw new IllegalStateException ("Zero matches have been found. Try the lookup with different options." );
173
+ }
174
+ return matches ;
175
+ }
176
+
177
+ private OccurrenceMatchingResult getMatch (int index ) {
178
+ var matches = getMultipleMatches (true );
179
+ if (index < 0 || index >= matches .size ()) {
180
+ throw new IndexOutOfBoundsException (String .format (
181
+ "The match #%s does not exist. The total number of found matches is %s" ,
182
+ index , matches .size ()
183
+ ));
184
+ }
185
+ return matches .get (index );
70
186
}
71
187
}
0 commit comments