Merge remote-tracking branch 'origin/master'

This commit is contained in:
Liana Bakradze
2014-09-24 14:03:49 +04:00
70 changed files with 1056 additions and 256 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -41,8 +41,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class RemoteConfiguration extends ModuleBasedConfiguration<JavaRunConfigurationModule> implements
RunConfigurationWithSuppressedDefaultRunAction {
public class RemoteConfiguration extends ModuleBasedConfiguration<JavaRunConfigurationModule>
implements RunConfigurationWithSuppressedDefaultRunAction, RemoteRunProfile {
@Override
public void writeExternal(final Element element) throws WriteExternalException {
@@ -65,9 +65,9 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
return null;
}
private PsiAnnotation getHardcodedContractAnnotation(PsiMethod listOwner) {
List<MethodContract> contracts = HardcodedContracts.getHardcodedContracts(listOwner, null);
return contracts.isEmpty() ? null : createContractAnnotation(contracts, true);
private PsiAnnotation getHardcodedContractAnnotation(PsiMethod method) {
List<MethodContract> contracts = HardcodedContracts.getHardcodedContracts(method, null);
return contracts.isEmpty() ? null : createContractAnnotation(contracts, !"java.lang.System.exit".equals(PsiUtil.getMemberQualifiedName(method)));
}
private static boolean ignoreBytecodeInference(PsiModifierListOwner owner, String annotationFQN) {
@@ -95,7 +95,7 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
private PsiAnnotation createContractAnnotation(List<MethodContract> contracts, boolean pure) {
final String attrs;
if (!contracts.isEmpty() && pure) {
attrs = "value = " + "\"" + StringUtil.join(contracts, "; ") + "\"; pure = true";
attrs = "value = " + "\"" + StringUtil.join(contracts, "; ") + "\", pure = true";
} else if (pure) {
attrs = "pure = true";
} else if (!contracts.isEmpty()) {
@@ -17,13 +17,16 @@ package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
@@ -44,7 +47,7 @@ public class ContractInference {
@NotNull
public static List<MethodContract> inferContracts(@NotNull final PsiMethod method) {
if (method instanceof PsiCompiledElement) {
if (isLibraryCode(method)) {
return Collections.emptyList();
}
@@ -56,6 +59,12 @@ public class ContractInference {
}
});
}
static boolean isLibraryCode(@NotNull PsiMethod method) {
if (method instanceof PsiCompiledElement) return true;
VirtualFile virtualFile = PsiUtilCore.getVirtualFile(method);
return virtualFile != null && FileIndexFacade.getInstance(method.getProject()).isInLibrarySource(virtualFile);
}
}
class ContractInferenceInterpreter {
@@ -124,7 +124,7 @@ public class DataFlowRunner {
joinInstructions.add(myInstructions[((GotoInstruction)instruction).getOffset()]);
} else if (instruction instanceof ConditionalGotoInstruction) {
joinInstructions.add(myInstructions[((ConditionalGotoInstruction)instruction).getOffset()]);
} else if (instruction instanceof MethodCallInstruction) {
} else if (instruction instanceof MethodCallInstruction && !((MethodCallInstruction)instruction).getContracts().isEmpty()) {
joinInstructions.add(myInstructions[index + 1]);
}
}
@@ -34,7 +34,7 @@ import java.util.List;
public class PurityInference {
public static boolean inferPurity(@NotNull final PsiMethod method) {
if (method instanceof PsiCompiledElement || method.getReturnType() == PsiType.VOID || method.getBody() == null || method.isConstructor()) {
if (ContractInference.isLibraryCode(method) || method.getReturnType() == PsiType.VOID || method.getBody() == null || method.isConstructor()) {
return false;
}
@@ -72,7 +72,7 @@ public class TabPostFormatProcessor implements PostFormatProcessor {
if (!source.isValid()) return range;
PsiFile file = source.getContainingFile();
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptionsByFile(file);
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptionsByFile(file, range);
boolean useTabs = indentOptions.USE_TAB_CHARACTER;
boolean smartTabs = indentOptions.SMART_TABS;
@@ -746,7 +746,7 @@ public class JavaDocInfoGenerator {
buffer.append("(");
boolean first = true;
for (PsiNameValuePair pair : attributes) {
if (!first) buffer.append("&nbsp;");
if (!first) buffer.append(",&nbsp;");
first = false;
final String name = pair.getName();
if (name != null) {
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -1,8 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -0,0 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -1,8 +1,8 @@
class A {
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
private void foo(boolean b) {
int x;
if (b) {
System.out.println(x);
}
}
}
@@ -920,4 +920,81 @@ public class Test {
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_UNSELECT_WORD_AT_CARET)
assert 'return field;' == myFixture.editor.selectionModel.selectedText
}
public void "test expand and collapse regions in selection"() {
def text = """
class Foo {
public static void main() {
new Runnable(){
public void run() {
}
}.run();
}
}
"""
configure text
assertEquals 3, foldRegionsCount
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_ALL_REGIONS)
assertEquals 3, expandedFoldRegionsCount
myFixture.editor.selectionModel.setSelection(text.indexOf("new"), text.indexOf("run();"))
myFixture.performEditorAction(IdeActions.ACTION_COLLAPSE_ALL_REGIONS)
assertEquals 1, expandedFoldRegionsCount
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_ALL_REGIONS)
assertEquals 3, expandedFoldRegionsCount
}
public void "test expand and collapse recursively"() {
def text = """
class Foo {
public static void main() {
new Runnable(){
public void run() {
}
}.run();
}
}
"""
configure text
assertEquals 3, foldRegionsCount
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_ALL_REGIONS)
assertEquals 3, expandedFoldRegionsCount
myFixture.editor.caretModel.moveToOffset(text.indexOf("new"))
myFixture.performEditorAction(IdeActions.ACTION_COLLAPSE_REGION_RECURSIVELY)
assertEquals 1, expandedFoldRegionsCount
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_REGION_RECURSIVELY)
assertEquals 3, expandedFoldRegionsCount
}
public void "test expand to level"() {
def text = """
class Foo {
public static void main() {
new Runnable(){
public void run() {
}
}.run();
}
}
"""
configure text
assertEquals 3, foldRegionsCount
myFixture.editor.caretModel.moveToOffset(text.indexOf("new"))
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_TO_LEVEL_1)
assertEquals 2, expandedFoldRegionsCount
myFixture.performEditorAction(IdeActions.ACTION_EXPAND_ALL_TO_LEVEL_1)
assertEquals 1, expandedFoldRegionsCount
}
private int getFoldRegionsCount() {
return myFixture.editor.foldingModel.allFoldRegions.length
}
private int getExpandedFoldRegionsCount() {
return myFixture.editor.foldingModel.allFoldRegions.count { it.isExpanded() ? 1 : 0}
}
}
@@ -38,6 +38,7 @@ public class FileIndentProviderTest extends LightPlatformCodeInsightFixtureTestC
private final static FileIndentOptionsProvider TEST_FILE_INDENT_OPTIONS_PROVIDER = new TestIndentOptionsProvider();
private static CommonCodeStyleSettings.IndentOptions myTestIndentOptions;
private static boolean myUseOnFullReformat;
@Override
protected void setUp() throws Exception {
@@ -54,6 +55,7 @@ public class FileIndentProviderTest extends LightPlatformCodeInsightFixtureTestC
Extensions.getRootArea().getExtensionPoint(FileIndentOptionsProvider.EP_NAME);
extensionPoint.unregisterExtension(TEST_FILE_INDENT_OPTIONS_PROVIDER);
myTestIndentOptions = null;
myUseOnFullReformat = false;
super.tearDown();
}
@@ -80,6 +82,11 @@ public class FileIndentProviderTest extends LightPlatformCodeInsightFixtureTestC
public CommonCodeStyleSettings.IndentOptions getIndentOptions(@NotNull PsiFile file) {
return myTestIndentOptions;
}
@Override
public boolean useOnFullReformat() {
return myUseOnFullReformat;
}
}
public void testTypeEnter() {
@@ -111,6 +118,16 @@ public class FileIndentProviderTest extends LightPlatformCodeInsightFixtureTestC
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
public void testReformatFileSupported() {
myUseOnFullReformat = true;
myTestIndentOptions.INDENT_SIZE = 3;
myTestIndentOptions.TAB_SIZE = 2;
myTestIndentOptions.USE_TAB_CHARACTER = true;
PsiFile file = myFixture.configureByFile(getTestName(true) + "_before.java");
CodeStyleManager.getInstance(getProject()).reformat(file);
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
public void testReformatText() {
myTestIndentOptions.INDENT_SIZE = 3;
myTestIndentOptions.TAB_SIZE = 2;
@@ -119,4 +136,27 @@ public class FileIndentProviderTest extends LightPlatformCodeInsightFixtureTestC
CodeStyleManager.getInstance(getProject()).reformatText(file, 0, file.getTextRange().getEndOffset());
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
/**
* Reformat using indent provider if a part of the file is selected.
*/
public void testReformatTextRange() {
myTestIndentOptions.INDENT_SIZE = 3;
myTestIndentOptions.TAB_SIZE = 2;
myTestIndentOptions.USE_TAB_CHARACTER = true;
PsiFile file = myFixture.configureByFile(getTestName(true) + "_before.java");
// Just any range smaller than the file
CodeStyleManager.getInstance(getProject()).reformatText(file, 6, file.getTextRange().getEndOffset() - 1);
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
public void testReformatTextFullSupported() {
myUseOnFullReformat = true;
myTestIndentOptions.INDENT_SIZE = 3;
myTestIndentOptions.TAB_SIZE = 2;
myTestIndentOptions.USE_TAB_CHARACTER = true;
PsiFile file = myFixture.configureByFile(getTestName(true) + "_before.java");
CodeStyleManager.getInstance(getProject()).reformatText(file, 0, file.getTextRange().getEndOffset());
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
}
@@ -0,0 +1,25 @@
/*
* 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.execution.configurations;
/**
* Special interface for remote debug processes
*
* @author Konstantin Bulenkov
* @since 14
*/
public interface RemoteRunProfile extends RunProfile {
}
@@ -663,26 +663,65 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
@NotNull
public IndentOptions getIndentOptionsByFile(@Nullable PsiFile file) {
return getIndentOptionsByFile(file, false);
return getIndentOptionsByFile(file, null);
}
@NotNull
public IndentOptions getIndentOptionsByFile(@Nullable PsiFile file, boolean ignoreDocOptions) {
public IndentOptions getIndentOptionsByFile(@Nullable PsiFile file, @Nullable TextRange formatRange) {
return getIndentOptionsByFile(file, formatRange, false);
}
/**
* Retrieves indent options for PSI file from an associated document or (if not defined in the document) from file indent options
* providers.
* @param file The PSI file to retrieve options for.
* @param formatRange The text range within the file for formatting purposes or null if there is either no specific range or multiple
* ranges. If the range covers the entire file (full reformat), options stored in the document are ignored and
* indent options are taken from file indent options providers.
* @param ignoreDocOptions Ignore options stored in the document and use file indent options providers even if there is no text range
* or the text range doesn't cover the entire file.
* @return Indent options from the associated document or file indent options providers.
* @see com.intellij.psi.codeStyle.FileIndentOptionsProvider
*/
@NotNull
public IndentOptions getIndentOptionsByFile(@Nullable PsiFile file, @Nullable TextRange formatRange, boolean ignoreDocOptions) {
if (file != null && file.isValid()) {
if (!ignoreDocOptions) {
boolean isFullReformat = isFileFullyCoveredByRange(file, formatRange);
if (!ignoreDocOptions && !isFullReformat) {
IndentOptions docOptions = IndentOptions.retrieveFromAssociatedDocument(file);
if (docOptions != null) return docOptions;
}
FileIndentOptionsProvider[] providers = Extensions.getExtensions(FileIndentOptionsProvider.EP_NAME);
for (FileIndentOptionsProvider provider : providers) {
IndentOptions indentOptions = provider.getIndentOptions(file);
if (indentOptions != null) return indentOptions;
if (!isFullReformat || provider.useOnFullReformat()) {
IndentOptions indentOptions = provider.getIndentOptions(file);
if (indentOptions != null) {
logIndentOptions(file, provider, indentOptions);
return indentOptions;
}
}
}
return getIndentOptions(file.getFileType());
}
else
return OTHER_INDENT_OPTIONS;
}
private static boolean isFileFullyCoveredByRange(@NotNull PsiFile file, @Nullable TextRange formatRange) {
return
formatRange != null &&
file.getTextRange().equals(formatRange);
}
private static void logIndentOptions(@NotNull PsiFile file,
@NotNull FileIndentOptionsProvider provider,
@NotNull IndentOptions options) {
LOG.info("Indent options returned by " + provider.getClass().getName() +
" for " + file.getName() +
": indent size=" + options.INDENT_SIZE +
", use tabs=" + options.USE_TAB_CHARACTER +
", tab size=" + options.TAB_SIZE);
}
@Nullable
private IndentOptions getLanguageIndentOptions(@Nullable FileType fileType) {
@@ -139,7 +139,7 @@ public class CodeStyleSettingsManager implements PersistentStateComponent<Elemen
if (documentManager != null) {
PsiFile file = documentManager.getPsiFile(document);
if (file != null) {
CommonCodeStyleSettings.IndentOptions indentOptions = getSettings(project).getIndentOptionsByFile(file, true);
CommonCodeStyleSettings.IndentOptions indentOptions = getSettings(project).getIndentOptionsByFile(file, null, true);
indentOptions.associateWithDocument(document);
}
}
@@ -33,4 +33,12 @@ public abstract class FileIndentOptionsProvider {
*/
@Nullable
public abstract CommonCodeStyleSettings.IndentOptions getIndentOptions(@NotNull PsiFile file);
/**
* Tells if the provider can be used when a complete file is reformatted.
* @return True by default
*/
public boolean useOnFullReformat() {
return true;
}
}
@@ -22,6 +22,7 @@ import com.intellij.icons.AllIcons;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Toggleable;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
import com.intellij.profile.codeInspection.SeverityProvider;
import com.intellij.profile.codeInspection.ui.LevelChooserAction;
@@ -33,7 +34,7 @@ import java.util.SortedSet;
/**
* @author Dmitry Batkovich
*/
public class InspectionFilterAction extends DefaultActionGroup {
public class InspectionFilterAction extends DefaultActionGroup implements Toggleable {
private final SeverityRegistrar mySeverityRegistrar;
private final InspectionsFilter myInspectionsFilter;
@@ -46,6 +47,12 @@ public class InspectionFilterAction extends DefaultActionGroup {
tune();
}
@Override
public void update(AnActionEvent e) {
super.update(e);
e.getPresentation().putClientProperty(Toggleable.SELECTED_PROPERTY, !myInspectionsFilter.isEmptyFilter());
}
private void tune() {
addAction(new ShowEnabledOrDisabledInspectionsAction(null));
addAction(new ShowEnabledOrDisabledInspectionsAction(true));
@@ -84,14 +84,14 @@ public class InspectionsConfigTreeTable extends TreeTable {
final int row = rowAtPoint(point);
final Object maybeIcon = getModel().getValueAt(row, column);
if (maybeIcon instanceof MultiScopeSeverityIcon) {
final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap =
final LinkedHashMap<String, HighlightDisplayLevel> scopeToAverageSeverityMap =
((MultiScopeSeverityIcon)maybeIcon).getScopeToAverageSeverityMap();
final JComponent component;
if (scopeToAverageSeverityMap.size() == 1) {
final HighlightSeverity severity = ContainerUtil.getFirstItem(scopeToAverageSeverityMap.values());
final HighlightDisplayLevel level = ContainerUtil.getFirstItem(scopeToAverageSeverityMap.values());
final JLabel label = new JLabel();
label.setIcon(HighlightDisplayLevel.find(severity).getIcon());
label.setText(SingleInspectionProfilePanel.renderSeverity(severity));
label.setIcon(level.getIcon());
label.setText(SingleInspectionProfilePanel.renderSeverity(level.getSeverity()));
component = label;
} else {
component = new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap);
@@ -19,6 +19,7 @@ package com.intellij.profile.codeInspection.ui.inspectionsTree;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.profile.codeInspection.ui.ScopeOrderComparator;
import com.intellij.ui.JBColor;
@@ -31,26 +32,36 @@ import java.util.List;
* @author Dmitry Batkovich
*/
public class MultiScopeSeverityIcon implements Icon {
private final static Logger LOG = Logger.getInstance(MultiScopeSeverityIcon.class);
private final static JBColor MIXED_SEVERITY_COLOR = JBColor.DARK_GRAY;
private final static int SIZE = 12;
private final LinkedHashMap<String, HighlightSeverity> myScopeToAverageSeverityMap;
private final LinkedHashMap<String, HighlightDisplayLevel> myScopeToAverageSeverityMap;
public MultiScopeSeverityIcon(final Map<String, HighlightSeverity> scopeToAverageSeverityMap,
final String defaultScopeName,
final InspectionProfileImpl inspectionProfile) {
final List<String> sortedScopeNames = new ArrayList<String>(scopeToAverageSeverityMap.keySet());
myScopeToAverageSeverityMap = new LinkedHashMap<String, HighlightSeverity>();
myScopeToAverageSeverityMap = new LinkedHashMap<String, HighlightDisplayLevel>();
Collections.sort(sortedScopeNames, new ScopeOrderComparator(inspectionProfile));
sortedScopeNames.remove(defaultScopeName);
sortedScopeNames.add(defaultScopeName);
for (final String scopeName : sortedScopeNames) {
myScopeToAverageSeverityMap.put(scopeName, scopeToAverageSeverityMap.get(scopeName));
final HighlightSeverity severity = scopeToAverageSeverityMap.get(scopeName);
if (severity == null) {
continue;
}
final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
if (level == null) {
continue;
}
myScopeToAverageSeverityMap.put(scopeName, level);
}
}
public LinkedHashMap<String, HighlightSeverity> getScopeToAverageSeverityMap() {
public LinkedHashMap<String, HighlightDisplayLevel> getScopeToAverageSeverityMap() {
return myScopeToAverageSeverityMap;
}
@@ -60,10 +71,10 @@ public class MultiScopeSeverityIcon implements Icon {
final int partWidth = iconWidth / myScopeToAverageSeverityMap.size();
final Collection<HighlightSeverity> values = myScopeToAverageSeverityMap.values();
final Collection<HighlightDisplayLevel> values = myScopeToAverageSeverityMap.values();
int idx = 0;
for (final HighlightSeverity severity : values) {
final Icon icon = HighlightDisplayLevel.find(severity).getIcon();
for (final HighlightDisplayLevel level : values) {
final Icon icon = level.getIcon();
g.setColor(icon instanceof HighlightDisplayLevel.SingleColorIconWithMask ?
((HighlightDisplayLevel.SingleColorIconWithMask)icon).getColor() : MIXED_SEVERITY_COLOR);
final int x = i + partWidth * idx;
@@ -16,7 +16,6 @@
package com.intellij.profile.codeInspection.ui.inspectionsTree;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.UIUtil;
@@ -37,7 +36,7 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
private final static int SCOPE_COLUMN = 0;
private final static int SEVERITY_COLUMN = 1;
public ScopesAndSeveritiesHintTable(final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap) {
public ScopesAndSeveritiesHintTable(final LinkedHashMap<String, HighlightDisplayLevel> scopeToAverageSeverityMap) {
super(new MyModel(scopeToAverageSeverityMap));
getColumnModel().getColumn(SCOPE_COLUMN).setCellRenderer(new DefaultTableCellRenderer() {
@@ -64,9 +63,9 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
final int row,
final int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final HighlightSeverity severity = (HighlightSeverity)value;
setIcon(HighlightDisplayLevel.find(severity).getIcon());
setText(SingleInspectionProfilePanel.renderSeverity(severity));
final HighlightDisplayLevel level = (HighlightDisplayLevel)value;
setIcon(level.getIcon());
setText(SingleInspectionProfilePanel.renderSeverity(level.getSeverity()));
setOpaque(false);
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, this);
return this;
@@ -90,10 +89,10 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
private final static class MyModel extends AbstractTableModel {
private final LinkedHashMap<String, HighlightSeverity> myScopeToAverageSeverityMap;
private final LinkedHashMap<String, HighlightDisplayLevel> myScopeToAverageSeverityMap;
private final List<String> myScopes;
public MyModel(final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap) {
public MyModel(final LinkedHashMap<String, HighlightDisplayLevel> scopeToAverageSeverityMap) {
myScopeToAverageSeverityMap = scopeToAverageSeverityMap;
myScopes = new ArrayList<String>(myScopeToAverageSeverityMap.keySet());
}
@@ -102,7 +101,7 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
public Class<?> getColumnClass(final int columnIndex) {
switch (columnIndex) {
case SCOPE_COLUMN: return String.class;
case SEVERITY_COLUMN: return HighlightSeverity.class;
case SEVERITY_COLUMN: return HighlightDisplayLevel.class;
default: throw new IllegalArgumentException();
}
}
@@ -129,7 +129,7 @@ public class CodeFormatterFacade {
if (file.getTextLength() > 0) {
try {
FormatterEx.getInstanceEx().format(
model, mySettings,mySettings.getIndentOptionsByFile(fileToFormat), new FormatTextRanges(range, true)
model, mySettings,mySettings.getIndentOptionsByFile(fileToFormat, range), new FormatTextRanges(range, true)
);
wrapLongLinesIfNecessary(file, document, startOffset, endOffset);
@@ -242,7 +242,7 @@ public class CodeFormatterFacade {
indentOptions = ((FormattingModelBuilderEx)builder).getIndentOptionsToUse(file, ranges, mySettings);
}
if (indentOptions == null) {
indentOptions = mySettings.getIndentOptionsByFile(file);
indentOptions = mySettings.getIndentOptionsByFile(file, textRanges.size() == 1 ? textRanges.get(0).getTextRange() : null);
}
formatter.format(model, mySettings, indentOptions, ranges);
@@ -150,6 +150,13 @@ public interface IdeActions {
@NonNls String ACTION_COLLAPSE_ALL = "CollapseAll";
@NonNls String ACTION_EXPORT_TO_TEXT_FILE = "ExportToTextFile";
@NonNls String ACTION_EXPAND_ALL_REGIONS = "ExpandAllRegions";
@NonNls String ACTION_COLLAPSE_ALL_REGIONS = "CollapseAllRegions";
@NonNls String ACTION_EXPAND_REGION_RECURSIVELY = "ExpandRegionRecursively";
@NonNls String ACTION_COLLAPSE_REGION_RECURSIVELY = "CollapseRegionRecursively";
@NonNls String ACTION_EXPAND_TO_LEVEL_1 = "ExpandToLevel1";
@NonNls String ACTION_EXPAND_ALL_TO_LEVEL_1 = "ExpandAllToLevel1";
@NonNls String ACTION_NEW_HORIZONTAL_TAB_GROUP = "NewHorizontalTabGroup";
@NonNls String ACTION_NEW_VERTICAL_TAB_GROUP = "NewVerticalTabGroup";
@NonNls String ACTION_MOVE_EDITOR_TO_OPPOSITE_TAB_GROUP = "MoveEditorToOppositeTabGroup";
@@ -34,7 +34,7 @@ public class OptionsBundle {
}
private static Reference<ResourceBundle> ourBundle;
@NonNls protected static final String PATH_TO_BUNDLE = "messages.OptionsBundle";
@NonNls public static final String PATH_TO_BUNDLE = "messages.OptionsBundle";
private OptionsBundle() {
}
@@ -43,6 +43,11 @@ import com.intellij.util.xmlb.annotations.Transient;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectObjectProcedure;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,7 +57,10 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@State(
name = "HttpConfigurable",
@@ -426,6 +434,34 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
}
}
@NotNull
public RequestConfig.Builder setProxy(@NotNull RequestConfig.Builder builder) {
return setProxy(builder, USE_HTTP_PROXY);
}
@NotNull
public CredentialsProvider setProxyCredentials(@NotNull CredentialsProvider provider) {
return setProxyCredentials(provider, USE_HTTP_PROXY);
}
@NotNull
public RequestConfig.Builder setProxy(@NotNull RequestConfig.Builder builder, boolean useProxy) {
if (useProxy) {
builder.setProxy(new HttpHost(PROXY_HOST, PROXY_PORT));
}
return builder;
}
@NotNull
public CredentialsProvider setProxyCredentials(@NotNull CredentialsProvider provider, boolean useProxy) {
if (useProxy && PROXY_AUTHENTICATION) {
provider.setCredentials(new AuthScope(PROXY_HOST, PROXY_PORT), new UsernamePasswordCredentials(PROXY_LOGIN, getPlainProxyPassword()));
}
return provider;
}
public static List<KeyValue<String, String>> getJvmPropertiesList(final boolean withAutodetection, @Nullable final URI uri) {
final HttpConfigurable me = getInstance();
if (! me.USE_HTTP_PROXY && ! me.USE_PROXY_PAC) {
@@ -168,7 +168,7 @@ public class CertificateManager implements PersistentStateComponent<CertificateM
}
@NotNull
private static SSLContext getSystemSslContext() {
public static SSLContext getSystemSslContext() {
// NOTE: SSLContext.getDefault() should not be called because it automatically creates
// default context which can't be initialized twice
try {
@@ -95,6 +95,11 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager {
@Override
public void checkServerTrusted(final X509Certificate[] certificates, String s) throws CertificateException {
checkServerTrusted(certificates, s, true, true);
}
public void checkServerTrusted(final X509Certificate[] certificates, String s, boolean addToKeyStore, boolean askUser)
throws CertificateException {
try {
mySystemManager.checkServerTrusted(certificates, s);
}
@@ -105,7 +110,7 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager {
myCustomManager.checkServerTrusted(certificates, s);
}
catch (CertificateException e2) {
if (myCustomManager.isBroken() || !confirmAndUpdate(certificates)) {
if (myCustomManager.isBroken() || !confirmAndUpdate(certificates, addToKeyStore, askUser)) {
throw e;
}
}
@@ -113,7 +118,7 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager {
}
}
private boolean confirmAndUpdate(final X509Certificate[] chain) {
private boolean confirmAndUpdate(final X509Certificate[] chain, boolean addToKeyStore, boolean askUser) {
Application app = ApplicationManager.getApplication();
final X509Certificate endPoint = chain[0];
// IDEA-123467 and IDEA-123335 workaround
@@ -125,10 +130,12 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager {
CertificateManager.Config config = CertificateManager.getInstance().getState();
if (app.isUnitTestMode() || app.isHeadlessEnvironment() || config.ACCEPT_AUTOMATICALLY) {
LOG.debug("Certificate will be accepted automatically");
myCustomManager.addCertificate(endPoint);
if (addToKeyStore) {
myCustomManager.addCertificate(endPoint);
}
return true;
}
boolean accepted = CertificateManager.showAcceptDialog(new Callable<DialogWrapper>() {
boolean accepted = askUser && CertificateManager.showAcceptDialog(new Callable<DialogWrapper>() {
@Override
public DialogWrapper call() throws Exception {
// TODO may be another kind of warning, if default trust store is missing
@@ -137,7 +144,9 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager {
});
if (accepted) {
LOG.info("Certificate was accepted by user");
myCustomManager.addCertificate(endPoint);
if (addToKeyStore) {
myCustomManager.addCertificate(endPoint);
}
}
return accepted;
}
@@ -626,26 +626,34 @@ public class HintManagerImpl extends HintManager implements Disposable {
int col2 = pos2.column;
Point location;
JLayeredPane layeredPane = editor.getComponent().getRootPane().getLayeredPane();
@NotNull JComponent externalComponent = editor.getComponent();
JRootPane rootPane = externalComponent.getRootPane();
if (rootPane != null) {
externalComponent = rootPane;
JLayeredPane layeredPane = rootPane.getLayeredPane();
if (layeredPane != null) {
externalComponent = layeredPane;
}
}
JComponent internalComponent = editor.getContentComponent();
if (constraint == RIGHT_UNDER) {
Point p = editor.logicalPositionToXY(new LogicalPosition(line2, col2));
if (!showByBalloon) {
p.y += editor.getLineHeight();
}
location = SwingUtilities.convertPoint(internalComponent, p, layeredPane);
location = SwingUtilities.convertPoint(internalComponent, p, externalComponent);
}
else {
Point p = editor.logicalPositionToXY(new LogicalPosition(line1, col1));
if (constraint == UNDER) {
p.y += editor.getLineHeight();
}
location = SwingUtilities.convertPoint(internalComponent, p, layeredPane);
location = SwingUtilities.convertPoint(internalComponent, p, externalComponent);
}
if (constraint == ABOVE && !showByBalloon) {
location.y -= hintSize.height;
int diff = location.x + hintSize.width - layeredPane.getWidth();
int diff = location.x + hintSize.width - externalComponent.getWidth();
if (diff > 0) {
location.x = Math.max(location.x - diff, 0);
}
@@ -19,6 +19,8 @@
*/
package com.intellij.ide.actions;
import com.intellij.AbstractBundle;
import com.intellij.CommonBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
@@ -31,10 +33,13 @@ import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.impl.ServiceManagerImpl;
import com.intellij.openapi.components.impl.stores.StateStorageManager;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.ZipUtil;
@@ -128,10 +133,10 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
}
@NotNull
public static MultiMap<File, ExportableComponent> getExportableComponentsMap(boolean onlyExisting) {
public static MultiMap<File, ExportableComponent> getExportableComponentsMap(final boolean onlyExisting) {
ExportableApplicationComponent[] components1 = ApplicationManager.getApplication().getComponents(ExportableApplicationComponent.class);
List<ExportableComponent> components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class);
MultiMap<File, ExportableComponent> result = MultiMap.createSet();
final MultiMap<File, ExportableComponent> result = MultiMap.createSet();
for (ExportableComponent component : ContainerUtil.concat(Arrays.asList(components1), components2)) {
for (File exportFile : component.getExportFiles()) {
result.putValue(exportFile, component);
@@ -147,42 +152,79 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
}
ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
StateStorageManager storageManager = application.getStateStore().getStateStorageManager();
List<Class<?>> classes = ServiceManagerImpl.getAllImplementationClasses(application);
for (Class<?> aClass : classes) {
final State stateAnnotation = aClass.getAnnotation(State.class);
if (stateAnnotation != null && stateAnnotation.storages().length == 1 && !StringUtil.isEmpty(stateAnnotation.name())) {
if (ExportableComponent.class.isAssignableFrom(aClass)) {
continue;
}
final StateStorageManager storageManager = application.getStateStore().getStateStorageManager();
ServiceManagerImpl.processAllImplementationClasses(application, new PairProcessor<Class<?>, PluginDescriptor>() {
@Override
public boolean process(@NotNull Class<?> aClass, @Nullable PluginDescriptor pluginDescriptor) {
State stateAnnotation = aClass.getAnnotation(State.class);
if (stateAnnotation != null && stateAnnotation.storages().length == 1 && !StringUtil.isEmpty(stateAnnotation.name())) {
if (ExportableComponent.class.isAssignableFrom(aClass)) {
return true;
}
Storage storage = stateAnnotation.storages()[0];
if (storage.roamingType() != RoamingType.DISABLED &&
storage.storageClass().equals(StateStorage.class) &&
storage.scheme() == StorageScheme.DEFAULT &&
!StringUtil.isEmpty(storage.file()) &&
storage.file().startsWith(StoragePathMacros.APP_CONFIG)) {
final File file = new File(storageManager.expandMacros(storage.file()));
if (!onlyExisting || file.exists()) {
result.putValue(file, new ExportableComponent() {
@NotNull
@Override
public File[] getExportFiles() {
return new File[]{file};
}
@NotNull
@Override
public String getPresentableName() {
return stateAnnotation.name();
}
});
Storage storage = stateAnnotation.storages()[0];
if (storage.roamingType() != RoamingType.DISABLED &&
storage.storageClass().equals(StateStorage.class) &&
storage.scheme() == StorageScheme.DEFAULT &&
!StringUtil.isEmpty(storage.file()) &&
storage.file().startsWith(StoragePathMacros.APP_CONFIG)) {
File file = new File(storageManager.expandMacros(storage.file()));
if (!onlyExisting || file.exists()) {
result.putValue(file, new MyExportableComponent(file, getExportableComponentPresentableName(stateAnnotation.name(), aClass, pluginDescriptor)));
}
}
}
return true;
}
});
return result;
}
@NotNull
private static String getExportableComponentPresentableName(@NotNull String defaultName, @NotNull Class<?> aClass, @Nullable PluginDescriptor pluginDescriptor) {
String resourceBundleName;
if (pluginDescriptor != null && pluginDescriptor instanceof IdeaPluginDescriptor && !"com.intellij".equals(pluginDescriptor.getPluginId().getIdString())) {
resourceBundleName = ((IdeaPluginDescriptor)pluginDescriptor).getResourceBundleBaseName();
}
else {
resourceBundleName = OptionsBundle.PATH_TO_BUNDLE;
}
return result;
if (resourceBundleName == null) {
return defaultName;
}
ClassLoader classLoader = pluginDescriptor == null ? null : pluginDescriptor.getPluginClassLoader();
classLoader = classLoader == null ? aClass.getClassLoader() : classLoader;
if (classLoader != null) {
ResourceBundle bundle = AbstractBundle.getResourceBundle(resourceBundleName, classLoader);
if (bundle != null) {
return CommonBundle.messageOrDefault(bundle, "exportable." + defaultName + ".presentable.name", defaultName);
}
}
return defaultName;
}
private static final class MyExportableComponent implements ExportableComponent {
private final File file;
private final String name;
public MyExportableComponent(@NotNull File file, @NotNull String name) {
this.file = file;
this.name = name;
}
@NotNull
@Override
public File[] getExportFiles() {
return new File[]{file};
}
@NotNull
@Override
public String getPresentableName() {
return name;
}
}
}
@@ -16,14 +16,11 @@
package com.intellij.openapi.actionSystem.impl;
import com.intellij.openapi.actionSystem.AbbreviationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.*;
/**
@@ -33,8 +30,7 @@ import java.util.*;
name = "AbbreviationManager",
storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/abbreviations.xml", roamingType = RoamingType.PER_PLATFORM)}
)
public class AbbreviationManagerImpl extends AbbreviationManager implements
ExportableComponent, PersistentStateComponent<Element> {
public class AbbreviationManagerImpl extends AbbreviationManager implements PersistentStateComponent<Element> {
private final Map<String, List<String>> myAbbreviation2ActionId = new THashMap<String, List<String>>();
private final Map<String, LinkedHashSet<String>> myActionId2Abbreviations = new THashMap<String, LinkedHashSet<String>>();
private final Map<String, LinkedHashSet<String>> myPluginsActionId2Abbreviations = new THashMap<String, LinkedHashSet<String>>();
@@ -109,18 +105,6 @@ public class AbbreviationManagerImpl extends AbbreviationManager implements
}
}
@NotNull
@Override
public File[] getExportFiles() {
return new File[]{PathManager.getOptionsFile("abbreviations")};
}
@NotNull
@Override
public String getPresentableName() {
return "Actions";
}
@Override
public Set<String> getAbbreviations() {
final Set<String> result = new HashSet<String>();
@@ -25,6 +25,7 @@ import com.intellij.openapi.extensions.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.PairProcessor;
import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.pico.AssignableToComponentAdapter;
import com.intellij.util.pico.ConstructorInjectionComponentAdapter;
@@ -32,7 +33,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.picocontainer.*;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ServiceManagerImpl implements BaseComponent {
private static final ExtensionPointName<ServiceDescriptor> APP_SERVICES = new ExtensionPointName<ServiceDescriptor>("com.intellij.applicationService");
@@ -83,31 +86,34 @@ public class ServiceManagerImpl implements BaseComponent {
return Arrays.asList(extensions);
}
@NotNull
public static List<Class<?>> getAllImplementationClasses(@NotNull ComponentManager componentManager) {
public static void processAllImplementationClasses(@NotNull ComponentManager componentManager, @NotNull PairProcessor<Class<?>, PluginDescriptor> processor) {
Collection adapters = componentManager.getPicoContainer().getComponentAdapters();
if (adapters.isEmpty()) {
return Collections.emptyList();
return;
}
List<Class<?>> classes = new ArrayList<Class<?>>(512);
for (Object o : adapters) {
if (o instanceof MyComponentAdapter) {
MyComponentAdapter adapter = (MyComponentAdapter)o;
ComponentAdapter delegate = adapter.myDelegate;
// we cannot use getDelegate - not all components are instantiable (JobSchedulerImpl, for example, causes such error)
Class aClass;
try {
classes.add(delegate == null ? adapter.loadClass(adapter.myDescriptor.getImplementation()) : delegate.getComponentImplementation());
// we cannot use getDelegate - not all components are instantiable (JobSchedulerImpl, for example, causes such error)
aClass = delegate == null ? adapter.loadClass(adapter.myDescriptor.getImplementation()) : delegate.getComponentImplementation();
}
catch (RuntimeException e) {
// ignore ClassNotFoundException - invalid entry (GithubSslSupport, for example)
if (!(e.getCause() instanceof ClassNotFoundException)) {
throw e;
}
continue;
}
if (!processor.process(aClass, adapter.myPluginDescriptor)) {
break;
}
}
}
return classes;
}
@Override
@@ -16,10 +16,8 @@
package com.intellij.openapi.editor.ex;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.util.text.StringUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NonNls;
@@ -28,7 +26,6 @@ import org.jetbrains.annotations.Nullable;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.EnumSet;
import java.util.Set;
@@ -36,7 +33,7 @@ import java.util.Set;
name = "EditorSettings",
storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/editor.xml")}
)
public class EditorSettingsExternalizable implements PersistentStateComponent<EditorSettingsExternalizable.OptionSet>, ExportableComponent {
public class EditorSettingsExternalizable implements PersistentStateComponent<EditorSettingsExternalizable.OptionSet> {
//Q: make it interface?
public static final class OptionSet {
public String LINE_SEPARATOR;
@@ -389,18 +386,6 @@ public class EditorSettingsExternalizable implements PersistentStateComponent<Ed
myOptions.REFRAIN_FROM_SCROLLING = b;
}
@Override
@NotNull
public File[] getExportFiles() {
return new File[]{PathManager.getOptionsFile("editor")};
}
@Override
@NotNull
public String getPresentableName() {
return OptionsBundle.message("options.editor.settings.presentable.name");
}
public boolean isWhitespacesShown() {
return myOptions.IS_WHITESPACES_SHOWN;
}
@@ -0,0 +1,30 @@
/*
* 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.openapi.fileEditor.impl;
import com.intellij.openapi.util.Key;
/** @deprecated use {@link com.intellij.openapi.editor.impl.TrailingSpacesStripper} (to be removed in IDEA 15) */
@SuppressWarnings("UnusedDeclaration")
public class TrailingSpacesStripper {
public static final Key<String> OVERRIDE_STRIP_TRAILING_SPACES_KEY =
com.intellij.openapi.editor.impl.TrailingSpacesStripper.OVERRIDE_STRIP_TRAILING_SPACES_KEY;
public static final Key<Boolean> OVERRIDE_ENSURE_NEWLINE_KEY =
com.intellij.openapi.editor.impl.TrailingSpacesStripper.OVERRIDE_ENSURE_NEWLINE_KEY;
}
@@ -247,7 +247,6 @@ project.settings.display.name=Project Settings [{0}]
template.project.settings.short.name=Template Project
project.settings.short.name=Project
options.color.schemes.presentable.name=Color schemes
options.editor.settings.presentable.name=Editor settings
options.java.attribute.descriptor.weak.warning=Weak Warning
options.java.attribute.descriptor.server.problems=Problem from server
options.java.attribute.descriptor.server.duplicate=Duplicate from server
@@ -277,4 +276,7 @@ color.settings.console.magentaBright=ANSI Bright Magenta
color.settings.console.cyanBright=ANSI Bright Cyan
color.settings.console.white=ANSI White
options.general.attribute.descriptor.live.template=Live Template
options.general.attribute.descriptor.live.template=Live Template
exportable.EditorSettings.presentable.name=Editor
exportable.AbbreviationManager.presentable.name=Actions
@@ -245,11 +245,8 @@
<applicationService serviceInterface="com.intellij.openapi.actionSystem.AbbreviationManager"
serviceImplementation="com.intellij.openapi.actionSystem.impl.AbbreviationManagerImpl"/>
<exportable serviceInterface="com.intellij.openapi.actionSystem.AbbreviationManager"/>
<applicationService serviceInterface="com.intellij.openapi.editor.ex.EditorSettingsExternalizable"
serviceImplementation="com.intellij.openapi.editor.ex.EditorSettingsExternalizable"/>
<exportable serviceInterface="com.intellij.openapi.editor.ex.EditorSettingsExternalizable"/>
<applicationService serviceImplementation="com.intellij.openapi.editor.ex.EditorSettingsExternalizable"/>
<scopeParserExtension implementation="com.intellij.psi.search.scope.packageSet.FilePackageSetParserExtension"/>
<applicationService serviceInterface="com.intellij.openapi.ui.popup.StackingPopupDispatcher" serviceImplementation="com.intellij.ui.popup.StackingPopupDispatcherImpl"/>
@@ -16,4 +16,4 @@ SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
AngularJS 134.1094 0.1.8 0.1.9
org.jetbrains.plugins.vagrant 0.1 0.2
org.intellij.clojure 0.2.1.178
net.nicoulaj.idea.markdown 0.9.6 0.9.5 0.9.4 0.9.3 0.9.2 0.9.1 0.8.3 0.8.2 0.8.1 0.8 0.7 0.6.1 0.6 0.5.1 0.5 0.4 0.3 0.2 0.1
net.nicoulaj.idea.markdown 0.9.5 0.9.4 0.9.3 0.9.2 0.9.1 0.8.3 0.8.2 0.8.1 0.8 0.7 0.6.1 0.6 0.5.1 0.5 0.4 0.3 0.2 0.1
@@ -91,6 +91,16 @@
<action id="ExpandAllRegions">
<keyboard-shortcut first-keystroke="meta MULTIPLY" />
</action>
<action id="ExpandAllToLevel1"/>
<action id="ExpandAllToLevel2"/>
<action id="ExpandAllToLevel3"/>
<action id="ExpandAllToLevel4"/>
<action id="ExpandAllToLevel5"/>
<action id="ExpandToLevel1"/>
<action id="ExpandToLevel2"/>
<action id="ExpandToLevel3"/>
<action id="ExpandToLevel4"/>
<action id="ExpandToLevel5"/>
<action id="ExternalJavaDoc">
<keyboard-shortcut first-keystroke="shift F2" />
</action>
@@ -555,5 +555,25 @@
<action id="NewScratchFile">
<keyboard-shortcut first-keystroke="meta shift N"/>
</action>
<action id="ExpandAllToLevel1">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="1"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD1"/>
</action>
<action id="ExpandAllToLevel2">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="2"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD2"/>
</action>
<action id="ExpandAllToLevel3">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="3"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD3"/>
</action>
<action id="ExpandAllToLevel4">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="4"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD4"/>
</action>
<action id="ExpandAllToLevel5">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="5"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD5"/>
</action>
</keymap>
</component>
@@ -353,5 +353,25 @@
<action id="NewScratchFile">
<keyboard-shortcut first-keystroke="control shift N"/>
</action>
<action id="ExpandAllToLevel1">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="1"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD1"/>
</action>
<action id="ExpandAllToLevel2">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="2"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD2"/>
</action>
<action id="ExpandAllToLevel3">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="3"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD3"/>
</action>
<action id="ExpandAllToLevel4">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="4"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD4"/>
</action>
<action id="ExpandAllToLevel5">
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="5"/>
<keyboard-shortcut first-keystroke="meta alt MULTIPLY" second-keystroke="NUMPAD5"/>
</action>
</keymap>
</component>
@@ -40,6 +40,7 @@ public class StripTrailingSpacesTest extends LightPlatformCodeInsightTestCase {
super.setUp();
EditorSettingsExternalizable settings = EditorSettingsExternalizable.getInstance();
oldSettings = settings.getState();
settings.loadState(new EditorSettingsExternalizable.OptionSet());
settings.setStripTrailingSpaces(EditorSettingsExternalizable.STRIP_TRAILING_SPACES_CHANGED);
settings.setVirtualSpace(false);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -34,6 +34,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PlatformLangTestCase;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PairProcessor;
import org.jetbrains.annotations.NotNull;
@@ -41,12 +42,13 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import static org.junit.Assert.assertNotEquals;
public class FileDocumentManagerImplTest extends PlatformLangTestCase {
private FileDocumentManagerImpl myDocumentManager;
private Boolean myReloadFromDisk;
public Boolean myReloadFromDisk;
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -148,7 +150,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments();
assertEquals(1, unsavedDocuments.length);
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals("test", new String(file.contentsToByteArray(), "UTF-8"));
}
public void testGetUnsavedDocuments_afterSaveAllDocuments() throws Exception {
@@ -216,7 +218,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments();
assertEquals(1, unsavedDocuments.length);
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals("test", new String(file.contentsToByteArray(), "UTF-8"));
}
finally {
myDocumentManager.dropAllUnsavedDocuments();
@@ -231,7 +233,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
@Override
public void run() {
myDocumentManager.getDocument(file).insertString(0, "xxx");
ObjectUtils.assertNotNull(myDocumentManager.getDocument(file)).insertString(0, "xxx");
}
});
@@ -252,7 +254,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
@Override
public void run() {
myDocumentManager.getDocument(file).insertString(0, "xxx");
ObjectUtils.assertNotNull(myDocumentManager.getDocument(file)).insertString(0, "xxx");
}
});
@@ -294,7 +296,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
myDocumentManager.saveDocument(document);
assertTrue(stamp != file.getModificationStamp());
assertEquals(document.getModificationStamp(), file.getModificationStamp());
assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals("xxx test", new String(file.contentsToByteArray(), "UTF-8"));
}
public void testSaveAllDocuments_DocumentWasChanged() throws Exception {
@@ -309,10 +311,9 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
}
});
myDocumentManager.saveAllDocuments();
assertTrue(stamp != file.getModificationStamp());
assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray()));
assertNotEquals(stamp, file.getModificationStamp());
assertEquals("xxx test", new String(file.contentsToByteArray(), "UTF-8"));
}
public void testGetFile() throws Exception {
@@ -341,7 +342,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
});
myDocumentManager.saveAllDocuments();
assertTrue(Arrays.equals("xxx test\rtest".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals("xxx test\rtest", new String(file.contentsToByteArray(), "UTF-8"));
}
public void testContentChanged_noDocument() throws Exception {
@@ -531,7 +532,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
assertEquals("old test", document.getText());
assertEquals(file.getModificationStamp(), document.getModificationStamp());
assertTrue(Arrays.equals("old test".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals("old test", new String(file.contentsToByteArray(), "UTF-8"));
assertEquals(documentStamp, document.getModificationStamp());
}
@@ -631,6 +632,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
assertNotNull(virtualFile.getPath(), original);
final PsiFile file = getPsiFile(original);
assertNotNull(file);
FileDocumentManagerListener saveListener = new FileDocumentManagerAdapter() {
@Override
public void beforeDocumentSaving(@NotNull Document document) {
@@ -650,6 +652,7 @@ public class FileDocumentManagerImplTest extends PlatformLangTestCase {
};
getProject().getMessageBus().connect(getTestRootDisposable()).subscribe(AppTopics.FILE_DOCUMENT_SYNC, saveListener);
final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
assertNotNull(document);
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
@Override
public void run() {
@@ -42,6 +42,9 @@ import java.util.Collections;
import java.util.List;
/**
* Represents a test result tree node.
* Not thread-safe. All methods should be called in EDT only.
*
* @author: Roman Chernyatchik
*/
public class SMTestProxy extends AbstractTestProxy {
@@ -296,6 +299,7 @@ public class SMTestProxy extends AbstractTestProxy {
}
public List<? extends SMTestProxy> getChildren() {
ApplicationManager.getApplication().assertIsDispatchThread();
return myChildren != null ? myChildren : Collections.<SMTestProxy>emptyList();
}
@@ -213,7 +213,8 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "shift F2", "GotoPreviousError", "GotoDeclaration"},
{ "shift control F7", "FindUsagesInFile", "HighlightUsagesInFile"},
{ "shift control I", "ImplementMethods", "QuickImplementations"},
{ "alt F9", "ViewBreakpoints", "EditBreakpoint"},
{ "alt F9", "ViewBreakpoints", "EditBreakpoint"},
{ "alt MULTIPLY", "ShowExecutionPoint", "Images.Thumbnails.ToggleRecursive"},
});
put("Default for XWin", new String[][] {
});
@@ -277,7 +278,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "control 2", "ActivateProjectToolWindow", "FileChooser.GotoProject", "DuplicatesForm.SendToRight"},
{ "control 3", "ActivateProjectToolWindow", "FileChooser.GotoModule"},
{ "control BACK_SPACE", "EditorDeleteToWordStart", "ToggleDockMode"},
{ "control DIVIDE", "CommentByLineComment", "Images.Editor.ActualSize"},
{ "control DIVIDE", "CollapseRegionRecursively", "Images.Editor.ActualSize"},
{ "control D", "EditorDuplicate", "CompareDirs", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control M", "Vcs.ShowMessageHistory", "Move"},
{ "control R", "RenameElement", "Console.TableResult.Reload", "org.jetbrains.plugins.ruby.rails.console.ReloadSources"},
@@ -42,15 +42,7 @@ public class TestsOutputConsolePrinter implements Printer, Disposable {
};
public TestsOutputConsolePrinter(@NotNull BaseTestsOutputConsoleView testsOutputConsoleView, final TestConsoleProperties properties, final AbstractTestProxy unboundOutputRoot) {
this(testsOutputConsoleView.getConsole(), properties, unboundOutputRoot);
}
/**
* @deprecated left for JSTestDriver compatibility
*/
@Deprecated
public TestsOutputConsolePrinter(final ConsoleView console, final TestConsoleProperties properties, final AbstractTestProxy unboundOutputRoot) {
myConsole = console;
myConsole = testsOutputConsoleView.getConsole();
myProperties = properties;
myUnboundOutputRoot = unboundOutputRoot;
myProperties.addListener(TestConsoleProperties.SCROLL_TO_STACK_TRACE, myPropertyListener);
@@ -148,7 +140,7 @@ public class TestsOutputConsolePrinter implements Printer, Disposable {
}
public boolean canPause() {
return myCurrentTest != null ? myCurrentTest.isInProgress() : false;
return myCurrentTest != null && myCurrentTest.isInProgress();
}
protected void scrollToBeginning() {
@@ -341,6 +341,7 @@ svn.use.terminal=false
svn.use.incoming.optimization=false
svn.executable.locale=C.UTF-8
svn.lowest.supported.format.for.command.line=1.7.0
svn.use.svnkit.for.https.server.certificate.check=true
completion.enable.relevant.method.chain.suggestions=false
ide.mac.message.sheets.java.emulation=false
@@ -439,4 +440,4 @@ spy.js.realtime.evaluation.description=Enables spy-js autocomplete and realtime
new.css.schema.enabled=true
editor.disable.rtl=false
editor.disable.rtl.description=Disables RTL support in editor (which is broken now anyway)
editor.disable.rtl.description=Disables RTL support in editor (which is broken now anyway)
@@ -15,9 +15,12 @@
*/
package com.intellij.util.containers;
import com.intellij.openapi.util.Comparing;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Immutable list in functional style
@@ -25,18 +28,15 @@ import java.util.*;
* @author nik
*/
public class FList<E> extends AbstractList<E> {
private static final FList<?> EMPTY_LIST = new FList();
private E myHead;
private FList<E> myTail;
private int mySize;
@SuppressWarnings("unchecked") private static final FList<?> EMPTY_LIST = new FList(null, null, 0);
private final E myHead;
private final FList<E> myTail;
private final int mySize;
private FList() {
}
private FList(E head, FList<E> tail) {
private FList(E head, FList<E> tail, int size) {
myHead = head;
myTail = tail;
mySize = tail.size()+1;
mySize = size;
}
@Override
@@ -58,7 +58,7 @@ public class FList<E> extends AbstractList<E> {
}
public FList<E> prepend(E elem) {
return new FList<E>(elem, this);
return new FList<E>(elem, this, mySize + 1);
}
public FList<E> without(E elem) {
@@ -120,7 +120,37 @@ public class FList<E> extends AbstractList<E> {
return mySize;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof FList) {
FList list1 = this;
FList list2 = (FList)o;
if (mySize != list2.mySize) return false;
while (list1 != null) {
if (!Comparing.equal(list1.myHead, list2.myHead)) return false;
list1 = list1.getTail();
list2 = list2.getTail();
if (list1 == list2) return true;
}
return true;
}
return super.equals(o);
}
@Override
public int hashCode() {
int result = 1;
FList each = this;
while (each != null) {
result = result * 31 + (each.myHead != null ? each.myHead.hashCode() : 0);
each = each.getTail();
}
return result;
}
public static <E> FList<E> emptyList() {
//noinspection unchecked
return (FList<E>)EMPTY_LIST;
}
}
@@ -61,6 +61,7 @@ import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XSuspendContext;
import com.intellij.xdebugger.frame.XValueMarkerProvider;
import com.intellij.xdebugger.impl.breakpoints.*;
import com.intellij.xdebugger.impl.evaluate.XDebuggerEditorLinePainter;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
@@ -891,6 +892,7 @@ public class XDebugSessionImpl implements XDebugSession {
myStopped = true;
myDebuggerManager.removeSession(this);
myDispatcher.getMulticaster().sessionStopped();
myProject.putUserData(XDebuggerEditorLinePainter.CACHE, null);
}
public boolean isInactiveSlaveBreakpoint(final XBreakpoint<?> breakpoint) {
@@ -28,6 +28,7 @@ import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
@@ -115,6 +116,7 @@ public class XValueHint extends AbstractValueHint {
boolean result = super.showHint(component);
if (result && getType() == ValueHintType.MOUSE_OVER_HINT) {
myDisposable = Disposer.newDisposable();
Disposer.register(((EditorImpl)getEditor()).getDisposable(), myDisposable);
ShortcutSet shortcut = ActionManager.getInstance().getAction("ShowErrorDescription").getShortcutSet();
new DumbAwareAction() {
@Override
@@ -133,7 +135,6 @@ public class XValueHint extends AbstractValueHint {
super.hideHint();
if (myDisposable != null) {
Disposer.dispose(myDisposable);
}
}
@@ -15,6 +15,11 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.execution.configurations.RemoteRunProfile;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ObjectUtils;
@@ -92,7 +97,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
myValueChildren.add(node);
newChildren.add(node);
if (Registry.is("ide.debugger.inline") && "this".equals(node.getName())) { //todo[kb]: try to generify this dirty hack
if (Registry.is("ide.debugger.inline") && "this".equals(node.getName()) && !isRemoteConfiguration(myTree)) { //todo[kb]: try to generify this dirty hack
//initialize "this" fields to display in inline view
node.getChildren();
}
@@ -113,6 +118,12 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
});
}
private static boolean isRemoteConfiguration(XDebuggerTree tree) {
DataContext context = DataManager.getInstance().getDataContext(tree);
ExecutionEnvironment env = LangDataKeys.EXECUTION_ENVIRONMENT.getData(context);
return env != null && env.getRunProfile() instanceof RemoteRunProfile;
}
@Nullable
private List<XValueGroupNodeImpl> createGroupNodes(List<XValueGroup> groups,
@Nullable List<XValueGroupNodeImpl> prevNodes,
@@ -149,13 +149,14 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
if (doc == null) return;
int line = sourcePosition.getLine();
Pair<VirtualFile, Integer> key = Pair.create(file, line);
Set<XValueNodeImpl> presentations = map.get(key);
if (presentations == null) {
presentations = new LinkedHashSet<XValueNodeImpl>();
map.put(key, presentations);
timestamps.put(file, doc.getModificationStamp());
}
Set<XValueNodeImpl> presentations = new LinkedHashSet<XValueNodeImpl>();
Set<XValueNodeImpl> old = map.get(key);
map.put(key, presentations);
timestamps.put(file, doc.getModificationStamp());
presentations.add(XValueNodeImpl.this);
if (old != null) {
presentations.addAll(old);
}
}
});
}
@@ -7,7 +7,6 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ThrowableComputable;
@@ -488,12 +487,12 @@ public class GithubCreatePullRequestWorker {
String localBranchName = "'" + myCurrentBranch + "'";
String targetBranchName = "'" + fork.getRemoteName() + "/" + branch.getRemoteName() + "'";
if (info.getInfo().getBranchToHeadCommits(myGitRepository).isEmpty()) {
return Messages.YES == GithubNotifications
return GithubNotifications
.showYesNoDialog(myProject, "Do you want to proceed anyway?",
"Empty pull request: the branch " + localBranchName + " is fully merged to the branch " + targetBranchName);
}
if (!info.getInfo().getHeadToBranchCommits(myGitRepository).isEmpty()) {
return Messages.YES == GithubNotifications
return GithubNotifications
.showYesNoDialog(myProject, "Do you want to proceed anyway?",
"The branch " + targetBranchName + " is not fully merged to the branch " + localBranchName);
}
@@ -49,14 +49,16 @@ import git4idea.repo.GitRepositoryManager;
import git4idea.util.GitFileUtils;
import git4idea.util.GitUIUtil;
import icons.GithubIcons;
import org.apache.http.HttpStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.GithubConnection;
import org.jetbrains.plugins.github.api.GithubRepo;
import org.jetbrains.plugins.github.api.GithubUserDetailed;
import org.jetbrains.plugins.github.api.*;
import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.ui.GithubShareDialog;
import org.jetbrains.plugins.github.util.*;
import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import org.jetbrains.plugins.github.util.GithubNotifications;
import org.jetbrains.plugins.github.util.GithubUrlUtil;
import org.jetbrains.plugins.github.util.GithubUtil;
import javax.swing.*;
import java.io.IOException;
@@ -114,19 +116,18 @@ public class GithubShareAction extends DumbAwareAction {
final boolean gitDetected = gitRepository != null;
final VirtualFile root = gitDetected ? gitRepository.getRoot() : project.getBaseDir();
final GithubAuthDataHolder authHolder = GithubAuthDataHolder.createFromSettings();
// check for existing git repo
boolean externalRemoteDetected = false;
if (gitDetected) {
final String githubRemote = GithubUtil.findGithubRemoteUrl(gitRepository);
if (githubRemote != null) {
GithubNotifications.showInfoURL(project, "Project is already on GitHub", "GitHub", githubRemote);
return;
if (!checkExistingRemote(project, authHolder, githubRemote)) return;
}
externalRemoteDetected = !gitRepository.getRemotes().isEmpty();
}
final GithubAuthDataHolder authHolder = GithubAuthDataHolder.createFromSettings();
// get available GitHub repos with modal progress
final GithubInfo githubInfo = loadGithubInfoWithModal(authHolder, project);
if (githubInfo == null) {
@@ -203,6 +204,53 @@ public class GithubShareAction extends DumbAwareAction {
}.queue();
}
private static boolean checkExistingRemote(@NotNull final Project project,
@NotNull final GithubAuthDataHolder authHolder,
@NotNull String remote) {
final GithubFullPath path = GithubUrlUtil.getUserAndRepositoryFromRemoteUrl(remote);
if (path == null) {
return GithubNotifications.showYesNoDialog(project,
"Project is already on GitHub",
"Can't connect to repository from configured remote. You could want to check .git config.\n" +
"Do you want to proceed anyway?");
}
try {
GithubRepo repo =
GithubUtil.computeValueInModal(project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubRepo, IOException>() {
@NotNull
@Override
public GithubRepo convert(ProgressIndicator indicator) throws IOException {
return GithubUtil
.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubConnection, GithubRepo, IOException>() {
@NotNull
@Override
public GithubRepo convert(@NotNull GithubConnection connection) throws IOException {
return GithubApiUtil.getDetailedRepoInfo(connection, path.getUser(), path.getRepository());
}
});
}
});
GithubNotifications.showInfoURL(project, "Project is already on GitHub", "GitHub", repo.getHtmlUrl());
return false;
}
catch (GithubStatusCodeException e) {
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
return GithubNotifications.showYesNoDialog(project,
"Project is already on GitHub",
"Can't connect to repository from configured remote. You could want to check .git config.\n" +
"Do you want to proceed anyway?");
}
GithubNotifications.showErrorDialog(project, "Failed to connect to GitHub", e);
return false;
}
catch (IOException e) {
GithubNotifications.showErrorDialog(project, "Failed to connect to GitHub", e);
return false;
}
}
@Nullable
private static GithubInfo loadGithubInfoWithModal(@NotNull final GithubAuthDataHolder authHolder, @NotNull final Project project) {
try {
@@ -144,10 +144,8 @@ public class GithubConnection {
.setConnectTimeout(timeout)
.setSocketTimeout(timeout);
final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
if (auth.isUseProxy() && proxySettings.USE_HTTP_PROXY && !StringUtil.isEmptyOrSpaces(proxySettings.PROXY_HOST)) {
builder
.setProxy(new HttpHost(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT));
if (auth.isUseProxy()) {
HttpConfigurable.getInstance().setProxy(builder);
}
return builder.build();
@@ -170,14 +168,10 @@ public class GithubConnection {
provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(basicAuth.getLogin(), basicAuth.getPassword()));
}
final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
//proxySettings.USE_HTTP_PROXY
if (auth.isUseProxy() && proxySettings.USE_HTTP_PROXY && !StringUtil.isEmptyOrSpaces(proxySettings.PROXY_HOST)) {
if (proxySettings.PROXY_AUTHENTICATION) {
provider.setCredentials(new AuthScope(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT),
new UsernamePasswordCredentials(proxySettings.PROXY_LOGIN, proxySettings.getPlainProxyPassword()));
}
if (auth.isUseProxy()) {
HttpConfigurable.getInstance().setProxyCredentials(provider);
}
return provider;
}
@@ -103,7 +103,7 @@ public class GithubCreatePullRequestDialog extends DialogWrapper {
createRemote = GithubNotifications.showYesNoDialog(project,
"Can't Find Remote",
"Configure remote for '" + fork.getPath().getUser() + "'?",
ourDoNotAskOption) == Messages.YES;
ourDoNotAskOption);
break;
}
@@ -136,15 +136,15 @@ public class GithubNotifications {
}
@Messages.YesNoResult
public static int showYesNoDialog(@Nullable Project project, @NotNull String title, @NotNull String message) {
return Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon());
public static boolean showYesNoDialog(@Nullable Project project, @NotNull String title, @NotNull String message) {
return Messages.YES == Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon());
}
@Messages.YesNoResult
public static int showYesNoDialog(@Nullable Project project,
@NotNull String title,
@NotNull String message,
@NotNull DialogWrapper.DoNotAskOption doNotAskOption) {
return Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon(), doNotAskOption);
public static boolean showYesNoDialog(@Nullable Project project,
@NotNull String title,
@NotNull String message,
@NotNull DialogWrapper.DoNotAskOption doNotAskOption) {
return Messages.YES == Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon(), doNotAskOption);
}
}
@@ -22,23 +22,39 @@ import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.net.ssl.CertificateManager;
import com.intellij.util.proxy.CommonProxy;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnConfiguration;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.dialogs.SimpleCredentialsDialog;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.SVNAuthentication;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.security.KeyManagementException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -165,12 +181,106 @@ public class AuthenticationService {
});
}
public boolean acceptSSLServerCertificate(final SVNURL repositoryUrl, final String realm) {
public boolean acceptSSLServerCertificate(@Nullable SVNURL repositoryUrl, final String realm) throws SvnBindException {
if (repositoryUrl == null) {
return false;
}
return new SSLServerCertificateAuthenticator(this, repositoryUrl, realm).tryAuthenticate();
boolean result;
if (Registry.is("svn.use.svnkit.for.https.server.certificate.check")) {
result = new SSLServerCertificateAuthenticator(this, repositoryUrl, realm).tryAuthenticate();
}
else {
HttpClient client = getClient(repositoryUrl);
try {
client.execute(new HttpGet(repositoryUrl.toDecodedString()));
result = true;
}
catch (IOException e) {
throw new SvnBindException(fixMessage(e), e);
}
}
return result;
}
@Nullable
private static String fixMessage(@NotNull IOException e) {
String message = null;
if (e instanceof SSLHandshakeException) {
if (StringUtil.containsIgnoreCase(e.getMessage(), "received fatal alert: handshake_failure")) {
message = e.getMessage() + ". Please try to specify SSL protocol manually - SSLv3 or TLSv1";
}
else if (e.getCause() != null) {
// SSLHandshakeException.getMessage() could contain full type name of cause exception - for instance when cause is
// CertificateException. We just use cause exception message not to show exception type to the user.
message = e.getCause().getMessage();
}
}
return message;
}
@NotNull
private HttpClient getClient(@NotNull SVNURL repositoryUrl) {
// TODO: Implement algorithm of resolving necessary enabled protocols (TLSv1 vs SSLv3) instead of just using values from Settings.
SSLContext sslContext = createSslContext(repositoryUrl);
List<String> supportedProtocols = getSupportedSslProtocols();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, ArrayUtil.toStringArray(supportedProtocols), null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpConfigurable httpSettings = HttpConfigurable.getInstance();
// TODO: Seems more suitable here to read timeout values directly from config file - without utilizing SvnAuthenticationManager.
return HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(getAuthenticationManager().getReadTimeout(repositoryUrl)).build())
.setDefaultRequestConfig(
httpSettings.setProxy(RequestConfig.custom(), haveDataForTmpConfig())
.setConnectTimeout(getAuthenticationManager().getConnectTimeout(repositoryUrl))
.build())
.setDefaultCredentialsProvider(httpSettings.setProxyCredentials(new BasicCredentialsProvider(), haveDataForTmpConfig()))
.build();
}
@NotNull
private List<String> getSupportedSslProtocols() {
List<String> result = ContainerUtil.newArrayList();
switch (myConfiguration.getSslProtocols()) {
case sslv3:
result.add("SSLv3");
break;
case tlsv1:
result.add("TLSv1");
break;
case all:
break;
}
return result;
}
@NotNull
private SSLContext createSslContext(@NotNull SVNURL url) {
SSLContext result = CertificateManager.getSystemSslContext();
TrustManager trustManager = new CertificateTrustManager(this, url);
try {
result.init(CertificateManager.getDefaultKeyManagers(), new TrustManager[]{trustManager}, null);
}
catch (KeyManagementException e) {
LOG.error(e);
}
return result;
}
@NotNull
public SvnAuthenticationManager getAuthenticationManager() {
return isActive() ? myConfiguration.getInteractiveManager(myVcs) : myConfiguration.getPassiveAuthenticationManager(myVcs.getProject());
}
public void clearPassiveCredentials(String realm, SVNURL repositoryUrl, boolean password) {
@@ -186,6 +296,7 @@ public class AuthenticationService {
}
}
// TODO: rename
public boolean haveDataForTmpConfig() {
final HttpConfigurable instance = HttpConfigurable.getInstance();
return SvnConfiguration.getInstance(myVcs.getProject()).isIsUseDefaultProxy() &&
@@ -0,0 +1,123 @@
/*
* 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 org.jetbrains.idea.svn.auth;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.net.ssl.CertificateManager;
import com.intellij.util.net.ssl.ClientOnlyTrustManager;
import org.apache.http.client.utils.URIBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnConfiguration;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* We assume that this trust manager is only used when server certificate is valid but untrusted. So we do not perform any additional
* validation here - just checking if certificate is trusted in several ways:
* - runtime cache
* - java trust store
* - "Server Certificates" settings
* - ask user
*
* @author Konstantin Kolosovsky.
*/
public class CertificateTrustManager extends ClientOnlyTrustManager {
private static final Logger LOG = Logger.getInstance(CertificateTrustManager.class);
@NotNull private final AuthenticationService myAuthenticationService;
@NotNull private final SVNURL myRepositoryUrl;
@NotNull private final String myRealm;
public CertificateTrustManager(@NotNull AuthenticationService authenticationService, @NotNull SVNURL repositoryUrl) {
myAuthenticationService = authenticationService;
myRepositoryUrl = repositoryUrl;
myRealm = new URIBuilder()
.setScheme(repositoryUrl.getProtocol())
.setHost(repositoryUrl.getHost())
.setPort(repositoryUrl.getPort())
.toString();
}
@Override
public void checkServerTrusted(@Nullable X509Certificate[] chain, String authType) throws CertificateException {
if (chain != null && chain.length > 0 && chain[0] != null) {
X509Certificate certificate = chain[0];
if (!checkPassive(certificate)) {
if (!isAcceptedByIdea(chain, authType)) {
checkActive(certificate);
}
// no exceptions - so certificate is trusted - save to runtime cache
acknowledge(certificate);
}
}
}
private boolean checkPassive(@NotNull X509Certificate certificate) throws CertificateEncodingException {
Object cachedData = SvnConfiguration.RUNTIME_AUTH_CACHE.getDataWithLowerCheck("svn.ssl.server", myRealm);
return certificate.equals(cachedData);
}
private static boolean isAcceptedByIdea(@NotNull X509Certificate[] chain, String authType) {
boolean result;
try {
CertificateManager.getInstance().getTrustManager().checkServerTrusted(chain, authType, false, false);
result = true;
}
catch (CertificateException e) {
LOG.debug(e);
result = false;
}
return result;
}
private void checkActive(@NotNull X509Certificate certificate) throws CertificateException {
boolean isStorageEnabled =
myAuthenticationService.getAuthenticationManager().getHostOptionsProvider().getHostOptions(myRepositoryUrl).isAuthStorageEnabled();
int result = myAuthenticationService.getAuthenticationManager().getInnerProvider()
.acceptServerAuthentication(myRepositoryUrl, myRealm, certificate, isStorageEnabled);
switch (result) {
case ISVNAuthenticationProvider.ACCEPTED:
// TODO: --trust-server-cert command line key does not allow caching credentials permanently - so permanent caching should be
// TODO: separately implemented. Try utilizing "Server Certificates" settings for this.
case ISVNAuthenticationProvider.ACCEPTED_TEMPORARY:
// acknowledge() is called in checkServerTrusted()
break;
case ISVNAuthenticationProvider.REJECTED:
throw new CertificateException("Server SSL certificate rejected");
}
}
private void acknowledge(@NotNull X509Certificate certificate) throws CertificateEncodingException {
myAuthenticationService.getVcs().getSvnConfiguration().acknowledge("svn.ssl.server", myRealm, certificate);
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return CertificateManager.getInstance().getTrustManager().getAcceptedIssuers();
}
}
@@ -41,6 +41,7 @@ import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.ui.UIUtil;
import com.trilead.ssh2.auth.AgentProxy;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.config.ProxyGroup;
@@ -722,20 +723,20 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
// 30 seconds
private final static int DEFAULT_READ_TIMEOUT = 30 * 1000;
@Override
public int getReadTimeout(final SVNRepository repository) {
String protocol = repository.getLocation().getProtocol();
public int getReadTimeout(@NotNull SVNURL url) {
String protocol = url.getProtocol();
if (HTTP.equals(protocol) || HTTPS.equals(protocol)) {
String host = repository.getLocation().getHost();
String timeout = getServersPropertyIdea(host, "http-timeout");
if (timeout != null) {
try {
return Integer.parseInt(timeout)*1000;
} catch (NumberFormatException nfe) {
// use default
}
String host = url.getHost();
String timeout = getServersPropertyIdea(host, "http-timeout");
if (timeout != null) {
try {
return Integer.parseInt(timeout) * 1000;
}
return DEFAULT_READ_TIMEOUT;
catch (NumberFormatException nfe) {
// use default
}
}
return DEFAULT_READ_TIMEOUT;
}
if (SVN_SSH.equals(protocol)) {
return (int)getConfig().getSshReadTimeout();
@@ -743,19 +744,28 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
return 0;
}
@Override
public int getConnectTimeout(SVNRepository repository) {
String protocol = repository.getLocation().getProtocol();
public int getConnectTimeout(@NotNull SVNURL url) {
String protocol = url.getProtocol();
if (SVN_SSH.equals(protocol)) {
return (int)getConfig().getSshConnectionTimeout();
}
final int connectTimeout = super.getConnectTimeout(repository);
final int connectTimeout = getHostOptionsProvider().getHostOptions(url).getConnectTimeout();
if ((HTTP.equals(protocol) || HTTPS.equals(protocol)) && (connectTimeout <= 0)) {
return DEFAULT_READ_TIMEOUT;
}
return connectTimeout;
}
@Override
public int getReadTimeout(@NotNull SVNRepository repository) {
return getReadTimeout(repository.getLocation());
}
@Override
public int getConnectTimeout(@NotNull SVNRepository repository) {
return getConnectTimeout(repository.getLocation());
}
// taken from default manager as is
private String getServersPropertyIdea(String host, final String name) {
final SVNCompositeConfigFile serversFile = getHostOptionsProvider().getServersFile();
@@ -25,7 +25,6 @@ import org.tmatesoft.svn.core.SVNURL;
*/
public abstract class AuthCallbackCase {
protected final SVNURL myUrl;
protected boolean myTried = false;
@NotNull protected final AuthenticationService myAuthenticationService;
AuthCallbackCase(@NotNull AuthenticationService authenticationService, SVNURL url) {
@@ -15,6 +15,7 @@
*/
package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.auth.AuthenticationService;
@@ -29,6 +30,7 @@ public class CertificateCallbackCase extends AuthCallbackCase {
private static final String CERTIFICATE_ERROR = "Error validating server certificate for";
private static final String UNTRUSTED_SERVER_CERTIFICATE = "Server SSL certificate untrusted";
private static final String CERTIFICATE_VERIFICATION_FAILED = "certificate verification failed";
private static final String CERTIFICATE_VERIFICATION_FAILED_ISSUER_NOT_TRUSTED = "certificate verification failed: issuer is not trusted";
private boolean accepted;
@@ -38,11 +40,22 @@ public class CertificateCallbackCase extends AuthCallbackCase {
@Override
public boolean canHandle(String error) {
boolean useSvnKit = Registry.is("svn.use.svnkit.for.https.server.certificate.check");
return error.startsWith(CERTIFICATE_ERROR) ||
// https one-way protocol untrusted server certificate
error.contains(UNTRUSTED_SERVER_CERTIFICATE) ||
// for instance, certificate issued for a different hostname, issuer is not trusted - for both 1.7 and 1.8
error.contains(CERTIFICATE_VERIFICATION_FAILED);
// any certificate verification failure - for instance, "certificate issued for a different hostname" and/or
// "issuer is not trusted" - for both 1.7 and 1.8.
// SVNKit-based implementation persists credentials (by utilizing SVNKit api) emulating situation as if credentials were cached
// by Subversion. That is why we could process both untrusted and invalid certificate errors.
useSvnKit && isCertificateVerificationFailed(error) ||
// valid but untrusted certificates - "issuer is not trusted" error - for both 1.7 and 1.8.
// Implementation not based on SVNKit does not persist credentials to emulate situation as if credentials were cached by
// Subversion. And in "--non-interactive" mode we could only make Subversion accept untrusted, but not invalid certificate.
// So we explicitly check that verification failure is only "issuer is not trusted". If certificate has some other failures,
// command will end with error.
!useSvnKit && isValidButUntrustedCertificate(error);
}
@Override
@@ -56,9 +69,8 @@ public class CertificateCallbackCase extends AuthCallbackCase {
realm = serverUrl != null ? serverUrl.toString() : realm;
}
if (!myTried && myAuthenticationService.acceptSSLServerCertificate(myUrl, realm)) {
if (myAuthenticationService.acceptSSLServerCertificate(myUrl, realm)) {
accepted = true;
myTried = true;
return true;
}
throw new SvnBindException("Server SSL certificate rejected");
@@ -87,6 +99,14 @@ public class CertificateCallbackCase extends AuthCallbackCase {
}
}
public static boolean isValidButUntrustedCertificate(@NotNull String error) {
return error.contains(CERTIFICATE_VERIFICATION_FAILED_ISSUER_NOT_TRUSTED);
}
public static boolean isCertificateVerificationFailed(@NotNull String error) {
return error.contains(CERTIFICATE_VERIFICATION_FAILED);
}
private SVNURL getServerUrl(String realm) {
SVNURL result = parseUrl(realm);
@@ -15,6 +15,7 @@
*/
package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.auth.AuthenticationService;
@@ -49,13 +50,17 @@ public class UsernamePasswordCallback extends AuthCallbackCase {
@Override
public boolean canHandle(String error) {
boolean useSvnKit = Registry.is("svn.use.svnkit.for.https.server.certificate.check");
return
// http/https protocol invalid credentials
error.contains(AUTHENTICATION_FAILED_MESSAGE) ||
// svn protocol invalid credentials - messages could be "Can't get password", "Can't get username or password"
error.contains(INVALID_CREDENTIALS_FOR_SVN_PROTOCOL) && error.contains(PASSWORD_STRING) ||
// http/https protocol, svn 1.7, non-interactive
error.contains(UNABLE_TO_CONNECT_MESSAGE) ||
// we additionally check that error is not related to certificate verification - as CertificateCallbackCase could only handle
// untrusted certificates, but not invalid when useSvnKit = false
(error.contains(UNABLE_TO_CONNECT_MESSAGE) && (useSvnKit || !CertificateCallbackCase.isCertificateVerificationFailed(error))) ||
// http, svn 1.6, non-interactive
StringUtil.containsIgnoreCase(error, COULD_NOT_AUTHENTICATE_TO_SERVER_MESSAGE);
}
+1
View File
@@ -91,6 +91,7 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="http-client" level="project" />
</component>
</module>
@@ -89,24 +89,19 @@ public abstract class NewBaseRepositoryImpl extends BaseRepository {
provider.setCredentials(BASIC_AUTH_SCOPE, new UsernamePasswordCredentials(getUsername(), getPassword()));
}
// Proxy authentication
HttpConfigurable proxySettings = HttpConfigurable.getInstance();
if (isUseProxy() && proxySettings.PROXY_AUTHENTICATION) {
provider.setCredentials(new AuthScope(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT),
new UsernamePasswordCredentials(proxySettings.PROXY_LOGIN, proxySettings.getPlainProxyPassword()));
}
HttpConfigurable.getInstance().setProxyCredentials(provider, isUseProxy());
return provider;
}
@NotNull
protected RequestConfig createRequestConfig() {
TaskSettings tasksSettings = TaskSettings.getInstance();
HttpConfigurable proxySettings = HttpConfigurable.getInstance();
RequestConfig.Builder builder = RequestConfig.custom()
.setConnectTimeout(3000)
.setSocketTimeout(tasksSettings.CONNECTION_TIMEOUT);
if (isUseProxy()) {
builder.setProxy(new HttpHost(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT));
}
HttpConfigurable.getInstance().setProxy(builder, isUseProxy());
return builder.build();
}
@@ -3,10 +3,17 @@ package org.jetbrains.builtInWebServer;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;
@@ -29,9 +36,21 @@ public final class ConsoleManager {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
ToolWindow toolWindow = ToolWindowManager.getInstance(netService.project).registerToolWindow(netService.getConsoleToolWindowId(), false, ToolWindowAnchor.BOTTOM, netService.project, true);
ActionGroup actionGroup = netService.getConsoleToolWindowActions();
ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, false);
SimpleToolWindowPanel toolWindowPanel = new SimpleToolWindowPanel(false, true);
toolWindowPanel.setContent(console.getComponent());
toolWindowPanel.setToolbar(toolbar.getComponent());
ToolWindow toolWindow = ToolWindowManager.getInstance(netService.project)
.registerToolWindow(netService.getConsoleToolWindowId(), false, ToolWindowAnchor.BOTTOM, netService.project, true);
toolWindow.setIcon(netService.getConsoleToolWindowIcon());
toolWindow.getContentManager().addContent(ContentFactory.SERVICE.getInstance().createContent(console.getComponent(), "", false));
Content content = ContentFactory.SERVICE.getInstance().createContent(toolWindowPanel, "", false);
Disposer.register(content, console);
toolWindow.getContentManager().addContent(content);
}
}, netService.project.getDisposed());
}
@@ -8,6 +8,8 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -119,7 +121,10 @@ public abstract class NetService implements Disposable {
@Nullable
protected abstract OSProcessHandler createProcessHandler(@NotNull Project project, int port) throws ExecutionException;
protected void connectToProcess(@NotNull AsyncResult<OSProcessHandler> asyncResult, int port, @NotNull OSProcessHandler processHandler, @NotNull Consumer<String> errorOutputConsumer) {
protected void connectToProcess(@NotNull AsyncResult<OSProcessHandler> asyncResult,
int port,
@NotNull OSProcessHandler processHandler,
@NotNull Consumer<String> errorOutputConsumer) {
asyncResult.setDone(processHandler);
}
@@ -139,6 +144,11 @@ public abstract class NetService implements Disposable {
@NotNull
protected abstract Icon getConsoleToolWindowIcon();
@NotNull
public ActionGroup getConsoleToolWindowActions() {
return new DefaultActionGroup();
}
private final class MyProcessAdapter extends ProcessAdapter implements Consumer<String> {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {