--- 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);
- }
- }
- }
- }
-
-}