/**
* Copyright (C) 2005 - 2014 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.installer.step;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.formic.InstallContext;
import org.formic.Installer;
import org.formic.util.CommandExecutor;
import org.formic.wizard.step.gui.RequirementsValidationStep;
import org.formic.wizard.step.gui.RequirementsValidationStep.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides requirements to validate for RequirementsValidationStep.
*
* @author Eric Van Dewoestine
*/
public class RequirementProvider
implements RequirementsValidationStep.RequirementProvider
{
private static final Logger logger =
LoggerFactory.getLogger(RequirementProvider.class);
@Override
public Requirement[] getRequirements()
{
if(Os.isFamily("windows")){
Requirement[] requirements = new Requirement[1];
requirements[0] = new EclipseRequirement();
return requirements;
}
InstallContext context = Installer.getContext();
boolean skipVim = ((Boolean)context.getValue("vim.skip")).booleanValue();
Requirement[] requirements = new Requirement[skipVim ? 3 : 4];
requirements[0] = new EclipseRequirement();
requirements[1] = new WhichRequirement("make");
requirements[2] = new WhichRequirement("gcc");
if (!skipVim){
requirements[3] = new VimRequirement();
}
return requirements;
}
@Override
public Status validate(Requirement requirement)
{
ValidatingRequirement req = (ValidatingRequirement)requirement;
return req.validate();
}
private class EclipseRequirement
extends ValidatingRequirement
{
public EclipseRequirement ()
{
super("eclipse");
}
public Status validate()
{
String eclipseHome = (String)
Installer.getContext().getValue("eclipse.home");
eclipseHome = eclipseHome.replace('\\', '/');
String version = versionFromPlugins(eclipseHome);
if (version == null){
return new Status(
WARN, Installer.getString("eclipse.validation.failed"));
}
String[] parts = StringUtils.split(version, '.');
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
int requiredMajor = Integer.parseInt(
Installer.getString("eclipse.version.major"));
int requiredMinor = Integer.parseInt(
Installer.getString("eclipse.version.minor"));
int requiredPatch = Integer.parseInt(
Installer.getString("eclipse.version.patch"));
if (major != requiredMajor ||
minor != requiredMinor ||
patch < requiredPatch)
{
return new Status(FAIL,
Installer.getString(
"eclipse.version.invalid",
version,
Installer.getString("eclipse.version")));
}
return OK_STATUS;
}
public String versionFromPlugins(String eclipseHome)
{
final String[] plugins = {"org.eclipse.platform"};
File file = new File(eclipseHome + "/plugins");
String[] names = file.list(new FilenameFilter(){
public boolean accept(File dir, String name){
for (int ii = 0; ii < plugins.length; ii++){
if (name.contains(plugins[ii])){
return true;
}
}
return false;
}
});
ArrayList<String> versions = new ArrayList<String>();
for (int ii = 0; ii < names.length; ii++){
String version = names[ii];
version = version.replaceFirst(".*?_(\\d+\\.\\d+).*", "$1");
version = version.replaceFirst("\\.$", "");
versions.add(version);
}
if (versions.size() > 0){
Collections.sort(versions);
return versions.get(versions.size() - 1);
}
logger.warn(
"Error checking eclipse version via plugins.");
return null;
}
}
private class VimRequirement
extends ValidatingRequirement
{
private final Pattern VERSION =
Pattern.compile(".*VIM - Vi IMproved (([0-9]+\\.)+[0-9]).*");
public VimRequirement ()
{
super("vim");
}
public Status validate()
{
try{
CommandExecutor command =
CommandExecutor.execute(new String[]{"vim", "--version"}, 2000);
if (command.getReturnCode() != 0){
logger.error(
"Error checking vim version: {}", command.getErrorMessage());
return new Status(
WARN, Installer.getString("vim.validation.failed"));
}
String result = command.getResult();
Matcher matcher = VERSION.matcher(result);
if(!matcher.find()){
logger.error("Error finding vim version in output: {}", result);
return new Status(
WARN, Installer.getString("vim.validation.failed"));
}
String version = matcher.group(1);
String[] parts = StringUtils.split(version, '.');
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
if(major < 7 || minor < 0 || patch < 0){
return new Status(FAIL,
Installer.getString("vim.version.invalid", version, "7.0.x"));
}
}catch(Exception e){
logger.error("Error checking vim version.", e);
return new Status(WARN, Installer.getString("vim.validation.failed"));
}
return OK_STATUS;
}
}
private class WhichRequirement
extends ValidatingRequirement
{
private String program;
public WhichRequirement (String program)
{
super(program);
this.program = program;
}
public Status validate()
{
try{
int result = Runtime.getRuntime().exec(
new String[] {"which", program}).waitFor();
if (result != 0){
return new Status(
FAIL, Installer.getString(program + ".not.found"));
}
}catch(Exception e){
logger.error("Error checking for '" + program + "'", e);
return new Status(
WARN, Installer.getString(program + ".validation.failed"));
}
return OK_STATUS;
}
}
}