Commit | Line | Data |
---|---|---|
be222f56 | 1 | /******************************************************************************* |
3bd950a7 | 2 | * Copyright (c) 2010, 2015 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 | 20 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
3bd950a7 | 21 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; |
b2c971ec | 22 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; |
3bd950a7 | 23 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; |
be222f56 | 24 | |
be222f56 PT |
25 | /** |
26 | * Filter node for the comparison operation | |
27 | * | |
28 | * @version 1.0 | |
29 | * @author Patrick Tasse | |
30 | */ | |
ec34bf48 | 31 | public class TmfFilterCompareNode extends TmfFilterAspectNode { |
be222f56 | 32 | |
ec34bf48 | 33 | /** compare node name */ |
be222f56 | 34 | public static final String NODE_NAME = "COMPARE"; //$NON-NLS-1$ |
ec34bf48 | 35 | /** not attribute name */ |
d5efe032 | 36 | public static final String NOT_ATTR = "not"; //$NON-NLS-1$ |
ec34bf48 | 37 | /** result attribute name */ |
d5efe032 | 38 | public static final String RESULT_ATTR = "result"; //$NON-NLS-1$ |
ec34bf48 | 39 | /** type attribute name */ |
d5efe032 | 40 | public static final String TYPE_ATTR = "type"; //$NON-NLS-1$ |
ec34bf48 | 41 | /** value attribute name */ |
d5efe032 AF |
42 | public static final String VALUE_ATTR = "value"; //$NON-NLS-1$ |
43 | ||
44 | /** | |
45 | * Supported comparison types | |
46 | */ | |
47 | public static enum Type { | |
ec34bf48 | 48 | /** numerical comparison type */ |
d5efe032 | 49 | NUM, |
ec34bf48 | 50 | /** alphanumerical comparison type */ |
d5efe032 | 51 | ALPHA, |
ec34bf48 | 52 | /** timestamp comparison type */ |
d5efe032 AF |
53 | TIMESTAMP |
54 | } | |
55 | ||
3bd950a7 | 56 | |
d5efe032 | 57 | private boolean fNot = false; |
d5efe032 AF |
58 | private int fResult; |
59 | private Type fType = Type.NUM; | |
60 | private String fValue; | |
b64984c4 | 61 | private transient Number fValueNumber; |
3bd950a7 PT |
62 | private transient ITmfTimestamp fValueTimestamp; |
63 | private transient TmfTimestampFormat fTimestampFormat = new TmfTimestampFormat("T.SSSSSSSSS"); //$NON-NLS-1$ | |
d5efe032 AF |
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 | } | |
be222f56 PT |
78 | |
79 | /** | |
80 | * @param not the NOT state | |
81 | */ | |
d5efe032 AF |
82 | public void setNot(boolean not) { |
83 | this.fNot = not; | |
84 | } | |
85 | ||
d5efe032 | 86 | /** |
3bd950a7 | 87 | * @return the compare result (-1, 0 or 1) |
d5efe032 AF |
88 | */ |
89 | public int getResult() { | |
90 | return fResult; | |
91 | } | |
92 | ||
93 | /** | |
3bd950a7 | 94 | * @param result the compare result (-1, 0 or 1) |
d5efe032 AF |
95 | */ |
96 | public void setResult(int result) { | |
d3c3d0e7 | 97 | this.fResult = (int) Math.signum(result); |
d5efe032 AF |
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 | /** | |
3bd950a7 | 116 | * @return the comparison value (in seconds for the TIMESTAMP type) |
d5efe032 AF |
117 | */ |
118 | public String getValue() { | |
119 | return fValue; | |
120 | } | |
121 | ||
122 | /** | |
3bd950a7 | 123 | * @param value the comparison value (in seconds for the TIMESTAMP type) |
d5efe032 AF |
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) { | |
d3c3d0e7 | 133 | fValueNumber = toNumber(value); |
d5efe032 | 134 | } else if (fType == Type.TIMESTAMP) { |
d3c3d0e7 | 135 | fValueTimestamp = toTimestamp(value); |
d5efe032 AF |
136 | } |
137 | } | |
138 | ||
ec34bf48 PT |
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 | ||
d5efe032 AF |
151 | @Override |
152 | public String getNodeName() { | |
153 | return NODE_NAME; | |
154 | } | |
155 | ||
156 | @Override | |
157 | public boolean matches(ITmfEvent event) { | |
ec34bf48 | 158 | if (event == null || fEventAspect == null) { |
d3c3d0e7 | 159 | return false; |
ec34bf48 PT |
160 | } |
161 | Object value = fEventAspect.resolve(event); | |
be222f56 | 162 | if (value == null) { |
d3c3d0e7 | 163 | return false; |
be222f56 PT |
164 | } |
165 | if (fType == Type.NUM) { | |
d3c3d0e7 PT |
166 | if (fValueNumber instanceof Double) { |
167 | Number valueNumber = toNumber(value); | |
168 | if (valueNumber != null) { | |
169 | return (Double.compare(valueNumber.doubleValue(), fValueNumber.doubleValue()) == fResult) ^ fNot; | |
be222f56 | 170 | } |
d3c3d0e7 PT |
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; | |
be222f56 PT |
177 | } |
178 | } | |
179 | } else if (fType == Type.ALPHA) { | |
180 | String valueString = value.toString(); | |
984ecd4c | 181 | int comp = (int) Math.signum(valueString.compareTo(fValue)); |
be222f56 PT |
182 | return (comp == fResult) ^ fNot; |
183 | } else if (fType == Type.TIMESTAMP) { | |
184 | if (fValueTimestamp != null) { | |
d3c3d0e7 PT |
185 | ITmfTimestamp valueTimestamp = toTimestamp(value); |
186 | if (valueTimestamp != null) { | |
187 | int comp = (int) Math.signum(valueTimestamp.compareTo(fValueTimestamp)); | |
188 | return (comp == fResult) ^ fNot; | |
be222f56 PT |
189 | } |
190 | } | |
191 | } | |
d3c3d0e7 PT |
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 { | |
b2c971ec | 215 | return TmfTimestamp.fromNanos(fTimestampFormat.parseValue(value.toString())); |
d3c3d0e7 PT |
216 | } catch (ParseException e) { |
217 | } | |
218 | return null; | |
d5efe032 AF |
219 | } |
220 | ||
221 | @Override | |
222 | public List<String> getValidChildren() { | |
223 | return new ArrayList<>(0); | |
224 | } | |
225 | ||
226 | @Override | |
e883975e | 227 | public String toString(boolean explicit) { |
d5efe032 AF |
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$ | |
e883975e | 231 | return getAspectLabel(explicit) + (fNot ? " not " : " ") + result + open + fValue + close; //$NON-NLS-1$ //$NON-NLS-2$ |
d5efe032 AF |
232 | } |
233 | ||
234 | @Override | |
235 | public ITmfFilterTreeNode clone() { | |
236 | TmfFilterCompareNode clone = (TmfFilterCompareNode) super.clone(); | |
d5efe032 AF |
237 | clone.setValue(fValue); |
238 | return clone; | |
239 | } | |
be222f56 | 240 | } |