org.jlab.coda.jevio
Class BaseStructure

java.lang.Object
  extended by org.jlab.coda.jevio.BaseStructure
All Implemented Interfaces:
java.lang.Cloneable, javax.swing.tree.MutableTreeNode, javax.swing.tree.TreeNode, IEvioStructure, IEvioWriter
Direct Known Subclasses:
EvioBank, EvioSegment, EvioTagSegment

public abstract class BaseStructure
extends java.lang.Object
implements java.lang.Cloneable, IEvioStructure, javax.swing.tree.MutableTreeNode, IEvioWriter

This is the base class for all evio structures: Banks, Segments, and TagSegments. It implements MutableTreeNode because a tree representation of events is created when a new event is parsed.

Note that using an EventBuilder for the same event in more than one thread can cause problems. For example the boolean lengthsUpToDate in this class would need to be volatile.

Author:
heddle, timmer - add byte order tracking, make setAllHeaderLengths more efficient

Constructor Summary
BaseStructure(BaseStructureHeader header)
          Constructor using a provided header
 
Method Summary
 void appendByteData(byte[] data)
          Appends byte data to the structure.
 void appendCompositeData(CompositeData[] data)
          Appends CompositeData objects to the structure.
 void appendDoubleData(double[] data)
          Appends double data to the structure.
 void appendFloatData(float[] data)
          Appends float data to the structure.
 void appendIntData(int[] data)
          Appends int data to the structure.
 void appendLongData(long[] data)
          Appends long data to the structure.
 void appendShortData(short[] data)
          Appends short data to the structure.
 void appendStringData(java.lang.String s)
          Appends string to the structure (as ascii).
 java.util.Enumeration<?> children()
          Get an enumeration of all the children of this structure.
 java.lang.Object clone()
          Clone this object.
 boolean getAllowsChildren()
          Checks whether children are allowed.
 byte[] getByteData()
          This is a method from the IEvioStructure Interface.
 java.nio.ByteOrder getByteOrder()
          What is the byte order of this data?
 javax.swing.tree.TreeNode getChildAt(int index)
          Obtain the child at the given index.
 int getChildCount()
          Get the count of the number of children.
 java.util.Vector<BaseStructure> getChildren()
          Get the children of this structure.
 CompositeData[] getCompositeData()
          This is a method from the IEvioStructure Interface.
 java.lang.String getDescription()
          Get the description from the name provider (dictionary), if there is one.
 double[] getDoubleData()
          This is a method from the IEvioStructure Interface.
 float[] getFloatData()
          This is a method from the IEvioStructure Interface.
 BaseStructureHeader getHeader()
          This is a method from the IEvioStructure Interface.
 int getIndex(javax.swing.tree.TreeNode node)
          Get the index of a node.
 int[] getIntData()
          This is a method from the IEvioStructure Interface.
 long[] getLongData()
          This is a method from the IEvioStructure Interface.
 java.util.List<BaseStructure> getMatchingStructures(IEvioFilter filter)
          Visit all the descendant structures, and collect those that pass a filter.
 int getNumberDataItems()
          Get the number of stored data items like number of banks, ints, floats, etc.
 BaseStructure getParent()
          Get the parent of this structure.
 byte[] getRawBytes()
          Get the raw data of the structure.
 short[] getShortData()
          This is a method from the IEvioStructure Interface.
 java.lang.String[] getStringData()
          This is a method from the IEvioStructure Interface.
abstract  StructureType getStructureType()
          A convenience method use instead of "instanceof" to see what type of structure we have.
 int getTotalBytes()
          Get the length of this structure in bytes, including the header.
