releng: Transition to jdt.annotation 2.0
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / Attribute.java
CommitLineData
a52fde77 1/*******************************************************************************
04927a83 2 * Copyright (c) 2012, 2015 Ericsson, EfficiOS Inc.
a52fde77
AM
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
cb42195c 5 *
a52fde77
AM
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
cb42195c 10 *
04927a83
AM
11 * Contributors:
12 * Alexandre Montplaisir - Initial API and implementation
a52fde77
AM
13 *******************************************************************************/
14
e894a508 15package org.eclipse.tracecompass.internal.statesystem.core;
a52fde77 16
04927a83
AM
17import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
18
a52fde77
AM
19import java.io.PrintWriter;
20import java.util.Collections;
fe0b6837 21import java.util.LinkedHashMap;
a52fde77 22import java.util.LinkedList;
cb42195c 23import java.util.Map;
a52fde77 24
04927a83
AM
25import org.eclipse.jdt.annotation.NonNull;
26
c3f21a07
AM
27import com.google.common.collect.ImmutableList;
28
a52fde77
AM
29/**
30 * An Attribute is a "node" in the Attribute Tree. It represents a smallest
31 * unit of the model which can be in a particular state at a given time.
cb42195c 32 *
a52fde77
AM
33 * It is abstract, as different implementations can provide different ways to
34 * access sub-attributes
cb42195c 35 *
04927a83 36 * @author Alexandre Montplaisir
cb42195c 37 *
a52fde77 38 */
c3f21a07 39public final class Attribute {
a52fde77
AM
40
41 private final Attribute parent;
04927a83 42 private final @NonNull String name;
a52fde77 43 private final int quark;
a6917276 44
c3f21a07
AM
45 /** The sub-attributes (<basename, attribute>) of this attribute */
46 private final Map<String, Attribute> subAttributes;
a52fde77
AM
47
48 /**
49 * Constructor
a6917276
AM
50 *
51 * @param parent
52 * The parent attribute of this one. Can be 'null' to represent
53 * this attribute is the root node of the tree.
54 * @param name
55 * Base name of this attribute
56 * @param quark
57 * The integer representation of this attribute
a52fde77 58 */
04927a83 59 public Attribute(Attribute parent, @NonNull String name, int quark) {
a52fde77
AM
60 this.parent = parent;
61 this.quark = quark;
62 this.name = name;
fe0b6837 63 this.subAttributes = Collections.synchronizedMap(new LinkedHashMap<String, Attribute>());
a52fde77
AM
64 }
65
a6917276
AM
66 // ------------------------------------------------------------------------
67 // Accessors
68 // ------------------------------------------------------------------------
69
a52fde77 70 /**
a6917276
AM
71 * Get the quark (integer representation) of this attribute.
72 *
73 * @return The quark of this attribute
a52fde77 74 */
a6917276 75 public int getQuark() {
a52fde77
AM
76 return quark;
77 }
78
a6917276
AM
79 /**
80 * Get the name of this attribute.
81 *
82 * @return The name of this attribute
83 */
04927a83 84 public @NonNull String getName() {
a6917276 85 return name;
a52fde77
AM
86 }
87
a6917276 88 /**
c3f21a07 89 * Get the list of child attributes below this one.
a6917276 90 *
c3f21a07 91 * @return The child attributes.
a6917276 92 */
c3f21a07
AM
93 public Iterable<Attribute> getSubAttributes() {
94 return ImmutableList.copyOf(subAttributes.values());
a52fde77
AM
95 }
96
a52fde77
AM
97 /**
98 * Get the matching quark for a given path-of-strings
cb42195c 99 *
a52fde77
AM
100 * @param path
101 * The path we are looking for, *relative to this node*.
102 * @return The matching quark, or -1 if that attribute does not exist.
103 */
a6917276 104 public int getSubAttributeQuark(String... path) {
a52fde77
AM
105 return this.getSubAttributeQuark(path, 0);
106 }
107
108 /**
109 * Other method to search through the attribute tree, but instead of
110 * returning the matching quark we return the AttributeTreeNode object
111 * itself. It can then be used as new "root node" for faster queries on the
112 * tree.
cb42195c 113 *
a52fde77
AM
114 * @param path
115 * The target path, *relative to this node*
116 * @return The Node object matching the last element in the path, or "null"
117 * if that attribute does not exist.
118 */
a6917276 119 public Attribute getSubAttributeNode(String... path) {
a52fde77
AM
120 return this.getSubAttributeNode(path, 0);
121 }
122
123 /**
124 * "Inner" part of the previous public method, which is used recursively. To
125 * avoid having to copy sub-arrays to pass down, we just track where we are
126 * at with the index parameter. It uses getSubAttributeNode(), whose
127 * implementation is left to the derived classes.
128 */
129 private int getSubAttributeQuark(String[] path, int index) {
130 Attribute targetNode = this.getSubAttributeNode(path, index);
131 if (targetNode == null) {
132 return -1;
133 }
134 return targetNode.getQuark();
135 }
136
0fdd2c45
FG
137 /**
138 * Get the parent attribute of this attribute
139 *
140 * @return The parent attribute
141 */
142 public Attribute getParentAttribute() {
143 return this.parent;
144 }
145
146 /**
147 * Get the parent quark of this attribute
148 *
149 * @return The quark of the parent attribute
150 */
151 public int getParentAttributeQuark() {
152 return this.parent.getQuark();
153 }
154
a52fde77 155 /* The methods how to access children are left to derived classes */
a6917276
AM
156
157 /**
158 * Add a sub-attribute to this attribute
159 *
160 * @param newSubAttribute The new attribute to add
161 */
c3f21a07 162 public void addSubAttribute(Attribute newSubAttribute) {
04927a83 163 if (newSubAttribute == null) {
c3f21a07
AM
164 throw new IllegalArgumentException();
165 }
166 subAttributes.put(newSubAttribute.getName(), newSubAttribute);
167 }
a6917276
AM
168
169 /**
170 * Get a sub-attribute from this node's sub-attributes
171 *
172 * @param path
173 * The *full* path to the attribute
174 * @param index
175 * The index in 'path' where this attribute is located
176 * (indicating where to start searching).
177 * @return The requested attribute
178 */
c3f21a07
AM
179 private Attribute getSubAttributeNode(String[] path, int index) {
180 final Attribute nextNode = subAttributes.get(path[index]);
181
182 if (nextNode == null) {
183 /* We don't have the expected child => the attribute does not exist */
184 return null;
185 }
186 if (index == path.length - 1) {
187 /* It's our job to process this request */
188 return nextNode;
189 }
190
191 /* Pass on the rest of the path to the relevant child */
192 return nextNode.getSubAttributeNode(path, index + 1);
193 }
a52fde77
AM
194
195 /**
196 * Return a String array composed of the full (absolute) path representing
197 * this attribute
cb42195c 198 *
34638411 199 * @return The full attribute path elements
a52fde77 200 */
4c4e2816 201 public String @NonNull [] getFullAttribute() {
a4524c1b 202 LinkedList<String> list = new LinkedList<>();
a52fde77
AM
203 Attribute curNode = this;
204
205 /* Add recursive parents to the list, but stop at the root node */
a6917276 206 while (curNode.parent != null) {
e2af45f9 207 list.addFirst(curNode.getName());
a6917276 208 curNode = curNode.parent;
a52fde77
AM
209 }
210
34638411 211 return checkNotNull(list.toArray(new String[0]));
a52fde77
AM
212 }
213
214 /**
215 * Return the absolute path of this attribute, as a single slash-separated
216 * String.
cb42195c 217 *
a6917276 218 * @return The full name of this attribute
a52fde77 219 */
04927a83 220 public @NonNull String getFullAttributeName() {
ab604305
AM
221 String[] array = this.getFullAttribute();
222 StringBuffer buf = new StringBuffer();
a52fde77 223
a52fde77 224 for (int i = 0; i < array.length - 1; i++) {
ab604305
AM
225 buf.append(array[i]);
226 buf.append('/');
a52fde77 227 }
ab604305 228 buf.append(array[array.length - 1]);
04927a83 229 return checkNotNull(buf.toString());
a52fde77
AM
230 }
231
232 @Override
233 public String toString() {
234 return getFullAttributeName() + " (" + quark + ')'; //$NON-NLS-1$
235 }
236
237 private int curDepth;
238
239 private void attributeNodeToString(PrintWriter writer, Attribute currentNode) {
a52fde77
AM
240 writer.println(currentNode.getName() + " (" + currentNode.quark + ')'); //$NON-NLS-1$
241 curDepth++;
242
cb42195c 243 for (Attribute nextNode : currentNode.getSubAttributes()) {
a52fde77
AM
244 /* Skip printing 'null' entries */
245 if (nextNode == null) {
246 continue;
247 }
c3f21a07 248 for (int j = 0; j < curDepth - 1; j++) {
a52fde77
AM
249 writer.print(" "); //$NON-NLS-1$
250 }
251 writer.print(" "); //$NON-NLS-1$
252 attributeNodeToString(writer, nextNode);
253 }
254 curDepth--;
255 return;
256 }
257
a6917276
AM
258 /**
259 * Debugging method to print the contents of this attribute
260 *
261 * @param writer
262 * PrintWriter where to write the information
263 */
264 public void debugPrint(PrintWriter writer) {
a52fde77
AM
265 /* Only used for debugging, shouldn't be externalized */
266 writer.println("------------------------------"); //$NON-NLS-1$
267 writer.println("Attribute tree: (quark)\n"); //$NON-NLS-1$
268 curDepth = 0;
269 attributeNodeToString(writer, this);
270 writer.print('\n');
271 }
272}
This page took 0.081984 seconds and 5 git commands to generate.