content: package ts.cmd;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  
  import ts.TypeScriptException;
  import ts.nodejs.INodejsLaunchConfiguration;
  import ts.nodejs.INodejsProcess;
  import ts.nodejs.INodejsProcessListener;
  import ts.nodejs.NodejsProcess;
  import ts.nodejs.NodejsProcessManager;
  
  public class AbstractCmd<T extends IOptions> {
  
  	private final File binFile;
  	private final File nodejsFile;
  	private final String binFileType;
  
  	public AbstractCmd(File binFile, File nodejsFile, String binFileType) {
  		this.binFile = binFile;
  		this.nodejsFile = nodejsFile;
  		this.binFileType = binFileType;
  	}
  
  	public List<String> createCommands(T options, List<String> filenames) {
  		List<String> cmds = NodejsProcess.createNodeCommands(nodejsFile, binFile);
  		fillOptions(options, filenames, cmds);
  		return cmds;
  	}
  
  	public INodejsProcess execute(File baseDir, final T options, final List<String> filenames,
  			INodejsProcessListener listener) throws TypeScriptException {
  		INodejsProcess process = NodejsProcessManager.getInstance().create(baseDir, binFile, nodejsFile,
  				new INodejsLaunchConfiguration() {
  
  					@Override
  					public List<String> createNodeArgs() {
  						List<String> args = new ArrayList<String>();
  						fillOptions(options, filenames, args);
  						return args;
  					}
  					
  					@Override
  					public Map<String, String> createNodeEnvironmentVariables() {
  						return null;
  					}
  				}, binFileType);
  
  		if (listener != null) {
  			process.addProcessListener(listener);
  		}
  		process.start();
  		try {
  			process.join();
  		} catch (InterruptedException e) {
  			throw new TypeScriptException(e);
  		}
  		return process;
  	}
  
  	private void fillOptions(T options, List<String> filenames, List<String> args) {
  		if (filenames != null) {
  			args.addAll(filenames);
  		}
  		if (options != null) {
  			options.fillOptions(args);
  		}
  	}
  }
  