abstract  java.lang.String getXMLElementName()
          Get the element name for the structure for writing to XML.
 void insert(javax.swing.tree.MutableTreeNode child)
          Convenience method to add a child at the end of the child list.
 void insert(javax.swing.tree.MutableTreeNode child, int index)
          Add a child at the given index.
 boolean isContainer()
          Checks whether this structure is a container, i.e.
 boolean isLeaf()
          Checks whether this is a leaf.
 boolean isSwap()
          Is a byte swap required? This is java and therefore big endian.
 void remove(int index)
          Removes the child at index from the receiver.
 void remove(javax.swing.tree.MutableTreeNode child)
          Removes the child.
 void removeFromParent()
          Remove this node from its parent.
 int setAllHeaderLengths()
          Compute and set length of all header fields for this structure and all its descendants.
 void setByteData(byte[] data)
          Set the data in this structure to the given array of bytes.
 void setByteOrder(java.nio.ByteOrder byteOrder)
          Set the byte order of this data.
 void setCompositeData(CompositeData[] data)
          Set the data in this structure to the given array of CompositeData objects.
 void setDoubleData(double[] data)
          Set the data in this structure to the given array of doubles.
 void setFloatData(float[] data)
          Set the data in this structure to the given array of floats.
 void setIntData(int[] data)
          Set the data in this structure to the given array of ints.
 void setLongData(long[] data)
          Set the data in this structure to the given array of longs.
 void setParent(javax.swing.tree.MutableTreeNode parent)
          Set the parent for this node.
 void setRawBytes(byte[] rawBytes)
          Set the data for the structure.
 void setShortData(short[] data)
          Set the data in this structure to the given array of shorts.
 void setStringData(java.lang.String[] data)
          Set the data in this structure to the given array of Strings.
 void setUserObject(java.lang.Object arg0)
          This method is not relevant for this implementation.
static byte[] stringsToRawBytes(java.lang.String[] strings)
          This method transforms an array of Strings into raw evio format data.
static int stringsToRawSize(java.lang.String[] strings)
          This method returns the number of bytes in a raw evio format of the given string array.
 java.lang.String toString()
          Obtain a string representation of the structure.
 java.lang.String toXML()
          Write this structure out as an XML format string.
abstract  void toXML(javax.xml.stream.XMLStreamWriter xmlWriter)
          This is a method that must be filled in by subclasses.
 void transform(BaseStructure structure)
          This method does a partial copy and is designed to help convert between banks, segments,and tagsegments in the StructureTransformer class (hence the name "transfrom").
static java.lang.String[] unpackRawBytesToStrings(byte[] rawBytes, int offset)
          This method extracts an array of strings from raw evio string data.
 void vistAllStructures(IEvioListener listener)
          Visit all the structures in this structure (including the structure itself -- which is considered its own descendant).
 void vistAllStructures(IEvioListener listener, IEvioFilter filter)
          Visit all the structures in this structure (including the structure itself -- which is considered its own descendant) in a depth first manner.
 int write(java.nio.ByteBuffer byteBuffer)
          Write myself out a byte buffer with fastest algorithms I could find.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

BaseStructure

public BaseStructure(BaseStructureHeader header)
Constructor using a provided header

Parameters:
header - the header to use.
See Also:
BaseStructureHeader
Method Detail

transform

public void transform(BaseStructure structure)
This method does a partial copy and is designed to help convert between banks, segments,and tagsegments in the StructureTransformer class (hence the name "transfrom"). It copies all the data from another BaseStructure object. Children are not copied in the deep clone way, but their references are added to this structure. It does not copy header data or the parent either.

Parameters:
structure - BaseStructure from which to copy data.

clone

public java.lang.Object clone()
Clone this object. First call the Object class's clone() method which creates a bitwise copy. Then clone all the mutable objects so that this method does a safe (not deep) clone. This means all children get cloned as well. Remind me again why anyone would want to clone their bratty kids?

Overrides:
clone in class java.lang.Object

getStructureType

public abstract StructureType getStructureType()
A convenience method use instead of "instanceof" to see what type of structure we have. Note: this returns the type of this structure, not the type of data (the content type) this structure holds.

Specified by:
getStructureType in interface IEvioStructure
Returns:
the StructureType of this structure.
See Also:
StructureType

toXML

public abstract void toXML(javax.xml.stream.XMLStreamWriter xmlWriter)
This is a method that must be filled in by subclasses. Write this structure out as an XML record.

