From 1e535bb597f8d8e3792c011fae835857ff766010 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Sat, 9 Apr 2011 00:31:19 +0400 Subject: [PATCH 01/16] new awesome check icon --- platform/icons/src/actions/checked.png | Bin 0 -> 135 bytes .../platform-api/src/com/intellij/util/Icons.java | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 platform/icons/src/actions/checked.png diff --git a/platform/icons/src/actions/checked.png b/platform/icons/src/actions/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..366b1b532cd6ab984f9591ed3172ee1bb4659abc GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhex5FlAr-fh6C^YQc#f1eSj?H= zl&Mh1d8GEpj9Y9+Zg-X*N>(sCpsL9fI)U}bM29`y6EYPY{>XLc3qRHrn89>pedCPD i5=Z|y-0?14z|8Qlh9~cNQMNtMWCl-HKbLh*2~7YwW-R0Y literal 0 HcmV?d00001 diff --git a/platform/platform-api/src/com/intellij/util/Icons.java b/platform/platform-api/src/com/intellij/util/Icons.java index 035f2b4e28b9..a7777e5a8357 100644 --- a/platform/platform-api/src/com/intellij/util/Icons.java +++ b/platform/platform-api/src/com/intellij/util/Icons.java @@ -109,7 +109,7 @@ public abstract class Icons { public static final Icon PROPERTIES_ICON = IconLoader.getIcon("/actions/properties.png"); public static final Icon SYNCHRONIZE_ICON = IconLoader.getIcon("/actions/sync.png"); - public static final Icon CHECK_ICON = IconLoader.getIcon("/actions/check.png"); + public static final Icon CHECK_ICON = IconLoader.getIcon("/actions/checked.png"); public static final Icon OPEN_EDIT_DIALOG_ICON = IconLoader.getIcon("/actions/showViewer.png"); public static final Icon FLATTEN_PACKAGES_ICON = IconLoader.getIcon("/objectBrowser/flattenPackages.png"); From 1f0b0c4106367c5abfa231646c23ff0deec753ea Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 8 Apr 2011 22:55:56 +0200 Subject: [PATCH 02/16] Make "Mismatched query and update of collection" inspection configuration work --- .../intellij/util/containers/OrderedSet.java | 4 +- .../ig/bugs/CollectionQueryCalledVisitor.java | 20 +---- .../bugs/CollectionUpdateCalledVisitor.java | 30 ++----- ...atchedCollectionQueryUpdateInspection.java | 69 +++++--------- .../siyeh/ig/ui/ExternalizableStringSet.java | 90 +++++++++++++++++++ 5 files changed, 126 insertions(+), 87 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java diff --git a/platform/util/src/com/intellij/util/containers/OrderedSet.java b/platform/util/src/com/intellij/util/containers/OrderedSet.java index 68953584df49..5be445d00170 100644 --- a/platform/util/src/com/intellij/util/containers/OrderedSet.java +++ b/platform/util/src/com/intellij/util/containers/OrderedSet.java @@ -121,7 +121,9 @@ public class OrderedSet extends AbstractSet implements List { } public T set(final int index, final T element) { - throw new UnsupportedOperationException(); + final T removed = remove(index); + add(index, element); + return removed; } public void add(final int index, final T element) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java index 8b8a95f5a3f7..580371d7c38c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java @@ -24,26 +24,14 @@ import java.util.Set; class CollectionQueryCalledVisitor extends JavaRecursiveElementVisitor{ - /** - * @noinspection StaticCollection - */ - @NonNls private static final Set queryNames = - new HashSet(6); - static{ - queryNames.add("copyInto"); - queryNames.add("drainTo"); - queryNames.add("propertyNames"); - queryNames.add("save"); - queryNames.add("store"); - queryNames.add("write"); - } + @NonNls private final Set queryNames; private boolean queried = false; private final PsiVariable variable; - CollectionQueryCalledVisitor(PsiVariable variable){ - super(); + CollectionQueryCalledVisitor(PsiVariable variable, Set queryNames){ this.variable = variable; + this.queryNames = queryNames; } @Override public void visitElement(@NotNull PsiElement element){ @@ -139,4 +127,4 @@ class CollectionQueryCalledVisitor extends JavaRecursiveElementVisitor{ public boolean isQueried(){ return queried; } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java index e33936796755..1e2f0e229d11 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java @@ -20,39 +20,19 @@ import com.siyeh.ig.psiutils.CollectionUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; +import java.util.*; class CollectionUpdateCalledVisitor extends JavaRecursiveElementVisitor{ - /** - * @noinspection StaticCollection - */ - @NonNls private static final Set updateNames = - new HashSet(14); - static{ - updateNames.add("add"); - updateNames.add("clear"); - updateNames.add("drainTo"); - updateNames.add("insert"); - updateNames.add("load"); - updateNames.add("offer"); - updateNames.add("poll"); - updateNames.add("push"); - updateNames.add("put"); - updateNames.add("remove"); - updateNames.add("replace"); - updateNames.add("retain"); - updateNames.add("set"); - updateNames.add("take"); - } + @NonNls private final Set updateNames; private boolean updated = false; private final PsiVariable variable; - CollectionUpdateCalledVisitor(PsiVariable variable){ - super(); + CollectionUpdateCalledVisitor(PsiVariable variable, + Set updateNames){ this.variable = variable; + this.updateNames = updateNames; } @Override public void visitElement(@NotNull PsiElement element){ diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java index 369961be9c17..1e84180335f5 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java @@ -17,9 +17,7 @@ package com.siyeh.ig.bugs; import com.intellij.codeInspection.ui.ListTable; import com.intellij.codeInspection.ui.ListWrappingTableModel; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -29,29 +27,25 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.CollectionUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; +import com.siyeh.ig.ui.ExternalizableStringSet; import com.siyeh.ig.ui.UiUtils; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; -import java.util.List; public class MismatchedCollectionQueryUpdateInspection extends BaseInspection { - @NonNls public String queries = "copyInto,drainTo,propertyNames,save,store,write"; - @NonNls public String updates = "add,clear,drainTo,insert,load,offer,poll,push,put,remove,replace,retain,set,take"; + public final ExternalizableStringSet queryNames = + new ExternalizableStringSet("copyInto", "drainTo", "propertyNames", + "save", "store", "write"); + public final ExternalizableStringSet updateNames = + new ExternalizableStringSet("add", "clear", "drainTo", "insert", + "load", "offer", "poll", "push", "put", "remove", "replace", + "retain", "set", "take"); - private final List queryNames = new ArrayList(); - private final List updateNames = new ArrayList(); - - public MismatchedCollectionQueryUpdateInspection() { - parseString(queries, queryNames); - parseString(updates, updateNames); - } + public MismatchedCollectionQueryUpdateInspection() {} @Override @NotNull @@ -82,16 +76,16 @@ public class MismatchedCollectionQueryUpdateInspection @Override public JComponent createOptionsPanel() { final JPanel panel = new JPanel(new GridBagLayout()); - final ListTable table1 = new ListTable(new ListWrappingTableModel( - queryNames, - InspectionGadgetsBundle.message("query.column.name"))); + final ListTable table1 = + new ListTable(new ListWrappingTableModel(queryNames, + InspectionGadgetsBundle.message("query.column.name"))); final JScrollPane scrollPane1 = ScrollPaneFactory.createScrollPane(table1); final ActionToolbar toolbar1 = UiUtils.createAddRemoveToolbar(table1); - final ListTable table2 = new ListTable(new ListWrappingTableModel( - updateNames, - InspectionGadgetsBundle.message("update.column.name"))); + final ListTable table2 = + new ListTable(new ListWrappingTableModel(updateNames, + InspectionGadgetsBundle.message("update.column.name"))); final JScrollPane scrollPane2 = ScrollPaneFactory.createScrollPane(table2); final ActionToolbar toolbar2 = UiUtils.createAddRemoveToolbar(table2); @@ -119,20 +113,6 @@ public class MismatchedCollectionQueryUpdateInspection return panel; } - @Override - public void readSettings(Element node) throws InvalidDataException { - super.readSettings(node); - parseString(queries, queryNames); - parseString(updates, updateNames); - } - - @Override - public void writeSettings(Element node) throws WriteExternalException { - queries = formatString(queryNames); - updates = formatString(updateNames); - super.writeSettings(node); - } - @Override public boolean isEnabledByDefault(){ return true; @@ -176,7 +156,7 @@ public class MismatchedCollectionQueryUpdateInspection return true; } - private static class MismatchedCollectionQueryUpdateVisitor + private class MismatchedCollectionQueryUpdateVisitor extends BaseInspectionVisitor{ @Override public void visitField(@NotNull PsiField field){ @@ -223,7 +203,7 @@ public class MismatchedCollectionQueryUpdateInspection } } - private static boolean collectionContentsAreUpdated( + private boolean collectionContentsAreUpdated( PsiVariable variable, PsiElement context){ if(collectionUpdateCalled(variable, context)){ return true; @@ -261,7 +241,7 @@ public class MismatchedCollectionQueryUpdateInspection context); } - private static boolean collectionContentsAreQueried( + private boolean collectionContentsAreQueried( PsiVariable variable, PsiElement context){ if(collectionQueryCalled(variable, context)){ return true; @@ -288,18 +268,18 @@ public class MismatchedCollectionQueryUpdateInspection context); } - private static boolean collectionQueryCalled(PsiVariable variable, + private boolean collectionQueryCalled(PsiVariable variable, PsiElement context){ final CollectionQueryCalledVisitor visitor = - new CollectionQueryCalledVisitor(variable); + new CollectionQueryCalledVisitor(variable, queryNames); context.accept(visitor); return visitor.isQueried(); } - private static boolean collectionUpdateCalled(PsiVariable variable, + private boolean collectionUpdateCalled(PsiVariable variable, PsiElement context){ final CollectionUpdateCalledVisitor visitor = - new CollectionUpdateCalledVisitor(variable); + new CollectionUpdateCalledVisitor(variable, updateNames); context.accept(visitor); return visitor.isUpdated(); } @@ -320,7 +300,6 @@ public class MismatchedCollectionQueryUpdateInspection @NotNull private final PsiVariable variable; CollectionQueriedByAssignmentVisitor(@NotNull PsiVariable variable){ - super(); this.variable = variable; } @@ -352,4 +331,4 @@ public class MismatchedCollectionQueryUpdateInspection return mayBeQueried; } } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java new file mode 100644 index 000000000000..956ec591faed --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java @@ -0,0 +1,90 @@ +/* + * Copyright 2011 Bas Leijdekkers + * + * 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.siyeh.ig.ui; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.OrderedSet; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +@SuppressWarnings({"HardCodedStringLiteral"}) +public class ExternalizableStringSet extends OrderedSet + implements JDOMExternalizable { + + private static final String SET = "set"; + private static final String ITEM = "item"; + private static final String VALUE = "value"; + + private final String[] defaultValues; + + /** + * note: reference to defaultValues is retained by this set! + */ + public ExternalizableStringSet(@NonNls String... defaultValues) { + this.defaultValues = defaultValues; + for (String defaultValue : defaultValues) { + add(defaultValue); + } + } + + private boolean hasDefaultValues() { + if (size() != defaultValues.length) { + return false; + } + for (String defaultValue : defaultValues) { + if (!contains(defaultValue)) { + return false; + } + } + return true; + } + + public void readExternal(Element element) throws InvalidDataException { + boolean dataFound = false; + for (Element set : (List) element.getChildren(SET)) { + if (!dataFound) { + clear(); + dataFound = true; + } + for (Element item : (List) set.getChildren(ITEM)) { + add(StringUtil.unescapeXml(item.getAttributeValue(VALUE))); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + if (hasDefaultValues()) { + return; + } + final Element set = new Element(SET); + element.addContent(set); + for (String value : this) { + if (value != null) { + final Element item = new Element(ITEM); + item.setAttribute(VALUE, StringUtil.escapeXml(value)); + set.addContent(item); + } + } + } +} From 481ec612a70da421a837f982620209873bb02046 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Sat, 9 Apr 2011 15:34:41 +0400 Subject: [PATCH 03/16] api for Groovy switch statement --- ...GroovySwitchStatementWithNoDefaultInspection.java | 4 ++-- .../codeInspection/utils/ControlFlowUtils.java | 2 +- .../codeInspection/utils/EquivalenceChecker.java | 12 +----------- .../lang/psi/api/statements/clauses/GrCaseLabel.java | 2 ++ .../psi/impl/statements/clauses/GrCaseLabelImpl.java | 11 +++++++++++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovySwitchStatementWithNoDefaultInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovySwitchStatementWithNoDefaultInspection.java index 567ead0b2e71..be19c99c0a5f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovySwitchStatementWithNoDefaultInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovySwitchStatementWithNoDefaultInspection.java @@ -53,11 +53,11 @@ public class GroovySwitchStatementWithNoDefaultInspection extends BaseInspection super.visitSwitchStatement(switchStatement); final GrCaseSection[] caseSections = switchStatement.getCaseSections(); for (GrCaseSection caseSection : caseSections) { - if (caseSection.getCaseLabel().getText().startsWith("default")) { + if (caseSection.getCaseLabel().isDefault()) { return; } } registerError(switchStatement.getFirstChild()); } } -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java index eceac6bbfec4..f9e39c176471 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java @@ -116,7 +116,7 @@ public class ControlFlowUtils { } boolean hasDefaultCase = false; for (GrCaseSection clause : caseClauses) { - if (clause.getCaseLabel().getText().equals("default")) { + if (clause.getCaseLabel().isDefault()) { hasDefaultCase = true; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java index b0586cf91e20..d89bda4ebd1b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java @@ -336,7 +336,7 @@ public class EquivalenceChecker { private static boolean caseClausesAreEquivalent(GrCaseSection clause1, GrCaseSection clause2) { final GrCaseLabel label1 = clause1.getCaseLabel(); final GrCaseLabel label2 = clause2.getCaseLabel(); - if (!expressionsAreEquivalent(getExpressionForCaseLabel(label1), getExpressionForCaseLabel(label2))) { + if (!expressionsAreEquivalent(label1.getValue(), label2.getValue())) { return false; } final GrStatement[] statements1 = clause1.getStatements(); @@ -352,16 +352,6 @@ public class EquivalenceChecker { return false; } - @Nullable - private static GrExpression getExpressionForCaseLabel(GrCaseLabel label) { - for (PsiElement child : label.getChildren()) { - if (child instanceof GrExpression) { - return (GrExpression) child; - } - } - return null; - } - private static boolean blockStatementsAreEquivalent(@NotNull GrBlockStatement statement1, @NotNull GrBlockStatement statement2) { final GrOpenBlock block1 = statement1.getBlock(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseLabel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseLabel.java index d736ffb04b6a..010f8de734f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseLabel.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/clauses/GrCaseLabel.java @@ -26,4 +26,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres public interface GrCaseLabel extends GroovyPsiElement { @Nullable GrExpression getValue(); + + boolean isDefault(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseLabelImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseLabelImpl.java index 39f3c03fd548..dce2a779b838 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseLabelImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/clauses/GrCaseLabelImpl.java @@ -17,7 +17,9 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.clauses; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -44,4 +46,13 @@ public class GrCaseLabelImpl extends GroovyPsiElementImpl implements GrCaseLabel public GrExpression getValue() { return findChildByClass(GrExpression.class); } + + @Override + public boolean isDefault() { + final PsiElement firstChild = getFirstChild(); + assert firstChild != null; + final ASTNode node = firstChild.getNode(); + assert node != null; + return node.getElementType() == GroovyTokenTypes.kDEFAULT; + } } \ No newline at end of file From 8af1c09ffbe6251ea07c392325a0f7a20fc22f09 Mon Sep 17 00:00:00 2001 From: anna Date: Sat, 9 Apr 2011 17:54:03 +0200 Subject: [PATCH 04/16] introduce field: layout change --- .../InplaceIntroduceConstantPopup.java | 70 +++-- .../InplaceIntroduceFieldPopup.java | 2 +- .../IntroduceFieldCentralPanel.java | 281 ++++-------------- .../introduceField/IntroduceFieldDialog.java | 2 +- .../IntroduceFieldDialogPanel.java | 260 ++++++++++++++++ .../IntroduceFieldPopupPanel.java | 246 +++++++++++++++ .../src/messages/RefactoringBundle.properties | 2 +- 7 files changed, 603 insertions(+), 260 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java create mode 100644 java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 1d0f6672106b..368662305e90 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -44,12 +44,10 @@ import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.introduceParameter.AbstractInplaceIntroducer; import com.intellij.refactoring.move.moveMembers.MoveMembersImpl; import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; -import com.intellij.refactoring.ui.JavaVisibilityPanel; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.refactoring.util.occurences.OccurenceManager; import com.intellij.ui.StateRestoringCheckBox; import com.intellij.ui.TitlePanel; -import com.intellij.util.VisibilityUtil; import javax.swing.*; import java.awt.*; @@ -194,28 +192,41 @@ public class InplaceIntroduceConstantPopup { private JPanel createLeftPanel() { final JPanel left = new JPanel(new GridBagLayout()); - final GridBagConstraints lgc = new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,0,0), 0, 0); + myVisibilityCombo = createVisibilityCombo(left, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(6,5,0,0), 0, 0), + myProject); + myMoveToAnotherClassCb = new JCheckBox("Move to another class"); + myMoveToAnotherClassCb.setMnemonic('m'); + myMoveToAnotherClassCb.setFocusable(false); + left.add(myMoveToAnotherClassCb, new GridBagConstraints(0, 1, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + return left; + } + + public static JComboBox createVisibilityCombo(final JPanel left, + final GridBagConstraints lgc, + final Project project) { final JLabel label = new JLabel("Visibility:"); label.setDisplayedMnemonic('V'); left.add(label, lgc); - myVisibilityCombo = new JComboBox(new String[]{PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PRIVATE}); - myVisibilityCombo.setRenderer(new ListCellRendererWrapper(myVisibilityCombo.getRenderer()){ + final JComboBox visibilityCombo = new JComboBox(new String[]{PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PRIVATE}); + visibilityCombo.setRenderer(new ListCellRendererWrapper(visibilityCombo.getRenderer()) { @Override public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) { setText(PsiBundle.visibilityPresentation(value)); } }); - label.setLabelFor(myVisibilityCombo); - myVisibilityCombo.setSelectedItem(JavaRefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY); - myVisibilityCombo.addKeyListener(new KeyAdapter() { - @Override - public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - ToolWindowManager.getInstance(myProject).activateEditorComponent(); - } - } - }); + label.setLabelFor(visibilityCombo); + visibilityCombo.setSelectedItem(JavaRefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY); + + appendActions(visibilityCombo, project); + lgc.gridx++; + lgc.insets.top = 2; + lgc.insets.left = 0; + left.add(visibilityCombo, lgc); + return visibilityCombo; + } + + static void appendActions(final JComboBox visibilityCombo, final Project project) { final AnAction arrow = new AnAction() { @Override public void actionPerformed(AnActionEvent e) { @@ -223,34 +234,29 @@ public class InplaceIntroduceConstantPopup { final int code = ((KeyEvent)e.getInputEvent()).getKeyCode(); final int delta = code == KeyEvent.VK_DOWN ? 1 : code == KeyEvent.VK_UP ? -1 : 0; if (delta == 0) return; - final int size = myVisibilityCombo.getModel().getSize(); - int next = myVisibilityCombo.getSelectedIndex() + delta; + final int size = visibilityCombo.getModel().getSize(); + int next = visibilityCombo.getSelectedIndex() + delta; if (next < 0 || next >= size) { if (!UISettings.getInstance().CYCLE_SCROLLING) { return; } next = (next + size) % size; } - myVisibilityCombo.setSelectedIndex(next); + visibilityCombo.setSelectedIndex(next); } } }; arrow.registerCustomShortcutSet(new CustomShortcutSet(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), null), - new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), null)), myVisibilityCombo); - lgc.gridx = 1; - lgc.insets.top = 2; - lgc.insets.left = 0; - left.add(myVisibilityCombo, lgc); + new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), null)), visibilityCombo); - myMoveToAnotherClassCb = new JCheckBox("Move to another class"); - myMoveToAnotherClassCb.setMnemonic('m'); - myMoveToAnotherClassCb.setFocusable(false); - lgc.gridx = 0; - lgc.gridy = 1; - lgc.gridwidth = 2; - lgc.insets.top = 0; - left.add(myMoveToAnotherClassCb, lgc); - return left; + visibilityCombo.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + ToolWindowManager.getInstance(project).activateEditorComponent(); + } + } + }); } public void performInplaceIntroduce() { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index ba9e22049290..45cd42225d79 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -115,7 +115,7 @@ public class InplaceIntroduceFieldPopup { myEditor = editor; myIntroduceFieldPanel = - new IntroduceFieldCentralPanel(parentClass, initializerExpression, localVariable, currentMethodConstructor, localVariable != null, aStatic, + new IntroduceFieldPopupPanel(parentClass, initializerExpression, localVariable, currentMethodConstructor, localVariable != null, aStatic, myOccurrences.length, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager); myWholePanel = new JPanel(new GridBagLayout()); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java index e90ac626d7a3..63c3e400c22a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java @@ -17,7 +17,6 @@ package com.intellij.refactoring.introduceField; import com.intellij.codeInsight.TestUtil; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.JavaRefactoringSettings; @@ -38,34 +37,27 @@ import java.awt.event.ItemListener; * User: anna * Date: 3/16/11 */ -public class IntroduceFieldCentralPanel { - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog"); +public abstract class IntroduceFieldCentralPanel { + protected static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog"); - private static boolean ourLastCbFinalState = false; + protected static boolean ourLastCbFinalState = false; - private final PsiClass myParentClass; - private final PsiExpression myInitializerExpression; - private final PsiLocalVariable myLocalVariable; - private final boolean myIsCurrentMethodConstructor; - private final boolean myIsInvokedOnDeclaration; - private final boolean myWillBeDeclaredStatic; - private final int myOccurrencesCount; - private final boolean myAllowInitInMethod; - private final boolean myAllowInitInMethodIfAll; - private final TypeSelectorManager myTypeSelectorManager; + protected final PsiClass myParentClass; + protected final PsiExpression myInitializerExpression; + protected final PsiLocalVariable myLocalVariable; + protected final boolean myIsCurrentMethodConstructor; + protected final boolean myIsInvokedOnDeclaration; + protected final boolean myWillBeDeclaredStatic; + protected final int myOccurrencesCount; + protected final boolean myAllowInitInMethod; + protected final boolean myAllowInitInMethodIfAll; + protected final TypeSelectorManager myTypeSelectorManager; private JCheckBox myCbReplaceAll; private StateRestoringCheckBox myCbDeleteVariable; private StateRestoringCheckBox myCbFinal; - private JRadioButton myRbInConstructor; - private JRadioButton myRbInCurrentMethod; - private JRadioButton myRbInFieldDeclaration; - private JRadioButton myRbInSetUp; - - private JavaVisibilityPanel myVisibilityPanel; - public IntroduceFieldCentralPanel(PsiClass parentClass, PsiExpression initializerExpression, PsiLocalVariable localVariable, @@ -84,79 +76,22 @@ public class IntroduceFieldCentralPanel { myTypeSelectorManager = typeSelectorManager; } - void initializeControls(PsiExpression initializerExpression, BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { - if (initializerExpression != null) { - setEnabledInitializationPlaces(initializerExpression, initializerExpression); - if (!myAllowInitInMethod) { - myRbInCurrentMethod.setEnabled(false); - } - } else { - myRbInConstructor.setEnabled(false); - myRbInCurrentMethod.setEnabled(false); - myRbInFieldDeclaration.setEnabled(false); - if (myRbInSetUp != null) myRbInSetUp.setEnabled(false); - } + protected abstract boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer); + public abstract BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace(); + protected abstract void initializeInitializerPlace(PsiExpression initializerExpression, + BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace); + protected abstract JComponent createInitializerPlacePanel(ItemListener itemListener, ItemListener finalUpdater); + public abstract void setInitializeInFieldDeclaration(); - final PsiMethod setUpMethod = TestUtil.findSetUpMethod(myParentClass); - if (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) && myRbInSetUp.isEnabled() || - ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD && TestUtil.isTestClass(myParentClass) && myRbInSetUp.isEnabled()) { - myRbInSetUp.setSelected(true); - } - else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) { - if (myRbInConstructor.isEnabled()) { - myRbInConstructor.setSelected(true); - } else { - selectInCurrentMethod(); - } - } else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) { - if (myRbInFieldDeclaration.isEnabled()) { - myRbInFieldDeclaration.setSelected(true); - } else { - selectInCurrentMethod(); - } - } else { - selectInCurrentMethod(); - } - String ourLastVisibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY; - myVisibilityPanel.setVisibility(ourLastVisibility); + public abstract void setVisibility(String visibility); + public abstract String getFieldVisibility(); + public abstract void addVisibilityListener(ChangeListener changeListener); + + protected void initializeControls(PsiExpression initializerExpression, + BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { myCbFinal.setSelected(myCbFinal.isEnabled() && ourLastCbFinalState); } - private void selectInCurrentMethod() { - if (myRbInCurrentMethod.isEnabled()) { - myRbInCurrentMethod.setSelected(true); - } - else if (myRbInFieldDeclaration.isEnabled()) { - myRbInFieldDeclaration.setSelected(true); - } - else { - myRbInCurrentMethod.setSelected(true); - } - } - - - public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() { - if (myRbInConstructor.isSelected()) { - return BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR; - } - if (myRbInCurrentMethod.isSelected()) { - return BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD; - } - if (myRbInFieldDeclaration.isSelected()) { - return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION; - } - if (myRbInSetUp != null && myRbInSetUp.isSelected()) { - return BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD; - } - - LOG.assertTrue(false); - return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION; - } - - - public String getFieldVisibility() { - return myVisibilityPanel.getVisibility(); - } public boolean isReplaceAllOccurrences() { if (myIsInvokedOnDeclaration) return true; @@ -174,29 +109,12 @@ public class IntroduceFieldCentralPanel { return myCbFinal.isSelected(); } - - protected JComponent createCenterPanel() { - JPanel panel = new JPanel(new GridBagLayout()); - GridBagConstraints gbConstraints = new GridBagConstraints(); - gbConstraints.fill = GridBagConstraints.HORIZONTAL; - gbConstraints.weightx = 1; - gbConstraints.weighty = 0; - gbConstraints.gridwidth = 1; - gbConstraints.gridx = 0; - gbConstraints.gridy = 0; - final Insets standardInsets = new Insets(0, 0, 0, 0); - gbConstraints.insets = standardInsets; - panel.add(createInitializerPlacePanel(), gbConstraints); ItemListener itemListener = new ItemListener() { public void itemStateChanged(ItemEvent e) { if (myCbReplaceAll != null && myAllowInitInMethod) { - myRbInCurrentMethod.setEnabled(myAllowInitInMethodIfAll || !myCbReplaceAll.isSelected()); - if (!myRbInCurrentMethod.isEnabled() && myRbInCurrentMethod.isSelected()) { - myRbInCurrentMethod.setSelected(false); - myRbInFieldDeclaration.setSelected(true); - } + updateInitializerSelection(); } updateTypeSelector(); } @@ -206,13 +124,29 @@ public class IntroduceFieldCentralPanel { updateCbFinal(); } }; - myRbInConstructor.addItemListener(itemListener); - myRbInCurrentMethod.addItemListener(itemListener); - myRbInFieldDeclaration.addItemListener(itemListener); - myRbInConstructor.addItemListener(finalUpdater); - myRbInCurrentMethod.addItemListener(finalUpdater); - myRbInFieldDeclaration.addItemListener(finalUpdater); - if (myRbInSetUp != null) myRbInSetUp.addItemListener(finalUpdater); + final JComponent initializerPlacePanel = createInitializerPlacePanel(itemListener, finalUpdater); + final JPanel checkboxes = appendCheckboxes(itemListener); + JPanel panel = composeWholePanel(initializerPlacePanel, checkboxes); + + updateTypeSelector(); + return panel; + } + + protected abstract JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel); + + protected void updateInitializerSelection() { + } + + private JPanel appendCheckboxes(ItemListener itemListener) { + GridBagConstraints gbConstraints = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1,1,0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); + JPanel panel = new JPanel(new GridBagLayout()); + myCbFinal = new StateRestoringCheckBox(); + myCbFinal.setFocusable(false); + myCbFinal.setText(RefactoringBundle.message("declare.final")); + myCbFinal.addItemListener(itemListener); + gbConstraints.gridy++; + panel.add(myCbFinal, gbConstraints); + if (myOccurrencesCount > 1) { myCbReplaceAll = new NonFocusableCheckBox(); myCbReplaceAll.setText(RefactoringBundle.message("replace.all.occurrences.of.expression.0.occurrences", myOccurrencesCount)); @@ -246,20 +180,7 @@ public class IntroduceFieldCentralPanel { } ); } - gbConstraints.insets = standardInsets; } - myCbFinal.addItemListener(itemListener); -// myCbStatic.addItemListener(itemListener); -// myCbStatic.addItemListener(finalUpdater); -// myCbStatic.addItemListener( -// new ItemListener() { -// public void itemStateChanged(ItemEvent e) { -// updateNameList(); -// } -// } -// ); - - updateTypeSelector(); return panel; } @@ -279,101 +200,15 @@ public class IntroduceFieldCentralPanel { } } - private JComponent createInitializerPlacePanel() { - JPanel mainPanel = new JPanel(); - mainPanel.setLayout(new BorderLayout()); - - JPanel initializationPanel = new JPanel(); - initializationPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("initialize.in.border.title"))); - initializationPanel.setLayout(new BoxLayout(initializationPanel, BoxLayout.Y_AXIS)); - - - myRbInCurrentMethod = new JRadioButton(); - myRbInCurrentMethod.setFocusable(false); - myRbInCurrentMethod.setText(RefactoringBundle.message("current.method.radio")); - myRbInCurrentMethod.setEnabled(myAllowInitInMethod); - - myRbInFieldDeclaration = new JRadioButton(); - myRbInFieldDeclaration.setFocusable(false); - myRbInFieldDeclaration.setText(RefactoringBundle.message("field.declaration.radio")); - - myRbInConstructor = new JRadioButton(); - myRbInConstructor.setFocusable(false); - myRbInConstructor.setText(RefactoringBundle.message("class.constructors.radio")); - - myVisibilityPanel = new JavaVisibilityPanel(false, false); - - myCbFinal = new StateRestoringCheckBox(); - myCbFinal.setFocusable(false); - myCbFinal.setText(RefactoringBundle.message("declare.final")); - - initializationPanel.add(myRbInCurrentMethod); - initializationPanel.add(myRbInFieldDeclaration); - initializationPanel.add(myRbInConstructor); - - if (TestUtil.isTestClass(myParentClass)) { - myRbInSetUp = new JRadioButton(); - myRbInSetUp.setFocusable(false); - myRbInSetUp.setText(RefactoringBundle.message("setup.method.radio")); - initializationPanel.add(myRbInSetUp); - } - - ButtonGroup bg = new ButtonGroup(); - bg.add(myRbInCurrentMethod); - bg.add(myRbInFieldDeclaration); - bg.add(myRbInConstructor); - if (myRbInSetUp != null) bg.add(myRbInSetUp); - - - -// modifiersPanel.add(myCbFinal); -// modifiersPanel.add(myCbStatic); - - JPanel groupPanel = new JPanel(new GridLayout(1, 2)); - groupPanel.add(initializationPanel); - groupPanel.add(myVisibilityPanel); - mainPanel.add(groupPanel, BorderLayout.CENTER); - mainPanel.add(myCbFinal, BorderLayout.SOUTH); - - return mainPanel; - } - private void updateCbFinal() { - boolean allowFinal = myRbInFieldDeclaration.isSelected() || (myRbInConstructor.isSelected() && !myWillBeDeclaredStatic); - if (myRbInCurrentMethod.isSelected() && myIsCurrentMethodConstructor) { - final PsiMethod[] constructors = myParentClass.getConstructors(); - allowFinal = constructors.length <= 1; - } - if (!allowFinal) { + if (!allowFinal()) { myCbFinal.makeUnselectable(false); } else { myCbFinal.makeSelectable(); } } - - - - private boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { - if (initializerPart instanceof PsiReferenceExpression) { - PsiReferenceExpression refExpr = (PsiReferenceExpression) initializerPart; - if (refExpr.getQualifierExpression() == null) { - PsiElement refElement = refExpr.resolve(); - if (refElement == null || - (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) && - !PsiTreeUtil.isAncestor(initializer, refElement, true)) { - myRbInFieldDeclaration.setEnabled(false); - myRbInConstructor.setEnabled(false); - if (myRbInSetUp != null) myRbInSetUp.setEnabled(false); - myCbFinal.setEnabled(false); - return false; - } - } - } - PsiElement[] children = initializerPart.getChildren(); - for (PsiElement child : children) { - if (!setEnabledInitializationPlaces(child, initializer)) return false; - } + protected boolean allowFinal() { return true; } @@ -383,10 +218,6 @@ public class IntroduceFieldCentralPanel { } } - public void addVisibilityListener(ChangeListener changeListener) { - myVisibilityPanel.addListener(changeListener); - } - public void addFinalListener(ItemListener itemListener) { myCbFinal.addItemListener(itemListener); } @@ -401,11 +232,11 @@ public class IntroduceFieldCentralPanel { myCbFinal.setSelected(createFinal); } - public void setInitializeInFieldDeclaration() { - myRbInFieldDeclaration.setSelected(true); + protected void enableFinal(boolean enable){ + myCbFinal.setEnabled(enable); } - public void setVisibility(String visibility) { - myVisibilityPanel.setVisibility(visibility); - } + + + } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java index e81d94a2aefe..8d5d0a5c7324 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java @@ -68,7 +68,7 @@ class IntroduceFieldDialog extends DialogWrapper { myParentClass = parentClass; myInitializerExpression = initializerExpression; myCentralPanel = - new IntroduceFieldCentralPanel(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration, + new IntroduceFieldDialogPanel(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration, willBeDeclaredStatic, occurrencesCount, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager); myLocalVariable = localVariable; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java new file mode 100644 index 000000000000..016238f3ad40 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialogPanel.java @@ -0,0 +1,260 @@ +/* + * Copyright 2000-2011 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.refactoring.introduceField; + +import com.intellij.codeInsight.TestUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.ui.JavaVisibilityPanel; +import com.intellij.refactoring.ui.TypeSelectorManager; +import com.intellij.ui.IdeBorderFactory; + +import javax.swing.*; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.ItemListener; + +/** + * User: anna + * Date: 4/8/11 + */ +public class IntroduceFieldDialogPanel extends IntroduceFieldCentralPanel { + private JRadioButton myRbInConstructor; + private JRadioButton myRbInCurrentMethod; + private JRadioButton myRbInFieldDeclaration; + private JRadioButton myRbInSetUp; + private JavaVisibilityPanel myVisibilityPanel; + + public IntroduceFieldDialogPanel(PsiClass parentClass, + PsiExpression initializerExpression, + PsiLocalVariable localVariable, + boolean isCurrentMethodConstructor, + boolean isInvokedOnDeclaration, + boolean willBeDeclaredStatic, + int occurrencesCount, + boolean allowInitInMethod, + boolean allowInitInMethodIfAll, + TypeSelectorManager typeSelectorManager) { + super(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration, willBeDeclaredStatic, + occurrencesCount, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager); + } + + protected void initializeControls(PsiExpression initializerExpression, BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { + super.initializeControls(initializerExpression, ourLastInitializerPlace); + initializeInitializerPlace(initializerExpression, ourLastInitializerPlace); + String ourLastVisibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY; + myVisibilityPanel.setVisibility(ourLastVisibility); + } + + protected void initializeInitializerPlace(PsiExpression initializerExpression, + BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { + if (initializerExpression != null) { + setEnabledInitializationPlaces(initializerExpression, initializerExpression); + if (!myAllowInitInMethod) { + myRbInCurrentMethod.setEnabled(false); + } + } else { + myRbInConstructor.setEnabled(false); + myRbInCurrentMethod.setEnabled(false); + myRbInFieldDeclaration.setEnabled(false); + if (myRbInSetUp != null) myRbInSetUp.setEnabled(false); + } + + final PsiMethod setUpMethod = TestUtil.findSetUpMethod(myParentClass); + if (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) && myRbInSetUp.isEnabled() || + ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD && TestUtil.isTestClass(myParentClass) && myRbInSetUp.isEnabled()) { + myRbInSetUp.setSelected(true); + } + else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) { + if (myRbInConstructor.isEnabled()) { + myRbInConstructor.setSelected(true); + } else { + selectInCurrentMethod(); + } + } else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) { + if (myRbInFieldDeclaration.isEnabled()) { + myRbInFieldDeclaration.setSelected(true); + } else { + selectInCurrentMethod(); + } + } else { + selectInCurrentMethod(); + } + } + + private void selectInCurrentMethod() { + if (myRbInCurrentMethod.isEnabled()) { + myRbInCurrentMethod.setSelected(true); + } + else if (myRbInFieldDeclaration.isEnabled()) { + myRbInFieldDeclaration.setSelected(true); + } + else { + myRbInCurrentMethod.setSelected(true); + } + } + + public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() { + if (myRbInConstructor.isSelected()) { + return BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR; + } + if (myRbInCurrentMethod.isSelected()) { + return BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD; + } + if (myRbInFieldDeclaration.isSelected()) { + return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION; + } + if (myRbInSetUp != null && myRbInSetUp.isSelected()) { + return BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD; + } + + LOG.assertTrue(false); + return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION; + } + + public String getFieldVisibility() { + return myVisibilityPanel.getVisibility(); + } + + protected JComponent createInitializerPlacePanel(ItemListener itemListener, ItemListener finalUpdater) { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + + JPanel initializationPanel = new JPanel(); + initializationPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("initialize.in.border.title"))); + initializationPanel.setLayout(new BoxLayout(initializationPanel, BoxLayout.Y_AXIS)); + + + myRbInCurrentMethod = new JRadioButton(); + myRbInCurrentMethod.setFocusable(false); + myRbInCurrentMethod.setText(RefactoringBundle.message("current.method.radio")); + myRbInCurrentMethod.setEnabled(myAllowInitInMethod); + + myRbInFieldDeclaration = new JRadioButton(); + myRbInFieldDeclaration.setFocusable(false); + myRbInFieldDeclaration.setText(RefactoringBundle.message("field.declaration.radio")); + + myRbInConstructor = new JRadioButton(); + myRbInConstructor.setFocusable(false); + myRbInConstructor.setText(RefactoringBundle.message("class.constructors.radio")); + + + + initializationPanel.add(myRbInCurrentMethod); + initializationPanel.add(myRbInFieldDeclaration); + initializationPanel.add(myRbInConstructor); + + if (TestUtil.isTestClass(myParentClass)) { + myRbInSetUp = new JRadioButton(); + myRbInSetUp.setFocusable(false); + myRbInSetUp.setText(RefactoringBundle.message("setup.method.radio")); + initializationPanel.add(myRbInSetUp); + } + + ButtonGroup bg = new ButtonGroup(); + bg.add(myRbInCurrentMethod); + bg.add(myRbInFieldDeclaration); + bg.add(myRbInConstructor); + if (myRbInSetUp != null) bg.add(myRbInSetUp); + + myRbInConstructor.addItemListener(itemListener); + myRbInCurrentMethod.addItemListener(itemListener); + myRbInFieldDeclaration.addItemListener(itemListener); + myRbInConstructor.addItemListener(finalUpdater); + myRbInCurrentMethod.addItemListener(finalUpdater); + myRbInFieldDeclaration.addItemListener(finalUpdater); + if (myRbInSetUp != null) myRbInSetUp.addItemListener(finalUpdater); + +// modifiersPanel.add(myCbFinal); +// modifiersPanel.add(myCbStatic); + + JPanel groupPanel = new JPanel(new GridLayout(1, 2)); + groupPanel.add(initializationPanel); + + myVisibilityPanel = new JavaVisibilityPanel(false, false); + groupPanel.add(myVisibilityPanel); + + mainPanel.add(groupPanel, BorderLayout.CENTER); + + return mainPanel; + } + + protected boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { + if (initializerPart instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression) initializerPart; + if (refExpr.getQualifierExpression() == null) { + PsiElement refElement = refExpr.resolve(); + if (refElement == null || + (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) && + !PsiTreeUtil.isAncestor(initializer, refElement, true)) { + myRbInFieldDeclaration.setEnabled(false); + myRbInConstructor.setEnabled(false); + if (myRbInSetUp != null) myRbInSetUp.setEnabled(false); + enableFinal(false); + return false; + } + } + } + PsiElement[] children = initializerPart.getChildren(); + for (PsiElement child : children) { + if (!setEnabledInitializationPlaces(child, initializer)) return false; + } + return true; + } + + public void addVisibilityListener(ChangeListener changeListener) { + myVisibilityPanel.addListener(changeListener); + } + + public void setInitializeInFieldDeclaration() { + myRbInFieldDeclaration.setSelected(true); + } + + public void setVisibility(String visibility) { + myVisibilityPanel.setVisibility(visibility); + } + + @Override + protected boolean allowFinal() { + boolean allowFinal = myRbInFieldDeclaration.isSelected() || (myRbInConstructor.isSelected() && !myWillBeDeclaredStatic); + if (myRbInCurrentMethod.isSelected() && myIsCurrentMethodConstructor) { + final PsiMethod[] constructors = myParentClass.getConstructors(); + allowFinal = constructors.length <= 1; + } + return allowFinal; + } + + @Override + protected void updateInitializerSelection() { + myRbInCurrentMethod.setEnabled(myAllowInitInMethodIfAll || !isReplaceAllOccurrences()); + if (!myRbInCurrentMethod.isEnabled() && myRbInCurrentMethod.isSelected()) { + myRbInCurrentMethod.setSelected(false); + myRbInFieldDeclaration.setSelected(true); + } + } + + protected JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel) { + JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints constraints = + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0); + panel.add(initializerPlacePanel, constraints); + panel.add(checkboxPanel, constraints); + return panel; + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java new file mode 100644 index 000000000000..7459de29e621 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java @@ -0,0 +1,246 @@ +/* + * Copyright 2000-2011 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.refactoring.introduceField; + +import com.intellij.codeInsight.TestUtil; +import com.intellij.ide.ui.ListCellRendererWrapper; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.ui.TypeSelectorManager; + +import javax.swing.*; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.*; + +/** + * User: anna + * Date: 4/8/11 + */ +public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel { + private JComboBox myInitializerCombo; + private JComboBox myVisibilityCombo; + private DefaultComboBoxModel myInitialisersPlaceModel; + + public IntroduceFieldPopupPanel(PsiClass parentClass, + PsiExpression initializerExpression, + PsiLocalVariable localVariable, + boolean isCurrentMethodConstructor, + boolean isInvokedOnDeclaration, + boolean willBeDeclaredStatic, + int occurrencesCount, + boolean allowInitInMethod, + boolean allowInitInMethodIfAll, + TypeSelectorManager typeSelectorManager) { + super(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration, willBeDeclaredStatic, + occurrencesCount, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager); + } + + protected void initializeControls(PsiExpression initializerExpression, BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { + super.initializeControls(initializerExpression, ourLastInitializerPlace); + initializeInitializerPlace(initializerExpression, ourLastInitializerPlace); + String ourLastVisibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY; + setVisibility(ourLastVisibility); + } + + protected void initializeInitializerPlace(PsiExpression initializerExpression, + BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace) { + if (initializerExpression != null) { + setEnabledInitializationPlaces(initializerExpression, initializerExpression); + if (!myAllowInitInMethod) { + myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); + } + } else { + myInitialisersPlaceModel.removeAllElements(); + } + + final PsiMethod setUpMethod = TestUtil.findSetUpMethod(myParentClass); + final boolean setupEnabled = myInitialisersPlaceModel.getIndexOf(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD) > -1; + if (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) && setupEnabled || + ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD && TestUtil.isTestClass(myParentClass) && + setupEnabled) { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); + } + else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) { + if (myInitialisersPlaceModel.getIndexOf(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) > -1) { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); + } else { + selectInCurrentMethod(); + } + } else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) { + if (myInitialisersPlaceModel.getIndexOf(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) > -1) { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); + } else { + selectInCurrentMethod(); + } + } else { + selectInCurrentMethod(); + } + } + + private void selectInCurrentMethod() { + if (myInitialisersPlaceModel.getIndexOf(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD) > -1) { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); + } + else if (myInitialisersPlaceModel.getIndexOf(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) > -1) { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); + } + else { + myInitialisersPlaceModel.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); + } + } + + public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() { + return (BaseExpressionToFieldHandler.InitializationPlace)myInitializerCombo.getSelectedItem(); + } + + public String getFieldVisibility() { + return (String)myVisibilityCombo.getSelectedItem(); + } + + protected JComponent createInitializerPlacePanel(final ItemListener itemListener, final ItemListener finalUpdater) { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + + JPanel groupPanel = new JPanel(new GridBagLayout()); + final GridBagConstraints gridBagConstraints = + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(0, 5, 0, 0), 0, 0); + gridBagConstraints.insets.top = 5; + final JLabel initLabel = new JLabel(RefactoringBundle.message("initialize.in.border.title") + ":"); + initLabel.setDisplayedMnemonic('i'); + groupPanel.add(initLabel, gridBagConstraints); + + myInitialisersPlaceModel = new DefaultComboBoxModel(); + myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); + myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); + myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); + if (TestUtil.isTestClass(myParentClass)) { + myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); + } + myInitializerCombo = new JComboBox(myInitialisersPlaceModel); + InplaceIntroduceConstantPopup.appendActions(myInitializerCombo, myParentClass.getProject()); + initLabel.setLabelFor(myInitializerCombo); + myInitializerCombo.setRenderer(new ListCellRendererWrapper(myInitializerCombo) { + @Override + public void customize(JList list, + BaseExpressionToFieldHandler.InitializationPlace value, + int index, + boolean selected, + boolean hasFocus) { + if (value == BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD) { + setText("current method"); + } else if (value == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) { + setText("constructor"); + } else if (value == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) { + setText("field declaration"); + } else { + setText("setUp"); + } + } + }); + myInitializerCombo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + itemListener.itemStateChanged(null); + finalUpdater.itemStateChanged(null); + } + }); + gridBagConstraints.gridx = 1; + gridBagConstraints.insets.top = 0; + gridBagConstraints.insets.left = 0; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + groupPanel.add(myInitializerCombo, gridBagConstraints); + + + + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.insets.top = 8; + gridBagConstraints.insets.left = 5; + myVisibilityCombo = InplaceIntroduceConstantPopup.createVisibilityCombo(groupPanel, gridBagConstraints, myParentClass.getProject()); + + mainPanel.add(groupPanel, BorderLayout.CENTER); + + return mainPanel; + } + + protected boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) { + if (initializerPart instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression) initializerPart; + if (refExpr.getQualifierExpression() == null) { + PsiElement refElement = refExpr.resolve(); + if (refElement == null || + (refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) && + !PsiTreeUtil.isAncestor(initializer, refElement, true)) { + myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); + myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); + myInitialisersPlaceModel.removeElement(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); + enableFinal(false); + return false; + } + } + } + PsiElement[] children = initializerPart.getChildren(); + for (PsiElement child : children) { + if (!setEnabledInitializationPlaces(child, initializer)) return false; + } + return true; + } + + public void addVisibilityListener(final ChangeListener changeListener) { + myVisibilityCombo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changeListener.stateChanged(null); + } + }); + } + + public void setInitializeInFieldDeclaration() { + myInitializerCombo.setSelectedItem(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); + } + + public void setVisibility(String visibility) { + myVisibilityCombo.setSelectedItem(visibility); + } + + @Override + protected boolean allowFinal() { + final Object selectedItem = myInitializerCombo.getSelectedItem(); + boolean allowFinal = selectedItem == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION || + (selectedItem == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR && !myWillBeDeclaredStatic); + if (selectedItem == BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD && myIsCurrentMethodConstructor) { + final PsiMethod[] constructors = myParentClass.getConstructors(); + allowFinal = constructors.length <= 1; + } + return allowFinal; + } + + protected JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel) { + final JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints constraints = + new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0); + constraints.insets.bottom = 5; + panel.add(initializerPlacePanel, constraints); + constraints.insets.left = 5; + panel.add(checkboxPanel, constraints); + return panel; + } +} diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index c9a937f99952..987dc8a60bd5 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -368,7 +368,7 @@ replace.all.occurences.checkbox=Replace &all occurrences introduce.constant.introduce.to.class=Introduce to class (fully qualified name): introduce.field.static.field.of.type=Static field of &type: introduce.field.field.of.type=Field of &type: -replace.all.occurrences.of.expression.0.occurrences=Replace &all occurrences of expression ({0} occurrences) +replace.all.occurrences.of.expression.0.occurrences=Replace &all occurrences ({0}) delete.variable.declaration=&Delete variable declaration initialize.in.border.title=Initialize in setup.method.radio=&setUp method From a59b9771d114f2427abd68f3423c7f65566505bb Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 4 Apr 2011 20:58:03 +0200 Subject: [PATCH 05/16] fix memleak in tests --- .../openapi/vfs/impl/local/LocalFileSystemImpl.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index dfdb178a1204..ccb9d2e0bb96 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -144,12 +144,13 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } } - // grand VFS refresh significantly slows down local tests and generally not needed - //ApplicationManager.getApplication().runWriteAction(new Runnable() { - // public void run() { - // refresh(false); - // } - //}); + // IMPORTANT! VFS refresh is a MUST here, because otherwise VirlualFile objects will be leaked in the + // components listening to VFS and relying on VFS contract + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + refresh(false); + } + }); myRootsToWatch.clear(); From f2945934774e46329fa89d1a2c7356d470f28e78 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 4 Apr 2011 22:47:09 +0200 Subject: [PATCH 06/16] change rollback --- .../openapi/vfs/impl/local/LocalFileSystemImpl.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index ccb9d2e0bb96..dfdb178a1204 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -144,13 +144,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } } - // IMPORTANT! VFS refresh is a MUST here, because otherwise VirlualFile objects will be leaked in the - // components listening to VFS and relying on VFS contract - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - refresh(false); - } - }); + // grand VFS refresh significantly slows down local tests and generally not needed + //ApplicationManager.getApplication().runWriteAction(new Runnable() { + // public void run() { + // refresh(false); + // } + //}); myRootsToWatch.clear(); From f30ae93906ecbc39633a8c041e77348010e317c0 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 5 Apr 2011 15:40:16 +0200 Subject: [PATCH 07/16] additional disposed checks --- .../com/intellij/openapi/project/DumbServiceImpl.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index 2a0a0ad62cb6..0fab1c658353 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -198,7 +198,9 @@ public class DumbServiceImpl extends DumbService { private void updateFinished() { myDumb = false; - myPublisher.exitDumbMode(); + if (!myProject.isDisposed()) { + myPublisher.exitDumbMode(); + } while (true) { final Runnable runnable; synchronized (myRunWhenSmartQueue) { @@ -207,10 +209,9 @@ public class DumbServiceImpl extends DumbService { } runnable = myRunWhenSmartQueue.pullFirst(); } - if (myProject.isDisposed()) { - return; + if (!myProject.isDisposed()) { + runnable.run(); } - runnable.run(); } } From b63986dce8a5c49dd6031cd066f3746074438d80 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 8 Apr 2011 17:13:39 +0200 Subject: [PATCH 08/16] non-VFS based FileTemplatesManager --- .../intellij/compiler/impl/CompileDriver.java | 2 +- .../impl/TranslatingCompilerFilesMonitor.java | 6 +- .../JavaCreateFromTemplateHandler.java | 4 +- .../ide/fileTemplates/FileTemplatesTest.java | 2 +- .../DefaultCreateFromTemplateHandler.java | 2 +- .../ide/fileTemplates/FileTemplate.java | 38 +- .../fileTemplates/FileTemplateManager.java | 60 +- .../ide/fileTemplates/FileTemplateUtil.java | 21 +- .../actions/CreateFromTemplateGroup.java | 5 +- .../impl/AllFileTemplatesConfigurable.java | 287 ++--- .../impl/BundledFileTemplate.java | 95 ++ .../impl/CustomFileTemplate.java | 63 + .../fileTemplates/impl/DefaultTemplate.java | 91 ++ .../impl/DeletedTemplatesManager.java | 42 + .../ide/fileTemplates/impl/FTManager.java | 321 +++++ .../fileTemplates/impl/FileTemplateBase.java | 107 ++ .../impl/FileTemplateConfigurable.java | 26 +- .../fileTemplates/impl/FileTemplateImpl.java | 399 ------ .../impl/FileTemplateManagerImpl.java | 1123 ++++++----------- .../fileTemplates/impl/FileTemplateTab.java | 21 +- .../impl/FileTemplateTabAsList.java | 18 +- .../impl/FileTemplateTabAsTree.java | 34 +- .../ide/fileTemplates/impl/UrlUtil.java | 120 ++ .../ui/CreateFromTemplateDialog.java | 5 +- .../src/messages/IdeBundle.properties | 6 - .../refactoring/move/GroovyMoveClassTest.java | 8 +- .../uiDesigner/actions/CreateFormAction.java | 2 +- 27 files changed, 1465 insertions(+), 1443 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/CustomFileTemplate.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DefaultTemplate.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DeletedTemplatesManager.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java delete mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 0b802cb3a9bc..e884f85dbfd8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -447,7 +447,7 @@ public class CompileDriver { if (message != null) { compileContext.addMessage(message); } - TranslatingCompilerFilesMonitor.getInstance().ensureInitializationCompleted(myProject); + TranslatingCompilerFilesMonitor.getInstance().ensureInitializationCompleted(myProject, compileContext.getProgressIndicator()); doCompile(compileContext, isRebuild, forceCompile, callback, checkCachesVersion); } finally { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index 3c89b1273640..9742ca6a98f0 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -965,16 +965,16 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } } - public void ensureInitializationCompleted(Project project) { + public void ensureInitializationCompleted(Project project, ProgressIndicator indicator) { final int id = getProjectId(project); synchronized (myInitializationLock) { while (myInitInProgress.contains(id)) { - if (!project.isOpen() || project.isDisposed()) { + if (!project.isOpen() || project.isDisposed() || (indicator != null && indicator.isCanceled())) { // makes no sense to continue waiting break; } try { - myInitializationLock.wait(); + myInitializationLock.wait(500); } catch (InterruptedException ignored) { break; diff --git a/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java b/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java index 42f2ac443362..b6034b3bb5b4 100644 --- a/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java +++ b/java/java-impl/src/com/intellij/ide/fileTemplates/JavaCreateFromTemplateHandler.java @@ -85,7 +85,7 @@ public class JavaCreateFromTemplateHandler implements CreateFromTemplateHandler } static void hackAwayEmptyPackage(PsiJavaFile file, FileTemplate template, Properties props) throws IncorrectOperationException { - if (!template.isJavaClassTemplate()) return; + if (!template.isTemplateOfType(StdFileTypes.JAVA)) return; String packageName = props.getProperty(FileTemplate.ATTRIBUTE_PACKAGE_NAME); if(packageName == null || packageName.length() == 0 || packageName.equals(FileTemplate.ATTRIBUTE_PACKAGE_NAME)){ @@ -104,7 +104,7 @@ public class JavaCreateFromTemplateHandler implements CreateFromTemplateHandler public PsiElement createFromTemplate(final Project project, final PsiDirectory directory, final String fileName, FileTemplate template, String templateText, Properties props) throws IncorrectOperationException { String extension = template.getExtension(); - PsiElement result = createClassOrInterface(project, directory, templateText, template.isAdjust(), extension); + PsiElement result = createClassOrInterface(project, directory, templateText, template.isReformatCode(), extension); hackAwayEmptyPackage((PsiJavaFile)result.getContainingFile(), template, props); return result; } diff --git a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.java b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.java index 5b1e1bf36b70..567864cb042d 100644 --- a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.java +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.java @@ -104,7 +104,7 @@ public class FileTemplatesTest extends IdeaTestCase { } finally { FileTemplateManager.getInstance().saveAll(); - FileTemplateManager.getInstance().removeTemplate(template, false); + FileTemplateManager.getInstance().removeTemplate(template); } } } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/DefaultCreateFromTemplateHandler.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/DefaultCreateFromTemplateHandler.java index 3f36b3eb30ab..9b3017c73407 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/DefaultCreateFromTemplateHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/DefaultCreateFromTemplateHandler.java @@ -42,7 +42,7 @@ public class DefaultCreateFromTemplateHandler implements CreateFromTemplateHandl directory.checkCreateFile(fileName); PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(fileName, templateText); - if (template.isAdjust()) { + if (template.isReformatCode()) { CodeStyleManager.getInstance(project).reformat(file); } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplate.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplate.java index 130e9b28fb25..7f719fa7a666 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplate.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplate.java @@ -16,6 +16,7 @@ package com.intellij.ide.fileTemplates; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.vfs.CharsetToolkit; import org.apache.velocity.runtime.parser.ParseException; import org.jetbrains.annotations.NonNls; @@ -29,21 +30,23 @@ import java.util.Properties; * @author MYakovlev * Date: Jul 24, 2002 */ -public interface FileTemplate{ - @NonNls String ATTRIBUTE_EXCEPTION = "EXCEPTION"; - @NonNls String ATTRIBUTE_DESCRIPTION = "DESCRIPTION"; - @NonNls String ATTRIBUTE_DISPLAY_NAME = "DISPLAY_NAME"; +public interface FileTemplate extends Cloneable { + FileTemplate[] EMPTY_ARRAY = new FileTemplate[0]; + + String ATTRIBUTE_EXCEPTION = "EXCEPTION"; + String ATTRIBUTE_DESCRIPTION = "DESCRIPTION"; + String ATTRIBUTE_DISPLAY_NAME = "DISPLAY_NAME"; - @NonNls String ATTRIBUTE_RETURN_TYPE = "RETURN_TYPE"; - @NonNls String ATTRIBUTE_DEFAULT_RETURN_VALUE = "DEFAULT_RETURN_VALUE"; - @NonNls String ATTRIBUTE_CALL_SUPER = "CALL_SUPER"; + String ATTRIBUTE_RETURN_TYPE = "RETURN_TYPE"; + String ATTRIBUTE_DEFAULT_RETURN_VALUE = "DEFAULT_RETURN_VALUE"; + String ATTRIBUTE_CALL_SUPER = "CALL_SUPER"; - @NonNls String ourEncoding = CharsetToolkit.UTF8; - @NonNls String ATTRIBUTE_CLASS_NAME = "CLASS_NAME"; - @NonNls String ATTRIBUTE_SIMPLE_CLASS_NAME = "SIMPLE_CLASS_NAME"; - @NonNls String ATTRIBUTE_METHOD_NAME = "METHOD_NAME"; - @NonNls String ATTRIBUTE_PACKAGE_NAME = "PACKAGE_NAME"; - @NonNls String ATTRIBUTE_NAME = "NAME"; + String ourEncoding = CharsetToolkit.UTF8; + String ATTRIBUTE_CLASS_NAME = "CLASS_NAME"; + String ATTRIBUTE_SIMPLE_CLASS_NAME = "SIMPLE_CLASS_NAME"; + String ATTRIBUTE_METHOD_NAME = "METHOD_NAME"; + String ATTRIBUTE_PACKAGE_NAME = "PACKAGE_NAME"; + String ATTRIBUTE_NAME = "NAME"; @NotNull String[] getUnsetAttributes(@NotNull Properties properties) throws ParseException; @@ -51,7 +54,7 @@ public interface FileTemplate{ void setName(@NotNull String name); - boolean isJavaClassTemplate(); + boolean isTemplateOfType(final FileType fType); boolean isDefault(); @@ -73,10 +76,9 @@ public interface FileTemplate{ void setExtension(@NotNull String extension); - boolean isAdjust(); + boolean isReformatCode(); - void setAdjust(boolean adjust); - - boolean isInternal(); + void setReformatCode(boolean reformat); + FileTemplate clone(); } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java index fc24a623eba3..386e5423546a 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java @@ -20,6 +20,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; import java.util.Collection; import java.util.Properties; @@ -32,56 +33,68 @@ public abstract class FileTemplateManager{ public static final Key DEFAULT_TEMPLATE_PROPERTIES = Key.create("DEFAULT_TEMPLATE_PROPERTIES"); public static final int RECENT_TEMPLATES_SIZE = 25; - @NonNls public static final String INTERNAL_HTML_TEMPLATE_NAME = "Html"; - @NonNls public static final String INTERNAL_HTML5_TEMPLATE_NAME = "Html5"; - @NonNls public static final String INTERNAL_XHTML_TEMPLATE_NAME = "Xhtml"; - @NonNls public static final String FILE_HEADER_TEMPLATE_NAME = "File Header"; + @NonNls + public static final String INTERNAL_HTML_TEMPLATE_NAME = "Html"; + @NonNls + public static final String INTERNAL_HTML5_TEMPLATE_NAME = "Html5"; + @NonNls + public static final String INTERNAL_XHTML_TEMPLATE_NAME = "Xhtml"; + @NonNls + public static final String FILE_HEADER_TEMPLATE_NAME = "File Header"; + public static final String DEFAULT_TEMPLATES_CATEGORY = "Default"; + public static final String INTERNAL_TEMPLATES_CATEGORY = "Internal"; + public static final String INCLUDES_TEMPLATES_CATEGORY = "Includes"; + public static final String CODE_TEMPLATES_CATEGORY = "Code"; + public static final String J2EE_TEMPLATES_CATEGORY = "J2EE"; public static FileTemplateManager getInstance(){ return ServiceManager.getService(FileTemplateManager.class); } - @NotNull public abstract FileTemplate[] getAllTemplates(); + @NotNull + public abstract FileTemplate[] getAllTemplates(); public abstract FileTemplate getTemplate(@NotNull @NonNls String templateName); - @NotNull public abstract Properties getDefaultProperties(); + @NotNull + public abstract Properties getDefaultProperties(); /** * Creates a new template with specified name. * @param name * @return created template */ - @NotNull public abstract FileTemplate addTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension); + @NotNull + public abstract FileTemplate addTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension); - public abstract void removeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly); - public abstract void removeInternal(@NotNull FileTemplate template); + public abstract void removeTemplate(@NotNull FileTemplate template); + //public abstract void removeInternal(@NotNull FileTemplate template); - @NotNull public abstract Collection getRecentNames(); + @NotNull + public abstract Collection getRecentNames(); public abstract void addRecentName(@NotNull @NonNls String name); public abstract void saveAll(); public abstract FileTemplate getInternalTemplate(@NotNull @NonNls String templateName); - @NotNull public abstract FileTemplate[] getInternalTemplates(); + @NotNull + public abstract FileTemplate[] getInternalTemplates(); public abstract FileTemplate getJ2eeTemplate(@NotNull @NonNls String templateName); public abstract FileTemplate getCodeTemplate(@NotNull @NonNls String templateName); - @NotNull public abstract FileTemplate[] getAllPatterns(); + @NotNull + public abstract FileTemplate[] getAllPatterns(); - public abstract FileTemplate addPattern(@NotNull @NonNls String name, @NotNull @NonNls String extension); + @NotNull + public abstract FileTemplate[] getAllCodeTemplates(); + + @NotNull + public abstract FileTemplate[] getAllJ2eeTemplates(); - @NotNull public abstract FileTemplate[] getAllCodeTemplates(); - @NotNull public abstract FileTemplate[] getAllJ2eeTemplates(); - - @NotNull public abstract FileTemplate addCodeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension); - @NotNull public abstract FileTemplate addJ2eeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension); - - public abstract void removePattern(@NotNull FileTemplate template, boolean fromDiskOnly); - public abstract void removeCodeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly); - public abstract void removeJ2eeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly); + @TestOnly + public abstract FileTemplate addInternal(@NotNull @NonNls String name, @NotNull @NonNls String extension); @NotNull public abstract String internalTemplateToSubject(@NotNull @NonNls String templateName); @@ -92,5 +105,6 @@ public abstract class FileTemplateManager{ @NotNull public abstract FileTemplate getDefaultTemplate(@NotNull @NonNls String name); - public abstract FileTemplate addInternal(@NotNull @NonNls String name, @NotNull @NonNls String extension); + public abstract void setTemplates(@NotNull String templatesCategory, Collection templates); + } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java index 92badac379be..b2e21797a8d6 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java @@ -17,7 +17,6 @@ package com.intellij.ide.fileTemplates; import com.intellij.ide.IdeBundle; -import com.intellij.ide.fileTemplates.impl.FileTemplateImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.command.CommandProcessor; @@ -25,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypes; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -199,16 +199,11 @@ public class FileTemplateUtil{ return stringWriter.toString(); } - public static FileTemplate cloneTemplate(FileTemplate template){ - FileTemplateImpl templateImpl = (FileTemplateImpl) template; - return (FileTemplate)templateImpl.clone(); - } - - public static void copyTemplate(FileTemplate src, FileTemplate dest){ - dest.setExtension(src.getExtension()); - dest.setName(src.getName()); - dest.setText(src.getText()); - dest.setAdjust(src.isAdjust()); + public static void copyTemplate(FileTemplate from, FileTemplate to){ + to.setExtension(from.getExtension()); + to.setName(from.getName()); + to.setText(from.getText()); + to.setReformatCode(from.isReformatCode()); } @SuppressWarnings({"HardCodedStringLiteral"}) @@ -289,7 +284,7 @@ public class FileTemplateUtil{ props.setProperty(dummyRef, ""); } - if (template.isJavaClassTemplate()){ + if (template.isTemplateOfType(StdFileTypes.JAVA)){ String packageName = props.getProperty(FileTemplate.ATTRIBUTE_PACKAGE_NAME); if(packageName == null || packageName.length() == 0){ props = new Properties(props); @@ -323,7 +318,7 @@ public class FileTemplateUtil{ } }); } - }, template.isJavaClassTemplate() + }, template.isTemplateOfType(StdFileTypes.JAVA) ? IdeBundle.message("command.create.class.from.template") : IdeBundle.message("command.create.file.from.template"), null); if(commandException[0] != null){ diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java index f86adaef8821..17b1fbb8ef19 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java @@ -27,6 +27,7 @@ import com.intellij.ide.fileTemplates.ui.SelectTemplateDialog; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDirectory; @@ -68,10 +69,10 @@ public class CreateFromTemplateGroup extends ActionGroup implements DumbAware { Arrays.sort(templates, new Comparator() { public int compare(FileTemplate template1, FileTemplate template2) { // java first - if (template1.isJavaClassTemplate() && !template2.isJavaClassTemplate()) { + if (template1.isTemplateOfType(StdFileTypes.JAVA) && !template2.isTemplateOfType(StdFileTypes.JAVA)) { return -1; } - if (template2.isJavaClassTemplate() && !template1.isJavaClassTemplate()) { + if (template2.isTemplateOfType(StdFileTypes.JAVA) && !template1.isTemplateOfType(StdFileTypes.JAVA)) { return 1; } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java index 1d63968f4a2e..c1ce12d44327 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java @@ -31,7 +31,6 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TabbedPaneWrapper; import com.intellij.util.ArrayUtil; @@ -46,6 +45,7 @@ import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; +import java.net.URL; import java.text.MessageFormat; import java.util.*; import java.util.List; @@ -58,6 +58,13 @@ import java.util.List; public class AllFileTemplatesConfigurable implements SearchableConfigurable { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable"); + + private static final String TEMPLATES_TITLE = IdeBundle.message("tab.filetemplates.templates"); + private static final String INCLUDES_TITLE = IdeBundle.message("tab.filetemplates.includes"); + private static final String CODE_TITLE = IdeBundle.message("tab.filetemplates.code"); + private static final String J2EE_TITLE = IdeBundle.message("tab.filetemplates.j2ee"); + private static final Icon ourIcon = IconLoader.getIcon("/general/fileTemplates.png"); + private JPanel myMainPanel; private FileTemplateTab myCurrentTab; private FileTemplateTab myTemplatesList; @@ -69,20 +76,12 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { private FileTemplateConfigurable myEditor; private boolean myModified = false; private JComponent myEditorComponent; - private static final int TEMPLATE_ID = 0; - private static final int PATTERN_ID = 1; - private static final int CODE_ID = 2; - private static final int J2EE_ID = 3; - private static final Icon ourIcon = IconLoader.getIcon("/general/fileTemplates.png"); private FileTemplateTab[] myTabs; - private static final String TEMPLATES_TITLE = IdeBundle.message("tab.filetemplates.templates"); - private static final String INCLUDES_TITLE = IdeBundle.message("tab.filetemplates.includes"); - private static final String CODE_TITLE = IdeBundle.message("tab.filetemplates.code"); - private static final String J2EE_TITLE = IdeBundle.message("tab.filetemplates.j2ee"); private Disposable myUIDisposable; + private final Set myInternalTemplateNames = new HashSet(); - @NonNls private static final String CURRENT_TAB = "FileTemplates.CurrentTab"; - @NonNls private static final String SELECTED_TEMPLATE = "FileTemplates.SelectedTemplate"; + private static final String CURRENT_TAB = "FileTemplates.CurrentTab"; + private static final String SELECTED_TEMPLATE = "FileTemplates.SelectedTemplate"; public Icon getIcon() { return ourIcon; @@ -97,14 +96,14 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { String ext = "java"; final FileTemplateDefaultExtension[] defaultExtensions = Extensions.getExtensions(FileTemplateDefaultExtension.EP_NAME); if (defaultExtensions.length > 0) { - ext = defaultExtensions [0].value; + ext = defaultExtensions[0].value; } createTemplate(IdeBundle.message("template.unnamed"), ext, ""); } - private FileTemplate createTemplate(@NotNull String prefName, @NotNull @NonNls String extension, @NotNull String content) { - FileTemplate[] templates = myCurrentTab.getTemplates(); - ArrayList names = new ArrayList(templates.length); + private void createTemplate(final @NotNull String prefName, final @NotNull String extension, final @NotNull String content) { + final FileTemplate[] templates = myCurrentTab.getTemplates(); + final Set names = new HashSet(); for (FileTemplate template : templates) { names.add(template.getName()); } @@ -113,32 +112,35 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { while (names.contains(name)) { name = prefName + " (" + ++i + ")"; } - FileTemplate newTemplate = new FileTemplateImpl(content, name, extension); + final FileTemplate newTemplate = new CustomFileTemplate(name, extension); + newTemplate.setText(content); myCurrentTab.addTemplate(newTemplate); myModified = true; myCurrentTab.selectTemplate(newTemplate); fireListChanged(); myEditor.focusToNameField(); - return newTemplate; } private void onClone() { - FileTemplate selected = myCurrentTab.getSelectedTemplate(); - if (selected == null) return; + final FileTemplate selected = myCurrentTab.getSelectedTemplate(); + if (selected == null) { + return; + } final FileTemplate[] templates = myCurrentTab.getTemplates(); - ArrayList names = new ArrayList(templates.length); + final Set names = new HashSet(); for (FileTemplate template : templates) { names.add(template.getName()); } @SuppressWarnings({"UnresolvedPropertyKey"}) - String nameTemplate = IdeBundle.message("template.copy.N.of.T"); + final String nameTemplate = IdeBundle.message("template.copy.N.of.T"); String name = MessageFormat.format(nameTemplate, "", selected.getName()); int i = 0; while (names.contains(name)) { name = MessageFormat.format(nameTemplate, ++i + " ", selected.getName()); } - FileTemplate newTemplate = new FileTemplateImpl(selected.getText(), name, selected.getExtension()); + final FileTemplate newTemplate = new CustomFileTemplate(name, selected.getExtension()); + newTemplate.setText(selected.getText()); myCurrentTab.addTemplate(newTemplate); myModified = true; myCurrentTab.selectTemplate(newTemplate); @@ -184,7 +186,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { }; myCurrentTab = myTemplatesList; - List allTabs = new ArrayList(Arrays.asList(myTemplatesList, myIncludesList, myCodeTemplatesList)); + final List allTabs = new ArrayList(Arrays.asList(myTemplatesList, myIncludesList, myCodeTemplatesList)); final Set factories = new THashSet(); ContainerUtil.addAll(factories, ApplicationManager.getApplication().getComponents(FileTemplateGroupDescriptorFactory.class)); @@ -274,13 +276,8 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { public void update(AnActionEvent e) { super.update(e); - FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); - FileTemplateManagerImpl manager = FileTemplateManagerImpl.getInstanceImpl(); - e.getPresentation().setEnabled(selectedItem != null - && !selectedItem.isDefault() - && - manager.getDefaultTemplate(selectedItem.getName(), selectedItem.getExtension()) != - null); + final FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); + e.getPresentation().setEnabled(selectedItem instanceof BundledFileTemplate && !selectedItem.isDefault()); } }; group.add(addAction); @@ -325,15 +322,13 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { private void onReset() { FileTemplate selected = myCurrentTab.getSelectedTemplate(); - if (selected != null) { + if (selected instanceof BundledFileTemplate) { if (Messages.showOkCancelDialog(IdeBundle.message("prompt.reset.to.original.template"), IdeBundle.message("title.reset.template"), Messages.getQuestionIcon()) != DialogWrapper.OK_EXIT_CODE) { return; } - FileTemplateImpl template = (FileTemplateImpl)selected; - - template.resetToDefault(); + ((BundledFileTemplate)selected).revertToDefaults(); myEditor.reset(); myModified = true; } @@ -343,9 +338,8 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { fireListChanged(); } - private void onTabChanged() { - int selectedIndex = myTabbedPane.getSelectedIndex(); + final int selectedIndex = myTabbedPane.getSelectedIndex(); if (0 <= selectedIndex && selectedIndex < myTabs.length) { myCurrentTab = myTabs[selectedIndex]; } @@ -381,7 +375,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { } private void selectTemplate(FileTemplate template) { - VirtualFile defDesc = null; + URL defDesc = null; if (myCurrentTab == myTemplatesList) { defDesc = FileTemplateManagerImpl.getInstanceImpl().getDefaultTemplateDescription(); } @@ -397,9 +391,10 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { } // internal template could not be removed and should be rendered bold - @SuppressWarnings({"SimplifiableIfStatement"}) public static boolean isInternalTemplate(String templateName, String templateTabTitle) { - if (templateName == null) return false; + if (templateName == null) { + return false; + } if (Comparing.strEqual(templateTabTitle, TEMPLATES_TITLE)) { return isInternalTemplateName(templateName); } @@ -412,13 +407,14 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { if (Comparing.strEqual(templateTabTitle, INCLUDES_TITLE)) { return Comparing.strEqual(templateName, FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); } - return false; } private static boolean isInternalTemplateName(final String templateName) { for(InternalTemplateBean bean: Extensions.getExtensions(InternalTemplateBean.EP_NAME)) { - if (Comparing.strEqual(templateName, bean.name)) return true; + if (Comparing.strEqual(templateName, bean.name)) { + return true; + } } return false; } @@ -453,11 +449,15 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { } private void initLists() { - FileTemplateManager templateManager = FileTemplateManager.getInstance(); - FileTemplate[] templates = templateManager.getAllTemplates(); - FileTemplate[] internals = templateManager.getInternalTemplates(); - FileTemplate[] templatesAndInternals = ArrayUtil.mergeArrays(internals, templates, FileTemplate.class); - myTemplatesList.init(templatesAndInternals); + final FileTemplateManager templateManager = FileTemplateManager.getInstance(); + + final FileTemplate[] internalTemplates = templateManager.getInternalTemplates(); + myInternalTemplateNames.clear(); + for (FileTemplate internalTemplate : internalTemplates) { + myInternalTemplateNames.add(((FileTemplateBase)internalTemplate).getQualifiedName()); + } + + myTemplatesList.init(ArrayUtil.mergeArrays(internalTemplates, templateManager.getAllTemplates(), FileTemplate.class)); myIncludesList.init(templateManager.getAllPatterns()); myCodeTemplatesList.init(templateManager.getAllCodeTemplates()); if (myJ2eeTemplatesList != null) { @@ -469,75 +469,53 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { return myModified || myEditor != null && myEditor.isModified(); } - /** - * If apply is acceptable, returns true. If no, returns false and fills error string. - */ - private boolean canApply(final boolean showErrorDialog, String[] errorString) { - for (FileTemplateTab list : myTabs) { - if (!canApply(showErrorDialog, errorString, list)) return false; - } - return true; - } - - private boolean canApply(final boolean showErrorDialog, String[] errorString, FileTemplateTab list) { + private void checkCanApply(FileTemplateTab list) throws ConfigurationException { final FileTemplate[] templates = myCurrentTab.getTemplates(); - ArrayList allNames = new ArrayList(); + final List allNames = new ArrayList(); FileTemplate itemWithError = null; - String errorMessage = null; - String errorTitle = null; boolean errorInName = true; + String errorString = null; for (FileTemplate template : templates) { - if (isInternalTemplateName(template.getName())) continue; - String currName = template.getName(); - String currExt = template.getExtension(); + if (isInternalTemplateName(template.getName())) { + continue; + } + final String currName = template.getName(); + final String currExt = template.getExtension(); if (currName.length() == 0) { itemWithError = template; - errorMessage = IdeBundle.message("error.please.specify.a.name.for.this.template"); - errorTitle = IdeBundle.message("title.template.name.not.specified"); - errorString[0] = IdeBundle.message("error.please.specify.template.name"); + errorString = IdeBundle.message("error.please.specify.template.name"); break; } if (allNames.contains(currName)) { itemWithError = template; - errorMessage = IdeBundle.message("error.please.specify.a.different.name.for.this.template"); - errorTitle = IdeBundle.message("title.template.already.exists"); - errorString[0] = IdeBundle.message("error.template.with.such.name.already.exists"); + errorString = IdeBundle.message("error.template.with.such.name.already.exists"); break; } if (currExt.length() == 0) { itemWithError = template; - errorMessage = IdeBundle.message("error.please.specify.extension"); - errorTitle = IdeBundle.message("title.template.extension.not.specified"); - errorString[0] = IdeBundle.message("error.please.specify.template.extension"); + errorString = IdeBundle.message("error.please.specify.template.extension"); errorInName = false; break; } allNames.add(currName); } - if (itemWithError == null) { - return true; - } - else { - final String _errorString = errorMessage; - final String _errorTitle = errorTitle; + + if (itemWithError != null) { final boolean _errorInName = errorInName; myTabbedPane.setSelectedIndex(Arrays.asList(myTabs).indexOf(list)); selectTemplate(itemWithError); list.selectTemplate(itemWithError); ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - if (showErrorDialog) { - Messages.showMessageDialog(myMainPanel, _errorString, _errorTitle, Messages.getErrorIcon()); - } - if (_errorInName) { - myEditor.focusToNameField(); - } - else { - myEditor.focusToExtensionField(); - } + public void run() { + if (_errorInName) { + myEditor.focusToNameField(); } - }); - return false; + else { + myEditor.focusToExtensionField(); + } + } + }); + throw new ConfigurationException(errorString); } } @@ -555,39 +533,34 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { myModified = true; myEditor.apply(); } - String[] errorString = new String[1]; - if (!canApply(false, errorString)) { - throw new ConfigurationException(errorString[0]); + + for (FileTemplateTab list : myTabs) { + checkCanApply(list); } + final FileTemplateManager templatesManager = FileTemplateManager.getInstance(); // Apply templates - ArrayList newModifiedItems = new ArrayList(); - FileTemplate[] templates = myTemplatesList.getTemplates(); - ContainerUtil.addAll(newModifiedItems, templates); - FileTemplateManager templatesManager = FileTemplateManager.getInstance(); - apply(newModifiedItems, myTemplatesList.savedTemplates, TEMPLATE_ID, templatesManager.getAllTemplates()); - - // Apply patterns - newModifiedItems = new ArrayList(); - templates = myIncludesList.getTemplates(); - ContainerUtil.addAll(newModifiedItems, templates); - apply(newModifiedItems, myIncludesList.savedTemplates, PATTERN_ID, templatesManager.getAllPatterns()); - - //Apply code templates - newModifiedItems = new ArrayList(); - templates = myCodeTemplatesList.getTemplates(); - ContainerUtil.addAll(newModifiedItems, templates); - apply(newModifiedItems, myCodeTemplatesList.savedTemplates, CODE_ID, templatesManager.getAllCodeTemplates()); - - //Apply J2EE templates + + final List templates = new ArrayList(); + final List internalTemplates = new ArrayList(); + for (FileTemplate template : myTemplatesList.getTemplates()) { + if (myInternalTemplateNames.contains(((FileTemplateBase)template).getQualifiedName())) { + internalTemplates.add(template); + } + else { + templates.add(template); + } + } + + templatesManager.setTemplates(FileTemplateManager.DEFAULT_TEMPLATES_CATEGORY, templates); + templatesManager.setTemplates(FileTemplateManager.INTERNAL_TEMPLATES_CATEGORY, internalTemplates); + templatesManager.setTemplates(FileTemplateManager.INCLUDES_TEMPLATES_CATEGORY, Arrays.asList(myIncludesList.getTemplates())); + templatesManager.setTemplates(FileTemplateManager.CODE_TEMPLATES_CATEGORY, Arrays.asList(myCodeTemplatesList.getTemplates())); if (myJ2eeTemplatesList != null) { - newModifiedItems = new ArrayList(); - templates = myJ2eeTemplatesList.getTemplates(); - ContainerUtil.addAll(newModifiedItems, templates); - apply(newModifiedItems, myJ2eeTemplatesList.savedTemplates, J2EE_ID, templatesManager.getAllJ2eeTemplates()); + templatesManager.setTemplates(FileTemplateManager.J2EE_TEMPLATES_CATEGORY, Arrays.asList(myJ2eeTemplatesList.getTemplates())); } - FileTemplateManager.getInstance().saveAll(); + templatesManager.saveAll(); if (myEditor != null) { myModified = false; @@ -596,80 +569,6 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { } } - private static void removeTemplate(FileTemplate aTemplate, int listId, boolean fromDiskOnly) { - FileTemplateManager manager = FileTemplateManager.getInstance(); - if (listId == TEMPLATE_ID) { - if (!aTemplate.isInternal()) { - manager.removeTemplate(aTemplate, fromDiskOnly); - } else { - manager.removeInternal(aTemplate); - } - } - else if (listId == PATTERN_ID) { - manager.removePattern(aTemplate, fromDiskOnly); - } - else if (listId == CODE_ID) { - manager.removeCodeTemplate(aTemplate, fromDiskOnly); - } - else if (listId == J2EE_ID) { - manager.removeJ2eeTemplate(aTemplate, fromDiskOnly); - } - } - - private static void apply(ArrayList newModifiedItems, - Map savedTemplate2ModifiedTemplate, - int listId, - FileTemplate[] templates) { - FileTemplateManager templatesManager = FileTemplateManager.getInstance(); - if (listId == TEMPLATE_ID) { - FileTemplate[] internals = templatesManager.getInternalTemplates(); - templates = ArrayUtil.mergeArrays(internals, templates, FileTemplate.class); - } - ArrayList savedTemplates = new ArrayList(); - // Delete removed and fill savedTemplates - for (FileTemplate aTemplate : templates) { - FileTemplate aModifiedTemplate = savedTemplate2ModifiedTemplate.get(aTemplate); - if (newModifiedItems.contains(aModifiedTemplate)) { - savedTemplates.add(aTemplate); - } else { - removeTemplate(aTemplate, listId, false); - savedTemplate2ModifiedTemplate.remove(aTemplate); - } - } - // Now all removed templates deleted from table, savedTemplates contains all templates in table - for (FileTemplate aTemplate : savedTemplates) { - FileTemplate aModifiedTemplate = savedTemplate2ModifiedTemplate.get(aTemplate); - LOG.assertTrue(aModifiedTemplate != null); - aTemplate.setAdjust(aModifiedTemplate.isAdjust()); - if (!aModifiedTemplate.isDefault()) { - FileTemplateUtil.copyTemplate(aModifiedTemplate, aTemplate); - } else { - if (!aTemplate.isDefault()) { - removeTemplate(aTemplate, listId, true); - } - } - } - - // Add new templates to table - for (FileTemplate aModifiedTemplate : newModifiedItems) { - LOG.assertTrue(aModifiedTemplate != null); - if (!savedTemplate2ModifiedTemplate.containsValue(aModifiedTemplate)) { - if (listId == TEMPLATE_ID) { - templatesManager.addTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); - } - else if (listId == PATTERN_ID) { - templatesManager.addPattern(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); - } - else if (listId == CODE_ID) { - templatesManager.addCodeTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); - } - else if (listId == J2EE_ID) { - templatesManager.addJ2eeTemplate(aModifiedTemplate.getName(), aModifiedTemplate.getExtension()).setText(aModifiedTemplate.getText()); - } - } - } - } - public void reset() { myEditor.reset(); initLists(); @@ -680,10 +579,10 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable { if (Comparing.strEqual(tab.getTitle(), tabName)) { myCurrentTab = tab; myTabbedPane.setSelectedIndex(idx); - final String selectedTemplate = component.getValue(SELECTED_TEMPLATE); + final String selectedTemplateName = component.getValue(SELECTED_TEMPLATE); final FileTemplate[] templates = myCurrentTab.getTemplates(); for (FileTemplate template : templates) { - if (Comparing.strEqual(template.getName(), selectedTemplate)) { + if (Comparing.strEqual(template.getName(), selectedTemplateName)) { tab.selectTemplate(template); break; } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java new file mode 100644 index 000000000000..2edba756bb84 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Eugene Zhuravlev + * Date: 4/6/11 + */ +public final class BundledFileTemplate extends FileTemplateBase { + + private final DefaultTemplate myDefaultTemplate; + private boolean myEnabled = true; // when user 'deletes' bundled plugin, it simply becomes disabled + + public BundledFileTemplate(@NotNull DefaultTemplate defaultTemplate) { + myDefaultTemplate = defaultTemplate; + } + + @NotNull + public String getName() { + return myDefaultTemplate.getName(); + } + + @NotNull + public String getExtension() { + return myDefaultTemplate.getExtension(); + } + + public void setName(@NotNull String name) { + // empty, cannot change name for bundled template + } + + public void setExtension(@NotNull String extension) { + // empty, cannot change extension for bundled template + } + + @NotNull + protected String getDefaultText() { + return myDefaultTemplate.getText(); + } + + @NotNull + public final String getDescription() { + return myDefaultTemplate.getDescriptionText(); + } + + public boolean isDefault() { + // todo: consider isReformat option here? + if (!getText().equals(getDefaultText())) { + return false; + } + return true; + } + + @Override + public BundledFileTemplate clone() { + return (BundledFileTemplate)super.clone(); + } + + public boolean isEnabled() { + return myEnabled; + } + + public void setEnabled(boolean enabled) { + if (enabled != myEnabled) { + myEnabled = enabled; + if (!enabled) { + revertToDefaults(); + } + } + } + + public void revertToDefaults() { + setText(null); + setReformatCode(DEFAULT_REFORMAT_CODE_VALUE); + } + + public boolean isTextModified() { + return !getText().equals(getDefaultText()); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/CustomFileTemplate.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/CustomFileTemplate.java new file mode 100644 index 000000000000..e41e5f5ea50b --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/CustomFileTemplate.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Eugene Zhuravlev + * Date: 4/6/11 + */ +public final class CustomFileTemplate extends FileTemplateBase { + private String myName; + private String myExtension; + + public CustomFileTemplate(@NotNull String name, @NotNull String extension) { + myName = name; + myExtension = extension; + } + + @NotNull + public String getName() { + return myName; + } + + public void setName(@NotNull String name) { + myName = name; + } + + @NotNull + public String getExtension() { + return myExtension; + } + + public void setExtension(@NotNull String extension) { + myExtension = extension; + } + + @NotNull + public String getDescription() { + return ""; // todo: some default description? + } + + public CustomFileTemplate clone() { + return (CustomFileTemplate)super.clone(); + } + + public boolean isDefault() { + return false; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DefaultTemplate.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DefaultTemplate.java new file mode 100644 index 000000000000..ff58cbd3bb73 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DefaultTemplate.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.net.URL; + +/** + * @author Eugene Zhuravlev + * Date: 3/28/11 + */ +public class DefaultTemplate { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.DefaultTemplate"); + + private final String myName; + private final String myExtension; + private final URL myTemplateURL; + @Nullable + private final URL myDescriptionURL; + private final String myText; + private final String myDescriptionText; + + public DefaultTemplate(@NotNull String name, @NotNull String extension, @NotNull URL templateURL, @Nullable URL descriptionURL) { + myName = name; + myExtension = extension; + myTemplateURL = templateURL; + myDescriptionURL = descriptionURL; + myText = loadText(templateURL); + myDescriptionText = descriptionURL != null? loadText(descriptionURL) : ""; + } + + private static String loadText(URL url) { + String text = ""; + try { + text = StringUtil.convertLineSeparators(UrlUtil.loadText(url)); + } + catch (IOException e) { + LOG.error(e); + } + return text; + } + + public String getName() { + return myName; + } + + public String getQualifiedName() { + return FileTemplateBase.getQualifiedName(getName(), getExtension()); + } + + public String getExtension() { + return myExtension; + } + + public URL getTemplateURL() { + return myTemplateURL; + } + + @Nullable + public URL getDescriptionURL() { + return myDescriptionURL; + } + + @NotNull + public String getText() { + return myText; + } + + @NotNull + public String getDescriptionText() { + return myDescriptionText; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DeletedTemplatesManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DeletedTemplatesManager.java new file mode 100644 index 000000000000..f601a21ef00a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/DeletedTemplatesManager.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import com.intellij.openapi.util.*; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +class DeletedTemplatesManager implements JDOMExternalizable { + public JDOMExternalizableStringList DELETED_DEFAULT_TEMPLATES = new JDOMExternalizableStringList(); + + public void addName(@NotNull @NonNls String nameWithExtension) { + DELETED_DEFAULT_TEMPLATES.remove(nameWithExtension); + DELETED_DEFAULT_TEMPLATES.add(nameWithExtension); + } + + public boolean contains(@NotNull @NonNls String nameWithExtension) { + return DELETED_DEFAULT_TEMPLATES.contains(nameWithExtension); + } + + public void readExternal(Element element) throws InvalidDataException { + DefaultJDOMExternalizer.readExternal(this, element); + } + + public void writeExternal(Element element) throws WriteExternalException { + DefaultJDOMExternalizer.writeExternal(this, element); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java new file mode 100644 index 000000000000..8f639f9d586d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java @@ -0,0 +1,321 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import com.intellij.CommonBundle; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.*; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: 3/22/11 + */ +class FTManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FTManager"); + public static final String TEMPLATES_DIR = "fileTemplates"; + public static final String DEFAULT_TEMPLATE_EXTENSION = "ft"; + public static final String TEMPLATE_EXTENSION_SUFFIX = "." + DEFAULT_TEMPLATE_EXTENSION; + public static final String CONTENT_ENCODING = CharsetToolkit.UTF8; + + private final String myName; + private final String myTemplatesDir; + private final Map myTemplates = new HashMap(); + private volatile List mySortedTemplates; + private final List myDefaultTemplates = new ArrayList(); + + FTManager(@NotNull @NonNls String name, @NotNull @NonNls String defaultTemplatesDirName) { + myName = name; + myTemplatesDir = TEMPLATES_DIR + (defaultTemplatesDirName.equals(".") ? "" : File.separator + defaultTemplatesDirName); + } + + public String getName() { + return myName; + } + + @NotNull + public Collection getAllTemplates(boolean includeDisabled) { + List sorted = mySortedTemplates; + if (sorted == null) { + sorted = new ArrayList(myTemplates.values()); + Collections.sort(sorted, new Comparator() { + public int compare(FileTemplateBase t1, FileTemplateBase t2) { + return t1.getName().compareToIgnoreCase(t2.getName()); + } + }); + mySortedTemplates = sorted; + } + + if (includeDisabled) { + return Collections.unmodifiableCollection(sorted); + } + + final List list = new ArrayList(sorted.size()); + for (FileTemplateBase template : sorted) { + if (template instanceof BundledFileTemplate && !((BundledFileTemplate)template).isEnabled()) { + continue; + } + list.add(template); + } + return list; + } + + /** + * @param templateQname + * @return template no matter enabled or disabled it is + */ + @Nullable + public FileTemplateBase getTemplate(@NotNull String templateQname) { + return myTemplates.get(templateQname); + } + + /** + * Disabled templates are never returned + * @param templateName + * @return + */ + @Nullable + public FileTemplateBase findTemplateByName(@NotNull String templateName) { + final FileTemplateBase template = myTemplates.get(templateName); + if (template != null) { + final boolean isEnabled = !(template instanceof BundledFileTemplate) || ((BundledFileTemplate)template).isEnabled(); + if (isEnabled) { + return template; + } + } + // templateName must be non-qualified name, since previous lookup found nothing + for (FileTemplateBase t : getAllTemplates(false)) { + final String qName = t.getQualifiedName(); + if (qName.startsWith(templateName) && qName.charAt(templateName.length()) == '.') { + return t; + } + } + return null; + } + + @NotNull + public FileTemplateBase addTemplate(String name, String extension) { + final String qName = FileTemplateBase.getQualifiedName(name, extension); + FileTemplateBase template = getTemplate(qName); + if (template == null) { + template = new CustomFileTemplate(name, extension); + myTemplates.put(qName, template); + mySortedTemplates = null; + } + return template; + } + + public void removeTemplate(@NotNull String qName) { + final FileTemplateBase template = myTemplates.get(qName); + if (template instanceof CustomFileTemplate) { + myTemplates.remove(qName); + mySortedTemplates = null; + } + else if (template instanceof BundledFileTemplate){ + ((BundledFileTemplate)template).setEnabled(false); + } + } + + public void updateTemplates(Collection newTemplates) { + final Set toDisable = new HashSet(); + for (DefaultTemplate template : myDefaultTemplates) { + toDisable.add(template.getQualifiedName()); + } + for (FileTemplate template : newTemplates) { + toDisable.remove(((FileTemplateBase)template).getQualifiedName()); + } + myTemplates.clear(); + mySortedTemplates = null; + for (DefaultTemplate template : myDefaultTemplates) { + final BundledFileTemplate bundled = createAndStoreBundledTemplate(template); + if (toDisable.contains(bundled.getQualifiedName())) { + bundled.setEnabled(false); + } + } + for (FileTemplate template : newTemplates) { + final FileTemplateBase _template = addTemplate(template.getName(), template.getExtension()); + _template.setText(template.getText()); + _template.setReformatCode(template.isReformatCode()); + } + } + + public void addDefaultTemplate(DefaultTemplate template) { + myDefaultTemplates.add(template); + createAndStoreBundledTemplate(template); + } + + private BundledFileTemplate createAndStoreBundledTemplate(DefaultTemplate template) { + final BundledFileTemplate bundled = new BundledFileTemplate(template); + final String qName = bundled.getQualifiedName(); + final FileTemplateBase previous = myTemplates.put(qName, bundled); + mySortedTemplates = null; + + LOG.assertTrue(previous == null, "Duplicate bundled template " + qName); + return bundled; + } + + // synchronizes templates: merges user-defined templates with default templates from the same category + //private void loadTemplates() { + // final File configRoot = getConfigRoot(false); + // File[] configFiles = configRoot.listFiles(); + // if (configFiles == null) { + // configFiles = ArrayUtil.EMPTY_FILE_ARRAY; + // } + // + // final List existingTemplates = new ArrayList(); + // // Read user-defined templates + // for (File file : configFiles) { + // if (file.isDirectory() || myTypeManager.isFileIgnored(file.getName()) || file.isHidden()) { + // continue; + // } + // String name = file.getName(); + // final String extension = myTypeManager.getExtension(name); + // name = name.substring(0, name.length() - extension.length() - 1); + // if (name.length() == 0) { + // continue; + // } + // final FileTemplate existing = myTemplates.findByName(name); + // if (existing == null || existing.isDefault()) { + // if (existing != null) { + // myTemplates.removeTemplate(existing); + // } + // FileTemplateImpl fileTemplate = new FileTemplateImpl(file, name, extension, false); + // myTemplates.addTemplate(fileTemplate); + // existingTemplates.add(fileTemplate); + // } + // else { + // // it is a user-defined template, revalidate it + // LOG.assertTrue(!((FileTemplateImpl)existing).isModified()); + // ((FileTemplateImpl)existing).invalidate(); + // existingTemplates.add(existing); + // } + // } + // + // for (final DefaultTemplate defaultTemplate : getDefaultTemplates()) { + // final String name = defaultTemplate.getName(); + // final FileTemplate template = myTemplates.findByName(name); + // if (template == null) { + // final FileTemplateImpl _template = new FileTemplateImpl(defaultTemplate.getTemplateURL(), defaultTemplate.getName(), defaultTemplate.getExtension()); + // _template.setDescription(defaultTemplate.getDescriptionURL()); + // myTemplates.addTemplate(_template); + // } + // } + // + // List toRemove = null; + // for (FileTemplate template : myTemplates.getAllTemplates()) { + // final FileTemplateImpl templateImpl = (FileTemplateImpl)template; + // if (!templateImpl.isDefault() && !existingTemplates.contains(templateImpl) && !templateImpl.isNew()) { + // if (toRemove == null) { + // toRemove = new ArrayList(); + // } + // toRemove.add(templateImpl); + // } + // } + // + // if (toRemove != null) { + // for (FileTemplateImpl template : toRemove) { + // myTemplates.removeTemplate(template); + // template.removeFromDisk(); + // } + // } + //} + + void saveTemplates() { + try { + final File configRoot = getConfigRoot(true); + + // first cleanup directory + final File[] files = configRoot.listFiles(); + if (files != null) { + for (File file : files) { + if (file.getName().endsWith(TEMPLATE_EXTENSION_SUFFIX)) { + FileUtil.delete(file); + } + } + } + + final String lineSeparator = CodeStyleSettingsManager.getSettings(ProjectManagerEx.getInstanceEx().getDefaultProject()).getLineSeparator(); + for (FileTemplateBase template : getAllTemplates(true)) { + if (template instanceof BundledFileTemplate && !((BundledFileTemplate)template).isTextModified()) { + continue; + } + saveTemplate(configRoot, template, lineSeparator); + } + } + catch (IOException e) { + LOG.error("Unable to save templates", e); + } + } + + /** Save template to file. If template is new, it is saved to specified directory. Otherwise it is saved to file from which it was read. + * If template was not modified, it is not saved. + * todo: review saving algorithm + */ + private static void saveTemplate(File parentDir, FileTemplateBase template, final String lineSeparator) throws IOException { + final File templateFile = new File(parentDir, template.getName() + "." + template.getExtension() + TEMPLATE_EXTENSION_SUFFIX); + + FileOutputStream fileOutputStream = new FileOutputStream(templateFile); + OutputStreamWriter outputStreamWriter; + try{ + outputStreamWriter = new OutputStreamWriter(fileOutputStream, CONTENT_ENCODING); + } + catch (UnsupportedEncodingException e){ + Messages.showMessageDialog(IdeBundle.message("error.unable.to.save.file.template.using.encoding", template.getName(), + CONTENT_ENCODING), + CommonBundle.getErrorTitle(), Messages.getErrorIcon()); + outputStreamWriter = new OutputStreamWriter(fileOutputStream); + } + String content = template.getText(); + + if (!lineSeparator.equals("\n")){ + content = StringUtil.convertLineSeparators(content, lineSeparator); + } + + outputStreamWriter.write(content); + outputStreamWriter.close(); + fileOutputStream.close(); + } + + public File getConfigRoot(boolean create) { + final File templatesPath = new File(PathManager.getConfigPath(), myTemplatesDir); + if (create && !templatesPath.exists()) { + final boolean created = templatesPath.mkdirs(); + if (!created) { + LOG.error("Cannot create directory: " + templatesPath.getAbsolutePath()); + } + } + return templatesPath; + } + + @Override + public String toString() { + return myName + " file template manager"; + } + +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java new file mode 100644 index 000000000000..e48ce5ff867d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.util.text.StringUtil; +import org.apache.velocity.runtime.parser.ParseException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.*; +import java.util.Map; +import java.util.Properties; + +/** + * @author Eugene Zhuravlev + * Date: 4/6/11 + */ +public abstract class FileTemplateBase implements FileTemplate { + public static final boolean DEFAULT_REFORMAT_CODE_VALUE = true; + public static final boolean DEFAULT_ENABLED_VALUE = true; + @Nullable + private String myText; + private boolean myShouldReformatCode = DEFAULT_REFORMAT_CODE_VALUE; + + public final boolean isReformatCode() { + return myShouldReformatCode; + } + + public final void setReformatCode(boolean reformat) { + myShouldReformatCode = reformat; + } + + public final String getQualifiedName() { + return getQualifiedName(getName(), getExtension()); + } + + public static String getQualifiedName(final String name, final String extension) { + return name + "." + extension; + } + + @NotNull + public final String getText() { + final String text = myText; + return text != null? text : getDefaultText(); + } + + public final void setText(@Nullable String text) { + if (text == null) { + myText = null; + } + else { + final String converted = StringUtil.convertLineSeparators(text); + myText = converted.equals(getDefaultText())? null : converted; + } + } + + @NotNull + protected String getDefaultText() { + return ""; + } + + @NotNull + public final String getText(Map attributes) throws IOException{ + return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getText())); + } + + @NotNull + public final String getText(Properties attributes) throws IOException{ + return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getText())); + } + + @NotNull + public final String[] getUnsetAttributes(@NotNull Properties properties) throws ParseException { + return FileTemplateUtil.calculateAttributes(getText(), properties, false); + } + + @Override + public FileTemplateBase clone() { + try { + return (FileTemplateBase)super.clone(); + } + catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + public boolean isTemplateOfType(@NotNull final FileType fType) { + return fType.equals(FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(getExtension())); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java index 7795585e21fc..48d46ffbcd0a 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java @@ -48,9 +48,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; @@ -70,6 +67,7 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.io.File; import java.io.IOException; +import java.net.URL; import java.util.ArrayList; /* @@ -94,7 +92,7 @@ public class FileTemplateConfigurable implements Configurable { private JPanel myTopPanel; private JEditorPane myDescriptionComponent; private boolean myModified = false; - private String myDefaultDescriptionUrl; + private URL myDefaultDescriptionUrl; private final Project myProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); private final ArrayList myChangeListeners = new ArrayList(); @@ -104,8 +102,8 @@ public class FileTemplateConfigurable implements Configurable { return myTemplate; } - public void setTemplate(FileTemplate template, VirtualFile defaultDescription) { - myDefaultDescriptionUrl = defaultDescription == null ? null : defaultDescription.getUrl(); + public void setTemplate(FileTemplate template, URL defaultDescription) { + myDefaultDescriptionUrl = defaultDescription; myTemplate = template; reset(); myNameField.selectAll(); @@ -168,11 +166,6 @@ public class FileTemplateConfigurable implements Configurable { myDescriptionComponent = new JEditorPane(CONTENT_TYPE_HTML, EMPTY_HTML); myDescriptionComponent.setEditable(false); -// myDescriptionComponent.setMargin(new Insets(2, 2, 2, 2)); - -// myDescriptionComponent = new JLabel(); -// myDescriptionComponent.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); -// myDescriptionComponent.setVerticalAlignment(SwingConstants.TOP); myAdjustBox = new JCheckBox(IdeBundle.message("checkbox.reformat.according.to.style")); myTopPanel = new JPanel(new GridBagLayout()); @@ -282,7 +275,7 @@ public class FileTemplateConfigurable implements Configurable { return true; } if (myTemplate != null) { - if (myTemplate.isAdjust() != myAdjustBox.isSelected()) { + if (myTemplate.isReformatCode() != myAdjustBox.isSelected()) { return true; } } @@ -304,7 +297,7 @@ public class FileTemplateConfigurable implements Configurable { } myTemplate.setName(name); myTemplate.setExtension(extension); - myTemplate.setAdjust(myAdjustBox.isSelected()); + myTemplate.setReformatCode(myAdjustBox.isSelected()); } myModified = false; } @@ -326,10 +319,7 @@ public class FileTemplateConfigurable implements Configurable { if ((description.length() == 0) && (myDefaultDescriptionUrl != null)) { try { - VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(myDefaultDescriptionUrl); - if (file != null) { - description = VfsUtil.loadText(file); - } + description = UrlUtil.loadText(myDefaultDescriptionUrl); } catch (IOException e) { LOG.error(e); @@ -340,7 +330,7 @@ public class FileTemplateConfigurable implements Configurable { myFile = createFile(text, name); myTemplateEditor = createEditor(); - boolean adjust = (myTemplate != null) && myTemplate.isAdjust(); + boolean adjust = (myTemplate != null) && myTemplate.isReformatCode(); myNameField.setText(name); myExtensionField.setText(extension); myAdjustBox.setSelected(adjust); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java deleted file mode 100644 index 9e12123a50a1..000000000000 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateImpl.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright 2000-2009 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.ide.fileTemplates.impl; - -import com.intellij.CommonBundle; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.ide.fileTemplates.FileTemplateUtil; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ex.ProjectManagerEx; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.util.ArrayUtil; -import org.apache.velocity.runtime.parser.ParseException; -import org.jetbrains.annotations.NotNull; - -import java.io.*; -import java.util.Map; -import java.util.Properties; - -/** - * @author MYakovlev - * Date: Jul 24, 2002 - */ -public class FileTemplateImpl implements FileTemplate, Cloneable{ - private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateImpl"); - - private String myDescription; - private String myContent; - private String myName; - private String myExtension; - private File myTemplateFile; // file to save in - private String myTemplateURL; - private boolean myRenamed = false; - private boolean myModified = false; - private boolean myReadOnly = false; - private boolean myAdjust = true; - - private boolean myIsInternal = false; - - /** Creates new template. This template is marked as 'new', i.e. it will be saved to new file at IDEA end. */ - FileTemplateImpl(@NotNull String content, @NotNull String name, @NotNull String extension){ - myContent = StringUtil.convertLineSeparators(content); - myName = replaceFileSeparatorChar(name); - myExtension = extension; - myModified = true; - } - - FileTemplateImpl(@NotNull File templateFile, @NotNull String name, @NotNull String extension, boolean isReadOnly) { - myTemplateFile = templateFile; - myName = replaceFileSeparatorChar(name); - myExtension = extension; - myModified = false; - myReadOnly = isReadOnly; - } - - FileTemplateImpl(@NotNull VirtualFile templateURL, @NotNull String name, @NotNull String extension) { - myTemplateURL = templateURL.getUrl(); - myName = name; - myExtension = extension; - myModified = false; - myReadOnly = true; - } - - public Object clone(){ - try{ - return super.clone(); - } - catch (CloneNotSupportedException e){ - // Should not be here - throw new RuntimeException(e); - } - } - - @NotNull - public String[] getUnsetAttributes(@NotNull Properties properties) throws ParseException{ - String content; - try{ - content = getContent(); - } - catch (IOException e){ - LOG.error("Unable to read template \""+myName+"\"", e); - return ArrayUtil.EMPTY_STRING_ARRAY; - } - return FileTemplateUtil.calculateAttributes(content, properties, false); - } - - public synchronized boolean isDefault(){ - return myReadOnly; - } - - @NotNull - public String getDescription(){ - try { - String description; - synchronized (this) { - description = myDescription; - } - if (description == null) return ""; - VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(description); - LOG.assertTrue(virtualFile != null, "Unable to find description at '" + description + "'"); - return VfsUtil.loadText(virtualFile); - } - catch (IOException e) { - return ""; - } - } - - synchronized void setDescription(VirtualFile file){ - myDescription = file.getUrl(); - } - - @NotNull - public synchronized String getName(){ - return myName; - } - - public synchronized boolean isJavaClassTemplate(){ - FileType fileType = FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(myExtension); - return fileType.equals(StdFileTypes.JAVA); - } - - @NotNull - public synchronized String getExtension(){ - return myExtension; - } - - @NotNull - public String getText(){ - try{ - return getContent(); - } - catch (IOException e){ - LOG.error("Unable to read template \""+myName+"\"", e); - return ""; - } - } - - public synchronized void setText(String text){ - // for read-only template we will save it later in user-defined templates - if(text == null){ - text = ""; - } - text = StringUtil.convertLineSeparators(text); - if(text.equals(getText())){ - return; - } - myContent = text; - myModified = true; - if(myReadOnly){ - myTemplateFile = null; - myTemplateURL = null; - myReadOnly = false; - } - } - - synchronized boolean isModified(){ - return myModified; - } - - /** Read template from file. */ - private static String readExternal(File file) throws IOException{ - return FileUtil.loadFile(file, ourEncoding); - } - - /** Read template from URL. */ - private static String readExternal(VirtualFile url) throws IOException{ - final Document content = FileDocumentManager.getInstance().getDocument(url); - return content != null ? content.getText() : new String(url.contentsToByteArray(), ourEncoding); - } - - /** Removes template file. - */ - synchronized void removeFromDisk() { - if (!myReadOnly && myTemplateFile != null && myTemplateFile.delete()) { - myModified = false; - } - } - - /** Save template to file. If template is new, it is saved to specified directory. Otherwise it is saved to file from which it was read. - * If template was not modified, it is not saved. - */ - void writeExternal(File defaultDir) throws IOException{ - File templateFile; - synchronized (this) { - if (!myModified && !myRenamed) { - return; - } - if(myRenamed){ - LOG.assertTrue(myTemplateFile != null); - LOG.assertTrue(myTemplateFile.delete()); - myTemplateFile = null; - myRenamed = false; - } - templateFile = myReadOnly ? null : myTemplateFile; - if(templateFile == null){ - LOG.assertTrue(defaultDir.isDirectory()); - templateFile = new File(defaultDir, myName+"."+myExtension); - } - } - - FileOutputStream fileOutputStream = new FileOutputStream(templateFile); - OutputStreamWriter outputStreamWriter; - try{ - outputStreamWriter = new OutputStreamWriter(fileOutputStream, ourEncoding); - } - catch (UnsupportedEncodingException e){ - Messages.showMessageDialog(IdeBundle.message("error.unable.to.save.file.template.using.encoding", getName(), ourEncoding), - CommonBundle.getErrorTitle(), Messages.getErrorIcon()); - outputStreamWriter = new OutputStreamWriter(fileOutputStream); - } - String content = getContent(); - Project project = ProjectManagerEx.getInstanceEx().getDefaultProject(); - String lineSeparator = CodeStyleSettingsManager.getSettings(project).getLineSeparator(); - - if (!lineSeparator.equals("\n")){ - content = StringUtil.convertLineSeparators(content, lineSeparator); - } - - outputStreamWriter.write(content); - outputStreamWriter.close(); - fileOutputStream.close(); - -// StringReader reader = new StringReader(getContent()); -// FileWriter fileWriter = new FileWriter(templateFile); -// BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); -// for(int currChar = reader.read(); currChar != -1; currChar = reader.read()){ -// bufferedWriter.write(currChar); -// } -// bufferedWriter.close(); -// fileWriter.close(); - synchronized (this) { - myModified = false; - myTemplateFile = templateFile; - } - } - - @NotNull - public String getText(Map attributes) throws IOException{ - return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getContent())); - } - - @NotNull - public String getText(Properties attributes) throws IOException{ - return StringUtil.convertLineSeparators(FileTemplateUtil.mergeTemplate(attributes, getContent())); - } - - public String toString(){ - return getName(); - } - - @NotNull - private String getContent() throws IOException{ - String content; - File templateIOFile; - String templateURL; - synchronized (this) { - content = myContent; - templateIOFile = myTemplateFile; - templateURL = myTemplateURL; - } - if(content == null) { - if(templateIOFile != null){ - content = StringUtil.convertLineSeparators(readExternal(templateIOFile)); - } - else { - if(templateURL != null){ - VirtualFile templateFile = VirtualFileManager.getInstance().findFileByUrl(templateURL); - content = templateFile == null ? "" : StringUtil.convertLineSeparators(readExternal(templateFile)); - } - else{ - content = ""; - } - } - synchronized (this) { - myContent = content; - } - } - - return content; - } - - synchronized void invalidate(){ - if(!myReadOnly){ - if(myTemplateFile != null || myTemplateURL != null){ - myContent = null; - } - } - } - - synchronized boolean isNew(){ - return myTemplateFile == null && myTemplateURL == null; - } - - public synchronized void setName(@NotNull String name){ - name = replaceFileSeparatorChar(name.trim()); - if(!myName.equals(name)){ - LOG.assertTrue(!myReadOnly); - myName = name; - myRenamed = true; - myModified = true; - } - } - - public synchronized void setExtension(@NotNull String extension){ - extension = extension.trim(); - if(!myExtension.equals(extension)){ - LOG.assertTrue(!myReadOnly); - myExtension = extension; - myRenamed = true; - myModified = true; - } - } - - public synchronized boolean isAdjust(){ - return myAdjust; - } - - public synchronized void setAdjust(boolean adjust){ - myAdjust = adjust; - } - - public void resetToDefault() { - LOG.assertTrue(!isDefault()); - String name; - String extension; - synchronized (this) { - name = myName; - extension = myExtension; - } - VirtualFile file = FileTemplateManagerImpl.getInstanceImpl().getDefaultTemplate(name, extension); - if (file == null) return; - try { - String text = readExternal(file); - setText(text); - synchronized (this) { - myReadOnly = true; - } - } - catch (IOException e) { - LOG.error ("Error reading template"); - } - } - - private static String replaceFileSeparatorChar(String s) { - StringBuilder buffer = new StringBuilder(); - char[] chars = s.toCharArray(); - for (char aChar : chars) { - if (aChar == File.separatorChar) { - buffer.append("$"); - } - else { - buffer.append(aChar); - } - } - return buffer.toString(); - } - - public synchronized void setInternal(boolean isInternal) { - myIsInternal = isInternal; - } - - public synchronized boolean isInternal() { - return myIsInternal; - } - - synchronized void setModified(boolean modified) { - myModified = modified; - } - - synchronized void setReadOnly(boolean readOnly) { - myReadOnly = readOnly; - } -} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index 33c059978838..b1a72fe9faa3 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -25,7 +25,6 @@ import com.intellij.ide.plugins.cl.PluginClassLoader; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.components.ExportableComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -33,22 +32,16 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; import com.intellij.openapi.util.*; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VfsUtil; -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.NewVirtualFile; -import com.intellij.openapi.vfs.newvfs.events.VFileEvent; -import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; import com.intellij.util.SystemProperties; import com.intellij.util.messages.MessageBus; import com.intellij.util.text.DateFormatUtil; -import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import java.io.File; import java.io.IOException; @@ -65,103 +58,211 @@ import java.util.*; * _inside_, not outside of the read action */ public class FileTemplateManagerImpl extends FileTemplateManager implements ExportableComponent, JDOMExternalizable { - private static final FileTemplateManagerImpl[] EMPTY_ARRAY = new FileTemplateManagerImpl[0]; private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl"); - @NonNls private static final String DEFAULT_TEMPLATE_EXTENSION = "ft"; - @NonNls private static final String TEMPLATES_DIR = "fileTemplates"; - @NonNls private static final String DEFAULT_TEMPLATES_TOP_DIR = TEMPLATES_DIR; - @NonNls private static final String INTERNAL_DIR = "internal"; - @NonNls private static final String INCLUDES_DIR = "includes"; - @NonNls private static final String CODETEMPLATES_DIR = "code"; - @NonNls private static final String J2EE_TEMPLATES_DIR = "j2ee"; - private final String myName; - @NonNls private final String myDefaultTemplatesDir; - @NonNls private final String myTemplatesDir; - private MyTemplates myTemplates; + private static final String TEMPLATES_DIR = "fileTemplates"; + private static final String DEFAULT_TEMPLATES_ROOT = TEMPLATES_DIR; + private static final String INTERNAL_DIR = "internal"; + private static final String INCLUDES_DIR = "includes"; + private static final String CODETEMPLATES_DIR = "code"; + private static final String J2EE_TEMPLATES_DIR = "j2ee"; + private static final String ROOT_DIR = "."; + + public static final String DESCRIPTION_FILE_EXTENSION = "html"; + private static final String DESCRIPTION_EXTENSION_SUFFIX = "." + DESCRIPTION_FILE_EXTENSION; + private static final String DESCRIPTION_FILE_NAME = "default." + DESCRIPTION_FILE_EXTENSION; + private final RecentTemplatesManager myRecentList = new RecentTemplatesManager(); - private final Set notAdjusted = new HashSet(); - private volatile boolean myLoaded = false; - private final FileTemplateManagerImpl myInternalTemplatesManager; - private final FileTemplateManagerImpl myPatternsManager; - private final FileTemplateManagerImpl myCodeTemplatesManager; - private final FileTemplateManagerImpl myJ2eeTemplatesManager; - private final MyDeletedTemplatesManager myDeletedTemplatesManager = new MyDeletedTemplatesManager(); - private VirtualFile myDefaultDescription; + private final FTManager myDefaultTemplatesManager; + private final FTManager myInternalTemplatesManager; + private final FTManager myPatternsManager; + private final FTManager myCodeTemplatesManager; + private final FTManager myJ2eeTemplatesManager; + + private final Map myDirToManagerMap = new HashMap(); - private static VirtualFile[] ourTopDirs; + private static final String ELEMENT_DELETED_TEMPLATES = "deleted_templates"; + private static final String ELEMENT_DELETED_INCLUDES = "deleted_includes"; + private static final String ELEMENT_RECENT_TEMPLATES = "recent_templates"; + private static final String ELEMENT_TEMPLATES = "templates"; + private static final String ELEMENT_INTERNAL_TEMPLATE = "internal_template"; + private static final String ELEMENT_TEMPLATE = "template"; + private static final String ATTRIBUTE_NAME = "name"; + private static final String ATTRIBUTE_REFORMAT = "reformat"; + private static final String ATTRIBUTE_ENABLED = "enabled"; + + private final FTManager[] myAllManagers; private final FileTypeManagerEx myTypeManager; - @NonNls private static final String ELEMENT_DELETED_TEMPLATES = "deleted_templates"; - @NonNls private static final String ELEMENT_DELETED_INCLUDES = "deleted_includes"; - @NonNls private static final String ELEMENT_RECENT_TEMPLATES = "recent_templates"; - @NonNls private static final String ELEMENT_TEMPLATES = "templates"; - @NonNls private static final String ELEMENT_INTERNAL_TEMPLATE = "internal_template"; - @NonNls private static final String ELEMENT_TEMPLATE = "template"; - @NonNls private static final String ATTRIBUTE_NAME = "name"; - @NonNls private static final String ATTRIBUTE_REFORMAT = "reformat"; - private final Object LOCK = new Object(); - private static final Object TOP_DIRS_LOCK = new Object(); - - private final FileTemplateManagerImpl[] myChildren; public static FileTemplateManagerImpl getInstanceImpl() { return (FileTemplateManagerImpl)ServiceManager.getService(FileTemplateManager.class); } public FileTemplateManagerImpl(@NotNull FileTypeManagerEx typeManager, @NotNull MessageBus bus) { - this("Default", ".", typeManager, - new FileTemplateManagerImpl("Internal", INTERNAL_DIR, typeManager, null, null, null, null), - new FileTemplateManagerImpl("Includes", INCLUDES_DIR, typeManager, null, null, null, null), - new FileTemplateManagerImpl("Code", CODETEMPLATES_DIR, typeManager, null, null, null, null), - new FileTemplateManagerImpl("J2EE", J2EE_TEMPLATES_DIR, typeManager, null, null, null, null)); + myTypeManager = typeManager; + myDefaultTemplatesManager = new FTManager(DEFAULT_TEMPLATES_CATEGORY, ROOT_DIR); + myInternalTemplatesManager = new FTManager(INTERNAL_TEMPLATES_CATEGORY, INTERNAL_DIR); + myPatternsManager = new FTManager(INCLUDES_TEMPLATES_CATEGORY, INCLUDES_DIR); + myCodeTemplatesManager = new FTManager(CODE_TEMPLATES_CATEGORY, CODETEMPLATES_DIR); + myJ2eeTemplatesManager = new FTManager(J2EE_TEMPLATES_CATEGORY, J2EE_TEMPLATES_DIR); + + myDirToManagerMap.put("", myDefaultTemplatesManager); + myDirToManagerMap.put(INTERNAL_DIR + "/", myInternalTemplatesManager); + myDirToManagerMap.put(INCLUDES_DIR + "/", myPatternsManager); + myDirToManagerMap.put(CODETEMPLATES_DIR + "/", myCodeTemplatesManager); + myDirToManagerMap.put(J2EE_TEMPLATES_DIR + "/", myJ2eeTemplatesManager); + + myAllManagers = new FTManager[]{myDefaultTemplatesManager, myInternalTemplatesManager, myPatternsManager, myCodeTemplatesManager, myJ2eeTemplatesManager}; - bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { - public void before(final List events) { - } - - public void after(final List events) { - refreshTopDirs(); - } - }); + loadDefaultTemplates(); + for (FTManager child : myAllManagers) { + loadCustomizedContent(child); + } + + // todo: do something with this hack + //if (ApplicationManager.getApplication().isUnitTestMode()) { + // for (String tname : Arrays.asList("Class", "AnnotationType", "Enum", "Interface")) { + // for (FileTemplate template : getAllTemplates()) { + // if (tname.equals(template.getName())) { + // myInternalTemplatesManager.getTemplateContainer().removeTemplate(template); + // break; + // } + // } + // FileTemplateImpl fileTemplate = new FileTemplateImpl(normalizeText(getTestClassTemplateText(tname)), tname, "java"); + // fileTemplate.setReadOnly(true); + // fileTemplate.setModified(false); + // myInternalTemplatesManager.getTemplateContainer().addTemplate(fileTemplate); + // fileTemplate.setInternal(true); + // } + //} + } - private FileTemplateManagerImpl(@NotNull @NonNls String name, - @NotNull @NonNls String defaultTemplatesDirName, - @NotNull FileTypeManagerEx fileTypeManagerEx, - FileTemplateManagerImpl internalTemplatesManager, - FileTemplateManagerImpl patternsManager, - FileTemplateManagerImpl codeTemplatesManager, - FileTemplateManagerImpl j2eeTemplatesManager) { - myName = name; - myDefaultTemplatesDir = defaultTemplatesDirName; - myTemplatesDir = TEMPLATES_DIR + (defaultTemplatesDirName.equals(".") ? "" : File.separator + defaultTemplatesDirName); - myTypeManager = fileTypeManagerEx; - myInternalTemplatesManager = internalTemplatesManager; - myPatternsManager = patternsManager; - myCodeTemplatesManager = codeTemplatesManager; - myJ2eeTemplatesManager = j2eeTemplatesManager; - myChildren = internalTemplatesManager == null ? EMPTY_ARRAY : new FileTemplateManagerImpl[]{internalTemplatesManager,patternsManager,codeTemplatesManager,j2eeTemplatesManager}; - - if (ApplicationManager.getApplication().isUnitTestMode() && defaultTemplatesDirName.equals(INTERNAL_DIR)) { - for (String tname : Arrays.asList("Class", "AnnotationType", "Enum", "Interface")) { - for (FileTemplate template : getAllTemplates()) { - if (template.getName().equals(tname)) { - myTemplates.removeTemplate(template); - break; + private void loadDefaultTemplates() { + final Set processedUrls = new HashSet(); + for (PluginDescriptor plugin : ApplicationManager.getApplication().getPlugins()) { + if (plugin instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)plugin).isEnabled()) { + final ClassLoader loader = plugin.getPluginClassLoader(); + if (loader instanceof PluginClassLoader && ((PluginClassLoader)loader).getUrls().isEmpty()) { + continue; // development mode, when IDEA_CORE's loader contains all the classpath + } + try { + final Enumeration systemResources = loader.getResources(DEFAULT_TEMPLATES_ROOT); + if (systemResources != null && systemResources.hasMoreElements()) { + while (systemResources.hasMoreElements()) { + final URL url = systemResources.nextElement(); + if (processedUrls.contains(url)) { + continue; + } + processedUrls.add(url); + loadDefaultsFromRoot(url); + } } } - FileTemplateImpl fileTemplate = new FileTemplateImpl(normalizeText(getTestClassTemplateText(tname)), tname, "java"); - fileTemplate.setReadOnly(true); - fileTemplate.setModified(false); - myTemplates.addTemplate(fileTemplate); - fileTemplate.setInternal(true); + catch (IOException e) { + LOG.error(e); + } } } } + private void loadDefaultsFromRoot(final URL root) throws IOException { + final List children = UrlUtil.getChildrenRelativePaths(root); + if (children.isEmpty()) { + return; + } + final Set descriptionPaths = new HashSet(); + for (String path : children) { + if (path.endsWith(DESCRIPTION_EXTENSION_SUFFIX)) { + descriptionPaths.add(path); + } + } + for (final String path : children) { + for (Map.Entry entry : myDirToManagerMap.entrySet()) { + final String prefix = entry.getKey(); + if (matchesPrefix(path, prefix)) { + if (path.endsWith(FTManager.TEMPLATE_EXTENSION_SUFFIX)) { + final String filename = path.substring(prefix.length(), path.length() - FTManager.TEMPLATE_EXTENSION_SUFFIX.length()); + final String extension = myTypeManager.getExtension(filename); + final String templateName = filename.substring(0, filename.length() - extension.length() - 1); + final URL templateUrl = new URL(root.toExternalForm() + "/" +path); + final String descriptionPath = getDescriptionPath(prefix, templateName, extension, descriptionPaths); + final URL descriptionUrl = descriptionPath != null? new URL(root.toExternalForm() + "/" + descriptionPath) : null; + entry.getValue().addDefaultTemplate(new DefaultTemplate(templateName, extension, templateUrl, descriptionUrl)); + } + break; // FTManagers loop + } + } + } + } + + private void loadCustomizedContent(FTManager manager) { + final File configRoot = manager.getConfigRoot(false); + File[] configFiles = configRoot.listFiles(); + if (configFiles == null) { + return; + } + for (File file : configFiles) { + if (file.isDirectory() || myTypeManager.isFileIgnored(file.getName()) || file.isHidden()) { + continue; + } + String name = file.getName(); + if (!name.endsWith(FTManager.TEMPLATE_EXTENSION_SUFFIX)) { + continue; + } + // cut default template extension + name = name.substring(0, name.length() - FTManager.TEMPLATE_EXTENSION_SUFFIX.length()); + + final String extension = myTypeManager.getExtension(name); + name = name.substring(0, name.length() - extension.length() - 1); + if (name.length() == 0) { + continue; + } + try { + final String text = FileUtil.loadFile(file, FTManager.CONTENT_ENCODING); + manager.addTemplate(name, extension).setText(text); + } + catch (IOException e) { + LOG.error(e); + } + } + } + + //Example: templateName="NewClass" templateExtension="java" + private static String getDescriptionPath(String pathPrefix, String templateName, String templateExtension, Set descriptionPaths) { + final Locale locale = Locale.getDefault(); + + String descName = MessageFormat.format("{0}.{1}_{2}_{3}" + DESCRIPTION_EXTENSION_SUFFIX, templateName, templateExtension, + locale.getLanguage(), locale.getCountry()); + String descPath = pathPrefix.length() > 0? pathPrefix + descName : descName; + if (descriptionPaths.contains(descPath)) { + return descPath; + } + + descName = MessageFormat.format("{0}.{1}_{2}" + DESCRIPTION_EXTENSION_SUFFIX, templateName, templateExtension, locale.getLanguage()); + descPath = pathPrefix.length() > 0? pathPrefix + descName : descName; + if (descriptionPaths.contains(descPath)) { + return descPath; + } + + descName = templateName + "." + templateExtension + DESCRIPTION_EXTENSION_SUFFIX; + descPath = pathPrefix.length() > 0? pathPrefix + descName : descName; + if (descriptionPaths.contains(descPath)) { + return descPath; + } + return null; + } + + private static boolean matchesPrefix(String path, String prefix) { + if (prefix.length() == 0) { + return !path.contains("/"); + } + return FileUtil.startsWith(path, prefix) && !path.substring(prefix.length()).contains("/"); + } + @NotNull public File[] getExportFiles() { - return new File[]{getParentDirectory(false), PathManager.getDefaultOptionsFile()}; + return new File[]{myDefaultTemplatesManager.getConfigRoot(false), PathManager.getDefaultOptionsFile()}; } @NotNull @@ -171,60 +272,28 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo @NotNull public FileTemplate[] getAllTemplates() { - ensureTemplatesAreLoaded(); - synchronized (LOCK) { - return myTemplates.getAllTemplates(); - } + final Collection templates = myDefaultTemplatesManager.getAllTemplates(false); + return templates.toArray(new FileTemplate[templates.size()]); } - public FileTemplate getTemplate(@NotNull @NonNls String templateName) { - ensureTemplatesAreLoaded(); - synchronized (LOCK) { - return myTemplates.findByName(templateName); - } + public FileTemplate getTemplate(@NotNull String templateName) { + return myDefaultTemplatesManager.findTemplateByName(templateName); } @NotNull - public FileTemplate addTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { - invalidate(); - ensureTemplatesAreLoaded(); - synchronized (LOCK) { + public FileTemplate addTemplate(@NotNull String name, @NotNull String extension) { + return myDefaultTemplatesManager.addTemplate(name, extension); + } - LOG.assertTrue(name.length() > 0); - if (myTemplates.findByName(name) != null) { - LOG.error("Duplicate template " + name); - } - - FileTemplate fileTemplate = new FileTemplateImpl("", name, extension); - myTemplates.addTemplate(fileTemplate); - return fileTemplate; + public void removeTemplate(@NotNull FileTemplate template) { + final String qName = ((FileTemplateBase)template).getQualifiedName(); + for (FTManager manager : myAllManagers) { + manager.removeTemplate(qName); } } - public void removeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly) { - ensureTemplatesAreLoaded(); - synchronized (LOCK) { - myTemplates.removeTemplate(template); - try { - ((FileTemplateImpl)template).removeFromDisk(); - } - catch (Exception e) { - LOG.error("Unable to remove template", e); - } - - if (!fromDiskOnly) { - myDeletedTemplatesManager.addName(template.getName() + "." + template.getExtension() + "." + DEFAULT_TEMPLATE_EXTENSION); - } - - invalidate(); - } - } - - public void removeInternal(@NotNull FileTemplate template) { - LOG.assertTrue(myInternalTemplatesManager != null); - myInternalTemplatesManager.removeTemplate(template, true); - } - public FileTemplate addInternal(@NotNull @NonNls String name, @NotNull @NonNls String extension) { + @TestOnly + public FileTemplate addInternal(@NotNull String name, @NotNull String extension) { return myInternalTemplatesManager.addTemplate(name, extension); } @@ -256,262 +325,153 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo return result; } - private File getParentDirectory(boolean create) { - File configPath = new File(PathManager.getConfigPath()); - File templatesPath = new File(configPath, myTemplatesDir); - if (!templatesPath.exists()) { - if (create) { - final boolean created = templatesPath.mkdirs(); - if (!created) { - LOG.error("Cannot create directory: " + templatesPath.getAbsolutePath()); - } - } - } - return templatesPath; - } - - private void ensureTemplatesAreLoaded() { - if (myLoaded) { - return; - } - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - synchronized (LOCK) { - if (myLoaded) { - return; - } - loadTemplates(); - for (FileTemplate template : myTemplates.getAllTemplates()) { - template.setAdjust(!notAdjusted.contains(template.getName())); - } - } - myLoaded = true; - } - }); - } - - private void loadTemplates() { - Collection defaultTemplates = getDefaultTemplates(); - for (VirtualFile file : defaultTemplates) { - //noinspection HardCodedStringLiteral - if (file.getName().equals("default.html")) { - myDefaultDescription = file; //todo[myakovlev] - } - } - - File templateDir = getParentDirectory(false); - File[] files = templateDir.listFiles(); - if (files == null) { - files = ArrayUtil.EMPTY_FILE_ARRAY; - } - - if (myTemplates == null) { - myTemplates = new MyTemplates(); - } - List existingTemplates = new ArrayList(); - // Read user-defined templates - for (File file : files) { - if (file.isDirectory() || FileTypeManagerEx.getInstance().isFileIgnored(file.getName())) { - continue; - } - String name = file.getName(); - String extension = myTypeManager.getExtension(name); - name = name.substring(0, name.length() - extension.length() - 1); - if (file.isHidden() || name.length() == 0) { - continue; - } - FileTemplate existing = myTemplates.findByName(name); - if (existing == null || existing.isDefault()) { - if (existing != null) { - myTemplates.removeTemplate(existing); - } - FileTemplateImpl fileTemplate = new FileTemplateImpl(file, name, extension, false); - //fileTemplate.setDescription(myDefaultDescription); default description will be shown - myTemplates.addTemplate(fileTemplate); - existingTemplates.add(fileTemplate); - } - else { - // it is a user-defined template, revalidate it - LOG.assertTrue(!((FileTemplateImpl)existing).isModified()); - ((FileTemplateImpl)existing).invalidate(); - existingTemplates.add(existing); - } - } - LOG.debug("FileTemplateManagerImpl.loadTemplates() reading default templates..."); - // Read default templates - for (VirtualFile file : defaultTemplates) { - if(FileTypeManagerEx.getInstance().isFileIgnored(file)) continue; - String name = file.getName(); //name.extension.ft , e.g. "NewClass.java.ft" - @NonNls String extension = myTypeManager.getExtension(name); - name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft" - if (extension.equals("html")) { - continue; - } - if (!extension.equals(DEFAULT_TEMPLATE_EXTENSION)) { - LOG.error(file.toString() + " should have *." + DEFAULT_TEMPLATE_EXTENSION + " extension!"); - } - extension = myTypeManager.getExtension(name); - name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass" extension="java" - FileTemplate aTemplate = myTemplates.findByName(name); - if (aTemplate == null) { - FileTemplate fileTemplate = new FileTemplateImpl(file, name, extension); - myTemplates.addTemplate(fileTemplate); - aTemplate = fileTemplate; - } - VirtualFile description = getDescriptionForTemplate(file); - if (description != null) { - ((FileTemplateImpl)aTemplate).setDescription(description); - } - /*else{ - ((FileTemplateImpl)aTemplate).setDescription(myDefaultDescription); - }*/ - } - FileTemplate[] allTemplates = myTemplates.getAllTemplates(); - for (FileTemplate template : allTemplates) { - FileTemplateImpl templateImpl = (FileTemplateImpl)template; - if (!templateImpl.isDefault()) { - if (!existingTemplates.contains(templateImpl)) { - if (!templateImpl.isNew()) { - myTemplates.removeTemplate(templateImpl); - templateImpl.removeFromDisk(); - } - } - } - } - } - - - private void saveTemplates() { - try { - if (myTemplates != null) { - for (FileTemplate template : myTemplates.getAllTemplates()) { - FileTemplateImpl templateImpl = (FileTemplateImpl)template; - if (templateImpl.isModified()) { - templateImpl.writeExternal(getParentDirectory(true)); - } - } - } - for (FileTemplateManagerImpl child : myChildren) { - child.saveTemplates(); - } - } - catch (IOException e) { - LOG.error("Unable to save templates", e); - } - } - @NotNull public Collection getRecentNames() { - ensureTemplatesAreLoaded(); - synchronized (LOCK) { - validateRecentNames(); - return myRecentList.getRecentNames(RECENT_TEMPLATES_SIZE); - } + validateRecentNames(); // todo: no need to do it lazily + return myRecentList.getRecentNames(RECENT_TEMPLATES_SIZE); } public void addRecentName(@NotNull @NonNls String name) { - synchronized (LOCK) { - myRecentList.addName(name); - } + myRecentList.addName(name); } public void readExternal(Element element) throws InvalidDataException { - Element deletedTemplatesElement = element.getChild(ELEMENT_DELETED_TEMPLATES); - if (deletedTemplatesElement != null) { - myDeletedTemplatesManager.readExternal(deletedTemplatesElement); - } - - Element deletedIncludesElement = element.getChild(ELEMENT_DELETED_INCLUDES); - if (deletedIncludesElement != null) { - myPatternsManager.myDeletedTemplatesManager.readExternal(deletedIncludesElement); - } - - Element recentElement = element.getChild(ELEMENT_RECENT_TEMPLATES); + final Element recentElement = element.getChild(ELEMENT_RECENT_TEMPLATES); if (recentElement != null) { myRecentList.readExternal(recentElement); } - Element templatesElement = element.getChild(ELEMENT_TEMPLATES); - if (templatesElement != null) { - invalidate(); - List children = templatesElement.getChildren(); - notAdjusted.clear(); - for (final Object aChildren : children) { - Element child = (Element)aChildren; - String name = child.getAttributeValue(ATTRIBUTE_NAME); - boolean reformat = Boolean.TRUE.toString().equals(child.getAttributeValue(ATTRIBUTE_REFORMAT)); - if (!reformat) { - notAdjusted.add(name); + for (final FTManager manager : myAllManagers) { + final Element templatesGroup = element.getChild(getXmlElementGroupName(manager)); + if (templatesGroup == null) { + continue; + } + final List children = element.getChildren(ELEMENT_TEMPLATE); + + for (final Object elem : children) { + final Element child = (Element)elem; + final String qName = child.getAttributeValue(ATTRIBUTE_NAME); + final FileTemplateBase template = manager.getTemplate(qName); + if (template == null) { + continue; + } + final boolean reformat = Boolean.TRUE.toString().equals(child.getAttributeValue(ATTRIBUTE_REFORMAT)); + template.setReformatCode(reformat); + if (template instanceof BundledFileTemplate) { + final boolean enabled = Boolean.getBoolean(child.getAttributeValue(ATTRIBUTE_REFORMAT)); + ((BundledFileTemplate)template).setEnabled(enabled); } } } + + //Element deletedTemplatesElement = element.getChild(ELEMENT_DELETED_TEMPLATES); + //if (deletedTemplatesElement != null) { + // myDefaultTemplatesManager.getDeletedTemplates().readExternal(deletedTemplatesElement); + //} + // + //Element deletedIncludesElement = element.getChild(ELEMENT_DELETED_INCLUDES); + //if (deletedIncludesElement != null) { + // myPatternsManager.getDeletedTemplates().readExternal(deletedIncludesElement); + //} + // + //Element recentElement = element.getChild(ELEMENT_RECENT_TEMPLATES); + //if (recentElement != null) { + // myRecentList.readExternal(recentElement); + //} + // + //Element templatesElement = element.getChild(ELEMENT_TEMPLATES); + //if (templatesElement != null) { + // myDefaultTemplatesManager.invalidate(); + // List children = templatesElement.getChildren(); + // myDefaultTemplatesManager.resetNotAdjusted(); + // for (final Object aChildren : children) { + // Element child = (Element)aChildren; + // String name = child.getAttributeValue(ATTRIBUTE_NAME); + // boolean reformat = Boolean.TRUE.toString().equals(child.getAttributeValue(ATTRIBUTE_REFORMAT)); + // if (!reformat) { + // myDefaultTemplatesManager.setNotAdjusted(name); + // } + // } + //} + } + + private static String getXmlElementGroupName(FTManager manager) { + return manager.getName().toLowerCase(Locale.US) + "_" + "templates"; } public void writeExternal(Element element) throws WriteExternalException { - saveTemplates(); + for (FTManager child : myAllManagers) { + child.saveTemplates(); + } validateRecentNames(); - - Element deletedTemplatesElement = new Element(ELEMENT_DELETED_TEMPLATES); - element.addContent(deletedTemplatesElement); - myDeletedTemplatesManager.writeExternal(deletedTemplatesElement); - - Element deletedIncludesElement = new Element(ELEMENT_DELETED_INCLUDES); - element.addContent(deletedIncludesElement); - myPatternsManager.myDeletedTemplatesManager.writeExternal(deletedIncludesElement); - - Element recentElement = new Element(ELEMENT_RECENT_TEMPLATES); + final Element recentElement = new Element(ELEMENT_RECENT_TEMPLATES); element.addContent(recentElement); myRecentList.writeExternal(recentElement); - Element templatesElement = new Element(ELEMENT_TEMPLATES); - element.addContent(templatesElement); - invalidate(); - FileTemplate[] internals = getInternalTemplates(); - for (FileTemplate internal : internals) { - templatesElement.addContent(createElement(internal, true)); - } - - FileTemplate[] allTemplates = getAllTemplates(); - for (FileTemplate fileTemplate : allTemplates) { - templatesElement.addContent(createElement(fileTemplate, false)); + for (FTManager manager : myAllManagers) { + final Element templatesGroup = new Element(getXmlElementGroupName(manager)); + element.addContent(templatesGroup); + for (FileTemplateBase template : manager.getAllTemplates(true)) { + // save only those settings that differ from defaults + boolean shouldSave = template.isReformatCode() != FileTemplateBase.DEFAULT_REFORMAT_CODE_VALUE; + if (template instanceof BundledFileTemplate) { + shouldSave |= ((BundledFileTemplate)template).isEnabled() != FileTemplateBase.DEFAULT_ENABLED_VALUE; + } + if (!shouldSave) { + continue; + } + final Element templateElement = new Element(ELEMENT_TEMPLATE); + templateElement.setAttribute(ATTRIBUTE_NAME, template.getQualifiedName()); + templateElement.setAttribute(ATTRIBUTE_REFORMAT, Boolean.toString(template.isReformatCode())); + if (template instanceof BundledFileTemplate) { + templateElement.setAttribute(ATTRIBUTE_ENABLED, Boolean.toString(((BundledFileTemplate)template).isEnabled())); + } + templatesGroup.addContent(templateElement); + } } + //Element deletedTemplatesElement = new Element(ELEMENT_DELETED_TEMPLATES); + //element.addContent(deletedTemplatesElement); + //myDefaultTemplatesManager.getDeletedTemplates().writeExternal(deletedTemplatesElement); + // + //Element deletedIncludesElement = new Element(ELEMENT_DELETED_INCLUDES); + //element.addContent(deletedIncludesElement); + //myPatternsManager.getDeletedTemplates().writeExternal(deletedIncludesElement); + // + //Element recentElement = new Element(ELEMENT_RECENT_TEMPLATES); + //element.addContent(recentElement); + //myRecentList.writeExternal(recentElement); + // + //Element templatesElement = new Element(ELEMENT_TEMPLATES); + //element.addContent(templatesElement); + //myDefaultTemplatesManager.invalidate(); + // + //for (FileTemplate internal : getInternalTemplates()) { + // templatesElement.addContent(createElement(internal, true)); + //} + // + //for (FileTemplate fileTemplate : getAllTemplates()) { + // templatesElement.addContent(createElement(fileTemplate, false)); + //} } - private static Element createElement(FileTemplate template, boolean isInternal) { - Element templateElement = new Element(isInternal ? ELEMENT_INTERNAL_TEMPLATE : ELEMENT_TEMPLATE); - templateElement.setAttribute(ATTRIBUTE_NAME, template.getName()); - templateElement.setAttribute(ATTRIBUTE_REFORMAT, Boolean.toString(template.isAdjust())); - return templateElement; - } + //private static Element createElement(FileTemplate template, boolean isInternal) { + // Element templateElement = new Element(isInternal ? ELEMENT_INTERNAL_TEMPLATE : ELEMENT_TEMPLATE); + // templateElement.setAttribute(ATTRIBUTE_NAME, template.getName()); + // templateElement.setAttribute(ATTRIBUTE_REFORMAT, Boolean.toString(template.isReformatCode())); + // return templateElement; + //} private void validateRecentNames() { - if (myTemplates != null) { - List allNames = new ArrayList(myTemplates.size()); - FileTemplate[] allTemplates = myTemplates.getAllTemplates(); - for (FileTemplate fileTemplate : allTemplates) { - allNames.add(fileTemplate.getName()); - } - myRecentList.validateNames(allNames); - } - } - - private void invalidate() { - synchronized (LOCK) { - saveAll(); - myLoaded = false; - if (myTemplates != null) { - FileTemplate[] allTemplates = myTemplates.getAllTemplates(); - for (FileTemplate template : allTemplates) { - ((FileTemplateImpl)template).invalidate(); - } - } + final Collection allTemplates = myDefaultTemplatesManager.getAllTemplates(false); + final List allNames = new ArrayList(allTemplates.size()); + for (FileTemplate fileTemplate : allTemplates) { + allNames.add(fileTemplate.getName()); } + myRecentList.validateNames(allNames); } public void saveAll() { - synchronized (LOCK) { - saveTemplates(); - } + myDefaultTemplatesManager.saveTemplates(); } @NotNull @@ -525,31 +485,26 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo } public FileTemplate getInternalTemplate(@NotNull @NonNls String templateName) { - synchronized (LOCK) { - LOG.assertTrue(myInternalTemplatesManager != null); + LOG.assertTrue(myInternalTemplatesManager != null); + FileTemplateBase template = myInternalTemplatesManager.findTemplateByName(templateName); - FileTemplateImpl template = (FileTemplateImpl)myInternalTemplatesManager.getTemplate(templateName); - - if (template == null) { - template = (FileTemplateImpl)getTemplate(templateName); - } - - if (template == null) { - template = (FileTemplateImpl)getJ2eeTemplate(templateName); // Hack to be able to register class templates from the plugin. - if (template != null) { - template.setAdjust(true); - } - else { - String text = normalizeText(getDefaultClassTemplateText(templateName)); - - template = (FileTemplateImpl)myInternalTemplatesManager.addTemplate(templateName, "java"); - template.setText(text); - } - } - - template.setInternal(true); - return template; + if (template == null) { + // todo: review the hack and try to get rid of this weird logic completely + template = myDefaultTemplatesManager.findTemplateByName(templateName); } + + if (template == null) { + template = (FileTemplateBase)getJ2eeTemplate(templateName); // Hack to be able to register class templates from the plugin. + if (template != null) { + template.setReformatCode(true); + } + else { + final String text = normalizeText(getDefaultClassTemplateText(templateName)); + template = myInternalTemplatesManager.addTemplate(templateName, "java"); + template.setText(text); + } + } + return template; } private static String normalizeText(String text) { @@ -597,382 +552,108 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo return getTemplateFromManager(templateName, myJ2eeTemplatesManager); } - private static FileTemplate getTemplateFromManager(@NotNull @NonNls String templateName, @NotNull FileTemplateManagerImpl templatesManager) { - String name = templateName; - String extension = templatesManager.myTypeManager.getExtension(name); - if (extension.length() > 0) { - name = name.substring(0, name.length() - extension.length() - 1); - } - FileTemplate template = templatesManager.getTemplate(name); + @Nullable + private static FileTemplate getTemplateFromManager(final @NotNull String templateName, final @NotNull FTManager ftManager) { + FileTemplateBase template = ftManager.getTemplate(templateName); if (template != null) { - if (extension.equals(template.getExtension())) { - return template; - } + return template; } - else { - if (ApplicationManager.getApplication().isUnitTestMode() && templateName.endsWith("ForTest")) return null; - - String message = templatesManager.templateNotFoundMessage(templateName); - LOG.error(message); + template = ftManager.findTemplateByName(templateName); + if (template != null) { + return template; } - return null; - } - - private String templateNotFoundMessage(String templateName) { - Collection defaultTemplates = getDefaultTemplates(); - @NonNls String message = - "Unable to find template '" + templateName + "' in " + this + - "\n Default templates are: " + toString(defaultTemplates); - message+= "\n Default template dir: '"+ myDefaultTemplatesDir+"'"; - for (VirtualFile topDir : getTopTemplatesDir()) { - VirtualFile parentDir = myDefaultTemplatesDir.equals(".") ? topDir : topDir.findChild(myDefaultTemplatesDir); - if (parentDir == null) { - message += "\n No templates in '" + topDir.getPath() + "'"; - } - else { - message += "\n " + parentDir.getPath() + ": " + toString(listDir(parentDir)); - } - } - - message += "\n Deleted templates: " + myDeletedTemplatesManager.DELETED_DEFAULT_TEMPLATES; - - return message; - } - - private static String toString(Collection defaultTemplates) { - return StringUtil.join(defaultTemplates, new Function() { - public String fun(VirtualFile virtualFile) { - return virtualFile.getPresentableUrl(); - } - }, ", "); - } - - - @SuppressWarnings({"HardCodedStringLiteral"}) - private VirtualFile getDescriptionForTemplate(VirtualFile vfile) { - if (vfile != null) { - VirtualFile parent = vfile.getParent(); - assert parent != null; - String name = vfile.getName(); //name.extension.ft , f.e. "NewClass.java.ft" - String extension = myTypeManager.getExtension(name); - if (extension.equals(DEFAULT_TEMPLATE_EXTENSION)) { - name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft" - - Locale locale = Locale.getDefault(); - String descName = MessageFormat.format("{0}_{1}_{2}.html", name, locale.getLanguage(), locale.getCountry()); - VirtualFile descFile = parent.findChild(descName); - if (descFile != null && descFile.isValid()) { - return descFile; - } - - descName = MessageFormat.format("{0}_{1}.html", name, locale.getLanguage()); - descFile = parent.findChild(descName); - if (descFile != null && descFile.isValid()) { - return descFile; - } - - descFile = parent.findChild(name + ".html"); - if (descFile != null && descFile.isValid()) { - return descFile; - } - } - } - return null; - } - - private static List listDir(VirtualFile vfile) { - List result = new ArrayList(); - if (vfile != null && vfile.isDirectory()) { - VirtualFile[] children = vfile.getChildren(); - for (VirtualFile child : children) { - if (!child.isDirectory()) { - result.add(child); - } - } - } - return result; - } - - private void removeDeletedTemplates(Set files) { - Iterator iterator = files.iterator(); - while (iterator.hasNext()) { - VirtualFile file = iterator.next(); - String nameWithExtension = file.getName(); - if (myDeletedTemplatesManager.contains(nameWithExtension)) { - iterator.remove(); - } - } - } - - private static VirtualFile getDefaultFromManager(@NotNull @NonNls String name, - @NotNull @NonNls String extension, - @NotNull FileTemplateManagerImpl manager) { - Collection files = manager.getDefaultTemplates(); - for (VirtualFile file : files) { - if (DEFAULT_TEMPLATE_EXTENSION.equals(file.getExtension())) { - String fullName = file.getNameWithoutExtension(); //Strip .ft - if (fullName.equals(name + "." + extension)) return file; - } - } - return null; - } - - public VirtualFile getDefaultTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { - VirtualFile result; - if ((result = getDefaultFromManager(name, extension, this)) != null) return result; - for (FileTemplateManagerImpl child : myChildren) { - if ((result = getDefaultFromManager(name, extension, child)) != null) return result; - } - return null; - } - - @NotNull - public FileTemplate getDefaultTemplate(@NotNull @NonNls String name) { - @NonNls String extension = myTypeManager.getExtension(name); - String nameWithoutExtension = StringUtil.trimEnd(name, "." + extension); - if (extension.length() == 0) { - extension = "java"; - } - VirtualFile file = getDefaultTemplate(nameWithoutExtension, extension); - if (file == null) { - String message = ""; - for (FileTemplateManagerImpl child : ArrayUtil.append(myChildren,this)) { - message += child.templateNotFoundMessage(name) + "\n"; - } - LOG.error(message); + if (templateName.endsWith("ForTest") && ApplicationManager.getApplication().isUnitTestMode()) { return null; } - return new FileTemplateImpl(file, nameWithoutExtension, extension); + + String message = "Template not found: " + templateName/*ftManager.templateNotFoundMessage(templateName)*/; + LOG.error(message); + return null; } @NotNull - private Collection getDefaultTemplates() { - LOG.assertTrue(!StringUtil.isEmpty(myDefaultTemplatesDir), myDefaultTemplatesDir); - VirtualFile[] topDirs = getTopTemplatesDir(); - if (LOG.isDebugEnabled()) { - @NonNls String message = "Top dirs found: "; - for (int i = 0; i < topDirs.length; i++) { - VirtualFile topDir = topDirs[i]; - message += (i > 0 ? ", " : "") + topDir.getPresentableUrl(); - } - LOG.debug(message); - } - Set templatesList = new THashSet(); - for (VirtualFile topDir : topDirs) { - final VirtualFile parentDir; - if (myDefaultTemplatesDir.equals(".")) { - parentDir = topDir; - } - else { - final ApplicationEx app = (ApplicationEx)ApplicationManager.getApplication(); - if (topDir instanceof NewVirtualFile && (!app.holdsReadLock() || app.isDispatchThread())) { - // need dispatch-thread-check because sync refresh in non-awt thread may cause deadlock - parentDir = ((NewVirtualFile)topDir).refreshAndFindChild(myDefaultTemplatesDir); - } - else { - parentDir = topDir.findChild(myDefaultTemplatesDir); - } - } - if (parentDir != null) { - templatesList.addAll(listDir(parentDir)); + public FileTemplate getDefaultTemplate(final @NotNull String name) { + final String templateQName = myTypeManager.getExtension(name).isEmpty()? FileTemplateBase.getQualifiedName(name, "java") : name; + + for (FTManager manager : myAllManagers) { + final FileTemplateBase template = manager.getTemplate(templateQName); + if (template instanceof BundledFileTemplate) { + final BundledFileTemplate copy = ((BundledFileTemplate)template).clone(); + copy.revertToDefaults(); + return copy; } } - removeDeletedTemplates(templatesList); - - return templatesList; - } - - private static void refreshTopDirs() { - synchronized (TOP_DIRS_LOCK) { - if (ourTopDirs != null) { - for (VirtualFile dir : ourTopDirs) { - if (!dir.exists()) { - ourTopDirs = null; - break; - } - } - } - } - } - - @NotNull - private static VirtualFile[] getTopTemplatesDir() { - synchronized (TOP_DIRS_LOCK) { - if (ourTopDirs != null) { - return ourTopDirs; - } - - Set dirList = new THashSet(); - - PluginDescriptor[] plugins = ApplicationManager.getApplication().getPlugins(); - for (PluginDescriptor plugin : plugins) { - if (plugin instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)plugin).isEnabled()) { - final ClassLoader loader = plugin.getPluginClassLoader(); - if (loader instanceof PluginClassLoader && ((PluginClassLoader)loader).getUrls().isEmpty()) { - continue; // development mode, when IDEA_CORE's loader contains all the classpath - } - appendDefaultTemplatesDirFromClassloader(loader, dirList); - } - } - - ourTopDirs = VfsUtil.toVirtualFileArray(dirList); - for (VirtualFile topDir : ourTopDirs) { - topDir.refresh(true,true); - } - return ourTopDirs; - } - } - - private static void appendDefaultTemplatesDirFromClassloader(ClassLoader classLoader, Set dirList) { - try { - Enumeration systemResources = classLoader.getResources(DEFAULT_TEMPLATES_TOP_DIR); - if (systemResources != null && systemResources.hasMoreElements()) { - Set urls = new HashSet(); - while (systemResources.hasMoreElements()) { - URL nextURL = (URL)systemResources.nextElement(); - if (!urls.contains(nextURL)) { - urls.add(nextURL); - String vfUrl = VfsUtil.convertFromUrl(nextURL); - VirtualFile dir = VirtualFileManager.getInstance().refreshAndFindFileByUrl(vfUrl); - if (dir == null) { - LOG.error("Cannot find file by URL: " + nextURL); - } - else { - if (LOG.isDebugEnabled()) { - LOG.debug("Top directory: " + dir.getPresentableUrl()); - } - dirList.add(dir); - } - } - } - } - } - catch (IOException e) { - LOG.error(e); - } + + String message = "Default template not found: " + name; + LOG.error(message); + return null; } @NotNull public FileTemplate[] getAllPatterns() { - return myPatternsManager.getAllTemplates(); + final Collection allTemplates = myPatternsManager.getAllTemplates(false); + return allTemplates.toArray(new FileTemplate[allTemplates.size()]); } - public FileTemplate getPattern(@NotNull @NonNls String name) { - return myPatternsManager.getTemplate(name); + public FileTemplate getPattern(@NotNull String name) { + return myPatternsManager.findTemplateByName(name); } - public FileTemplate addPattern(@NotNull @NonNls String name, @NotNull @NonNls String extension) { - LOG.assertTrue(myPatternsManager != null); - return myPatternsManager.addTemplate(name, extension); - } + //public FileTemplate addPattern(@NotNull @NonNls String name, @NotNull @NonNls String extension) { + // LOG.assertTrue(myPatternsManager != null); + // return myPatternsManager.addTemplate(name, extension); + //} - public void removePattern(@NotNull FileTemplate template, boolean fromDiskOnly) { - LOG.assertTrue(myPatternsManager != null); - myPatternsManager.removeTemplate(template, fromDiskOnly); - } + //public void removePattern(@NotNull FileTemplate template, boolean fromDiskOnly) { + // LOG.assertTrue(myPatternsManager != null); + // myPatternsManager.removeTemplate(template, fromDiskOnly); + //} @NotNull public FileTemplate[] getAllCodeTemplates() { - LOG.assertTrue(myCodeTemplatesManager != null); - return myCodeTemplatesManager.getAllTemplates(); + final Collection templates = myCodeTemplatesManager.getAllTemplates(false); + return templates.toArray(new FileTemplate[templates.size()]); } @NotNull public FileTemplate[] getAllJ2eeTemplates() { - LOG.assertTrue(myJ2eeTemplatesManager != null); - return myJ2eeTemplatesManager.getAllTemplates(); + final Collection templates = myJ2eeTemplatesManager.getAllTemplates(false); + return templates.toArray(new FileTemplate[templates.size()]); } - @NotNull - public FileTemplate addCodeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { - LOG.assertTrue(myCodeTemplatesManager != null); - return myCodeTemplatesManager.addTemplate(name, extension); - } + //@NotNull + //public FileTemplate addCodeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { + // return myCodeTemplatesManager.addTemplate(name, extension); + //} - @NotNull - public FileTemplate addJ2eeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { - LOG.assertTrue(myJ2eeTemplatesManager != null); - return myJ2eeTemplatesManager.addTemplate(name, extension); - } + //@NotNull + //public FileTemplate addJ2eeTemplate(@NotNull @NonNls String name, @NotNull @NonNls String extension) { + // return myJ2eeTemplatesManager.addTemplate(name, extension); + //} - public void removeCodeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly) { - LOG.assertTrue(myCodeTemplatesManager != null); - myCodeTemplatesManager.removeTemplate(template, fromDiskOnly); - } + //public void removeCodeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly) { + // myCodeTemplatesManager.removeTemplate(template, fromDiskOnly); + //} + // + //public void removeJ2eeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly) { + // myJ2eeTemplatesManager.removeTemplate(template, fromDiskOnly); + //} - public void removeJ2eeTemplate(@NotNull FileTemplate template, boolean fromDiskOnly) { - LOG.assertTrue(myJ2eeTemplatesManager != null); - myJ2eeTemplatesManager.removeTemplate(template, fromDiskOnly); - } - - public VirtualFile getDefaultTemplateDescription() { - return myDefaultDescription; - } - - public VirtualFile getDefaultIncludeDescription() { - return myPatternsManager.myDefaultDescription; - } - - private static class MyTemplates { - private final List myTemplatesList = new ArrayList(); - - public int size() { - return myTemplatesList.size(); - } - - public void removeTemplate(FileTemplate template) { - myTemplatesList.remove(template); - } - - @NotNull - public FileTemplate[] getAllTemplates() { - return myTemplatesList.toArray(new FileTemplate[myTemplatesList.size()]); - } - - public FileTemplate findByName(@NotNull @NonNls String name) { - for (FileTemplate template : myTemplatesList) { - if (template.getName().equals(name)) { - return template; - } + public void setTemplates(@NotNull String templatesCategory, Collection templates) { + for (FTManager manager : myAllManagers) { + if (templatesCategory.equals(manager.getName())) { + manager.updateTemplates(templates); + break; } - return null; - } - - public void addTemplate(@NotNull FileTemplate newTemplate) { - String newName = newTemplate.getName(); - - for (FileTemplate template : myTemplatesList) { - if (template == newTemplate) { - return; - } - if (template.getName().compareToIgnoreCase(newName) > 0) { - myTemplatesList.add(myTemplatesList.indexOf(template), newTemplate); - return; - } - } - myTemplatesList.add(newTemplate); } } - private static class MyDeletedTemplatesManager implements JDOMExternalizable { - public JDOMExternalizableStringList DELETED_DEFAULT_TEMPLATES = new JDOMExternalizableStringList(); + public URL getDefaultTemplateDescription() { + return null; // todo + } - public void addName(@NotNull @NonNls String nameWithExtension) { - DELETED_DEFAULT_TEMPLATES.remove(nameWithExtension); - DELETED_DEFAULT_TEMPLATES.add(nameWithExtension); - } - - public boolean contains(@NotNull @NonNls String nameWithExtension) { - return DELETED_DEFAULT_TEMPLATES.contains(nameWithExtension); - } - - public void readExternal(Element element) throws InvalidDataException { - DefaultJDOMExternalizer.readExternal(this, element); - } - - public void writeExternal(Element element) throws WriteExternalException { - DefaultJDOMExternalizer.writeExternal(this, element); - } + public URL getDefaultIncludeDescription() { + return null; // todo } private static class RecentTemplatesManager implements JDOMExternalizable { @@ -1003,10 +684,4 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo } } - - @NonNls - @Override - public String toString() { - return myName + " file template manager"; - } } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java index fbfa2d074890..aa22513649d6 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTab.java @@ -17,12 +17,12 @@ package com.intellij.ide.fileTemplates.impl; import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.ide.fileTemplates.FileTemplateUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; @@ -30,7 +30,7 @@ import java.util.Map; * @author Alexey Kudravtsev */ abstract class FileTemplateTab { - public Map savedTemplates; + protected final java.util.List myTemplates = new ArrayList(); private final String myTitle; protected static final Color MODIFIED_FOREGROUND = new Color(0, 0, 210); @@ -49,17 +49,18 @@ abstract class FileTemplateTab { public abstract void onTemplateSelected(); public void init(FileTemplate[] templates) { - FileTemplate oldSelection = getSelectedTemplate(); + final FileTemplate oldSelection = getSelectedTemplate(); + final String oldSelectionName = oldSelection != null? ((FileTemplateBase)oldSelection).getQualifiedName() : null; + + myTemplates.clear(); FileTemplate newSelection = null; - Map templatesToSave = new LinkedHashMap(); - for (FileTemplate aTemplate : templates) { - FileTemplate copy = FileTemplateUtil.cloneTemplate(aTemplate); - templatesToSave.put(aTemplate, copy); - if (savedTemplates != null && savedTemplates.get(aTemplate) == oldSelection) { + for (FileTemplate original : templates) { + final FileTemplateBase copy = (FileTemplateBase)original.clone(); + if (oldSelectionName != null && oldSelectionName.equals(copy.getQualifiedName())) { newSelection = copy; } + myTemplates.add(copy); } - savedTemplates = templatesToSave; initSelection(newSelection); } @@ -69,7 +70,7 @@ abstract class FileTemplateTab { @NotNull public FileTemplate[] getTemplates() { - return savedTemplates.values().toArray(new FileTemplate[savedTemplates.values().size()]); + return myTemplates.toArray(new FileTemplate[myTemplates.size()]); } public abstract void addTemplate(FileTemplate newTemplate); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java index ebea3ccac46a..c548fba03d92 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsList.java @@ -76,17 +76,16 @@ abstract class FileTemplateTabAsList extends FileTemplateTab { public void removeSelected() { final FileTemplate selectedTemplate = getSelectedTemplate(); - if (selectedTemplate == null) return; - DefaultListModel model = (DefaultListModel) myList.getModel(); - int selectedIndex = myList.getSelectedIndex(); + if (selectedTemplate == null) { + return; + } + final DefaultListModel model = (DefaultListModel) myList.getModel(); + final int selectedIndex = myList.getSelectedIndex(); model.remove(selectedIndex); if (!model.isEmpty()) { myList.setSelectedIndex(Math.min(selectedIndex, model.size() - 1)); } onTemplateSelected(); -// myModified = true; -// fireListChanged(); -// onListSelectionChanged(); } private static class MyListModel extends DefaultListModel { @@ -101,14 +100,15 @@ abstract class FileTemplateTabAsList extends FileTemplateTab { protected void initSelection(FileTemplate selection) { myModel = new MyListModel(); myList.setModel(myModel); - final FileTemplate[] templates = savedTemplates.values().toArray(new FileTemplate[savedTemplates.values().size()]); - for (FileTemplate template : templates) { + for (FileTemplate template : myTemplates) { myModel.addElement(template); } if (selection != null) { selectTemplate(selection); } - else if (myList.getModel().getSize() > 0) myList.setSelectedIndex(0); + else if (myList.getModel().getSize() > 0) { + myList.setSelectedIndex(0); + } } public void fireDataChanged() { diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java index 50aba2f4af88..787fa3db923a 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTabAsTree.java @@ -19,7 +19,6 @@ package com.intellij.ide.fileTemplates.impl; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateDescriptor; import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor; -import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -65,9 +64,10 @@ abstract class FileTemplateTabAsTree extends FileTemplateTab { } protected abstract FileTemplateNode initModel(); + protected static class FileTemplateNode extends DefaultMutableTreeNode { private Icon myIcon; - private final String myTemplate; + private final String myTemplateName; FileTemplateNode(FileTemplateDescriptor descriptor) { this(descriptor.getDisplayName(), @@ -84,14 +84,14 @@ abstract class FileTemplateTabAsTree extends FileTemplateTab { this(name, icon, children, null); } - FileTemplateNode(Icon icon, String template) { - this(template, icon, Collections.emptyList(), template); + FileTemplateNode(Icon icon, String templateName) { + this(templateName, icon, Collections.emptyList(), templateName); } - private FileTemplateNode(String name, Icon icon, List children, String template) { + private FileTemplateNode(String name, Icon icon, List children, String templateName) { super(name); myIcon = icon; - myTemplate = template; + myTemplateName = templateName; for (FileTemplateNode child : children) { add(child); } @@ -101,8 +101,8 @@ abstract class FileTemplateTabAsTree extends FileTemplateTab { return myIcon; } - public String getTemplate() { - return myTemplate; + public String getTemplateName() { + return myTemplateName; } } @@ -121,7 +121,7 @@ abstract class FileTemplateTabAsTree extends FileTemplateTab { final FileTemplateNode node = (FileTemplateNode)value; setText((String) node.getUserObject()); setIcon(node.getIcon()); - setFont(getFont().deriveFont(AllFileTemplatesConfigurable.isInternalTemplate(node.getTemplate(), getTitle()) ? Font.BOLD : Font.PLAIN)); + setFont(getFont().deriveFont(AllFileTemplatesConfigurable.isInternalTemplate(node.getTemplateName(), getTitle()) ? Font.BOLD : Font.PLAIN)); final FileTemplate template = getTemplate(node); if (template != null && !template.isDefault()) { @@ -163,15 +163,25 @@ abstract class FileTemplateTabAsTree extends FileTemplateTab { @Nullable public FileTemplate getSelectedTemplate() { final TreePath selectionPath = myTree.getSelectionPath(); - if (selectionPath == null) return null; + if (selectionPath == null) { + return null; + } final FileTemplateNode node = (FileTemplateNode)selectionPath.getLastPathComponent(); return getTemplate(node); } @Nullable private FileTemplate getTemplate(final FileTemplateNode node) { - final String template = node.getTemplate(); - return template == null || savedTemplates == null ? null : savedTemplates.get(FileTemplateManager.getInstance().getJ2eeTemplate(template)); + final String templateName = node.getTemplateName(); + if (templateName == null || myTemplates.isEmpty()) { + return null; + } + for (FileTemplateBase template : myTemplates) { + if (templateName.equals(template.getQualifiedName()) || templateName.equals(template.getName())) { + return template; + } + } + return null; } public JComponent getComponent() { diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java new file mode 100644 index 000000000000..48c6c0a204a1 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java @@ -0,0 +1,120 @@ +/* + * Copyright 2000-2011 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.ide.fileTemplates.impl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.URLUtil; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * @author Eugene Zhuravlev + * Date: 3/25/11 + */ +class UrlUtil { + private static final String JAR_SEPARATOR = "!/"; + private static final String URL_PATH_SEPARATOR = "/"; + private static final String FILE_PROTOCOL = "file"; + private static final String FILE_PROTOCOL_PREFIX = FILE_PROTOCOL + ":"; + private static final String JAR_PROTOCOL = "jar"; + private static final String JAR_PROTOCOL_PREFIX = JAR_PROTOCOL + ":"; + + public static String loadText(URL url) throws IOException { + final InputStream stream = new BufferedInputStream(URLUtil.openStream(url)); + try { + return new String(FileUtil.loadBytes(stream), FileTemplate.ourEncoding); + } + finally { + stream.close(); + } + } + + public static List getChildrenRelativePaths(URL root) throws IOException { + final String protocol = root.getProtocol(); + if ("jar".equalsIgnoreCase(protocol)) { + return getChildPathsFromJar(root); + } + if ("file".equalsIgnoreCase(protocol)){ + return getChildPathsFromFile(root); + } + return Collections.emptyList(); + } + + private static List getChildPathsFromFile(URL root) { + final List paths = new ArrayList(); + final File rootFile = new File(root.getPath()); + new Object() { + void collectFiles(File fromFile, String prefix) { + final File[] list = fromFile.listFiles(); + if (list != null) { + for (File file : list) { + final String childRelativePath = prefix.length() == 0 ? file.getName() : prefix + URL_PATH_SEPARATOR + file.getName(); + if (file.isDirectory()) { + collectFiles(file, childRelativePath); + } + else { + paths.add(childRelativePath); + } + } + } + } + }.collectFiles(rootFile, ""); + return paths; + } + + private static List getChildPathsFromJar(URL root) throws IOException { + final List paths = new ArrayList(); + String file = root.getFile(); + if (file.startsWith(FILE_PROTOCOL_PREFIX)) { + file = file.substring(FILE_PROTOCOL_PREFIX.length()); + } + final int jarSeparatorIndex = file.indexOf(JAR_SEPARATOR); + assert jarSeparatorIndex > 0; + + String rootDirName = file.substring(jarSeparatorIndex + 2); + if (!rootDirName.endsWith(URL_PATH_SEPARATOR)) { + rootDirName += URL_PATH_SEPARATOR; + } + final ZipFile zipFile = new ZipFile(FileUtil.unquote(file.substring(0, jarSeparatorIndex))); + try { + final Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + final ZipEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + final String relPath = entry.getName(); + if (relPath.startsWith(rootDirName)) { + paths.add(relPath.substring(rootDirName.length())); + } + } + } + return paths; + } + finally { + zipFile.close(); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java index 9fbf32255e04..4a22227d958a 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/CreateFromTemplateDialog.java @@ -22,6 +22,7 @@ import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.fileTemplates.FileTemplateUtil; import com.intellij.ide.fileTemplates.actions.AttributesDefaults; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; @@ -74,7 +75,7 @@ public class CreateFromTemplateDialog extends DialogWrapper { } if (unsetAttributes != null) { - myAttrPanel = new CreateFromTemplatePanel(unsetAttributes, !myTemplate.isJavaClassTemplate(), attributesDefaults); + myAttrPanel = new CreateFromTemplatePanel(unsetAttributes, !myTemplate.isTemplateOfType(StdFileTypes.JAVA), attributesDefaults); myAttrComponent = myAttrPanel.getComponent(); init(); } @@ -124,7 +125,7 @@ public class CreateFromTemplateDialog extends DialogWrapper { } private String getErrorMessage() { - return myTemplate.isJavaClassTemplate() ? IdeBundle.message("title.cannot.create.class") : IdeBundle.message("title.cannot.create.file"); + return myTemplate.isTemplateOfType(StdFileTypes.JAVA) ? IdeBundle.message("title.cannot.create.class") : IdeBundle.message("title.cannot.create.file"); } @Nullable diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index d37c91b955f4..b3b50b511025 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -121,14 +121,8 @@ tab.filetemplates.templates=Templates tab.filetemplates.includes=Includes tab.filetemplates.code=Code tab.filetemplates.j2ee=Java EE -error.please.specify.a.name.for.this.template=Please specify a name for this template -title.template.name.not.specified=Template Name Not Specified error.please.specify.template.name=Please specify template name -error.please.specify.a.different.name.for.this.template=Please specify a different name for this template -title.template.already.exists=Template already exists error.template.with.such.name.already.exists=Template with such name already exists. Please specify a different template name -error.please.specify.extension=Please specify an extension for this template -title.template.extension.not.specified=Template Extension Not Specified title.cannot.save.current.template=Cannot save current template error.please.specify.template.extension=Please specify template extension action.create.template=Create Template diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java index 2fb1e670fcde..779ee52fec84 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java @@ -56,13 +56,13 @@ public class GroovyMoveClassTest extends LightCodeInsightFixtureTestCase { super.setUp(); final FileTemplateManager templateManager = FileTemplateManager.getInstance(); FileTemplate temp = templateManager.getTemplate("GroovyClass.groovyForTest"); - if (temp != null) templateManager.removeTemplate(temp, false); + if (temp != null) templateManager.removeTemplate(temp); temp = templateManager.addTemplate("GroovyClass.groovyForTest", "groovy"); temp.setText("#if ( $PACKAGE_NAME != \"\" )package ${PACKAGE_NAME}\n" + "#end\n" + "class ${NAME} {\n" + "}"); temp = templateManager.getTemplate("GroovyClass.groovy"); - if (temp != null) templateManager.removeTemplate(temp, false); + if (temp != null) templateManager.removeTemplate(temp); temp = templateManager.addTemplate("GroovyClass.groovy", "groovy"); temp.setText("#if ( $PACKAGE_NAME != \"\" )package ${PACKAGE_NAME}\n" + "#end\n" + "class ${NAME} {\n" + "}"); @@ -72,10 +72,10 @@ public class GroovyMoveClassTest extends LightCodeInsightFixtureTestCase { protected void tearDown() throws Exception { final FileTemplateManager templateManager = FileTemplateManager.getInstance(); FileTemplate temp = templateManager.getTemplate("GroovyClass.groovy"); - templateManager.removeTemplate(temp, false); + templateManager.removeTemplate(temp); temp = templateManager.getTemplate("GroovyClass.groovyForTest"); - templateManager.removeTemplate(temp, false); + templateManager.removeTemplate(temp); super.tearDown(); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java index 754fd63060fe..1910a15d7013 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java @@ -60,7 +60,7 @@ public class CreateFormAction extends AbstractCreateFormAction { final FileTemplate template = manager.getTemplate("GUI Form"); //noinspection HardCodedStringLiteral if (template != null && template.getExtension().equals("form")) { - manager.removeTemplate(template, false); + manager.removeTemplate(template); } } }); From 9ac06e8cfdca98e6ace266ed13782080bad1ee1a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sat, 9 Apr 2011 19:00:35 +0200 Subject: [PATCH 09/16] support settings in older format --- .../impl/FileTemplateManagerImpl.java | 171 ++++++++++++------ 1 file changed, 111 insertions(+), 60 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index b1a72fe9faa3..db3c77826d93 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -119,22 +119,18 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo loadCustomizedContent(child); } - // todo: do something with this hack - //if (ApplicationManager.getApplication().isUnitTestMode()) { - // for (String tname : Arrays.asList("Class", "AnnotationType", "Enum", "Interface")) { - // for (FileTemplate template : getAllTemplates()) { - // if (tname.equals(template.getName())) { - // myInternalTemplatesManager.getTemplateContainer().removeTemplate(template); - // break; - // } - // } - // FileTemplateImpl fileTemplate = new FileTemplateImpl(normalizeText(getTestClassTemplateText(tname)), tname, "java"); - // fileTemplate.setReadOnly(true); - // fileTemplate.setModified(false); - // myInternalTemplatesManager.getTemplateContainer().addTemplate(fileTemplate); - // fileTemplate.setInternal(true); - // } - //} + if (ApplicationManager.getApplication().isUnitTestMode()) { + for (String tname : Arrays.asList("Class", "AnnotationType", "Enum", "Interface")) { + for (FileTemplate template : myInternalTemplatesManager.getAllTemplates(true)) { + if (tname.equals(template.getName())) { + myInternalTemplatesManager.removeTemplate(((FileTemplateBase)template).getQualifiedName()); + break; + } + } + final FileTemplateBase template = myInternalTemplatesManager.addTemplate(tname, "java"); + template.setText(normalizeText(getTestClassTemplateText(tname))); + } + } } @@ -202,33 +198,52 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo if (configFiles == null) { return; } + + final List oldFormatTemplates = new ArrayList(); + final Set processedNames = new HashSet(); + for (File file : configFiles) { if (file.isDirectory() || myTypeManager.isFileIgnored(file.getName()) || file.isHidden()) { continue; } String name = file.getName(); if (!name.endsWith(FTManager.TEMPLATE_EXTENSION_SUFFIX)) { + oldFormatTemplates.add(file); continue; } // cut default template extension name = name.substring(0, name.length() - FTManager.TEMPLATE_EXTENSION_SUFFIX.length()); - - final String extension = myTypeManager.getExtension(name); - name = name.substring(0, name.length() - extension.length() - 1); - if (name.length() == 0) { - continue; - } - try { - final String text = FileUtil.loadFile(file, FTManager.CONTENT_ENCODING); - manager.addTemplate(name, extension).setText(text); - } - catch (IOException e) { - LOG.error(e); + processedNames.add(name); + + addTemplateFromFile(manager, name, file); + } + + for (File oldFile : oldFormatTemplates) { + final String name = oldFile.getName(); + if (!processedNames.contains(name)) { + addTemplateFromFile(manager, name, oldFile); } + FileUtil.delete(oldFile); } } - + + private void addTemplateFromFile(FTManager manager, String templateQName, File file) { + final String extension = myTypeManager.getExtension(templateQName); + templateQName = templateQName.substring(0, templateQName.length() - extension.length() - 1); + if (templateQName.length() == 0) { + return; + } + try { + final String text = FileUtil.loadFile(file, FTManager.CONTENT_ENCODING); + manager.addTemplate(templateQName, extension).setText(text); + } + catch (IOException e) { + LOG.error(e); + } + } + //Example: templateName="NewClass" templateExtension="java" + @Nullable private static String getDescriptionPath(String pathPrefix, String templateName, String templateExtension, Set descriptionPaths) { final Locale locale = Locale.getDefault(); @@ -341,6 +356,33 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo myRecentList.readExternal(recentElement); } + // support older format + final DeletedTemplatesManager deletedDefaults = new DeletedTemplatesManager(); + Element deletedTemplatesElement = element.getChild(ELEMENT_DELETED_TEMPLATES); + if (deletedTemplatesElement != null) { + deletedDefaults.readExternal(deletedTemplatesElement); + } + + final DeletedTemplatesManager deletedIncludes = new DeletedTemplatesManager(); + Element deletedIncludesElement = element.getChild(ELEMENT_DELETED_INCLUDES); + if (deletedIncludesElement != null) { + deletedIncludes.readExternal(deletedIncludesElement); + } + + final Set templateNamesWithReformatOff = new HashSet(); + final Element templatesElement = element.getChild(ELEMENT_TEMPLATES); + if (templatesElement != null) { + final List children = templatesElement.getChildren(); + for (final Object child : children) { + final Element childElement = (Element)child; + boolean reformat = Boolean.TRUE.toString().equals(childElement.getAttributeValue(ATTRIBUTE_REFORMAT)); + if (!reformat) { + final String name = childElement.getAttributeValue(ATTRIBUTE_NAME); + templateNamesWithReformatOff.add(name); + } + } + } + for (final FTManager manager : myAllManagers) { final Element templatesGroup = element.getChild(getXmlElementGroupName(manager)); if (templatesGroup == null) { @@ -364,39 +406,44 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo } } - //Element deletedTemplatesElement = element.getChild(ELEMENT_DELETED_TEMPLATES); - //if (deletedTemplatesElement != null) { - // myDefaultTemplatesManager.getDeletedTemplates().readExternal(deletedTemplatesElement); - //} - // - //Element deletedIncludesElement = element.getChild(ELEMENT_DELETED_INCLUDES); - //if (deletedIncludesElement != null) { - // myPatternsManager.getDeletedTemplates().readExternal(deletedIncludesElement); - //} - // - //Element recentElement = element.getChild(ELEMENT_RECENT_TEMPLATES); - //if (recentElement != null) { - // myRecentList.readExternal(recentElement); - //} - // - //Element templatesElement = element.getChild(ELEMENT_TEMPLATES); - //if (templatesElement != null) { - // myDefaultTemplatesManager.invalidate(); - // List children = templatesElement.getChildren(); - // myDefaultTemplatesManager.resetNotAdjusted(); - // for (final Object aChildren : children) { - // Element child = (Element)aChildren; - // String name = child.getAttributeValue(ATTRIBUTE_NAME); - // boolean reformat = Boolean.TRUE.toString().equals(child.getAttributeValue(ATTRIBUTE_REFORMAT)); - // if (!reformat) { - // myDefaultTemplatesManager.setNotAdjusted(name); - // } - // } - //} + // apply data loaded from older format + final boolean hasDeletedDefaultsInOlderFormat = !deletedDefaults.DELETED_DEFAULT_TEMPLATES.isEmpty(); + final boolean hasDeletedincludesinOlderFormat = !deletedIncludes.DELETED_DEFAULT_TEMPLATES.isEmpty(); + final boolean hasTemplatesWithReformatAttibuteAltered = !templateNamesWithReformatOff.isEmpty(); + final boolean hasSettingsInOlderFormat = hasDeletedDefaultsInOlderFormat || + hasDeletedincludesinOlderFormat || + hasTemplatesWithReformatAttibuteAltered; + if (hasSettingsInOlderFormat) { + final Collection allDefaults = myDefaultTemplatesManager.getAllTemplates(true); + if (hasDeletedDefaultsInOlderFormat) { + applyDeletedState(deletedDefaults, allDefaults); + } + if (hasDeletedincludesinOlderFormat) { + applyDeletedState(deletedIncludes, myPatternsManager.getAllTemplates(true)); + } + if (hasTemplatesWithReformatAttibuteAltered) { + applyReformatState(templateNamesWithReformatOff, allDefaults); + applyReformatState(templateNamesWithReformatOff, myInternalTemplatesManager.getAllTemplates(true)); + } + } } - private static String getXmlElementGroupName(FTManager manager) { - return manager.getName().toLowerCase(Locale.US) + "_" + "templates"; + // need this to support options from older format + private static void applyReformatState(Set templateNamesWithReformatOff, Collection templates) { + for (FileTemplateBase template : templates) { + if (templateNamesWithReformatOff.contains(template.getName())) { + template.setReformatCode(false); + } + } + } + + // need this to support options from older format + private static void applyDeletedState(DeletedTemplatesManager deletedDefaults, Collection templates) { + for (FileTemplateBase template : templates) { + if (template instanceof BundledFileTemplate && deletedDefaults.contains(template.getQualifiedName())) { + ((BundledFileTemplate)template).setEnabled(false); + } + } } public void writeExternal(Element element) throws WriteExternalException { @@ -461,6 +508,10 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo // return templateElement; //} + private static String getXmlElementGroupName(FTManager manager) { + return manager.getName().toLowerCase(Locale.US) + "_" + "templates"; + } + private void validateRecentNames() { final Collection allTemplates = myDefaultTemplatesManager.getAllTemplates(false); final List allNames = new ArrayList(allTemplates.size()); From 58840087dcdc042ba3b8ba28bfff00b918ef79ca Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sat, 9 Apr 2011 19:33:36 +0200 Subject: [PATCH 10/16] fix 'enabled' attribute loading --- .../ide/fileTemplates/impl/FileTemplateManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index db3c77826d93..639df179ba01 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -400,7 +400,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo final boolean reformat = Boolean.TRUE.toString().equals(child.getAttributeValue(ATTRIBUTE_REFORMAT)); template.setReformatCode(reformat); if (template instanceof BundledFileTemplate) { - final boolean enabled = Boolean.getBoolean(child.getAttributeValue(ATTRIBUTE_REFORMAT)); + final boolean enabled = Boolean.getBoolean(child.getAttributeValue(ATTRIBUTE_ENABLED, "true")); ((BundledFileTemplate)template).setEnabled(enabled); } } From 504b6d25645dc6dd0350808e69886b5588830b21 Mon Sep 17 00:00:00 2001 From: anna Date: Sat, 9 Apr 2011 19:49:01 +0200 Subject: [PATCH 11/16] quick fix to annotate parameter @Nullable: do not suggest to annotate non project method when external annotations are disabled --- .../codeInspection/nullable/NullableStuffInspection.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java index ad128d05b993..ef36d3d08461 100644 --- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java @@ -27,8 +27,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.codeStyle.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.OverridingMethodsSearch; @@ -70,7 +69,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { public void visitMethodCallExpression(PsiMethodCallExpression expression) { if (!PsiUtil.isLanguageLevel5OrHigher(expression) || !REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD) return; final PsiMethod psiMethod = expression.resolveMethod(); - if (psiMethod != null) { + if (psiMethod != null && (psiMethod.getManager().isInProject(psiMethod) || CodeStyleSettingsManager.getInstance().getCurrentSettings().USE_EXTERNAL_ANNOTATIONS)) { final PsiParameterList parameterList = psiMethod.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); final PsiExpression[] expressions = expression.getArgumentList().getExpressions(); From e0974b0adeb67296e3a49fbd6940b88e1fa05b2b Mon Sep 17 00:00:00 2001 From: anna Date: Sat, 9 Apr 2011 20:22:45 +0200 Subject: [PATCH 12/16] introduce parameter: layout --- .../InplaceIntroduceConstantPopup.java | 2 +- .../InplaceIntroduceParameterPopup.java | 90 +++++++++++++++---- .../IntroduceParameterSettingsUI.java | 2 +- 3 files changed, 73 insertions(+), 21 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 368662305e90..6fa66246a4aa 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -226,7 +226,7 @@ public class InplaceIntroduceConstantPopup { return visibilityCombo; } - static void appendActions(final JComboBox visibilityCombo, final Project project) { + public static void appendActions(final JComboBox visibilityCombo, final Project project) { final AnAction arrow = new AnAction() { @Override public void actionPerformed(AnActionEvent e) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 1254d9567356..f377dd2186f0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -18,24 +18,31 @@ package com.intellij.refactoring.introduceParameter; import com.intellij.codeInsight.intention.impl.TypeExpression; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.util.*; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.IntroduceParameterRefactoring; import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.introduceField.InplaceIntroduceConstantPopup; import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; import com.intellij.refactoring.ui.TypeSelectorManager; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.TitlePanel; import com.intellij.usageView.UsageInfo; +import com.intellij.util.ui.UIUtil; import gnu.trove.TIntArrayList; import gnu.trove.TIntProcedure; @@ -67,6 +74,9 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { private String myParameterName; private final String myExprText; + private JComboBox myReplaceFieldsCb; + private boolean myInitialized = false; + InplaceIntroduceParameterPopup(final Project project, final Editor editor, @@ -95,30 +105,78 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { myWholePanel = new JPanel(new GridBagLayout()); myWholePanel.setBorder(null); final GridBagConstraints gc = - new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); final TitlePanel titlePanel = new TitlePanel(); titlePanel.setBorder(null); titlePanel.setText(IntroduceParameterHandler.REFACTORING_NAME); + gc.gridwidth = 2; myWholePanel.add(titlePanel, gc); - gc.insets = new Insets(5, 5, 5, 0); + gc.insets = new Insets(0, 5, 0, 0); + gc.gridwidth = 1; + gc.fill = GridBagConstraints.NONE; if (myOccurrences.length > 1 && !myIsInvokedOnDeclaration) { gc.gridy++; createOccurrencesCb(gc, myWholePanel, myOccurrences.length); } - final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); - createLocalVariablePanel(gc, myWholePanel, settings); - createRemoveParamsPanel(gc, myWholePanel); - if (Util.anyFieldsWithGettersPresent(classMemberRefs)) { - gc.gridy++; - myWholePanel.add(createReplaceFieldsWithGettersPanel(), gc); - } gc.gridy++; + gc.insets.left = 5; createDelegateCb(gc, myWholePanel); + + + final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); + final JPanel rightPanel = new JPanel(new GridBagLayout()); + final GridBagConstraints rgc = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,5), 0, 0); + createLocalVariablePanel(rgc, rightPanel, settings); + createRemoveParamsPanel(rgc, rightPanel); + if (Util.anyFieldsWithGettersPresent(classMemberRefs)) { + rgc.gridy++; + rightPanel.add(createReplaceFieldsWithGettersPanel(), rgc); + } + + gc.gridx = 1; + gc.gridheight = myCbReplaceAllOccurences != null ? 3 : 2; + gc.gridy = 1; + myWholePanel.add(rightPanel, gc); } + @Override + protected JPanel createReplaceFieldsWithGettersPanel() { + final LabeledComponent component = new LabeledComponent(); + myReplaceFieldsCb = new JComboBox(new Integer[] {IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, + IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE}); + myReplaceFieldsCb.setRenderer(new ListCellRendererWrapper(myReplaceFieldsCb) { + @Override + public void customize(JList list, Integer value, int index, boolean selected, boolean hasFocus) { + switch (value) { + case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE: + setText(UIUtil.removeMnemonic(RefactoringBundle.message("do.not.replace"))); + break; + case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE: + setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.fields.inaccessible.in.usage.context"))); + break; + default: + setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.all.fields"))); + } + } + }); + myReplaceFieldsCb.setSelectedItem(JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS); + InplaceIntroduceConstantPopup.appendActions(myReplaceFieldsCb, myProject); + component.setComponent(myReplaceFieldsCb); + component.setText(RefactoringBundle.message("replace.fields.used.in.expressions.with.their.getters")); + component.getLabel().setDisplayedMnemonic('u'); + component.setLabelLocation(BorderLayout.NORTH); + component.setBorder(IdeBorderFactory.createEmptyBorder(3, 3, 2, 2)); + return component; + } + + @Override + protected int getReplaceFieldsWithGetters() { + return (Integer)myReplaceFieldsCb.getSelectedItem(); + } + void inplaceIntroduceParameter() { startIntroduceTemplate(false); } @@ -182,17 +240,11 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { @Override protected JComponent getComponent() { - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(myWholePanel, BorderLayout.CENTER); - - final JPanel wrapper = new JPanel(new BorderLayout()); - wrapper.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - if (myCanBeFinal != null) { - wrapper.add(myCanBeFinal, BorderLayout.NORTH); + if (!myInitialized) { + myInitialized = true; + myWholePanel.add(myCanBeFinal, new GridBagConstraints(0, myCbReplaceAllOccurences == null ? 2 : 3, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 5, 2, 5), 0, 0)); } - panel.add(wrapper, BorderLayout.SOUTH); - - return panel; + return myWholePanel; } @Override diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java index 21fee109fade..ee404b0bf2a3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java @@ -251,7 +251,7 @@ public abstract class IntroduceParameterSettingsUI { panel.add(myCbDeleteLocalVariable, gbConstraints); myCbDeleteLocalVariable.setSelected(settings.INTRODUCE_PARAMETER_DELETE_LOCAL_VARIABLE); - gbConstraints.insets = new Insets(4, 0, 4, 8); + gbConstraints.insets = new Insets(0, 0, 4, 8); if(myHasInitializer) { myCbUseInitializer = new StateRestoringCheckBox(); myCbUseInitializer.setText(RefactoringBundle.message("use.variable.initializer.to.initialize.parameter")); From 8e48fdaabe20ef6dd09bd1ebbee9e2bac83664b8 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sat, 9 Apr 2011 20:47:02 +0200 Subject: [PATCH 13/16] fix tests --- .../src/com/intellij/ide/fileTemplates/impl/FTManager.java | 5 +++++ .../ide/fileTemplates/impl/FileTemplateManagerImpl.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java index 8f639f9d586d..aaea2e71518c 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java @@ -128,6 +128,11 @@ class FTManager { myTemplates.put(qName, template); mySortedTemplates = null; } + else { + if (template instanceof BundledFileTemplate && !((BundledFileTemplate)template).isEnabled()) { + ((BundledFileTemplate)template).setEnabled(true); + } + } return template; } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index 639df179ba01..335c233041e2 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -98,7 +98,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo return (FileTemplateManagerImpl)ServiceManager.getService(FileTemplateManager.class); } - public FileTemplateManagerImpl(@NotNull FileTypeManagerEx typeManager, @NotNull MessageBus bus) { + public FileTemplateManagerImpl(@NotNull FileTypeManagerEx typeManager) { myTypeManager = typeManager; myDefaultTemplatesManager = new FTManager(DEFAULT_TEMPLATES_CATEGORY, ROOT_DIR); myInternalTemplatesManager = new FTManager(INTERNAL_TEMPLATES_CATEGORY, INTERNAL_DIR); From a42c1108128f2769edc672806d49f2e9651a0993 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Fri, 8 Apr 2011 23:21:01 +0400 Subject: [PATCH 14/16] 'PRODUCT_NAME' file template property is now initialized by default for all the products --- .../intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index 335c233041e2..5076f42beafd 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -326,6 +326,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo props.setProperty("MINUTE", getCalendarValue(calendar, Calendar.MINUTE)); props.setProperty("USER", SystemProperties.getUserName()); + props.setProperty("PRODUCT_NAME", ApplicationNamesInfo.getInstance().getFullProductName()); return props; } From a2de585bc8940c371d206b71b664a34585171c57 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Fri, 8 Apr 2011 23:31:56 +0400 Subject: [PATCH 15/16] typo --- .../intellij/ide/projectView/actions/MarkExcludeRootAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java index 054001b07770..f5f43948188c 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java @@ -34,7 +34,7 @@ public class MarkExcludeRootAction extends MarkRootAction { VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); String message = vFiles.length == 1 ? FileUtil.toSystemDependentName(vFiles [0].getPath()) : vFiles.length + " selected files"; final int rc = Messages.showOkCancelDialog(e.getData(PlatformDataKeys.PROJECT), - "Are you sure you would you like to exclude " + message + + "Are you sure you would like to exclude " + message + " from the project?\nYou can restore excluded folders later using the Project Structure dialog.", "Mark as Excluded", Messages.getQuestionIcon()); if (rc != 0) { From c8a38afa69c876bd6b8354a6f10ed75af6d19a6f Mon Sep 17 00:00:00 2001 From: "Eugene.Kudelevsky" Date: Mon, 11 Apr 2011 04:23:18 +0400 Subject: [PATCH 16/16] fix tests --- .../org/jetbrains/android/AndroidXmlSchemaProvider.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java b/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java index a6d5dc103ffd..943d39fc03e5 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java @@ -74,12 +74,7 @@ public class AndroidXmlSchemaProvider extends XmlSchemaProvider { public Result compute() { final URL resource = AndroidXmlSchemaProvider.class.getResource("android.xsd"); final VirtualFile fileByURL = VfsUtil.findFileByURL(resource); - XmlFile result = ApplicationManager.getApplication().runWriteAction(new Computable() { - @Override - public XmlFile compute() { - return (XmlFile)PsiManager.getInstance(module.getProject()).findFile(fileByURL).copy(); - } - }); + XmlFile result = (XmlFile)PsiManager.getInstance(module.getProject()).findFile(fileByURL).copy(); return new Result(result, PsiModificationTracker.MODIFICATION_COUNT); } }, false);