trace/tracebuilder/com.nokia.tracebuilder/src/com/nokia/tracebuilder/engine/propertydialog/RunInstrumenterCallback.java
changeset 10 ed1c9f64298a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trace/tracebuilder/com.nokia.tracebuilder/src/com/nokia/tracebuilder/engine/propertydialog/RunInstrumenterCallback.java	Wed Jun 23 14:35:40 2010 +0300
@@ -0,0 +1,333 @@
+/*
+* 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:
+*
+* Dialog callback to process instrumentation
+*
+*/
+package com.nokia.tracebuilder.engine.propertydialog;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.nokia.tracebuilder.engine.CheckListDialogEntry;
+import com.nokia.tracebuilder.engine.SourceContextManager;
+import com.nokia.tracebuilder.engine.TraceBuilderDialogs;
+import com.nokia.tracebuilder.engine.TraceBuilderGlobals;
+import com.nokia.tracebuilder.engine.TraceObjectPropertyDialog;
+import com.nokia.tracebuilder.engine.TraceObjectPropertyDialogTemplate;
+import com.nokia.tracebuilder.engine.TraceBuilderDialogs.CheckListDialogParameters;
+import com.nokia.tracebuilder.engine.TraceBuilderDialogs.CheckListDialogType;
+import com.nokia.tracebuilder.engine.TraceBuilderErrorCodes.StringErrorParameters;
+import com.nokia.tracebuilder.engine.TraceBuilderErrorCodes.TraceBuilderErrorCode;
+import com.nokia.tracebuilder.engine.source.SourceEngine;
+import com.nokia.tracebuilder.engine.source.SourceProperties;
+import com.nokia.tracebuilder.engine.utils.TraceUtils;
+import com.nokia.tracebuilder.model.Trace;
+import com.nokia.tracebuilder.model.TraceBuilderException;
+import com.nokia.tracebuilder.model.TraceGroup;
+import com.nokia.tracebuilder.model.TraceModel;
+import com.nokia.tracebuilder.model.TraceModelExtension;
+import com.nokia.tracebuilder.model.TraceObjectModifier;
+import com.nokia.tracebuilder.model.TraceObjectUtils;
+import com.nokia.tracebuilder.project.FormattingUtils;
+import com.nokia.tracebuilder.source.SourceContext;
+import com.nokia.tracebuilder.source.SourceParser;
+
+/**
+ * Dialog callback to process instrumentation
+ * 
+ */
+public final class RunInstrumenterCallback extends PropertyDialogCallback {
+
+	/**
+	 * Duplicate name changed warning
+	 */
+	private static final String DUPLICATE_NAME_CHANGED = Messages
+			.getString("RunInstrumenterCallback.DuplicateName"); //$NON-NLS-1$
+
+	/**
+	 * Source engine for trace additions
+	 */
+	private SourceEngine sourceEngine;
+
+	/**
+	 * Context manager
+	 */
+	private SourceContextManager contextManager;
+
+	/**
+	 * Instrumenter ID
+	 */
+	private String instrumenterID;
+
+	/**
+	 * Creates a new instrumenter callback
+	 * 
+	 * @param model
+	 *            the trace model
+	 * @param sourceEngine
+	 *            the source engine
+	 * @param contextManager
+	 *            the source context manager
+	 * @param instrumenterID
+	 *            the instrumenter ID
+	 */
+	public RunInstrumenterCallback(TraceModel model, SourceEngine sourceEngine,
+			SourceContextManager contextManager, String instrumenterID) {
+		super(model);
+		this.sourceEngine = sourceEngine;
+		this.contextManager = contextManager;
+		this.instrumenterID = instrumenterID;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.tracebuilder.engine.PropertyDialogManagerCallback#
+	 *      okSelected(com.nokia.tracebuilder.engine.TraceObjectPropertyDialog)
+	 */
+	public void okSelected(TraceObjectPropertyDialog dialog)
+			throws TraceBuilderException {
+		String groupName = dialog.getTarget();
+		// If group does not exist, it will be created
+		TraceGroup group = model.findGroupByName(groupName);
+		int groupId = 0;
+		if (group == null) {
+			groupId = FormattingUtils.getGroupID(model, groupName);
+			model.getVerifier().checkTraceGroupProperties(model, null, groupId,
+					groupName);
+		}
+		Iterator<SourceContext> contexts = showFunctionQueryDialog(dialog);
+		if (contexts != null) {
+			String oldCategory = TraceBuilderGlobals.getEvents()
+					.setEventCategory("Instrumenter"); //$NON-NLS-1$
+			contextManager.setInstrumenterID(instrumenterID);
+			model.startProcessing();
+			try {
+				// Group is created if it does not exist
+				if (group == null && contexts.hasNext()) {
+					group = model.getFactory().createTraceGroup(groupId,
+							groupName, null);
+				}
+				while (contexts.hasNext()) {
+					SourceContext context = contexts.next();
+					contextManager.setContext(context);
+					processContext(dialog, group, context);
+				}
+			} finally {
+				model.processingComplete();
+				// These must be reset even if errors occurs
+				contextManager.setContext(null);
+				contextManager.setInstrumenterID(""); //$NON-NLS-1$
+				TraceBuilderGlobals.getEvents().setEventCategory(oldCategory);
+			}
+		}
+	}
+
+	/**
+	 * Shows the function tree view, which can be used to select the functions
+	 * to be instrumented
+	 * 
+	 * @param dialog
+	 *            the property dialog
+	 * @return the iterator of functions to be instrumented
+	 * @throws TraceBuilderException
+	 *             if instrumenter fails
+	 */
+	private Iterator<SourceContext> showFunctionQueryDialog(
+			TraceObjectPropertyDialog dialog) throws TraceBuilderException {
+		Iterator<SourceContext> retval = null;
+		CheckListDialogEntry root = createFunctionQueryDialogTree(dialog);
+		if (root.hasChildren()) {
+			ArrayList<CheckListDialogEntry> rootItems = new ArrayList<CheckListDialogEntry>();
+			rootItems.add(root);
+			CheckListDialogParameters params = new CheckListDialogParameters();
+			params.dialogType = CheckListDialogType.INSTRUMENT_FILES;
+			params.rootItems = rootItems;
+			params.expandLevel = 1;
+			params.showRoot = false;
+			int res = TraceBuilderGlobals.getDialogs().showCheckList(params);
+			if (res == TraceBuilderDialogs.OK) {
+				retval = getCheckedContexts(root);
+			}
+		} else {
+			StringErrorParameters sp = new StringErrorParameters();
+			sp.string = dialog.getTemplate().getTitle();
+			throw new TraceBuilderException(
+					TraceBuilderErrorCode.NO_FUNCTIONS_TO_INSTRUMENT_WITH_TEMPLATE,
+					sp);
+		}
+		return retval;
+	}
+
+	/**
+	 * Creates the tree for the query dialog
+	 * 
+	 * @param dialog
+	 *            the property dialog
+	 * @return the root of the tree
+	 */
+	private CheckListDialogEntry createFunctionQueryDialogTree(
+			TraceObjectPropertyDialog dialog) {
+		TraceObjectPropertyDialogTemplate template = dialog.getTemplate();
+		CheckListDialogEntry root = new CheckListDialogEntry();
+		// Tells the dialog to go through children and check those that are
+		// checked
+		root.setChecked(true);
+		for (SourceProperties source : sourceEngine) {
+			ArrayList<String> nonSourceFiles = sourceEngine.getNonSourceFiles();
+			if (!nonSourceFiles.contains(source.getFilePath()+ source.getFileName())) {
+				addSourceToList(template, root, source);
+			}
+		}
+		return root;
+	}
+
+	/**
+	 * Adds a source to the query dialog tree
+	 * 
+	 * @param template
+	 *            the template from the property dialog
+	 * @param root
+	 *            the root entry
+	 * @param source
+	 *            the source properties
+	 */
+	private void addSourceToList(TraceObjectPropertyDialogTemplate template,
+			CheckListDialogEntry root, SourceProperties source) {
+		if (!source.isReadOnly()) {
+			SourceParser parser = source.getSourceEditor();
+			CheckListDialogEntry sourceEntry = new CheckListDialogEntry();
+			sourceEntry.setObject(source.getFileName());
+			Iterator<SourceContext> contexts = parser.getContexts();
+			while (contexts.hasNext()) {
+				addContextToList(template, sourceEntry, contexts.next());
+			}
+			if (sourceEntry.hasChildren()) {
+				root.addChild(sourceEntry);
+			}
+		}
+	}
+
+	/**
+	 * Adds a context to the query dialog tree
+	 * 
+	 * @param template
+	 *            the template from the property dialog
+	 * @param sourceEntry
+	 *            the source where the context is to be added
+	 * @param context
+	 *            the source context to be added
+	 */
+	private void addContextToList(TraceObjectPropertyDialogTemplate template,
+			CheckListDialogEntry sourceEntry, SourceContext context) {
+		boolean available = true;
+		if (template instanceof ContextBasedTemplate) {
+			available = ((ContextBasedTemplate) template)
+					.isAvailableInContext(context);
+		}
+		if (available) {
+			CheckListDialogEntry contextEntry = new CheckListDialogEntry();
+			contextEntry.setObject(context);
+			contextEntry.setChecked(true);
+			sourceEntry.addChild(contextEntry);
+		}
+	}
+
+	/**
+	 * Gets the checked contexts from the query tree
+	 * 
+	 * @param root
+	 *            the root of the tree
+	 * @return iterator of checked contexts
+	 */
+	private Iterator<SourceContext> getCheckedContexts(CheckListDialogEntry root) {
+		ArrayList<SourceContext> contextList = new ArrayList<SourceContext>();
+		for (CheckListDialogEntry entry : root) {
+			for (CheckListDialogEntry context : entry) {
+				if (context.isChecked()) {
+					contextList.add((SourceContext) context.getObject());
+				}
+			}
+		}
+		Iterator<SourceContext> retval;
+		if (!contextList.isEmpty()) {
+			retval = contextList.iterator();
+		} else {
+			retval = null;
+		}
+		return retval;
+	}
+
+	/**
+	 * Processes the given context
+	 * 
+	 * @param dialog
+	 *            the flags from the dialog
+	 * @param group
+	 *            the target trace group
+	 * @param context
+	 *            the context to be processed
+	 */
+	private void processContext(TraceObjectPropertyDialog dialog,
+			TraceGroup group, SourceContext context) {
+		try {
+			int id = group.getNextTraceID();
+			String name = TraceUtils.convertName(formatTrace(dialog.getName(),
+					context));
+			String value = formatTrace(dialog.getValue(), context);
+			TraceObjectModifier nameModifier = TraceObjectUtils
+					.modifyDuplicateTraceName(group.getModel(), name);
+			group.getModel().getVerifier().checkTraceProperties(group, null,
+					id, nameModifier.getData(), value);
+			TraceModelExtension[] extArray = createExtensions(group, dialog);
+			Trace trace = group.getModel().getFactory().createTrace(group, id,
+					nameModifier.getData(), value, extArray);
+			if (nameModifier.hasChanged()) {
+				TraceBuilderGlobals.getEvents().postWarningMessage(
+						DUPLICATE_NAME_CHANGED + name, trace);
+			}
+			sourceEngine.insertTrace(trace, sourceEngine
+					.getSourceOfContext(context), context.getOffset());
+			TraceUtils.multiplyTrace(trace, context.getOffset(), sourceEngine);
+
+			SourceProperties properties = sourceEngine
+					.getSourceOfContext(context);
+			String fileName = context.getFileName();
+			if (fileName != null) {
+				String headerFileName = TraceBuilderGlobals.getHeaderFileName(fileName);
+				sourceEngine.addInclude(properties, headerFileName);
+			}
+
+		} catch (TraceBuilderException e) {
+			TraceBuilderGlobals.getEvents().postError(e);
+		}
+	}
+
+	/**
+	 * Formats the trace specified into instrumenter dialog
+	 * 
+	 * @param format
+	 *            the formatting
+	 * @param context
+	 *            the context where trace is added
+	 * @return the formatted trace
+	 */
+	private String formatTrace(String format, SourceContext context) {
+		String cname = context.getClassName();
+		String fname = context.getFunctionName();
+		return TraceUtils.formatTrace(format, cname, fname);
+	}
+}