Parameters:
xmlWriter - the writer used to write the events. It is tied to an open file.

getXMLElementName

public abstract java.lang.String getXMLElementName()
Get the element name for the structure for writing to XML.

Returns:
the element name for the structure for writing to XML.

toXML

public java.lang.String toXML()
Write this structure out as an XML format string.


getByteOrder

public java.nio.ByteOrder getByteOrder()
What is the byte order of this data?

Returns:
ByteOrder.BIG_ENDIAN or ByteOrder.LITTLE_ENDIAN

setByteOrder

public void setByteOrder(java.nio.ByteOrder byteOrder)
Set the byte order of this data. This method cannot be used to swap data. It is only used to describe the endianness of the rawdata contained.

Parameters:
byteOrder - ByteOrder.BIG_ENDIAN or ByteOrder.LITTLE_ENDIAN

isSwap

public boolean isSwap()
Is a byte swap required? This is java and therefore big endian. If data is little endian, then a swap is required.

Returns:
true if byte swapping is required (data is little endian).

getDescription

public java.lang.String getDescription()
Get the description from the name provider (dictionary), if there is one.

Specified by:
getDescription in interface IEvioStructure
Returns:
the description from the name provider (dictionary), if there is one. If not, return NameProvider.NO_NAME_STRING.

toString

public java.lang.String toString()
Obtain a string representation of the structure.

Overrides:
toString in class java.lang.Object
Returns:
a string representation of the structure.

getHeader

public BaseStructureHeader getHeader()
This is a method from the IEvioStructure Interface. Return the header for this structure.

Specified by:
getHeader in interface IEvioStructure
Returns:
the header for this structure.

getNumberDataItems

public int getNumberDataItems()
Get the number of stored data items like number of banks, ints, floats, etc. (not the size in ints or bytes). Some items may be padded such as shorts and bytes. This will tell the meaningful number of such data items. In the case of containers, returns number of bytes not in header.

Returns:
number of stored data items (not size or length), or number of bytes if container

getTotalBytes

public int getTotalBytes()
Get the length of this structure in bytes, including the header.

Returns:
the length of this structure in bytes, including the header.

getRawBytes

public byte[] getRawBytes()
Get the raw data of the structure.

Returns:
the raw data of the structure.

setRawBytes

public void setRawBytes(byte[] rawBytes)
Set the data for the structure.

Parameters:
rawBytes - the structure raw data.

getIntData

public int[] getIntData()
This is a method from the IEvioStructure Interface. Gets the raw data as an integer array, if the content type as indicated by the header is appropriate.

NOTE: since Java does not have unsigned primitives, both INT32 and UINT32 data types will be returned as int arrays. The application will have to deal with reinterpreting signed ints that are negative as unsigned ints.

Specified by:
getIntData in interface IEvioStructure
Returns:
the data as an int array, or null if this makes no sense for the given content type.

getLongData

public long[] getLongData()
This is a method from the IEvioStructure Interface. Gets the raw data as a long array, if the content type as indicated by the header is appropriate.

NOTE: since Java does not have unsigned primitives, both LONG64 and ULONG64 data types will be returned as long arrays. The application will have to deal with reinterpreting signed longs that are negative as unsigned longs.

Specified by:
getLongData in interface IEvioStructure
Returns:
the data as an long array, or null if this makes no sense for the given content type.

getFloatData

public float[] getFloatData()
This is a method from the IEvioStructure Interface. Gets the raw data as a float array, if the content type as indicated by the header is appropriate.

Specified by:
getFloatData in interface IEvioStructure
Returns:
the data as an double array, or null if this makes no sense for the given contents type.

getDoubleData

public double[] getDoubleData()
This is a method from the IEvioStructure Interface. Gets the raw data as a double array, if the content type as indicated by the header is appropriate.

Specified by:
getDoubleData in interface IEvioStructure
Returns:
the data as an double array, or null if this makes no sense for the given content type.

getShortData

