trace/tracebuilder/com.nokia.tracebuilder/src/com/nokia/tracebuilder/engine/propertydialog/RunInstrumenterCallback.java
changeset 10 ed1c9f64298a
equal deleted inserted replaced
9:14dc2103a631 10:ed1c9f64298a
       
     1 /*
       
     2 * Copyright (c) 2008 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 * Dialog callback to process instrumentation
       
    17 *
       
    18 */
       
    19 package com.nokia.tracebuilder.engine.propertydialog;
       
    20 
       
    21 import java.util.ArrayList;
       
    22 import java.util.Iterator;
       
    23 
       
    24 import com.nokia.tracebuilder.engine.CheckListDialogEntry;
       
    25 import com.nokia.tracebuilder.engine.SourceContextManager;
       
    26 import com.nokia.tracebuilder.engine.TraceBuilderDialogs;
       
    27 import com.nokia.tracebuilder.engine.TraceBuilderGlobals;
       
    28 import com.nokia.tracebuilder.engine.TraceObjectPropertyDialog;
       
    29 import com.nokia.tracebuilder.engine.TraceObjectPropertyDialogTemplate;
       
    30 import com.nokia.tracebuilder.engine.TraceBuilderDialogs.CheckListDialogParameters;
       
    31 import com.nokia.tracebuilder.engine.TraceBuilderDialogs.CheckListDialogType;
       
    32 import com.nokia.tracebuilder.engine.TraceBuilderErrorCodes.StringErrorParameters;
       
    33 import com.nokia.tracebuilder.engine.TraceBuilderErrorCodes.TraceBuilderErrorCode;
       
    34 import com.nokia.tracebuilder.engine.source.SourceEngine;
       
    35 import com.nokia.tracebuilder.engine.source.SourceProperties;
       
    36 import com.nokia.tracebuilder.engine.utils.TraceUtils;
       
    37 import com.nokia.tracebuilder.model.Trace;
       
    38 import com.nokia.tracebuilder.model.TraceBuilderException;
       
    39 import com.nokia.tracebuilder.model.TraceGroup;
       
    40 import com.nokia.tracebuilder.model.TraceModel;
       
    41 import com.nokia.tracebuilder.model.TraceModelExtension;
       
    42 import com.nokia.tracebuilder.model.TraceObjectModifier;
       
    43 import com.nokia.tracebuilder.model.TraceObjectUtils;
       
    44 import com.nokia.tracebuilder.project.FormattingUtils;
       
    45 import com.nokia.tracebuilder.source.SourceContext;
       
    46 import com.nokia.tracebuilder.source.SourceParser;
       
    47 
       
    48 /**
       
    49  * Dialog callback to process instrumentation
       
    50  * 
       
    51  */
       
    52 public final class RunInstrumenterCallback extends PropertyDialogCallback {
       
    53 
       
    54 	/**
       
    55 	 * Duplicate name changed warning
       
    56 	 */
       
    57 	private static final String DUPLICATE_NAME_CHANGED = Messages
       
    58 			.getString("RunInstrumenterCallback.DuplicateName"); //$NON-NLS-1$
       
    59 
       
    60 	/**
       
    61 	 * Source engine for trace additions
       
    62 	 */
       
    63 	private SourceEngine sourceEngine;
       
    64 
       
    65 	/**
       
    66 	 * Context manager
       
    67 	 */
       
    68 	private SourceContextManager contextManager;
       
    69 
       
    70 	/**
       
    71 	 * Instrumenter ID
       
    72 	 */
       
    73 	private String instrumenterID;
       
    74 
       
    75 	/**
       
    76 	 * Creates a new instrumenter callback
       
    77 	 * 
       
    78 	 * @param model
       
    79 	 *            the trace model
       
    80 	 * @param sourceEngine
       
    81 	 *            the source engine
       
    82 	 * @param contextManager
       
    83 	 *            the source context manager
       
    84 	 * @param instrumenterID
       
    85 	 *            the instrumenter ID
       
    86 	 */
       
    87 	public RunInstrumenterCallback(TraceModel model, SourceEngine sourceEngine,
       
    88 			SourceContextManager contextManager, String instrumenterID) {
       
    89 		super(model);
       
    90 		this.sourceEngine = sourceEngine;
       
    91 		this.contextManager = contextManager;
       
    92 		this.instrumenterID = instrumenterID;
       
    93 	}
       
    94 
       
    95 	/*
       
    96 	 * (non-Javadoc)
       
    97 	 * 
       
    98 	 * @see com.nokia.tracebuilder.engine.PropertyDialogManagerCallback#
       
    99 	 *      okSelected(com.nokia.tracebuilder.engine.TraceObjectPropertyDialog)
       
   100 	 */
       
   101 	public void okSelected(TraceObjectPropertyDialog dialog)
       
   102 			throws TraceBuilderException {
       
   103 		String groupName = dialog.getTarget();
       
   104 		// If group does not exist, it will be created
       
   105 		TraceGroup group = model.findGroupByName(groupName);
       
   106 		int groupId = 0;
       
   107 		if (group == null) {
       
   108 			groupId = FormattingUtils.getGroupID(model, groupName);
       
   109 			model.getVerifier().checkTraceGroupProperties(model, null, groupId,
       
   110 					groupName);
       
   111 		}
       
   112 		Iterator<SourceContext> contexts = showFunctionQueryDialog(dialog);
       
   113 		if (contexts != null) {
       
   114 			String oldCategory = TraceBuilderGlobals.getEvents()
       
   115 					.setEventCategory("Instrumenter"); //$NON-NLS-1$
       
   116 			contextManager.setInstrumenterID(instrumenterID);
       
   117 			model.startProcessing();
       
   118 			try {
       
   119 				// Group is created if it does not exist
       
   120 				if (group == null && contexts.hasNext()) {
       
   121 					group = model.getFactory().createTraceGroup(groupId,
       
   122 							groupName, null);
       
   123 				}
       
   124 				while (contexts.hasNext()) {
       
   125 					SourceContext context = contexts.next();
       
   126 					contextManager.setContext(context);
       
   127 					processContext(dialog, group, context);
       
   128 				}
       
   129 			} finally {
       
   130 				model.processingComplete();
       
   131 				// These must be reset even if errors occurs
       
   132 				contextManager.setContext(null);
       
   133 				contextManager.setInstrumenterID(""); //$NON-NLS-1$
       
   134 				TraceBuilderGlobals.getEvents().setEventCategory(oldCategory);
       
   135 			}
       
   136 		}
       
   137 	}
       
   138 
       
   139 	/**
       
   140 	 * Shows the function tree view, which can be used to select the functions
       
   141 	 * to be instrumented
       
   142 	 * 
       
   143 	 * @param dialog
       
   144 	 *            the property dialog
       
   145 	 * @return the iterator of functions to be instrumented
       
   146 	 * @throws TraceBuilderException
       
   147 	 *             if instrumenter fails
       
   148 	 */
       
   149 	private Iterator<SourceContext> showFunctionQueryDialog(
       
   150 			TraceObjectPropertyDialog dialog) throws TraceBuilderException {
       
   151 		Iterator<SourceContext> retval = null;
       
   152 		CheckListDialogEntry root = createFunctionQueryDialogTree(dialog);
       
   153 		if (root.hasChildren()) {
       
   154 			ArrayList<CheckListDialogEntry> rootItems = new ArrayList<CheckListDialogEntry>();
       
   155 			rootItems.add(root);
       
   156 			CheckListDialogParameters params = new CheckListDialogParameters();
       
   157 			params.dialogType = CheckListDialogType.INSTRUMENT_FILES;
       
   158 			params.rootItems = rootItems;
       
   159 			params.expandLevel = 1;
       
   160 			params.showRoot = false;
       
   161 			int res = TraceBuilderGlobals.getDialogs().showCheckList(params);
       
   162 			if (res == TraceBuilderDialogs.OK) {
       
   163 				retval = getCheckedContexts(root);
       
   164 			}
       
   165 		} else {
       
   166 			StringErrorParameters sp = new StringErrorParameters();
       
   167 			sp.string = dialog.getTemplate().getTitle();
       
   168 			throw new TraceBuilderException(
       
   169 					TraceBuilderErrorCode.NO_FUNCTIONS_TO_INSTRUMENT_WITH_TEMPLATE,
       
   170 					sp);
       
   171 		}
       
   172 		return retval;
       
   173 	}
       
   174 
       
   175 	/**
       
   176 	 * Creates the tree for the query dialog
       
   177 	 * 
       
   178 	 * @param dialog
       
   179 	 *            the property dialog
       
   180 	 * @return the root of the tree
       
   181 	 */
       
   182 	private CheckListDialogEntry createFunctionQueryDialogTree(
       
   183 			TraceObjectPropertyDialog dialog) {
       
   184 		TraceObjectPropertyDialogTemplate template = dialog.getTemplate();
       
   185 		CheckListDialogEntry root = new CheckListDialogEntry();
       
   186 		// Tells the dialog to go through children and check those that are
       
   187 		// checked
       
   188 		root.setChecked(true);
       
   189 		for (SourceProperties source : sourceEngine) {
       
   190 			ArrayList<String> nonSourceFiles = sourceEngine.getNonSourceFiles();
       
   191 			if (!nonSourceFiles.contains(source.getFilePath()+ source.getFileName())) {
       
   192 				addSourceToList(template, root, source);
       
   193 			}
       
   194 		}
       
   195 		return root;
       
   196 	}
       
   197 
       
   198 	/**
       
   199 	 * Adds a source to the query dialog tree
       
   200 	 * 
       
   201 	 * @param template
       
   202 	 *            the template from the property dialog
       
   203 	 * @param root
       
   204 	 *            the root entry
       
   205 	 * @param source
       
   206 	 *            the source properties
       
   207 	 */
       
   208 	private void addSourceToList(TraceObjectPropertyDialogTemplate template,
       
   209 			CheckListDialogEntry root, SourceProperties source) {
       
   210 		if (!source.isReadOnly()) {
       
   211 			SourceParser parser = source.getSourceEditor();
       
   212 			CheckListDialogEntry sourceEntry = new CheckListDialogEntry();
       
   213 			sourceEntry.setObject(source.getFileName());
       
   214 			Iterator<SourceContext> contexts = parser.getContexts();
       
   215 			while (contexts.hasNext()) {
       
   216 				addContextToList(template, sourceEntry, contexts.next());
       
   217 			}
       
   218 			if (sourceEntry.hasChildren()) {
       
   219 				root.addChild(sourceEntry);
       
   220 			}
       
   221 		}
       
   222 	}
       
   223 
       
   224 	/**
       
   225 	 * Adds a context to the query dialog tree
       
   226 	 * 
       
   227 	 * @param template
       
   228 	 *            the template from the property dialog
       
   229 	 * @param sourceEntry
       
   230 	 *            the source where the context is to be added
       
   231 	 * @param context
       
   232 	 *            the source context to be added
       
   233 	 */
       
   234 	private void addContextToList(TraceObjectPropertyDialogTemplate template,
       
   235 			CheckListDialogEntry sourceEntry, SourceContext context) {
       
   236 		boolean available = true;
       
   237 		if (template instanceof ContextBasedTemplate) {
       
   238 			available = ((ContextBasedTemplate) template)
       
   239 					.isAvailableInContext(context);
       
   240 		}
       
   241 		if (available) {
       
   242 			CheckListDialogEntry contextEntry = new CheckListDialogEntry();
       
   243 			contextEntry.setObject(context);
       
   244 			contextEntry.setChecked(true);
       
   245 			sourceEntry.addChild(contextEntry);
       
   246 		}
       
   247 	}
       
   248 
       
   249 	/**
       
   250 	 * Gets the checked contexts from the query tree
       
   251 	 * 
       
   252 	 * @param root
       
   253 	 *            the root of the tree
       
   254 	 * @return iterator of checked contexts
       
   255 	 */
       
   256 	private Iterator<SourceContext> getCheckedContexts(CheckListDialogEntry root) {
       
   257 		ArrayList<SourceContext> contextList = new ArrayList<SourceContext>();
       
   258 		for (CheckListDialogEntry entry : root) {
       
   259 			for (CheckListDialogEntry context : entry) {
       
   260 				if (context.isChecked()) {
       
   261 					contextList.add((SourceContext) context.getObject());
       
   262 				}
       
   263 			}
       
   264 		}
       
   265 		Iterator<SourceContext> retval;
       
   266 		if (!contextList.isEmpty()) {
       
   267 			retval = contextList.iterator();
       
   268 		} else {
       
   269 			retval = null;
       
   270 		}
       
   271 		return retval;
       
   272 	}
       
   273 
       
   274 	/**
       
   275 	 * Processes the given context
       
   276 	 * 
       
   277 	 * @param dialog
       
   278 	 *            the flags from the dialog
       
   279 	 * @param group
       
   280 	 *            the target trace group
       
   281 	 * @param context
       
   282 	 *            the context to be processed
       
   283 	 */
       
   284 	private void processContext(TraceObjectPropertyDialog dialog,
       
   285 			TraceGroup group, SourceContext context) {
       
   286 		try {
       
   287 			int id = group.getNextTraceID();
       
   288 			String name = TraceUtils.convertName(formatTrace(dialog.getName(),
       
   289 					context));
       
   290 			String value = formatTrace(dialog.getValue(), context);
       
   291 			TraceObjectModifier nameModifier = TraceObjectUtils
       
   292 					.modifyDuplicateTraceName(group.getModel(), name);
       
   293 			group.getModel().getVerifier().checkTraceProperties(group, null,
       
   294 					id, nameModifier.getData(), value);
       
   295 			TraceModelExtension[] extArray = createExtensions(group, dialog);
       
   296 			Trace trace = group.getModel().getFactory().createTrace(group, id,
       
   297 					nameModifier.getData(), value, extArray);
       
   298 			if (nameModifier.hasChanged()) {
       
   299 				TraceBuilderGlobals.getEvents().postWarningMessage(
       
   300 						DUPLICATE_NAME_CHANGED + name, trace);
       
   301 			}
       
   302 			sourceEngine.insertTrace(trace, sourceEngine
       
   303 					.getSourceOfContext(context), context.getOffset());
       
   304 			TraceUtils.multiplyTrace(trace, context.getOffset(), sourceEngine);
       
   305 
       
   306 			SourceProperties properties = sourceEngine
       
   307 					.getSourceOfContext(context);
       
   308 			String fileName = context.getFileName();
       
   309 			if (fileName != null) {
       
   310 				String headerFileName = TraceBuilderGlobals.getHeaderFileName(fileName);
       
   311 				sourceEngine.addInclude(properties, headerFileName);
       
   312 			}
       
   313 
       
   314 		} catch (TraceBuilderException e) {
       
   315 			TraceBuilderGlobals.getEvents().postError(e);
       
   316 		}
       
   317 	}
       
   318 
       
   319 	/**
       
   320 	 * Formats the trace specified into instrumenter dialog
       
   321 	 * 
       
   322 	 * @param format
       
   323 	 *            the formatting
       
   324 	 * @param context
       
   325 	 *            the context where trace is added
       
   326 	 * @return the formatted trace
       
   327 	 */
       
   328 	private String formatTrace(String format, SourceContext context) {
       
   329 		String cname = context.getClassName();
       
   330 		String fname = context.getFunctionName();
       
   331 		return TraceUtils.formatTrace(format, cname, fname);
       
   332 	}
       
   333 }