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