Commit | Line | Data |
---|---|---|
be222f56 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2010, 2014 Ericsson |
be222f56 PT |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Patrick Tasse - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
2bdf0193 | 13 | package org.eclipse.tracecompass.tmf.core.filter.model; |
be222f56 PT |
14 | |
15 | import java.text.NumberFormat; | |
16 | import java.text.ParseException; | |
17 | import java.util.ArrayList; | |
18 | import java.util.List; | |
19 | ||
2bdf0193 AM |
20 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
21 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
be222f56 PT |
22 | |
23 | ||
24 | /** | |
25 | * Filter node for the comparison operation | |
26 | * | |
27 | * @version 1.0 | |
28 | * @author Patrick Tasse | |
29 | */ | |
ec34bf48 | 30 | public class TmfFilterCompareNode extends TmfFilterAspectNode { |
be222f56 | 31 | |
ec34bf48 | 32 | /** compare node name */ |
be222f56 | 33 | public static final String NODE_NAME = "COMPARE"; //$NON-NLS-1$ |
ec34bf48 | 34 | /** not attribute name */ |
d5efe032 | 35 | public static final String NOT_ATTR = "not"; //$NON-NLS-1$ |
ec34bf48 | 36 | /** result attribute name */ |
d5efe032 | 37 | public static final String RESULT_ATTR = "result"; //$NON-NLS-1$ |
ec34bf48 | 38 | /** type attribute name */ |
d5efe032 | 39 | public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ |
ec34bf48 | 40 | /** value attribute name */ |
d5efe032 AF |
41 | public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ |
42 | ||
43 | /** | |
44 | * Supported comparison types | |
45 | */ | |
46 | public static enum Type { | |
ec34bf48 | 47 | /** numerical comparison type */ |
d5efe032 | 48 | NUM, |
ec34bf48 | 49 | /** alphanumerical comparison type */ |
d5efe032 | 50 | ALPHA, |
ec34bf48 | 51 | /** timestamp comparison type */ |
d5efe032 AF |
52 | TIMESTAMP |
53 | } | |
54 | ||
55 | private boolean fNot = false; | |
d5efe032 AF |
56 | private int fResult; |
57 | private Type fType = Type.NUM; | |
58 | private String fValue; | |
b64984c4 VP |
59 | private transient Number fValueNumber; |
60 | private transient TmfTimestamp fValueTimestamp; | |
d5efe032 AF |
61 | |
62 | /** | |
63 | * @param parent the parent node | |
64 | */ | |
65 | public TmfFilterCompareNode(ITmfFilterTreeNode parent) { | |
66 | super(parent); | |
67 | } | |
68 | ||
69 | /** | |
70 | * @return the NOT state | |
71 | */ | |
72 | public boolean isNot() { | |
73 | return fNot; | |
74 | } | |
be222f56 PT |
75 | |
76 | /** | |
77 | * @param not the NOT state | |
78 | */ | |
d5efe032 AF |
79 | public void setNot(boolean not) { |
80 | this.fNot = not; | |
81 | } | |
82 | ||
d5efe032 AF |
83 | /** |
84 | * @return the compare result | |
85 | */ | |
86 | public int getResult() { | |
87 | return fResult; | |
88 | } | |
89 | ||
90 | /** | |
91 | * @param result the compare result | |
92 | */ | |
93 | public void setResult(int result) { | |
94 | this.fResult = result; | |
95 | } | |
96 | ||
97 | /** | |
98 | * @return the comparison type | |
99 | */ | |
100 | public Type getType() { | |
101 | return fType; | |
102 | } | |
103 | ||
104 | /** | |
105 | * @param type the comparison type | |
106 | */ | |
107 | public void setType(Type type) { | |
108 | this.fType = type; | |
109 | setValue(fValue); | |
110 | } | |
111 | ||
112 | /** | |
113 | * @return the comparison value | |
114 | */ | |
115 | public String getValue() { | |
116 | return fValue; | |
117 | } | |
118 | ||
119 | /** | |
120 | * @param value the comparison value | |
121 | */ | |
122 | public void setValue(String value) { | |
123 | this.fValue = value; | |
124 | fValueNumber = null; | |
125 | fValueTimestamp = null; | |
126 | if (value == null) { | |
127 | return; | |
128 | } | |
129 | if (fType == Type.NUM) { | |
130 | try { | |
131 | fValueNumber = NumberFormat.getInstance().parse(value).doubleValue(); | |
132 | } catch (ParseException e) { | |
133 | } | |
134 | } else if (fType == Type.TIMESTAMP) { | |
135 | try { | |
136 | fValueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat.getInstance().parse(value.toString()).doubleValue())); | |
137 | } catch (ParseException e) { | |
138 | } | |
139 | } | |
140 | } | |
141 | ||
ec34bf48 PT |
142 | /** |
143 | * @return true if the value is valid for the comparison type | |
144 | */ | |
145 | public boolean hasValidValue() { | |
146 | if (fType == Type.NUM) { | |
147 | return fValueNumber != null; | |
148 | } else if (fType == Type.TIMESTAMP) { | |
149 | return fValue != null && !fValue.isEmpty() && fValueTimestamp != null; | |
150 | } | |
151 | return fValue != null; | |
152 | } | |
153 | ||
d5efe032 AF |
154 | @Override |
155 | public String getNodeName() { | |
156 | return NODE_NAME; | |
157 | } | |
158 | ||
159 | @Override | |
160 | public boolean matches(ITmfEvent event) { | |
ec34bf48 PT |
161 | if (event == null || fEventAspect == null) { |
162 | return false ^ fNot; | |
163 | } | |
164 | Object value = fEventAspect.resolve(event); | |
be222f56 PT |
165 | if (value == null) { |
166 | return false ^ fNot; | |
167 | } | |
168 | if (fType == Type.NUM) { | |
169 | if (fValueNumber != null) { | |
170 | if (value instanceof Number) { | |
0126a8ca AM |
171 | double valueDouble = ((Number) value).doubleValue(); |
172 | return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; | |
be222f56 PT |
173 | } |
174 | try { | |
0126a8ca AM |
175 | double valueDouble = NumberFormat.getInstance().parse(value.toString()).doubleValue(); |
176 | return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot; | |
be222f56 PT |
177 | } catch (ParseException e) { |
178 | } | |
179 | } | |
180 | } else if (fType == Type.ALPHA) { | |
181 | String valueString = value.toString(); | |
182 | int comp = valueString.compareTo(fValue.toString()); | |
183 | if (comp < -1) { | |
184 | comp = -1; | |
185 | } else if (comp > 1) { | |
186 | comp = 1; | |
187 | } | |
188 | return (comp == fResult) ^ fNot; | |
189 | } else if (fType == Type.TIMESTAMP) { | |
190 | if (fValueTimestamp != null) { | |
191 | if (value instanceof TmfTimestamp) { | |
192 | TmfTimestamp valueTimestamp = (TmfTimestamp) value; | |
065cc19b | 193 | return (valueTimestamp.compareTo(fValueTimestamp) == fResult) ^ fNot; |
be222f56 PT |
194 | } |
195 | try { | |
196 | TmfTimestamp valueTimestamp = new TmfTimestamp((long) (1E9 * NumberFormat | |
197 | .getInstance().parse(value.toString()).doubleValue())); | |
065cc19b | 198 | return (valueTimestamp.compareTo(fValueTimestamp) == fResult) ^ fNot; |
be222f56 PT |
199 | } catch (ParseException e) { |
200 | } | |
201 | } | |
202 | } | |
203 | return false ^ fNot; | |
d5efe032 AF |
204 | } |
205 | ||
206 | @Override | |
207 | public List<String> getValidChildren() { | |
208 | return new ArrayList<>(0); | |
209 | } | |
210 | ||
211 | @Override | |
212 | public String toString() { | |
213 | String result = (fResult == 0 ? "= " : fResult < 0 ? "< " : "> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
214 | String open = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "["); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
215 | String close = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
ec34bf48 PT |
216 | String aspectName = fEventAspect != null ? fEventAspect.getName() : ""; //$NON-NLS-1$ |
217 | return aspectName + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$ | |
d5efe032 AF |
218 | } |
219 | ||
220 | @Override | |
221 | public ITmfFilterTreeNode clone() { | |
222 | TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone(); | |
d5efe032 AF |
223 | clone.setValue(fValue); |
224 | return clone; | |
225 | } | |
b64984c4 VP |
226 | |
227 | @Override | |
228 | public int hashCode() { | |
229 | final int prime = 31; | |
230 | int result = super.hashCode(); | |
b64984c4 VP |
231 | result = prime * result + (fNot ? 1231 : 1237); |
232 | result = prime * result + fResult; | |
233 | result = prime * result + ((fType == null) ? 0 : fType.hashCode()); | |
234 | result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); | |
235 | return result; | |
236 | } | |
237 | ||
238 | @Override | |
239 | public boolean equals(Object obj) { | |
240 | if (this == obj) { | |
241 | return true; | |
242 | } | |
243 | if (!super.equals(obj)) { | |
244 | return false; | |
245 | } | |
246 | if (getClass() != obj.getClass()) { | |
247 | return false; | |
248 | } | |
249 | TmfFilterCompareNode other = (TmfFilterCompareNode) obj; | |
b64984c4 VP |
250 | if (fNot != other.fNot) { |
251 | return false; | |
252 | } | |
253 | if (fResult != other.fResult) { | |
254 | return false; | |
255 | } | |
256 | if (fType != other.fType) { | |
257 | return false; | |
258 | } | |
259 | if (fValue == null) { | |
260 | if (other.fValue != null) { | |
261 | return false; | |
262 | } | |
263 | } else if (!fValue.equals(other.fValue)) { | |
264 | return false; | |
265 | } | |
266 | return true; | |
267 | } | |
be222f56 | 268 | } |