public short[] getShortData()
This is a method from the IEvioStructure Interface. Gets the raw data as a short array, if the contents type as indicated by the header is appropriate.

NOTE: since Java does not have unsigned primitives, both SHORT16 and USHORT16 data types will be returned as short arrays. The application will have to deal with reinterpreting signed shorts that are negative as unsigned shorts.

Specified by:
getShortData in interface IEvioStructure
Returns:
the data as an short array, or null if this makes no sense for the given contents type.

getCompositeData

public CompositeData[] getCompositeData()
                                 throws EvioException
This is a method from the IEvioStructure Interface. Gets the composite data as an array of CompositeData objects, if the content type as indicated by the header is appropriate.

Specified by:
getCompositeData in interface IEvioStructure
Returns:
the data as an array of CompositeData objects, or null if this makes no sense for the given content type.
Throws:
EvioException - if the data is internally inconsistent

getByteData

public byte[] getByteData()
This is a method from the IEvioStructure Interface. Gets the raw data as an byte array, if the contents type as indicated by the header is appropriate.

NOTE: since Java does not have unsigned primitives, CHAR8 and UCHAR8 data types will be returned as byte arrays. The application will have to deal with reinterpreting bytes as characters, if necessary.

Specified by:
getByteData in interface IEvioStructure
Returns:
the data as an byte array, or null if this makes no sense for the given contents type.

getStringData

public java.lang.String[] getStringData()
This is a method from the IEvioStructure Interface. Gets the raw data (ascii) as an array of String objects, if the contents type as indicated by the header is appropriate. For any other behavior, the user should retrieve the data as a byte array and manipulate it in the exact manner desired.

Originally, in evio versions 1, 2 and 3, only one string was stored. Recent changes allow an array of strings to be stored and retrieved. The changes are backwards compatible. The following is true about the string raw data format:

Specified by:
getStringData in interface IEvioStructure
Returns:
the data as an array of String objects if DataType is CHARSTAR8, or null if this makes no sense for the given type.

stringsToRawSize

public static int stringsToRawSize(java.lang.String[] strings)
This method returns the number of bytes in a raw evio format of the given string array.

Parameters:
strings - array of String objects to size
Returns:
the number of bytes in a raw evio format of the given string array

stringsToRawBytes

public static byte[] stringsToRawBytes(java.lang.String[] strings)
This method transforms an array of Strings into raw evio format data.

Parameters:
strings - array of String objects to transform
Returns:
byte array containing evio format string array

unpackRawBytesToStrings

public static java.lang.String[] unpackRawBytesToStrings(byte[] rawBytes,
                                                         int offset)
This method extracts an array of strings from raw evio string data.

Parameters:
rawBytes - raw evio string data
offset - offset into raw data array
Returns:
array of Strings or null if processing error

getParent

public BaseStructure getParent()
Get the parent of this structure. The outer event bank is the only structure with a null parent (the only orphan). All other structures have non-null parent giving the container in which they were embedded. Part of the MutableTreeNode interface.

Specified by:
getParent in interface javax.swing.tree.TreeNode
Returns:
the parent of this structure.

children

public java.util.Enumeration<?> children()
Get an enumeration of all the children of this structure. If none, it returns a constant, empty Enumeration. Part of the MutableTreeNode interface.

Specified by:
children in interface javax.swing.tree.TreeNode

insert

public void insert(javax.swing.tree.MutableTreeNode child,
                   int index)
Add a child at the given index.

Specified by:
insert in interface javax.swing.tree.MutableTreeNode
Parameters:
child - the child to add.
index - the target index. Part of the MutableTreeNode interface.

insert

public void insert(javax.swing.tree.MutableTreeNode child)
Convenience method to add a child at the end of the child list. In this application where are not concerned with the ordering of the children.

Parameters:
child - the child to add. It will be added to the end of child list.

remove

public void remove(int index)
Removes the child at index from the receiver. Part of the MutableTreeNode interface.

Specified by:
remove in interface javax.swing.tree.MutableTreeNode
Parameters:
index - the target index for removal.

