/*******************************************************************************
- * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2012, 2013 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
+ *
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
*******************************************************************************/
package org.eclipse.linuxtools.internal.tmf.core.statesystem;
import java.util.List;
import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
/**
* The Attribute Tree is the /proc-like filesystem used to organize attributes.
* Each node of this tree is both like a file and a directory in the
* "file system".
- *
+ *
* @author alexmont
- *
+ *
*/
-final class AttributeTree {
+public final class AttributeTree {
/* "Magic number" for attribute tree files or file sections */
- private final static int ATTRIB_TREE_MAGIC_NUMBER = 0x06EC3671;
+ private static final int ATTRIB_TREE_MAGIC_NUMBER = 0x06EC3671;
private final StateSystem ss;
private final List<Attribute> attributeList;
/**
* Standard constructor, create a new empty Attribute Tree
- *
+ *
* @param ss
* The StateSystem to which this AT is attached
*/
- AttributeTree(StateSystem ss) {
+ public AttributeTree(StateSystem ss) {
this.ss = ss;
this.attributeList = Collections.synchronizedList(new ArrayList<Attribute>());
this.attributeTreeRoot = new AlphaNumAttribute(null, "root", -1); //$NON-NLS-1$
}
/**
- * "Existing file" constructor Builds a attribute tree from a "mapping file"
- * or mapping section previously saved somewhere.
- *
+ * "Existing file" constructor. Builds an attribute tree from a
+ * "mapping file" or mapping section previously saved somewhere.
+ *
* @param ss
* StateSystem to which this AT is attached
* @param fis
* File stream where to read the AT information. Make sure it's
- * seeked at the right place!
+ * sought at the right place!
* @throws IOException
+ * If there is a problem reading from the file stream
*/
- AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
+ public AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
this(ss);
DataInputStream in = new DataInputStream(new BufferedInputStream(fis));
/* Message for exceptions, shouldn't be externalized */
final String errorMessage = "The attribute tree file section is either invalid or corrupted."; //$NON-NLS-1$
- ArrayList<String[]> list = new ArrayList<String[]>();
+ ArrayList<String[]> list = new ArrayList<>();
byte[] curByteArray;
String curFullString;
String[] curStringArray;
}
/**
- * Tell the Attribute Tree to write itself somewhere. The passed
- * FileOutputStream defines where (which file/position).
- *
- * @param fos
- * Where to write. Make sure it's seeked at the right position
- * you want.
+ * Tell the Attribute Tree to write itself somewhere in a file.
+ *
+ * @param file
+ * The file to write to
+ * @param pos
+ * The position (in bytes) in the file where to write
* @return The total number of bytes written.
*/
- int writeSelf(File file, long pos) {
- RandomAccessFile raf = null;
+ public int writeSelf(File file, long pos) {
int total = 0;
byte[] curByteArray;
- try {
- raf = new RandomAccessFile(file, "rw"); //$NON-NLS-1$
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw");) { //$NON-NLS-1$
raf.seek(pos);
/* Write the almost-magic number */
} catch (IOException e) {
e.printStackTrace();
- } finally {
- if (raf != null) {
- try {
- raf.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
}
return total;
}
* Return the number of attributes this system as seen so far. Note that
* this also equals the integer value (quark) the next added attribute will
* have.
- *
- * @return
+ *
+ * @return The current number of attributes in the tree
*/
- int getNbAttributes() {
+ public int getNbAttributes() {
return attributeList.size();
}
/**
- * This is the version to specifically add missing attributes.
- *
- * If 'numericalNode' is true, all the new attributes created will be of
- * type 'NumericalNode' instead of 'AlphaNumNode'. Be careful with this, if
- * you do not want ALL added attributes to be numerical, call this function
- * first with 'false' to create the parent nodes, then call it again to make
- * sure only the final node is numerical.
- *
+ * Get the quark for a given attribute path. No new attribute will be
+ * created : if the specified path does not exist, throw an error.
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the specified attribute
* @throws AttributeNotFoundException
+ * If the specified path was not found
*/
- int getQuarkDontAdd(int startingNodeQuark, String... subPath)
+ public int getQuarkDontAdd(int startingNodeQuark, String... subPath)
throws AttributeNotFoundException {
assert (startingNodeQuark >= -1);
return knownQuark;
}
- // FIXME synchronized here is probably quite costly... maybe only locking
- // the "for" would be enough?
- synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
+ /**
+ * Get the quark of a given attribute path. If that specified path does not
+ * exist, it will be created (and the quark that was just created will be
+ * returned).
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the attribute represented by the path
+ */
+ public synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
+ // FIXME synchronized here is probably quite costly... maybe only locking
+ // the "for" would be enough?
assert (subPath != null && subPath.length > 0);
assert (startingNodeQuark >= -1);
attributeList.size());
prevNode.addSubAttribute(nextNode);
attributeList.add(nextNode);
- ss.transState.addEmptyEntry();
+ ss.addEmptyAttribute();
}
prevNode = nextNode;
}
- return attributeList.size() - 1;
+ /*
+ * Insert an initial null value for this attribute in the state
+ * system (in case the state provider doesn't set one).
+ */
+ final int newAttrib = attributeList.size() - 1;
+ try {
+ ss.modifyAttribute(ss.getStartTime(), TmfStateValue.nullValue(), newAttrib);
+ } catch (TimeRangeException e) {
+ /* Should not happen, we're inserting at ss's start time */
+ throw new IllegalStateException(e);
+ } catch (AttributeNotFoundException e) {
+ /* Should not happen, we just created this attribute! */
+ throw new IllegalStateException(e);
+ } catch (StateValueTypeException e) {
+ /* Should not happen, there is no existing state value, and the
+ * one we insert is a null value anyway. */
+ throw new IllegalStateException(e);
+ }
+
+ return newAttrib;
}
/*
* The attribute was already existing, return the quark of that
return knownQuark;
}
- int getSubAttributesCount(int quark) {
- return attributeList.get(quark).getSubAttributesList().size();
- }
-
/**
* Returns the sub-attributes of the quark passed in parameter
- *
+ *
* @param attributeQuark
+ * The quark of the attribute to print the sub-attributes of.
* @param recursive
- * @return
+ * Should the query be recursive or not? If false, only children
+ * one level deep will be returned. If true, all descendants will
+ * be returned (depth-first search)
+ * @return The list of quarks representing the children attributes
* @throws AttributeNotFoundException
+ * If 'attributeQuark' is invalid, or if there is no attrbiute
+ * associated to it.
*/
- List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
+ public List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
throws AttributeNotFoundException {
- List<Integer> listOfChildren = new ArrayList<Integer>();
+ List<Integer> listOfChildren = new ArrayList<>();
Attribute startingAttribute;
/* Check if the quark is valid */
private void addSubAttributes(List<Integer> list, Attribute curAttribute,
boolean recursive) {
- for (Attribute childNode : curAttribute.getSubAttributesList()) {
+ for (Attribute childNode : curAttribute.getSubAttributes()) {
list.add(childNode.getQuark());
if (recursive) {
addSubAttributes(list, childNode, true);
}
}
- String getAttributeName(int quark) {
+ /**
+ * Get then base name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The (base) name of the attribute
+ */
+ public String getAttributeName(int quark) {
return attributeList.get(quark).getName();
}
- String getFullAttributeName(int quark) {
+ /**
+ * Get the full path name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The full path name of the attribute
+ */
+ public String getFullAttributeName(int quark) {
if (quark >= attributeList.size() || quark < 0) {
return null;
}
return attributeList.get(quark).getFullAttributeName();
}
- void debugPrint(PrintWriter writer) {
+ /**
+ * Debug-print all the attributes in the tree.
+ *
+ * @param writer
+ * The writer where to print the output
+ */
+ public void debugPrint(PrintWriter writer) {
attributeTreeRoot.debugPrint(writer);
}
-}
\ No newline at end of file
+}