1 /*******************************************************************************
2 * Copyright (c) 2010, 2015 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.core
.filter
.model
;
15 import java
.text
.NumberFormat
;
16 import java
.text
.ParseException
;
17 import java
.util
.ArrayList
;
18 import java
.util
.List
;
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
;
26 * Filter node for the comparison operation
29 * @author Patrick Tasse
31 public class TmfFilterCompareNode
extends TmfFilterAspectNode
{
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$
45 * Supported comparison types
47 public static enum Type
{
48 /** numerical comparison type */
50 /** alphanumerical comparison type */
52 /** timestamp comparison type */
57 private boolean fNot
= false;
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$
66 * @param parent the parent node
68 public TmfFilterCompareNode(ITmfFilterTreeNode parent
) {
73 * @return the NOT state
75 public boolean isNot() {
80 * @param not the NOT state
82 public void setNot(boolean not
) {
87 * @return the compare result (-1, 0 or 1)
89 public int getResult() {
94 * @param result the compare result (-1, 0 or 1)
96 public void setResult(int result
) {
97 this.fResult
= (int) Math
.signum(result
);
101 * @return the comparison type
103 public Type
getType() {
108 * @param type the comparison type
110 public void setType(Type type
) {
116 * @return the comparison value (in seconds for the TIMESTAMP type)
118 public String
getValue() {
123 * @param value the comparison value (in seconds for the TIMESTAMP type)
125 public void setValue(String value
) {
128 fValueTimestamp
= null;
132 if (fType
== Type
.NUM
) {
133 fValueNumber
= toNumber(value
);
134 } else if (fType
== Type
.TIMESTAMP
) {
135 fValueTimestamp
= toTimestamp(value
);
140 * @return true if the value is valid for the comparison type
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;
148 return fValue
!= null;
152 public String
getNodeName() {
157 public boolean matches(ITmfEvent event
) {
158 if (event
== null || fEventAspect
== null) {
161 Object value
= fEventAspect
.resolve(event
);
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
;
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
;
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
;
195 private static Number
toNumber(Object value
) {
196 if (value
instanceof Number
) {
197 return (Number
) value
;
200 return Long
.decode(value
.toString());
201 } catch (NumberFormatException e
) {
204 return NumberFormat
.getInstance().parse(value
.toString());
205 } catch (ParseException e
) {
210 private ITmfTimestamp
toTimestamp(Object value
) {
211 if (value
instanceof ITmfTimestamp
) {
212 return (ITmfTimestamp
) value
;
215 return TmfTimestamp
.fromNanos(fTimestampFormat
.parseValue(value
.toString()));
216 } catch (ParseException e
) {
222 public List
<String
> getValidChildren() {
223 return new ArrayList
<>(0);
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$
235 public ITmfFilterTreeNode
clone() {
236 TmfFilterCompareNode clone
= (TmfFilterCompareNode
) super.clone();
237 clone
.setValue(fValue
);