bcacc235a2e083373256b8fe00e1a1b647955e8a
[idea/community.git] / java / compiler / impl / src / com / intellij / compiler / options / ValidationConfigurable.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.compiler.options;
17
18 import com.intellij.ide.util.ElementsChooser;
19 import com.intellij.openapi.compiler.Compiler;
20 import com.intellij.openapi.compiler.CompilerBundle;
21 import com.intellij.openapi.compiler.CompilerManager;
22 import com.intellij.openapi.compiler.Validator;
23 import com.intellij.openapi.compiler.options.ExcludedEntriesConfigurable;
24 import com.intellij.openapi.compiler.options.ExcludesConfiguration;
25 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
26 import com.intellij.openapi.module.Module;
27 import com.intellij.openapi.module.ModuleManager;
28 import com.intellij.openapi.options.Configurable;
29 import com.intellij.openapi.options.ConfigurationException;
30 import com.intellij.openapi.options.SearchableConfigurable;
31 import com.intellij.openapi.project.Project;
32 import com.intellij.openapi.roots.ModuleRootManager;
33 import com.intellij.openapi.roots.ProjectFileIndex;
34 import com.intellij.openapi.roots.ProjectRootManager;
35 import com.intellij.openapi.vfs.VirtualFile;
36 import com.intellij.ui.IdeBorderFactory;
37 import com.intellij.uiDesigner.core.GridConstraints;
38 import com.intellij.util.NullableFunction;
39 import com.intellij.util.SmartList;
40 import com.intellij.util.containers.ContainerUtil;
41 import com.intellij.util.ui.JBUI;
42 import gnu.trove.THashSet;
43 import gnu.trove.TObjectHashingStrategy;
44 import org.jetbrains.annotations.NotNull;
45
46 import javax.swing.*;
47 import java.util.*;
48
49 /**
50  * @author Dmitry Avdeev
51  */
52 public class ValidationConfigurable implements SearchableConfigurable, Configurable.NoScroll {
53
54   private JPanel myPanel;
55   private JCheckBox myValidateBox;
56   private ElementsChooser<Compiler> myValidators;
57   private JPanel myExcludedEntriesPanel;
58   private JPanel myValidatorsPanel;
59   private final Project myProject;
60   private final ValidationConfiguration myConfiguration;
61   private final ExcludedEntriesConfigurable myExcludedConfigurable;
62
63   public ValidationConfigurable(final Project project) {
64     myProject = project;
65     myConfiguration = ValidationConfiguration.getInstance(myProject);
66     myExcludedConfigurable = createExcludedConfigurable(project);
67
68     myValidatorsPanel.setBorder(IdeBorderFactory.createTitledBorder("Validators:", false, JBUI.insetsTop(8)).setShowLine(false));
69     myValidators.getEmptyText().setText(CompilerBundle.message("no.validators"));
70
71     myExcludedEntriesPanel.setBorder(IdeBorderFactory.createTitledBorder("Exclude from validation:", false, JBUI.insetsTop(8)).setShowLine(false));
72   }
73
74   private static ExcludedEntriesConfigurable createExcludedConfigurable(final Project project) {
75     final ExcludesConfiguration configuration = ValidationConfiguration.getExcludedEntriesConfiguration(project);
76     final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
77     final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, false, false, false, true) {
78       @Override
79       public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
80         return super.isFileVisible(file, showHiddenFiles) && (project.isDefault() || !index.isExcluded(file));
81       }
82     };
83
84     List<VirtualFile> allContentRoots = new ArrayList<>();
85     for (final Module module: ModuleManager.getInstance(project).getModules()) {
86       final VirtualFile[] moduleContentRoots = ModuleRootManager.getInstance(module).getContentRoots();
87       Collections.addAll(allContentRoots, moduleContentRoots);
88     }
89     descriptor.setRoots(allContentRoots);
90     return new ExcludedEntriesConfigurable(project, descriptor, configuration);
91   }
92
93   @Override
94   @NotNull
95   public String getId() {
96     return "project.validation";
97   }
98
99   @Override
100   public String getDisplayName() {
101     return CompilerBundle.message("validation.display.name");
102   }
103
104   @Override
105   public String getHelpTopic() {
106     return "reference.projectsettings.compiler.validation";
107   }
108
109   @Override
110   public JComponent createComponent() {
111     final GridConstraints constraints = new GridConstraints();
112     constraints.setFill(GridConstraints.FILL_BOTH);
113     myExcludedEntriesPanel.add(myExcludedConfigurable.createComponent(), constraints);
114     return myPanel;
115   }
116
117   @Override
118   public boolean isModified() {
119     List<Compiler> selectedElements = myValidators.getMarkedElements();
120     List<Compiler> markedValidators = getMarkedValidators();
121     if (markedValidators.size() != selectedElements.size()) {
122       return true;
123     }
124     Set<Compiler> set = new THashSet<>(selectedElements, new TObjectHashingStrategy<Compiler>() {
125       @Override
126       public int computeHashCode(Compiler object) {
127         return object.getDescription().hashCode();
128       }
129
130       @Override
131       public boolean equals(Compiler o1, Compiler o2) {
132         return o1.getDescription().equals(o2.getDescription());
133       }
134     });
135     return myConfiguration.isValidateOnBuild() != myValidateBox.isSelected() ||
136         set.retainAll(markedValidators) ||
137         myExcludedConfigurable.isModified();
138   }
139
140   @Override
141   public void apply() throws ConfigurationException {
142     myConfiguration.setValidateOnBuild(myValidateBox.isSelected());
143     for (int i = 0; i < myValidators.getElementCount(); i++) {
144       final Compiler validator = myValidators.getElementAt(i);
145       myConfiguration.setSelected(validator,  myValidators.isElementMarked(validator));
146     }
147     myExcludedConfigurable.apply();
148   }
149
150   @Override
151   public void reset() {
152     myValidateBox.setSelected(myConfiguration.isValidateOnBuild());
153     final List<Compiler> validators = getValidators();
154     Collections.sort(validators, Comparator.comparing(Compiler::getDescription));
155     myValidators.setElements(validators, false);
156     myValidators.markElements(getMarkedValidators());
157     myExcludedConfigurable.reset();
158   }
159
160   private List<Compiler> getMarkedValidators() {
161     final List<Compiler> validators = getValidators();
162     return ContainerUtil.mapNotNull(validators, (NullableFunction<Compiler, Compiler>)validator -> myConfiguration.isSelected(validator) ? validator : null);
163   }
164
165   private List<Compiler> getValidators() {
166     final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
167     return new SmartList<>(compilerManager.getCompilers(Validator.class));
168   }
169
170   @Override
171   public void disposeUIResources() {
172     myExcludedConfigurable.disposeUIResources();
173   }
174
175   private void createUIComponents() {
176     myValidators = new ElementsChooser<Compiler>(true) {
177       @Override
178       protected String getItemText(@NotNull final Compiler validator) {
179         final String description = validator.getDescription();
180         return description.replace(" Validator", "").replace(" validator", "");
181       }
182     };
183   }
184 }