remove

public void remove(javax.swing.tree.MutableTreeNode child)
Removes the child. Part of the MutableTreeNode interface.

Specified by:
remove in interface javax.swing.tree.MutableTreeNode
Parameters:
child - the child node being removed.

removeFromParent

public void removeFromParent()
Remove this node from its parent. Part of the MutableTreeNode interface.

Specified by:
removeFromParent in interface javax.swing.tree.MutableTreeNode

setParent

public void setParent(javax.swing.tree.MutableTreeNode parent)
Set the parent for this node. Part of the MutableTreeNode interface.

Specified by:
setParent in interface javax.swing.tree.MutableTreeNode

vistAllStructures

public void vistAllStructures(IEvioListener listener)
Visit all the structures in this structure (including the structure itself -- which is considered its own descendant). This is similar to listening to the event as it is being parsed, but is done to a complete (already) parsed event.

Parameters:
listener - an listener to notify as each structure is visited.

vistAllStructures

public void vistAllStructures(IEvioListener listener,
                              IEvioFilter filter)
Visit all the structures in this structure (including the structure itself -- which is considered its own descendant) in a depth first manner.

Parameters:
listener - an listener to notify as each structure is visited.
filter - an optional filter that must "accept" structures before they are passed to the listener. If null, all structures are passed. In this way, specific types of structures can be captured.

getMatchingStructures

public java.util.List<BaseStructure> getMatchingStructures(IEvioFilter filter)
Visit all the descendant structures, and collect those that pass a filter.

Parameters:
filter - the filter that must be passed. If null, this will return all the structures.
Returns:
a collection of all structures that are accepted by a filter.

setUserObject

public void setUserObject(java.lang.Object arg0)
This method is not relevant for this implementation. An empty implementation is provided to satisfy the interface. Part of the MutableTreeNode interface.

Specified by:
setUserObject in interface javax.swing.tree.MutableTreeNode

getAllowsChildren

public boolean getAllowsChildren()
Checks whether children are allowed. Structures of structures can have children. Structures of primitive data can not. Thus is is entirely determined by the content type. Part of the MutableTreeNode interface.

Specified by:
getAllowsChildren in interface javax.swing.tree.TreeNode
Returns:
true if this node does not hold primitive data, i.e., if it is a structure of structures (a container).

getChildAt

public javax.swing.tree.TreeNode getChildAt(int index)
Obtain the child at the given index. Part of the MutableTreeNode interface.

Specified by:
getChildAt in interface javax.swing.tree.TreeNode
Parameters:
index - the target index.
Returns:
the child at the given index or null if none

getChildCount

public int getChildCount()
Get the count of the number of children. Part of the MutableTreeNode interface.

Specified by:
getChildCount in interface javax.swing.tree.TreeNode
Returns:
the number of children.

getIndex

public int getIndex(javax.swing.tree.TreeNode node)
Get the index of a node. Part of the MutableTreeNode interface.

Specified by:
getIndex in interface javax.swing.tree.TreeNode
Returns:
the index of the target node or -1 if no such node in tree

isLeaf

public boolean isLeaf()
Checks whether this is a leaf. Leaves are structures with no children. All structures that contain primitive data are leaf structures. Part of the MutableTreeNode interface.
Note: this means that an empty container, say a Bank of Segments that have no segments, is a leaf.

Specified by:
isLeaf in interface javax.swing.tree.TreeNode
Returns:
true if this is a structure with a primitive data type, i.e., it is not a container structure that contains other structures.

isContainer

public boolean isContainer()
Checks whether this structure is a container, i.e. a structure of structures.

Returns:
true if this structure is a container. This is the same check as getAllowsChildren().

getChildren

public java.util.Vector<BaseStructure> getChildren()
Get the children of this structure.

Returns:
the children of this structure.

setAllHeaderLengths

public int setAllHeaderLengths()
Compute and set length of all header fields for this structure and all its descendants. For writing events, this will be crucial for setting the values in the headers.

