/** * Copyright (C) 2005 - 2013 Eric Van Dewoestine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.eclim.plugin.dltk.command.launching; import java.util.ArrayList; import org.eclim.Services; import org.eclim.annotation.Command; import org.eclim.command.CommandLine; import org.eclim.command.Options; import org.eclim.plugin.core.command.AbstractCommand; import org.eclim.plugin.core.project.ProjectNatureFactory; import org.eclim.plugin.dltk.preference.DltkInterpreterTypeManager; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.dltk.core.environment.EnvironmentManager; import org.eclipse.dltk.core.environment.IEnvironment; import org.eclipse.dltk.core.environment.IFileHandle; import org.eclipse.dltk.core.internal.environment.LazyFileHandle; import org.eclipse.dltk.debug.ui.interpreters.InterpretersUpdater; import org.eclipse.dltk.internal.debug.ui.interpreters.EnvironmentVariableContentProvider; import org.eclipse.dltk.launching.EnvironmentVariable; import org.eclipse.dltk.launching.IInterpreterInstall; import org.eclipse.dltk.launching.IInterpreterInstallType; import org.eclipse.dltk.launching.InterpreterStandin; import org.eclipse.dltk.launching.LibraryLocation; import org.eclipse.dltk.launching.ScriptRuntime; import org.eclipse.dltk.utils.PlatformFileUtils; /** * Command to add a new interpreter. * * Majority of the code here was gleaned from * org.eclipse.dltk.internal.debug.ui.interpreters.AddScriptInterpreterDialog * * @author Eric Van Dewoestine */ @Command( name = "dltk_add_interpreter", options = "REQUIRED l nature ARG," + "REQUIRED t type ARG," + "REQUIRED p path ARG," + "OPTIONAL n name ARG" ) public class AddInterpreterCommand extends AbstractCommand { @Override public Object execute(CommandLine commandLine) throws Exception { String alias = getNatureAlias(commandLine); String nature = ProjectNatureFactory.getNatureForAlias(alias); if (alias == null){ throw new RuntimeException( Services.getMessage("nature.alias.not.found", alias)); } String interpreterPath = commandLine.getValue(Options.PATH_OPTION); IInterpreterInstallType type = getInterpreterInstallType(nature, commandLine); if (type == null){ throw new RuntimeException( Services.getMessage("interpreter.type.not.found")); } IEnvironment env = EnvironmentManager.getLocalEnvironment(); IFileHandle file = PlatformFileUtils .findAbsoluteOrEclipseRelativeFile(env, new Path(interpreterPath)); if (!file.exists()){ throw new RuntimeException( Services.getMessage("interpreter.path.not.found", interpreterPath)); } EnvironmentVariableContentProvider envVarsProvider = new EnvironmentVariableContentProvider(); EnvironmentVariable[] envVars = envVarsProvider.getVariables(); LibraryLocation[] libs = type.getDefaultLibraryLocations( file, envVars, new NullProgressMonitor()); IStatus status = type.validateInstallLocation( file, envVars, libs, new NullProgressMonitor()); if (!status.isOK()){ throw new RuntimeException(status.getMessage()); } IInterpreterInstall deflt = ScriptRuntime.getDefaultInterpreterInstall( new ScriptRuntime.DefaultInterpreterEntry(nature, env.getId())); if (deflt != null && deflt.getInstallLocation().equals(file)){ throw new RuntimeException( Services.getMessage("interpreter.already.exists", interpreterPath)); } ArrayList<IInterpreterInstall> interpreters = new ArrayList<IInterpreterInstall>(); IInterpreterInstallType[] types = ScriptRuntime.getInterpreterInstallTypes(nature); for (IInterpreterInstallType iit : types){ IInterpreterInstall[] installs = iit.getInterpreterInstalls(); for (IInterpreterInstall install : installs){ if (install.getInstallLocation().equals(file)){ throw new RuntimeException( Services.getMessage("interpreter.already.exists", interpreterPath)); } interpreters.add(install); } } String name = commandLine.getValue(Options.NAME_OPTION); if (name == null){ name = generateInterpreterName(file, nature); } String id = null; do { id = String.valueOf(System.currentTimeMillis()); } while (type.findInterpreterInstall(id) != null); IInterpreterInstall install = new InterpreterStandin(type, id); install.setInstallLocation( new LazyFileHandle(env.getId(), new Path(interpreterPath))); install.setName(name); install.setLibraryLocations(libs); install.setInterpreterArgs(null); // future use install = ((InterpreterStandin)install).convertToRealInterpreter(); interpreters.add(install); if(deflt == null){ deflt = install; ScriptRuntime.setDefaultInterpreterInstall(install, null, false); } IInterpreterInstall[] defaults = {deflt}; IInterpreterInstall[] installs = interpreters.toArray(new IInterpreterInstall[interpreters.size()]); InterpretersUpdater updater = new InterpretersUpdater(); updater.updateInterpreterSettings(nature, installs, defaults); return Services.getMessage("interpreter.added"); } protected String getNatureAlias(CommandLine commandLine) throws Exception { return commandLine.getValue(Options.LANG_OPTION); } protected IInterpreterInstallType getInterpreterInstallType( String nature, CommandLine commandLine) throws Exception { String interpreterType = commandLine.getValue(Options.TYPE_OPTION); return DltkInterpreterTypeManager .getInterpreterInstallType(interpreterType, nature); } // mostly ripped off from eclipse. protected String generateInterpreterName(IFileHandle file, String nature) { final String genName; final IPath path = new Path(file.getCanonicalPath()); if (path.segmentCount() > 0) { genName = path.lastSegment(); } else { genName = null; } // Add number if interpreter with such name already exists. String name = genName; if (name != null) { int index = 0; while (!validateGeneratedName(name, nature)) { name = genName + "(" + String.valueOf(++index) + ")"; } } return name; } protected boolean validateGeneratedName(String name, String nature) { IInterpreterInstallType[] types = ScriptRuntime.getInterpreterInstallTypes(nature); for (IInterpreterInstallType type : types){ IInterpreterInstall install = type.findInterpreterInstallByName(name); if (install != null) { return false; } } return true; } }