ctf: Fix Javadoc for all public methods
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / CTFTrace.java
index 69b2dd9057019ee4ce2c725568c2659988d5b466..91fcd596ecb2e3ff7865a22a1b281487134b0718 100644 (file)
@@ -16,6 +16,7 @@ import java.io.File;
 import java.io.FileFilter;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.Serializable;
 import java.nio.ByteOrder;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
@@ -23,20 +24,29 @@ import java.nio.channels.FileChannel.MapMode;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
 
-import org.eclipse.linuxtools.ctf.core.CtfCorePlugin;
 import org.eclipse.linuxtools.ctf.core.event.CTFClock;
-import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
-import org.eclipse.linuxtools.ctf.core.event.metadata.exceptions.ParseException;
+import org.eclipse.linuxtools.ctf.core.event.EventDeclaration;
+import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.Definition;
 import org.eclipse.linuxtools.ctf.core.event.types.IDefinitionScope;
 import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
 import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
 import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
+import org.eclipse.linuxtools.internal.ctf.core.Activator;
+import org.eclipse.linuxtools.internal.ctf.core.event.io.BitBuffer;
+import org.eclipse.linuxtools.internal.ctf.core.event.metadata.exceptions.ParseException;
+import org.eclipse.linuxtools.internal.ctf.core.trace.Stream;
+import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInput;
+import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndex;
 
 /**
  * <b><u>CTFTrace</u></b>
@@ -101,7 +111,7 @@ public class CTFTrace implements IDefinitionScope {
     /**
      * Packet header structure declaration
      */
-    private StructDeclaration packetHeaderDecl;
+    private StructDeclaration packetHeaderDecl = null;
 
     /**
      * Packet header structure definition
@@ -114,17 +124,33 @@ public class CTFTrace implements IDefinitionScope {
     /**
      * Collection of streams contained in the trace.
      */
-    private final HashMap<Long, Stream> streams = new HashMap<Long, Stream>();
+    private final HashMap<Long, Stream> streams;
 
     /**
      * Collection of environment variables set by the tracer
      */
-    private final HashMap<String, String> environment = new HashMap<String, String>();
+    private final HashMap<String, String> environment;
 
     /**
      * Collection of all the clocks in a system.
      */
-    private final HashMap<String, CTFClock> clocks = new HashMap<String, CTFClock>();
+    private final HashMap<String, CTFClock> clocks;
+
+    /** FileChannels to the streams */
+    private final List<FileChannel> streamFileChannels;
+
+    /** Handlers for the metadata files */
+    private final static FileFilter metadataFileFilter = new MetadataFileFilter();
+    private final static Comparator<File> metadataComparator = new MetadataComparator(); // $codepro.audit.disable
+                                                                                         // fieldJavadoc
+
+    /** map of all the event types */
+    private final HashMap<Long,HashMap<Long, EventDeclaration>> eventDecs;
+    /** map of all the event types */
+    private final HashMap<StreamInput,HashMap<Long, EventDefinition>> eventDefs;
+    /** map of all the indexes */
+    private final HashMap<StreamInput, StreamInputPacketIndex> indexes;
+
 
 
     // ------------------------------------------------------------------------
