sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/internal/ui/graph/MemOpDescriptor.java
changeset 15 0367d2db2c06
parent 6 f65f740e69f9
equal deleted inserted replaced
14:bb339882c6e9 15:0367d2db2c06
    64 import com.nokia.s60tools.analyzetool.global.Constants;
    64 import com.nokia.s60tools.analyzetool.global.Constants;
    65 import com.nokia.s60tools.analyzetool.global.Util;
    65 import com.nokia.s60tools.analyzetool.global.Util;
    66 import com.nokia.s60tools.analyzetool.internal.ui.util.GraphUtils;
    66 import com.nokia.s60tools.analyzetool.internal.ui.util.GraphUtils;
    67 
    67 
    68 /**
    68 /**
    69  * MemOpDescriptor provides properties of any Alloc/Leak/Free suitable to be displayed in eclipse
    69  * MemOpDescriptor provides properties of any Alloc/Leak/Free suitable to be
    70  * Properties View.
    70  * displayed in eclipse Properties View.
    71  * 
    71  * 
    72  */
    72  */
    73 @SuppressWarnings("restriction")
    73 @SuppressWarnings("restriction")
    74 class MemOpDescriptor implements IPropertySource {
    74 class MemOpDescriptor implements IPropertySource {
    75 	BaseInfo memInfo;
    75 	BaseInfo memInfo;
    76 	
    76 
    77 	/** process Id descriptor */
    77 	/** process Id descriptor */
    78 	private static final String PID_ID = "pid"; //$NON-NLS-1$
    78 	private static final String PID_ID = "pid"; //$NON-NLS-1$
    79 	private final DotTextPropertyDescriptor PID_DESCRIPTOR = new DotTextPropertyDescriptor(PID_ID, Messages.MemOpDescriptor_1);
    79 	private final DotTextPropertyDescriptor PID_DESCRIPTOR = new DotTextPropertyDescriptor(
       
    80 			PID_ID, Messages.MemOpDescriptor_1);
    80 
    81 
    81 	/** Memory operation type Allocation/Leak/Free descriptor */
    82 	/** Memory operation type Allocation/Leak/Free descriptor */
    82 	private static final String TYPE_ID = "type"; //$NON-NLS-1$
    83 	private static final String TYPE_ID = "type"; //$NON-NLS-1$
    83 	private final DotTextPropertyDescriptor TYPE_DESCRIPTOR = new DotTextPropertyDescriptor(TYPE_ID, Messages.MemOpDescriptor_3);
    84 	private final DotTextPropertyDescriptor TYPE_DESCRIPTOR = new DotTextPropertyDescriptor(
       
    85 			TYPE_ID, Messages.MemOpDescriptor_3);
    84 
    86 
    85 	/** Time descriptor */
    87 	/** Time descriptor */
    86 	private static final String TIME_ID = "time"; //$NON-NLS-1$
    88 	private static final String TIME_ID = "time"; //$NON-NLS-1$
    87 	private final DotTextPropertyDescriptor TIME_DESCRIPTOR = new DotTextPropertyDescriptor(TIME_ID, Messages.MemOpDescriptor_5);
    89 	private final DotTextPropertyDescriptor TIME_DESCRIPTOR = new DotTextPropertyDescriptor(
       
    90 			TIME_ID, Messages.MemOpDescriptor_5);
    88 
    91 
    89 	/** size descriptor */
    92 	/** size descriptor */
    90 	private static final String SIZE_ID = "size"; //$NON-NLS-1$
    93 	private static final String SIZE_ID = "size"; //$NON-NLS-1$
    91 	private final DotTextPropertyDescriptor SIZE_DESCRIPTOR = new DotTextPropertyDescriptor(SIZE_ID, Messages.MemOpDescriptor_7);
    94 	private final DotTextPropertyDescriptor SIZE_DESCRIPTOR = new DotTextPropertyDescriptor(
       
    95 			SIZE_ID, Messages.MemOpDescriptor_7);
    92 
    96 
    93 	/** memory address descriptor */
    97 	/** memory address descriptor */
    94 	private static final String ADDR_ID = "address"; //$NON-NLS-1$
    98 	private static final String ADDR_ID = "address"; //$NON-NLS-1$
    95 	private final DotTextPropertyDescriptor ADDR_DESCRIPTOR = new DotTextPropertyDescriptor(ADDR_ID, Messages.MemOpDescriptor_9);
    99 	private final DotTextPropertyDescriptor ADDR_DESCRIPTOR = new DotTextPropertyDescriptor(
       
   100 			ADDR_ID, Messages.MemOpDescriptor_9);
    96 
   101 
    97 	/** total memory size consumed by the process descriptor */
   102 	/** total memory size consumed by the process descriptor */
    98 	private static final String TSIZE_ID = "total"; //$NON-NLS-1$
   103 	private static final String TSIZE_ID = "total"; //$NON-NLS-1$
    99 	private final DotTextPropertyDescriptor TSIZE_DESCRIPTOR = new DotTextPropertyDescriptor(TSIZE_ID, Messages.MemOpDescriptor_11);
   104 	private final DotTextPropertyDescriptor TSIZE_DESCRIPTOR = new DotTextPropertyDescriptor(
   100 
   105 			TSIZE_ID, Messages.MemOpDescriptor_11);
   101 	/** life time of an allocation descriptor. This applies only to non Leaked allocations  */
   106 
       
   107 	/** thread id descriptor */
       
   108 	private static final String THREAD_ID = "thread"; //$NON-NLS-1$
       
   109 	private final DotTextPropertyDescriptor THREAD_DESCRIPTOR = new DotTextPropertyDescriptor(
       
   110 			THREAD_ID, Messages.MemOpDescriptor_10);
       
   111 
       
   112 	/**
       
   113 	 * life time of an allocation descriptor. This applies only to non Leaked
       
   114 	 * allocations
       
   115 	 */
   102 	private static final String LIFETIME_ID = "lifetime"; //$NON-NLS-1$
   116 	private static final String LIFETIME_ID = "lifetime"; //$NON-NLS-1$
   103 	private final DotTextPropertyDescriptor LIFETIME_DESCRIPTOR = new DotTextPropertyDescriptor(LIFETIME_ID, Messages.MemOpDescriptor_13);
   117 	private final DotTextPropertyDescriptor LIFETIME_DESCRIPTOR = new DotTextPropertyDescriptor(
       
   118 			LIFETIME_ID, Messages.MemOpDescriptor_13);
   104 	private static final String ATTRIBUTES_GROUP = "Attributes"; //$NON-NLS-1$
   119 	private static final String ATTRIBUTES_GROUP = "Attributes"; //$NON-NLS-1$
   105 	/** used for making absolute time values relative */
   120 	/** used for making absolute time values relative */
   106 	private long baseTime;
   121 	private long baseTime;
   107 
   122 
   108 	/** callstack item descriptor id*/
   123 	/** callstack item descriptor id */
   109 	private static final String CALL_STACK_ID = "callstack"; //$NON-NLS-1$
   124 	private static final String CALL_STACK_ID = "callstack"; //$NON-NLS-1$
   110 
   125 
   111 	/** current project */
   126 	/** current project */
   112 	IProject iCurrentProject = null;
   127 	IProject iCurrentProject = null;
   113 	/** Symbol Reader */
   128 	/** Symbol Reader */
   114 	SymReader iSymReader = null;
   129 	SymReader iSymReader = null;
   115 	/** c++ files from the current project */
   130 	/** c++ files from the current project */
   116 	AbstractList<String> cppFileNames;
   131 	AbstractList<String> cppFileNames;
   117 	static final String LINE_SEPARATOR = " :: "; //$NON-NLS-1$
   132 	static final String LINE_SEPARATOR = " :: "; //$NON-NLS-1$
   118 	
   133 
   119 	private ICallstackManager callstackManager;
   134 	private ICallstackManager callstackManager;
       
   135 
   120 	/**
   136 	/**
   121 	 * Constructor
   137 	 * Constructor
   122 	 * @param newBaseTime usually process start time, used for making absolute time values relative   
   138 	 * 
   123 	 * @param info the alloc or free info
   139 	 * @param newBaseTime
   124 	 * @param project IProject to use for locating source file 
   140 	 *            usually process start time, used for making absolute time
   125 	 * @param symReader the SymReader to use for pinpointing
   141 	 *            values relative
   126 	 * @param cppFiles 
   142 	 * @param info
   127 	 * @param callstackManager CallstackManager for reading callstacks from BaseInfo
   143 	 *            the alloc or free info
   128 	 */
   144 	 * @param project
   129 	public MemOpDescriptor(Long newBaseTime, BaseInfo info, IProject project, SymReader symReader, AbstractList<String> cppFiles, ICallstackManager callstackManager) {
   145 	 *            IProject to use for locating source file
       
   146 	 * @param symReader
       
   147 	 *            the SymReader to use for pinpointing
       
   148 	 * @param cppFiles
       
   149 	 * @param callstackManager
       
   150 	 *            CallstackManager for reading callstacks from BaseInfo
       
   151 	 */
       
   152 	public MemOpDescriptor(Long newBaseTime, BaseInfo info, IProject project,
       
   153 			SymReader symReader, AbstractList<String> cppFiles,
       
   154 			ICallstackManager callstackManager) {
   130 		memInfo = info;
   155 		memInfo = info;
   131 		iCurrentProject = project;
   156 		iCurrentProject = project;
   132 		iSymReader = symReader;
   157 		iSymReader = symReader;
   133 		cppFileNames = cppFiles;
   158 		cppFileNames = cppFiles;
   134 		this.baseTime = newBaseTime;	
   159 		this.baseTime = newBaseTime;
   135 		this.callstackManager = callstackManager;
   160 		this.callstackManager = callstackManager;
   136 	}
   161 	}
   137 
   162 
   138 	/* (non-Javadoc)
   163 	/*
       
   164 	 * (non-Javadoc)
       
   165 	 * 
   139 	 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
   166 	 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
   140 	 */
   167 	 */
   141 	public Object getEditableValue() {
   168 	public Object getEditableValue() {
   142 		return null; // no edit
   169 		return null; // no edit
   143 	}
   170 	}
   144 
   171 
   145 
   172 	/*
   146 
   173 	 * (non-Javadoc)
   147 
   174 	 * 
   148 	/* (non-Javadoc)
   175 	 * @see
   149 	 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
   176 	 * org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
   150 	 */
   177 	 */
   151 	public IPropertyDescriptor[] getPropertyDescriptors() {
   178 	public IPropertyDescriptor[] getPropertyDescriptors() {
   152 		final List<IPropertyDescriptor> completeList = new ArrayList<IPropertyDescriptor>();
   179 		final List<IPropertyDescriptor> completeList = new ArrayList<IPropertyDescriptor>();
   153 		PID_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   180 		PID_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   154 		completeList.add(PID_DESCRIPTOR);
   181 		completeList.add(PID_DESCRIPTOR);
   160 		completeList.add(SIZE_DESCRIPTOR);
   187 		completeList.add(SIZE_DESCRIPTOR);
   161 		ADDR_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   188 		ADDR_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   162 		completeList.add(ADDR_DESCRIPTOR);
   189 		completeList.add(ADDR_DESCRIPTOR);
   163 		TSIZE_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   190 		TSIZE_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   164 		completeList.add(TSIZE_DESCRIPTOR);
   191 		completeList.add(TSIZE_DESCRIPTOR);
   165 		if (memInfo instanceof AllocInfo && ((AllocInfo)memInfo).isFreed()) {
   192 		THREAD_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
       
   193 		completeList.add(THREAD_DESCRIPTOR);
       
   194 		if (memInfo instanceof AllocInfo && ((AllocInfo) memInfo).isFreed()) {
   166 			LIFETIME_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   195 			LIFETIME_DESCRIPTOR.setCategory(ATTRIBUTES_GROUP);
   167 			completeList.add(LIFETIME_DESCRIPTOR); //only non leaks
   196 			completeList.add(LIFETIME_DESCRIPTOR); // only non leaks
   168 		}
   197 		}
   169 		// add callstack descriptors
   198 		// add callstack descriptors
   170 		if (callstackManager != null && callstackManager.hasCallstack(memInfo)){
   199 		if (callstackManager != null && callstackManager.hasCallstack(memInfo)) {
   171 			try {
   200 			try {
   172 				List<AllocCallstack> callstack = callstackManager.readCallstack(memInfo);
   201 				List<AllocCallstack> callstack = callstackManager
   173 				if (callstack != null){
   202 						.readCallstack(memInfo);
       
   203 				if (callstack != null) {
   174 					for (int i = 0; i < callstack.size(); i++) {
   204 					for (int i = 0; i < callstack.size(); i++) {
   175 						
   205 
   176 						final DotTextPropertyDescriptor propDesc = new DotTextPropertyDescriptor(i, CALL_STACK_ID);
   206 						final DotTextPropertyDescriptor propDesc = new DotTextPropertyDescriptor(
       
   207 								i, CALL_STACK_ID);
   177 						propDesc.setCategory("CallStack"); //$NON-NLS-1$
   208 						propDesc.setCategory("CallStack"); //$NON-NLS-1$
   178 						completeList.add(propDesc);
   209 						completeList.add(propDesc);
   179 					}					
   210 					}
   180 				}
   211 				}
   181 			} catch (IOException e) {
   212 			} catch (IOException e) {
   182 				//since callstacks aren't fatal and we can't handle it usefully here, log this to the error log
   213 				// since callstacks aren't fatal and we can't handle it usefully
   183 				Activator.getDefault().log(IStatus.ERROR, Messages.MemOpDescriptor_18, e);
   214 				// here, log this to the error log
   184 			}			
   215 				Activator.getDefault().log(IStatus.ERROR,
   185 		}
   216 						Messages.MemOpDescriptor_18, e);
   186 		return completeList.toArray(new TextPropertyDescriptor[completeList.size()]);
   217 			}
   187 	}
   218 		}
   188 
   219 		return completeList.toArray(new TextPropertyDescriptor[completeList
   189 	/* (non-Javadoc)
   220 				.size()]);
   190 	 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
   221 	}
       
   222 
       
   223 	/*
       
   224 	 * (non-Javadoc)
       
   225 	 * 
       
   226 	 * @see
       
   227 	 * org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java
       
   228 	 * .lang.Object)
   191 	 */
   229 	 */
   192 	public Object getPropertyValue(Object id) {
   230 	public Object getPropertyValue(Object id) {
   193 		//Note, this method must return String values for the CellEditor to work
   231 		// Note, this method must return String values for the CellEditor to
       
   232 		// work
   194 		if (PID_ID.equals(id)) {
   233 		if (PID_ID.equals(id)) {
   195 			return String.valueOf(memInfo.getProcessID());//process ids are usually decimal values
   234 			return String.valueOf(memInfo.getProcessID());// process ids are
       
   235 			// usually decimal
       
   236 			// values
   196 		}
   237 		}
   197 		if (TYPE_ID.equals(id))
   238 		if (TYPE_ID.equals(id))
   198 			return memInfo instanceof AllocInfo ? ((AllocInfo)memInfo).isFreed() ? Messages.MemOpDescriptor_19 : Messages.MemOpDescriptor_20 : Messages.MemOpDescriptor_21;
   239 			return memInfo instanceof AllocInfo ? ((AllocInfo) memInfo)
       
   240 					.isFreed() ? Messages.MemOpDescriptor_19
       
   241 					: Messages.MemOpDescriptor_20 : Messages.MemOpDescriptor_21;
   199 		if (TIME_ID.equals(id))
   242 		if (TIME_ID.equals(id))
   200 			return GraphUtils.renderTime(memInfo.getTime() - baseTime);
   243 			return GraphUtils.renderTime(memInfo.getTime() - baseTime);
   201 		if (SIZE_ID.equals(id))
   244 		if (SIZE_ID.equals(id))
   202 			return String.format(Messages.MemOpDescriptor_22,memInfo.getSizeInt());
   245 			return String.format(Messages.MemOpDescriptor_22, memInfo
       
   246 					.getSizeInt());
   203 		if (ADDR_ID.equals(id))
   247 		if (ADDR_ID.equals(id))
   204 			return Long.toString(memInfo.getMemoryAddress(),16);
   248 			return Long.toString(memInfo.getMemoryAddress(), 16);
   205 		if (TSIZE_ID.equals(id))
   249 		if (TSIZE_ID.equals(id))
   206 			return String.format(Messages.MemOpDescriptor_23,memInfo.getTotalMem());
   250 			return String.format(Messages.MemOpDescriptor_23, memInfo
       
   251 					.getTotalMem());
       
   252 		if (THREAD_ID.equals(id))
       
   253 			return String.valueOf(memInfo.getThreadId());
   207 		if (LIFETIME_ID.equals(id)) {
   254 		if (LIFETIME_ID.equals(id)) {
   208 			if (memInfo instanceof AllocInfo && ((AllocInfo)memInfo).isFreed()) {
   255 			if (memInfo instanceof AllocInfo && ((AllocInfo) memInfo).isFreed()) {
   209 				AllocInfo info = (AllocInfo) memInfo;
   256 				AllocInfo info = (AllocInfo) memInfo;
   210 				return GraphUtils.renderTime(info.getFreedBy().getTime() - info.getTime()); 
   257 				return GraphUtils.renderTime(info.getFreedBy().getTime()
   211 			}
   258 						- info.getTime());
   212 			throw new IllegalStateException("Should not happen because we did not provide a lifetime descriptor for leak and free"); //$NON-NLS-1$
   259 			}
   213 		}
   260 			throw new IllegalStateException(
   214 		if (id instanceof Integer && callstackManager.hasCallstack(memInfo)){
   261 					"Should not happen because we did not provide a lifetime descriptor for leak and free."); //$NON-NLS-1$
   215 			int callstackId = (Integer)id;
   262 		}
       
   263 		if (id instanceof Integer && callstackManager.hasCallstack(memInfo)) {
       
   264 			int callstackId = (Integer) id;
   216 			try {
   265 			try {
   217 				List<AllocCallstack> callstackList = callstackManager.readCallstack(memInfo);
   266 				List<AllocCallstack> callstackList = callstackManager
   218 				if (callstackId < callstackList.size()){
   267 						.readCallstack(memInfo);
   219 					AllocCallstack callstackItem = callstackList.get(callstackId);
   268 				if (callstackId < callstackList.size()) {
       
   269 					AllocCallstack callstackItem = callstackList
       
   270 							.get(callstackId);
   220 					DllLoad tempLoad = callstackItem.getDllLoad();
   271 					DllLoad tempLoad = callstackItem.getDllLoad();
   221 					long addr = callstackItem.getMemoryAddress();
   272 					long addr = callstackItem.getMemoryAddress();
   222 					
   273 
   223 					String name = String.format(Messages.MemOpDescriptor_25,addr);
   274 					String name = String.format(Messages.MemOpDescriptor_25,
   224 					if (tempLoad != null && callstackItem.getMemoryAddress()!= tempLoad.getStartAddress()) {
   275 							addr);
   225 						SourceFile aSourcefile = pinpoint(callstackItem.getMemoryAddress(),
   276 					if (tempLoad != null
   226 								callstackItem.getDllLoad());
   277 							&& callstackItem.getMemoryAddress() != tempLoad
   227 						if (aSourcefile != null) { //callstack resolved to a file-function-line
   278 									.getStartAddress()) {
   228 							return name + LINE_SEPARATOR + callstackItem.getDllLoad().getName() + LINE_SEPARATOR + aSourcefile.getFileName()+ LINE_SEPARATOR + aSourcefile.getFunctionName() + LINE_SEPARATOR + aSourcefile.getLineNumber();
   279 						SourceFile aSourcefile = pinpoint(callstackItem
       
   280 								.getMemoryAddress(), callstackItem.getDllLoad());
       
   281 						if (aSourcefile != null) { // callstack resolved to a
       
   282 							// file-function-line
       
   283 							return name + LINE_SEPARATOR
       
   284 									+ callstackItem.getDllLoad().getName()
       
   285 									+ LINE_SEPARATOR
       
   286 									+ aSourcefile.getFileName()
       
   287 									+ LINE_SEPARATOR
       
   288 									+ aSourcefile.getFunctionName()
       
   289 									+ LINE_SEPARATOR
       
   290 									+ aSourcefile.getLineNumber();
   229 						}
   291 						}
   230 					}
   292 					}
   231 					return name + (tempLoad != null ? LINE_SEPARATOR + tempLoad.getName() : ""); //$NON-NLS-1$
   293 					return name
       
   294 							+ (tempLoad != null ? LINE_SEPARATOR
       
   295 									+ tempLoad.getName() : ""); //$NON-NLS-1$
   232 				}
   296 				}
   233 			} catch (IOException e) {
   297 			} catch (IOException e) {
   234 				//since callstacks aren't fatal and we can't handle it usefully here, log this to the error log
   298 				// since callstacks aren't fatal and we can't handle it usefully
   235 				Activator.getDefault().log(IStatus.ERROR, Messages.MemOpDescriptor_27, e);
   299 				// here, log this to the error log
       
   300 				Activator.getDefault().log(IStatus.ERROR,
       
   301 						Messages.MemOpDescriptor_27, e);
   236 			}
   302 			}
   237 		}
   303 		}
   238 		return null;
   304 		return null;
   239 	}
   305 	}
   240 
   306 
   241 	/* (non-Javadoc)
   307 	/*
   242 	 * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
   308 	 * (non-Javadoc)
       
   309 	 * 
       
   310 	 * @see
       
   311 	 * org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang
       
   312 	 * .Object)
   243 	 */
   313 	 */
   244 	public boolean isPropertySet(Object id) {
   314 	public boolean isPropertySet(Object id) {
   245 		return false;
   315 		return false;
   246 	}
   316 	}
   247 
   317 
   248 	/* (non-Javadoc)
   318 	/*
   249 	 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
   319 	 * (non-Javadoc)
       
   320 	 * 
       
   321 	 * @see
       
   322 	 * org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java
       
   323 	 * .lang.Object)
   250 	 */
   324 	 */
   251 	public void resetPropertyValue(Object id) {
   325 	public void resetPropertyValue(Object id) {
   252 		// do nothing
   326 		// do nothing
   253 	}
   327 	}
   254 
   328 
   255 	/* (non-Javadoc)
   329 	/*
   256 	 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
   330 	 * (non-Javadoc)
       
   331 	 * 
       
   332 	 * @see
       
   333 	 * org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java
       
   334 	 * .lang.Object, java.lang.Object)
   257 	 */
   335 	 */
   258 	public void setPropertyValue(Object id, Object value) {
   336 	public void setPropertyValue(Object id, Object value) {
   259 		// do nothing
   337 		// do nothing
   260 	}
   338 	}
   261 
   339 
   262 	
   340 	/**
   263 	/**
   341 	 * DotTextPropertyDescriptor defines a read only TextPropertyDescriptor It
   264 	 * DotTextPropertyDescriptor  defines a read only TextPropertyDescriptor
   342 	 * also add a customised key/mouse listener. This listener will be useful
   265 	 * It also add a customised key/mouse listener.
   343 	 * for pinpointing the source.
   266 	 * This listener will be useful for pinpointing the source.
   344 	 * 
   267 	 *
       
   268 	 */
   345 	 */
   269 	private class DotTextPropertyDescriptor extends TextPropertyDescriptor {
   346 	private class DotTextPropertyDescriptor extends TextPropertyDescriptor {
   270 
   347 
   271 		/**
   348 		/**
   272 		 * Constructor
   349 		 * Constructor
   273 		 * @param id Descriptor Id
   350 		 * 
   274 		 * @param displayName Descriptor display name
   351 		 * @param id
       
   352 		 *            Descriptor Id
       
   353 		 * @param displayName
       
   354 		 *            Descriptor display name
   275 		 */
   355 		 */
   276 		public DotTextPropertyDescriptor(Object id, String displayName) {
   356 		public DotTextPropertyDescriptor(Object id, String displayName) {
   277 			super(id, displayName);
   357 			super(id, displayName);
   278 		}
   358 		}
   279 
   359 
   280 		/**
   360 		/**
   281 		 * create a Read Only TextCellEditor and add the defined listener to its Control.
   361 		 * create a Read Only TextCellEditor and add the defined listener to its
       
   362 		 * Control.
       
   363 		 * 
   282 		 * @see org.eclipse.ui.views.properties.TextPropertyDescriptor#createPropertyEditor(org.eclipse.swt.widgets.Composite)
   364 		 * @see org.eclipse.ui.views.properties.TextPropertyDescriptor#createPropertyEditor(org.eclipse.swt.widgets.Composite)
   283 		 */
   365 		 */
   284 		@Override
   366 		@Override
   285 		public CellEditor createPropertyEditor(Composite parent) {
   367 		public CellEditor createPropertyEditor(Composite parent) {
   286 			TextCellEditor editor = new SimpleTextCellEditor(parent,SWT.READ_ONLY);
   368 			TextCellEditor editor = new SimpleTextCellEditor(parent,
       
   369 					SWT.READ_ONLY);
   287 			Text control = (Text) editor.getControl();
   370 			Text control = (Text) editor.getControl();
   288 			control.setEditable(false);
   371 			control.setEditable(false);
   289 			
   372 
   290 			DotPropKeyMouseListener listener = new DotPropKeyMouseListener();
   373 			DotPropKeyMouseListener listener = new DotPropKeyMouseListener();
   291 			control.addKeyListener(listener);
   374 			control.addKeyListener(listener);
   292 			control.addMouseListener(listener);
   375 			control.addMouseListener(listener);
   293 			if (getValidator() != null) {
   376 			if (getValidator() != null) {
   294 				editor.setValidator(getValidator());
   377 				editor.setValidator(getValidator());
   295 			}
   378 			}
   296 			return editor;
   379 			return editor;
   297 		}
   380 		}
   298 	}
   381 	}
   299 		
   382 
   300 		
       
   301 	private class SimpleTextCellEditor extends TextCellEditor {
   383 	private class SimpleTextCellEditor extends TextCellEditor {
   302 		public SimpleTextCellEditor(Composite parent, int readOnly) {
   384 		public SimpleTextCellEditor(Composite parent, int readOnly) {
   303 			super(parent,readOnly);
   385 			super(parent, readOnly);
   304 		}
   386 		}
   305 
   387 
   306 		@Override
   388 		@Override
   307 		public boolean isCopyEnabled() {
   389 		public boolean isCopyEnabled() {
   308 			return false;
   390 			return false;
   309 		}
   391 		}
   310 		
   392 
   311 		@Override
   393 		@Override
   312 		public boolean isCutEnabled() {
   394 		public boolean isCutEnabled() {
   313 			return false;
   395 			return false;
   314 		}
   396 		}
   315 		
   397 
   316 		@Override
   398 		@Override
   317 		public boolean isPasteEnabled() {
   399 		public boolean isPasteEnabled() {
   318 			return false;
   400 			return false;
   319 		}
   401 		}
   320 		
   402 
   321 		@Override
   403 		@Override
   322 		public boolean isFindEnabled() {
   404 		public boolean isFindEnabled() {
   323 			return false;
   405 			return false;
   324 		}
   406 		}
   325 	}
   407 	}
   326 	
   408 
   327 	
   409 	/**
   328 	/**
   410 	 * This class is only for convenience for the moment. It's very likely that
   329 	 * This class is only for convenience for the moment.
   411 	 * the listener will be provided by AnalyzeToolGraph
   330 	 * It's very likely that the listener will be provided by AnalyzeToolGraph
   412 	 * 
   331 	 *
       
   332 	 */
   413 	 */
   333 	private class DotPropKeyMouseListener implements KeyListener, MouseListener {
   414 	private class DotPropKeyMouseListener implements KeyListener, MouseListener {
   334 
   415 
   335 		//key
   416 		// Key
   336 
   417 
   337 		public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
   418 		public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
   338 			//do nothing by design
   419 			// do nothing by design
   339 		}
   420 		}
   340 
   421 
   341 		public void keyReleased(org.eclipse.swt.events.KeyEvent keyEvent) {
   422 		public void keyReleased(org.eclipse.swt.events.KeyEvent keyEvent) {
   342 			//System.out.println("key released.");
   423 			// System.out.println("key released.");
   343 			if (keyEvent.character == '\r') {
   424 			if (keyEvent.character == '\r') {
   344 				String text = ((Text)keyEvent.getSource()).getText();
   425 				String text = ((Text) keyEvent.getSource()).getText();
   345 				if (text != null) {
   426 				if (text != null) {
   346 					String[] segs = text.split(LINE_SEPARATOR);
   427 					String[] segs = text.split(LINE_SEPARATOR);
   347 					if (segs.length == 5) {
   428 					if (segs.length == 5) {
   348 						openEditor(segs[2], segs[4]);
   429 						openEditor(segs[2], segs[4]);
   349 					}
   430 					}
   350 				}
   431 				}
   351 			}
   432 			}
   352 			
   433 		}
   353 		}
   434 
   354 
   435 		// Mouse
   355 		//Mouse
   436 
   356 		
       
   357 		public void mouseDoubleClick(MouseEvent e) {
   437 		public void mouseDoubleClick(MouseEvent e) {
   358 			String text = ((Text)e.getSource()).getText();
   438 			String text = ((Text) e.getSource()).getText();
   359 			if (text != null) {
   439 			if (text != null) {
   360 				String[] segs = text.split(LINE_SEPARATOR);
   440 				String[] segs = text.split(LINE_SEPARATOR);
   361 				if (segs.length == 5) {
   441 				if (segs.length == 5) {
   362 					openEditor(segs[2], segs[4]);
   442 					openEditor(segs[2], segs[4]);
   363 				}
   443 				}
   364 			}
   444 			}
   365 		}
   445 		}
   366 
   446 
   367 		public void mouseDown(MouseEvent e) {
   447 		public void mouseDown(MouseEvent e) {
   368 			//do nothing by design
   448 			// do nothing by design
   369 		}
   449 		}
   370 
   450 
   371 		public void mouseUp(MouseEvent e) {
   451 		public void mouseUp(MouseEvent e) {
   372 			//do nothing by design
   452 			// do nothing by design
   373 		}
   453 		}
   374 	}
   454 	}
   375 	
   455 
   376 	
       
   377 	/**
   456 	/**
   378 	 * Pinpoints one memory address to source code line.
   457 	 * Pinpoints one memory address to source code line.
   379 	 *
   458 	 * 
   380 	 * @param memoryAddress
   459 	 * @param memoryAddress
   381 	 *            Memory address
   460 	 *            Memory address
   382 	 * @param dllLoad
   461 	 * @param dllLoad
   383 	 *           DllLoad item
   462 	 *            DllLoad item
   384 	 * @return SourceFile if found otherwise null
   463 	 * @return SourceFile if found otherwise null
   385 	 */
   464 	 */
   386 	private SourceFile pinpoint(Long memoryAddress, DllLoad dllLoad) {
   465 	private SourceFile pinpoint(Long memoryAddress, DllLoad dllLoad) {
   387 
   466 
   388 		if (dllLoad != null) {
   467 		if (dllLoad != null) {
   389 
   468 
   390 			ISymbolFile symbolFile = iSymReader.getSymbolFile(dllLoad.getName(),
   469 			ISymbolFile symbolFile = iSymReader.getSymbolFile(
   391 					false);
   470 					dllLoad.getName(), false);
   392 			if( symbolFile != null ) {
   471 			if (symbolFile != null) {
   393 				return pinpointToSrcLine(symbolFile, memoryAddress, dllLoad);
   472 				return pinpointToSrcLine(symbolFile, memoryAddress, dllLoad);
   394 			}
   473 			}
   395 		}
   474 		}
   396 		return null;
   475 		return null;
   397 	}
   476 	}
   398 	
   477 
   399 	/**
   478 	/**
   400 	 * Pinpoints memory address to source code line
   479 	 * Pinpoints memory address to source code line
   401 	 *
   480 	 * 
   402 	 * @param symbolFile
   481 	 * @param symbolFile
   403 	 *            Opened symbol file
   482 	 *            Opened symbol file
   404 	 * @param memoryAddress
   483 	 * @param memoryAddress
   405 	 *            Used memory address
   484 	 *            Used memory address
   406 	 * @param dllLoad
   485 	 * @param dllLoad
   424 			} else {
   503 			} else {
   425 				defaultLinkAddress = -4096L;
   504 				defaultLinkAddress = -4096L;
   426 			}
   505 			}
   427 
   506 
   428 			// calculate memory address in symbol file
   507 			// calculate memory address in symbol file
   429 			long calculated = (memoryAddress - dllLoad.getStartAddress()) + defaultLinkAddress;
   508 			long calculated = (memoryAddress - dllLoad.getStartAddress())
       
   509 					+ defaultLinkAddress;
   430 
   510 
   431 			java.math.BigInteger bigAddress = new java.math.BigInteger(Long
   511 			java.math.BigInteger bigAddress = new java.math.BigInteger(Long
   432 					.toHexString(calculated), 16);
   512 					.toHexString(calculated), 16);
   433 			IFunction func = symbolFile.findFunctionByAddress(bigAddress);
   513 			IFunction func = symbolFile.findFunctionByAddress(bigAddress);
   434 			ISourceLocation loc = symbolFile.findSourceLocation(bigAddress);
   514 			ISourceLocation loc = symbolFile.findSourceLocation(bigAddress);
   435 			if (func != null && loc != null) {
   515 			if (func != null && loc != null) {
   436 				String sourceFile = loc.getSourceFile();
   516 				String sourceFile = loc.getSourceFile();
   437 				if (sourceFile == null
   517 				if (sourceFile == null || sourceFile.equalsIgnoreCase("")) //$NON-NLS-1$
   438 						|| sourceFile.equalsIgnoreCase("")) //$NON-NLS-1$
       
   439 					return null;
   518 					return null;
   440 				int lineNumber = loc.getLineNumber();
   519 				int lineNumber = loc.getLineNumber();
   441 				if (lineNumber == 0)
   520 				if (lineNumber == 0)
   442 					return null;
   521 					return null;
   443 				String name = func.getName();
   522 				String name = func.getName();
   444 				if (name == null
   523 				if (name == null || name.equalsIgnoreCase("")) //$NON-NLS-1$
   445 						|| name.equalsIgnoreCase("")) //$NON-NLS-1$
       
   446 					return null;
   524 					return null;
   447 				/*
   525 				/*
   448 				 * if( onlyForProjectFiles &&
   526 				 * if( onlyForProjectFiles &&
   449 				 * !isFilePartOfTheProject(loc.getSourceFile()) ) return null;
   527 				 * !isFilePartOfTheProject(loc.getSourceFile()) ) return null;
   450 				 */
   528 				 */
   452 				file.setFileName(sourceFile);
   530 				file.setFileName(sourceFile);
   453 				file.setLineNumber(lineNumber);
   531 				file.setLineNumber(lineNumber);
   454 				file.setFunctionName(name);
   532 				file.setFunctionName(name);
   455 				return file;
   533 				return file;
   456 			}
   534 			}
   457 
       
   458 		} catch (java.lang.NumberFormatException nfe) {
   535 		} catch (java.lang.NumberFormatException nfe) {
   459 			// do nothing by design
   536 			// do nothing by design
   460 			nfe.printStackTrace();
   537 			nfe.printStackTrace();
   461 		} catch (Exception e) {
   538 		} catch (Exception e) {
   462 			// do nothing by design
   539 			// do nothing by design
   463 			e.printStackTrace();
   540 			e.printStackTrace();
   464 		}
   541 		}
   465 
       
   466 		return null;
   542 		return null;
   467 	}
   543 	}
   468 	
   544 
   469 	
       
   470 	/**
   545 	/**
   471 	 * Opens current callstack item on default editor and pinpoints memory leak
   546 	 * Opens current callstack item on default editor and pinpoints memory leak
   472 	 * line
   547 	 * line
   473 	 *
   548 	 * 
   474 	 * @param cppFileName
   549 	 * @param cppFileName
   475 	 *            Cpp file name
   550 	 *            Cpp file name
   476 	 * @param lineNumber
   551 	 * @param lineNumber
   477 	 *            Cpp file line number
   552 	 *            Cpp file line number
   478 	 */
   553 	 */
   479 	private void openEditor(String cppFileName, String lineNumber) {
   554 	private void openEditor(String cppFileName, String lineNumber) {
   480 
   555 
   481 		//check that used information is given
   556 		// check that used information is given
   482 		//we need to know file name and file line number
   557 		// we need to know file name and file line number
   483 		//that we could open the right line in editor
   558 		// that we could open the right line in editor
   484 		if (cppFileName == null || ("").equals(cppFileName) //$NON-NLS-1$
   559 		if (cppFileName == null || ("").equals(cppFileName) //$NON-NLS-1$
   485 				|| lineNumber == null || ("").equals(lineNumber)) { //$NON-NLS-1$
   560 				|| lineNumber == null || ("").equals(lineNumber)) { //$NON-NLS-1$
   486 			return;
   561 			return;
   487 		}
   562 		}
   488 		try {
   563 		try {
   489 
       
   490 			IFile file = null;
   564 			IFile file = null;
   491 			String usedFileName = null;
   565 			String usedFileName = null;
   492 			usedFileName = getFileNames(cppFileName);
   566 			usedFileName = getFileNames(cppFileName);
   493 			if (iCurrentProject.isOpen()) {
   567 			if (iCurrentProject.isOpen()) {
   494 				file = ResourcesPlugin.getWorkspace().getRoot().getFile(
   568 				file = ResourcesPlugin.getWorkspace().getRoot().getFile(
   509 					// file found => skip the rest of the projects
   583 					// file found => skip the rest of the projects
   510 					if (file != null && file.exists()) {
   584 					if (file != null && file.exists()) {
   511 						break;
   585 						break;
   512 					}
   586 					}
   513 				}
   587 				}
   514 
       
   515 			}
   588 			}
   516 
   589 
   517 			// if file still not found
   590 			// if file still not found
   518 			// display info to user and leave
   591 			// display info to user and leave
   519 			if (file == null || !file.exists()) {
   592 			if (file == null || !file.exists()) {
   541 			ce.printStackTrace();
   614 			ce.printStackTrace();
   542 		} catch (Exception e) {
   615 		} catch (Exception e) {
   543 			e.printStackTrace();
   616 			e.printStackTrace();
   544 		}
   617 		}
   545 	}
   618 	}
   546 	
   619 
   547 	/**
   620 	/**
   548 	 * Find symbol reader api pinpointed class file for project class files.
   621 	 * Find symbol reader api pinpointed class file for project class files.
   549 	 *
   622 	 * 
   550 	 * @param fileName
   623 	 * @param fileName
   551 	 *            Cpp file name
   624 	 *            cpp file name
   552 	 * @return Found cpp file location
   625 	 * @return found cpp file location
   553 	 */
   626 	 */
   554 	private String getFileNames(String fileName) {
   627 	private String getFileNames(String fileName) {
   555 		int slash = Util.getLastSlashIndex(fileName);
   628 		int slash = Util.getLastSlashIndex(fileName);
   556 		String tempFile = fileName.substring(slash + 1, fileName.length());
   629 		String tempFile = fileName.substring(slash + 1, fileName.length());
   557 
   630 
   558 		String realFileName = fileName;
   631 		String realFileName = fileName;
   559 		for(String tempFileName : cppFileNames){
   632 		for (String tempFileName : cppFileNames) {
   560 			int slashTemp = Util.getLastSlashIndex(tempFileName);
   633 			int slashTemp = Util.getLastSlashIndex(tempFileName);
   561 			String tempFileWithoutExt = tempFileName.substring(slashTemp + 1,
   634 			String tempFileWithoutExt = tempFileName.substring(slashTemp + 1,
   562 					tempFileName.length());
   635 					tempFileName.length());
   563 			if (tempFileWithoutExt.equalsIgnoreCase(tempFile)) {
   636 			if (tempFileWithoutExt.equalsIgnoreCase(tempFile)) {
   564 				realFileName = tempFileName;
   637 				realFileName = tempFileName;
   565 				break;
   638 				break;
   566 			}
   639 			}
   567 		}
   640 		}
   568 
       
   569 		return realFileName;
   641 		return realFileName;
   570 	}
   642 	}
   571 }
   643 }