mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-57233 Editor font antialising/appearance problems on Linux
Refactored jdk bundle handling, added tests Added linux jdk selection support
This commit is contained in:
@@ -59,6 +59,8 @@ IDE_BIN_HOME=`dirname "$SCRIPT_LOCATION"`
|
||||
# ---------------------------------------------------------------------
|
||||
if [ -n "$@@product_uc@@_JDK" -a -x "$@@product_uc@@_JDK/bin/java" ]; then
|
||||
JDK="$@@product_uc@@_JDK"
|
||||
elif [ -s "$HOME/.@@system_selector@@/config/@@vm_options@@.jdk" ]; then
|
||||
JDK=`$CAT $HOME/.@@system_selector@@/config/@@vm_options@@.jdk`
|
||||
elif [ -x "$IDE_HOME/jre/jre/bin/java" ] && "$IDE_HOME/jre/jre/bin/java" -version > /dev/null 2>&1 ; then
|
||||
JDK="$IDE_HOME/jre"
|
||||
elif [ -n "$JDK_HOME" -a -x "$JDK_HOME/bin/java" ]; then
|
||||
|
||||
@@ -27,20 +27,23 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.JdkBundle;
|
||||
import com.intellij.util.JdkBundleList;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author denis
|
||||
@@ -49,37 +52,36 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
@NonNls private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.SwitchBootJdkAction");
|
||||
@NonNls private static final String productJdkConfigFileName = getExecutable() + ".jdk";
|
||||
@NonNls private static final File productJdkConfigFile = new File(PathManager.getConfigPath(), productJdkConfigFileName);
|
||||
@NonNls private static final File customJdkFile = new File(PathManager.getHomePath() + File.separator + "jre" + File.separator + "jdk");
|
||||
@NonNls private static final File bundledJdkFile = getBundledJDKFile();
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
private static File getBundledJDKFile() {
|
||||
StringBuilder bundledJDKPath = new StringBuilder(PathManager.getHomePath() + File.separator + "jre");
|
||||
if (SystemInfo.isMac) {
|
||||
bundledJDKPath.append(File.separator).append("jdk");
|
||||
}
|
||||
return new File(bundledJDKPath.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Presentation presentation = e.getPresentation();
|
||||
if (!SystemInfo.isMac || !customJdkFile.exists()) {
|
||||
if (!(SystemInfo.isMac || (SystemInfo.isLinux && PlatformUtils.isIntelliJ()))) {
|
||||
presentation.setEnabledAndVisible(false);
|
||||
return;
|
||||
}
|
||||
e.getPresentation().setText("Switch Boot JDK");
|
||||
}
|
||||
|
||||
public static List<JdkBundleDescriptor> getBundlesFromFile(@NotNull File fileWithBundles) {
|
||||
InputStream stream = null;
|
||||
InputStreamReader inputStream;
|
||||
BufferedReader bufferedReader;
|
||||
|
||||
List<JdkBundleDescriptor> list = new ArrayList<JdkBundleDescriptor>();
|
||||
|
||||
|
||||
public static List<JdkBundle> getBundlesFromFile(@NotNull File fileWithBundles) {
|
||||
List<JdkBundle> list = new ArrayList<JdkBundle>();
|
||||
try {
|
||||
stream = new FileInputStream(fileWithBundles);
|
||||
inputStream = new InputStreamReader(stream, Charset.forName("UTF-8"));
|
||||
bufferedReader = new BufferedReader(inputStream);
|
||||
|
||||
String line;
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
for (String line : FileUtil.loadLines(fileWithBundles, "UTF-8")) {
|
||||
File file = new File(line);
|
||||
if (file.exists()) {
|
||||
list.add(new JdkBundleDescriptor(file, file.getName()));
|
||||
list.add(JdkBundle.createBundle(file, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,14 +89,8 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
// The device builders can throw IllegalStateExceptions if
|
||||
// build gets called before everything is properly setup
|
||||
LOG.error(e);
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error reading JDK bundles", e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -120,6 +116,7 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
File selectedJdkBundleFile = dialog.getSelectedFile();
|
||||
FileWriter fooWriter = null;
|
||||
try {
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
fooWriter = new FileWriter(productJdkConfigFile, false);
|
||||
fooWriter.write(selectedJdkBundleFile.getAbsolutePath());
|
||||
}
|
||||
@@ -140,67 +137,55 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
}
|
||||
}
|
||||
|
||||
private static class JdkBundleDescriptor {
|
||||
private File bundleAsFile;
|
||||
private String visualRepresentation;
|
||||
|
||||
public JdkBundleDescriptor(@NotNull File bundleAsFile, @NotNull String visualRepresentation) {
|
||||
this.bundleAsFile = bundleAsFile;
|
||||
this.visualRepresentation = visualRepresentation;
|
||||
}
|
||||
|
||||
public File getBundleAsFile() {
|
||||
return bundleAsFile;
|
||||
}
|
||||
|
||||
public String getVisualRepresentation() {
|
||||
return visualRepresentation;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SwitchBootJdkDialog extends DialogWrapper {
|
||||
|
||||
@NotNull private final ComboBox myComboBox;
|
||||
|
||||
protected SwitchBootJdkDialog(@Nullable Project project, final List<JdkBundleDescriptor> jdkBundlesList) {
|
||||
protected SwitchBootJdkDialog(@Nullable Project project, final List<JdkBundle> jdkBundlesList) {
|
||||
super(project, false);
|
||||
|
||||
final ArrayList<JdkBundleDescriptor> pathsList = JdkUtil.findJdkPaths();
|
||||
if (!jdkBundlesList.isEmpty()) {
|
||||
JdkBundleDescriptor jdkBundleDescription = jdkBundlesList.get(0);
|
||||
pathsList.add(0, jdkBundleDescription);
|
||||
}
|
||||
final JdkBundleList pathsList = findJdkPaths();
|
||||
|
||||
myComboBox = new ComboBox();
|
||||
|
||||
DefaultComboBoxModel model = new DefaultComboBoxModel();
|
||||
|
||||
for (JdkBundleDescriptor jdkBundlePath : pathsList) {
|
||||
if (!(jdkBundlesList.isEmpty() || jdkBundlePath == null)
|
||||
&& FileUtil.filesEqual(jdkBundlePath.getBundleAsFile(),jdkBundlesList.get(0).getBundleAsFile()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (JdkBundle jdkBundlePath : pathsList.toArrayList()) {
|
||||
//noinspection unchecked
|
||||
model.addElement(jdkBundlePath);
|
||||
}
|
||||
|
||||
myComboBox.setModel(model);
|
||||
model.addListDataListener(new ListDataListener() {
|
||||
@Override
|
||||
public void intervalAdded(ListDataEvent e) { }
|
||||
|
||||
if (pathsList.isEmpty()) {
|
||||
myComboBox.setEnabled(false);
|
||||
}
|
||||
@Override
|
||||
public void intervalRemoved(ListDataEvent e) { }
|
||||
|
||||
@Override
|
||||
public void contentsChanged(ListDataEvent e) {
|
||||
setOKActionEnabled(!((JdkBundle)myComboBox.getSelectedItem()).isBoot());
|
||||
}
|
||||
});
|
||||
|
||||
//noinspection unchecked
|
||||
myComboBox.setModel(model);
|
||||
|
||||
myComboBox.setRenderer(new ListCellRendererWrapper() {
|
||||
@Override
|
||||
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value != null) {
|
||||
JdkBundleDescriptor jdkBundleDescriptor = ((JdkBundleDescriptor)value);
|
||||
JdkBundle jdkBundleDescriptor = ((JdkBundle)value);
|
||||
if (jdkBundleDescriptor.isBoot()) {
|
||||
setForeground(JBColor.DARK_GRAY);
|
||||
}
|
||||
setText(jdkBundleDescriptor.getVisualRepresentation());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Null value has been passed to a cell renderer. Available JDKs count: " + pathsList.size());
|
||||
LOG.debug("Null value has been passed to a cell renderer. Available JDKs count: " + pathsList.toArrayList().size());
|
||||
StringBuilder jdkNames = new StringBuilder();
|
||||
for (JdkBundleDescriptor jdkBundlePath : pathsList) {
|
||||
for (JdkBundle jdkBundlePath : pathsList.toArrayList()) {
|
||||
if (!jdkBundlesList.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -215,6 +200,7 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
});
|
||||
|
||||
setTitle("Switch IDE Boot JDK");
|
||||
setOKActionEnabled(false); // First item is a boot jdk
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -237,88 +223,44 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
public File getSelectedFile() {
|
||||
return ((JdkBundleDescriptor)myComboBox.getSelectedItem()).bundleAsFile;
|
||||
return ((JdkBundle)myComboBox.getSelectedItem()).getBundleAsFile();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String STANDARD_JDK_LOCATION_ON_MAC_OS_X = "/Library/Java/JavaVirtualMachines/";
|
||||
private static final String STANDARD_JDK_6_LOCATION_ON_MAC_OS_X = "/System/Library/Java/JavaVirtualMachines/";
|
||||
private static final String [] STANDARD_JVM_LOCATIONS_ON_LINUX = new String[] {
|
||||
"/usr/lib/jvm/", // Ubuntu
|
||||
"/usr/java/" // Fedora
|
||||
};
|
||||
|
||||
private static class JdkUtil {
|
||||
private static ArrayList <JdkBundleDescriptor> findJdkPaths () {
|
||||
ArrayList<JdkBundleDescriptor> jdkPathsList = new ArrayList<JdkBundleDescriptor>();
|
||||
if (!SystemInfo.isMac) return jdkPathsList;
|
||||
private static final Version JDK6_VERSION = new Version(1, 6, 0);
|
||||
private static final Version JDK8_VERSION = new Version(1, 8, 0);
|
||||
|
||||
if (customJdkFile.exists()) {
|
||||
jdkPathsList.add(new JdkBundleDescriptor(customJdkFile, "JDK bundled with IDE"));
|
||||
}
|
||||
|
||||
ArrayList<JdkBundleDescriptor> jdk6List = jdkBundlesFromLocation(STANDARD_JDK_6_LOCATION_ON_MAC_OS_X, "1.6.0");
|
||||
private static JdkBundleList findJdkPaths() {
|
||||
JdkBundle bootJdk = JdkBundle.createBoot();
|
||||
|
||||
if (jdk6List.isEmpty()) {
|
||||
jdkPathsList.addAll(jdkBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, "1.6.0"));
|
||||
}
|
||||
JdkBundleList jdkBundleList = new JdkBundleList();
|
||||
jdkBundleList.addBundle(bootJdk, true);
|
||||
|
||||
jdkPathsList.addAll(jdkBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, "jdk1.8.0_(\\d*).jdk"));
|
||||
|
||||
return jdkPathsList;
|
||||
if (bundledJdkFile.exists()) {
|
||||
JdkBundle bundledJdk = JdkBundle.createBundle(bundledJdkFile, false, true);
|
||||
jdkBundleList.addBundle(bundledJdk, true);
|
||||
}
|
||||
|
||||
private static ArrayList<JdkBundleDescriptor> jdkBundlesFromLocation(String jdkLocationOnMacOsX, String filter) {
|
||||
|
||||
ArrayList<JdkBundleDescriptor> localJdkPathsList = new ArrayList<JdkBundleDescriptor>();
|
||||
|
||||
File standardJdkLocationOnMacFile = new File(jdkLocationOnMacOsX);
|
||||
|
||||
if (!standardJdkLocationOnMacFile.exists()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Location does not exists: " + jdkLocationOnMacOsX);
|
||||
}
|
||||
return localJdkPathsList;
|
||||
}
|
||||
|
||||
File[] filesInStandardJdkLocation = standardJdkLocationOnMacFile.listFiles();
|
||||
|
||||
if (filesInStandardJdkLocation == null) {
|
||||
LOG.debug("Some IO exception happened.");
|
||||
return localJdkPathsList;
|
||||
}
|
||||
|
||||
int latestUpdateNumber = 0;
|
||||
JdkBundleDescriptor latestBundle = null;
|
||||
|
||||
Pattern p = Pattern.compile(filter);
|
||||
|
||||
for (File possibleJdkBundle : filesInStandardJdkLocation) {
|
||||
// todo add some logic to verify the bundle
|
||||
|
||||
Matcher m = p.matcher(possibleJdkBundle.getName());
|
||||
|
||||
while (m.find()) {
|
||||
try {
|
||||
if (m.groupCount() > 0) {
|
||||
int updateNumber = Integer.parseInt(m.group(1));
|
||||
if (latestUpdateNumber < updateNumber) {
|
||||
latestBundle = new JdkBundleDescriptor(possibleJdkBundle, possibleJdkBundle.getName());
|
||||
}
|
||||
} else {
|
||||
latestBundle = new JdkBundleDescriptor(possibleJdkBundle, possibleJdkBundle.getName());
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Fail parsing update number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (latestBundle != null) {
|
||||
localJdkPathsList.add(latestBundle);
|
||||
}
|
||||
|
||||
return localJdkPathsList;
|
||||
if (SystemInfo.isMac) {
|
||||
jdkBundleList.addBundlesFromLocation(STANDARD_JDK_6_LOCATION_ON_MAC_OS_X, JDK6_VERSION, JDK6_VERSION);
|
||||
jdkBundleList.addBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, JDK6_VERSION, JDK6_VERSION);
|
||||
jdkBundleList.addBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, JDK8_VERSION, null);
|
||||
}
|
||||
else if (SystemInfo.isLinux) {
|
||||
for (String location : STANDARD_JVM_LOCATIONS_ON_LINUX) {
|
||||
jdkBundleList.addBundlesFromLocation(location, JDK8_VERSION, null);
|
||||
}
|
||||
}
|
||||
|
||||
return jdkBundleList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed 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 com.intellij.util;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.util.ExecUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JdkBundle {
|
||||
@NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.util.JdkBundle");
|
||||
|
||||
private static final Pattern[] VERSION_UPDATE_PATTERNS = {
|
||||
Pattern.compile("^java version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+)\".*", Pattern.MULTILINE),
|
||||
Pattern.compile("^openjdk version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+).*\".*", Pattern.MULTILINE),
|
||||
Pattern.compile("^[a-zA-Z() \"\\d]*([\\d]+\\.[\\d]+\\.?[\\d]*).*", Pattern.MULTILINE)
|
||||
};
|
||||
|
||||
@NotNull private File myBundleAsFile;
|
||||
@NotNull private String myBundleName;
|
||||
@Nullable private Pair<Version, Integer> myVersionUpdate;
|
||||
private boolean myBoot;
|
||||
private boolean myBundled;
|
||||
|
||||
public JdkBundle(@NotNull File bundleAsFile,
|
||||
@NotNull String bundleName,
|
||||
@Nullable Pair<Version, Integer> versionUpdate, boolean boot, boolean bundled) {
|
||||
myBundleAsFile = bundleAsFile;
|
||||
myBundleName = bundleName;
|
||||
myVersionUpdate = versionUpdate;
|
||||
myBoot = boot;
|
||||
myBundled = bundled;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static JdkBundle createBundle(@NotNull File jvm, boolean boot, boolean bundled) {
|
||||
File javaHome = SystemInfo.isMac ? new File(jvm, "Contents/Home") : jvm;
|
||||
if (!new File(javaHome, "lib/tools.jar").exists()) return null; // Skip JRE
|
||||
|
||||
Pair<String, Pair<Version, Integer>> nameVersionAndUpdate = getJDKNameVersionAndUpdate(jvm.getAbsolutePath());
|
||||
return new JdkBundle(jvm, nameVersionAndUpdate.first, nameVersionAndUpdate.second, boot, bundled);
|
||||
}
|
||||
|
||||
public static JdkBundle createBoot() {
|
||||
File bootJDK = new File(System.getProperty("java.home")).getParentFile();
|
||||
if (SystemInfo.isMac) {
|
||||
bootJDK = bootJDK.getParentFile().getParentFile();
|
||||
}
|
||||
return createBundle(bootJDK, true, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public File getBundleAsFile() {
|
||||
return myBundleAsFile;
|
||||
}
|
||||
|
||||
public String getVisualRepresentation() {
|
||||
StringBuilder representation = new StringBuilder(myBundleName);
|
||||
if (myVersionUpdate != null) {
|
||||
representation.append(myVersionUpdate.first.toString()).append((myVersionUpdate.second > 0 ? "_" + myVersionUpdate.second : ""));
|
||||
}
|
||||
|
||||
if (myBoot || myBundled) {
|
||||
representation.append(" [");
|
||||
if (myBoot) representation.append(myBundled ? "boot, " : "boot");
|
||||
if (myBundled) representation.append("bundled");
|
||||
representation.append("]");
|
||||
}
|
||||
return representation.toString();
|
||||
}
|
||||
|
||||
public void setBundled(boolean bundled) {
|
||||
myBundled = bundled;
|
||||
}
|
||||
|
||||
public boolean isBoot() {
|
||||
return myBoot;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getBundleName() {
|
||||
return myBundleName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Pair<Version, Integer> getVersionUpdate() {
|
||||
return myVersionUpdate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Version getVersion() {
|
||||
return myVersionUpdate != null ? myVersionUpdate.first : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getNameVersion() {
|
||||
return myBundleName + ((myVersionUpdate != null) ? myVersionUpdate.first.toString() : "");
|
||||
}
|
||||
|
||||
private static Pair<String, Pair<Version, Integer>> getJDKNameVersionAndUpdate(String jvmPath) {
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setExePath(jvmPath + (SystemInfo.isMac ? "/Contents/Home/" : "/") + "jre" +
|
||||
File.separator + "bin" + File.separator + "java");
|
||||
commandLine.addParameter("-version");
|
||||
|
||||
String displayVersion = null;
|
||||
Pair<Version, Integer> versionAndUpdate = null;
|
||||
try {
|
||||
displayVersion = ExecUtil.readFirstLine(commandLine.createProcess().getErrorStream(), null);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
|
||||
if (displayVersion != null) {
|
||||
versionAndUpdate = VersionUtil.parseVersionAndUpdate(displayVersion, VERSION_UPDATE_PATTERNS);
|
||||
displayVersion = displayVersion.replaceFirst("\".*\"", "");
|
||||
}
|
||||
else {
|
||||
displayVersion = new File(jvmPath).getName();
|
||||
}
|
||||
|
||||
return Pair.create(displayVersion, versionAndUpdate);
|
||||
}
|
||||
|
||||
public boolean isBundled() {
|
||||
return myBundled;
|
||||
}
|
||||
|
||||
public void setBoot(boolean boot) {
|
||||
myBoot = boot;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed 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 com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class JdkBundleList {
|
||||
@NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.util.JdkBundleList");
|
||||
|
||||
private ArrayList<JdkBundle> bundleList = new ArrayList<JdkBundle>();
|
||||
private HashMap<String, JdkBundle> bundleMap = new HashMap<String, JdkBundle>();
|
||||
private HashMap<String, JdkBundle> nameVersionMap = new HashMap<String, JdkBundle>();
|
||||
|
||||
public void addBundle(JdkBundle bundle, boolean forceOldVersion) {
|
||||
JdkBundle bundleDescr = bundleMap.get(bundle.getBundleAsFile().getAbsolutePath());
|
||||
if (bundleDescr == null) {
|
||||
addMostRecent(bundle, forceOldVersion);
|
||||
}
|
||||
else {
|
||||
if (bundle.isBundled()) bundleDescr.setBundled(true); // preserve bundled flag
|
||||
if (bundle.isBoot()) bundleDescr.setBoot(true); // preserve boot flag
|
||||
}
|
||||
}
|
||||
|
||||
private void addMostRecent(JdkBundle bundleDescriptor, boolean forceOldVersion) {
|
||||
Pair<Version, Integer> versionUpdate = bundleDescriptor.getVersionUpdate();
|
||||
boolean updateVersionMap = versionUpdate != null;
|
||||
if (!bundleList.isEmpty() && updateVersionMap) {
|
||||
JdkBundle latestJdk = nameVersionMap.get(bundleDescriptor.getNameVersion());
|
||||
if (latestJdk != null) {
|
||||
Pair<Version, Integer> latestVersionUpdate = latestJdk.getVersionUpdate();
|
||||
if (latestVersionUpdate != null) {
|
||||
if (latestVersionUpdate.second >= versionUpdate.second) {
|
||||
if (!forceOldVersion) return; // do not add old non bundled jdk builds unless asked
|
||||
|
||||
updateVersionMap = false; // include bundled version but do not update map
|
||||
}
|
||||
else if (!latestJdk.isBoot() && !latestJdk.isBundled()) { // preserve boot and bundled versions
|
||||
bundleList.remove(latestJdk);
|
||||
nameVersionMap.remove(latestJdk.getNameVersion());
|
||||
bundleMap.remove(latestJdk.getBundleAsFile().getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bundleList.add(bundleDescriptor);
|
||||
bundleMap.put(bundleDescriptor.getBundleAsFile().getAbsolutePath(), bundleDescriptor);
|
||||
|
||||
if (updateVersionMap) {
|
||||
nameVersionMap.put(bundleDescriptor.getNameVersion(), bundleDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
public void addBundlesFromLocation(String location, @Nullable Version minVer, @Nullable Version maxVer) {
|
||||
File jvmLocation = new File(location);
|
||||
|
||||
if (!jvmLocation.exists()) {
|
||||
LOG.debug("Standard jvm location does not exists: " + jvmLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
File[] jvms = jvmLocation.listFiles();
|
||||
|
||||
if (jvms == null) {
|
||||
LOG.debug("Cannot get jvm list from: " + jvmLocation);
|
||||
return;
|
||||
}
|
||||
|
||||
for (File jvm : jvms) {
|
||||
JdkBundle jvmBundle = JdkBundle.createBundle(jvm, false, false);
|
||||
if (jvmBundle == null || jvmBundle.getVersionUpdate() == null) continue;
|
||||
|
||||
Version jdkVer = jvmBundle.getVersion();
|
||||
if (jdkVer == null) continue; // Skip unknown
|
||||
|
||||
if (minVer != null && jdkVer.lessThan(minVer.major, minVer.minor, minVer.bugfix)) {
|
||||
continue; // Skip below supported
|
||||
}
|
||||
|
||||
if (maxVer != null && maxVer.lessThan(jdkVer.major, jdkVer.minor, jdkVer.bugfix)) {
|
||||
continue; // Skip above supported
|
||||
}
|
||||
|
||||
addBundle(jvmBundle, false);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<JdkBundle> toArrayList() {
|
||||
return bundleList;
|
||||
}
|
||||
|
||||
public boolean contains(String path) {
|
||||
return bundleMap.keySet().contains(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed 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 com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.intellij.testFramework.UsefulTestCase.assertSameElements;
|
||||
|
||||
public class JdkBundleListTest {
|
||||
@Test
|
||||
public void testAddBundle() throws Exception {
|
||||
JdkBundle jb0 = new JdkBundle(new File("/jb0"), "java", Pair.create(new Version(1, 8, 0), new Integer(0)), true, false);
|
||||
JdkBundle jb1 = new JdkBundle(new File("/jb1"), "java", Pair.create(new Version(1, 8, 0), new Integer(1)), false, false);
|
||||
JdkBundle jb2 = new JdkBundle(new File("/jb2"), "java", Pair.create(new Version(1, 8, 0), new Integer(2)), false, false);
|
||||
JdkBundle jb3 = new JdkBundle(new File("/jb3"), "java", Pair.create(new Version(1, 8, 0), new Integer(3)), false, false);
|
||||
JdkBundle jb4 = new JdkBundle(new File("/jb4"), "java", Pair.create(new Version(1, 8, 0), new Integer(4)), false, false);
|
||||
|
||||
JdkBundle ob0 = new JdkBundle(new File("/ob0"), "openjdk", Pair.create(new Version(1, 8, 0), new Integer(0)), false, true);
|
||||
JdkBundle ob1 = new JdkBundle(new File("/ob1"), "openjdk", Pair.create(new Version(1, 8, 0), new Integer(1)), false, false);
|
||||
JdkBundle ob2 = new JdkBundle(new File("/ob2"), "openjdk", Pair.create(new Version(1, 8, 0), new Integer(2)), false, false);
|
||||
JdkBundle ob3 = new JdkBundle(new File("/ob3"), "openjdk", Pair.create(new Version(1, 8, 0), new Integer(3)), false, false);
|
||||
JdkBundle ob4 = new JdkBundle(new File("/ob4"), "openjdk", Pair.create(new Version(1, 8, 0), new Integer(4)), false, false);
|
||||
|
||||
JdkBundleList bundleList = new JdkBundleList();
|
||||
|
||||
bundleList.addBundle(jb3, false);
|
||||
bundleList.addBundle(ob1, false);
|
||||
bundleList.addBundle(jb2, false);
|
||||
bundleList.addBundle(ob2, false);
|
||||
bundleList.addBundle(jb0, true);
|
||||
bundleList.addBundle(ob0, true);
|
||||
bundleList.addBundle(jb1, false);
|
||||
bundleList.addBundle(ob4, false);
|
||||
bundleList.addBundle(jb4, false);
|
||||
bundleList.addBundle(ob3, false);
|
||||
|
||||
assertSameElements(bundleList.toArrayList(), Arrays.asList(jb4, ob4, jb0, ob0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed 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 com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static junit.framework.TestCase.*;
|
||||
|
||||
public class JdkBundleTest {
|
||||
|
||||
@Test
|
||||
public void testCreateBundle() throws Exception {
|
||||
if (SystemInfo.isWindows) return; // Windows is not supported so far
|
||||
File bootJDK = new File(System.getProperty("java.home")).getParentFile();
|
||||
if (SystemInfo.isMac) {
|
||||
bootJDK = bootJDK.getParentFile().getParentFile();
|
||||
}
|
||||
String verStr = System.getProperty("java.version");
|
||||
|
||||
JdkBundle bundle = JdkBundle.createBundle(bootJDK, true, true);
|
||||
assertNotNull(bundle);
|
||||
|
||||
assertTrue(bundle.isBoot());
|
||||
assertTrue(bundle.isBundled());
|
||||
|
||||
assertTrue(FileUtil.filesEqual(bundle.getBundleAsFile(), bootJDK));
|
||||
Pair<Version, Integer> verUpdate = bundle.getVersionUpdate();
|
||||
|
||||
assertNotNull(verUpdate);
|
||||
|
||||
assertEquals(verStr, verUpdate.first.toString() + "_" + verUpdate.second.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateBoot() throws Exception {
|
||||
if (SystemInfo.isWindows) return; // Windows is not supported so far
|
||||
File bootJDK = new File(System.getProperty("java.home")).getParentFile();
|
||||
if (SystemInfo.isMac) {
|
||||
bootJDK = bootJDK.getParentFile().getParentFile();
|
||||
}
|
||||
String verStr = System.getProperty("java.version");
|
||||
|
||||
JdkBundle bundle = JdkBundle.createBoot();
|
||||
|
||||
assertTrue(bundle.isBoot());
|
||||
assertFalse(bundle.isBundled());
|
||||
|
||||
assertTrue(FileUtil.filesEqual(bundle.getBundleAsFile(), bootJDK));
|
||||
Pair<Version, Integer> verUpdate = bundle.getVersionUpdate();
|
||||
|
||||
assertNotNull(verUpdate);
|
||||
|
||||
assertEquals(verStr, verUpdate.first.toString() + "_" + verUpdate.second.toString());
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -48,4 +49,41 @@ public class VersionUtil {
|
||||
(versions.length > 2) ? Integer.parseInt(versions[2]) : 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Pair<Version,Integer> parseVersionAndUpdate(@NotNull String version, @NotNull Pattern... patterns) {
|
||||
String[] versions = null;
|
||||
String updateStr = null;
|
||||
|
||||
for (Pattern pattern : patterns) {
|
||||
Matcher matcher = pattern.matcher(version);
|
||||
if (matcher.find()) {
|
||||
String versionGroup = matcher.group(1);
|
||||
if (versionGroup != null) {
|
||||
updateStr = matcher.groupCount() > 1 ? matcher.group(2) : null;
|
||||
versions = versionGroup.split("\\.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (versions == null || versions.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer update = null;
|
||||
if (updateStr != null) {
|
||||
try {
|
||||
update = Integer.parseInt(updateStr);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (update == null) update = new Integer(0); // Treating no update info as update 0
|
||||
|
||||
return Pair.create(
|
||||
new Version(Integer.parseInt(versions[0]), Integer.parseInt(versions[1]), (versions.length > 2) ? Integer.parseInt(versions[2]) : 0),
|
||||
update);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Version;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -13,8 +14,13 @@ public class VersionUtilTest extends TestCase {
|
||||
Pattern.compile("^openjdk version \"([\\d]+\\.[\\d]+\\.[\\d]+)_[\\d]+.*\".*", Pattern.MULTILINE),
|
||||
Pattern.compile("^[a-zA-Z() \\d]*([\\d]+\\.[\\d]+\\.?[\\d]*).*", Pattern.MULTILINE)
|
||||
};
|
||||
private static final Pattern[] VERSION_UPDATE_PATTERNS = {
|
||||
Pattern.compile("^java version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+)\".*", Pattern.MULTILINE),
|
||||
Pattern.compile("^openjdk version \"([\\d]+\\.[\\d]+\\.[\\d]+)_([\\d]+).*\".*", Pattern.MULTILINE),
|
||||
Pattern.compile("^[a-zA-Z() \"\\d]*([\\d]+\\.[\\d]+\\.?[\\d]*).*", Pattern.MULTILINE)
|
||||
};
|
||||
|
||||
private static final Object[][] testData = {
|
||||
private static final Object[][] testDataVersion = {
|
||||
{"GNU gdb 6.3.50-20050815 (Apple version gdb-1824) (Wed Feb 6 22:51:23 UTC 2013)", new Version(6, 3, 50)},
|
||||
{"GNU gdb (GDB) 7.6", new Version(7, 6, 0)},
|
||||
{"GNU gdb (GDB) 7.6something123", new Version(7, 6, 0)},
|
||||
@@ -29,10 +35,27 @@ public class VersionUtilTest extends TestCase {
|
||||
{"openjdk version \"1.8.1_60-release\"", new Version(1, 8, 1)}
|
||||
};
|
||||
|
||||
private static final Object[][] testDataVersionUpdate = {
|
||||
{"java version \"1.6.0\"", new Version(1, 6, 0), new Integer(0)},
|
||||
{"java version \"1.6.0_36\"", new Version(1, 6, 0), new Integer(36)},
|
||||
{"java version \"1.7.0_85\"", new Version(1, 7, 0), new Integer(85)},
|
||||
{"openjdk version \"1.8.0_45-internal\"", new Version(1, 8, 0), new Integer(45)},
|
||||
{"openjdk version \"1.8.1_60-release\"", new Version(1, 8, 1), new Integer(60)}
|
||||
};
|
||||
|
||||
public void testParseVersion() throws Exception {
|
||||
for (Object[] aTestData : testData) {
|
||||
for (Object[] aTestData : testDataVersion) {
|
||||
String versionString = (String)aTestData[0];
|
||||
assertEquals("For \"" + versionString + "\"", aTestData[1], VersionUtil.parseVersion(versionString, VERSION_PATTERNS));
|
||||
}
|
||||
}
|
||||
public void testParseVersionAndUpdate() throws Exception {
|
||||
for (Object[] aTestData : testDataVersionUpdate) {
|
||||
String versionString = (String)aTestData[0];
|
||||
Pair<Version, Integer> versionAndUpdate = VersionUtil.parseVersionAndUpdate(versionString, VERSION_UPDATE_PATTERNS);
|
||||
assertNotNull(versionAndUpdate);
|
||||
assertEquals("For \"" + versionString + "\"", aTestData[1], versionAndUpdate.first);
|
||||
assertEquals("For \"" + versionString + "\"", aTestData[2], versionAndUpdate.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user