tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/source/SourceProperties.java
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
 * All rights reserved.
hgs
parents:
diff changeset
     4
 * This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
 * under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
 * which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
 *
hgs
parents:
diff changeset
     9
 * Initial Contributors:
hgs
parents:
diff changeset
    10
 * Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
 *
hgs
parents:
diff changeset
    12
 * Contributors:
hgs
parents:
diff changeset
    13
 *
hgs
parents:
diff changeset
    14
 * Description:
hgs
parents:
diff changeset
    15
 *
hgs
parents:
diff changeset
    16
 * Properties of a source document opened to Eclipse editor
hgs
parents:
diff changeset
    17
 *
hgs
parents:
diff changeset
    18
 */
hgs
parents:
diff changeset
    19
package com.nokia.tracecompiler.engine.source;
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
import java.util.ArrayList;
hgs
parents:
diff changeset
    22
import java.util.Iterator;
hgs
parents:
diff changeset
    23
hgs
parents:
diff changeset
    24
import com.nokia.tracecompiler.engine.TraceCompilerEngineConfiguration;
hgs
parents:
diff changeset
    25
import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals;
hgs
parents:
diff changeset
    26
import com.nokia.tracecompiler.engine.TraceLocation;
hgs
parents:
diff changeset
    27
import com.nokia.tracecompiler.model.TraceModel;
hgs
parents:
diff changeset
    28
import com.nokia.tracecompiler.source.SourceDocumentFactory;
hgs
parents:
diff changeset
    29
import com.nokia.tracecompiler.source.SourceDocumentInterface;
hgs
parents:
diff changeset
    30
import com.nokia.tracecompiler.source.SourceIterator;
hgs
parents:
diff changeset
    31
import com.nokia.tracecompiler.source.SourceParser;
hgs
parents:
diff changeset
    32
import com.nokia.tracecompiler.source.SourceParserException;
hgs
parents:
diff changeset
    33
import com.nokia.tracecompiler.source.SourcePropertyProvider;
hgs
parents:
diff changeset
    34
import com.nokia.tracecompiler.source.SourceStringSearch;
hgs
parents:
diff changeset
    35
hgs
parents:
diff changeset
    36
/**
hgs
parents:
diff changeset
    37
 * Properties of a source document which contains trace locations
hgs
parents:
diff changeset
    38
 * 
hgs
parents:
diff changeset
    39
 */
hgs
parents:
diff changeset
    40
