srcanaapps/depexplorer/com.nokia.s60tools.appdep/src/com/nokia/s60tools/appdep/ui/views/main/MainViewSelectionChangedListener.java
changeset 0 a02c979e8dfd
equal deleted inserted replaced
-1:000000000000 0:a02c979e8dfd
       
     1 /*
       
     2 * Copyright (c) 2006 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 */
       
    17  
       
    18  
       
    19 package com.nokia.s60tools.appdep.ui.views.main;
       
    20 
       
    21 import java.io.FileNotFoundException;
       
    22 import java.io.IOException;
       
    23 import java.util.ArrayList;
       
    24 import java.util.NoSuchElementException;
       
    25 
       
    26 import org.eclipse.jface.viewers.ISelectionChangedListener;
       
    27 import org.eclipse.jface.viewers.SelectionChangedEvent;
       
    28 
       
    29 import com.nokia.s60tools.appdep.core.AppDepSettings;
       
    30 import com.nokia.s60tools.appdep.core.ITargetPlatform;
       
    31 import com.nokia.s60tools.appdep.core.data.CacheDataConstants;
       
    32 import com.nokia.s60tools.appdep.core.data.ComponentLinkLeafNode;
       
    33 import com.nokia.s60tools.appdep.core.data.ComponentNode;
       
    34 import com.nokia.s60tools.appdep.core.data.ComponentParentNode;
       
    35 import com.nokia.s60tools.appdep.core.model.ComponentPropertiesData;
       
    36 import com.nokia.s60tools.appdep.core.model.ExportFunctionData;
       
    37 import com.nokia.s60tools.appdep.core.model.ImportFunctionData;
       
    38 import com.nokia.s60tools.appdep.exceptions.CacheFileDoesNotExistException;
       
    39 import com.nokia.s60tools.appdep.exceptions.CacheIndexNotReadyException;
       
    40 import com.nokia.s60tools.appdep.resources.Messages;
       
    41 import com.nokia.s60tools.sdk.SdkInformation;
       
    42 
       
    43 /**
       
    44  * Selection change listener for main view.
       
    45  */
       
    46 public class MainViewSelectionChangedListener implements
       
    47 		ISelectionChangedListener {
       
    48 
       
    49 	//
       
    50 	// Members
       
    51 	//
       
    52 	private final MainView view;
       
    53 	private final ArrayList<ImportFunctionData> importFunctionsArrayList;
       
    54 	private final ArrayList<ExportFunctionData> exportFunctionsArrayList;
       
    55 	private boolean propertiesFoundSuccessfully;
       
    56 	
       
    57 	/**
       
    58 	 * Default constructor.
       
    59 	 * @param view Reference to main view
       
    60 	 * @param importFunctionsArrayList Import function list to be updated on selection.
       
    61 	 * @param exportFunctionsArrayList Export function list to be updated on selection.
       
    62 	 */
       
    63 	public MainViewSelectionChangedListener(MainView view, 
       
    64 										    ArrayList<ImportFunctionData> importFunctionsArrayList,
       
    65 										    ArrayList<ExportFunctionData> exportFunctionsArrayList){
       
    66 		this.view = view;
       
    67 		this.importFunctionsArrayList = importFunctionsArrayList;
       
    68 		this.exportFunctionsArrayList = exportFunctionsArrayList;
       
    69 	}
       
    70 	
       
    71 	/* (non-Javadoc)
       
    72 	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
       
    73 	 */
       
    74 	public void selectionChanged(SelectionChangedEvent event) {
       
    75 		try {			
       
    76 			
       
    77 			Object obj = view.getComponentTreeSelectedElement();
       
    78 			
       
    79 			// By default component properties data reference
       
    80 			// is set to null
       
    81 			view.setSelectedComponentPropertiesData(null);
       
    82 						
       
    83 			if(obj == null){
       
    84 				// We might get null-selections when
       
    85 				// tree is expanded/collapsed.
       
    86 				return;
       
    87 			}
       
    88 			else{
       
    89 				// Storing the selection for further reference in case 
       
    90 				// selection is lost because of the user decides
       
    91 				// to use 'Go Into' functionality which loses the selection.
       
    92 				view.setMostRecentlySelectedComponentNode(obj);
       
    93 			}
       
    94 						
       
    95 			// The object is for sure an instance of ComponentNode
       
    96 			ComponentNode node = (ComponentNode) obj;
       
    97 			// Storing name of the selected component (that might be name of the concrete component replacing generic one).
       
    98 			String selectedComponentName = node.getName();
       
    99 			// Component node instance which is selected or selected leaf node refers to
       
   100 			ComponentParentNode componentNodeInstance;
       
   101 			// Storing original component name in here, if we are replacing a generic component
       
   102 			String selectedComponentOriginalName;
       
   103 			if(node instanceof ComponentParentNode){
       
   104 				componentNodeInstance = (ComponentParentNode)node;
       
   105 			}
       
   106 			else{
       
   107 				// We have leaf node 
       
   108 				ComponentLinkLeafNode leafNode = (ComponentLinkLeafNode)node;
       
   109 				// Getting referred component
       
   110 				componentNodeInstance = leafNode.getReferredComponent();
       
   111 			}
       
   112 			// Storing name of the original component if needed
       
   113 			if(componentNodeInstance.wasGenericComponent()){
       
   114 				selectedComponentOriginalName = componentNodeInstance.getOriginalName();	
       
   115 			}else{
       
   116 				// No concrete component replacement done and therefore selected component is the original one.
       
   117 				selectedComponentOriginalName = selectedComponentName;		
       
   118 			}
       
   119 			
       
   120 			String parentComponentName = node.getParent().getName();
       
   121 			
       
   122 			AppDepSettings st = AppDepSettings.getActiveSettings();
       
   123 			SdkInformation sdkInfo = st.getCurrentlyUsedSdk();
       
   124 
       
   125 			//Updating tool bar text if the view is fully populated
       
   126 			// i.e. dependency search is finished.
       
   127 			if(!MainView.isDependencySearchOngoing()){
       
   128 				String descr = null;
       
   129 				if(sdkInfo != null){
       
   130 					descr = 
       
   131 							Messages.getString("MainViewSelectionChangedListener.SDK_Prefix") //$NON-NLS-1$
       
   132 							+ sdkInfo.getSdkId()
       
   133 							+ " - " //$NON-NLS-1$
       
   134 							+  st.getCurrentlyUsedTargetPlatformsAsString()
       
   135 							+ " " //$NON-NLS-1$
       
   136 							+  st.getBuildType().getBuildTypeDescription()
       
   137 							+ Messages.getString("MainViewSelectionChangedListener.Component_Prefix") //$NON-NLS-1$
       
   138 							+ node.getFullName();
       
   139 							
       
   140 					view.updateDescription(descr);
       
   141 				}
       
   142 			}
       
   143 			
       
   144 			// Fetching property information for the selected component
       
   145 			//For properties, cannot use selectedComponentName, because it may point to generic component
       
   146 			propertiesFoundSuccessfully = updateComponentPropertyInformation(selectedComponentName, st.getCurrentlyAnalyzedComponentTargetPlatform());
       
   147 			
       
   148 			// Clearing old information for imported functions
       
   149 			importFunctionsArrayList.clear();
       
   150 			// and also for exported ones
       
   151 			exportFunctionsArrayList.clear();
       
   152 
       
   153 			// Is currently used SDK configured?
       
   154 			if(sdkInfo != null){
       
   155 				// Export functions array list can be populated
       
   156 				// if component is not an EXE file, because there
       
   157 				// might exist EXE and DLL files with the same name,
       
   158 				// and the export function information is only available
       
   159 				// for DLLs. If EXE files were passed further, it would
       
   160 				// give the information for the DLL with the same name.
       
   161 				if(! isExeFile(selectedComponentName)){
       
   162 					// For exported functions using always concrete component if available
       
   163 					updateExportFunctionsArray(selectedComponentName);
       
   164 				}				
       
   165 			}
       
   166 			
       
   167 			// Checking if root component has been selected
       
   168 			ComponentParentNode pNode = null;
       
   169 			if(obj instanceof ComponentParentNode){
       
   170 				pNode = (ComponentParentNode) obj;
       
   171 				if(pNode.isRootComponent()){
       
   172 					// Disabling action that are not valid for root component
       
   173 					view.disableSetAsNewRootAction();
       
   174 					// The showing of parent import functions
       
   175 					// is not applicable for the root component
       
   176 					// Just refreshing view when old imported
       
   177 					// functions information has been cleared.
       
   178 					refreshMainView();
       
   179 					return;
       
   180 				}
       
   181 			}
       
   182 			else if(obj instanceof ComponentLinkLeafNode){
       
   183 				ComponentLinkLeafNode linkNode = (ComponentLinkLeafNode) obj;
       
   184 				pNode = linkNode.getReferredComponent();
       
   185 			}
       
   186 
       
   187 			// Also link node can refer to root component
       
   188 			if(pNode.isMissing() || pNode.isRootComponent()){
       
   189 				view.disableSetAsNewRootAction();							
       
   190 				view.enableLocateComponentAction();
       
   191 			}
       
   192 			else{
       
   193 				view.enableSetAsNewRootAction();
       
   194 				view.disableLocateComponentAction();
       
   195 			}
       
   196 			
       
   197 			// Import functions can be fetched selected node is not root component
       
   198 			updateImportFunctionsArray(selectedComponentOriginalName, parentComponentName);
       
   199 			
       
   200 			// Checks if there are unresolved import function names and if those can be fetched from export function data
       
   201 			checkForUnresolvedImportFunctionNames();
       
   202 			
       
   203 			// Finally asking from main view that content providers gets updated data for showing.
       
   204 			refreshMainView();
       
   205 		}
       
   206 		catch (CacheIndexNotReadyException e) {
       
   207 			//
       
   208 			// This may happen when no SDK selection has been made and therefore
       
   209 			// no cache indexes has been created.
       
   210 			// There is only single node in tree view with help text available
       
   211 			// for selection that for sure raises this exception.
       
   212 			//
       
   213 			// => can be ignored safely
       
   214 			//
       
   215 		}
       
   216 		catch (Exception e) {
       
   217 			e.printStackTrace();
       
   218 		}
       
   219 
       
   220 	}
       
   221 
       
   222 	/**
       
   223 	 * Checks if there are unresolved import function names and if those can be fetched from export function data.
       
   224 	 * This method does not have any effects if there are no unresolved imported functions, and if there are no
       
   225 	 * exported function data available.
       
   226 	 * @precondition if there are unresolved imported function names, there has to be valid exported functions data 
       
   227 	 *               available for successful operation.
       
   228 	 * @postcondition names of unresolved imported function names in <code>importFunctionsArrayList</code> are replaced 
       
   229 	 *                by function names got from <code>exportFunctionsArrayList</code>.
       
   230 	 */
       
   231 	private void checkForUnresolvedImportFunctionNames() {
       
   232 		// In case there is no exported data available, there is no use to continue the checking
       
   233 		if(exportFunctionsArrayList.size() == 0) return;
       
   234 		
       
   235 		// Otherwise checking imported functions array for unresolved function names
       
   236 		for (int i = 0; i < importFunctionsArrayList.size(); i++) {
       
   237 			ImportFunctionData importFunc = importFunctionsArrayList.get(i);
       
   238 			if(importFunc.getFunctionName().endsWith(CacheDataConstants.FUNC_NAME_NOT_RESOLVED)){
       
   239 				String funcName = getFuncNameFromExportedFunctions(importFunc.getFunctionOrdinalAsInt()); 
       
   240 				if(funcName !=  null){
       
   241 					importFunc.setFunctionName(funcName);
       
   242 				}
       
   243 			}
       
   244 		}
       
   245 	}
       
   246 
       
   247 	/**
       
   248 	 * Gets function name from exported function array list with given ordinal. 
       
   249 	 * @param ordinal function ordinal to get name for.
       
   250 	 * @return Function name or <code>null</code> if cannot be resolved.
       
   251 	 */
       
   252 	private String getFuncNameFromExportedFunctions(int ordinal) {
       
   253 		// If we have valid ordinal that exists also in exported functions data...
       
   254 		if(ordinal > 0 && ordinal <= exportFunctionsArrayList.size()){
       
   255 			//...returning the function name for it
       
   256 			return exportFunctionsArrayList.get(ordinal-1).getFunctionName();
       
   257 		}
       
   258 		//  Could not found match from exported function data 
       
   259 		return null;
       
   260 	}
       
   261 
       
   262 	/**
       
   263 	 * Checks is given file name has EXE extension, or not.
       
   264 	 * @param fileNameStr File name to be checked for.
       
   265 	 * @return Returns <code>true</code> if file has EXE extension, 
       
   266 	 *         otherwise <code>false</code>.
       
   267 	 */
       
   268 	private boolean isExeFile(String fileNameStr) {
       
   269 		int extIndex = fileNameStr.lastIndexOf("."); //$NON-NLS-1$
       
   270 		if(extIndex != -1){
       
   271 			String extStr = fileNameStr.substring(extIndex+1, fileNameStr.length());
       
   272 			if(extStr.equalsIgnoreCase("EXE")){ //$NON-NLS-1$
       
   273 				return true;
       
   274 			}
       
   275 		}
       
   276 		return false;
       
   277 	}
       
   278 
       
   279 	/**
       
   280 	 * Performs refresh and other operation needed to
       
   281 	 * run after refresh. 
       
   282 	 */
       
   283 	private void refreshMainView() {
       
   284 		view.refresh();
       
   285 		if(propertiesFoundSuccessfully){
       
   286 			// This resizes value column which enables the seeing
       
   287 			// of all the capabilities defined for the component.
       
   288 			view.performValueColumnPackToPropertiesTab();			
       
   289 		}
       
   290 	}
       
   291 
       
   292 	/**
       
   293 	 * Updates importFunctionsArrayList with information that was found
       
   294 	 * for the selected component.
       
   295 	 * @param selectedComponentName Name of the component that has been selected.
       
   296 	 * @param parentComponentName Parent component of the selected component.
       
   297 	 * @throws FileNotFoundException
       
   298 	 * @throws IOException
       
   299 	 * @throws CacheIndexNotReadyException
       
   300 	 * @throws CacheFileDoesNotExistException 
       
   301 	 */
       
   302 	private void updateImportFunctionsArray(String selectedComponentName, String parentComponentName) throws FileNotFoundException, IOException, CacheIndexNotReadyException, CacheFileDoesNotExistException {
       
   303 		
       
   304 		importFunctionsArrayList.clear(); // Making sure that array is cleared
       
   305 		try {
       
   306 			// Non-root component => seeking for the parent imported functions
       
   307 			importFunctionsArrayList.addAll(
       
   308 											MainViewDataPopulator.getParentImportedFunctionsForComponent(
       
   309 																	parentComponentName,
       
   310 																	selectedComponentName)
       
   311 											);												             												
       
   312 		} catch (Exception e) {
       
   313 			// Catching exceptions here, because throwing them upper level would prevent fetching of component properties.
       
   314 			e.printStackTrace();
       
   315 		}
       
   316 	}
       
   317 
       
   318 	/**
       
   319 	 * Updates property information for the currently
       
   320 	 * selected component.
       
   321 	 * @param selectedComponentName Name of the component that has been selected.
       
   322 	 * @param targetPlatform Target platform restriction, or <code>null</code> if target platform does not matter.
       
   323 	 * @return Returns <code>true</code> of component properties was found successfully, 
       
   324 	 *         otherwise returns <code>false</code>.
       
   325 	 * @throws IOException
       
   326 	 * @throws CacheIndexNotReadyException
       
   327 	 */
       
   328 	private boolean updateComponentPropertyInformation(String selectedComponentName, ITargetPlatform targetPlatform) throws IOException, CacheIndexNotReadyException {
       
   329 		
       
   330 		boolean propertiesFound = false;
       
   331 		
       
   332 		try {
       
   333 			
       
   334 			ComponentPropertiesData comPropData = MainViewDataPopulator
       
   335 														.getComponentPropertyArrayForComponent(selectedComponentName, targetPlatform);
       
   336 			propertiesFound = true;
       
   337 			view.setSelectedComponentPropertiesData(comPropData);
       
   338 		} catch (NoSuchElementException e1) {
       
   339 			// This can be ignored because there may be components 
       
   340 			// that does not exist in cache at all
       
   341 		} catch (java.lang.NullPointerException e1) {
       
   342 			// This can be ignored because we'll get this if
       
   343 			// currently used SDK is not yet configured and we
       
   344 			// select the root node that just advices the user
       
   345 			// to double-click the root node.
       
   346 		} catch (CacheFileDoesNotExistException e2) {
       
   347 			// This might happen during dialog to view transitions
       
   348 			// When cache file does not exist yet.
       
   349 		} catch (Exception e3) {
       
   350 			e3.printStackTrace();
       
   351 		}
       
   352 		return propertiesFound;
       
   353 	}
       
   354 
       
   355 	/**
       
   356 	 * Updates exportFunctionsArrayList with information that was found
       
   357 	 * for the selected component.
       
   358 	 * @param selectedComponentName Name of the component that has been selected.
       
   359 	 * @throws FileNotFoundException
       
   360 	 * @throws IOException
       
   361 	 * @throws CacheIndexNotReadyException
       
   362 	 * @throws CacheFileDoesNotExistException 
       
   363 	 */
       
   364 	private void updateExportFunctionsArray(String selectedComponentName) throws FileNotFoundException, IOException, CacheIndexNotReadyException, CacheFileDoesNotExistException {
       
   365 
       
   366 		try {
       
   367 			exportFunctionsArrayList.clear(); // Making sure that earlier results are destroyed
       
   368 			// Populating with new data
       
   369 			exportFunctionsArrayList.addAll(MainViewDataPopulator.getExportedFunctionsForComponent(selectedComponentName));
       
   370 
       
   371 		} catch (NoSuchElementException e) {
       
   372 			// The selected component does necessary
       
   373 			// have any data about exported functions.
       
   374 			// Therefore we can ignore this exception
       
   375 		} catch (Exception e) {
       
   376 			e.printStackTrace();
       
   377 		}
       
   378 	}	
       
   379 	
       
   380 }