diff -r a151135b0cf9 -r aa2539c91954 tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/model/TraceModel.java --- a/tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/model/TraceModel.java Wed Sep 29 17:45:35 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,997 +0,0 @@ -/* -* Copyright (c) 2008 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: -* -* Trace model is a collection of trace groups -* -*/ -package com.nokia.tracecompiler.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Properties; - -import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals; -import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode; -import com.nokia.tracecompiler.engine.project.SortedProperties; -import com.nokia.tracecompiler.project.FormattingUtils; -import com.nokia.tracecompiler.source.SourceConstants; - -/** - * Trace model is a collection of trace groups. Listener interfaces can be - * attached to a trace model to receive change notifications when traces are - * added, removed or modified. - * - */ -public class TraceModel extends TraceObject implements Iterable { - - /** - * Group property prefix - */ - public final String GROUP_PROPERTY_PREFIX = "[GROUP]"; //$NON-NLS-1$ - - /** - * Trace property prefix - */ - public final String TRACE_PROPERTY_PREFIX = "[TRACE]"; //$NON-NLS-1$ - - /** - * Obsolete property prefix - */ - public final String OBSOLETE_PROPERTY_PREFIX = "[[OBSOLETE]]"; //$NON-NLS-1$ - - /** - * Group Id prefix - */ - public final String GROUP_ID_PREFIX = "["; //$NON-NLS-1$ - - /** - * Group Id suffix - */ - public final String GROUP_ID_SUFFIX = "]"; //$NON-NLS-1$ - - /** - * Factory object for creating other trace objects - */ - private TraceObjectFactory factory; - - /** - * Property verifier interface - */ - private TraceObjectPropertyVerifier verifier; - - /** - * List of trace groups - */ - private ArrayList groups = new ArrayList(); - - /** - * List of traces, sorted by name - */ - private ArrayList tracesByName = new ArrayList(); - - /** - * List of model listeners - */ - private ArrayList modelListeners = new ArrayList(); - - /** - * List of extension listeners - */ - private ArrayList extensionListeners = new ArrayList(); - - /** - * List of reset listeners - */ - private ArrayList resetListeners = new ArrayList(); - - /** - * Processing listeners - */ - private ArrayList processingListeners = new ArrayList(); - - /** - * List of constant tables - */ - private ArrayList constantTables = new ArrayList(); - - /** - * Validity flag - */ - private boolean valid; - - /** - * Number of nested calls to startProcessing - */ - private int isProcessing; - - /** - * Model was changed during processing - */ - private boolean modelChangedDuringProcessing; - - /** - * Fixed Ids from fixed Ids definition file - */ - private SortedProperties fixedIds; - - /** - * Hex radix - */ - public int HEX_RADIX = 16; // CodForChk_Dis_Magic - - /** - * Constructor - * - * @param factory - * the rule factory - * @param verifier - * the property verifier - * @throws TraceCompilerException - */ - public TraceModel(TraceObjectRuleFactory factory, - TraceObjectPropertyVerifier verifier) throws TraceCompilerException { - // Stored for callback purposes - setModel(this); - this.factory = new TraceObjectFactory(this, factory); - this.verifier = verifier; - } - - /** - * Adds a new trace model listener to this model - * - * @param listener - * the new listener - */ - public void addModelListener(TraceModelListener listener) { - modelListeners.add(listener); - } - - /** - * Removes a trace model listener. Does nothing if the listener is not found - * - * @param listener - * the listener to be removed - */ - public void removeModelListener(TraceModelListener listener) { - modelListeners.remove(listener); - } - - /** - * Adds a new trace model extension listener to this model - * - * @param listener - * the new listener - */ - public void addExtensionListener(TraceModelExtensionListener listener) { - extensionListeners.add(listener); - } - - /** - * Removes a trace model extension listener. Does nothing if the listener is - * not found - * - * @param listener - * the listener to be removed - */ - public void removeExtensionListener(TraceModelExtensionListener listener) { - extensionListeners.remove(listener); - } - - /** - * Adds a new trace model reset listener to this model - * - * @param listener - * the new listener - */ - public void addResetListener(TraceModelResetListener listener) { - resetListeners.add(listener); - } - - /** - * Removes a trace model reset listener. Does nothing if the listener is not - * found - * - * @param listener - * the listener to be removed - */ - public void removeResetListener(TraceModelResetListener listener) { - resetListeners.remove(listener); - } - - /** - * Adds a new trace model listener to this model - * - * @param listener - * the new listener - */ - public void addProcessingListener(TraceProcessingListener listener) { - processingListeners.add(listener); - } - - /** - * Removes a processing listener. Does nothing if the listener is not found - * - * @param listener - * the listener to be removed - */ - public void removeProcessingListener(TraceProcessingListener listener) { - processingListeners.remove(listener); - } - - /** - * Returns highest group ID + 1. Can be used to create an unique ID for a - * new trace group. - * - * @return the next trace group ID - * @throws TraceCompilerException - */ - public int getNextGroupID() throws TraceCompilerException { - int currentMaxGroupId = 0; - int nextGroupId = 0; - // Check if there are some fixed Ids - if (fixedIds != null) { - Enumeration keys = this.fixedIds.keys(); - // Go through fixed Ids and check if there are fixed group Ids - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (key.startsWith(GROUP_PROPERTY_PREFIX) - || key.startsWith(OBSOLETE_PROPERTY_PREFIX - + GROUP_PROPERTY_PREFIX)) { - // Fixed group Id found. Try to covert it to int value. - String value = fixedIds.getProperty(key); - int fixedId = 0; - try { - fixedId = Integer.decode(value).intValue(); - } catch (NumberFormatException e) { - // Corrupted. Get next group Id later on. - currentMaxGroupId = 0; - break; - } - // Check if found fixed Id is bigger than current max group - // Id - if (fixedId > currentMaxGroupId) { - currentMaxGroupId = fixedId; - } - } - } - } - - // If there were fixed group Ids. Set next group Id to be current max - // group Id + 1 - if (currentMaxGroupId != 0) { - nextGroupId = currentMaxGroupId + 1; - } - - // Get current max group id in model - int maxGroupIdInModel = 0; - for (TraceGroup group : groups) { - int groupIdInModel = group.getID(); - if (groupIdInModel > maxGroupIdInModel) { - maxGroupIdInModel = groupIdInModel; - } - } - - // If next group Id is zero or smaller than current max group id in - // model + 1. Set it be same as current max group id in model + 1. This - // is done in case that we have added more than one new group after last - // fixed Id update - if (nextGroupId == 0 || nextGroupId < maxGroupIdInModel + 1) { - nextGroupId = maxGroupIdInModel + 1; - } - - // Check that next group Id is not bigger than max group Id - if (nextGroupId > TraceCompilerEngineGlobals.MAX_GROUP_ID) { - throw new TraceCompilerException( - TraceCompilerErrorCode.RUN_OUT_OF_GROUP_IDS); - } - - return nextGroupId; - } - - /** - * Returns highest constant table ID + 1. Can be used to create an unique ID - * for a new constant table. - * - * @return the next constant table ID - */ - public int getNextConstantTableID() { - int max = 0; - for (TraceConstantTable table : constantTables) { - int id = table.getID(); - if (id > max) { - max = id; - } - } - return max + 1; - } - - /** - * Removes a trace group from this model. Create groupRemoved event to model - * listeners - * - * @param group - * the group to be removed - * @throws TraceCompilerException - */ - public void removeGroup(TraceGroup group) throws TraceCompilerException { - if (groups.remove(group)) { - notifyObjectRemoved(this, group); - group.reset(); - } - } - - /** - * Determines if this model contains any trace groups - * - * @return true if there are trace groups - */ - public boolean hasGroups() { - return !groups.isEmpty(); - } - - /** - * Gets the number of trace groups - * - * @return trace group count - */ - public int getGroupCount() { - return groups.size(); - } - - /** - * Returns the trace groups of this model - * - * @return the iterator over the groups - */ - public Iterator getGroups() { - return groups.iterator(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Iterable#iterator() - */ - public Iterator iterator() { - return groups.iterator(); - } - - /** - * Removes all trace groups and parameters from this model. Extensions are - * not removed. Notifies the reset listeners with modelResetting and - * modelReset - * - * @see TraceModelResetListener#modelResetting - * @see TraceModelResetListener#modelReset - */ - @Override - public void reset() { - notifyModelResetting(); - // Properties are removed, other extensions are left - removeExtensions(TraceObjectPropertyList.class); - groups.clear(); - tracesByName.clear(); - constantTables.clear(); - fixedIds = null; - super.reset(); - notifyModelReset(); - } - - /** - * Gets the group which has given ID - * - * @param id - * the id - * @return group or null - */ - public TraceGroup findGroupByID(int id) { - TraceGroup retval = null; - for (TraceGroup group : groups) { - if (group.getID() == id) { - retval = group; - break; - } - } - return retval; - } - - /** - * Locates a trace group which has the given name. - * - * @param name - * the name of the trace group - * @return the group or null if not found - * @see TraceObject#getName - */ - public TraceGroup findGroupByName(String name) { - TraceGroup retval = null; - for (TraceGroup group : groups) { - if (group.getName().equals(name)) { - retval = group; - break; - } - } - return retval; - } - - /** - * Locates a trace which has the given name. - * - * @param name - * the name of the trace - * @return the trace or null if not found - * @see TraceObject#getName - */ - public Trace findTraceByName(String name) { - Trace retval; - int index = Collections.binarySearch(tracesByName, name, - TraceObjectUtils.traceToNameComparator); - if (index >= 0) { - retval = tracesByName.get(index); - } else { - retval = null; - } - return retval; - } - - /** - * Returns the group at given index - * - * @param index - * the group index - * @return the group - */ - public TraceGroup getGroupAt(int index) { - return groups.get(index); - } - - /** - * Removes a constant table from this model. Creates objectRemoved event to - * model listeners - * - * @see TraceModelListener#objectRemoved(TraceObject, TraceObject) - * @param table - * the table to be removed - * @throws TraceCompilerException - */ - public void removeConstantTable(TraceConstantTable table) throws TraceCompilerException { - if (constantTables.remove(table)) { - notifyObjectRemoved(this, table); - table.reset(); - } - } - - /** - * Gets the constant tables of this model - * - * @return the tables iterator - */ - public Iterator getConstantTables() { - return constantTables.iterator(); - } - - /** - * Gets a constant table by ID - * - * @param id - * the ID - * @return the table or null - */ - public TraceConstantTable findConstantTableByID(int id) { - TraceConstantTable retval = null; - for (TraceConstantTable table : constantTables) { - if (table.getID() == id) { - retval = table; - break; - } - } - return retval; - } - - /** - * Gets a constant table by name - * - * @param tableName - * the name - * @return the table or null - */ - public TraceConstantTable findConstantTableByName(String tableName) { - TraceConstantTable retval = null; - for (TraceConstantTable table : constantTables) { - if (table.getName().equals(tableName)) { - retval = table; - break; - } - } - return retval; - } - - /** - * Checks if this model contains constant tables - * - * @return true if there are constant tables - */ - public boolean hasConstantTables() { - return !constantTables.isEmpty(); - } - - /** - * Returns the constant table at given index - * - * @param index - * the group index - * @return the group - */ - public TraceConstantTable getConstantTableAt(int index) { - return constantTables.get(index); - } - - /** - * Adds a new trace group to this model. Creates objectAdded event to model - * listeners. This is only intended to be called from TraceGroup - * constructor, so this is not public. - * - * @see TraceModelListener#objectAdded(TraceObject, TraceObject) - * @param group - * the group to be added - */ - void addGroup(TraceGroup group) { - groups.add(group); - notifyObjectAdded(this, group); - } - - /** - * Adds a constant table to this model. Created objectAdded event to model - * listeners. This is only intended to be called from constant table - * constructor, so this is not public - * - * @see TraceModelListener#objectAdded(TraceObject, TraceObject) - * @param table - * the constant table - */ - void addConstantTable(TraceConstantTable table) { - constantTables.add(table); - notifyObjectAdded(this, table); - } - - /** - * Fires propertiesUpdated event. Called from trace objects when their - * properties change. - * - * @see TraceModelListener#propertyUpdated(TraceObject, int) - * @param source - * the object that changed - * @param property - * the property that changed - * @throws TraceCompilerException - */ - void notifyPropertyUpdated(TraceObject source, int property) throws TraceCompilerException { - if (source instanceof Trace) { - if (property == TraceModelListener.NAME) { - Collections.sort(tracesByName, - TraceObjectUtils.traceObjectNameComparator); - } - ((Trace) source).getGroup().tracePropertyUpdated(source, property); - } - for (TraceModelListener l : modelListeners) { - l.propertyUpdated(source, property); - } - modelChangedDuringProcessing = true; - } - - /** - * Fires objectAdded event to listeners - * - * @see TraceModelListener#objectAdded(TraceObject, TraceObject) - * @param owner - * the owner object - * @param object - * the object that was added - */ - void notifyObjectAdded(TraceObject owner, TraceObject object) { - // List is sorted when the name is set to the trace - if (object instanceof Trace) { - tracesByName.add((Trace) object); - } - for (TraceModelListener l : modelListeners) { - l.objectAdded(owner, object); - } - modelChangedDuringProcessing = true; - } - - /** - * Fires objectRemoved event to listeners - * - * @see TraceModelListener#objectRemoved(TraceObject, TraceObject) - * @param owner - * the owner object - * @param object - * the object that was removed - * @throws TraceCompilerException - */ - void notifyObjectRemoved(TraceObject owner, TraceObject object) throws TraceCompilerException { - if (object instanceof Trace) { - int index = Collections.binarySearch(tracesByName, (Trace) object, - TraceObjectUtils.traceObjectNameComparator); - tracesByName.remove(index); - } - notifyOnDelete(object); - for (TraceModelListener l : modelListeners) { - l.objectRemoved(owner, object); - } - modelChangedDuringProcessing = true; - } - - /** - * Notifies that an object creation is complete - * - * @see TraceModelListener#objectCreationComplete(TraceObject) - * @param object - * the object - * @throws TraceCompilerException - */ - void notifyObjectCreationComplete(TraceObject object) throws TraceCompilerException { - for (TraceModelListener l : modelListeners) { - l.objectCreationComplete(object); - } - } - - /** - * Fires modelResetting event to all listeners - * - * @see TraceModelResetListener#modelResetting() - */ - private void notifyModelResetting() { - for (TraceModelResetListener l : resetListeners) { - l.modelResetting(); - } - } - - /** - * Fires modelReset event to all listeners - * - * @see TraceModelResetListener#modelReset() - */ - private void notifyModelReset() { - for (TraceModelResetListener l : resetListeners) { - l.modelReset(); - } - } - - /** - * Fires extensionAdded event. Called from TraceObject when extension is - * added to it - * - * @see TraceModelExtensionListener#extensionAdded(TraceObject, - * TraceModelExtension) - * @param object - * the trace object - * @param extension - * the new extension - */ - void notifyExtensionAdded(TraceObject object, TraceModelExtension extension) { - for (TraceModelExtensionListener l : extensionListeners) { - l.extensionAdded(object, extension); - } - modelChangedDuringProcessing = true; - } - - /** - * Fires extensionRemoved event. Called from TraceObject when extension is - * removed from it - * - * @see TraceModelExtensionListener#extensionRemoved(TraceObject, - * TraceModelExtension) - * @param object - * the object - * @param extension - * the removed extension - */ - void notifyExtensionRemoved(TraceObject object, - TraceModelExtension extension) { - for (TraceModelExtensionListener l : extensionListeners) { - l.extensionRemoved(object, extension); - } - modelChangedDuringProcessing = true; - } - - /** - * Gets the validity flag of this model - * - * @return the validity flag - */ - public boolean isValid() { - return valid; - } - - /** - * Sets the validity flag - * - * @param valid - * new flag value - * @throws TraceCompilerException - */ - public void setValid(boolean valid) throws TraceCompilerException { - if (valid != this.valid) { - this.valid = valid; - for (TraceModelResetListener l : resetListeners) { - l.modelValid(valid); - } - } - } - - /** - * Gets the trace object factory - * - * @return the factory - */ - public TraceObjectFactory getFactory() { - return factory; - } - - /** - * Gets the object verifier interface. The verifier should be used before - * updating object properties - * - * @return the verifier - */ - public TraceObjectPropertyVerifier getVerifier() { - return verifier; - } - - /** - * Notifies the process listeners that a process the results in multiple - * listener updates is about to start - */ - public void startProcessing() { - isProcessing++; - if (isProcessing == 1) { - modelChangedDuringProcessing = false; - for (TraceProcessingListener l : processingListeners) { - l.processingStarted(); - } - } - } - - /** - * Notifies the process listeners that a process the results in multiple - * listener updates has finished - */ - public void processingComplete() { - isProcessing--; - if (isProcessing == 0) { - for (TraceProcessingListener l : processingListeners) { - l.processingComplete(modelChangedDuringProcessing); - } - modelChangedDuringProcessing = false; - } - } - - /** - * Checks the state of the processing flag - * - * @return the processing flag - */ - public boolean isProcessing() { - return isProcessing > 0; - } - - /** - * Checks if model has traces - * - * @return true if there's traces, false if not - */ - public boolean hasTraces() { - boolean retval = false; - for (TraceGroup group : groups) { - if (group.hasTraces()) { - retval = true; - break; - } - } - return retval; - } - - /** - * Gets group ID from properties - * - * @param properties - * the properties - * @param group - * the group - * @return the group ID - * @throws TraceCompilerException - */ - public int getGroupID(Properties properties, TraceGroup group) - throws TraceCompilerException { - String value = properties.getProperty(GROUP_PROPERTY_PREFIX - + group.getName()); - int id; - if (value == null) { - // Not found, assign a proper ID - id = getNewIdForGroup(group); - - } else { - try { - id = Integer.decode(value).intValue(); - TraceGroup traceGroup = findGroupByID(id); - if (traceGroup != null && !traceGroup.equals(group)) { - // Id already in use, assign a proper ID - id = getNewIdForGroup(group); - } - } catch (NumberFormatException e) { - // Corrupted, assign a proper ID - id = getNewIdForGroup(group); - } - } - group.internalSetID(id); - return id; - } - - /** - * Gets a new ID for this group - * - * @param group - * the group - * @return a new ID for this group - * @throws TraceCompilerException - */ - private int getNewIdForGroup(TraceGroup group) throws TraceCompilerException { - int id = FormattingUtils.getGroupID(group.getModel(), group.getName()); - return id; - } - - /** - * Saves trace and group identifiers to given properties. - * - * @param properties - * the properties to use - */ - public void saveIDs(Properties properties) { - properties.clear(); - StringBuffer sb = new StringBuffer(); - for (TraceGroup group : this) { - int groupId = group.getID(); - properties.setProperty(GROUP_PROPERTY_PREFIX + group.getName(), - SourceConstants.HEX_PREFIX + Integer.toHexString(groupId)); - for (Trace trace : group) { - int traceId = trace.getID(); - properties.setProperty(TRACE_PROPERTY_PREFIX - + createTraceName(sb, group, trace), - SourceConstants.HEX_PREFIX - + Integer.toHexString(traceId)); - } - } - } - - /** - * Merges the group and trace names together - * - * @param sb - * the buffer where name is stored - * @param group - * group - * @param trace - * trace - * @return the trace name - */ - public String createTraceName(StringBuffer sb, TraceGroup group, Trace trace) { - sb.setLength(0); - sb.append(group.getName()); - sb.append(GROUP_ID_PREFIX); - int groupId = group.getID(); - String groupIdString = SourceConstants.HEX_PREFIX - + Integer.toString(groupId, HEX_RADIX).toUpperCase(); - sb.append(groupIdString); - sb.append(GROUP_ID_SUFFIX); - sb.append(SourceConstants.UNDERSCORE); - sb.append(trace.getName()); - return sb.toString(); - } - - /** - * Gets fixed group and trace ids - * - * @return fixed Ids - */ - public SortedProperties getFixedIds() { - return fixedIds; - } - - /** - * Set fixed group and trace ids - * - * @param fixedIds - * fixed Ids - */ - public void setFixedIds(SortedProperties fixedIds) { - this.fixedIds = fixedIds; - } - - /** - * Gets next trace ID - * - * @param group - * the group - * @return the trace ID - * @throws TraceCompilerException - */ - public int getNextTraceId(TraceGroup group) throws TraceCompilerException { - int currentMaxTraceID = 0; - int nextTraceId = 0; - // Check if there are some fixed Ids - if (fixedIds != null) { - Enumeration keys = this.fixedIds.keys(); - String groupName = group.getName(); - int groupId = group.getID(); - String groupIdString = SourceConstants.HEX_PREFIX - + Integer.toString(groupId, HEX_RADIX).toUpperCase(); - // Go through fixed Ids and check if there are fixed trace Ids to - // this group - while (keys.hasMoreElements()) { - String key = (String) keys.nextElement(); - if (key.startsWith(TRACE_PROPERTY_PREFIX + groupName - + GROUP_ID_PREFIX + groupIdString + GROUP_ID_SUFFIX - + SourceConstants.UNDERSCORE) - || key.startsWith(OBSOLETE_PROPERTY_PREFIX - + TRACE_PROPERTY_PREFIX + groupName - + GROUP_ID_PREFIX + groupIdString - + GROUP_ID_SUFFIX + SourceConstants.UNDERSCORE)) { - // Fixed trace Id to in this group found. Try to covert it - // to int value. - String value = fixedIds.getProperty(key); - int fixedId = 0; - try { - fixedId = Integer.decode(value).intValue(); - } catch (NumberFormatException e) { - // Corrupted. Get next trace Id later on. - nextTraceId = 0; - break; - } - // Check if found fixed Id is bigger than current max trace - // Id in this group - if (fixedId > currentMaxTraceID) { - currentMaxTraceID = fixedId; - } - } - } - // If there were fixed trace Ids to this group. Set next trace Id to - // be current max trace Id + 1 - if (currentMaxTraceID != 0) { - nextTraceId = currentMaxTraceID + 1; - } - // If next trace Id is zero or smaller than trace Id that group - // suggest. Set it be same as group suggest. This is done in case - // that we have added more than one new trace to same group after - // last fixed Id update - if (nextTraceId == 0 || nextTraceId < group.getNextTraceID()) { - nextTraceId = group.getNextTraceID(); - } - } else { - // No fixed Ids. Get next trace Id from group - nextTraceId = group.getNextTraceID(); - } - // Check that next trace Id is not bigger than max trace Id - if (nextTraceId > TraceCompilerEngineGlobals.MAX_TRACE_ID) { - throw new TraceCompilerException( - TraceCompilerErrorCode.RUN_OUT_OF_TRACE_IDS); - } - - return nextTraceId; - } - -}