ctf: Make events immutable
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / scope / LexicalScope.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11
12 package org.eclipse.linuxtools.ctf.core.event.scope;
13
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.Map;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21
22 import com.google.common.base.Joiner;
23
24 /**
25 * A node of a lexical scope
26 *
27 * @author Matthew Khouzam
28 * @since 3.0
29 */
30 @NonNullByDefault
31 public class LexicalScope implements Comparable<LexicalScope> {
32 /**
33 * Empty string
34 *
35 * @since 3.0
36 */
37 public static final LexicalScope ROOT = new LexicalScope(null, ""); //$NON-NLS-1$
38
39 /**
40 * Trace string
41 *
42 * @since 3.0
43 */
44 public static final LexicalScope TRACE = new LexicalScope(ROOT, "trace"); //$NON-NLS-1$
45
46 /**
47 * Env string
48 *
49 * @since 3.0
50 */
51 public static final LexicalScope ENV = new LexicalScope(ROOT, "env"); //$NON-NLS-1$
52
53 /**
54 * Stream string
55 *
56 * @since 3.0
57 */
58 public static final LexicalScope STREAM = new LexicalScope(ROOT, "stream"); //$NON-NLS-1$
59
60 /**
61 * Event string
62 *
63 * @since 3.0
64 */
65 public static final LexicalScope EVENT = new LexicalScope(ROOT, "event"); //$NON-NLS-1$
66
67 /**
68 * Variant string
69 *
70 * @since 3.0
71 */
72 public static final LexicalScope VARIANT = new LexicalScope(ROOT, "variant"); //$NON-NLS-1$
73
74 /**
75 * packet string
76 *
77 * @since 3.0
78 */
79 public static final LexicalScope PACKET = new LexicalScope(ROOT, "packet"); //$NON-NLS-1$
80
81 /**
82 * Packet header string
83 *
84 * @since 3.0
85 *
86 */
87 public static final LexicalScope PACKET_HEADER = new LexicalScope(PACKET, "header"); //$NON-NLS-1$
88
89 /**
90 * Stream packet scope
91 *
92 * @since 3.0
93 */
94 public static final LexicalScope STREAM_PACKET = new LexicalScope(STREAM, "packet"); //$NON-NLS-1$
95
96 /**
97 * Stream Packet header string
98 *
99 * @since 3.0
100 */
101 public static final LexicalScope STREAM_PACKET_CONTEXT = new LexicalScope(STREAM_PACKET, "context"); //$NON-NLS-1$
102
103 /**
104 * Trace packet scope
105 *
106 * @since 3.0
107 */
108 public static final LexicalScope TRACE_PACKET = new LexicalScope(TRACE, "packet"); //$NON-NLS-1$
109
110 /**
111 * Stream event scope
112 *
113 * @since 3.0
114 */
115 public static final LexicalScope STREAM_EVENT = new LexicalScope(STREAM, "event"); //$NON-NLS-1$
116
117 /**
118 * Trace packet header string
119 *
120 * @since 3.0
121 */
122 public static final LexicalScope TRACE_PACKET_HEADER = new LexicalScope(STREAM_EVENT, "header"); //$NON-NLS-1$
123
124 /**
125 * Stream event context
126 *
127 * @since 3.0
128 */
129 public static final LexicalScope STREAM_EVENT_CONTEXT = new LexicalScope(STREAM_EVENT, "context"); //$NON-NLS-1$
130
131 /**
132 * Stream event header
133 *
134 * @since 3.0
135 */
136 public static final LexicalScope STREAM_EVENT_HEADER = new LexicalScope(TRACE_PACKET, "header"); //$NON-NLS-1$
137
138 /**
139 * Fields in an event
140 *
141 * @since 3.0
142 */
143 public static final LexicalScope FIELDS = new LexicalScope(ROOT, "fields"); //$NON-NLS-1$
144
145 /**
146 * Context of an event
147 *
148 * @since 3.0
149 */
150 public static final LexicalScope CONTEXT = new LexicalScope(ROOT, "context"); //$NON-NLS-1$
151
152 /**
153 * Sorted list of parent paths
154 *
155 * @since 3.0
156 */
157 public static final LexicalScope[] PARENT_PATHS = {
158 ROOT,
159 CONTEXT,
160 FIELDS,
161 PACKET_HEADER,
162 STREAM_EVENT_CONTEXT,
163 STREAM_EVENT_HEADER,
164 STREAM_PACKET_CONTEXT,
165 TRACE_PACKET_HEADER
166 };
167
168 private int hash = 0;
169 private final String fName;
170 private final String fPath;
171 private final Map<String, LexicalScope> fChildren;
172
173 /**
174 * The scope constructor
175 *
176 * @param parent
177 * The parent node, can be null, but shouldn't
178 * @param name
179 * the name of the field
180 */
181 public LexicalScope(@Nullable LexicalScope parent, String name) {
182 fName = name;
183 if (parent != null) {
184 String pathString = Joiner.on('.').skipNulls().join(parent.fPath, parent.getName());
185 if (pathString.startsWith(".")) { //$NON-NLS-1$
186 pathString = pathString.substring(1);
187 }
188 if (pathString == null) {
189 // we should get an NPE on pathString.startsWith before getting this
190 throw new IllegalStateException(
191 "Lexical scope constructor had null pathstring for " + //$NON-NLS-1$
192 parent.toString() + " and " + name); //$NON-NLS-1$
193 }
194 fPath = pathString;
195 parent.addChild(fName, this);
196 } else {
197 fPath = ""; //$NON-NLS-1$
198 }
199
200 @SuppressWarnings("null")
201 @NonNull
202 Map<String, LexicalScope> children =
203 Collections.synchronizedMap(new HashMap<String, LexicalScope>());
204 fChildren = children;
205 }
206
207 /**
208 * Adds a child lexical scope
209 *
210 * @param name
211 * the name of the child
212 * @param child
213 * the child
214 */
215 private void addChild(String name, LexicalScope child) {
216 fChildren.put(name, child);
217 }
218
219 /**
220 * Get the name
221 *
222 * @return the name
223 */
224 public String getName() {
225 return fName;
226 }
227
228 /**
229 * Gets a child of a given name
230 *
231 * @param name
232 * the child
233 * @return the scope, can be null
234 */
235 @Nullable
236 public LexicalScope getChild(String name) {
237 return fChildren.get(name);
238 }
239
240 @Override
241 public String toString() {
242 return fPath + '.' + fName;
243 }
244
245 @Override
246 public int compareTo(@Nullable LexicalScope other) {
247 if (other == null) {
248 throw new IllegalArgumentException();
249 }
250 int comp = fPath.compareTo(other.fPath);
251 if (comp == 0) {
252 return fName.compareTo(other.fName);
253 }
254 return comp;
255 }
256
257 @Override
258 public synchronized int hashCode() {
259 if (hash == 0) {
260 final int prime = 31;
261 hash = prime * (prime + fName.hashCode()) + fPath.hashCode();
262 }
263 return hash;
264 }
265
266 @Override
267 public boolean equals(@Nullable Object obj) {
268 if (this == obj) {
269 return true;
270 }
271 if (obj == null) {
272 return false;
273 }
274 if (getClass() != obj.getClass()) {
275 return false;
276 }
277 LexicalScope other = (LexicalScope) obj;
278 if (!fName.equals(other.fName)) {
279 return false;
280 }
281 return fPath.equals(other.fPath);
282 }
283 }
This page took 0.061598 seconds and 5 git commands to generate.