imakerplugin/com.nokia.s60tools.imaker/src/com/nokia/s60tools/imaker/internal/wrapper/IMakerWrapper.java
changeset 0 61163b28edca
child 1 7ff23301fe22
equal deleted inserted replaced
-1:000000000000 0:61163b28edca
       
     1 /*
       
     2 * Copyright (c) 2009 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.imaker.internal.wrapper;
       
    20 
       
    21 
       
    22 import java.io.File;
       
    23 import java.io.IOException;
       
    24 import java.io.OutputStream;
       
    25 import java.io.PipedInputStream;
       
    26 import java.io.PipedOutputStream;
       
    27 import java.util.ArrayList;
       
    28 import java.util.Iterator;
       
    29 import java.util.List;
       
    30 import java.util.Map;
       
    31 import java.util.regex.Matcher;
       
    32 import java.util.regex.Pattern;
       
    33 
       
    34 import org.eclipse.core.runtime.IProgressMonitor;
       
    35 import org.eclipse.core.runtime.IStatus;
       
    36 import org.eclipse.core.runtime.Status;
       
    37 
       
    38 import com.nokia.s60tools.imaker.IIMakerWrapper;
       
    39 import com.nokia.s60tools.imaker.IMakerPlugin;
       
    40 import com.nokia.s60tools.imaker.IMakerUtils;
       
    41 import com.nokia.s60tools.imaker.Messages;
       
    42 import com.nokia.s60tools.imaker.UIConfiguration;
       
    43 import com.nokia.s60tools.imaker.exceptions.IMakerCoreAlreadyRunningException;
       
    44 import com.nokia.s60tools.imaker.exceptions.IMakerCoreCancelledException;
       
    45 import com.nokia.s60tools.imaker.exceptions.IMakerCoreExecutionException;
       
    46 import com.nokia.s60tools.imaker.exceptions.IMakerCoreNotFoundException;
       
    47 import com.nokia.s60tools.imaker.internal.iqrf.Configuration;
       
    48 import com.nokia.s60tools.imaker.internal.iqrf.ConfigurationElement;
       
    49 import com.nokia.s60tools.imaker.internal.iqrf.IMaker;
       
    50 import com.nokia.s60tools.imaker.internal.iqrf.IQRFFactory;
       
    51 import com.nokia.s60tools.imaker.internal.iqrf.Interface;
       
    52 import com.nokia.s60tools.imaker.internal.iqrf.Result;
       
    53 import com.nokia.s60tools.imaker.internal.iqrf.Setting;
       
    54 import com.nokia.s60tools.imaker.internal.iqrf.Target;
       
    55 import com.nokia.s60tools.imaker.internal.iqrf.wrapper.IQRFWrapper;
       
    56 
       
    57 /**
       
    58  * This class implements the IIMakerWrapper interface which is used
       
    59  * to interface with iMaker core.
       
    60  * 
       
    61  * @version 1.0
       
    62  */
       
    63 public class IMakerWrapper implements IIMakerWrapper {
       
    64 	/** Shared singleton instance */
       
    65 //	private static IIMakerWrapper instance;
       
    66 
       
    67 	/** Public instance variables */
       
    68 	public PipedOutputStream pos = null;
       
    69 	public PipedInputStream pis = null;
       
    70 
       
    71 	/** Public instance variables */
       
    72 	private Boolean builderRunning = false;
       
    73 	private List<String> params = null;
       
    74 	private IProgressMonitor monitor = null;
       
    75 	private int exitValue = 0;
       
    76 	private boolean runVerdict;
       
    77 	private String dProduct = null;
       
    78 //	private String dTarget = null;
       
    79 	private Pattern blockBegin = Pattern.compile("-{30,}");
       
    80 
       
    81 	private OutputStream outputStream;
       
    82 	private List<String> tool;
       
    83 	private IMakerCoreExecutionException lastImakerException;
       
    84 
       
    85 	/**
       
    86 	 * Default constructor
       
    87 	 */
       
    88 	public IMakerWrapper(List<String> tool) {
       
    89 		params = new ArrayList<String>();
       
    90 		this.tool = tool;
       
    91 		this.lastImakerException = new IMakerCoreExecutionException("No configurations loaded!");
       
    92 	}
       
    93 
       
    94 	public boolean isRunning() {
       
    95 		return builderRunning;
       
    96 	}
       
    97 
       
    98 	/* (non-Javadoc)
       
    99 	 * @see com.nokia.s60tools.imakerplugin.wrapper.IIMakerWrapper#getIMakerCoreVersion()
       
   100 	 */
       
   101 	public String getIMakerCoreVersion() throws IMakerCoreNotFoundException, IMakerCoreExecutionException {
       
   102 		verifyExists();
       
   103 		params.clear();
       
   104 		params.add(IMakerWrapperPreferences.CMD_FETCH_VERSION);
       
   105 		List<String> version = executeCommand(params);
       
   106 		String vers = "";
       
   107 		for (String line : version) {
       
   108 			if(line.startsWith("iMaker")) {
       
   109 				vers = line;
       
   110 				break;
       
   111 			}
       
   112 		}
       
   113 		return vers;
       
   114 	}
       
   115 
       
   116 	private void verifyExists() throws IMakerCoreNotFoundException {
       
   117 		if(!IMakerUtils.iMakerCoreExists(tool.get(0))) {
       
   118 			IMakerCoreNotFoundException e = new IMakerCoreNotFoundException();
       
   119 			String newMessage = e.getMessage() +" "+ Messages.getString("IMakerWrapper.27").replace("xxx", tool.get(0));
       
   120 			throw new IMakerCoreNotFoundException(newMessage);
       
   121 		}
       
   122 	}
       
   123 
       
   124 	/* (non-Javadoc)
       
   125 	 * @see com.nokia.s60tools.imakerplugin.wrapper.IIMakerWrapper#getConfigurations(java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
       
   126 	 */
       
   127 	public List<UIConfiguration> getConfigurations(IProgressMonitor monitor) 
       
   128 	throws IMakerCoreExecutionException, IMakerCoreNotFoundException {
       
   129 		this.monitor = monitor;
       
   130 		verifyExists();
       
   131 		List<UIConfiguration> configurations = getConfigurations((String)null);
       
   132 		return configurations;
       
   133 	}
       
   134 
       
   135 	private List<UIConfiguration> getConfigurations(String makefile) throws IMakerCoreExecutionException {
       
   136 		List<UIConfiguration> uiConfigs = new ArrayList<UIConfiguration>();
       
   137 		List<String> makeFiles=null;
       
   138 		if(makefile==null||makefile.equals("")) {
       
   139 			makeFiles = queryMakefiles();
       
   140 		} else {
       
   141 			makeFiles = new ArrayList<String>();
       
   142 			makeFiles.add(makefile);
       
   143 		}
       
   144 		
       
   145 		if (monitor != null) {
       
   146 			monitor.beginTask(Messages.getString("IMakerWrapper.3"), (makeFiles.size()*2));
       
   147 		}
       
   148 		loadDefaultData();
       
   149 		Result result = parseResult(makeFiles);
       
   150 		
       
   151 		// Get configurations out of the result object
       
   152 		Iterator<Configuration> configIter = result.getConfigurations().iterator();
       
   153 		while (configIter.hasNext()) {
       
   154 			Configuration item = configIter.next();
       
   155 			if(item.getTargetrefs().size()==0) continue;
       
   156 			uiConfigs.add(new UIConfiguration(item));
       
   157 		}
       
   158 		if(uiConfigs.isEmpty()) {
       
   159 			throw lastImakerException;
       
   160 		}
       
   161 		if (monitor != null) {
       
   162 			monitor.done();
       
   163 		}
       
   164 		if(dProduct!=null) {
       
   165 			for(UIConfiguration config: uiConfigs) {
       
   166 				String pname = config.getConfigurationName();
       
   167 				if(pname != null && pname.equals(dProduct)) {
       
   168 					config.setDefaultConfig(true);
       
   169 //					config.setDefaultTarget(dTarget);
       
   170 					break;
       
   171 				}
       
   172 			}			
       
   173 		}
       
   174 		return uiConfigs;
       
   175 	}
       
   176 
       
   177 	/**
       
   178 	 * fetches default configuration and target if given
       
   179 	 */
       
   180 	private void loadDefaultData() {
       
   181 		params.clear();
       
   182 		params.add(IMakerWrapperPreferences.DEFAULT_DATA);// + configPath
       
   183 		Pattern product = Pattern.compile("\\s*IMAKER_CONFMK.*image_conf_(.*)\\.mk.\\s*");
       
   184 //		Pattern target  = Pattern.compile("\\s*TARGET_DEFAULT\\s*=\\s*.(.*).\\s*");
       
   185 		try {
       
   186 			List<String> lines = executeCommand(params);
       
   187 			for (String line : lines) {
       
   188 				Matcher matcher = product.matcher(line);
       
   189 				if(matcher.matches()) {
       
   190 					String pr = matcher.group(1);
       
   191 					if(!pr.equals("")) {
       
   192 						dProduct = pr;
       
   193 						break;
       
   194 					}
       
   195 				}
       
   196 //				matcher = target.matcher(line);
       
   197 //				if(matcher.matches()) {
       
   198 //					String tr = matcher.group(1);
       
   199 //					if(!tr.equals("")) {
       
   200 //						dTarget = tr;
       
   201 //						System.out.println("default target = " + tr);
       
   202 //						continue;
       
   203 //					}
       
   204 //				}
       
   205 			}
       
   206 		} catch (IMakerCoreExecutionException e) {
       
   207 			e.printStackTrace();
       
   208 		}
       
   209 	}
       
   210 
       
   211 	private List<String> queryMakefiles() throws IMakerCoreExecutionException {
       
   212 		List<String> makeFiles;
       
   213 		params.clear();
       
   214 		params.add(IMakerWrapperPreferences.CMD_FETCH_CONFIGURATIONS);// + configPath
       
   215 		makeFiles = executeCommand(params);
       
   216 		
       
   217 		// Remove redundant lines of information from makeFile list
       
   218 		if ((makeFiles != null) && (makeFiles.size() > 0)) {
       
   219 			List<String> tmpMakeFiles = new ArrayList<String>();
       
   220 			
       
   221 			Iterator<String> iter = makeFiles.iterator();
       
   222 			while (iter.hasNext()) {
       
   223 				String makefile = iter.next().toLowerCase();
       
   224 				if (makefile.matches(
       
   225 						IMakerWrapperPreferences.MAKEFILE_LIST_PATTERN)) {
       
   226 					tmpMakeFiles.add(makefile);					
       
   227 				}
       
   228 			}
       
   229 			makeFiles = tmpMakeFiles;
       
   230 		}
       
   231 		return makeFiles;
       
   232 	}
       
   233 
       
   234 	public UIConfiguration getConfiguration(List<String> parameters,
       
   235 			IProgressMonitor mon) throws IMakerCoreExecutionException,
       
   236 			IMakerCoreNotFoundException {
       
   237 		this.monitor = mon;
       
   238 		verifyExists();
       
   239 		if(parameters==null||parameters.size()<2) {
       
   240 			return null;
       
   241 		}
       
   242 		if (monitor != null) {
       
   243 			monitor.beginTask(Messages.getString("IMakerWrapper.4"), 2); //$NON-NLS-1$
       
   244 		}
       
   245 		
       
   246 		params.clear();
       
   247 		params.add(parameters.remove(0));
       
   248 		params.add(IMakerWrapperPreferences.ARG_FETCH_CONFIGURATION);
       
   249 		String makefile = parameters.remove(0);
       
   250 		params.add(makefile);
       
   251 		params.add(IMakerWrapperPreferences.CMD_FETCH_CONFIGURATION);
       
   252 		params.addAll(parameters);
       
   253 		
       
   254 		builderRunning=true;
       
   255 		List<String> settingsList = executeCommand(params);
       
   256 		builderRunning=false;
       
   257 		
       
   258 		ArrayList<ConfigurationElement> elements = new ArrayList<ConfigurationElement>();
       
   259 		ArrayList<Setting> settings = new ArrayList<Setting>();
       
   260 		
       
   261 		parseConfigurations(settingsList, elements, settings);
       
   262 		
       
   263 		Configuration config = createConfiguration(makefile);
       
   264 		setUpConfiguration(config, settings);
       
   265 		
       
   266 		if (monitor != null) {
       
   267 			monitor.done();
       
   268 		}
       
   269 		return new UIConfiguration(config);
       
   270 	}
       
   271 	
       
   272 	/* (non-Javadoc)
       
   273 	 * @see com.nokia.s60tools.imakerplugin.wrapper.IIMakerWrapper#isBuilderRunning()
       
   274 	 */
       
   275 	public Boolean isBuilderRunning() {
       
   276 		return builderRunning;
       
   277 	}
       
   278 
       
   279 
       
   280 	/* (non-Javadoc)
       
   281 	 * @see com.nokia.s60tools.imakerplugin.wrapper.IIMakerWrapper#flashImage(java.util.List)
       
   282 	 */
       
   283 	public boolean flashImage(List<String> cmdParams) {
       
   284 		return false;
       
   285 	}
       
   286 
       
   287 	/* (non-Javadoc)
       
   288 	 * @see com.nokia.s60tools.imakerplugin.wrapper.IIMakerWrapper#buildImage(java.util.List)
       
   289 	 */
       
   290 	public boolean buildImage(List<String> cmdParams, OutputStream out) throws IMakerCoreExecutionException, 
       
   291 	IMakerCoreAlreadyRunningException, IMakerCoreNotFoundException {
       
   292 		this.outputStream = out;
       
   293 		verifyExists();
       
   294 		builderRunning = true;
       
   295 		List<String> ret = executeCommand(cmdParams);
       
   296 		builderRunning = false;
       
   297 		return getReturnStatus(ret);
       
   298 	}
       
   299 
       
   300 	private boolean getReturnStatus(List<String> ret) {
       
   301 		if(exitValue==0) {
       
   302 			//old imaker check output
       
   303 			try {
       
   304 				String vers = ret.get(0);
       
   305 				String verNumber = IMakerUtils.parseIMakerVersion(vers);
       
   306 				String versionNumber = verNumber;
       
   307 				String[] parts = versionNumber.split("\\.");
       
   308 				if(Integer.parseInt(parts[0])<=8&&Integer.parseInt(parts[1])<35&&Integer.parseInt(parts[2])<3) {
       
   309 					runVerdict = validateBuildResult(ret);
       
   310 				} else {
       
   311 					runVerdict = true;
       
   312 				}
       
   313 			} catch (Exception e) {
       
   314 				return runVerdict = true;
       
   315 			}
       
   316 			return runVerdict;
       
   317 		} else {
       
   318 			return (runVerdict=false);
       
   319 		}
       
   320 	}
       
   321 
       
   322 	/**
       
   323 	 * Method returns configuration information as an XMI document.
       
   324 	 * 
       
   325 	 * @return An XMI document describing configurations.
       
   326 	 * @throws IMakerCoreExecutionException 
       
   327 	 */
       
   328 	public String getConfigurationsAsXMI() throws IMakerCoreExecutionException {
       
   329 		// First create a result object and then use it to query
       
   330 		// the EMF for xmi document.
       
   331 
       
   332 		List<String> makeFiles = queryMakefiles();
       
   333 		Result result=null;
       
   334 		result = parseResult(makeFiles);
       
   335 
       
   336 		IMaker imaker = IQRFFactory.eINSTANCE.createIMaker();
       
   337 		imaker.setResult(result);
       
   338 		imaker.setQuery(IMakerWrapperPreferences.CMD_FETCH_CONFIGURATIONS);
       
   339 		IQRFWrapper wrapper = new IQRFWrapper();
       
   340 		String xmi = wrapper.getXMLDocument(imaker);
       
   341 		return xmi;
       
   342 	}
       
   343 
       
   344 	/**
       
   345 	 * Calls the iMaker on a command line and reads the output.
       
   346 	 * 
       
   347 	 * @param  cmd additional arguments to be passed to the iMaker core.
       
   348 	 * @return Output of iMaker as list of Strings.
       
   349 	 */
       
   350 	private List<String> executeCommand(List<String> params) throws IMakerCoreExecutionException {
       
   351 		List<String> cmd = prepareCommand(params);
       
   352 
       
   353 		// Try to start a process to execute iMaker
       
   354 		try {
       
   355 			// Finally build a new ProcessBuilder with cmds.
       
   356 			ProcessBuilder builder = new ProcessBuilder(cmd);
       
   357 			Map<String, String> environment = builder.environment();
       
   358 			environment.put(IMakerWrapperPreferences.IMAKER_EXITSHELL, "1");
       
   359 			// In windows environment, the working directory of
       
   360 			// ProcessBuilder must point to the drive/path where
       
   361 			// the imaker is run. Usually x:\
       
   362 			String com = cmd.get(0);
       
   363 			if (com.charAt(1) == IMakerWrapperPreferences.MAKEFILE_DRIVE_DESIGNATOR) {
       
   364 				String dir = com.substring(0, 2);
       
   365 				builder.directory(new File(dir));
       
   366 			}
       
   367 
       
   368 			builder.redirectErrorStream(true);
       
   369 			Process process = builder.start();
       
   370 
       
   371 			// Start reading the output
       
   372 			StreamGobbler gobbler = new StreamGobbler(process.getInputStream(), outputStream);
       
   373 			gobbler.start();
       
   374 			
       
   375 			ArrayList<String> output;
       
   376 			try {
       
   377 				exitValue = process.waitFor();
       
   378 				gobbler.join();
       
   379 				output = gobbler.getOutput();
       
   380 				exitValue  = process.exitValue();
       
   381 				if(exitValue!=0) {
       
   382 					StringBuilder error = new StringBuilder();
       
   383 //					for (String str : output) {
       
   384 //						error.append(str+"\n");
       
   385 //					}
       
   386 					
       
   387 					error.append(Messages.getString("IMakerWrapper.28") + " ");
       
   388 					for (String str : cmd) {
       
   389 						error.append(str+" ");
       
   390 					}
       
   391 					throw new IMakerCoreExecutionException(error.toString());
       
   392 				}
       
   393 				return output;
       
   394 			} catch (InterruptedException e) {
       
   395 				e.printStackTrace();
       
   396 			}
       
   397 		} catch (IOException ioe) {
       
   398 			throw new IMakerCoreExecutionException(ioe.getMessage());
       
   399 		}
       
   400 		throw new IMakerCoreExecutionException();
       
   401 	}
       
   402 
       
   403 	private List<String> prepareCommand(List<String> prm) {
       
   404 		List<String> cmd = new ArrayList<String>();
       
   405 		cmd.addAll(tool);
       
   406 		cmd.addAll(prm);
       
   407 		return cmd;
       
   408 	}
       
   409 
       
   410 	/**
       
   411 	 * Validates the output from iMaker to determine if the
       
   412 	 * operation was successful.
       
   413 	 * 
       
   414 	 * @param  out  output from the iMaker.
       
   415 	 * @return true if the iMaker exited successfully based
       
   416 	 *              on the output, otherwise false.
       
   417 	 */
       
   418 	private boolean validateBuildResult(List<String> out) {
       
   419 		if(out.size()>1) {
       
   420 			String last = out.get(out.size()-2) + out.get(out.size()-1);
       
   421 
       
   422 			if(last.indexOf(Messages.getString("IMakerWrapper.22"))>-1) {
       
   423 				return (runVerdict=true);
       
   424 			}
       
   425 			if (last.indexOf(Messages.getString("IMakerWrapper.7")) > -1) { //$NON-NLS-1$
       
   426 				return (runVerdict=false);
       
   427 			}
       
   428 			if (last.indexOf(Messages.getString("IMakerWrapper.8")) > -1) { //$NON-NLS-1$
       
   429 				return (runVerdict=false);
       
   430 			}
       
   431 		}
       
   432 		if(out.size()==1) {
       
   433 			String entry = out.get(0);
       
   434 			return (runVerdict=entry.startsWith(Messages.getString("IMakerWrapper.23")));
       
   435 		}
       
   436 		return (runVerdict=false);
       
   437 	}
       
   438 
       
   439 	public boolean getRunVerdict() {
       
   440 		return runVerdict;
       
   441 	}
       
   442 
       
   443 	/**
       
   444 	 * Parses ConfigurationElement and Setting objects from the output
       
   445 	 * of iMaker.
       
   446 	 * 
       
   447 	 * @param confData Lines of data to be parsed.
       
   448 	 * @param elements ConfigurationElement list where to store results
       
   449 	 * @param settings Setting list where to store results
       
   450 	 */
       
   451 	private void parseConfigurations(List<String> confData,
       
   452 			ArrayList<ConfigurationElement> elements,
       
   453 			ArrayList<Setting> settings) {
       
   454 
       
   455 		confData = clearResultList(confData);
       
   456 
       
   457 		String line                        = null;
       
   458 		Iterator<String> lineIter          = confData.iterator();
       
   459 		Pattern varValuePt                 = Pattern.compile(Messages.getString("IMakerWrapper.9")); //$NON-NLS-1$
       
   460 		Pattern varBodyPt                  = Pattern.compile(Messages.getString("IMakerWrapper.10")); //$NON-NLS-1$
       
   461 		Setting setting                    = null;
       
   462 		ConfigurationElement configElement = null;
       
   463 
       
   464 		String name = null;
       
   465 		String desc = null;
       
   466 		String values = null;
       
   467 		while (lineIter.hasNext()) {
       
   468 			line = lineIter.next();
       
   469 
       
   470 			if(blockBegin.matcher(line).matches()) {
       
   471 				setting       = IQRFFactory.eINSTANCE.createSetting();
       
   472 				configElement = IQRFFactory.eINSTANCE.createConfigurationElement();
       
   473 				name = lineIter.next();
       
   474 				lineIter.next(); // ignore type line
       
   475 				desc = lineIter.next();
       
   476 				values = lineIter.next();
       
   477 				Matcher matcher = varValuePt.matcher(name);
       
   478 				if(matcher.matches()) {
       
   479 					setting.setName(matcher.group(1));
       
   480 					configElement.setName(setting.getName());
       
   481 					setting.setValue(matcher.group(2));
       
   482 				}
       
   483 				matcher = varBodyPt.matcher(desc);
       
   484 				if(matcher.matches()) {
       
   485 					configElement.setDescription(matcher.group(2));
       
   486 				}
       
   487 				matcher = varBodyPt.matcher(values);
       
   488 				if(matcher.matches()) {
       
   489 					values = matcher.group(2);
       
   490 					values = values.replaceAll(Messages.getString("IMakerWrapper.12"), "");
       
   491 					values = values.replaceAll(Messages.getString("IMakerWrapper.14"), ""); //$NON-NLS-1$ //$NON-NLS-2$
       
   492 					configElement.setValues(values);
       
   493 				}
       
   494 				setting.setConfigurationElement(configElement);
       
   495 				settings.add(setting);
       
   496 				elements.add(configElement);				
       
   497 			}	
       
   498 		}
       
   499 	}
       
   500 
       
   501 	/**
       
   502 	 * Parses an interface object from a string.
       
   503 	 * 
       
   504 	 * @return An interface object.
       
   505 	 */
       
   506 	private Interface parseInterface() {
       
   507 		Interface intf = IQRFFactory.eINSTANCE.createInterface();
       
   508 		intf.setName(IMakerWrapperPreferences.INTERFACE_DEFAULT_NAME);
       
   509 		return intf;
       
   510 	}
       
   511 
       
   512 
       
   513 	/**
       
   514 	 * Parses targets from the output of iMaker.
       
   515 	 * 
       
   516 	 * @param targetStr Lines of data to be parsed.
       
   517 	 * @return List of parsed Target objects.
       
   518 	 */
       
   519 	private ArrayList<Target> parseTargets(List<String> targetStr) {
       
   520 
       
   521 		targetStr = clearResultList(targetStr);
       
   522 
       
   523 		String line               = null;
       
   524 		Iterator<String> lineIter = targetStr.iterator();
       
   525 		ArrayList<Target> targets = new ArrayList<Target>();
       
   526 		Pattern tgBodyPt          = Pattern.compile(Messages.getString("IMakerWrapper.16")); //$NON-NLS-1$
       
   527 		Matcher tgValueMt         = null;
       
   528 		Target target             = null;
       
   529 		
       
   530 		while ((lineIter != null) && lineIter.hasNext()) {
       
   531 			line = lineIter.next();
       
   532 			//new target
       
   533 			if(blockBegin.matcher(line).matches()) {
       
   534 				String name = lineIter.next();
       
   535 				target = IQRFFactory.eINSTANCE.createTarget();
       
   536 				target.setName(name.trim());				
       
   537 				//ignore type
       
   538 				lineIter.next();
       
   539 				
       
   540 				String desc = lineIter.next();
       
   541 				tgValueMt = tgBodyPt.matcher(desc);
       
   542 				if (tgValueMt.matches()) {
       
   543 					if (tgValueMt.group(1).toLowerCase().equals(
       
   544 							IMakerWrapperPreferences.TARGET_FIELD_DESCRIPTION)) {
       
   545 						target.setDescription(tgValueMt.group(2));
       
   546 					}
       
   547 				}
       
   548 				targets.add(target);
       
   549 			}
       
   550 		}
       
   551 		return targets;
       
   552 	}
       
   553 
       
   554 	/**
       
   555 	 * @param dirtyList
       
   556 	 * @return
       
   557 	 */
       
   558 	private ArrayList<String> clearResultList(List<String> dirtyList) {
       
   559 		ArrayList<String> cleanList = new ArrayList<String>();
       
   560 		Iterator<String> lineIter = dirtyList.iterator();
       
   561 		while(lineIter.hasNext()) {
       
   562 			String line = lineIter.next();
       
   563 			if(!line.startsWith(Messages.getString("IMakerWrapper.17"))  //$NON-NLS-1$
       
   564 					&& !line.startsWith(Messages.getString("IMakerWrapper.18"))  //$NON-NLS-1$
       
   565 					&& line.length() > 0 ) {
       
   566 				cleanList.add(line);
       
   567 			}
       
   568 		}
       
   569 		return cleanList;
       
   570 	}
       
   571 
       
   572 	/**
       
   573 	 * Finds a target in the list of targets given as a parameter.
       
   574 	 * 
       
   575 	 * @param targets A List of targets to search.
       
   576 	 * @param target  The target to search for.
       
   577 	 * @return The target found in the list or null if not found. 
       
   578 	 */
       
   579 	private Target findTarget(List<Target> targets, Target target) {
       
   580 		Target retTarget = null;
       
   581 		Iterator<Target> targetIter = targets.iterator();
       
   582 
       
   583 		while ((targetIter != null) && targetIter.hasNext()) {
       
   584 			Target tmp = targetIter.next();
       
   585 			if (tmp.getName().equals(target.getName())) {
       
   586 				retTarget = tmp;
       
   587 				break;
       
   588 			}
       
   589 		}
       
   590 		return retTarget;
       
   591 	}
       
   592 
       
   593 	/**
       
   594 	 * Parses a result object from a string.
       
   595 	 * 
       
   596 	 * @param configElements A list of configuration elements as strings.
       
   597 	 * @param makeFiles      A list of makefiles as strings.
       
   598 	 * @return A result object.
       
   599 	 * @throws IMakerCoreExecutionException 
       
   600 	 * @throws InterruptedException if the operation gets cancelled
       
   601 	 */
       
   602 	private Result parseResult(List<String> makeFiles) throws IMakerCoreExecutionException {
       
   603 		ArrayList<Target> targets = null;
       
   604 		Result result = IQRFFactory.eINSTANCE.createResult();
       
   605 
       
   606 		Interface intf = parseInterface();
       
   607 
       
   608 		// Process configurations/settings, targets and hwids
       
   609 		if ((makeFiles != null) && (makeFiles.size() > 0)) {
       
   610 			Iterator<String> iterConfigs = makeFiles.iterator();
       
   611 			while ((iterConfigs != null) && iterConfigs.hasNext()) {
       
   612 				// Get settings and targets for each configuration/makefile
       
   613 				// and first create a Configuration object.
       
   614 				String makeFile = iterConfigs.next();
       
   615 				Configuration config = createConfiguration(makeFile);
       
   616 				if (monitor != null) {
       
   617 					monitor.subTask(Messages.getString("IMakerWrapper.19")+": "+makeFile); //$NON-NLS-1$
       
   618 				}
       
   619 				params.clear();
       
   620 				params.add(IMakerWrapperPreferences.CMD_FETCH_TARGETS);
       
   621 				params.add(IMakerWrapperPreferences.ARG_FETCH_CONFIGURATION);
       
   622 				params.add(makeFile);
       
   623 				List<String> prodTargets; 
       
   624 				try {
       
   625 					prodTargets = executeCommand(params);
       
   626 				} catch (IMakerCoreExecutionException e) {
       
   627 					this.lastImakerException = e;
       
   628 					if(monitor != null) {
       
   629 						monitor.worked(1);
       
   630 					}
       
   631 					String message = "Error while fetching configurations. " +
       
   632 					e.getMessage();
       
   633 					IStatus status = new Status(IStatus.ERROR,
       
   634 							IMakerPlugin.getDefault().getBundle().getSymbolicName(),
       
   635 							IStatus.ERROR, message, e);
       
   636 					IMakerPlugin.getDefault().getLog().log(status);
       
   637 					continue;
       
   638 				}
       
   639 
       
   640 				ArrayList<Target> allTargets = new ArrayList<Target>();
       
   641 				targets = parseTargets(prodTargets);
       
   642 				Iterator<Target> targetIter = targets.iterator();
       
   643 				
       
   644 				while ((targetIter != null) && targetIter.hasNext()) {
       
   645 					Target target = targetIter.next();
       
   646 					Target found = findTarget(allTargets, target);
       
   647 					if (found == null) {
       
   648 						allTargets.add(target);
       
   649 						result.addTarget(target);
       
   650 						config.addTargetRef(target);
       
   651 					} else {
       
   652 						config.addTargetRef(found);
       
   653 					}
       
   654 				}
       
   655 				if (monitor != null) {
       
   656 					monitor.worked(1);
       
   657 					monitor.subTask(Messages.getString("IMakerWrapper.20")+": "+makeFile); //$NON-NLS-1$
       
   658 				}
       
   659 				params.set(0, IMakerWrapperPreferences.CMD_FETCH_CONFIGURATION);
       
   660 				List<String> settingsList;
       
   661 				try {
       
   662 					settingsList = executeCommand(params);
       
   663 				} catch (IMakerCoreExecutionException e) {
       
   664 					this.lastImakerException = e;
       
   665 					if(monitor != null) {
       
   666 						monitor.worked(1);
       
   667 					}
       
   668 					String message = "Error while fetching configurations. " +
       
   669 					e.getMessage();
       
   670 					IStatus status = new Status(IStatus.ERROR,
       
   671 							IMakerPlugin.getDefault().getBundle().getSymbolicName(),
       
   672 							IStatus.ERROR, message, e);
       
   673 					IMakerPlugin.getDefault().getLog().log(status);
       
   674 					continue;
       
   675 				}
       
   676 				
       
   677 				ArrayList<ConfigurationElement> elements = new ArrayList<ConfigurationElement>();
       
   678 				ArrayList<Setting> settings = new ArrayList<Setting>();
       
   679 
       
   680 				parseConfigurations(settingsList, elements, settings);
       
   681 
       
   682 				Iterator<ConfigurationElement> iterElem = elements.iterator();
       
   683 				while ((iterElem != null) && (iterElem.hasNext())) {
       
   684 					intf.addConfigurationElement(iterElem.next());
       
   685 				}
       
   686 				setUpConfiguration(config, settings);
       
   687 				result.addInterface(intf);
       
   688 				result.addConfiguration(config);
       
   689 				
       
   690 				if(monitor != null) {
       
   691 					monitor.worked(1);
       
   692 					if(monitor.isCanceled()) {
       
   693 						throw new IMakerCoreCancelledException("User cancellation!");
       
   694 					}
       
   695 				}
       
   696 			}
       
   697 		}
       
   698 		return result;
       
   699 	}
       
   700 
       
   701 	private void setUpConfiguration(Configuration config,
       
   702 			ArrayList<Setting> settings) {
       
   703 		// Go through settings and find hwid data
       
   704 		String[] hwids = null;
       
   705 		Iterator<Setting> iterSetting = settings.iterator();
       
   706 		while ((iterSetting != null) && iterSetting.hasNext()) {
       
   707 			Setting setting = iterSetting.next();
       
   708 			String name = setting.getName();
       
   709 			if(name!=null&&name.equals(Messages.getString("IMakerWrapper.21"))) { //$NON-NLS-1$
       
   710 				String str = setting.getValue();
       
   711 				hwids =	str.split(IMakerWrapperPreferences.HWID_DELIMITER);
       
   712 			}
       
   713 		}
       
   714 
       
   715 		iterSetting = settings.iterator();
       
   716 		while ((iterSetting != null) && iterSetting.hasNext()) {
       
   717 			Setting setting = iterSetting.next();
       
   718 			// Check to see if it's a hwid
       
   719 			String name = setting.getName();
       
   720 			if (name!=null&&name.toLowerCase().equals(IMakerWrapperPreferences.HWID)) {
       
   721 				// Process hwids
       
   722 				String defHwid = setting.getValue();
       
   723 				String hwidList = ""; //$NON-NLS-1$
       
   724 
       
   725 				for (int i=0,j=hwids.length; i<j; i++) {
       
   726 					if (hwids[i].equals(defHwid)) {
       
   727 						hwids[i] = hwids[i]+IMakerWrapperPreferences.HWID_DEFAULT_MARKER;
       
   728 					}
       
   729 					hwidList += hwids[i];
       
   730 					if (i < j-1) {
       
   731 						hwidList += " "; //$NON-NLS-1$
       
   732 					}
       
   733 				}
       
   734 				setting.setValue(hwidList);
       
   735 			}
       
   736 			config.addSetting(setting);
       
   737 		}
       
   738 	}
       
   739 
       
   740 	private Configuration createConfiguration(String makeFile) {
       
   741 		Configuration config = IQRFFactory.eINSTANCE.createConfiguration();
       
   742 //		File file = new File(makeFile);
       
   743 		config.setFilePath(makeFile);
       
   744 //		config.setName(file.getName());
       
   745 		return config;
       
   746 	}
       
   747 
       
   748 	public void cancel() {
       
   749 //		if(process!=null&&builderRunning) {
       
   750 //			try {
       
   751 //				process.getInputStream().close();
       
   752 //			} catch (IOException e) {
       
   753 //				e.printStackTrace();
       
   754 //			}
       
   755 //			process.destroy();
       
   756 //			builderRunning=false;
       
   757 //		}
       
   758 	}
       
   759 
       
   760 	public String getWorkdir(String makefile) throws IMakerCoreNotFoundException, IMakerCoreAlreadyRunningException, IMakerCoreExecutionException {
       
   761 		String target = "help-variable-WORKDIR*-value";
       
   762 		String retValue = null;
       
   763 		verifyExists();
       
   764 		List<String> parameters = new ArrayList<String>();
       
   765 		parameters.add("-f");
       
   766 		parameters.add(makefile);
       
   767 		parameters.add(target);
       
   768 		
       
   769 		List<String> ret = executeCommand(parameters);
       
   770 		String output = ret.get(0);
       
   771 		for (String str : ret) {
       
   772 			if(str.startsWith("WORK")) {
       
   773 				output = str;
       
   774 				break;
       
   775 			}
       
   776 		}
       
   777 		int start = output.indexOf('/');
       
   778 		output = output.substring(start+1,output.length()-1);
       
   779 		retValue = output;
       
   780 		return retValue;
       
   781 	}
       
   782 
       
   783 //	@Override
       
   784 	public String getBuildCommand(List<String> params) {
       
   785 		StringBuffer sb = new StringBuffer();
       
   786 		sb.append(tool.get(0) + " ");
       
   787 		String[] parameters = null;
       
   788 		String prms = params.toString();
       
   789 		if(prms.length()>2) {
       
   790 			prms = prms.substring(1, prms.length()-1);
       
   791 			parameters=prms.split(Messages.getString("IMakerWrapper.5")); //$NON-NLS-1$
       
   792 		}
       
   793 		for(String str: parameters) {
       
   794 			sb.append(str);
       
   795 		}
       
   796 		return sb.toString();
       
   797 	}
       
   798 
       
   799 	public List<String> getTool() {
       
   800 		return this.tool;
       
   801 	}
       
   802 
       
   803 	public String getTargetSteps(String target, String makefile, IProgressMonitor monitor) {
       
   804 		if (monitor != null) {
       
   805 			monitor.beginTask(Messages.getString("IMakerWrapper.24"),2);
       
   806 			monitor.subTask(Messages.getString("IMakerWrapper.25"));
       
   807 		}
       
   808 		Pattern pattern = Pattern.compile(".*\\s*=\\s*.(.*).");
       
   809 		List<String> cmd = new ArrayList<String>();
       
   810 		cmd.add(IMakerWrapperPreferences.ARG_FETCH_CONFIGURATION);
       
   811 		cmd.add(makefile);
       
   812 		cmd.add(target);
       
   813 		cmd.add(IMakerWrapperPreferences.TARGET_STEPS);
       
   814 		try {
       
   815 			if(monitor!=null) {
       
   816 				monitor.worked(1);
       
   817 				monitor.subTask(Messages.getString("IMakerWrapper.26"));
       
   818 			}
       
   819 			StringBuilder sb = new StringBuilder();
       
   820 			List<String> ret = executeCommand(cmd);
       
   821 			for (String str : ret) {
       
   822 				Matcher matcher = pattern.matcher(str);
       
   823 				if(matcher.find()) {
       
   824 					int end = matcher.end(1);
       
   825 					int start = matcher.start(1);
       
   826 					String retValue = str.substring(start,end);
       
   827 					if(monitor!=null) {
       
   828 						monitor.worked(1);
       
   829 						monitor.done();
       
   830 					}
       
   831 					sb.append(retValue);
       
   832 					sb.append(" ");
       
   833 				}
       
   834 			}
       
   835 			String str = sb.toString();
       
   836 			if(str.equals("")) {
       
   837 				return null;
       
   838 			} else {
       
   839 				return str;
       
   840 			}
       
   841 		} catch (IMakerCoreExecutionException e) {
       
   842 			e.printStackTrace();
       
   843 		}
       
   844 		return null;
       
   845 	}
       
   846 
       
   847 	public boolean buildImage(File impFile, OutputStream out)
       
   848 			throws IMakerCoreNotFoundException, IMakerCoreExecutionException,
       
   849 			IMakerCoreAlreadyRunningException {
       
   850 		if(impFile==null||!impFile.exists()) {
       
   851 			throw new IMakerCoreExecutionException("Invalid imp file given!");
       
   852 		}
       
   853 		this.outputStream = out;
       
   854 		verifyExists();
       
   855 		
       
   856 		params.clear();
       
   857 		params.add("-f");
       
   858 		params.add("\""+impFile.getAbsolutePath()+"\"");
       
   859 		builderRunning = true;
       
   860 		List<String> ret = executeCommand(params);
       
   861 		builderRunning = false;
       
   862 		return getReturnStatus(ret);
       
   863 	}	
       
   864 }