blob: b908a05c6f8e4b6f8aea9c43ca2e36b946cba264 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.nativeexecution.api.util;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.netbeans.modules.nativeexecution.api.util.Shell.ShellType;
import org.netbeans.modules.nativeexecution.spi.support.NativeExecutionUserNotification;;
//import org.netbeans.modules.dlight.nativeexecution.ui.ShellValidationStatusPanel;
//import org.openide.DialogDescriptor;
//import org.openide.DialogDisplayer;
//import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
/**
*
* @author ak119685
*/
public final class ShellValidationSupport {
protected static final ShellValidationStatus NOSHELL = new ShellValidationStatus(null, Arrays.asList("No shell"), null); // NOI18N
protected static final ShellValidationStatus VALID = new ShellValidationStatus(null, null, null);
private ShellValidationSupport() {
}
public static ShellValidationStatus getValidationStatus(final Shell shell) {
if (shell == null) {
return NOSHELL;
}
if (shell.type == ShellType.CYGWIN) {
return validateCygwinShell(shell);
}
return VALID;
}
private static ShellValidationStatus validateCygwinShell(final Shell shell) {
assert shell != null && shell.type == ShellType.CYGWIN;
ArrayList<String> validationErrors = new ArrayList<>();
ArrayList<String> validationWarnings = new ArrayList<>();
String jdkBitness = System.getProperty("os.arch"); // NOI18N
if (jdkBitness == null) {
jdkBitness = ""; // NOI18N
}
String cygwinBitness = "";
File uname_exe = new File(shell.bindir, "uname.exe"); // NOI18N
if (uname_exe.exists()) {
// Should not use NativeProcess here as it needs expander, which is
// not available yet ...
ProcessUtils.ExitStatus exitStatus = ProcessUtils.execute(new ProcessBuilder(uname_exe.getPath(), "-m")); // NOI18N
if (exitStatus.isOK()) {
cygwinBitness = exitStatus.getOutputString().trim();
}
}
if (cygwinBitness.equals("i686") && !jdkBitness.equals("x86")) { // NOI18N
validationWarnings.add(NbBundle.getMessage(ShellValidationSupport.class, "ShellValidationSupport.ValidationWarning.Cygwin32OnJDK64")); // NOI18N
} else if (cygwinBitness.equals("x86_64") && jdkBitness.equals("x86")) { // NOI18N
validationWarnings.add(NbBundle.getMessage(ShellValidationSupport.class, "ShellValidationSupport.ValidationWarning.Cygwin64OnJDK32")); // NOI18N
}
File mount_util = new File(shell.bindir, "mount.exe"); // NOI18N
File cygpath_util = new File(shell.bindir, "cygpath.exe"); // NOI18N
if (!mount_util.exists()) {
validationErrors.add(loc("ShellValidationSupport.ValidationError.fileNotFound", mount_util.getAbsolutePath())); // NOI18N
}
if (!cygpath_util.exists()) {
validationErrors.add(loc("ShellValidationSupport.ValidationError.fileNotFound", cygpath_util.getAbsolutePath())); // NOI18N
}
ProcessBuilder pb = new ProcessBuilder(mount_util.getAbsolutePath());
ProcessUtils.ExitStatus exitStatus = ProcessUtils.execute(pb);
List<String> output = exitStatus.getOutputLines();
if (!exitStatus.isOK()) {
validationErrors.add(loc("ShellValidationSupport.ValidationError.validationFailed", shell.bindir.getAbsolutePath())); // NOI18N
}
Pattern pattern = Pattern.compile("(.*) on (/.*) type .*"); // NOI18N
boolean rootIsMounted = false;
for (String line : output) {
Matcher m = pattern.matcher(line);
if (m.matches()) {
String winpath = m.group(1);
File winfile = new File(winpath);
String cygpath = m.group(2);
if (cygpath.equals("/")) { // NOI18N
rootIsMounted = true;
}
if (!winfile.exists()) {
validationErrors.add(loc("ShellValidationSupport.ValidationError.absentMountPoint", winpath, cygpath)); // NOI18N
continue;
}
if (cygpath.startsWith("/usr")) { // NOI18N
String p1 = (winfile.getParentFile().getAbsolutePath() + '\\').toLowerCase();
String p2 = (shell.bindir.getParentFile().getAbsolutePath() + '\\').toLowerCase();
if (!p2.startsWith(p1)) {
validationWarnings.add(loc("ShellValidationSupport.ValidationError.wrongMountPoint", winpath, cygpath)); // NOI18N
continue;
}
}
}
}
if (!rootIsMounted) {
validationErrors.add(loc("ShellValidationSupport.ValidationError.rootIsNotMounted")); // NOI18N
}
return new ShellValidationStatus(shell, validationErrors, validationWarnings);
}
public static boolean confirm(final ShellValidationStatus status) {
return confirm(null, null, status);
}
public static boolean confirm(final String header, final String footer, final ShellValidationStatus status) {
if (status == null || status == NOSHELL) {
if (Boolean.getBoolean("nativeexecution.mode.unittest") || "true".equals(System.getProperty("cnd.command.line.utility"))) { // NOI18N
System.err.println(loc("ShellValidationSupport.ValidationError.NoShell"));
} else {
NativeExecutionUserNotification.getDefault().notify(loc("ShellValidationSupport.ValidationError.NoShell"), // NOI18N
NativeExecutionUserNotification.Descriptor.ERROR);
// DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
// loc("ShellValidationSupport.ValidationError.NoShell"), // NOI18N
// NotifyDescriptor.ERROR_MESSAGE));
}
return false;
}
if (status.isValid() && !status.hasWarnings()) {
return true;
}
final String key = status.shell.toString();
String allowBroken = NbPreferences.forModule(WindowsSupport.class).get(key, "no"); // NOI18N
if ("yes".equals(allowBroken)) { // NOI18N
return true;
}
Object response = null;
if (Boolean.getBoolean("nativeexecution.mode.unittest")) {
System.err.println(loc("ShellValidationSupport.ValidationError.ErrorDialogTitle", "cygwin"));
System.err.println(header);
for (String error : status.shell.getValidationStatus().getErrors()) {
System.err.println(error);
}
System.err.println(footer);
return true;
} else {
return NativeExecutionUserNotification.getDefault().confirmShellStatusValiation(
loc("ShellValidationSupport.ValidationError.ErrorDialogTitle", "cygwin"),//NOI18N
header, footer, status.shell);
// final ShellValidationStatusPanel errorPanel = new ShellValidationStatusPanel(header, footer, status.shell);
//
// final JButton noButton = new JButton("No"); // NOI18N
// errorPanel.setActionListener(new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// noButton.setEnabled(!errorPanel.isRememberDecision());
// }
// });
//
// DialogDescriptor dd = new DialogDescriptor(errorPanel,
// loc("ShellValidationSupport.ValidationError.ErrorDialogTitle", "cygwin"), // NOI18N
// true,
// new Object[]{DialogDescriptor.YES_OPTION, noButton},
// noButton,
// DialogDescriptor.DEFAULT_ALIGN, null, null);
//
// Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
//
// try {
// dialog.setVisible(true);
// } catch (Throwable th) {
// if (!(th.getCause() instanceof InterruptedException)) {
// throw new RuntimeException(th);
// }
// dd.setValue(DialogDescriptor.CANCEL_OPTION);
// } finally {
// dialog.dispose();
// }
//
// response = dd.getValue();
//
// if (response == DialogDescriptor.YES_OPTION && errorPanel.isRememberDecision()) {
// NbPreferences.forModule(WindowsSupport.class).put(key, "yes"); // NOI18N
// }
}
// return (response == DialogDescriptor.YES_OPTION);
}
public static class ShellValidationStatus {
private final List<String> errors = new ArrayList<>();
private final List<String> warnings = new ArrayList<>();
private final Shell shell;
private ShellValidationStatus(Shell shell, List<String> errors, List<String> warnings) {
if (errors != null) {
this.errors.addAll(errors);
}
if (warnings != null) {
this.warnings.addAll(warnings);
}
this.shell = shell;
}
public boolean isValid() {
return errors.isEmpty();
}
public List<String> getErrors() {
return Collections.unmodifiableList(errors);
}
public List<String> getWarnings() {
return Collections.unmodifiableList(warnings);
}
public boolean hasWarnings() {
return !warnings.isEmpty();
}
}
private static String loc(String key, String... params) {
return NbBundle.getMessage(ShellValidationSupport.class, key, params);
}
}