TMF: Add get parent to state system
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / Attribute.java
CommitLineData
a52fde77 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
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 *
a52fde77
AM
11 *******************************************************************************/
12
18ab1d18 13package org.eclipse.linuxtools.internal.tmf.core.statesystem;
a52fde77
AM
14
15import java.io.PrintWriter;
cb42195c 16import java.util.ArrayList;
a52fde77
AM
17import java.util.Collections;
18import java.util.HashMap;
19import java.util.LinkedList;
20import java.util.List;
cb42195c 21import java.util.Map;
a52fde77
AM
22
23/**
24 * An Attribute is a "node" in the Attribute Tree. It represents a smallest
25 * unit of the model which can be in a particular state at a given time.
cb42195c 26 *
a52fde77
AM
27 * It is abstract, as different implementations can provide different ways to
28 * access sub-attributes
cb42195c 29 *
a52fde77 30 * @author alexmont
cb42195c 31 *
a52fde77 32 */
a6917276 33public abstract class Attribute {
a52fde77
AM
34
35 private final Attribute parent;
36 private final String name;
37 private final int quark;
a6917276
AM
38
39 /** The list of sub-attributes */
cb42195c 40 protected final List<Attribute> subAttributes;
a52fde77
AM
41
42 /**
43 * Constructor
a6917276
AM
44 *
45 * @param parent
46 * The parent attribute of this one. Can be 'null' to represent
47 * this attribute is the root node of the tree.
48 * @param name
49 * Base name of this attribute
50 * @param quark
51 * The integer representation of this attribute
a52fde77 52 */
a6917276 53 public Attribute(Attribute parent, String name, int quark) {
a52fde77
AM
54 this.parent = parent;
55 this.quark = quark;
56 this.name = name;
a4524c1b 57 this.subAttributes = new ArrayList<>();
a52fde77
AM
58 }
59
a6917276
AM
60 // ------------------------------------------------------------------------
61 // Accessors
62 // ------------------------------------------------------------------------
63
a52fde77 64 /**
a6917276
AM
65 * Get the quark (integer representation) of this attribute.
66 *
67 * @return The quark of this attribute
a52fde77 68 */
a6917276 69 public int getQuark() {
a52fde77
AM
70 return quark;
71 }
72
a6917276
AM
73 /**
74 * Get the name of this attribute.
75 *
76 * @return The name of this attribute
77 */
78 public String getName() {
79 return name;
a52fde77
AM
80 }
81
a6917276
AM
82 /**
83 * Get the list of child attributes below this one. This is a read-only
84 * view.
85 *
86 * @return The list of child attributes.
87 */
88 public List<Attribute> getSubAttributes() {
cb42195c 89 return Collections.unmodifiableList(subAttributes);
a52fde77
AM
90 }
91
a52fde77
AM
92 /**
93 * Get the matching quark for a given path-of-strings
cb42195c 94 *
a52fde77
AM
95 * @param path
96 * The path we are looking for, *relative to this node*.
97 * @return The matching quark, or -1 if that attribute does not exist.
98 */
a6917276 99 public int getSubAttributeQuark(String... path) {
a52fde77
AM
100 return this.getSubAttributeQuark(path, 0);
101 }
102
103 /**
104 * Other method to search through the attribute tree, but instead of
105 * returning the matching quark we return the AttributeTreeNode object
106 * itself. It can then be used as new "root node" for faster queries on the
107 * tree.
cb42195c 108 *
a52fde77
AM
109 * @param path
110 * The target path, *relative to this node*
111 * @return The Node object matching the last element in the path, or "null"
112 * if that attribute does not exist.
113 */
a6917276 114 public Attribute getSubAttributeNode(String... path) {
a52fde77
AM
115 return this.getSubAttributeNode(path, 0);
116 }
117
118 /**
119 * "Inner" part of the previous public method, which is used recursively. To
120 * avoid having to copy sub-arrays to pass down, we just track where we are
121 * at with the index parameter. It uses getSubAttributeNode(), whose
122 * implementation is left to the derived classes.
123 */
124 private int getSubAttributeQuark(String[] path, int index) {
125 Attribute targetNode = this.getSubAttributeNode(path, index);
126 if (targetNode == null) {
127 return -1;
128 }
129 return targetNode.getQuark();
130 }
131
0fdd2c45
FG
132 /**
133 * Get the parent attribute of this attribute
134 *
135 * @return The parent attribute
136 */
137 public Attribute getParentAttribute() {
138 return this.parent;
139 }
140
141 /**
142 * Get the parent quark of this attribute
143 *
144 * @return The quark of the parent attribute
145 */
146 public int getParentAttributeQuark() {
147 return this.parent.getQuark();
148 }
149
a52fde77 150 /* The methods how to access children are left to derived classes */
a6917276
AM
151
152 /**
153 * Add a sub-attribute to this attribute
154 *
155 * @param newSubAttribute The new attribute to add
156 */
157 protected abstract void addSubAttribute(Attribute newSubAttribute);
158
159 /**
160 * Get a sub-attribute from this node's sub-attributes
161 *
162 * @param path
163 * The *full* path to the attribute
164 * @param index
165 * The index in 'path' where this attribute is located
166 * (indicating where to start searching).
167 * @return The requested attribute
168 */
169 protected abstract Attribute getSubAttributeNode(String[] path, int index);
a52fde77
AM
170
171 /**
172 * Return a String array composed of the full (absolute) path representing
173 * this attribute
cb42195c 174 *
a52fde77
AM
175 * @return
176 */
a6917276 177 private String[] getFullAttribute() {
a4524c1b 178 LinkedList<String> list = new LinkedList<>();
a52fde77
AM
179 Attribute curNode = this;
180
181 /* Add recursive parents to the list, but stop at the root node */
a6917276 182 while (curNode.parent != null) {
e2af45f9 183 list.addFirst(curNode.getName());
a6917276 184 curNode = curNode.parent;
a52fde77
AM
185 }
186
a52fde77
AM
187 return list.toArray(new String[0]);
188 }
189
190 /**
191 * Return the absolute path of this attribute, as a single slash-separated
192 * String.
cb42195c 193 *
a6917276 194 * @return The full name of this attribute
a52fde77 195 */
a6917276 196 public String getFullAttributeName() {
ab604305
AM
197 String[] array = this.getFullAttribute();
198 StringBuffer buf = new StringBuffer();
a52fde77 199
a52fde77 200 for (int i = 0; i < array.length - 1; i++) {
ab604305
AM
201 buf.append(array[i]);
202 buf.append('/');
a52fde77 203 }
ab604305
AM
204 buf.append(array[array.length - 1]);
205 return buf.toString();
a52fde77
AM
206 }
207
208 @Override
209 public String toString() {
210 return getFullAttributeName() + " (" + quark + ')'; //$NON-NLS-1$
211 }
212
213 private int curDepth;
214
215 private void attributeNodeToString(PrintWriter writer, Attribute currentNode) {
216 int j;
217
218 writer.println(currentNode.getName() + " (" + currentNode.quark + ')'); //$NON-NLS-1$
219 curDepth++;
220
cb42195c 221 for (Attribute nextNode : currentNode.getSubAttributes()) {
a52fde77
AM
222 /* Skip printing 'null' entries */
223 if (nextNode == null) {
224 continue;
225 }
226 for (j = 0; j < curDepth - 1; j++) {
227 writer.print(" "); //$NON-NLS-1$
228 }
229 writer.print(" "); //$NON-NLS-1$
230 attributeNodeToString(writer, nextNode);
231 }
232 curDepth--;
233 return;
234 }
235
a6917276
AM
236 /**
237 * Debugging method to print the contents of this attribute
238 *
239 * @param writer
240 * PrintWriter where to write the information
241 */
242 public void debugPrint(PrintWriter writer) {
a52fde77
AM
243 /* Only used for debugging, shouldn't be externalized */
244 writer.println("------------------------------"); //$NON-NLS-1$
245 writer.println("Attribute tree: (quark)\n"); //$NON-NLS-1$
246 curDepth = 0;
247 attributeNodeToString(writer, this);
248 writer.print('\n');
249 }
250}
251
252/**
253 * This is the basic implementation, where sub-attributes names can be composed
254 * of any alphanumeric characters, and are stored as Strings. A HashMap is used
255 * to access them.
cb42195c 256 *
a52fde77 257 * @author alexmont
cb42195c 258 *
a52fde77
AM
259 */
260final class AlphaNumAttribute extends Attribute {
261
a6917276 262 private final Map<String, Integer> subAttributesMap;
a52fde77 263
a6917276 264 public AlphaNumAttribute(Attribute parent, String name, int quark) {
a52fde77 265 super(parent, name, quark);
a4524c1b 266 this.subAttributesMap = new HashMap<>();
a52fde77
AM
267 }
268
269 @Override
a6917276 270 protected synchronized void addSubAttribute(Attribute newSubAttribute) {
a52fde77
AM
271 assert (newSubAttribute != null);
272 assert (newSubAttribute.getName() != null);
273 /* This should catch buggy state changing statements */
274 assert (!newSubAttribute.getName().equals(this.getName()));
275
276 subAttributesMap.put(newSubAttribute.getName(), subAttributes.size());
277 subAttributes.add(newSubAttribute);
278 }
279
280 @Override
281 protected synchronized Attribute getSubAttributeNode(String[] path,
282 int index) {
283 Integer indexOfNextNode = subAttributesMap.get(path[index]);
284 Attribute nextNode;
285
286 if (indexOfNextNode == null) {
287 /* We don't have the expected child => the attribute does not exist */
288 return null;
289 }
290 if (index == path.length - 1) {
291 /* It's our job to process this request */
292 return subAttributes.get(indexOfNextNode);
293 }
294
295 nextNode = subAttributes.get(indexOfNextNode);
296 return nextNode.getSubAttributeNode(path, index + 1);
297 }
298}
This page took 0.052894 seconds and 5 git commands to generate.