tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/TraceLocationConverter.java
changeset 56 aa2539c91954
parent 54 a151135b0cf9
child 60 e54443a6878c
child 62 1c2bb2fc7c87
--- a/tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/TraceLocationConverter.java	Wed Sep 29 17:45:35 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,679 +0,0 @@
-/*
- * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). 
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description:
- *
- * Location converter monitors locations and converts them to traces if necessary.
- *
- */
-package com.nokia.tracecompiler.engine;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-
-import com.nokia.tracecompiler.TraceCompilerConstants;
-import com.nokia.tracecompiler.TraceCompilerLogger;
-import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
-import com.nokia.tracecompiler.engine.project.ProjectConstants;
-import com.nokia.tracecompiler.engine.project.ProjectEngine;
-import com.nokia.tracecompiler.engine.project.SortedProperties;
-import com.nokia.tracecompiler.engine.project.TraceIDCache;
-import com.nokia.tracecompiler.engine.rules.PerformanceEventRuleBase;
-import com.nokia.tracecompiler.engine.rules.StateTraceRule;
-import com.nokia.tracecompiler.engine.source.SourceParserRule;
-import com.nokia.tracecompiler.engine.source.SourceProperties;
-import com.nokia.tracecompiler.engine.source.SourceParserRule.ParameterConversionResult;
-import com.nokia.tracecompiler.engine.source.SourceParserRule.TraceConversionResult;
-import com.nokia.tracecompiler.model.Trace;
-import com.nokia.tracecompiler.model.TraceCompilerException;
-import com.nokia.tracecompiler.model.TraceGroup;
-import com.nokia.tracecompiler.model.TraceModel;
-import com.nokia.tracecompiler.model.TraceModelExtension;
-import com.nokia.tracecompiler.model.TraceModelPersistentExtension;
-import com.nokia.tracecompiler.model.TraceParameter;
-import com.nokia.tracecompiler.project.FormattingUtils;
-import com.nokia.tracecompiler.project.GroupNames;
-import com.nokia.tracecompiler.project.ProjectUtils;
-import com.nokia.tracecompiler.source.SourceConstants;
-
-/**
- * Location converter monitors locations and converts them to traces if
- * necessary.
- * 
- */
-public final class TraceLocationConverter {
-
-	/**
-	 * Number of deprecated groups
-	 */
-	final static int NUMBER_OF_DEPRECATED_GROUPS = 3;
-
-	/**
-	 * Deprecated group name map
-	 */
-	Map<String, String> deprecatedGroupNameMap = new HashMap<String, String>(
-			NUMBER_OF_DEPRECATED_GROUPS);
-
-	/**
-	 * Trace model
-	 */
-	private TraceModel model;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param model
-	 *            the trace model
-	 */
-	TraceLocationConverter(TraceModel model) {
-		this.model = model;
-		initializeDeprecatedGroupNameMap();
-	}
-
-	/**
-	 * Initialize deprecated group name map
-	 */
-	private void initializeDeprecatedGroupNameMap() {
-		deprecatedGroupNameMap.put(GroupNames.TRACE_API,
-				GroupNames.TRACE_BORDER);
-		deprecatedGroupNameMap.put(GroupNames.TRACE_DEBUG,
-				GroupNames.TRACE_DUMP);
-		deprecatedGroupNameMap.put(GroupNames.TRACE_DETAILED,
-				GroupNames.TRACE_INTERNALS);
-	}
-
-	/**
-	 * Source opened notification
-	 * 
-	 * @param properties
-	 *            the source properties
-	 * @throws TraceCompilerException 
-	 */
-	void sourceOpened(SourceProperties properties) throws TraceCompilerException {
-		//make sure all errors are reported AFTER processing a file
-		TraceCompilerEngineGlobals.getSourceContextManager()
-				.setConverting(true);
-		model.startProcessing();
-		try {
-			// Load fixed group and trace ids from definition file to model
-			//no errors are reported here 
-			if (model.getFixedIds() == null) {
-				loadFixedIdsFromDefinitionFileToModel();
-			}
-
-			for (TraceLocation loc : properties) {
-				autoConvertLocation(loc);
-			}
-			// If there are duplicates or unused traces, they are removed
-			// Note that this will work across source files although this
-			// function is processing only one file.
-			// If a trace is created, all locations from all open source files
-			// are linked to that trace and thus it will be removed as
-			// duplicate.
-			removeDuplicateTraces();
-
-		} finally {
-			model.processingComplete();
-			SourceContextManager manager = TraceCompilerEngineGlobals
-					.getSourceContextManager();
-			manager.setConverting(false);
-			manager.setContext(null);
-		}
-	}
-
-	/**
-	 * Load fixed Ids from definiton file to properties
-	 * 
-	 */
-	private void loadFixedIdsFromDefinitionFileToModel() {
-		TraceIDCache cache = model.getExtension(TraceIDCache.class);
-
-		// Create trace Id cache if it does not exist
-		try {
-			if (cache == null) {
-				String path;
-				path = ProjectUtils.getLocationForFile(model,
-						ProjectEngine.traceFolderName,
-						ProjectConstants.FIXED_ID_DEFINITIONS_FILE_NAME, false);
-				if (path != null) {
-					cache = new TraceIDCache(new File(path).getParent());
-					model.addExtension(cache);
-				}
-			}
-			if (cache != null) {
-				File cacheFile = new File(cache.getAbsolutePath());
-				// Try to load Ids from trace Id cache file
-				try {
-					SortedProperties fixedIds = new SortedProperties();
-					if (cacheFile.exists()) {
-						String thisLine;
-						boolean allOldFixedIdsAreValid = true;
-						String group = model.GROUP_PROPERTY_PREFIX;
-						FileInputStream fis = new FileInputStream(cacheFile);
-						BufferedReader myInput = new BufferedReader(
-								new InputStreamReader(fis));
-						// Read the old fixed id definition file
-						while ((thisLine = myInput.readLine()) != null) {
-							if (thisLine.indexOf(group) != -1) {
-								thisLine = thisLine.substring(group.length(),
-										thisLine.length());
-								if (!searchForOldGroupIds(thisLine)) {						
-									String msg  = Messages.getString("TraceLocationConverter.GroupIdValueError"); //$NON-NLS-1$
-									TraceCompilerEngineGlobals.getEvents().postWarningMessage(msg, null);
-									// We need only one old invalid id to make all of them invalid
-									allOldFixedIdsAreValid = false;
-									break;
-								}
-							}
-						}
-						fis.close();
-						
-						if (allOldFixedIdsAreValid) {
-							// Create file input stream again
-							FileInputStream newFis = new FileInputStream(cacheFile);
-							fixedIds.load(newFis);
-							// Load fixed Ids from properties to model
-							model.setFixedIds(fixedIds);
-							newFis.close();
-						}
-						
-					}
-				} catch (IOException e) {
-					// If there is a problem with the cache file, just delete it
-					// make sure the model fixed ids is null
-					model.setFixedIds(null);
-					cacheFile.delete();
-					// We do not raise an exception but we need to report a info
-					TraceCompilerLogger.printWarning(Messages.getString("TraceLocationConverter.FixedIdProblemWarningBeginText") + cacheFile.toString() + Messages.getString("TraceLocationConverter.FixedIdProblemWarningMiddleText") + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
-				}
-			}
-		} catch (TraceCompilerException e) {
-			// This exception can probably be ignored
-			TraceCompilerLogger.printWarning("Could not create ID cache : " + e.getMessage()); //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Searches the fixed_id file to see if there are any old definitions
-	 * 
-	 * @param string
-	 *            of text from the fixed_id files
-	 * @return boolean 
-	 */
-	public static boolean searchForOldGroupIds(String str) {
-		
-		boolean oldGroupIdValid = true;
-
-		//get group name from the string
-		int index = str.indexOf(SourceConstants.ASSIGN_WITH_OUT_SPACES);
-		if (index == -1) {
-			//not valid string, so ignore it, just return success
-			return true;
-		}
-
-		String groupName = str.substring(0, index);
-
-		//get group id
-		str = str.substring(str.indexOf(SourceConstants.HEX_PREFIX) + 2, str
-				.length());
-
-		int groupId = -1;
-
-		try {
-			groupId = Integer.parseInt(str.trim(),
-					TraceCompilerConstants.HEX_RADIX);
-		} catch (NumberFormatException e) {
-			//it's not an hex number so fail
-			oldGroupIdValid = false;
-		}
-
-		//get group id from ost header file
-		int fileGroupId = GroupNames.getIdByName(groupName);
-
-		if (fileGroupId != 0) {
-			//found 1
-			if (fileGroupId != groupId) //group id has changed, so old one can't be used
-				oldGroupIdValid = false;
-		} else {
-			if ((GroupNames.USER_GROUP_ID_FIRST > groupId)
-					|| (groupId > GroupNames.USER_GROUP_ID_LAST)) //not within new user defined Ids
-				oldGroupIdValid = false;
-		}
-
-		return oldGroupIdValid;
-	}
-
-	/**
-	 * Converts the given location to trace if parser supports auto-conversion
-	 * 
-	 * @param location
-	 *            the location
-	 */
-	private void autoConvertLocation(TraceLocation location) {
-		// Stores the context of the location to the context manager.
-		TraceCompilerEngineGlobals.getSourceContextManager().setContext(
-				location.getParser().getContext(location.getOffset()));
-		Trace trace = location.getTrace();
-		if (trace == null) {
-			// If the trace does not exist, the parser determines if the
-			// location can be converted
-			if (location.getParserRule().getLocationParser()
-					.isLocationConverted(location)) {
-				try {
-					convertLocation(location, null, true);
-				} catch (TraceCompilerException e) {
-					// If converter fails, the error code is stored into the
-					// location. The location notifies all validity listeners
-					// about the change
-					location.setConverterErrorCode((TraceCompilerErrorCode) e
-							.getErrorCode(), e.getErrorParameters());
-				}
-			}
-		} else {
-			// If the trace already exists in the model, it is updated
-			// based on the source file contents
-			updateLocation(location);
-		}
-	}
-
-	/**
-	 * Recreates the trace from changed location when source is saved
-	 * 
-	 * @param location
-	 *            the location to be checked
-	 */
-	private void updateLocation(TraceLocation location) {
-		// Parser determines if the location can be converted
-		if (location.getParserRule().getLocationParser().isLocationConverted(
-				location)) {
-			try {
-				Trace trace = location.getTrace();
-				// If a location has changed, the old trace is removed
-				// and a new one created. Persistent extensions are moved to the
-				// new trace
-				Iterator<TraceModelPersistentExtension> extensions = null;
-				if (trace != null) {
-					extensions = trace
-							.getExtensions(TraceModelPersistentExtension.class);
-					trace.getGroup().removeTrace(trace);
-				}
-				convertLocation(location, extensions, true);
-
-				// Check that the location is inside a function. Otherwise throw
-				// an error because the code is unreachable
-				if (location.getFunctionName() == null) {
-					throw new TraceCompilerException(
-							TraceCompilerErrorCode.UNREACHABLE_TRACE_LOCATION);
-				}
-
-			} catch (TraceCompilerException e) {
-				// If converter fails, the error code is stored into the
-				// location. The location notifies all validity listeners about
-				// the change
-				location.setConverterErrorCode((TraceCompilerErrorCode) e
-						.getErrorCode(), e.getErrorParameters());
-			}
-		}
-	}
-
-	/**
-	 * Removes all duplicate traces from the model
-	 * @throws TraceCompilerException 
-	 */
-	private void removeDuplicateTraces() throws TraceCompilerException {
-		boolean groupRemoved = true;
-		while (groupRemoved) {
-			groupRemoved = false;
-			for (TraceGroup group : model) {
-				removeDuplicateTracesFromGroup(group);
-				if (!group.hasTraces()) {
-					model.removeGroup(group);
-					groupRemoved = true;
-					break;
-				}
-			}
-		}
-	}
-
-	/**
-	 * Removes duplicate traces from a trace group
-	 * 
-	 * @param group
-	 *            the group
-	 * @throws TraceCompilerException 
-	 */
-	private void removeDuplicateTracesFromGroup(TraceGroup group) throws TraceCompilerException {
-		boolean traceRemoved = true;
-		while (traceRemoved) {
-			traceRemoved = false;
-			for (Trace trace : group) {
-				TraceLocationList list = trace
-						.getExtension(TraceLocationList.class);
-				if (list != null) {
-					if (list.getLocationCount() > 1) {
-						// All the locations are marked as duplicates and the
-						// trace is deleted
-						TraceCompilerErrorCode code = TraceCompilerErrorCode.TRACE_HAS_MULTIPLE_LOCATIONS;
-						for (LocationProperties loc : list) {
-							((TraceLocation) loc).setConverterErrorCode(code,
-									null);
-						}
-						group.removeTrace(trace);
-						traceRemoved = true;
-						break;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Converts a location to a Trace object.
-	 * 
-	 * @param location
-	 *            the location to be converted
-	 * @param extensions
-	 *            persistent extensions to be added to the new trace
-	 * @param autoConvert
-	 *            true if converting without user interaction
-	 * @return the new trace
-	 * @throws TraceCompilerException
-	 *             if conversion fails
-	 */
-	private Trace convertLocation(TraceLocation location,
-			Iterator<TraceModelPersistentExtension> extensions,
-			boolean autoConvert) throws TraceCompilerException {
-		Trace trace = null;
-		// If the parser has failed, the validity code is not OK and the
-		// location cannot be converted. Traces marked with no-trace error code
-		// have not yet been converted, so that is OK. Traces that have
-		// duplicate ID's error code can be parsed, since the duplicates might
-		// no longer exist.
-		if (!autoConvert
-				|| location.getValidityCode() == TraceCompilerErrorCode.OK
-				|| location.getValidityCode() == TraceCompilerErrorCode.TRACE_DOES_NOT_EXIST
-				|| location.getValidityCode() == TraceCompilerErrorCode.TRACE_HAS_MULTIPLE_LOCATIONS) {
-			// The parser does the actual conversion
-			SourceParserRule rule = location.getParserRule();
-			TraceConversionResult result = rule.getLocationParser()
-					.convertLocation(location);
-			// After parser has finished, the trace is created.
-			trace = convertWithoutUI(result, extensions);
-
-			if (trace != null) {
-				model.startProcessing();
-				try {
-					createParametersFromConversionResult(location, result,
-							trace);
-					// Runs a location validity check and notifies listeners
-					// that location is now OK
-					location.setConverterErrorCode(TraceCompilerErrorCode.OK,
-							null);
-				} catch (TraceCompilerException e) {
-					// If parameters cannot be created, the trace is removed
-					TraceGroup group = trace.getGroup();
-					trace.getGroup().removeTrace(trace);
-					if (!group.hasTraces()) {
-						group.getModel().removeGroup(group);
-					}
-					throw e;
-				} finally {
-					model.processingComplete();
-				}
-			}
-		}
-		return trace;
-	}
-
-	/**
-	 * Converts a location to trace without UI
-	 * 
-	 * @param result
-	 *            the conversion result from parser
-	 * @param extensions
-	 *            persistent extensions to be added to the new trace
-	 * @return the converted trace
-	 * @throws TraceCompilerException
-	 *             if location properties are not valid
-	 */
-	private Trace convertWithoutUI(TraceConversionResult result,
-			Iterator<TraceModelPersistentExtension> extensions)
-			throws TraceCompilerException {
-		Trace trace = null;
-		if (result.group != null) {
-			String groupName = result.group;
-			TraceGroup group = handleGroup(groupName);
-			trace = handleTrace(result, extensions, group);
-		} else {
-			throw new TraceCompilerException(
-					TraceCompilerErrorCode.GROUP_NOT_SELECTED);
-		}
-		return trace;
-	}
-
-	/**
-	 * Handle trace
-	 * 
-	 * @param result
-	 *            the conversion result from parser
-	 * @param extensions
-	 *            persistent extensions to be added to the new trace
-	 * @param group
-	 *            the group where trace belongs to
-	 * @return the trace
-	 * @throws TraceCompilerException
-	 */
-	private Trace handleTrace(TraceConversionResult result,
-			Iterator<TraceModelPersistentExtension> extensions, TraceGroup group)
-			throws TraceCompilerException {
-		// First try to find Id to trace from fixed Ids
-		Trace trace = null;
-		Properties fixedIds = model.getFixedIds();
-		String groupName = result.group;
-		String traceName = result.name;
-		int groupId = group.getID();
-		String groupIdString = SourceConstants.HEX_PREFIX
-				+ Integer.toString(groupId, model.HEX_RADIX).toUpperCase();
-		int traceId = 0;
-		if (fixedIds != null) {
-			String tracePropertyName = groupName + model.GROUP_ID_PREFIX
-					+ groupIdString + model.GROUP_ID_SUFFIX
-					+ SourceConstants.UNDERSCORE + traceName;
-			String value = fixedIds.getProperty(model.TRACE_PROPERTY_PREFIX
-					+ tracePropertyName);
-			if (value != null) {
-				try {
-					traceId = Integer.decode(value).intValue();
-				} catch (NumberFormatException e) {
-					// Corrupted, assign a proper Id later on
-					traceId = 0;
-				}
-			}
-		}
-		// If there was no fixed Id to this trace, get Id from model
-		if (traceId == 0) {
-			traceId = model.getNextTraceId(group);
-		}
-
-		String text = result.text;
-		model.getVerifier().checkTraceProperties(group, null, traceId,
-				traceName, text);
-		TraceModelExtension[] extArray = createExtensionArray(result,
-				extensions);
-		trace = model.getFactory().createTrace(group, traceId, traceName, text,
-				extArray);
-
-		if ((trace.getExtension(StateTraceRule.class) == null)
-				&& (group.getName()
-						.equals("TRACE_STATE"))) { //$NON-NLS-1$
-			throw new TraceCompilerException(
-					TraceCompilerErrorCode.INVALID_USAGE_OF_TRACE_STATE_GROUP_NAME);
-		} else if ((trace.getExtension(PerformanceEventRuleBase.class) == null)
-				&& (group.getName()
-						.equals("TRACE_PERFORMANCE"))) { //$NON-NLS-1$
-			throw new TraceCompilerException(
-					TraceCompilerErrorCode.INVALID_USAGE_OF_TRACE_PERFORMACE_GROUP_NAME);
-		}
-
-		return trace;
-	}
-
-	/**
-	 * Handle group. Try to fnd group from model. If it does not exist then
-	 * create new group.
-	 * 
-	 * @param groupName
-	 *            the name of the group
-	 * @return the handled group
-	 * @throws TraceCompilerException
-	 */
-	private TraceGroup handleGroup(String groupName)
-			throws TraceCompilerException {
-		String deprecatedGroupName = null;
-		
-		// Convert deprecated group name to valid group name if needed
-		if (deprecatedGroupNameMap.containsKey(groupName)) {
-			deprecatedGroupName = groupName;
-			groupName = deprecatedGroupNameMap.get(groupName);
-		}
-
-		// If auto-convert flag is set, the location is converted without
-		// user interaction. A new trace group is created if not found
-		TraceGroup group = model.findGroupByName(groupName);
-		if (group == null) {
-			
-			// Print warning related to deprecated group name change if needed
-			if (deprecatedGroupName != null) {
-				String message = Messages
-						.getString("TraceLocationConverter.DeprecatedGroupIdWarningStart");//$NON-NLS-1$
-				message += SourceConstants.SPACE + deprecatedGroupName
-						+ SourceConstants.SPACE;
-				message += Messages
-						.getString("TraceLocationConverter.DeprecatedGroupIdWarningMiddle");//$NON-NLS-1$
-				message += SourceConstants.SPACE + groupName
-						+ SourceConstants.SPACE;
-				message += Messages
-						.getString("TraceLocationConverter.DeprecatedGroupIdWarningEnd");//$NON-NLS-1$
-				TraceCompilerLogger.printWarning(message);
-			}
-
-			int groupId = 0;
-			Properties fixedIds = model.getFixedIds();
-
-			// First try to find Id to group from fixed Ids
-			if (fixedIds != null) {
-				String value = fixedIds.getProperty(model.GROUP_PROPERTY_PREFIX
-						+ groupName);
-				if (value != null) {
-					try {
-						groupId = Integer.decode(value).intValue();
-					} catch (NumberFormatException e) {
-						// Corrupted, assign a proper Id later on
-						groupId = 0;
-					}
-				}
-			}
-			// If there was no fixed Id to this group, get Id from model
-			if (groupId == 0) {
-				groupId = FormattingUtils.getGroupID(model, groupName);
-			}
-			model.getVerifier().checkTraceGroupProperties(model, null, groupId,
-					groupName);
-			group = model.getFactory().createTraceGroup(groupId, groupName,
-					null);
-		}
-
-		return group;
-	}
-
-	/**
-	 * Combines extensions into one array
-	 * 
-	 * @param result
-	 *            the conversion result
-	 * @param extensions
-	 *            the persistent extensions from old trace
-	 * @return the combined array of extensions
-	 */
-	private TraceModelExtension[] createExtensionArray(
-			TraceConversionResult result,
-			Iterator<TraceModelPersistentExtension> extensions) {
-		TraceModelExtension[] extArray = null;
-		ArrayList<TraceModelExtension> ext = null;
-		if (result.extensions != null) {
-			ext = new ArrayList<TraceModelExtension>();
-			ext.addAll(result.extensions);
-		}
-		if (extensions != null) {
-			if (ext == null) {
-				ext = new ArrayList<TraceModelExtension>();
-			}
-			while (extensions.hasNext()) {
-				ext.add(extensions.next());
-			}
-		}
-		if (ext != null) {
-			extArray = new TraceModelExtension[ext.size()];
-			ext.toArray(extArray);
-		}
-		return extArray;
-	}
-
-	/**
-	 * Creates the trace parameters based on trace conversion result
-	 * 
-	 * @param converted
-	 *            the location that was converted
-	 * @param result
-	 *            the conversion result
-	 * @param trace
-	 *            the trace
-	 * @throws TraceCompilerException
-	 *             if parameters cannot be created
-	 */
-	private void createParametersFromConversionResult(TraceLocation converted,
-			TraceConversionResult result, Trace trace)
-			throws TraceCompilerException {
-		if (result.parameters != null) {
-			for (int i = 0; i < result.parameters.size(); i++) {
-				int id = trace.getNextParameterID();
-				ParameterConversionResult res = result.parameters.get(i);
-				boolean warning = false;
-				if (res.type == null) {
-					warning = true;
-					res.type = TraceParameter.HEX32;
-				}
-				model.getVerifier().checkTraceParameterProperties(trace, null,
-						id, res.name, res.type);
-				TraceModelExtension[] extArray = null;
-				if (res.extensions != null) {
-					extArray = new TraceModelExtension[res.extensions.size()];
-					res.extensions.toArray(extArray);
-				}
-				TraceParameter param = model.getFactory().createTraceParameter(
-						trace, id, res.name, res.type, extArray);
-				if (warning) {
-					String msg = Messages
-							.getString("TraceCompiler.UnknownTypeWarning"); //$NON-NLS-1$
-					TraceCompilerEngineGlobals.getEvents().postWarningMessage(
-							msg, param);
-				}
-			}
-		}
-	}
-
-}