TMF: Make the ITmfEventAspect#resolve nullable
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / filter / model / TmfFilterTreeNode.java
CommitLineData
be222f56 1/*******************************************************************************
11252342 2 * Copyright (c) 2010, 2013 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 * Yuriy Vashchuk (yvashchuk@gmail.com) - Initial API and implementation
11 * Patrick Tasse - Refactoring
a1bc6c45 12 * Vincent Perot - Add subfield filtering
be222f56
PT
13 *******************************************************************************/
14
2bdf0193 15package org.eclipse.tracecompass.tmf.core.filter.model;
be222f56
PT
16
17import java.util.ArrayList;
18import java.util.Arrays;
19import java.util.List;
20
2bdf0193
AM
21import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
22import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
be222f56
PT
23
24/**
25 * The base class for the Filter tree nodes
26 *
27 * @version 1.0
28 * @author Yuriy Vashchuk
29 * @author Patrick Tasse
30 */
31public abstract class TmfFilterTreeNode implements ITmfFilterTreeNode, Cloneable {
32
a1bc6c45
VP
33 private static final char SLASH = '/';
34 private static final char BACKSLASH = '\\';
35
11252342
AM
36 private static final String[] VALID_CHILDREN = {
37 TmfFilterEventTypeNode.NODE_NAME,
38 TmfFilterAndNode.NODE_NAME,
39 TmfFilterOrNode.NODE_NAME,
40 TmfFilterContainsNode.NODE_NAME,
41 TmfFilterEqualsNode.NODE_NAME,
d9b1b4ed 42 TmfFilterMatchesFieldNode.NODE_NAME,
11252342
AM
43 TmfFilterCompareNode.NODE_NAME
44 };
be222f56 45
11252342 46 private ITmfFilterTreeNode parent = null;
a4524c1b 47 private ArrayList<ITmfFilterTreeNode> children = new ArrayList<>();
be222f56 48
a1bc6c45
VP
49 private String fPathAsString = null;
50 private String[] fPathAsArray = null;
51
be222f56 52 /**
11252342
AM
53 * @param parent
54 * the parent node
be222f56
PT
55 */
56 public TmfFilterTreeNode(final ITmfFilterTreeNode parent) {
11252342
AM
57 if (parent != null) {
58 parent.addChild(this);
59 }
60 }
61
62 @Override
63 public ITmfFilterTreeNode getParent() {
64 return parent;
65 }
66
67 @Override
68 public abstract String getNodeName();
69
70 @Override
71 public boolean hasChildren() {
72 return (children.size() > 0);
be222f56
PT
73 }
74
11252342
AM
75 @Override
76 public int getChildrenCount() {
77 return children.size();
78 }
79
80 @Override
81 public ITmfFilterTreeNode[] getChildren() {
82 return children.toArray(new ITmfFilterTreeNode[0]);
83 }
84
85 @Override
86 public ITmfFilterTreeNode getChild(final int index) throws IndexOutOfBoundsException {
87 return children.get(index);
88 }
89
90 @Override
91 public ITmfFilterTreeNode remove() {
92 if (getParent() != null) {
93 getParent().removeChild(this);
94 }
95 return this;
96 }
97
98 @Override
99 public ITmfFilterTreeNode removeChild(ITmfFilterTreeNode node) {
100 children.remove(node);
101 node.setParent(null);
102 return node;
103 }
104
105 @Override
106 public int addChild(final ITmfFilterTreeNode node) {
107 node.setParent(this);
108 if (children.add(node)) {
109 return (children.size() - 1);
110 }
111 return -1;
112 }
113
114 @Override
115 public ITmfFilterTreeNode replaceChild(final int index, final ITmfFilterTreeNode node) throws IndexOutOfBoundsException {
116 node.setParent(this);
117 return children.set(index, node);
118 }
119
120 @Override
121 public void setParent(final ITmfFilterTreeNode parent) {
122 this.parent = parent;
123 }
124
125 @Override
126 public abstract boolean matches(ITmfEvent event);
be222f56
PT
127
128 /**
b64984c4
VP
129 * @param event
130 * the event
131 * @param field
132 * the field id
be222f56
PT
133 * @return the field value
134 */
135 protected Object getFieldValue(ITmfEvent event, String field) {
136 Object value = null;
137 if (ITmfEvent.EVENT_FIELD_CONTENT.equals(field)) {
a4a6acf4 138 value = event.getContent().toString();
be222f56
PT
139 }
140 else if (ITmfEvent.EVENT_FIELD_TYPE.equals(field)) {
141 value = event.getType().getName();
142 }
143 else if (ITmfEvent.EVENT_FIELD_TIMESTAMP.equals(field)) {
144 value = event.getTimestamp().toString();
e1de2fd4 145 } else {
a1bc6c45
VP
146 if (field == null) {
147 return null;
148 }
149 ITmfEventField eventField;
150 if (field.isEmpty() || field.charAt(0) != SLASH) {
151 eventField = event.getContent().getField(field);
152 } else {
153 String[] array = getPathArray(field);
154 eventField = event.getContent().getSubField(array);
155 }
156
be222f56
PT
157 if (eventField != null) {
158 value = eventField.getValue();
159 }
160 }
161 return value;
162 }
163
a1bc6c45
VP
164 private String[] getPathArray(String field) {
165
166 // Check if last request was not the same string.
167 if (field.equals(fPathAsString)) {
168 return fPathAsArray;
169 }
170
171 // Generate the new path array
172 StringBuilder sb = new StringBuilder();
173 List<String> list = new ArrayList<>();
174
175 // We start at 1 since the first character is a slash that we want to
176 // ignore.
177 for (int i = 1; i < field.length(); i++) {
178 char charAt = field.charAt(i);
179 if (charAt == SLASH) {
180 // char is slash. Cut here.
181 list.add(sb.toString());
182 sb = new StringBuilder();
183 } else if (charAt == BACKSLASH && i < field.length() - 1 && field.charAt(i + 1) == SLASH) {
184 // Uninterpreted slash. Add it.
185 sb.append(SLASH);
186 i++;
187 } else {
188 // Any other character. Add.
189 sb.append(charAt);
190 }
191 }
192
193 // Last block. Add it to list.
194 list.add(sb.toString());
195
196 // Transform to array
197 String[] array = new String[list.size()];
198 list.toArray(array);
199
200 // Save new values.
201 // Array first for solving concurrency issues
202 fPathAsArray = array;
203 fPathAsString = field;
204
205 return array;
206 }
207
11252342
AM
208 @Override
209 public List<String> getValidChildren() {
210 return Arrays.asList(VALID_CHILDREN);
211 }
212
213 @Override
214 public ITmfFilterTreeNode clone() {
215 try {
216 TmfFilterTreeNode clone = (TmfFilterTreeNode) super.clone();
217 clone.parent = null;
a4524c1b 218 clone.children = new ArrayList<>(children.size());
11252342
AM
219 for (ITmfFilterTreeNode child : getChildren()) {
220 clone.addChild(child.clone());
221 }
222 return clone;
223 } catch (CloneNotSupportedException e) {
224 return null;
225 }
226 }
b64984c4
VP
227
228 @Override
229 public int hashCode() {
230 final int prime = 31;
231 int result = 1;
232 result = prime * result + ((children == null) ? 0 : children.hashCode());
233 return result;
234 }
235
236 @Override
237 public boolean equals(Object obj) {
238 if (this == obj) {
239 return true;
240 }
241 if (obj == null) {
242 return false;
243 }
244 if (getClass() != obj.getClass()) {
245 return false;
246 }
247 TmfFilterTreeNode other = (TmfFilterTreeNode) obj;
248 if (children == null) {
249 if (other.children != null) {
250 return false;
251 }
252 } else if (!children.equals(other.children)) {
253 return false;
254 }
255 return true;
256 }
be222f56 257}
This page took 0.06371 seconds and 5 git commands to generate.