tmf: Make TmfEventFieldAspect independent of event content
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / filter / model / TmfFilterCompareNode.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2015 Ericsson
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
13 package org.eclipse.tracecompass.tmf.core.filter.model;
14
15 import java.text.NumberFormat;
16 import java.text.ParseException;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
21 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
22 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
23 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
24
25
26 /**
27 * Filter node for the comparison operation
28 *
29 * @version 1.0
30 * @author Patrick Tasse
31 */
32 public class TmfFilterCompareNode extends TmfFilterAspectNode {
33
34 /** compare node name */
35 public static final String NODE_NAME = "COMPARE"; //$NON-NLS-1$
36 /** not attribute name */
37 public static final String NOT_ATTR = "not"; //$NON-NLS-1$
38 /** result attribute name */
39 public static final String RESULT_ATTR = "result"; //$NON-NLS-1$
40 /** type attribute name */
41 public static final String TYPE_ATTR = "type"; //$NON-NLS-1$
42 /** value attribute name */
43 public static final String VALUE_ATTR = "value"; //$NON-NLS-1$
44
45 /**
46 * Supported comparison types
47 */
48 public static enum Type {
49 /** numerical comparison type */
50 NUM,
51 /** alphanumerical comparison type */
52 ALPHA,
53 /** timestamp comparison type */
54 TIMESTAMP
55 }
56
57
58 private boolean fNot = false;
59 private int fResult;
60 private Type fType = Type.NUM;
61 private String fValue;
62 private transient Number fValueNumber;
63 private transient ITmfTimestamp fValueTimestamp;
64 private transient TmfTimestampFormat fTimestampFormat = new TmfTimestampFormat("T.SSSSSSSSS"); //$NON-NLS-1$
65
66 /**
67 * @param parent the parent node
68 */
69 public TmfFilterCompareNode(ITmfFilterTreeNode parent) {
70 super(parent);
71 }
72
73 /**
74 * @return the NOT state
75 */
76 public boolean isNot() {
77 return fNot;
78 }
79
80 /**
81 * @param not the NOT state
82 */
83 public void setNot(boolean not) {
84 this.fNot = not;
85 }
86
87 /**
88 * @return the compare result (-1, 0 or 1)
89 */
90 public int getResult() {
91 return fResult;
92 }
93
94 /**
95 * @param result the compare result (-1, 0 or 1)
96 */
97 public void setResult(int result) {
98 this.fResult = (int) Math.signum(result);
99 }
100
101 /**
102 * @return the comparison type
103 */
104 public Type getType() {
105 return fType;
106 }
107
108 /**
109 * @param type the comparison type
110 */
111 public void setType(Type type) {
112 this.fType = type;
113 setValue(fValue);
114 }
115
116 /**
117 * @return the comparison value (in seconds for the TIMESTAMP type)
118 */
119 public String getValue() {
120 return fValue;
121 }
122
123 /**
124 * @param value the comparison value (in seconds for the TIMESTAMP type)
125 */
126 public void setValue(String value) {
127 this.fValue = value;
128 fValueNumber = null;
129 fValueTimestamp = null;
130 if (value == null) {
131 return;
132 }
133 if (fType == Type.NUM) {
134 fValueNumber = toNumber(value);
135 } else if (fType == Type.TIMESTAMP) {
136 fValueTimestamp = toTimestamp(value);
137 }
138 }
139
140 /**
141 * @return true if the value is valid for the comparison type
142 */
143 public boolean hasValidValue() {
144 if (fType == Type.NUM) {
145 return fValueNumber != null;
146 } else if (fType == Type.TIMESTAMP) {
147 return fValue != null && !fValue.isEmpty() && fValueTimestamp != null;
148 }
149 return fValue != null;
150 }
151
152 @Override
153 public String getNodeName() {
154 return NODE_NAME;
155 }
156
157 @Override
158 public boolean matches(ITmfEvent event) {
159 if (event == null || fEventAspect == null) {
160 return false;
161 }
162 Object value = fEventAspect.resolve(event);
163 if (value == null) {
164 return false;
165 }
166 if (fType == Type.NUM) {
167 if (fValueNumber instanceof Double) {
168 Number valueNumber = toNumber(value);
169 if (valueNumber != null) {
170 return (Double.compare(valueNumber.doubleValue(), fValueNumber.doubleValue()) == fResult) ^ fNot;
171 }
172 } else if (fValueNumber != null) {
173 Number valueNumber = toNumber(value);
174 if (valueNumber instanceof Double || valueNumber instanceof Float) {
175 return (Double.compare(valueNumber.doubleValue(), fValueNumber.doubleValue()) == fResult) ^ fNot;
176 } else if (valueNumber != null) {
177 return (Long.compare(valueNumber.longValue(), fValueNumber.longValue()) == fResult) ^ fNot;
178 }
179 }
180 } else if (fType == Type.ALPHA) {
181 String valueString = value.toString();
182 int comp = (int) Math.signum(valueString.compareTo(fValue.toString()));
183 return (comp == fResult) ^ fNot;
184 } else if (fType == Type.TIMESTAMP) {
185 if (fValueTimestamp != null) {
186 ITmfTimestamp valueTimestamp = toTimestamp(value);
187 if (valueTimestamp != null) {
188 int comp = (int) Math.signum(valueTimestamp.compareTo(fValueTimestamp));
189 return (comp == fResult) ^ fNot;
190 }
191 }
192 }
193 return false;
194 }
195
196 private static Number toNumber(Object value) {
197 if (value instanceof Number) {
198 return (Number) value;
199 }
200 try {
201 return Long.decode(value.toString());
202 } catch (NumberFormatException e) {
203 }
204 try {
205 return NumberFormat.getInstance().parse(value.toString());
206 } catch (ParseException e) {
207 }
208 return null;
209 }
210
211 private ITmfTimestamp toTimestamp(Object value) {
212 if (value instanceof ITmfTimestamp) {
213 return (ITmfTimestamp) value;
214 }
215 try {
216 return new TmfNanoTimestamp(fTimestampFormat.parseValue(value.toString()));
217 } catch (ParseException e) {
218 }
219 return null;
220 }
221
222 @Override
223 public List<String> getValidChildren() {
224 return new ArrayList<>(0);
225 }
226
227 @Override
228 public String toString() {
229 String result = (fResult == 0 ? "= " : fResult < 0 ? "< " : "> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
230 String open = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "["); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
231 String close = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
232 return getAspectLabel() + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$
233 }
234
235 @Override
236 public ITmfFilterTreeNode clone() {
237 TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone();
238 clone.setValue(fValue);
239 return clone;
240 }
241
242 @Override
243 public int hashCode() {
244 final int prime = 31;
245 int result = super.hashCode();
246 result = prime * result + (fNot ? 1231 : 1237);
247 result = prime * result + fResult;
248 result = prime * result + ((fType == null) ? 0 : fType.hashCode());
249 result = prime * result + ((fValue == null) ? 0 : fValue.hashCode());
250 return result;
251 }
252
253 @Override
254 public boolean equals(Object obj) {
255 if (this == obj) {
256 return true;
257 }
258 if (!super.equals(obj)) {
259 return false;
260 }
261 if (getClass() != obj.getClass()) {
262 return false;
263 }
264 TmfFilterCompareNode other = (TmfFilterCompareNode) obj;
265 if (fNot != other.fNot) {
266 return false;
267 }
268 if (fResult != other.fResult) {
269 return false;
270 }
271 if (fType != other.fType) {
272 return false;
273 }
274 if (fValue == null) {
275 if (other.fValue != null) {
276 return false;
277 }
278 } else if (!fValue.equals(other.fValue)) {
279 return false;
280 }
281 return true;
282 }
283 }
This page took 0.035978 seconds and 5 git commands to generate.