Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-04-11 21:53:43 +04:00
44 changed files with 624 additions and 491 deletions
-1
View File
@@ -314,7 +314,6 @@
</inspection_tool>
<inspection_tool class="MethodNamesDifferOnlyByCase" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverloadsParentMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesPrivateMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -197,7 +197,6 @@ public class CompilerErrorTreeView extends NewErrorTreeViewPanel {
final String[] text = messageElement.getText();
if (text.length > 0) {
if (text[0].startsWith("[") && text[0].indexOf("]") != -1) {
presentation.setVisible(true);
final Navigatable navigatable = messageElement.getNavigatable();
if (navigatable instanceof OpenFileDescriptor) {
final OpenFileDescriptor fileDescriptor = (OpenFileDescriptor)navigatable;
@@ -217,6 +216,7 @@ public class CompilerErrorTreeView extends NewErrorTreeViewPanel {
final SuppressFix suppressInspectionFix = getSuppressAction(id);
final boolean available = suppressInspectionFix.isAvailable(project, null, context);
presentation.setEnabled(available);
presentation.setVisible(available);
if (available) {
presentation.setText(suppressInspectionFix.getText());
}
@@ -459,7 +459,7 @@ public class JavaCompletionUtil {
}
}
if (javaReference instanceof PsiReferenceExpression && !((PsiReferenceExpression)javaReference).isQualified()) {
if (javaReference instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement)javaReference).isQualified()) {
final StaticMemberProcessor memberProcessor = JavaGlobalMemberNameCompletionContributor.completeStaticMembers(parameters);
memberProcessor.processMembersOfRegisteredClasses(matcher, new PairConsumer<PsiMember, PsiClass>() {
@Override
@@ -29,6 +29,7 @@ import com.intellij.ide.fileTemplates.JavaTemplateUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -182,7 +183,7 @@ public class CreateFromUsageUtils {
}
}
public static void setupEditor(PsiMethod method, Editor newEditor) {
public static void setupEditor(PsiMethod method, final Editor newEditor) {
PsiCodeBlock body = method.getBody();
if (body != null) {
PsiElement l = PsiTreeUtil.skipSiblingsForward(body.getLBrace(), PsiWhiteSpace.class);
@@ -191,7 +192,14 @@ public class CreateFromUsageUtils {
int start = l.getTextRange().getStartOffset();
int end = r.getTextRange().getEndOffset();
newEditor.getCaretModel().moveToOffset(Math.max(start, end));
newEditor.getSelectionModel().setSelection(Math.min(start, end), Math.max(start, end));
if (end < start) {
newEditor.getCaretModel().moveToOffset(end + 1);
CodeStyleManager styleManager = CodeStyleManager.getInstance(method.getProject());
final String lineIndent = styleManager.getLineIndent(method.getContainingFile(), Math.min(start, end));
EditorModificationUtil.insertStringAtCaret(newEditor, lineIndent);
} else {
newEditor.getSelectionModel().setSelection(Math.min(start, end), Math.max(start, end));
}
newEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
}
@@ -0,0 +1,11 @@
import static Foo.assertNotNull;
class Foo {
static void assertNotNull() {}
}
class Bar {
{
asnn<caret> lists.get(0).size() > 0);
}
}
@@ -0,0 +1,11 @@
import static Foo.assertNotNull;
class Foo {
static void assertNotNull() {}
}
class Bar {
{
assertNotNull();<caret> lists.get(0).size() > 0);
}
}
@@ -1328,5 +1328,6 @@ public class ListUtils {
public void testListArrayListCast() { doTest('\n') }
public void testInterfaceImplementationNoCast() { doTest() }
public void testStaticallyImportedMethodsBeforeExpression() { doTest() }
}
@@ -208,6 +208,8 @@ public class IncProjectBuilder {
private void runBuild(CompileContext context) throws ProjectBuildException {
context.setDone(0.0f);
LOG.info("Building project '" + context.getProject().getProjectName() + "'; isRebuild:" +context.isProjectRebuild() + "; isMake:" + context.isMake());
if (context.isProjectRebuild()) {
cleanOutputRoots(context);
}
@@ -136,6 +136,11 @@ public class ClassRepr extends Proto {
public boolean hadValue() {
return false;
}
@Override
public boolean weakedAccess() {
return diff.weakedAccess();
}
};
}
@@ -1,6 +1,7 @@
package org.jetbrains.ether.dependencyView;
import com.intellij.openapi.util.Pair;
import org.jetbrains.asm4.Opcodes;
import java.util.*;
@@ -12,6 +13,16 @@ import java.util.*;
* To change this template use File | Settings | File Templates.
*/
abstract class Difference {
public static boolean isPackageLocal(final int access) {
return (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0;
}
public static boolean weakerAccess(final int me, final int then) {
return ((me & Opcodes.ACC_PRIVATE) > 0 && (then & Opcodes.ACC_PRIVATE) == 0) ||
((me & Opcodes.ACC_PROTECTED) > 0 && (then & Opcodes.ACC_PUBLIC) > 0) ||
(isPackageLocal(me) && (then & Opcodes.ACC_PROTECTED) > 0);
}
public static final int NONE = 0;
public static final int ACCESS = 1;
public static final int TYPE = 2;
@@ -21,8 +32,11 @@ abstract class Difference {
public interface Specifier<T> {
Collection<T> added();
Collection<T> removed();
Collection<Pair<T, Difference>> changed();
boolean unchanged();
}
@@ -105,11 +119,13 @@ abstract class Difference {
public abstract boolean no();
public abstract boolean weakedAccess();
public abstract int addedModifiers();
public abstract int removedModifiers();
public abstract boolean packageLocalOn();
public abstract boolean hadValue ();
public abstract boolean hadValue();
}
@@ -733,19 +733,9 @@ public class Mappings {
}
}
private static boolean isPackageLocal(final int access) {
return (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0;
}
private static boolean weakerAccess(final int me, final int then) {
return ((me & Opcodes.ACC_PRIVATE) > 0 && (then & Opcodes.ACC_PRIVATE) == 0) ||
((me & Opcodes.ACC_PROTECTED) > 0 && (then & Opcodes.ACC_PUBLIC) > 0) ||
(isPackageLocal(me) && (then & Opcodes.ACC_PROTECTED) > 0);
}
private static boolean isVisibleIn(final ClassRepr c, final ProtoMember m, final ClassRepr scope) {
final boolean privacy = ((m.access & Opcodes.ACC_PRIVATE) > 0) && c.name != scope.name;
final boolean packageLocality = isPackageLocal(m.access) && !c.getPackageName().equals(scope.getPackageName());
final boolean packageLocality = Difference.isPackageLocal(m.access) && !c.getPackageName().equals(scope.getPackageName());
return !privacy && !packageLocality;
}
@@ -1080,7 +1070,7 @@ public class Mappings {
final Option<Boolean> subtypeOf = u.isSubtypeOf(mm.type, m.type);
if (weakerAccess(mm.access, m.access) ||
if (Difference.weakerAccess(mm.access, m.access) ||
((m.access & Opcodes.ACC_STATIC) > 0 && (mm.access & Opcodes.ACC_STATIC) == 0) ||
((m.access & Opcodes.ACC_STATIC) == 0 && (mm.access & Opcodes.ACC_STATIC) > 0) ||
((m.access & Opcodes.ACC_FINAL) > 0) ||
@@ -1382,7 +1372,7 @@ public class Mappings {
final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0;
final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0;
final boolean ffPublic = (ff.access & Opcodes.ACC_PUBLIC) > 0;
final boolean ffPLocal = isPackageLocal(ff.access);
final boolean ffPLocal = Difference.isPackageLocal(ff.access);
if (!ffPrivate) {
final TIntHashSet propagated = o.propagateFieldAccess(ff.name, cc.name);
@@ -1441,10 +1431,15 @@ public class Mappings {
final Difference d = f.second;
final FieldRepr field = f.first;
debug("Field: ", it.name);
debug("Field: ", field.name);
if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & mask) == mask) {
if ((d.base() & Difference.ACCESS) > 0 || ((d.base() & Difference.VALUE) > 0 && d.hadValue())) {
final int changedModifiers = d.addedModifiers() | d.removedModifiers();
final boolean harmful = (changedModifiers & (Opcodes.ACC_STATIC | Opcodes.ACC_FINAL)) > 0;
final boolean accessChanged = (changedModifiers & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) > 0;
final boolean valueChanged = (d.base() & Difference.VALUE) > 0 && d.hadValue();
if (harmful || valueChanged || (accessChanged && !d.weakedAccess())) {
debug("Inline field changed it's access or value => a switch to non-incremental mode requested");
if (!incrementalDecision(it.name, field, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
@@ -1643,7 +1638,10 @@ public class Mappings {
}
}
private void cleanupRemovedClass(@NotNull ClassRepr cr, Collection<UsageRepr.Cluster> clusters, IntIntMultiMaplet subclassesTrashBin, IntIntMultiMaplet dependenciesTrashBin) {
private void cleanupRemovedClass(@NotNull ClassRepr cr,
Collection<UsageRepr.Cluster> clusters,
IntIntMultiMaplet subclassesTrashBin,
IntIntMultiMaplet dependenciesTrashBin) {
final int className = cr.name;
for (final int superSomething : cr.getSupers()) {
@@ -1811,7 +1809,6 @@ public class Mappings {
return true;
}
});
}
finally {
delta.close();
@@ -2026,7 +2023,7 @@ public class Mappings {
@NotNull
private Set<ClassRepr> getDeletedClasses() {
return myDeletedClasses != null? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
return myDeletedClasses != null ? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
private TIntHashSet getChangedClasses() {
@@ -2052,5 +2049,4 @@ public class Mappings {
private void debug(final String comment, final boolean s) {
myDebugS.debug(comment, s);
}
}
@@ -85,6 +85,11 @@ class MethodRepr extends ProtoMember {
public boolean hadValue() {
return ((MethodRepr)past).hasValue();
}
@Override
public boolean weakedAccess() {
return diff.weakedAccess();
}
};
}
@@ -1,6 +1,6 @@
package org.jetbrains.ether.dependencyView;
import groovyjarjarasm.asm.Opcodes;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.ether.RW;
import java.io.DataInput;
@@ -86,17 +86,19 @@ class Proto implements RW.Savable {
public boolean packageLocalOn() {
return ((past.access & Opcodes.ACC_PRIVATE) != 0 ||
(past.access & Opcodes.ACC_PUBLIC) != 0 ||
(past.access & Opcodes.ACC_PROTECTED) != 0)
&&
((access & Opcodes.ACC_PRIVATE) == 0 && (access & Opcodes.ACC_PROTECTED) == 0 && (access & Opcodes.ACC_PUBLIC) == 0);
(past.access & Opcodes.ACC_PROTECTED) != 0) &&
Difference.isPackageLocal(access);
}
@Override
public boolean hadValue() {
return false;
}
@Override
public boolean weakedAccess() {
return Difference.weakerAccess(past.access, access);
}
};
}
}
@@ -172,6 +172,11 @@ abstract class ProtoMember extends Proto {
public boolean hadValue() {
return ((ProtoMember)past).hasValue();
}
@Override
public boolean weakedAccess() {
return diff.weakedAccess();
}
};
}
}
@@ -211,6 +211,14 @@ public class IconUtil {
return getToolbarDecoratorIcon("addClass.png");
}
public static Icon getImportIcon() {
return IconLoader.getIcon("/toolbarDecorator/import.png");
}
public static Icon getExportIcon() {
return IconLoader.getIcon("/toolbarDecorator/export.png");
}
public static Icon getToolbarDecoratorIcon(String name) {
return IconLoader.getIcon(getToolbarDecoratorIconsFolder() + name);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -17,12 +17,22 @@
package com.intellij.codeInsight.template.impl;
import com.intellij.openapi.options.CompoundScheme;
import org.jetbrains.annotations.Nullable;
public class TemplateGroup extends CompoundScheme<TemplateImpl> {
private final String myReplace;
public TemplateGroup(final String name) {
super(name);
this(name, null);
}
public TemplateGroup(String name, @Nullable String replace) {
super(name);
myReplace = replace;
}
public String getReplace() {
return myReplace;
}
}
@@ -487,7 +487,14 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
String templateName = getDefaultTemplateName(defTemplate);
InputStream inputStream = DecodeDefaultsUtil.getDefaultsInputStream(provider, defTemplate);
if (inputStream != null) {
readDefTemplateFile(inputStream, templateName, provider.getClass().getClassLoader(), registerTemplate);
TemplateGroup group =
readTemplateFile(JDOMUtil.loadDocument(inputStream), templateName, true, registerTemplate, provider.getClass().getClassLoader());
if (group != null && group.getReplace() != null) {
Collection<TemplateImpl> templates = myTemplates.get(group.getReplace());
for (TemplateImpl template : templates) {
removeTemplate(template);
}
}
}
}
@@ -495,10 +502,6 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
return defTemplate.substring(defTemplate.lastIndexOf("/") + 1);
}
private void readDefTemplateFile(InputStream inputStream, String defGroupName, ClassLoader classLoader, boolean registerTemplate) throws JDOMException, InvalidDataException, IOException {
readTemplateFile(JDOMUtil.loadDocument(inputStream), defGroupName, true, registerTemplate, classLoader);
}
@Nullable
private TemplateGroup readTemplateFile(Document document, @NonNls String defGroupName, boolean isDefault, boolean registerTemplate, ClassLoader classLoader) throws InvalidDataException {
if (document == null) {
@@ -512,7 +515,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
String groupName = root.getAttributeValue(GROUP);
if (groupName == null || groupName.length() == 0) groupName = defGroupName;
TemplateGroup result = new TemplateGroup(groupName);
TemplateGroup result = new TemplateGroup(groupName, root.getAttributeValue("REPLACE"));
Map<String, TemplateImpl> created = new LinkedHashMap<String, TemplateImpl>();
@@ -22,6 +22,7 @@ import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.ui.InspectionNode;
import com.intellij.codeInspection.ui.InspectionTreeNode;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -109,5 +110,8 @@ public class CommonInspectionToolWrapper extends InspectionToolWrapper<Inspectio
return getTool().queryExternalUsagesRequests(manager);
}
@Override
public void exportResults(@NotNull Element parentNode) {
getTool().exportResults(parentNode);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -176,7 +176,10 @@ public class ProjectWideFacetListenersRegistryImpl extends ProjectWideFacetListe
}
public <F extends Facet> void unregisterListener(@NotNull FacetTypeId<F> typeId, @NotNull ProjectWideFacetListener<? extends F> listener) {
myDispatchers.get(typeId).removeListener(listener);
final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
if (dispatcher != null) {
dispatcher.removeListener(listener);
}
}
public <F extends Facet> void registerListener(@NotNull final FacetTypeId<F> typeId, @NotNull final ProjectWideFacetListener<? extends F> listener,
@@ -22,6 +22,7 @@ import com.intellij.application.options.SchemesToImportPopup;
import com.intellij.ide.highlighter.custom.SyntaxTable;
import com.intellij.ide.highlighter.custom.impl.ReadFileType;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
@@ -35,7 +36,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.templateLanguages.TemplateDataLanguagePatterns;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.IconUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,8 +44,6 @@ import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
@@ -134,13 +133,13 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
public void reset() {
myTempPatternsTable = myManager.getExtensionMap().copy();
myTempTemplateDataLanguages = TemplateDataLanguagePatterns.getInstance().getAssocTable();
myTempFileTypes = new HashSet<FileType>(Arrays.asList(getModifiableFileTypes()));
myOriginalToEditedMap.clear();
updateFileTypeList();
updateExtensionList();
myFileTypePanel.myIgnoreFilesField.setText(myManager.getIgnoredFilesList());
}
@@ -148,7 +147,8 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
if (!myManager.isIgnoredFilesListEqualToCurrent(myFileTypePanel.myIgnoreFilesField.getText())) return true;
HashSet types = new HashSet(Arrays.asList(getModifiableFileTypes()));
return !myTempPatternsTable.equals(myManager.getExtensionMap()) || !myTempFileTypes.equals(types) ||
!myOriginalToEditedMap.isEmpty() || !myTempTemplateDataLanguages.equals(TemplateDataLanguagePatterns.getInstance().getAssocTable());
!myOriginalToEditedMap.isEmpty() ||
!myTempTemplateDataLanguages.equals(TemplateDataLanguagePatterns.getInstance().getAssocTable());
}
public void disposeUIResources() {
@@ -194,7 +194,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
UserFileType ftToEdit = myOriginalToEditedMap.get(fileType);
if (ftToEdit == null) ftToEdit = ((UserFileType)fileType).clone();
TypeEditor editor =
new TypeEditor(myRecognizedFileType.myEditButton, ftToEdit, FileTypesBundle.message("filetype.edit.existing.title"));
new TypeEditor(myRecognizedFileType.myFileTypesList, ftToEdit, FileTypesBundle.message("filetype.edit.existing.title"));
editor.show();
if (editor.isOK()) {
myOriginalToEditedMap.put((UserFileType)fileType, ftToEdit);
@@ -220,7 +220,8 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
private void addFileType() {
//TODO: support adding binary file types...
AbstractFileType type = new AbstractFileType(new SyntaxTable());
TypeEditor<AbstractFileType> editor = new TypeEditor<AbstractFileType>(myRecognizedFileType.myAddButton, type, FileTypesBundle.message("filetype.edit.new.title"));
TypeEditor<AbstractFileType> editor =
new TypeEditor<AbstractFileType>(myRecognizedFileType.myFileTypesList, type, FileTypesBundle.message("filetype.edit.new.title"));
editor.show();
if (editor.isOK()) {
myTempFileTypes.add(type);
@@ -242,7 +243,9 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
if (type == null) return;
final String title =
item == null ? FileTypesBundle.message("filetype.edit.add.pattern.title") : FileTypesBundle.message("filetype.edit.edit.pattern.title");
item == null
? FileTypesBundle.message("filetype.edit.add.pattern.title")
: FileTypesBundle.message("filetype.edit.edit.pattern.title");
final Language oldLanguage = item == null ? null : myTempTemplateDataLanguages.findAssociatedFileType(item);
final FileTypePatternDialog dialog = new FileTypePatternDialog(item, type, oldLanguage);
@@ -259,20 +262,21 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
FileType registeredFileType = findExistingFileType(matcher);
if (registeredFileType != null && registeredFileType != type) {
if (registeredFileType.isReadOnly()) {
Messages.showMessageDialog(myPatterns.myAddButton,
Messages.showMessageDialog(myPatterns.myPatternsList,
FileTypesBundle.message("filetype.edit.add.pattern.exists.error", registeredFileType.getDescription()),
title, Messages.getErrorIcon());
return;
}
else {
if (0 == Messages.showOkCancelDialog(myPatterns.myAddButton, FileTypesBundle.message("filetype.edit.add.pattern.exists.message",
registeredFileType.getDescription()),
FileTypesBundle.message("filetype.edit.add.pattern.exists.title"),
FileTypesBundle.message("filetype.edit.add.pattern.reassign.button"),
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon())) {
if (0 == Messages.showOkCancelDialog(myPatterns.myPatternsList, FileTypesBundle.message("filetype.edit.add.pattern.exists.message",
registeredFileType.getDescription()),
FileTypesBundle.message("filetype.edit.add.pattern.exists.title"),
FileTypesBundle.message("filetype.edit.add.pattern.reassign.button"),
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon())) {
myTempPatternsTable.removeAssociation(matcher, registeredFileType);
myTempTemplateDataLanguages.removeAssociation(matcher, oldLanguage);
} else {
}
else {
return;
}
}
@@ -345,16 +349,13 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
public static class RecognizedFileTypes extends JPanel {
private JList myFileTypesList;
private JButton myAddButton;
private JButton myEditButton;
private JButton myRemoveButton;
private JPanel myWholePanel;
private JButton myExportButton;
private JButton myImportButton;
private FileTypeConfigurable myController;
public RecognizedFileTypes() {
super(new BorderLayout());
add(myWholePanel, BorderLayout.CENTER);
myFileTypesList = new JBList(new DefaultListModel());
myFileTypesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myFileTypesList.setCellRenderer(new FileTypeRenderer(myFileTypesList.getCellRenderer(), new FileTypeRenderer.FileTypeListProvider() {
public Iterable<FileType> getCurrentFileTypeList() {
ArrayList<FileType> result = new ArrayList<FileType>();
@@ -364,16 +365,80 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
return result;
}
}));
myFileTypesList.setModel(new DefaultListModel());
myFileTypesList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) myController.editFileType();
}
});
if (getSchemesManager().isImportAvailable()) {
myImportButton.setVisible(true);
}
if (getSchemesManager().isExportAvailable()) {
myExportButton.setVisible(true);
}
ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myFileTypesList)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.addFileType();
}
}).setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.removeFileType();
}
}).setEditAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.editFileType();
}
}).setEditActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final FileType fileType = getSelectedFileType();
return canBeModified(fileType);
}
}).setRemoveActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final FileType fileType = getSelectedFileType();
final boolean modified = canBeModified(fileType);
final boolean shared = getSchemesManager().isShared(fileType);
return shared || modified;
}
}).disableUpDownActions();
//if (getSchemesManager().isImportAvailable()) {
toolbarDecorator.addExtraAction(new AnActionButton("Import Shared...", IconUtil.getImportIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
new SchemesToImportPopup<FileType, AbstractFileType>(myFileTypesList) {
protected void onSchemeSelected(final AbstractFileType scheme) {
myController.importFileType(scheme);
}
}.show(getSchemesManager(), collectRegisteredFileTypes());
}
});
//}
//if (getSchemesManager().isExportAvailable()) {
toolbarDecorator.addExtraAction(new AnActionButton("Share...", IconUtil.getExportIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
FileType selected = (FileType)myFileTypesList.getSelectedValue();
if (selected instanceof AbstractFileType) {
ExportSchemeAction.doExport((AbstractFileType)selected, getSchemesManager());
}
}
@Override
public void updateButton(AnActionEvent e) {
FileType fileType = getSelectedFileType();
boolean b = canBeModified(fileType);
boolean shared = getSchemesManager().isShared(fileType);
setEnabled(b && !shared);
}
});
//}
add(toolbarDecorator.createPanel(), BorderLayout.CENTER);
setBorder(IdeBorderFactory.createTitledBorder(FileTypesBundle.message("filetypes.recognized.group"), false));
}
private SchemesManager<FileType, AbstractFileType> getSchemesManager() {
@@ -381,58 +446,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
}
public void attachActions(final FileTypeConfigurable controller) {
myAddButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.addFileType();
}
});
myEditButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.editFileType();
}
});
myFileTypesList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
FileType fileType = getSelectedFileType();
boolean b = canBeModified(fileType);
myEditButton.setEnabled(b);
myRemoveButton.setEnabled(b);
boolean shared = getSchemesManager().isShared(fileType);
myExportButton.setEnabled(b && !shared);
if (shared) {
myRemoveButton.setEnabled(true);
}
}
});
myRemoveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.removeFileType();
}
});
myFileTypesList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) controller.editFileType();
}
});
myImportButton.addActionListener(new ActionListener(){
public void actionPerformed(final ActionEvent e) {
new SchemesToImportPopup<FileType, AbstractFileType>(myWholePanel){
protected void onSchemeSelected(final AbstractFileType scheme) {
controller.importFileType(scheme);
}
}.show(getSchemesManager(), collectRegisteredFileTypes());
}
});
myExportButton.addActionListener(new ActionListener(){
public void actionPerformed(final ActionEvent e) {
FileType selected = (FileType)myFileTypesList.getSelectedValue();
if (selected instanceof AbstractFileType) {
ExportSchemeAction.doExport((AbstractFileType)selected, getSchemesManager());
}
}
});
myController = controller;
}
private Collection<FileType> collectRegisteredFileTypes() {
@@ -448,7 +462,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
}
public JComponent getComponent() {
return myWholePanel;
return this;
}
public void setFileTypes(FileType[] types) {
@@ -489,13 +503,10 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
updateFileTypeList();
updateExtensionList();
myRecognizedFileType.selectFileType(type);
}
public static class PatternsPanel extends JPanel {
private JBList myPatternsList;
private JComponent myAddButton;
private JPanel myWholePanel;
private FileTypeConfigurable myController;
public PatternsPanel() {
@@ -505,27 +516,25 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
myPatternsList.setCellRenderer(new ExtensionRenderer());
myPatternsList.getEmptyText().setText(FileTypesBundle.message("filetype.settings.no.patterns"));
myWholePanel = ToolbarDecorator.createDecorator(myPatternsList)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.addPattern();
}
}).setEditAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.editPattern();
}
}).setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.removePattern();
}
}).disableUpDownActions().createPanel();
UIUtil.addBorder(myWholePanel, IdeBorderFactory.createTitledBorder(FileTypesBundle.message("filetype.registered.patterns.group"), false));
myAddButton = ToolbarDecorator.findAddButton(myWholePanel).getContextComponent();
add(ToolbarDecorator.createDecorator(myPatternsList)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.addPattern();
}
}).setEditAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.editPattern();
}
}).setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
myController.removePattern();
}
}).disableUpDownActions().createPanel(), BorderLayout.CENTER);
add(myWholePanel, BorderLayout.CENTER);
setBorder(IdeBorderFactory.createTitledBorder(FileTypesBundle.message("filetype.registered.patterns.group"), false));
}
public void attachActions(final FileTypeConfigurable controller) {
@@ -533,7 +542,7 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
}
public JComponent getComponent() {
return myWholePanel;
return this;
}
public void clearList() {
@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.fileTypes.impl.FileTypeConfigurable.RecognizedFileTypes">
<grid id="82e7b" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="115" y="72" width="597" height="345"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
</clientProperties>
<border type="etched" title-resource-bundle="messages/FileTypesBundle" title-key="filetypes.recognized.group"/>
<children>
<scrollpane id="de9d1" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="6" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="80" height="80"/>
<preferred-size width="200" height="150"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="f12a0" class="com.intellij.ui.components.JBList" binding="myFileTypesList">
<constraints/>
<properties>
<selectionMode value="0"/>
</properties>
</component>
</children>
</scrollpane>
<component id="2631f" class="javax.swing.JButton" binding="myEditButton">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/FileTypesBundle" key="filetypes.recognized.edit.button"/>
</properties>
</component>
<component id="eb813" class="javax.swing.JButton" binding="myAddButton">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/FileTypesBundle" key="filetypes.recognized.add.button"/>
</properties>
</component>
<component id="55eb9" class="javax.swing.JButton" binding="myRemoveButton">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/FileTypesBundle" key="filetypes.recognized.remove.button"/>
</properties>
</component>
<vspacer id="73ae2">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="274f" class="javax.swing.JButton" binding="myExportButton" default-binding="true">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Share..."/>
<visible value="false"/>
</properties>
</component>
<component id="69cb9" class="javax.swing.JButton" binding="myImportButton" default-binding="true">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="true"/>
<text value="&amp;Import Shared..."/>
<visible value="false"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -58,6 +58,7 @@ public abstract class StartupManager {
* progress bar is displayed. You may access the PSI structures from the activity.
*
* @param runnable the activity to execute.
* @see StartupActivity#POST_STARTUP_ACTIVITY
*/
public abstract void registerPostStartupActivity(@NotNull Runnable runnable);
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.table.TableView;
import com.intellij.util.ui.ElementProducer;
@@ -78,6 +79,7 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
private Dimension myPreferredSize;
private CommonActionsPanel myPanel;
private Comparator<AnActionButton> myButtonComparator;
private boolean myAsTopToolbar = false;
protected abstract JComponent getComponent();
@@ -87,33 +89,31 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
return myPanel;
}
public ToolbarDecorator initPositionAndBorder() {
myToolbarPosition = UIUtil.isUnderAquaLookAndFeel() ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.RIGHT;
myBorder = new CustomLineBorder(0,
myToolbarPosition == ActionToolbarPosition.RIGHT ? 1 : 0,
myToolbarPosition == ActionToolbarPosition.TOP ? 1 : 0,
myToolbarPosition == ActionToolbarPosition.LEFT ? 1 : 0);
final JComponent c = getComponent();
if (c != null) {
c.setBorder(IdeBorderFactory.createEmptyBorder(0));
}
public ToolbarDecorator initPosition() {
setToolbarPosition(SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.RIGHT);
return this;
}
public ToolbarDecorator setAsTopToolbar() {
myAsTopToolbar = true;
setToolbarPosition(ActionToolbarPosition.TOP);
return this;
}
public static ToolbarDecorator createDecorator(@NotNull JTable table) {
return new TableToolbarDecorator(table, null).initPositionAndBorder();
return new TableToolbarDecorator(table, null).initPosition();
}
public static ToolbarDecorator createDecorator(@NotNull JTree tree) {
return new TreeToolbarDecorator(tree).initPositionAndBorder();
return new TreeToolbarDecorator(tree).initPosition();
}
public static ToolbarDecorator createDecorator(@NotNull JList list) {
return new ListToolbarDecorator(list).initPositionAndBorder();
return new ListToolbarDecorator(list).initPosition();
}
public static <T> ToolbarDecorator createDecorator(@NotNull TableView<T> table, @Nullable ElementProducer<T> producer) {
return new TableToolbarDecorator(table, producer).initPositionAndBorder();
return new TableToolbarDecorator(table, producer).initPosition();
}
public ToolbarDecorator disableAddAction() {
@@ -301,9 +301,15 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
installUpdaters();
updateButtons();
installDnD();
panel.setBorder(new LineBorder(UIUtil.getBorderColor()));
panel.putClientProperty(ActionToolbar.ACTION_TOOLBAR_PROPERTY_KEY, myPanel.getComponent(0));
DataManager.registerDataProvider(panel, this);
if (!myAsTopToolbar) {
panel.setBorder(new LineBorder(UIUtil.getBorderColor()));
final JComponent c = getComponent();
if (contextComponent != null) {
contextComponent.setBorder(IdeBorderFactory.createEmptyBorder(0));
}
}
return panel;
}
@@ -31,9 +31,8 @@ class TreeToolbarDecorator extends ToolbarDecorator {
}
@Override
public ToolbarDecorator initPositionAndBorder() {
return super.initPositionAndBorder()
.setToolbarPosition(SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.TOP);
public ToolbarDecorator initPosition() {
return setToolbarPosition(SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.TOP);
}
@Override
@@ -24,6 +24,7 @@ import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -136,25 +137,10 @@ public class CustomFileTypeEditor extends SettingsEditor<AbstractFileType> {
JPanel panel = new JPanel(new BorderLayout());
JPanel fileTypePanel = new JPanel(new BorderLayout());
JPanel info = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.WEST;
gc.fill = GridBagConstraints.BOTH;
info.add(new JLabel(IdeBundle.message("editbox.customfiletype.name")), gc);
gc.gridx = 1;
gc.gridy = 0;
gc.weightx = 1;
info.add(myFileTypeName, gc);
gc.weightx = 0;
gc.gridx = 0;
gc.gridy = 1;
info.add(new JLabel(IdeBundle.message("editbox.customfiletype.description")), gc);
gc.gridx = 1;
info.add(myFileTypeDescr, gc);
info.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
JPanel info = FormBuilder.createFormBuilder()
.addLabeledComponent(IdeBundle.message("editbox.customfiletype.name"), myFileTypeName)
.addLabeledComponent(IdeBundle.message("editbox.customfiletype.description"), myFileTypeDescr).getPanel();
info.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
fileTypePanel.add(info, BorderLayout.NORTH);
JPanel highlighterPanel = new JPanel();
@@ -164,10 +150,11 @@ public class CustomFileTypeEditor extends SettingsEditor<AbstractFileType> {
commentsAndNumbersPanel.setLayout(new GridBagLayout());
JPanel _panel1 = new JPanel(new BorderLayout());
GridBag gb = new GridBag().setDefaultFill(GridBagConstraints.HORIZONTAL).setDefaultAnchor(GridBagConstraints.WEST).setDefaultInsets(1,
5,
1,
5);
GridBag gb = new GridBag()
.setDefaultFill(GridBagConstraints.HORIZONTAL)
.setDefaultAnchor(GridBagConstraints.WEST)
.setDefaultInsets(1, 5, 1, 5);
commentsAndNumbersPanel.add(new JLabel(IdeBundle.message("editbox.customfiletype.line.comment")), gb.nextLine().next());
commentsAndNumbersPanel.add(myLineComment, gb.next());
commentsAndNumbersPanel.add(myCommentAtLineStart, gb.next().coverLine(2));
@@ -33,7 +33,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
/**
@@ -135,7 +135,9 @@ public class Utils{
if (actionGroup.hideIfNoVisibleChildren() && !visibleChildren) {
continue;
}
presentation.setEnabled(actionGroup.canBePerformed(context) || visibleChildren);
if (!actionGroup.canBePerformed(context) && !visibleChildren) {
presentation.setEnabled(false);
}
list.add(child);
}
else {
@@ -21,7 +21,6 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
@@ -34,9 +33,6 @@ import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.concurrency.JBLock;
import com.intellij.util.concurrency.JBReentrantReadWriteLock;
import com.intellij.util.concurrency.LockFactory;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -47,51 +43,30 @@ import java.io.IOException;
import java.util.*;
public final class LocalFileSystemImpl extends LocalFileSystemBase implements ApplicationComponent {
private final JBReentrantReadWriteLock LOCK = LockFactory.createReadWriteLock();
private final JBLock WRITE_LOCK = LOCK.writeLock();
private final Object myLock = new Object();
private final List<WatchRequestImpl> myRootsToWatch = new ArrayList<WatchRequestImpl>();
private WatchRequest[] myCachedNormalizedRequests = null;
private WatchRequestImpl[] myCachedNormalizedRequests = null;
private final FileWatcher myWatcher;
private static class WatchRequestImpl implements WatchRequest {
public final String myRootPath;
public String myFSRootPath;
public final boolean myToWatchRecursively;
boolean myDominated;
private final String myRootPath;
private final boolean myToWatchRecursively;
private String myFSRootPath;
private boolean myDominated;
public WatchRequestImpl(String rootPath, final boolean toWatchRecursively) {
myToWatchRecursively = toWatchRecursively;
final int index = rootPath.indexOf(JarFileSystem.JAR_SEPARATOR);
if (index >= 0) rootPath = rootPath.substring(0, index);
final File file = new File(rootPath.replace('/', File.separatorChar));
if (!file.isDirectory()) {
final File parentFile = file.getParentFile();
if (parentFile != null) {
if (SystemInfo.isFileSystemCaseSensitive) {
myFSRootPath = parentFile.getAbsolutePath(); // fixes problem with symlinks under Unix (however does not under Windows!)
}
else {
try {
myFSRootPath = parentFile.getCanonicalPath();
}
catch (IOException e) {
myFSRootPath = rootPath; //need something
}
}
}
else {
myFSRootPath = rootPath.replace('/', File.separatorChar);
}
myRootPath = myFSRootPath.replace(File.separatorChar, '/');
}
else {
myRootPath = rootPath.replace(File.separatorChar, '/');
myFSRootPath = rootPath.replace('/', File.separatorChar);
File rootFile = new File(FileUtil.toSystemDependentName(rootPath));
if (index > 0 || !rootFile.isDirectory()) {
rootFile = rootFile.getParentFile();
assert rootFile != null : rootPath;
}
myFSRootPath = rootFile.getAbsolutePath();
myRootPath = FileUtil.toSystemIndependentName(myFSRootPath);
myToWatchRecursively = toWatchRecursively;
}
@Override
@@ -100,6 +75,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
return myRootPath;
}
/** @deprecated implementation details (to remove in IDEA 13) */
@Override
@NotNull
public String getFileSystemRootPath() {
@@ -111,13 +87,10 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
return myToWatchRecursively;
}
/** @deprecated implementation details (to remove in IDEA 13) */
@Override
public boolean dominates(@NotNull WatchRequest other) {
if (myToWatchRecursively) {
return other.getRootPath().startsWith(myRootPath);
}
return !other.isToWatchRecursively() && myRootPath.equals(other.getRootPath());
return LocalFileSystemImpl.dominates(this, (WatchRequestImpl)other);
}
@Override
@@ -160,13 +133,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
myRootsToWatch.clear();
}
private WatchRequest[] normalizeRootsForRefresh() {
private WatchRequestImpl[] normalizeRootsForRefresh() {
if (myCachedNormalizedRequests != null) return myCachedNormalizedRequests;
List<WatchRequestImpl> result = new ArrayList<WatchRequestImpl>();
// No need to call for a read action here since we're only called with it on hands already.
WRITE_LOCK.lock();
try {
synchronized (myLock) {
NextRoot:
for (WatchRequestImpl request : myRootsToWatch) {
String rootPath = request.getRootPath();
@@ -189,20 +161,17 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
request.myDominated = false;
}
}
finally {
WRITE_LOCK.unlock();
}
myCachedNormalizedRequests = result.toArray(new WatchRequest[result.size()]);
myCachedNormalizedRequests = result.toArray(new WatchRequestImpl[result.size()]);
return myCachedNormalizedRequests;
}
private void storeRefreshStatusToFiles() {
if (FileWatcher.getInstance().isOperational()) {
if (myWatcher.isOperational()) {
// TODO: different ways to mark dirty for all these cases
markPathsDirty(FileWatcher.getInstance().getDirtyPaths());
markFlatDirsDirty(FileWatcher.getInstance().getDirtyDirs());
markRecursiveDirsDirty(FileWatcher.getInstance().getDirtyRecursivePaths());
markPathsDirty(myWatcher.getDirtyPaths());
markFlatDirsDirty(myWatcher.getDirtyDirs());
markRecursiveDirsDirty(myWatcher.getDirtyRecursivePaths());
}
}
@@ -269,26 +238,22 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
application.runReadAction(new Runnable() {
@Override
public void run() {
WRITE_LOCK.lock();
try {
final WatchRequest[] watchRequests = normalizeRootsForRefresh();
synchronized (myLock) {
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
List<String> myRecursiveRoots = new ArrayList<String>();
List<String> myFlatRoots = new ArrayList<String>();
for (WatchRequest root : watchRequests) {
for (WatchRequestImpl root : watchRequests) {
if (root.isToWatchRecursively()) {
myRecursiveRoots.add(root.getFileSystemRootPath());
myRecursiveRoots.add(root.myFSRootPath);
}
else {
myFlatRoots.add(root.getFileSystemRootPath());
myFlatRoots.add(root.myFSRootPath);
}
}
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
}
finally {
WRITE_LOCK.unlock();
}
}
});
}
@@ -298,8 +263,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
private static final long PERIOD = 1000;
public StoreRefreshStatusThread() {
//noinspection HardCodedStringLiteral
super("StoreRefreshStatusThread");
super(StoreRefreshStatusThread.class.getSimpleName());
setPriority(MIN_PRIORITY);
setDaemon(true);
}
@@ -324,14 +288,13 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
@Override
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) {
if (rootPath.length() == 0 || !FileWatcher.getInstance().isOperational()) return null;
if (rootPath.length() == 0 || !myWatcher.isOperational()) return null;
Application app = ApplicationManager.getApplication();
return app.runReadAction(new Computable<WatchRequest>() {
@Override
public WatchRequest compute() {
WRITE_LOCK.lock();
try {
synchronized (myLock) {
final WatchRequestImpl result = new WatchRequestImpl(rootPath, toWatchRecursively);
boolean alreadyWatched = isAlreadyWatched(result);
if (!alreadyWatched) {
@@ -355,24 +318,29 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
setUpFileWatcher();
return result;
}
finally {
WRITE_LOCK.unlock();
}
}
});
}
private boolean isAlreadyWatched(final WatchRequest request) {
for (final WatchRequest current : normalizeRootsForRefresh()) {
if (current.dominates(request)) return true;
private boolean isAlreadyWatched(final WatchRequestImpl request) {
for (final WatchRequestImpl current : normalizeRootsForRefresh()) {
if (dominates(current, request)) return true;
}
return false;
}
private static boolean dominates(final WatchRequestImpl request, final WatchRequestImpl other) {
if (request.myToWatchRecursively) {
return other.myRootPath.startsWith(request.myRootPath);
}
return !other.myToWatchRecursively && request.myRootPath.equals(other.myRootPath);
}
@Override
@NotNull
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively) {
if (!FileWatcher.getInstance().isOperational()) return Collections.emptySet();
if (!myWatcher.isOperational()) return Collections.emptySet();
final Set<WatchRequest> result = new HashSet<WatchRequest>();
final Set<VirtualFile> filesToSynchronize = new HashSet<VirtualFile>();
@@ -380,8 +348,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
Application application = ApplicationManager.getApplication();
application.runReadAction(new Runnable() {
public void run() {
WRITE_LOCK.lock();
try {
synchronized (myLock) {
for (String rootPath : rootPaths) {
LOG.assertTrue(rootPath != null);
if (rootPath.length() > 0) {
@@ -399,9 +366,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
finally {
WRITE_LOCK.unlock();
}
}
});
@@ -421,16 +385,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
WRITE_LOCK.lock();
try {
synchronized (myLock) {
if (myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
}
finally {
WRITE_LOCK.unlock();
}
}
});
}
@@ -439,16 +399,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
WRITE_LOCK.lock();
try {
synchronized (myLock) {
if (myRootsToWatch.removeAll(rootsToWatch)) {
myCachedNormalizedRequests = null;
setUpFileWatcher();
}
}
finally {
WRITE_LOCK.unlock();
}
}
});
}
@@ -195,26 +195,32 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static final boolean IS_UNDER_TEAMCITY = System.getProperty("bootstrap.testcases") != null;
private static final boolean SHOULD_PERFORM_ACCESS_CHECK = System.getenv("NO_FS_ROOTS_ACCESS_CHECK") == null;
private static final boolean IS_UNIT_TESTS = ApplicationManager.getApplication().isUnitTestMode();
private static final Collection<String> additionalRoots = new THashSet<String>();
private static final Collection<String> ourAdditionalRoots = new THashSet<String>();
@TestOnly
public static void allowToAccess(@NotNull String root) {
additionalRoots.add(FileUtil.toSystemIndependentName(root));
public static void allowRootAccess(@NotNull String... roots) {
for (String root : roots) {
ourAdditionalRoots.add(FileUtil.toSystemIndependentName(root));
}
}
@TestOnly
public static void disallowRootAccess(@NotNull String... roots) {
for (String root : roots) {
ourAdditionalRoots.remove(FileUtil.toSystemIndependentName(root));
}
}
@TestOnly
private static void assertAccessInTests(VirtualFileSystemEntry child) {
if (IS_UNIT_TESTS &&
IS_UNDER_TEAMCITY &&
ApplicationManager.getApplication() instanceof ApplicationImpl &&
((ApplicationImpl)ApplicationManager.getApplication()).isComponentsCreated() &&
SHOULD_PERFORM_ACCESS_CHECK) {
final Application application = ApplicationManager.getApplication();
if (IS_UNDER_TEAMCITY &&
SHOULD_PERFORM_ACCESS_CHECK &&
application.isUnitTestMode() &&
application instanceof ApplicationImpl &&
((ApplicationImpl)application).isComponentsCreated()) {
NewVirtualFileSystem fileSystem = child.getFileSystem();
if (fileSystem != LocalFileSystem.getInstance() && fileSystem != JarFileSystem.getInstance()) {
return;
@@ -256,25 +262,25 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
@Nullable
private static Set<String> allowedRoots() {
if (insideGettingRoots) return null;
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length == 0) return null;
final Set<String> allowed = new THashSet<String>();
String homePath = PathManager.getHomePath();
allowed.add(FileUtil.toSystemIndependentName(homePath));
allowed.add(FileUtil.toSystemIndependentName(PathManager.getHomePath()));
try {
URL outUrl = Application.class.getResource("/");
String output = new File(outUrl.toURI()).getParentFile().getParentFile().getPath();
allowed.add(FileUtil.toSystemIndependentName(output));
}
catch (URISyntaxException ignored) { }
String javaHome = SystemProperties.getJavaHome();
allowed.add(FileUtil.toSystemIndependentName(javaHome));
String tempDirectorySpecific = new File(FileUtil.getTempDirectory()).getParent();
allowed.add(FileUtil.toSystemIndependentName(tempDirectorySpecific));
String tempDirectory = System.getProperty("java.io.tmpdir");
allowed.add(FileUtil.toSystemIndependentName(tempDirectory));
String userHome = SystemProperties.getUserHome();
allowed.add(FileUtil.toSystemIndependentName(userHome));
allowed.add(FileUtil.toSystemIndependentName(SystemProperties.getJavaHome()));
allowed.add(FileUtil.toSystemIndependentName(new File(FileUtil.getTempDirectory()).getParent()));
allowed.add(FileUtil.toSystemIndependentName(System.getProperty("java.io.tmpdir")));
allowed.add(FileUtil.toSystemIndependentName(SystemProperties.getUserHome()));
for (Project project : openProjects) {
if (!project.isInitialized()) {
return null; // all is allowed
@@ -290,12 +296,8 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
allowed.add(FileUtil.toSystemIndependentName(location));
}
//for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) {
// allowed.add(FileUtil.toSystemIndependentName(sdk.getHomePath()));
//}
for (String root : additionalRoots) {
allowed.add(root);
}
allowed.addAll(ourAdditionalRoots);
return allowed;
}
@@ -303,20 +305,19 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static VirtualFile[] getAllRoots(Project project) {
insideGettingRoots = true;
Set<VirtualFile> roots = new THashSet<VirtualFile>();
final Set<VirtualFile> roots = new THashSet<VirtualFile>();
final Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries();
for (OrderEntry entry : orderEntries) {
VirtualFile[] files = entry.getFiles(OrderRootType.CLASSES);
ContainerUtil.addAll(roots, files);
files = entry.getFiles(OrderRootType.SOURCES);
ContainerUtil.addAll(roots, files);
files = entry.getFiles(OrderRootType.CLASSES_AND_OUTPUT);
ContainerUtil.addAll(roots, files);
ContainerUtil.addAll(roots, entry.getFiles(OrderRootType.CLASSES));
ContainerUtil.addAll(roots, entry.getFiles(OrderRootType.SOURCES));
ContainerUtil.addAll(roots, entry.getFiles(OrderRootType.CLASSES_AND_OUTPUT));
}
}
insideGettingRoots = false;
return VfsUtil.toVirtualFileArray(roots);
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.local;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.idea.Bombed;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
@@ -27,6 +28,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.testFramework.PlatformLangTestCase;
import com.intellij.util.Function;
import com.intellij.util.TimeoutUtil;
@@ -35,6 +37,7 @@ import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class FileWatcherTest extends PlatformLangTestCase {
@@ -104,7 +107,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(file);
delete(file);
}
}
@@ -131,7 +134,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(file);
delete(file);
}
}
@@ -159,7 +162,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(topDir);
delete(topDir);
}
}
@@ -180,7 +183,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(topDir);
delete(topDir);
}
}
@@ -201,7 +204,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(topDir);
delete(topDir);
}
}
@@ -246,7 +249,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoots(Arrays.asList(request1, request2));
FileUtil.delete(topDir);
delete(topDir);
}
}
@@ -273,8 +276,8 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(topLink);
FileUtil.delete(topDir);
delete(topLink);
delete(topDir);
}
}
@@ -302,8 +305,8 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
finally {
myFileSystem.removeWatchedRoot(request);
FileUtil.delete(linkDir);
FileUtil.delete(targetDir);
delete(linkDir);
delete(targetDir);
}
}
@@ -334,32 +337,40 @@ public class FileWatcherTest extends PlatformLangTestCase {
final int rv = new GeneralCommandLine("subst", subst + ":", targetDir.getAbsolutePath()).createProcess().waitFor();
assertEquals(0, rv);
final File substDir = new File((subst + ":\\").toUpperCase(Locale.US), subDir.getName());
final File substFile = new File(substDir, file.getName());
refresh(targetDir);
refresh(substDir);
final String substRoot = (subst + ":\\").toUpperCase(Locale.US);
VirtualDirectoryImpl.allowRootAccess(substRoot);
final LocalFileSystem.WatchRequest request = watch(substDir);
try {
FileUtil.writeToFile(file, "new content");
assertEvent(VFileContentChangeEvent.class, substFile.getAbsolutePath());
final File substDir = new File(substRoot, subDir.getName());
final File substFile = new File(substDir, file.getName());
refresh(targetDir);
refresh(substDir);
final LocalFileSystem.WatchRequest request2 = watch(targetDir);
final LocalFileSystem.WatchRequest request = watch(substDir);
try {
FileUtil.delete(file);
assertEvent(VFileDeleteEvent.class, file.getAbsolutePath(), substFile.getAbsolutePath());
FileUtil.writeToFile(file, "new content");
assertEvent(VFileContentChangeEvent.class, substFile.getAbsolutePath());
final LocalFileSystem.WatchRequest request2 = watch(targetDir);
try {
FileUtil.delete(file);
assertEvent(VFileDeleteEvent.class, file.getAbsolutePath(), substFile.getAbsolutePath());
}
finally {
unwatch(request2);
}
FileUtil.writeToFile(file, "re-creation");
assertEvent(VFileCreateEvent.class, substFile.getAbsolutePath());
}
finally {
unwatch(request2);
myFileSystem.removeWatchedRoot(request);
}
FileUtil.writeToFile(file, "re-creation");
assertEvent(VFileCreateEvent.class, substFile.getAbsolutePath());
}
finally {
myFileSystem.removeWatchedRoot(request);
VirtualDirectoryImpl.disallowRootAccess(substRoot);
delete(targetDir);
new GeneralCommandLine("subst", subst + ":", "/d").createProcess().waitFor();
FileUtil.delete(targetDir);
}
}
@@ -415,6 +426,22 @@ public class FileWatcherTest extends PlatformLangTestCase {
return vFile;
}
private void delete(@NotNull final File file) throws IOException {
final VirtualFile vFile = myFileSystem.findFileByIoFile(file);
if (vFile != null) {
final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
try {
vFile.delete(this);
}
finally {
token.finish();
}
}
if (file.exists()) {
FileUtil.delete(file);
}
}
private void assertEvent(final Class<? extends VFileEvent> type, final String... paths) throws InterruptedException {
final List<VFileEvent> events = getEvents();
assertEquals(events.toString(), paths.length, events.size());
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2012 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.vcs;
import com.intellij.openapi.Disposable;
import com.intellij.util.Alarm;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 4/11/12
* Time: 3:10 PM
*/
public class ConstantZipperUpdater {
private final ZipperUpdater myZipperUpdater;
private final Runnable myRunnable;
public ConstantZipperUpdater(final int delay, final Alarm.ThreadToUse threadToUse, final Disposable parentDisposable,
final Runnable runnable) {
myRunnable = runnable;
myZipperUpdater = new ZipperUpdater(delay, threadToUse, parentDisposable);
}
public void request() {
myZipperUpdater.queue(myRunnable);
}
}
@@ -20,12 +20,15 @@ import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectLocator;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.ConstantZipperUpdater;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.ZipperUpdater;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.util.Alarm;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.intellij.util.messages.MessageBusConnection;
@@ -34,6 +37,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -49,10 +53,45 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
private final MessageBusConnection myMessageBusConnection;
// for tests only
private boolean myForbid;
private final ConstantZipperUpdater myZipperUpdater;
private final List<FileAndDirsCollector> myQueue;
private final Object myLock;
public VcsDirtyScopeVfsListener() {
myProjectLocator = ProjectLocator.getInstance();
myMessageBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
myLock = new Object();
myQueue = new ArrayList<FileAndDirsCollector>();
myZipperUpdater = new ConstantZipperUpdater(300, Alarm.ThreadToUse.SHARED_THREAD, ApplicationManager.getApplication(),
new Runnable() {
@Override
public void run() {
ArrayList<FileAndDirsCollector> list;
synchronized (myLock) {
list = new ArrayList<FileAndDirsCollector>(myQueue);
myQueue.clear();
}
Map<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> map =
new HashMap<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>>();
for (FileAndDirsCollector collector : list) {
Map<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> pairMap =
collector.map;
for (Map.Entry<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> entry : pairMap
.entrySet()) {
final VcsDirtyScopeManager key = entry.getKey();
Pair<HashSet<FilePath>, HashSet<FilePath>> existing = map.get(key);
Pair<HashSet<FilePath>, HashSet<FilePath>> value = entry.getValue();
if (existing != null) {
existing.getFirst().addAll(value.getFirst());
existing.getSecond().addAll(value.getSecond());
} else {
map.put(key, value);
}
}
}
new FileAndDirsCollector().markDirty(map);
}
});
}
public void setForbid(boolean forbid) {
@@ -130,14 +169,10 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
}
private void markDirtyOnPooled(final FileAndDirsCollector dirtyFilesAndDirs) {
if (! dirtyFilesAndDirs.isEmpty()) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
dirtyFilesAndDirs.markDirty();
}
});
synchronized (myLock) {
myQueue.add(dirtyFilesAndDirs);
}
myZipperUpdater.request();
}
@Nullable
@@ -201,7 +236,11 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
}
void markDirty() {
for (Map.Entry<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> entry : map.entrySet()) {
markDirty(map);
}
void markDirty(final Map<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> outerMap) {
for (Map.Entry<VcsDirtyScopeManager, Pair<HashSet<FilePath>, HashSet<FilePath>>> entry : outerMap.entrySet()) {
VcsDirtyScopeManager manager = entry.getKey();
HashSet<FilePath> files = entry.getValue().first;
HashSet<FilePath> dirs = entry.getValue().second;
@@ -360,36 +360,25 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
removeMapping();
updateRootCheckers();
}
}).setAddActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
return !myIsDisabled;
}
}).setEditActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
return (!myIsDisabled) && hasSelection;
}
}).setRemoveActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
return (!myIsDisabled) && hasSelection;
}
}).disableUpDownActions().createPanel();
AnActionButton addButton = ToolbarDecorator.findAddButton(panelForTable);
assert addButton != null;
addButton.addCustomUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
return !myIsDisabled;
}
});
AnActionButton editButton = ToolbarDecorator.findEditButton(panelForTable);
assert editButton != null;
editButton.addCustomUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
return (!myIsDisabled) && hasSelection;
}
});
AnActionButton removeButton = ToolbarDecorator.findRemoveButton(panelForTable);
assert removeButton != null;
removeButton.addCustomUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
final boolean hasSelection = myDirectoryMappingTable.getSelectedObject() != null;
return (!myIsDisabled) && hasSelection;
}
});
panelForTable.setPreferredSize(new Dimension(-1, 200));
return panelForTable;
}
@@ -523,8 +512,9 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
VcsRootErrorLabel(String title) {
super(new BorderLayout(DEFAULT_HGAP, DEFAULT_VGAP));
CompoundBorder outsideBorder = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, UIUtil.getPanelBackground()),
BorderFactory.createLineBorder(UIUtil.getPanelBackground().darker()));
CompoundBorder outsideBorder =
BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, UIUtil.getPanelBackground()),
BorderFactory.createLineBorder(UIUtil.getPanelBackground().darker()));
setBorder(BorderFactory.createCompoundBorder(outsideBorder, BorderFactory.createEmptyBorder(DEFAULT_VGAP, DEFAULT_HGAP,
DEFAULT_VGAP, DEFAULT_HGAP)));
setOpaque(true);
@@ -553,5 +543,4 @@ public class VcsDirectoryConfigurationPanel extends PanelWithButtons implements
}, null);
}
}
}
@@ -36,7 +36,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class VcsManagerConfigurable extends SearchableConfigurable.Parent.Abstract implements Configurable.NoScroll {
public class VcsManagerConfigurable extends SearchableConfigurable.Parent.Abstract {
public static final Icon ICON = IconLoader.getIcon("/general/configurableVcs.png");
private final Project myProject;
private VcsDirectoryConfigurationPanel myMappings;
@@ -218,9 +218,11 @@ public class GitSSHXmlRpcClient implements GitSSHHandler {
return (String)myClient.execute(methodName("getLastSuccessful"), parameters);
}
catch (XmlRpcException e) {
log("getLastSuccessful failed. handlerNo: " + handlerNo + ", userName: " + userName + ", client: " + myClient.getURL());
throw new RuntimeException("Invocation failed " + e.getMessage(), e);
}
catch (IOException e) {
log("getLastSuccessful failed. handlerNo: " + handlerNo + ", userName: " + userName + ", client: " + myClient.getURL());
throw new RuntimeException("Invocation failed " + e.getMessage(), e);
}
}
@@ -248,4 +250,8 @@ public class GitSSHXmlRpcClient implements GitSSHHandler {
private static <T> Vector<T> adjustNull(final Vector<T> s) {
return s.size() == 0 ? null : s;
}
private static void log(String s) {
System.err.println(s);
}
}
@@ -573,5 +573,12 @@ public class SSHConfig {
private static <T> T mergeValue(T first, T second) {
return first == null ? second : first;
}
@Override
public String toString() {
return String.format("Host{myUser='%s', myHostName='%s', myPort=%d, myIdentityFile='%s'}",
myUser, myHostName, myPort, myIdentityFile);
}
}
}
@@ -191,8 +191,9 @@ public class SSHMain {
*/
private void authenticate(final Connection c) throws IOException {
LinkedList<String> methods = new LinkedList<String>(myHost.getPreferredMethods());
//log("authenticating... " + this);
String lastSuccessfulMethod = myXmlRpcClient.getLastSuccessful(myHandlerNo, getUserHostString());
System.err.println("SSH: authentication methods: " + methods + " last successful method: " + lastSuccessfulMethod);
//log("SSH: authentication methods: " + methods + " last successful method: " + lastSuccessfulMethod);
if (lastSuccessfulMethod != null && lastSuccessfulMethod.length() > 0 && methods.remove(lastSuccessfulMethod)) {
methods.addFirst(lastSuccessfulMethod);
}
@@ -588,4 +589,15 @@ public class SSHMain {
}
}
}
@Override
public String toString() {
return String
.format("SSHMain{myHost=%s, myHandlerNo=%d, myCommand='%s', myExitCode=%d, myLastError='%s'}", myHost, myHandlerNo, myCommand,
myExitCode, myLastError);
}
private static void log(String s) {
System.err.println(s);
}
}
@@ -399,7 +399,9 @@ public abstract class GitHandler {
myHandlerNo = ssh.registerHandler(new GitSSHGUIHandler(myProject));
myEnvironmentCleanedUp = false;
myEnv.put(GitSSHHandler.SSH_HANDLER_ENV, Integer.toString(myHandlerNo));
myEnv.put(GitSSHHandler.SSH_PORT_ENV, Integer.toString(ssh.getXmlRcpPort()));
int port = ssh.getXmlRcpPort();
myEnv.put(GitSSHHandler.SSH_PORT_ENV, Integer.toString(port));
LOG.debug(String.format("handler=%s, port=%s", myHandlerNo, port));
}
myCommandLine.setEnvParams(myEnv);
// start process
@@ -36,6 +36,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.xml.*;
import com.intellij.util.xml.reflect.DomCollectionChildDescription;
import org.jetbrains.annotations.NotNull;
@@ -50,10 +51,18 @@ import org.jetbrains.idea.maven.utils.MavenLog;
import org.jetbrains.idea.maven.vfs.MavenPropertiesVirtualFileSystem;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MavenDomUtil {
// see http://maven.apache.org/settings.html
private static final Set<String> SUBTAGS_IN_SETTINGS_FILE = CollectionFactory.newSet("localRepository", "interactiveMode",
"usePluginRegistry", "offline", "pluginGroups",
"servers", "mirrors", "proxies", "profiles",
"activeProfiles");
public static boolean isMavenFile(PsiFile file) {
return isProjectFile(file) || isProfilesFile(file) || isSettingsFile(file);
}
@@ -71,14 +80,36 @@ public class MavenDomUtil {
if (!(file instanceof XmlFile)) return false;
String name = file.getName();
return name.equals(MavenConstants.PROFILES_XML);
if (!name.equals(MavenConstants.PROFILES_XML)) return false;
XmlTag rootTag = ((XmlFile)file).getRootTag();
return rootTag != null && "profilesXml".equals(rootTag.getName());
}
public static boolean isSettingsFile(PsiFile file) {
if (!(file instanceof XmlFile)) return false;
String name = file.getName();
return name.equals(MavenConstants.SETTINGS_XML);
if (!name.equals(MavenConstants.SETTINGS_XML)) return false;
XmlTag rootTag = ((XmlFile)file).getRootTag();
if (rootTag == null || !"settings".equals(rootTag.getName())) return false;
String xmlns = rootTag.getAttributeValue("xmlns");
if (xmlns != null) {
return xmlns.contains("maven");
}
boolean hasTag = false;
for (PsiElement e = rootTag.getFirstChild(); e != null; e = e.getNextSibling()) {
if (e instanceof XmlTag) {
if (SUBTAGS_IN_SETTINGS_FILE.contains(((XmlTag)e).getName())) return true;
hasTag = true;
}
}
return !hasTag;
}
public static boolean isMavenFile(PsiElement element) {
@@ -145,7 +145,7 @@ public class MavenProjectReader {
return new RawModelReadResult(result, problems, alwaysOnProfiles);
}
private void readModelBody(MavenModelBase mavenModelBase, MavenBuildBase mavenBuildBase, Element xmlModel) {
private static void readModelBody(MavenModelBase mavenModelBase, MavenBuildBase mavenBuildBase, Element xmlModel) {
mavenModelBase.setModules(MavenJDOMUtil.findChildrenValuesByPath(xmlModel, "modules", "module"));
collectProperties(MavenJDOMUtil.findChildByPath(xmlModel, "properties"), mavenModelBase);
@@ -23,7 +23,9 @@ import org.jetbrains.idea.maven.utils.actions.MavenAction;
import org.jetbrains.idea.maven.utils.actions.MavenActionUtil;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ToggleProfileAction extends MavenAction {
public void update(AnActionEvent e) {
@@ -55,7 +57,7 @@ public class ToggleProfileAction extends MavenAction {
return activeCount == 0 || activeCount == selectedProfiles.size();
}
private boolean isActive(MavenProjectsManager projectsManager, List<String> profiles) {
private static boolean isActive(MavenProjectsManager projectsManager, List<String> profiles) {
return projectsManager.getExplicitProfiles().contains(profiles.get(0));
}
@@ -64,7 +66,7 @@ public class ToggleProfileAction extends MavenAction {
MavenProjectsManager manager = MavenActionUtil.getProjectsManager(e.getDataContext());
List<String> selectedProfiles = e.getData(MavenDataKeys.MAVEN_PROFILES);
Collection<String> activeProfiles = manager.getExplicitProfiles();
Set<String> activeProfiles = new HashSet<String>(manager.getExplicitProfiles());
if (isActive(manager, selectedProfiles)) {
activeProfiles.removeAll(selectedProfiles);
}
@@ -33,8 +33,6 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static com.intellij.openapi.util.text.StringUtil.isEmptyOrSpaces;
public class MavenJDOMUtil {
@Nullable
public static Element read(final VirtualFile file, @Nullable final ErrorHandler handler) {
@@ -95,7 +93,7 @@ public class MavenJDOMUtil {
public void endTag(CharSequence localName, String namespace, int startoffset, int endoffset) {
String name = localName.toString();
if (isEmptyOrSpaces(name)) return;
if (StringUtil.isEmptyOrSpaces(name)) return;
int index = -1;
for (int i = stack.size() - 1; i >= 0; i--) {
@@ -129,22 +127,27 @@ public class MavenJDOMUtil {
return result[0];
}
@Nullable
public static Element findChildByPath(@Nullable Element element, String path) {
if (element == null) return null;
int i = 0;
while (element != null) {
int dot = path.indexOf('.', i);
if (dot == -1) {
return element.getChild(path.substring(i));
}
List<String> parts = StringUtil.split(path, ".");
Element current = element;
for (String each : parts) {
current = current.getChild(each);
if (current == null) break;
element = element.getChild(path.substring(i, dot));
i = dot + 1;
}
return current;
return null;
}
public static String findChildValueByPath(@Nullable Element element, String path, String defaultValue) {
Element child = findChildByPath(element, path);
String childValue = child == null ? null : child.getTextTrim();
return StringUtil.isEmptyOrSpaces(childValue) ? defaultValue : childValue;
if (child == null) return defaultValue;
String childValue = child.getTextTrim();
return childValue.isEmpty() ? defaultValue : childValue;
}
public static String findChildValueByPath(@Nullable Element element, String path) {
@@ -163,7 +166,7 @@ public class MavenJDOMUtil {
List<String> result = new ArrayList<String>();
for (Element each : findChildrenByPath(element, path, childrenName)) {
String value = each.getTextTrim();
if (!StringUtil.isEmptyOrSpaces(value)) {
if (!value.isEmpty()) {
result.add(value);
}
}
@@ -173,13 +176,20 @@ public class MavenJDOMUtil {
private static List<Element> collectChildren(@Nullable Element container, String subPath) {
if (container == null) return Collections.emptyList();
List<String> subParts = StringUtil.split(subPath, ".");
String childName = subParts.get(0);
String pathInChild = subParts.size() > 1 ? StringUtil.join(subParts.subList(1, subParts.size()), ".") : null;
int firstDot = subPath.indexOf('.');
if (firstDot == -1) {
//noinspection unchecked
return (List<Element>)container.getChildren(subPath);
}
String childName = subPath.substring(0, firstDot);
String pathInChild = subPath.substring(firstDot + 1);
List<Element> result = new ArrayList<Element>();
//noinspection unchecked
for (Element each : (Iterable<? extends Element>)container.getChildren(childName)) {
Element child = pathInChild == null ? each : findChildByPath(each, pathInChild);
Element child = findChildByPath(each, pathInChild);
if (child != null) result.add(child);
}
return result;
@@ -101,7 +101,7 @@ public class SvnHistoryProvider
@Override
protected void updateButtons() {
}
}.initPositionAndBorder()
}.initPosition()
.addExtraAction(AnActionButton.fromAction(sourceAction))
.createPanel();
fieldPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.TOP));