1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
;
14 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.util
.concurrent
.ConcurrentHashMap
;
19 import org
.eclipse
.jdt
.annotation
.NonNull
;
20 import org
.eclipse
.jdt
.annotation
.NonNullByDefault
;
21 import org
.eclipse
.jdt
.annotation
.Nullable
;
23 import com
.google
.common
.base
.Joiner
;
26 * A node of a lexical scope
28 * @author Matthew Khouzam
31 public class LexicalScope
implements Comparable
<LexicalScope
> {
35 public static final LexicalScope ROOT
= new RootScope();
40 public static final LexicalScope TRACE
= new LexicalScope(ROOT
, "trace"); //$NON-NLS-1$
45 public static final LexicalScope ENV
= new LexicalScope(ROOT
, "env"); //$NON-NLS-1$
50 public static final LexicalScope STREAM
= new LexicalScope(ROOT
, "stream"); //$NON-NLS-1$
55 public static final LexicalScope EVENT
= new LexicalScope(ROOT
, "event"); //$NON-NLS-1$
60 public static final LexicalScope VARIANT
= new LexicalScope(ROOT
, "variant"); //$NON-NLS-1$
65 public static final LexicalScope PACKET
= new LexicalScope(ROOT
, "packet"); //$NON-NLS-1$
68 * Packet header string
70 public static final LexicalScope PACKET_HEADER
= new PacketHeaderScope();
75 public static final LexicalScope STREAM_PACKET
= new LexicalScope(STREAM
, "packet"); //$NON-NLS-1$
78 * Stream Packet header string
80 public static final LexicalScope STREAM_PACKET_CONTEXT
= new LexicalScope(STREAM_PACKET
, "context"); //$NON-NLS-1$
85 public static final LexicalScope TRACE_PACKET
= new LexicalScope(TRACE
, "packet"); //$NON-NLS-1$
90 public static final LexicalScope STREAM_EVENT
= new LexicalScope(STREAM
, "event"); //$NON-NLS-1$
93 * Trace packet header string
95 public static final LexicalScope TRACE_PACKET_HEADER
= new LexicalScope(TRACE_PACKET
, "header"); //$NON-NLS-1$
98 * Stream event context
100 public static final LexicalScope STREAM_EVENT_CONTEXT
= new LexicalScope(STREAM_EVENT
, "context"); //$NON-NLS-1$
103 * Stream event header
105 public static final LexicalScope STREAM_EVENT_HEADER
= new LexicalScope(STREAM_EVENT
, "header"); //$NON-NLS-1$
110 public static final LexicalScope EVENT_HEADER
= new EventHeaderScope(EVENT
, "header"); //$NON-NLS-1$
115 public static final LexicalScope FIELDS
= new FieldsScope(ROOT
, "fields"); //$NON-NLS-1$
118 * Context of an event
120 public static final LexicalScope CONTEXT
= new LexicalScope(ROOT
, "context"); //$NON-NLS-1$
123 * Sorted list of parent paths
125 public static final LexicalScope
[] PARENT_PATHS
= {
130 STREAM_EVENT_CONTEXT
,
132 STREAM_PACKET_CONTEXT
,
136 private int hash
= 0;
137 private final String fName
;
138 private final String fPath
;
139 private final Map
<String
, LexicalScope
> fChildren
= new ConcurrentHashMap
<>();
142 * The scope constructor
145 * The parent node, can be null, but shouldn't
147 * the name of the field
149 public LexicalScope(@Nullable LexicalScope parent
, String name
) {
151 if (parent
!= null) {
152 @NonNull String pathString
= checkNotNull(Joiner
.on('.').skipNulls().join(parent
.fPath
, parent
.getName()));
154 * if joiner return null, we get an NPE... so we won't assign fPath
157 if (pathString
.startsWith(".")) { //$NON-NLS-1$
159 * substring throws an exception or returns a string, it won't
162 pathString
= checkNotNull(pathString
.substring(1));
165 parent
.addChild(fName
, this);
167 fPath
= ""; //$NON-NLS-1$
172 * Adds a child lexical scope
175 * the name of the child
179 private void addChild(String name
, LexicalScope child
) {
180 fChildren
.put(name
, child
);
188 public String
getName() {
193 * Gets a child of a given name
197 * @return the scope, can be null
200 public LexicalScope
getChild(String name
) {
201 return fChildren
.get(name
);
205 public String
toString() {
206 return (fPath
.isEmpty() ? fName
: fPath
+ '.' + fName
);
210 public int compareTo(@Nullable LexicalScope other
) {
212 throw new IllegalArgumentException();
214 int comp
= fPath
.compareTo(other
.fPath
);
216 return fName
.compareTo(other
.fName
);
222 public synchronized int hashCode() {
224 final int prime
= 31;
225 hash
= prime
* (prime
+ fName
.hashCode()) + fPath
.hashCode();
231 public boolean equals(@Nullable Object obj
) {
238 if (getClass() != obj
.getClass()) {
241 LexicalScope other
= (LexicalScope
) obj
;
242 if (!fName
.equals(other
.fName
)) {
245 return fPath
.equals(other
.fPath
);