blob: 346b9cf718182d4cace5fea6815b24953aa03e1f [file] [log] [blame]
/*
* Copyright 2000-2014 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.facet.impl.ui.libraries.versions;
import com.intellij.facet.frameworks.LibrariesDownloadAssistant;
import com.intellij.facet.frameworks.beans.Artifact;
import com.intellij.facet.ui.libraries.FacetLibrariesValidator;
import com.intellij.facet.ui.libraries.FacetLibrariesValidatorDescription;
import com.intellij.facet.ui.libraries.LibraryInfo;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.libraries.JarVersionDetectionUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class VersionsComponent {
private JPanel myMainPanel;
private static final String UNKNOWN_RI_NAME = "Unknown";
private final @NotNull Module myModule;
private final FacetLibrariesValidator myValidator;
private final ButtonGroup myButtonGroup = new ButtonGroup();
private final Map<String, Pair<JRadioButton, JComboBox>> myButtons = new HashMap<String, Pair<JRadioButton, JComboBox>>();
private Artifact myCurrentVersion = null;
public VersionsComponent(@NotNull final Module module, FacetLibrariesValidator validator) {
myModule = module;
myValidator = validator;
}
public JPanel getJComponent() {
if (myMainPanel == null) {
init();
}
return myMainPanel;
}
@Nullable
public Artifact getCurrentVersion() {
return myCurrentVersion;
}
private void init() {
myMainPanel = new JPanel(new GridBagLayout());
Set<String> referenceImplementations = getRIs();
if (referenceImplementations.size() == 1) {
String ri = referenceImplementations.iterator().next();
addSingletonReferenceImplementationUI(ri);
}
else {
for (String ri : referenceImplementations) {
addMultipleReferenceImplementationUI(ri);
if (myCurrentVersion == null) {
myCurrentVersion = getCurrentVersion(ri);
}
}
if (myCurrentVersion != null) {
Pair<JRadioButton, JComboBox> currentPair = myButtons.get(myCurrentVersion.getName());
if (currentPair != null) {
currentPair.first.setSelected(true);
currentPair.second.setSelectedItem(myCurrentVersion);
for (Pair<JRadioButton, JComboBox> buttonsPair : myButtons.values()) {
buttonsPair.second.setEnabled(buttonsPair == currentPair);
}
}
}
}
}
@Nullable
protected String getFacetDetectionClass(@NotNull String currentRI) {
return null;
}
@NotNull
protected abstract Artifact[] getLibraries();
@Nullable
private Artifact getCurrentVersion(@NotNull String currentRI) {
String detectionClass = getFacetDetectionClass(currentRI);
if (detectionClass != null) {
final String version = JarVersionDetectionUtil.detectJarVersion(detectionClass, myModule);
if (version != null) {
Artifact approximatedVersion = null;
for (Artifact info : getLibraries()) {
if (version.equals(info.getVersion())) {
return info;
}
if (version.contains(info.getVersion())) {
approximatedVersion = info;
}
}
return approximatedVersion;
}
}
return null;
}
private List<Artifact> getSupportedVersions(@NotNull String ri) {
List<Artifact> versions = new ArrayList<Artifact>();
for (Artifact version : getLibraries()) {
if (ri.equals(version.getName())) {
versions.add(version);
}
}
return versions;
}
private void addSingletonReferenceImplementationUI(@NotNull final String ri) {
JComboBox comboBox = createComboBox(ri);
addToPanel(new JLabel(ri), comboBox);
Artifact version = getCurrentVersion(ri);
if (version != null) {
comboBox.setSelectedItem(version);
}
}
private void addMultipleReferenceImplementationUI(@NotNull final String ri) {
final JRadioButton radioButton = createRadioButton(ri);
final JComboBox comboBox = createComboBox(ri);
comboBox.setEnabled(false);
addToPanel(radioButton, comboBox);
myButtons.put(ri, Pair.create(radioButton, comboBox));
myButtonGroup.add(radioButton);
}
private void addToPanel(@NotNull JComponent first, @NotNull JComponent second) {
myMainPanel.add(first, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.LINE_START,
GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0));
myMainPanel.add(second,
new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.LINE_END, GridBagConstraints.BOTH,
new Insets(2, 2, 2, 2), 0, 0));
}
private JRadioButton createRadioButton(final String ri) {
final JRadioButton radioButton = new JRadioButton(ri);
radioButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
for (Pair<JRadioButton, JComboBox> pair : myButtons.values()) {
if (pair.getFirst().equals(radioButton)) {
JComboBox comboBox = pair.second;
comboBox.setEnabled(true);
Artifact currentVersion = getCurrentVersion(ri);
if (currentVersion != null) {
comboBox.setSelectedItem(currentVersion);
}
else {
if (comboBox.getSelectedIndex() < 0) {
comboBox.setSelectedItem(getAppropriateVersion(getSupportedVersions(ri)));
}
else {
updateCurrentVersion(comboBox); // activate already selected
}
}
}
else {
pair.second.setEnabled(false);
}
}
}
});
return radioButton;
}
private JComboBox createComboBox(String ri) {
final JComboBox comboBox = new JComboBox();
List<Artifact> versions = getSupportedVersions(ri);
comboBox.setModel(new CollectionComboBoxModel(versions, null));
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateCurrentVersion(comboBox);
}
});
return comboBox;
}
private void updateCurrentVersion(JComboBox comboBox) {
final Artifact versionInfo = getSelectedVersion(comboBox);
if (versionInfo != null) {
myCurrentVersion = versionInfo;
myValidator.setDescription(getFacetLibrariesValidatorDescription(versionInfo));
myValidator.setRequiredLibraries(getRequiredLibraries(versionInfo));
}
}
protected FacetLibrariesValidatorDescription getFacetLibrariesValidatorDescription(Artifact version) {
return new FacetLibrariesValidatorDescription(version.getVersion()) {
@NonNls
public String getDefaultLibraryName() {
if (myCurrentVersion != null) {
String ri = myCurrentVersion.getName();
String version = myCurrentVersion.getVersion();
return StringUtil.isEmptyOrSpaces(ri) ? version : ri + "." + version;
}
return super.getDefaultLibraryName();
}
};
}
@Nullable
private static Artifact getAppropriateVersion(List<Artifact> versions) {
return versions.size() > 0 ? versions.get(0) : null;
}
private static LibraryInfo[] getRequiredLibraries(Artifact version) {
final LibraryInfo[] infos = LibrariesDownloadAssistant.getLibraryInfos(version);
return infos == null ? LibraryInfo.EMPTY_ARRAY : infos;
}
@Nullable
private static Artifact getSelectedVersion(@NotNull JComboBox comboBox) {
final Object version = comboBox.getModel().getSelectedItem();
return version instanceof Artifact ? (Artifact)version : null;
}
public FacetLibrariesValidator getValidator() {
return myValidator;
}
@NotNull
public Module getModule() {
return myModule;
}
public Set<String> getRIs() {
Set<String> ris = new HashSet<String>();
for (Artifact version : getLibraries()) {
String ri = version.getName();
if (!StringUtil.isEmptyOrSpaces(ri)) {
ris.add(ri);
}
else {
ris.add(UNKNOWN_RI_NAME);
}
}
return ris;
}
}