public class SourceProperties implements Iterable<TraceLocation> {
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
	/**
hgs
parents:
diff changeset
    43
	 * Trace locations within the source
hgs
parents:
diff changeset
    44
	 */
hgs
parents:
diff changeset
    45
	private ArrayList<TraceLocation> locations = new ArrayList<TraceLocation>();
hgs
parents:
diff changeset
    46
hgs
parents:
diff changeset
    47
	/**
hgs
parents:
diff changeset
    48
	 * Source parser
hgs
parents:
diff changeset
    49
	 */
hgs
parents:
diff changeset
    50
	private SourceParser sourceParser;
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
	/**
hgs
parents:
diff changeset
    53
	 * Offset is stored in preProcess and reset in postProcess.
hgs
parents:
diff changeset
    54
	 */
hgs
parents:
diff changeset
    55
	private int firstChangedLocation = -1;
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
	/**
hgs
parents:
diff changeset
    58
	 * Offset is stored in preProcess and reset in postProcess.
hgs
parents:
diff changeset
    59
	 */
hgs
parents:
diff changeset
    60
	private int firstUnchangedLocation = -1;
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
	/**
hgs
parents:
diff changeset
    63
	 * The searchers for trace identifiers
hgs
parents:
diff changeset
    64
	 */
hgs
parents:
diff changeset
    65
	private ArrayList<SourceStringSearch> searchers = new ArrayList<SourceStringSearch>();
hgs
parents:
diff changeset
    66
hgs
parents:
diff changeset
    67
	/**
hgs
parents:
diff changeset
    68
	 * Start index for calls to parseTrace
hgs
parents:
diff changeset
    69
	 */
hgs
parents:
diff changeset
    70
	private int searchStartIndex;
hgs
parents:
diff changeset
    71
hgs
parents:
diff changeset
    72
	/**
hgs
parents:
diff changeset
    73
	 * Read-only flag
hgs
parents:
diff changeset
    74
	 */
hgs
parents:
diff changeset
    75
	private boolean readOnly;
hgs
parents:
diff changeset
    76
hgs
parents:
diff changeset
    77
	/**
hgs
parents:
diff changeset
    78
	 * Creates source properties for given source document
hgs
parents:
diff changeset
    79
	 * 
hgs
parents:
diff changeset
    80
	 * @param model
hgs
parents:
diff changeset
    81
	 *            the trace model
hgs
parents:
diff changeset
    82
	 * @param framework
hgs
parents:
diff changeset
    83
	 *            the document framework
hgs
parents:
diff changeset
    84
	 * @param document
hgs
parents:
diff changeset
    85
	 *            the document
hgs
parents:
diff changeset
    86
	 */
hgs
parents:
diff changeset
    87
	SourceProperties(TraceModel model, SourceDocumentFactory framework,
hgs
parents:
diff changeset
    88
			SourceDocumentInterface document) {
hgs
parents:
diff changeset
    89
		sourceParser = new SourceParser(framework, document);
hgs
parents:
diff changeset
    90
		Iterator<SourceParserRule> parsers = model
hgs
parents:
diff changeset
    91
				.getExtensions(SourceParserRule.class);
hgs
parents:
diff changeset
    92
		while (parsers.hasNext()) {
hgs
parents:
diff changeset
    93
			// The rule defines what to search and how to interpret the
hgs
parents:
diff changeset
    94
			// parameters. It is stored into the searcher as search data
hgs
parents:
diff changeset
    95
			addParserRule(parsers.next());
hgs
parents:
diff changeset
    96
		}
hgs
parents:
diff changeset
    97
	}
hgs
parents:
diff changeset
    98
hgs
parents:
diff changeset
    99
	/**
hgs
parents:
diff changeset
   100
	 * Gets the source parser
hgs
parents:
diff changeset
   101
	 * 
hgs
parents:
diff changeset
   102
	 * @return the parser
hgs
parents:
diff changeset
   103
	 */
hgs
parents:
diff changeset
   104
	public SourceParser getSourceParser() {
hgs
parents:
diff changeset
   105
		return sourceParser;
hgs
parents:
diff changeset
   106
	}
hgs
parents:
diff changeset
   107
hgs
parents:
diff changeset
   108
	/*
hgs
parents:
diff changeset
   109
	 * (non-Javadoc)
hgs
parents:
diff changeset
   110
	 * 
hgs
parents:
diff changeset
   111
	 * @see java.lang.Iterable#iterator()
hgs
parents:
diff changeset
   112
	 */
hgs
parents:
diff changeset
   113
	public Iterator<TraceLocation> iterator() {
hgs
parents:
diff changeset
   114
		return locations.iterator();
hgs
parents:
diff changeset
   115
	}
hgs
parents:
diff changeset
   116
hgs
parents:
diff changeset
   117
	/**
hgs
parents:
diff changeset
   118
	 * Gets the file name of this source
hgs
parents:
diff changeset
   119
	 * 
hgs
parents:
diff changeset
   120
	 * @return the name
hgs
parents:
diff changeset
   121
	 */
hgs
parents:
diff changeset
   122
	public String getFileName() {
hgs
parents:
diff changeset
   123
		String retval = null;
hgs
parents:
diff changeset
   124
		if (sourceParser != null) {
hgs
parents:
diff changeset
   125
			SourceDocumentInterface source = sourceParser.getSource();
hgs
parents:
diff changeset
   126
			if (source != null) {
hgs
parents:
diff changeset
   127
				SourcePropertyProvider provider = source.getPropertyProvider();
hgs
parents:
diff changeset
   128
				if (provider != null) {
hgs
parents:
diff changeset
   129
					retval = provider.getFileName();
hgs
parents:
diff changeset
   130
				}
hgs
parents:
diff changeset
   131
			}
hgs
parents:
diff changeset
   132
		}
hgs
parents:
diff changeset
   133
		return retval;
hgs
parents:
diff changeset
   134
	}
hgs
parents:
diff changeset
   135
hgs
parents:
diff changeset
   136
	/**
hgs
parents:
diff changeset
   137
	 * Sets the read-only flag for this source. Traces cannot be added to
hgs
parents:
diff changeset
   138
	 * read-only sources, but they can be parsed for data
hgs
parents:
diff changeset
   139
	 * 
hgs
parents:
diff changeset
   140
	 * @param readOnly
hgs
parents:
diff changeset
   141
	 *            the read-only flag
hgs
parents:
diff changeset
   142
	 */
hgs
parents:
diff changeset
   143
	void setReadOnly(boolean readOnly) {
hgs
parents:
diff changeset
   144
		this.readOnly = readOnly;
hgs
parents:
diff changeset
   145
	}
hgs
parents:
diff changeset
   146
hgs
parents:
diff changeset
   147
	/**
hgs
parents:
diff changeset
   148
	 * Gets the read-only flag
hgs
parents:
diff changeset
   149
	 * 
hgs
parents:
diff changeset
   150
	 * @return read-only flag
hgs
parents:
diff changeset
   151
	 */
hgs
parents:
diff changeset
   152
	public boolean isReadOnly() {
hgs
parents:
diff changeset
   153
		return readOnly;
hgs
parents:
diff changeset
   154
	}
hgs
parents:
diff changeset
   155
hgs
parents:
diff changeset
   156
	/**
hgs
parents:
diff changeset
   157
	 * Source opened notification
hgs
parents:
diff changeset
   158
	 */
hgs
parents:
diff changeset
   159
	void sourceOpened() {
hgs
parents:
diff changeset
   160
		updateTraces(0, sourceParser.getDataLength());
hgs
parents:
diff changeset
   161
	}
hgs
parents:
diff changeset
   162
hgs
parents:
diff changeset
   163
	/**
hgs
parents:
diff changeset
   164
	 * Parses the document starting from given offset and locates the trace
hgs
parents:
diff changeset
   165
	 * entries from it. The first unchanged trace entry stops the search
hgs
parents:
diff changeset
   166
	 * 
hgs
parents:
diff changeset
   167
	 * @param startOffset
hgs
parents:
diff changeset
   168
	 *            the offset where to start the search
hgs
parents:
diff changeset
   169
	 * @param endOffset
hgs
parents:
diff changeset
   170
	 *            the offset where to end the search
hgs
parents:
diff changeset
   171
	 */
hgs
parents:
diff changeset
   172
	private void updateTraces(int startOffset, int endOffset) {
hgs
parents:
diff changeset
   173
		Iterator<SourceStringSearch> itr = searchers.iterator();
hgs
parents:
diff changeset
   174
		while (itr.hasNext()) {
hgs
parents:
diff changeset
   175
			SourceStringSearch searcher = itr.next();
hgs
parents:
diff changeset
   176
			searcher.resetSearch(startOffset, endOffset);
hgs
parents:
diff changeset
   177
			updateTraces(endOffset, searcher);
hgs
parents:
diff changeset
   178
		}
hgs
parents:
diff changeset
   179
	}
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
	/**
hgs
parents:
diff changeset
   182
	 * Uses the given SourceSearch to parse traces
hgs
parents:
diff changeset
   183
	 * 
hgs
parents:
diff changeset
   184
	 * @param end
hgs
parents:
diff changeset
   185
	 *            the offset where parser should stop
hgs
parents:
diff changeset
   186
	 * @param searcher
hgs
parents:
diff changeset
   187
	 *            the searcher
hgs
parents:
diff changeset
   188
	 */
hgs
parents:
diff changeset
   189
	private void updateTraces(int end, SourceStringSearch searcher) {
hgs
parents:
diff changeset
   190
		int offset;
hgs
parents:
diff changeset
   191
		searchStartIndex = 0;
hgs
parents:
diff changeset
   192
		// If not updating, the entries contents are processed
hgs
parents:
diff changeset
   193
		do {
hgs
parents:
diff changeset
   194
			offset = searcher.findNext();
hgs
parents:
diff changeset
   195
			try {
hgs
parents:
diff changeset
   196
				if (offset != -1 && offset < end) {
hgs
parents:
diff changeset
   197
					String tag = isValidTrace(offset, searcher
hgs
parents:
diff changeset
   198
							.getSearchString().length(), searcher, false);
hgs
parents:
diff changeset
   199
					if (tag != null) {
hgs
parents:
diff changeset
   200
						parseTrace(offset, (SourceParserRule) searcher
hgs
parents:
diff changeset
   201
								.getSearchData(), tag);
hgs
parents:
diff changeset
   202
					}
hgs
parents:
diff changeset
   203
				}
hgs
parents:
diff changeset
   204
			} catch (SourceParserException e) {
hgs
parents:
diff changeset
   205
				TraceLocation location = new TraceLocation(this, offset,
hgs
parents:
diff changeset
   206
						offset + 80);
hgs
parents:
diff changeset
   207
				TraceCompilerEngineGlobals
hgs
parents:
diff changeset
   208
						.getEvents()
hgs
parents:
diff changeset
   209
						.postErrorMessage(
hgs
parents:
diff changeset
   210
								Messages
hgs
parents:
diff changeset
   211
										.getString("SourceProperties.parsingArrowAtBeginText") + location.getFilePath() + location.getFileName() + Messages.getString("SourceProperties.parsingArrownAtMiddleText") + location.getLineNumber(), null, true); //$NON-NLS-1$ //$NON-NLS-2$
hgs
parents:
diff changeset
   212
				// If the parameters cannot be parsed, the trace is
hgs
parents:
diff changeset
   213
				// not added to the array
hgs
parents:
diff changeset
   214
			}
hgs
parents:
diff changeset
   215
		} while (offset != -1 && offset < end);
hgs
parents:
diff changeset
   216
	}
hgs
parents:
diff changeset
   217
hgs
parents:
diff changeset
   218
	/**
hgs
parents:
diff changeset
   219
	 * Parses a trace found from the document and adds it to the document's list
hgs
parents:
diff changeset
   220
	 * of positions. The position updater keeps the trace location up-to-date.
hgs
parents:
diff changeset
   221
	 * 
hgs
parents:
diff changeset
   222
	 * @param offset
hgs
parents:
diff changeset
   223
	 *            the offset to the trace
hgs
parents:
diff changeset
   224
	 * @param parserRule
hgs
parents:
diff changeset
   225
	 *            the parser to be attached to the location
hgs
parents:
diff changeset
   226
	 * @param locationTag
hgs
parents:
diff changeset
   227
	 *            the tag of the location
hgs
parents:
diff changeset
   228
	 * @throws SourceParserException
hgs
parents:
diff changeset
   229
	 *             if trace cannot be parsed
hgs
parents:
diff changeset
   230
	 */
hgs
parents:
diff changeset
   231
	private void parseTrace(int offset, SourceParserRule parserRule,
hgs
parents:
diff changeset
   232
			String locationTag) throws SourceParserException {
hgs
parents:
diff changeset
   233
		int arrayIndex = -1;
hgs
parents:
diff changeset
   234
		// Checks the changed locations. If a matching offset if found, the
hgs
parents:
diff changeset
   235
		// location is an existing one. In that case the location is not
hgs
parents:
diff changeset
   236
		// added to the array. If an offset larger than the new offset is
hgs
parents:
diff changeset
   237
		// found from the array, the location is inserted into that slot. If
hgs
parents:
diff changeset
   238
		// all locations within the array are smaller than the new offset,
hgs
parents:
diff changeset
   239
		// the new location is inserted before the first unchanged location.
hgs
parents:
diff changeset
   240
		// Since the locations in the array are ordered, the checking can
hgs
parents:
diff changeset
   241
		// always start from the latest location that has been found from
hgs
parents:
diff changeset
   242
		// the array. The caller of this function must set
hgs
parents:
diff changeset
   243
		// parseTraceStartIndex to 0 before starting a loop where this
hgs
parents:
diff changeset
   244
		// function is called. If firstUnchangedLocation is -1, this is the
hgs
parents:
diff changeset
   245
		// first time the file is being parsed and thus all locations are
hgs
parents:
diff changeset
   246
		// checked
hgs
parents:
diff changeset
   247
		boolean found = false;
hgs
parents:
diff changeset
   248
		int searchEndIndex;
hgs
parents:
diff changeset
   249
		int newSearchStartIndex = -1;
hgs
parents:
diff changeset
   250
		if (firstUnchangedLocation >= 0) {
hgs
parents:
diff changeset
   251
			searchEndIndex = firstUnchangedLocation;
hgs
parents:
diff changeset
   252
		} else {
hgs
parents:
diff changeset
   253
			searchEndIndex = locations.size();
hgs
parents:
diff changeset
   254
		}
hgs
parents:
diff changeset
   255
		for (int i = searchStartIndex; i < searchEndIndex && !found; i++) {
hgs
parents:
diff changeset
   256
			TraceLocation location = locations.get(i);
hgs
parents:
diff changeset
   257
			// Deleted locations are ignored. If a trace was replaced, the
hgs
parents:
diff changeset
   258
			// new offset will match the offset of the deleted one.
hgs
parents:
diff changeset
   259
			if (!location.isDeleted()) {
hgs
parents:
diff changeset
   260
				// If the offset of the trace matches an existing offset,
hgs
parents:
diff changeset
   261
				// the trace is old one. If the offset within the array is
hgs
parents:
diff changeset
   262
				// larger than the source offset, the trace found from
hgs
parents:
diff changeset
   263
				// source is new.
hgs
parents:
diff changeset
   264
				if (location.getOffset() == offset) {
hgs
parents:
diff changeset
   265
					found = true;
hgs
parents:
diff changeset
   266
					// Starts the next search from the value following the
hgs
parents:
diff changeset
   267
					// trace that was found
hgs
parents:
diff changeset
   268
					searchStartIndex = i + 1;
hgs
parents:
diff changeset
   269
					arrayIndex = -1;
hgs
parents:
diff changeset
   270
				} else if (location.getOffset() > offset) {
hgs
parents:
diff changeset
   271
					found = true;
hgs
parents:
diff changeset
   272
					// A new trace will be added into the current index, so
hgs
parents:
diff changeset
   273
					// the next search will start from the same location as
hgs
parents:
diff changeset
   274
					// was checked now. The index is updated after the trace has
hgs
parents:
diff changeset
   275
					// succesfully been created
hgs
parents:
diff changeset
   276
					newSearchStartIndex = i + 1;
hgs
parents:
diff changeset
   277
					arrayIndex = i;
hgs
parents:
diff changeset
   278
				}
hgs
parents:
diff changeset
   279
			}
hgs
parents:
diff changeset
   280
		}
hgs
parents:
diff changeset
   281
		// If trace was not found from the list, the trace is new and all
hgs
parents:
diff changeset
   282
		// traces following it are also new. The start index is set to point
hgs
parents:
diff changeset
   283
		// past the first unchanged location and thus the next search will
hgs
parents:
diff changeset
   284
		// ignore the above loop.
hgs
parents:
diff changeset
   285
		if (!found) {
hgs
parents:
diff changeset
   286
			arrayIndex = searchEndIndex;
hgs
parents:
diff changeset
   287
			searchStartIndex = firstUnchangedLocation + 1;
hgs
parents:
diff changeset
   288
		}
hgs
parents:
diff changeset
   289
		if (arrayIndex >= 0) {
hgs
parents:
diff changeset
   290
			// Creates a new location if it was not found
hgs
parents:
diff changeset
   291
			ArrayList<String> list = new ArrayList<String>();
hgs
parents:
diff changeset
   292
			int endOfTrace = sourceParser
hgs
parents:
diff changeset
   293
					.tokenizeParameters(offset, list, true);
hgs
parents:
diff changeset
   294
hgs
parents:
diff changeset
   295
			TraceLocation location = new TraceLocation(this, offset, endOfTrace
hgs
parents:
diff changeset
   296
					- offset);
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
			// The parser rules have been associated with the searchers. The
hgs
parents:
diff changeset
   299
			// parser rule that found the location is associated with the
hgs
parents:
diff changeset
   300
			// location and used to process its parameters
hgs
parents:
diff changeset
   301
			location.setTag(locationTag);
hgs
parents:
diff changeset
   302
			location.setParserRule(parserRule);
hgs
parents:
diff changeset
   303
			location.setData(list);
hgs
parents:
diff changeset
   304
hgs
parents:
diff changeset
   305
			TraceCompilerEngineGlobals
hgs
parents:
diff changeset
   306
					.getEvents()
hgs
parents:
diff changeset
   307
					.postInfoMessage(
hgs
parents:
diff changeset
   308
							Messages
hgs
parents:
diff changeset
   309
									.getString("SourceProperties.newTraceLocationFoundBeginText") + location.getFilePath() + location.getFileName() + Messages.getString("SourceProperties.newTraceLocationFoundMiddleText") + location.getLineNumber() + Messages.getString("SourceProperties.newTraceLocationFoundEndText") + location.getTraceText(), null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
hgs
parents:
diff changeset
   310
hgs
parents:
diff changeset
   311
			locations.add(arrayIndex, location);
hgs
parents:
diff changeset
   312
			// The changed flag is set to newly added traces. If a location
hgs
parents:
diff changeset
   313
			// is added prior to the first changed location, the index of first
hgs
parents:
diff changeset
   314
			// changed location needs to be adjusted so that the flag gets
hgs
parents:
diff changeset
   315
			// cleared in postprocessing. Also the index of first unchanged
hgs
parents:
diff changeset
   316
			// location needs to be updated to reflect the changed array
hgs
parents:
diff changeset
   317
			if (firstUnchangedLocation >= 0) {
hgs
parents:
diff changeset
   318
				location.setContentChanged(true);
hgs
parents:
diff changeset
   319
				if (arrayIndex < firstChangedLocation) {
hgs
parents:
diff changeset
   320
					firstChangedLocation = arrayIndex;
hgs
parents:
diff changeset
   321
				}
hgs
parents:
diff changeset
   322
				firstUnchangedLocation++;
hgs
parents:
diff changeset
   323
			}
hgs
parents:
diff changeset
   324
			// Updates the search start index if trace creation was succesful
hgs
parents:
diff changeset
   325
			if (newSearchStartIndex >= 0) {
hgs
parents:
diff changeset
   326
				searchStartIndex = newSearchStartIndex;
hgs
parents:
diff changeset
   327
			}
hgs
parents:
diff changeset
   328
		}
hgs
parents:
diff changeset
   329
	}
hgs
parents:
diff changeset
   330
hgs
parents:
diff changeset
   331
	/**
hgs
parents:
diff changeset
   332
	 * Checks that a trace is valid
hgs
parents:
diff changeset
   333
	 * 
hgs
parents:
diff changeset
   334
	 * @param offset
hgs
parents:
diff changeset
   335
	 *            offset to trace identifier
hgs
parents:
diff changeset
   336
	 * @param length
hgs
parents:
diff changeset
   337
	 *            length of trace
hgs
parents:
diff changeset
   338
	 * @param searcher
hgs
parents:
diff changeset
   339
	 *            the source searcher
hgs
parents:
diff changeset
   340
	 * @param checkMainTag
hgs
parents:
diff changeset
   341
	 *            true if the main search tag needs to be checked, false if only
hgs
parents:
diff changeset
   342
	 *            the tag suffix is checked
hgs
parents:
diff changeset
   343
	 * @return the trace tag or null if trace is not valid
hgs
parents:
diff changeset
   344
	 */
hgs
parents:
diff changeset
   345
	private String isValidTrace(int offset, int length,
hgs
parents:
diff changeset
   346
			SourceStringSearch searcher, boolean checkMainTag) {
hgs
parents:
diff changeset
   347
		String retval = null;
hgs
parents:
diff changeset
   348
		try {
hgs
parents:
diff changeset
   349
			int idlen = searcher.getSearchString().length();
hgs
parents:
diff changeset
   350
			int idend = offset + idlen;
hgs
parents:
diff changeset
   351
			if (checkMainTag) {
hgs
parents:
diff changeset
   352
				if (length >= idlen
hgs
parents:
diff changeset
   353
						&& searcher.isSearchStringMatch(sourceParser.getData(
hgs
parents:
diff changeset
   354
								offset, idlen))) {
hgs
parents:
diff changeset
   355
					// The previous character must be a separator or white space
hgs
parents:
diff changeset
   356
					if (offset == 0
hgs
parents:
diff changeset
   357
							|| !Character.isJavaIdentifierPart(sourceParser
hgs
parents:
diff changeset
   358
									.getData(offset - 1))) {
hgs
parents:
diff changeset
   359
						retval = getSearchTag(offset, idend);
hgs
parents:
diff changeset
   360
					}
hgs
parents:
diff changeset
   361
				}
hgs
parents:
diff changeset
   362
			} else {
hgs
parents:
diff changeset
   363
				// If main tag is not checked
hgs
parents:
diff changeset
   364
				retval = getSearchTag(offset, idend);
hgs
parents:
diff changeset
   365
			}
hgs
parents:
diff changeset
   366
			retval = verifyTag(searcher, retval, idlen);
hgs
parents:
diff changeset
   367
		} catch (Exception e) {
hgs
parents:
diff changeset
   368
			if (TraceCompilerEngineConfiguration.ASSERTIONS_ENABLED) {
hgs
parents:
diff changeset
   369
				TraceCompilerEngineGlobals.getEvents().postAssertionFailed(
hgs
parents:
diff changeset
   370
						"Trace validity check failed", e); //$NON-NLS-1$
hgs
parents:
diff changeset
   371
			}
hgs
parents:
diff changeset
   372
		}
hgs
parents:
diff changeset
   373
		return retval;
hgs
parents:
diff changeset
   374
	}
hgs
parents:
diff changeset
   375
hgs
parents:
diff changeset
   376
	/**
hgs
parents:
diff changeset
   377
	 * Verifies the tag against tag suffixes from parser
hgs
parents:
diff changeset
   378
	 * 
hgs
parents:
diff changeset
   379
	 * @param searcher
hgs
parents:
diff changeset
   380
	 *            the searcher
hgs
parents:
diff changeset
   381
	 * @param tag
hgs
parents:
diff changeset
   382
	 *            the tag include main tag and suffix
hgs
parents:
diff changeset
   383
	 * @param idlen
hgs
parents:
diff changeset
   384
	 *            the length of the main tag
hgs
parents:
diff changeset
   385
	 * @return the tag if it is valid, null if not
hgs
parents:
diff changeset
   386
	 */
hgs
parents:
diff changeset
   387
	private String verifyTag(SourceStringSearch searcher, String tag, int idlen) {
hgs
parents:
diff changeset
   388
		if (tag != null) {
hgs
parents:
diff changeset
   389
			// The trace suffix is verified by the parser. For example, if
hgs
parents:
diff changeset
   390
			// search data is "SymbianTrace" and the tag found from source
hgs
parents:
diff changeset
   391
			// is "SymbianTraceData1", the parser checks if "Data1" is a
hgs
parents:
diff changeset
   392
			// valid trace tag suffix.
hgs
parents:
diff changeset
   393
			if (!((SourceParserRule) searcher.getSearchData())
hgs
parents:
diff changeset
   394
					.isAllowedTagSuffix(tag.substring(idlen))) {
hgs
parents:
diff changeset
   395
				tag = null;
hgs
parents:
diff changeset
   396
			}
hgs
parents:
diff changeset
   397
		}
hgs
parents:
diff changeset
   398
		return tag;
hgs
parents:
diff changeset
   399
	}
hgs
parents:
diff changeset
   400
hgs
parents:
diff changeset
   401
	/**
hgs
parents:
diff changeset
   402
	 * Gets the search tag between offset and next '(' character
hgs
parents:
diff changeset
   403
	 * 
hgs
parents:
diff changeset
   404
	 * @param offset
hgs
parents:
diff changeset
   405
	 *            the start of tag
hgs
parents:
diff changeset
   406
	 * @param idend
hgs
parents:
diff changeset
   407
	 *            the end of tag
hgs
parents:
diff changeset
   408
	 * @return the tag
hgs
parents:
diff changeset
   409
	 * @throws SourceParserException
hgs
parents:
diff changeset
   410
	 *             if parser fails
hgs
parents:
diff changeset
   411
	 */
hgs
parents:
diff changeset
   412
	private String getSearchTag(int offset, int idend)
hgs
parents:
diff changeset
   413
			throws SourceParserException {
hgs
parents:
diff changeset
   414
		// Locates the parameters starting from trace identifier
hgs
parents:
diff changeset
   415
		String retval = null;
hgs
parents:
diff changeset
   416
		SourceIterator srcitr = sourceParser.createIterator(idend - 1,
hgs
parents:
diff changeset
   417
				SourceParser.SKIP_ALL);
hgs
parents:
diff changeset
   418
		boolean found = false;
hgs
parents:
diff changeset
   419
		while (srcitr.hasNext() && !found) {
hgs
parents:
diff changeset
   420
			char c = srcitr.next();
hgs
parents:
diff changeset
   421
			if (c == ';') {
hgs
parents:
diff changeset
   422
				// Trace must have parameters
hgs
parents:
diff changeset
   423
				found = true;
hgs
parents:
diff changeset
   424
			} else if (c == '(') {
hgs
parents:
diff changeset
   425
				found = true;
hgs
parents:
diff changeset
   426
				// Stores the tag into location
hgs
parents:
diff changeset
   427
				retval = sourceParser.getData(offset, srcitr.previousIndex()
hgs
parents:
diff changeset
   428
						- offset + 1);
hgs
parents:
diff changeset
   429
			} else if (srcitr.hasSkipped()) {
hgs
parents:
diff changeset
   430
				// White spaces are not allowed within trace tag
hgs
parents:
diff changeset
   431
				found = true;
hgs
parents:
diff changeset
   432
			}
hgs
parents:
diff changeset
   433
		}
hgs
parents:
diff changeset
   434
		return retval;
hgs
parents:
diff changeset
   435
	}
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
	/**
hgs
parents:
diff changeset
   438
	 * Checks if a trace can be inserted into given location
hgs
parents:
diff changeset
   439
	 * 
hgs
parents:
diff changeset
   440
	 * @param offset
hgs
parents:
diff changeset
   441
	 *            the offset to the location
hgs
parents:
diff changeset
   442
	 * @return true if location is valid
hgs
parents:
diff changeset
   443
	 */
hgs
parents:
diff changeset
   444
	boolean checkInsertLocation(int offset) {
hgs
parents:
diff changeset
   445
		boolean retval = true;
hgs
parents:
diff changeset
   446
		try {
hgs
parents:
diff changeset
   447
			offset = sourceParser.findStartOfLine(offset, false, true);
hgs
parents:
diff changeset
   448
			if (sourceParser.isInExcludedArea(offset)) {
hgs
parents:
diff changeset
   449
				retval = false;
hgs
parents:
diff changeset
   450
			}
hgs
parents:
diff changeset
   451
		} catch (SourceParserException e) {
hgs
parents:
diff changeset
   452
			retval = false;
hgs
parents:
diff changeset
   453
		}
hgs
parents:
diff changeset
   454
		return retval;
hgs
parents:
diff changeset
   455
	}
hgs
parents:
diff changeset
   456
hgs
parents:
diff changeset
   457
	/**
hgs
parents:
diff changeset
   458
	 * Adds a new parser
hgs
parents:
diff changeset
   459
	 * 
hgs
parents:
diff changeset
   460
	 * @param rule
hgs
parents:
diff changeset
   461
	 *            the new parser rule
hgs
parents:
diff changeset
   462
	 */
hgs
parents:
diff changeset
   463
	void addParserRule(SourceParserRule rule) {
hgs
parents:
diff changeset
   464
		SourceStringSearch searcher = sourceParser.startStringSearch(rule
hgs
parents:
diff changeset
   465
				.getSearchTag(), 0, -1, SourceParser.MATCH_WORD_BEGINNING
hgs
parents:
diff changeset
   466
				| SourceParser.SKIP_ALL);
hgs
parents:
diff changeset
   467
		searcher.setSearchData(rule);
hgs
parents:
diff changeset
   468
		searchers.add(searcher);
hgs
parents:
diff changeset
   469
	}
hgs
parents:
diff changeset
   470
hgs
parents:
diff changeset
   471
}