trace/traceviewer/com.nokia.traceviewer/src/com/nokia/traceviewer/engine/DataReaderAccess.java
changeset 11 5b9d4d8641ce
equal deleted inserted replaced
10:ed1c9f64298a 11:5b9d4d8641ce
       
     1 /*
       
     2  * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description:
       
    15  *
       
    16  * Data Reader Access class
       
    17  *
       
    18  */
       
    19 package com.nokia.traceviewer.engine;
       
    20 
       
    21 import java.util.ArrayList;
       
    22 import java.util.List;
       
    23 
       
    24 import com.nokia.traceviewer.engine.dataprocessor.FilterProcessor;
       
    25 
       
    26 /**
       
    27  * DataReader Access class
       
    28  */
       
    29 public class DataReaderAccess {
       
    30 
       
    31 	/**
       
    32 	 * Main file path
       
    33 	 */
       
    34 	private final String filePath;
       
    35 
       
    36 	/**
       
    37 	 * Callback where dataReaders return data
       
    38 	 */
       
    39 	private final MediaCallback mediaCallback;
       
    40 
       
    41 	/**
       
    42 	 * The Main dataReader which is always reading the binary file
       
    43 	 */
       
    44 	private DataReader mainDataReader;
       
    45 
       
    46 	/**
       
    47 	 * Reference to the current dataReader reading data to view
       
    48 	 */
       
    49 	private DataReader currentDataReader;
       
    50 
       
    51 	/**
       
    52 	 * DataReader which handles scrolling
       
    53 	 */
       
    54 	private DataScrollReader scrollReader;
       
    55 
       
    56 	/**
       
    57 	 * Datareader which reads only the filter file
       
    58 	 */
       
    59 	private DataReader filterDataReader;
       
    60 
       
    61 	/**
       
    62 	 * List of media callbacks which should be informed when file handle is
       
    63 	 * changed
       
    64 	 */
       
    65 	private List<MediaCallback> ownMediaCallbacks;
       
    66 
       
    67 	/**
       
    68 	 * File start offset. Is non-zero when triggering was on.
       
    69 	 */
       
    70 	private long fileStartOffset;
       
    71 
       
    72 	/**
       
    73 	 * Constructor
       
    74 	 * 
       
    75 	 * @param mediaCallback
       
    76 	 *            media callback
       
    77 	 * @param fileName
       
    78 	 *            file name
       
    79 	 */
       
    80 	public DataReaderAccess(MediaCallback mediaCallback, String fileName) {
       
    81 		this.mediaCallback = mediaCallback;
       
    82 		this.filePath = fileName;
       
    83 	}
       
    84 
       
    85 	/**
       
    86 	 * Creates the main DataReader
       
    87 	 */
       
    88 	public void createMainDataReader() {
       
    89 		// Create Main reader
       
    90 		TraceConfiguration conf = new TraceConfiguration();
       
    91 		conf.setScrolledTrace(false);
       
    92 		conf.setFilteredOut(false);
       
    93 		conf.setReadFromFilterFile(false);
       
    94 
       
    95 		if (mainDataReader != null) {
       
    96 			mainDataReader.shutdown();
       
    97 		}
       
    98 		mainDataReader = TraceViewerGlobals.getTraceProvider()
       
    99 				.createDataReader(mediaCallback, conf);
       
   100 
       
   101 		mainDataReader.setFilePath(filePath);
       
   102 		mainDataReader.setFileStartOffset(fileStartOffset);
       
   103 		mainDataReader.start();
       
   104 
       
   105 		// Not filtering
       
   106 		if (!TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   107 				.getFilterProcessor().isFiltering()) {
       
   108 			setCurrentDataReader(mainDataReader);
       
   109 			// Filtering, create filter data reader
       
   110 		} else {
       
   111 			TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   112 					.getFilterProcessor().buildFilterFileWriter();
       
   113 		}
       
   114 
       
   115 		if (scrollReader != null) {
       
   116 			scrollReader.shutdown();
       
   117 			scrollReader = null;
       
   118 		}
       
   119 	}
       
   120 
       
   121 	/**
       
   122 	 * Gets current data reader
       
   123 	 * 
       
   124 	 * @return the current data reader
       
   125 	 */
       
   126 	public DataReader getCurrentDataReader() {
       
   127 		return currentDataReader;
       
   128 	}
       
   129 
       
   130 	/**
       
   131 	 * Sets current data reader
       
   132 	 * 
       
   133 	 * @param reader
       
   134 	 *            new current data reader
       
   135 	 */
       
   136 	public void setCurrentDataReader(DataReader reader) {
       
   137 		currentDataReader = reader;
       
   138 		notifyOwnCallbacks();
       
   139 	}
       
   140 
       
   141 	/**
       
   142 	 * Gets the main data reader
       
   143 	 * 
       
   144 	 * @return main data reader
       
   145 	 */
       
   146 	public DataReader getMainDataReader() {
       
   147 		return mainDataReader;
       
   148 	}
       
   149 
       
   150 	/**
       
   151 	 * Sets the main data reader
       
   152 	 * 
       
   153 	 * @param reader
       
   154 	 *            new main data reader
       
   155 	 */
       
   156 	public void setMainDataReader(DataReader reader) {
       
   157 		if (mainDataReader != null) {
       
   158 			mainDataReader.shutdown();
       
   159 		}
       
   160 		mainDataReader = reader;
       
   161 	}
       
   162 
       
   163 	/**
       
   164 	 * Gets the scroll reader
       
   165 	 * 
       
   166 	 * @return scroll reader
       
   167 	 */
       
   168 	public DataScrollReader getScrollReader() {
       
   169 		return scrollReader;
       
   170 	}
       
   171 
       
   172 	/**
       
   173 	 * Sets the scroll reader
       
   174 	 * 
       
   175 	 * @param scrollReader
       
   176 	 *            new scroll reader
       
   177 	 */
       
   178 	public void setScrollReader(DataScrollReader scrollReader) {
       
   179 		this.scrollReader = scrollReader;
       
   180 	}
       
   181 
       
   182 	/**
       
   183 	 * Deletes current scroll reader
       
   184 	 */
       
   185 	public void deleteScrollReader() {
       
   186 		if (scrollReader != null) {
       
   187 			scrollReader.shutdown();
       
   188 			scrollReader = null;
       
   189 		}
       
   190 	}
       
   191 
       
   192 	/**
       
   193 	 * Deletes current filter reader
       
   194 	 */
       
   195 	public void deleteFilterReader() {
       
   196 		if (filterDataReader != null) {
       
   197 			filterDataReader.shutdown();
       
   198 			filterDataReader = null;
       
   199 		}
       
   200 	}
       
   201 
       
   202 	/**
       
   203 	 * Sets the file start offset
       
   204 	 * 
       
   205 	 * @param offset
       
   206 	 *            file start offset
       
   207 	 */
       
   208 	public void setFileStartOffset(long offset) {
       
   209 		this.fileStartOffset = offset;
       
   210 	}
       
   211 
       
   212 	/**
       
   213 	 * Start scroll reader
       
   214 	 * 
       
   215 	 * @param offset
       
   216 	 *            start offset
       
   217 	 * @param numberOfBlocks
       
   218 	 *            number of blocks
       
   219 	 */
       
   220 	public void startScrollReader(int offset, int numberOfBlocks) {
       
   221 		// Get the file position having given offset
       
   222 		int index = currentDataReader.getFileMap().getIndexFromOffset(offset);
       
   223 		long pos = currentDataReader.getFileMap().getItem(index).longValue();
       
   224 		int startTrace = index * TraceViewerGlobals.blockSize;
       
   225 		boolean scrollReadedExisted = true;
       
   226 
       
   227 		if (scrollReader == null) {
       
   228 			scrollReadedExisted = false;
       
   229 			// Sets this reader to read only blocks
       
   230 			TraceConfiguration conf = new TraceConfiguration();
       
   231 			conf.setScrolledTrace(true);
       
   232 			// Check if filtering
       
   233 			if (TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   234 					.getFilterProcessor().isFiltering()) {
       
   235 				conf.setReadFromFilterFile(true);
       
   236 			}
       
   237 
       
   238 			// Create scroll reader the same type as current data reader is
       
   239 			scrollReader = currentDataReader.createScrollReader(mediaCallback,
       
   240 					conf);
       
   241 		}
       
   242 
       
   243 		scrollReader.setBlockReader(numberOfBlocks, startTrace, true);
       
   244 		scrollReader.setFilePosition(pos);
       
   245 
       
   246 		// Synchronize the threads
       
   247 		synchronized (scrollReader) {
       
   248 			if (!scrollReadedExisted) {
       
   249 				// Start the new thread
       
   250 				scrollReader.start();
       
   251 			} else {
       
   252 				// Wake the thread if it exists
       
   253 				scrollReader.notifyAll();
       
   254 			}
       
   255 			// Put caller thread waiting. Must be careful here because the
       
   256 			// caller thread is usually the UI thread. If syncExec call happens
       
   257 			// during the fetching of the data, UI will be blocked forever!
       
   258 			try {
       
   259 				scrollReader.wait();
       
   260 			} catch (InterruptedException e) {
       
   261 				e.printStackTrace();
       
   262 			}
       
   263 		}
       
   264 	}
       
   265 
       
   266 	/**
       
   267 	 * Creates and starts own data reader. When reader is no longer needed, call
       
   268 	 * shutdown method and set the reader to null.
       
   269 	 * 
       
   270 	 * @param reader
       
   271 	 *            own data reader to start. Should be null when calling this
       
   272 	 *            method for the first time. Then the return value of this
       
   273 	 *            method should be inserted to the reader object in the calling
       
   274 	 *            class
       
   275 	 * @param callback
       
   276 	 *            callback class where to return traces read
       
   277 	 * @param numberOfBlocks
       
   278 	 *            number of blocks to read
       
   279 	 * @param pos
       
   280 	 *            file position to set
       
   281 	 * @param startTrace
       
   282 	 *            trace number where to start reading
       
   283 	 * @param blocking
       
   284 	 *            if true, blocks the calling thread until all the traces are
       
   285 	 *            read. Use with caution. If the amount of traces is big,
       
   286 	 *            program may hang or the stack could get full. Only use
       
   287 	 *            blocking when reading couple of blocks!
       
   288 	 * @return reference to the reader
       
   289 	 */
       
   290 	public DataScrollReader startOwnDataReader(DataScrollReader reader,
       
   291 			MediaCallback callback, int numberOfBlocks, long pos,
       
   292 			int startTrace, boolean blocking) {
       
   293 		boolean dataReadedExisted = true;
       
   294 
       
   295 		// Create new general data reader if it doesn't exist or the callback is
       
   296 		// different
       
   297 		if (reader == null) {
       
   298 			dataReadedExisted = false;
       
   299 			// Sets this reader to read only blocks
       
   300 			TraceConfiguration conf = new TraceConfiguration();
       
   301 			conf.setScrolledTrace(true);
       
   302 			// Check if filtering
       
   303 			if (TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   304 					.getFilterProcessor().isFiltering()) {
       
   305 				conf.setReadFromFilterFile(true);
       
   306 			}
       
   307 
       
   308 			// Create own data reader the same type as current data reader is
       
   309 			reader = currentDataReader.createScrollReader(callback, conf);
       
   310 			addMediaCallbackToList(callback);
       
   311 		}
       
   312 
       
   313 		reader.setBlockReader(numberOfBlocks, startTrace, blocking);
       
   314 		reader.setFilePosition(pos);
       
   315 
       
   316 		// Synchronize the threads
       
   317 		synchronized (reader) {
       
   318 			if (!dataReadedExisted) {
       
   319 				// Start the new thread
       
   320 				reader.start();
       
   321 			} else {
       
   322 				// Wake the thread if it exists
       
   323 				reader.notifyAll();
       
   324 			}
       
   325 			if (blocking) {
       
   326 				// Put caller thread waiting
       
   327 				try {
       
   328 					reader.wait();
       
   329 				} catch (InterruptedException e) {
       
   330 					e.printStackTrace();
       
   331 				}
       
   332 			}
       
   333 		}
       
   334 		return reader;
       
   335 	}
       
   336 
       
   337 	/**
       
   338 	 * Creates filter data reader
       
   339 	 */
       
   340 	public void createFilterDataReader() {
       
   341 		// Configuration for filter file reader
       
   342 		TraceConfiguration conf = new TraceConfiguration();
       
   343 		conf.setScrolledTrace(false);
       
   344 		conf.setReadFromFilterFile(true);
       
   345 
       
   346 		// Shut down possible old one
       
   347 		deleteFilterReader();
       
   348 
       
   349 		// Create binary filter file data reader
       
   350 		if (!TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   351 				.getFilterProcessor().isUsingExternalFilter()
       
   352 				&& !(mainDataReader instanceof PlainTextReader)) {
       
   353 			filterDataReader = TraceViewerGlobals.getTraceProvider()
       
   354 					.createDataReader(mediaCallback, conf);
       
   355 
       
   356 			// Create plain text filter file data reader
       
   357 		} else {
       
   358 			filterDataReader = new PlainTextReader(mediaCallback, conf);
       
   359 		}
       
   360 
       
   361 		filterDataReader.setFilePath(FilterProcessor.DEFAULT_FILTER_FILE_PATH);
       
   362 
       
   363 		// Set as current datareader. Will also notify own callbacks.
       
   364 		setCurrentDataReader(filterDataReader);
       
   365 
       
   366 		// Delete old scrollReader
       
   367 		deleteScrollReader();
       
   368 
       
   369 		// Start the reader
       
   370 		filterDataReader.start();
       
   371 	}
       
   372 
       
   373 	/**
       
   374 	 * Creates log file data reader
       
   375 	 * 
       
   376 	 * @param file
       
   377 	 *            file name
       
   378 	 * @param binary
       
   379 	 *            is the log file binary
       
   380 	 */
       
   381 	public void createLogFileReader(String file, boolean binary) {
       
   382 		// Configuration for log file reader
       
   383 		TraceConfiguration conf = new TraceConfiguration();
       
   384 		conf.setScrolledTrace(false);
       
   385 		conf.setReadFromFilterFile(false);
       
   386 		conf.setFilteredOut(false);
       
   387 
       
   388 		// New main reader
       
   389 		DataReader newReader = null;
       
   390 
       
   391 		// Binary file
       
   392 		if (binary) {
       
   393 			// Create new DataReader
       
   394 			newReader = TraceViewerGlobals.getTraceProvider().createDataReader(
       
   395 					mediaCallback, conf);
       
   396 
       
   397 			// Plain text file
       
   398 		} else {
       
   399 			newReader = new PlainTextReader(mediaCallback, conf);
       
   400 		}
       
   401 		newReader.setFilePath(file);
       
   402 
       
   403 		// Set the new reader to main reader
       
   404 		setMainDataReader(newReader);
       
   405 
       
   406 		// If not filtering, set as currentDataReader
       
   407 		if (!TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   408 				.getFilterProcessor().isFiltering()) {
       
   409 			setCurrentDataReader(newReader);
       
   410 
       
   411 			// If filtering, empty old filter file and create new filter data
       
   412 			// reader
       
   413 		} else {
       
   414 			TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   415 					.getFilterProcessor().buildFilterFileWriter();
       
   416 			createFilterDataReader();
       
   417 		}
       
   418 
       
   419 		TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   420 				.getLogger().setLogFileOpened(true);
       
   421 
       
   422 		// Import possible trace comments first
       
   423 		TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   424 				.getTraceCommentHandler().importTraceComments(file);
       
   425 
       
   426 		// Start the reader
       
   427 		newReader.start();
       
   428 	}
       
   429 
       
   430 	/**
       
   431 	 * Opens log file
       
   432 	 * 
       
   433 	 * @param file
       
   434 	 *            file to be opened
       
   435 	 * @param binary
       
   436 	 *            is this binary file
       
   437 	 */
       
   438 	public void openLogFile(String file, boolean binary) {
       
   439 		// Delete old scrollReader and generalReader
       
   440 		deleteScrollReader();
       
   441 		notifyOwnCallbacks();
       
   442 
       
   443 		// Stop reader if it exists
       
   444 		if (getMainDataReader() != null) {
       
   445 
       
   446 			// If paused, unpause
       
   447 			boolean paused = getMainDataReader().isPaused();
       
   448 			getMainDataReader().shutdown();
       
   449 
       
   450 			if (paused) {
       
   451 				TraceViewerGlobals.getTraceViewer().getView()
       
   452 						.getActionFactory().getPauseAction().run();
       
   453 			}
       
   454 		}
       
   455 
       
   456 		// Clear everything
       
   457 		TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   458 				.getLogger().setLogFileOpened(false);
       
   459 		TraceViewerGlobals.getTraceViewer().clearAllData();
       
   460 
       
   461 		// Disconnect
       
   462 		if (TraceViewerGlobals.getTraceViewer().getConnection() != null
       
   463 				&& TraceViewerGlobals.getTraceViewer().getConnection()
       
   464 						.isConnected()) {
       
   465 			TraceViewerGlobals.getTraceViewer().getView().getActionFactory()
       
   466 					.getConnectAction().run();
       
   467 		}
       
   468 
       
   469 		// Remove possible triggers
       
   470 		TraceViewerGlobals.getTraceViewer().getDataProcessorAccess()
       
   471 				.getTriggerProcessor().removeTriggers();
       
   472 
       
   473 		// Create and start log file reader
       
   474 		createLogFileReader(file, binary);
       
   475 	}
       
   476 
       
   477 	/**
       
   478 	 * Notifies own callbacks that file handle has changed. They should shutdown
       
   479 	 * the reader and set it null.
       
   480 	 */
       
   481 	private void notifyOwnCallbacks() {
       
   482 		if (ownMediaCallbacks != null) {
       
   483 			for (int i = 0; i < ownMediaCallbacks.size(); i++) {
       
   484 				MediaCallback callback = ownMediaCallbacks.get(i);
       
   485 				if (callback != null) {
       
   486 					callback.dataHandleChanged();
       
   487 				}
       
   488 			}
       
   489 			ownMediaCallbacks.clear();
       
   490 		}
       
   491 	}
       
   492 
       
   493 	/**
       
   494 	 * Adds own callback to the list
       
   495 	 * 
       
   496 	 * @param callback
       
   497 	 *            own callback to be added
       
   498 	 */
       
   499 	private void addMediaCallbackToList(MediaCallback callback) {
       
   500 
       
   501 		// Create the array
       
   502 		if (ownMediaCallbacks == null) {
       
   503 			ownMediaCallbacks = new ArrayList<MediaCallback>();
       
   504 		}
       
   505 
       
   506 		// Add to the list
       
   507 		if (!ownMediaCallbacks.contains(callback)) {
       
   508 			ownMediaCallbacks.add(callback);
       
   509 		}
       
   510 	}
       
   511 }