@@ -135,11 +161,13 @@ public class CTFTrace implements IDefinitionScope {
      * Trace constructor.
      *
      * @param path
-     *            Filesystem path of the trace directory.
-     * @throws IOException
+     *            Filesystem path of the trace directory
+     * @throws CTFReaderException
+     *             If no CTF trace was found at the path
      */
     public CTFTrace(String path) throws CTFReaderException {
         this(new File(path));
+
     }
 
     /**
@@ -148,24 +176,139 @@ public class CTFTrace implements IDefinitionScope {
      * @param path
      *            Filesystem path of the trace directory.
      * @throws CTFReaderException
+     *             If no CTF trace was found at the path
      */
-    @SuppressWarnings("unqualified-field-access")
     public CTFTrace(File path) throws CTFReaderException {
         this.path = path;
+        this.metadata = new Metadata(this);
 
-        metadata = new Metadata(this);
+        /* Set up the internal containers for this trace */
+        streams = new HashMap<Long, Stream>();
+        environment = new HashMap<String, String>();
+        clocks = new HashMap<String, CTFClock>();
+        streamFileChannels = new LinkedList<FileChannel>();
+        eventDecs = new HashMap<Long, HashMap<Long, EventDeclaration>>();
+        eventDefs = new HashMap<StreamInput, HashMap<Long, EventDefinition>>();
 
         if (!this.path.isDirectory()) {
             throw new CTFReaderException("Path must be a valid directory"); //$NON-NLS-1$
         }
 
-        this.open();
+        /* Open and parse the metadata file */
+        metadata.parse();
+
+        if (Activator.getDefault() != null) {
+            Activator.getDefault().log(metadata.toString());
+        }
+
+        /* Open all the trace files */
+        /* Create the definitions needed to read things from the files */
+        if (packetHeaderDecl != null) {
+            packetHeaderDef = packetHeaderDecl.createDefinition(this,
+                    "packet.header"); //$NON-NLS-1$
+        }
+
+        /* List files not called metadata and not hidden. */
+        File[] files = path.listFiles(metadataFileFilter);
+        Arrays.sort(files, metadataComparator);
+        indexes = new HashMap<StreamInput, StreamInputPacketIndex>();
+        /* Try to open each file */
+        for (File streamFile : files) {
+            openStreamInput(streamFile);
+        }
+
+        /* Create their index */
+        for (Map.Entry<Long, Stream> stream : streams.entrySet()) {
+            Set<StreamInput> inputs = stream.getValue().getStreamInputs();
+            for (StreamInput s : inputs) {
+                /*
+                 * Copy the events
+                 */
+                Iterator<Entry<Long, EventDeclaration>> it = s.getStream()
+                        .getEvents().entrySet().iterator();
+                while (it.hasNext()) {
+                    Map.Entry<Long, EventDeclaration> pairs = it.next();
+                    Long eventNum = pairs.getKey();
+                    EventDeclaration eventDec = pairs.getValue();
+                    getEvents(s.getStream().getId()).put(eventNum, eventDec);
+                }
+
+                /*
+                 * index the trace
+                 */
+                s.setupIndex();
+            }
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        /* If this trace gets closed, release the descriptors to the streams */
+        for (FileChannel fc : streamFileChannels) {
+            if (fc != null) {
+                try {
+                    fc.close();
+                } catch (IOException e) {
+                    // do nothing it's ok, we tried to close it.
+                }
+            }
+        }
+        super.finalize();
+
     }
 
     // ------------------------------------------------------------------------
     // Getters/Setters/Predicates
     // ------------------------------------------------------------------------
 
+    /**
+     * Gets an event declaration hash map for a given streamID
+     *
+     * @param streamId
+     *            The ID of the stream from which to read
+     * @return The Hash map with the event declarations
+     */
+    public HashMap<Long, EventDeclaration> getEvents(Long streamId) {
+        return eventDecs.get(streamId);
+    }
+
+    /**
+     * Gets an index for a given StreamInput
+     * @param id the StreamInput
+     * @return The index
+     */
+    public StreamInputPacketIndex getIndex(StreamInput id){
+        if(! indexes.containsKey(id)){
+            indexes.put(id, new StreamInputPacketIndex());
+        }
+        return indexes.get(id);
+    }
+
+    /**
+     * Gets an event Declaration hashmap for a given StreamInput
+     * @param id the StreamInput
+     * @return the hashmap with the event definitions
+     */
+    public HashMap<Long, EventDefinition> getEventDefs(StreamInput id) {
+        if(! eventDefs.containsKey(id)){
+            eventDefs.put(id, new HashMap<Long, EventDefinition>());
+        }
+        return eventDefs.get(id);
+    }
+
+    /**
+     * Get an event by it's ID
+     *
+     * @param streamId
+     *            The ID of the stream from which to read
+     * @param id
+     *            the ID of the event
+     * @return the event declaration
+     */
+    public EventDeclaration getEventType(long streamId, long id) {
+        return getEvents(streamId).get(id);
+    }
+
     /**
      * Method getStream gets the stream for a given id
      *
@@ -359,117 +502,22 @@ public class CTFTrace implements IDefinitionScope {
     // Operations
     // ------------------------------------------------------------------------
 
-    /**
-     * Opens the trace and creates the index.
-     *
-     * @throws CTFReaderException
-     */
-    private void open() throws CTFReaderException {
-        /* Open and parse the metadata file */
-        openTraceMetadata();
-
-        if (CtfCorePlugin.getDefault() != null) {
-            CtfCorePlugin.getDefault().log(metadata.toString());
-        }
-        /* Open all the trace files */
-        openStreamInputs();
-
-        /* Create their index */
-        createStreamInputIndexes();
-    }
-
-    /**
-     * Parses the metadata
-     *
-     * @throws CTFReaderException
-     */
-    private void openTraceMetadata() throws CTFReaderException {
-        metadata.parse();
-    }
-
-    /**
-     * Creates the definitions needed by the Trace class to open the trace
-     * files.
-     */
-    private void createDefinitions() {
-        if (packetHeaderDecl != null) {
-            packetHeaderDef = packetHeaderDecl.createDefinition(this,
-                    "packet.header"); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Creates the indexes of all the trace files.
-     *
-     * @throws CTFReaderException
-     */
-    private void createStreamInputIndexes() throws CTFReaderException {
-        for (Map.Entry<Long, Stream> stream : streams.entrySet()) {
-            Set<StreamInput> inputs = stream.getValue().getStreamInputs();
-            for (StreamInput s : inputs) {
-                s.createIndex();
-            }
-        }
-    }
-
-    /**
-     * Tries to open every file in the trace directory (except metadata).
-     *
-     * @throws CTFReaderException
-     */
-    private void openStreamInputs() throws CTFReaderException {
-        /* Create the definitions needed to read things from the files */
-        createDefinitions();
-
-        /* List files not called metadata and not hidden. */
-        File[] files = path.listFiles(new FileFilter() {
-
-            @Override
-            public boolean accept(File pathname) {
-
-                if (pathname.isDirectory()) {
-                    return false;
-                }
-
-                if (pathname.isHidden()) {
-                    return false;
-                }
-
-                if (pathname.getName().equals("metadata")) { //$NON-NLS-1$
-                    return false;
-                }
-
-                return true;
-            }
-        });
-        Arrays.sort(files, new Comparator<File>() {
-
-            @Override
-            public int compare(File o1, File o2) {
-
-                return o1.getName().compareTo(o2.getName());
-
-            }
-        });
-
-        /* Try to open each file */
-        for (File s : files) {
-            openStreamInput(s);
-        }
-    }
-
     /**
      * Tries to open the given file, reads the first packet header of the file
      * and check its validity.
      *
      * @param streamFile
      *            A trace file in the trace directory.
+     * @param index
+     *            Which index in the class' streamFileChannel array this file
+     *            must use
      * @throws CTFReaderException
      */
     private void openStreamInput(File streamFile) throws CTFReaderException {
-        FileChannel streamFileChannel;
         MappedByteBuffer byteBuffer;
         BitBuffer streamBitBuffer;
+        Stream stream;
+        FileChannel fc;
 
         if (!streamFile.canRead()) {
             throw new CTFReaderException("Unreadable file : " //$NON-NLS-1$
@@ -478,10 +526,11 @@ public class CTFTrace implements IDefinitionScope {
 
         try {
             /* Open the file and get the FileChannel */
-            streamFileChannel = new FileInputStream(streamFile).getChannel();
+            fc = new FileInputStream(streamFile).getChannel();
+            streamFileChannels.add(fc);
 
             /* Map one memory page of 4 kiB */
-            byteBuffer = streamFileChannel.map(MapMode.READ_ONLY, 0, 4096);
+            byteBuffer = fc.map(MapMode.READ_ONLY, 0, 4096);
         } catch (IOException e) {
             /* Shouldn't happen at this stage if every other check passed */
             throw new CTFReaderException();
@@ -495,20 +544,22 @@ public class CTFTrace implements IDefinitionScope {
             packetHeaderDef.read(streamBitBuffer);
 
             /* Check the magic number */
-            IntegerDefinition magicDef = (IntegerDefinition) packetHeaderDef.lookupDefinition("magic"); //$NON-NLS-1$
+            IntegerDefinition magicDef = (IntegerDefinition) packetHeaderDef
+                    .lookupDefinition("magic"); //$NON-NLS-1$
             int magic = (int) magicDef.getValue();
             if (magic != Utils.CTF_MAGIC) {
                 throw new CTFReaderException("CTF magic mismatch"); //$NON-NLS-1$
             }
 
             /* Check UUID */
-            ArrayDefinition uuidDef = (ArrayDefinition) packetHeaderDef.lookupDefinition("uuid"); //$NON-NLS-1$
-            assert ((uuidDef != null) && (uuidDef.getDeclaration().getLength() == Utils.UUID_LEN));
+            ArrayDefinition uuidDef = (ArrayDefinition) packetHeaderDef
+                    .lookupDefinition("uuid"); //$NON-NLS-1$
             if (uuidDef != null) {
                 byte[] uuidArray = new byte[Utils.UUID_LEN];
 
                 for (int i = 0; i < Utils.UUID_LEN; i++) {
-                    IntegerDefinition uuidByteDef = (IntegerDefinition) uuidDef.getElem(i);
+                    IntegerDefinition uuidByteDef = (IntegerDefinition) uuidDef
+                            .getElem(i);
                     uuidArray[i] = (byte) uuidByteDef.getValue();
                 }
 
@@ -523,31 +574,24 @@ public class CTFTrace implements IDefinitionScope {
             // TODO: it hasn't been checked that the stream_id field exists and
             // is an unsigned
             // integer
-            IntegerDefinition streamIDDef = (IntegerDefinition) packetHeaderDef.lookupDefinition("stream_id"); //$NON-NLS-1$
+            IntegerDefinition streamIDDef = (IntegerDefinition) packetHeaderDef
+                    .lookupDefinition("stream_id"); //$NON-NLS-1$
             assert (streamIDDef != null);
 
             long streamID = streamIDDef.getValue();
 
             /* Get the stream to which this trace file belongs to */
-            Stream stream = streams.get(streamID);
-
-            /* Create the stream input */
-            StreamInput streamInput = new StreamInput(stream,
-                    streamFileChannel, streamFile);
-
-            /* Add a reference to the streamInput in the stream */
-            stream.addInput(streamInput);
+            stream = streams.get(streamID);
         } else {
             /* No packet header, we suppose there is only one stream */
-            Stream stream = streams.get(null);
+            stream = streams.get(null);
+        }
 
-            /* Create the stream input */
-            StreamInput streamInput = new StreamInput(stream,
-                    streamFileChannel, streamFile);
+        /* Create the stream input */
+        StreamInput streamInput = new StreamInput(stream, fc, streamFile);
 
-            /* Add a reference to the streamInput in the stream */
-            stream.addInput(streamInput);
-        }
+        /* Add a reference to the streamInput in the stream */
+        stream.addInput(streamInput);
     }
 
     /**
@@ -571,8 +615,8 @@ public class CTFTrace implements IDefinitionScope {
      *
      * @param stream
      *            A stream object.
-     *
      * @throws ParseException
+     *             If there was some problem reading the metadata
      */
     public void addStream(Stream stream) throws ParseException {
 
@@ -585,8 +629,7 @@ public class CTFTrace implements IDefinitionScope {
         }
 
         /*
-         * If the stream we try to add has the null key, it must be the only
-         * one. Thus, if the streams container is not empty, it is not valid.
+         * If the stream we try to add has the null key, it must be the onl         * one. Thus, if the streams container is not empty, it is not valid.
          */
         if ((stream.getId() == null) && (streams.size() != 0)) {
             throw new ParseException("Stream without id with multiple streams"); //$NON-NLS-1$
@@ -599,37 +642,131 @@ public class CTFTrace implements IDefinitionScope {
 
         /* It should be ok now. */
         streams.put(stream.getId(), stream);
+        eventDecs.put(stream.getId(), new HashMap<Long,EventDeclaration>());
     }
 
+    /**
+     * gets the Environment variables from the trace metadata (See CTF spec)
+     * @return the environment variables in a hashmap form (key value)
+     */
     public HashMap<String, String> getEnvironment() {
         return environment;
     }
 
-    public String lookupEnvironment( String key )
-    {
+    /**
+     * Look up a specific environment variable
+     * @param key the key to look for
+     * @return the value of the variable, can be null.
+     */
+    public String lookupEnvironment(String key) {
         return environment.get(key);
     }
 
-    public void addEnvironmentVar( String varName, String varValue)
-    {
+    /**
+     * Add a variable to the environment variables
+     * @param varName the name of the variable
+     * @param varValue the value of the variable
+     */
+    public void addEnvironmentVar(String varName, String varValue) {
         environment.put(varName, varValue);
     }
 
+    /**
+     * Add a clock to the clock list
+     * @param nameValue the name of the clock (full name with scope)
+     * @param ctfClock the clock
+     */
     public void addClock(String nameValue, CTFClock ctfClock) {
-       clocks.put(nameValue, ctfClock);
+        clocks.put(nameValue, ctfClock);
     }
 
-    public CTFClock getClock(String name){
+    /**
+     * gets the clock with a specific name
+     * @param name the name of the clock.
+     * @return the clock
+     */
+    public CTFClock getClock(String name) {
         return clocks.get(name);
     }
 
-    public CTFClock getClock(){
-        if( clocks.size() == 1 )
-        {
-            String key = (String) clocks.keySet().toArray()[0];
-            return clocks.get(key);
+    private CTFClock singleClock;
+    private long singleOffset;
+
+    /**
+     * gets the clock if there is only one. (this is 100% of the use cases as of June 2012)
+     * @return the clock
+     */
+    public final CTFClock getClock() {
+        if (clocks.size() == 1) {
+            if (singleClock == null) {
+                singleClock = clocks.get(clocks.keySet().toArray()[0]);
+                singleOffset = (Long) getClock().getProperty("offset"); //$NON-NLS-1$
+            }
+            return singleClock;
         }
         return null;
     }
 
+    /**
+     * gets the time offset of a clock with respect to UTC in nanoseconds
+     * @return the time offset of a clock with respect to UTC in nanoseconds
+     */
+    public final long getOffset() {
+        if (getClock() == null) {
+            return 0;
+        }
+        return singleOffset;
+    }
+
+    /**
+     * Does a given stream contain any events?
+     * @param id the stream ID
+     * @return true if the stream has events.
+     */
+    public boolean hasEvents(Long id){
+        return eventDecs.containsKey(id);
+    }
+
+    /**
+     * Add an event declaration map to the events map.
+     * @param id the id of a stream
+     * @return the hashmap containing events.
+     */
+    public HashMap<Long, EventDeclaration> createEvents(Long id){
+        HashMap<Long, EventDeclaration> value = eventDecs.get(id);
+        if( value == null ) {
+            value = new HashMap<Long, EventDeclaration>();
+            eventDecs.put(id, value);
+        }
+        return value;
+    }
+
+}
+
+class MetadataFileFilter implements FileFilter {
+
+    @Override
+    public boolean accept(File pathname) {
+        if (pathname.isDirectory()) {
+            return false;
+        }
+        if (pathname.isHidden()) {
+            return false;
+        }
+        if (pathname.getName().equals("metadata")) { //$NON-NLS-1$
+            return false;
+        }
+        return true;
+    }
+
+}
+
+class MetadataComparator implements Comparator<File>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public int compare(File o1, File o2) {
+        return o1.getName().compareTo(o2.getName());
+    }
 }
This page took 0.034523 seconds and 5 git commands to generate.