4c9b4aed69b28760278855bcbb12b948a7989e66
[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 = 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 try {
135 fValueNumber = NumberFormat.getInstance().parse(value).doubleValue();
136 } catch (ParseException e) {
137 }
138 } else if (fType == Type.TIMESTAMP) {
139 try {
140 fValueTimestamp = new TmfNanoTimestamp(fTimestampFormat.parseValue(value.toString()));
141 } catch (ParseException e) {
142 }
143 }
144 }
145
146 /**
147 * @return true if the value is valid for the comparison type
148 */
149 public boolean hasValidValue() {
150 if (fType == Type.NUM) {
151 return fValueNumber != null;
152 } else if (fType == Type.TIMESTAMP) {
153 return fValue != null && !fValue.isEmpty() && fValueTimestamp != null;
154 }
155 return fValue != null;
156 }
157
158 @Override
159 public String getNodeName() {
160 return NODE_NAME;
161 }
162
163 @Override
164 public boolean matches(ITmfEvent event) {
165 if (event == null || fEventAspect == null) {
166 return false ^ fNot;
167 }
168 Object value = fEventAspect.resolve(event);
169 if (value == null) {
170 return false ^ fNot;
171 }
172 if (fType == Type.NUM) {
173 if (fValueNumber != null) {
174 if (value instanceof Number) {
175 double valueDouble = ((Number) value).doubleValue();
176 return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot;
177 }
178 try {
179 double valueDouble = NumberFormat.getInstance().parse(value.toString()).doubleValue();
180 return (Double.compare(valueDouble, fValueNumber.doubleValue()) == fResult) ^ fNot;
181 } catch (ParseException e) {
182 }
183 }
184 } else if (fType == Type.ALPHA) {
185 String valueString = value.toString();
186 int comp = (int) Math.signum(valueString.compareTo(fValue.toString()));
187 return (comp == fResult) ^ fNot;
188 } else if (fType == Type.TIMESTAMP) {
189 if (fValueTimestamp != null) {
190 if (value instanceof ITmfTimestamp) {
191 ITmfTimestamp valueTimestamp = (ITmfTimestamp) value;
192 return (valueTimestamp.compareTo(fValueTimestamp) == fResult) ^ fNot;
193 }
194 try {
195 ITmfTimestamp valueTimestamp = new TmfNanoTimestamp(fTimestampFormat.parseValue(value.toString()));
196 return (valueTimestamp.compareTo(fValueTimestamp) == fResult) ^ fNot;
197 } catch (ParseException e) {
198 }
199 }
200 }
201 return false ^ fNot;
202 }
203
204 @Override
205 public List<String> getValidChildren() {
206 return new ArrayList<>(0);
207 }
208
209 @Override
210 public String toString() {
211 String result = (fResult == 0 ? "= " : fResult < 0 ? "< " : "> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
212 String open = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "["); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
213 String close = (fType == Type.NUM ? "" : fType == Type.ALPHA ? "\"" : "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
214 String aspectName = fEventAspect != null ? fEventAspect.getName() : ""; //$NON-NLS-1$
215 return aspectName + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$
216 }
217
218 @Override
219 public ITmfFilterTreeNode clone() {
220 TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone();
221 clone.setValue(fValue);
222 return clone;
223 }
224
225 @Override
226 public int hashCode() {
227 final int prime = 31;
228 int result = super.hashCode();
229 result = prime * result + (fNot ? 1231 : 1237);
230 result = prime * result + fResult;
231 result = prime * result + ((fType == null) ? 0 : fType.hashCode());
232 result = prime * result + ((fValue == null) ? 0 : fValue.hashCode());
233 return result;
234 }
235
236 @Override
237 public boolean equals(Object obj) {
238 if (this == obj) {
239 return true;
240 }
241 if (!super.equals(obj)) {
242 return false;
243 }
244 if (getClass() != obj.getClass()) {
245 return false;
246 }
247 TmfFilterCompareNode other = (TmfFilterCompareNode) obj;
248 if (fNot != other.fNot) {
249 return false;
250 }
251 if (fResult != other.fResult) {
252 return false;
253 }
254 if (fType != other.fType) {
255 return false;
256 }
257 if (fValue == null) {
258 if (other.fValue != null) {
259 return false;
260 }
261 } else if (!fValue.equals(other.fValue)) {
262 return false;
263 }
264 return true;
265 }
266 }
This page took 0.037932 seconds and 4 git commands to generate.