Returns:
the length that would go in the header field (for a leaf).

write

public int write(java.nio.ByteBuffer byteBuffer)
Write myself out a byte buffer with fastest algorithms I could find.

Specified by:
write in interface IEvioWriter
Parameters:
byteBuffer - the byteBuffer to write to.
Returns:
the number of bytes written.

appendIntData

public void appendIntData(int[] data)
                   throws EvioException
Appends int data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the int data to append, or set if there is no existing data.
Throws:
EvioException - if adding data to a structure of a different data type

appendShortData

public void appendShortData(short[] data)
                     throws EvioException
Appends short data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the short data to append, or set if there is no existing data.
Throws:
EvioException

appendLongData

public void appendLongData(long[] data)
                    throws EvioException
Appends long data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the long data to append, or set if there is no existing data.
Throws:
EvioException

appendByteData

public void appendByteData(byte[] data)
                    throws EvioException
Appends byte data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the byte data to append, or set if there is no existing data.
Throws:
EvioException

appendFloatData

public void appendFloatData(float[] data)
                     throws EvioException
Appends float data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the float data to append, or set if there is no existing data.
Throws:
EvioException

appendStringData

public void appendStringData(java.lang.String s)
                      throws EvioException
Appends string to the structure (as ascii). If the structure has no data, then this is the same as setting the data.

Parameters:
s - the string to append (as ascii), or set if there is no existing data.
Throws:
EvioException

appendDoubleData

public void appendDoubleData(double[] data)
                      throws EvioException
Appends double data to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the double data to append, or set if there is no existing data.
Throws:
EvioException

appendCompositeData

public void appendCompositeData(CompositeData[] data)
                         throws EvioException
Appends CompositeData objects to the structure. If the structure has no data, then this is the same as setting the data.

Parameters:
data - the CompositeData objects to append, or set if there is no existing data.
Throws:
EvioException

setIntData

public void setIntData(int[] data)
Set the data in this structure to the given array of ints. All previously existing data will be gone. If the previous data type was not DataType.UINT32 or DataType.INT32, it will be reset in the header to DataType.INT32.

Parameters:
data - the int data to set to.

setShortData

public void setShortData(short[] data)
Set the data in this structure to the given array of shorts. All previously existing data will be gone. If the previous data type was not DataType.USHORT16 or DataType.SHORT16, it will be reset in the header to DataType.SHORT16.

Parameters:
data - the short data to set to.

setLongData

public void setLongData(long[] data)
Set the data in this structure to the given array of longs. All previously existing data will be gone. If the previous data type was not DataType.ULONG64 or DataType.LONG64, it will be reset in the header to DataType.LONG64.

Parameters:
data - the long data to set to.

setByteData

public void setByteData(byte[] data)
Set the data in this structure to the given array of bytes. All previously existing data will be gone. If the previous data type was not DataType.UCHAR8 or DataType.CHAR8, it will be reset in the header to DataType.CHAR8.

Parameters:
data - the byte data to set to.

setFloatData

public void setFloatData(float[] data)
Set the data in this structure to the given array of floats. All previously existing data will be gone. If the previous data type was not DataType.FLOAT32, it will be reset in the header to that type.

Parameters:
data - the float data to set to.

setDoubleData

public void setDoubleData(double[] data)
Set the data in this structure to the given array of doubles. All previously existing data will be gone. If the previous data type was not DataType.DOUBLE64, it will be reset in the header to that type.

Parameters:
data - the double data to set to.

setStringData

public void setStringData(java.lang.String[] data)
Set the data in this structure to the given array of Strings. All previously existing data will be gone. If the previous data type was not DataType.CHARSTAR8,it will be reset in the header to that type.

Parameters:
data - the String data to set to.

setCompositeData

public void setCompositeData(CompositeData[] data)
Set the data in this structure to the given array of CompositeData objects. All previously existing data will be gone. If the previous data type was not DataType.COMPOSITE, it will be reset in the header to that type.

Parameters:
data - the array of CompositeData objects to set to.