From f7916ef70a3e80b91220f11ad358a4ebffdbd216 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 10 Dec 2014 15:55:46 +0300 Subject: [PATCH] IDEA-27486 Make file templates per-project: initial --- .../impl/FileTemplateTestUtil.java | 4 +- .../ide/actions/SaveFileAsTemplateAction.java | 2 +- .../fileTemplates/FileTemplateManager.java | 25 ++- .../fileTemplates/FileTemplatesScheme.java | 52 +++++ .../impl/AllFileTemplatesConfigurable.java | 30 ++- .../fileTemplates/impl/ChangeSchemaCombo.java | 39 ++++ .../ide/fileTemplates/impl/FTManager.java | 65 +++++- .../impl/FileTemplateManagerImpl.java | 195 +++++------------- .../impl/FileTemplateTabAsList.java | 2 +- .../impl/FileTemplatesLoader.java | 56 +---- .../ui/ConfigureTemplatesDialog.java | 2 +- .../src/META-INF/LangExtensions.xml | 6 +- .../intellij/ide/LightFileTemplatesTest.java | 56 +++++ .../search/SearchableOptionsTest.java | 2 +- .../testSrc/fileTemplates/testTemplate.txt.ft | 1 + 15 files changed, 314 insertions(+), 223 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplatesScheme.java create mode 100644 platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ChangeSchemaCombo.java create mode 100644 platform/platform-tests/testSrc/com/intellij/ide/LightFileTemplatesTest.java create mode 100644 platform/platform-tests/testSrc/fileTemplates/testTemplate.txt.ft diff --git a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateTestUtil.java b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateTestUtil.java index 7dbf802c8c02..305454563ab8 100644 --- a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateTestUtil.java +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateTestUtil.java @@ -15,7 +15,6 @@ */ package com.intellij.ide.fileTemplates.impl; -import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -48,7 +47,6 @@ public class FileTemplateTestUtil { } public static void loadCustomizedContent(FTManager templateManager) { - FileTemplatesLoader loader = new FileTemplatesLoader(FileTypeManagerEx.getInstanceEx()); - loader.loadCustomizedContent(templateManager); + templateManager.loadCustomizedContent(); } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SaveFileAsTemplateAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SaveFileAsTemplateAction.java index f0d99a3a2976..1fc669bbdee4 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SaveFileAsTemplateAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SaveFileAsTemplateAction.java @@ -37,7 +37,7 @@ public class SaveFileAsTemplateAction extends AnAction{ VirtualFile file = assertNotNull(e.getData(CommonDataKeys.VIRTUAL_FILE)); String extension = assertNotNull(file.getExtension()); String nameWithoutExtension = file.getNameWithoutExtension(); - AllFileTemplatesConfigurable fileTemplateOptions = new AllFileTemplatesConfigurable(); + AllFileTemplatesConfigurable fileTemplateOptions = new AllFileTemplatesConfigurable(project); ConfigureTemplatesDialog dialog = new ConfigureTemplatesDialog(project, fileTemplateOptions); fileTemplateOptions.selectTemplatesTab(); PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); 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 ea175a559236..bfa3bc1b5089 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateManager.java @@ -18,6 +18,7 @@ package com.intellij.ide.fileTemplates; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -47,11 +48,25 @@ public abstract class FileTemplateManager{ 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); + public static FileTemplateManager getInstance(@NotNull Project project){ + return ServiceManager.getService(project, FileTemplateManager.class); } - @NotNull + /** Use {@link #getInstance(Project)} instead */ + @Deprecated + public static FileTemplateManager getInstance(){ + return getInstance(ProjectManager.getInstance().getDefaultProject()); + } + + @NotNull + public abstract FileTemplatesScheme getCurrentScheme(); + + public abstract void setCurrentScheme(@NotNull FileTemplatesScheme scheme); + + @NotNull + public abstract FileTemplatesScheme getProjectScheme(); + + @NotNull public abstract FileTemplate[] getAllTemplates(); public abstract FileTemplate getTemplate(@NotNull @NonNls String templateName); @@ -100,11 +115,15 @@ public abstract class FileTemplateManager{ @NotNull public abstract String internalTemplateToSubject(@NotNull @NonNls String templateName); + @Deprecated @NotNull public abstract String localizeInternalTemplateName(@NotNull FileTemplate template); public abstract FileTemplate getPattern(@NotNull @NonNls String name); + /** + * Returns template with default (bundled) text. + */ @NotNull public abstract FileTemplate getDefaultTemplate(@NotNull @NonNls String name); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplatesScheme.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplatesScheme.java new file mode 100644 index 000000000000..37cad6ded0f2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplatesScheme.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.fileTemplates; + +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.options.Scheme; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * @author Dmitry Avdeev + */ +public abstract class FileTemplatesScheme implements Scheme { + + public final static FileTemplatesScheme DEFAULT = new FileTemplatesScheme("Default") { + @NotNull + @Override + public String getTemplatesDir() { + return new File(PathManager.getConfigPath(), TEMPLATES_DIR).getPath(); + } + }; + + public static final String TEMPLATES_DIR = "fileTemplates"; + + private final String myName; + + public FileTemplatesScheme(@NotNull String name) { + myName = name; + } + + @NotNull + public String getName() { + return myName; + } + + @NotNull + public abstract String getTemplatesDir(); +} 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 5f1006635c2a..ab329f0a3f3c 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 @@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.OnePixelSplitter; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.SideBorder; @@ -68,6 +69,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con private static final String CODE_TITLE = IdeBundle.message("tab.filetemplates.code"); private static final String OTHER_TITLE = IdeBundle.message("tab.filetemplates.j2ee"); + private final Project myProject; private JPanel myMainPanel; private FileTemplateTab myCurrentTab; private FileTemplateTab myTemplatesList; @@ -87,6 +89,10 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con private static final String CURRENT_TAB = "FileTemplates.CurrentTab"; private static final String SELECTED_TEMPLATE = "FileTemplates.SelectedTemplate"; + public AllFileTemplatesConfigurable(Project project) { + myProject = project; + } + private void onRemove() { myCurrentTab.removeSelected(); myModified = true; @@ -329,22 +335,34 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con group.add(removeAction); group.add(cloneAction); group.add(resetAction); + addAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myCurrentTab.getComponent()); removeAction.registerCustomShortcutSet(CommonShortcuts.getDelete(), myCurrentTab.getComponent()); myToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(); + myToolBar.setBorder(IdeBorderFactory.createEmptyBorder()); + + JPanel toolbarPanel = new JPanel(new BorderLayout()); + toolbarPanel.add(myToolBar, BorderLayout.WEST); + //JComponent schemaComponent = + // ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, new DefaultCompactActionGroup(new ChangeSchemaCombo()), true) + // .getComponent(); + //JPanel schemaPanel = new JPanel(new BorderLayout()); + //schemaPanel.add(schemaComponent, BorderLayout.EAST); + //schemaPanel.add(new JLabel("Schema:"), BorderLayout.WEST); + //toolbarPanel.add(schemaPanel, BorderLayout.EAST); + JPanel centerPanel = new JPanel(new BorderLayout()); centerPanel.add(myTabbedPane.getComponent(), BorderLayout.NORTH); - //leftPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); OnePixelSplitter splitter = new OnePixelSplitter(false, 0.3f); splitter.setFirstComponent(myLeftPanel); splitter.setSecondComponent(myEditorComponent); centerPanel.add(splitter, BorderLayout.CENTER); myMainPanel = new JPanel(new BorderLayout()); - myMainPanel.add(myToolBar, BorderLayout.NORTH); + myMainPanel.add(toolbarPanel, BorderLayout.NORTH); myMainPanel.add(centerPanel, BorderLayout.CENTER); return myMainPanel; } @@ -388,7 +406,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con return; } if (selectedValue == null) { - myEditor.setTemplate(null, FileTemplateManagerImpl.getInstanceImpl().getDefaultTemplateDescription()); + myEditor.setTemplate(null, FileTemplateManagerImpl.getInstanceImpl(myProject).getDefaultTemplateDescription()); myEditorComponent.repaint(); } else { @@ -418,10 +436,10 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con private void selectTemplate(FileTemplate template) { URL defDesc = null; if (myCurrentTab == myTemplatesList) { - defDesc = FileTemplateManagerImpl.getInstanceImpl().getDefaultTemplateDescription(); + defDesc = FileTemplateManagerImpl.getInstanceImpl(myProject).getDefaultTemplateDescription(); } else if (myCurrentTab == myIncludesList) { - defDesc = FileTemplateManagerImpl.getInstanceImpl().getDefaultIncludeDescription(); + defDesc = FileTemplateManagerImpl.getInstanceImpl(myProject).getDefaultIncludeDescription(); } if (myEditor.getTemplate() != template) { myEditor.setTemplate(template, defDesc); @@ -666,7 +684,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con public static void editCodeTemplate(@NotNull final String templateId, Project project) { final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); - final AllFileTemplatesConfigurable configurable = new AllFileTemplatesConfigurable(); + final AllFileTemplatesConfigurable configurable = new AllFileTemplatesConfigurable(project); util.editConfigurable(project, configurable, new Runnable() { @Override public void run() { diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ChangeSchemaCombo.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ChangeSchemaCombo.java new file mode 100644 index 000000000000..27bd70914cd6 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ChangeSchemaCombo.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.project.DumbAware; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author Dmitry Avdeev + */ +public class ChangeSchemaCombo extends ComboBoxAction implements DumbAware { + + public ChangeSchemaCombo() { +// getTemplatePresentation().setText(current.getName()); + } + + @NotNull + @Override + protected DefaultActionGroup createPopupActionGroup(JComponent button) { + return new DefaultActionGroup(); + } +} 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 0fad9adde99b..99edd0ea64ec 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 @@ -16,8 +16,9 @@ package com.intellij.ide.fileTemplates.impl; import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.openapi.application.PathManager; +import com.intellij.ide.fileTemplates.FileTemplatesScheme; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -37,7 +38,6 @@ import java.util.*; */ 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; @@ -46,6 +46,7 @@ class FTManager { private final String myName; private final boolean myInternal; private final String myTemplatesDir; + private FileTemplatesScheme myScheme = FileTemplatesScheme.DEFAULT; private final Map myTemplates = new HashMap(); private volatile List mySortedTemplates; private final List myDefaultTemplates = new ArrayList(); @@ -57,13 +58,17 @@ class FTManager { FTManager(@NotNull @NonNls String name, @NotNull @NonNls String defaultTemplatesDirName, boolean internal) { myName = name; myInternal = internal; - myTemplatesDir = TEMPLATES_DIR + (defaultTemplatesDirName.equals(".") ? "" : File.separator + defaultTemplatesDirName); + myTemplatesDir = defaultTemplatesDirName; } public String getName() { return myName; } + public void setScheme(FileTemplatesScheme scheme) { + myScheme = scheme; + } + @NotNull public Collection getAllTemplates(boolean includeDisabled) { List sorted = mySortedTemplates; @@ -195,6 +200,58 @@ class FTManager { return bundled; } + + void loadCustomizedContent() { + final File configRoot = getConfigRoot(false); + final File[] configFiles = configRoot.listFiles(); + if (configFiles == null) { + return; + } + + final List templateWithDefaultExtension = new ArrayList(); + final Set processedNames = new HashSet(); + + for (File file : configFiles) { + if (file.isDirectory() || FileTypeManager.getInstance().isFileIgnored(file.getName()) || file.isHidden()) { + continue; + } + final String name = file.getName(); + if (name.endsWith(FTManager.TEMPLATE_EXTENSION_SUFFIX)) { + templateWithDefaultExtension.add(file); + } + else { + processedNames.add(name); + addTemplateFromFile(name, file); + } + } + + for (File file : templateWithDefaultExtension) { + String name = file.getName(); + // cut default template extension + name = name.substring(0, name.length() - FTManager.TEMPLATE_EXTENSION_SUFFIX.length()); + if (!processedNames.contains(name)) { + addTemplateFromFile(name, file); + } + FileUtil.delete(file); + } + } + + private void addTemplateFromFile(String fileName, File file) { + Pair nameExt = FTManager.decodeFileName(fileName); + final String extension = nameExt.second; + final String templateQName = nameExt.first; + if (templateQName.length() == 0) { + return; + } + try { + final String text = FileUtil.loadFile(file, CharsetToolkit.UTF8_CHARSET); + addTemplate(templateQName, extension).setText(text); + } + catch (IOException e) { + LOG.error(e); + } + } + public void saveTemplates() { final File configRoot = getConfigRoot(true); @@ -288,7 +345,7 @@ class FTManager { } public File getConfigRoot(boolean create) { - final File templatesPath = new File(PathManager.getConfigPath(), myTemplatesDir); + final File templatesPath = myTemplatesDir.isEmpty() ? new File(myScheme.getTemplatesDir()) : new File(myScheme.getTemplatesDir(), myTemplatesDir); if (create) { final boolean created = templatesPath.mkdirs(); if (!created && !templatesPath.exists()) { 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 93b239e49831..9be88f61376b 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 @@ -19,13 +19,14 @@ package com.intellij.ide.fileTemplates.impl; import com.intellij.ide.IdeBundle; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplatesScheme; import com.intellij.ide.fileTemplates.InternalTemplateBean; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; @@ -37,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import java.io.File; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; @@ -49,19 +51,15 @@ import java.util.*; * locking policy: if the class needs to take a read or write action, the LOCK lock must be taken * _inside_, not outside of the read action */ -public class FileTemplateManagerImpl extends FileTemplateManager implements JDOMExternalizable { +public class FileTemplateManagerImpl extends FileTemplateManager { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl"); private final RecentTemplatesManager myRecentList = new RecentTemplatesManager(); - - @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"; - private final FileTypeManagerEx myTypeManager; - private final ExportableFileTemplateSettings myTemplateSettings; + private final FileTemplatesScheme myProjectScheme; + private FileTemplatesScheme myScheme = FileTemplatesScheme.DEFAULT; + private final FTManager myInternalTemplatesManager; private final FTManager myDefaultTemplatesManager; private final FTManager myPatternsManager; @@ -71,23 +69,26 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements JDOM private final URL myDefaultTemplateDescription; private final URL myDefaultIncludeDescription; - public static FileTemplateManagerImpl getInstanceImpl() { - return (FileTemplateManagerImpl)ServiceManager.getService(FileTemplateManager.class); + public static FileTemplateManagerImpl getInstanceImpl(Project project) { + return (FileTemplateManagerImpl)getInstance(project); } - public FileTemplateManagerImpl(@NotNull FileTypeManagerEx typeManager, ProjectManager pm /*need this to ensure disposal of the service _after_ project manager*/) { + public FileTemplateManagerImpl(@NotNull FileTypeManagerEx typeManager, + /*need this to ensure disposal of the service _after_ project manager*/ + @SuppressWarnings("UnusedParameters") ProjectManager pm, + final Project project) { myTypeManager = typeManager; - myTemplateSettings = ExportableFileTemplateSettings.getInstance(); - assert myTemplateSettings != null : "Can not instantiate " + ExportableFileTemplateSettings.class.getName(); + ExportableFileTemplateSettings templateSettings = ExportableFileTemplateSettings.getInstance(); + assert templateSettings != null : "Can not instantiate " + ExportableFileTemplateSettings.class.getName(); - myInternalTemplatesManager = myTemplateSettings.getInternalTemplatesManager(); - myDefaultTemplatesManager = myTemplateSettings.getDefaultTemplatesManager(); - myPatternsManager = myTemplateSettings.getPatternsManager(); - myCodeTemplatesManager = myTemplateSettings.getCodeTemplatesManager(); - myJ2eeTemplatesManager = myTemplateSettings.getJ2eeTemplatesManager(); - myAllManagers = myTemplateSettings.getAllManagers(); - myDefaultTemplateDescription = myTemplateSettings.getDefaultTemplateDescription(); - myDefaultIncludeDescription = myTemplateSettings.getDefaultIncludeDescription(); + myInternalTemplatesManager = templateSettings.getInternalTemplatesManager(); + myDefaultTemplatesManager = templateSettings.getDefaultTemplatesManager(); + myPatternsManager = templateSettings.getPatternsManager(); + myCodeTemplatesManager = templateSettings.getCodeTemplatesManager(); + myJ2eeTemplatesManager = templateSettings.getJ2eeTemplatesManager(); + myAllManagers = templateSettings.getAllManagers(); + myDefaultTemplateDescription = templateSettings.getDefaultTemplateDescription(); + myDefaultIncludeDescription = templateSettings.getDefaultIncludeDescription(); if (ApplicationManager.getApplication().isUnitTestMode()) { for (String tname : Arrays.asList("Class", "AnnotationType", "Enum", "Interface")) { @@ -102,6 +103,33 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements JDOM } } + myProjectScheme = new FileTemplatesScheme("Project") { + @NotNull + @Override + public String getTemplatesDir() { + return new File(project.getBasePath(), TEMPLATES_DIR).getPath(); + } + }; + } + + @NotNull + @Override + public FileTemplatesScheme getCurrentScheme() { + return myScheme; + } + + @Override + public void setCurrentScheme(@NotNull FileTemplatesScheme scheme) { + myScheme = scheme; + for (FTManager manager : myAllManagers) { + manager.setScheme(scheme); + } + } + + @NotNull + @Override + public FileTemplatesScheme getProjectScheme() { + return myProjectScheme; } @Override @@ -182,127 +210,6 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements JDOM myRecentList.addName(name); } - @Override - public void readExternal(Element element) throws InvalidDataException { - final Element recentElement = element.getChild(ELEMENT_RECENT_TEMPLATES); - if (recentElement != null) { - 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(ExportableFileTemplateSettings.ATTRIBUTE_REFORMAT)); - if (!reformat) { - final String name = childElement.getAttributeValue(ExportableFileTemplateSettings.ATTRIBUTE_NAME); - templateNamesWithReformatOff.add(name); - } - } - } - - if (!myTemplateSettings.isLoaded()) { - myTemplateSettings.doLoad(element); - } - - // 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)); - } - } - } - - // need this to support options from older format - private static void applyReformatState(@NotNull Set templateNamesWithReformatOff, @NotNull 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(@NotNull DeletedTemplatesManager deletedDefaults, @NotNull Collection templates) { - for (FileTemplateBase template : templates) { - if (template instanceof BundledFileTemplate && deletedDefaults.contains(template.getQualifiedName())) { - ((BundledFileTemplate)template).setEnabled(false); - } - } - } - - @Override - public void writeExternal(Element element) throws WriteExternalException { - for (FTManager child : myAllManagers) { - child.saveTemplates(); - } - validateRecentNames(); - final Element recentElement = new Element(ELEMENT_RECENT_TEMPLATES); - element.addContent(recentElement); - myRecentList.writeExternal(recentElement); - - //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.isReformatCode())); - // return templateElement; - //} - private void validateRecentNames() { final Collection allTemplates = myDefaultTemplatesManager.getAllTemplates(false); final List allNames = new ArrayList(allTemplates.size()); @@ -516,7 +423,5 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements JDOM public void writeExternal(Element element) throws WriteExternalException { DefaultJDOMExternalizer.writeExternal(this, element); } - } - } 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 4fcc7604d380..cff188ea9e78 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 @@ -69,7 +69,7 @@ abstract class FileTemplateTabAsList extends FileTemplateTab { final boolean internalTemplate = AllFileTemplatesConfigurable.isInternalTemplate(template.getName(), getTitle()); if (internalTemplate) { setFont(getFont().deriveFont(Font.BOLD)); - setText(FileTemplateManagerImpl.getInstanceImpl().localizeInternalTemplateName(template)); + setText(template.getName()); } else { setFont(getFont().deriveFont(Font.PLAIN)); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplatesLoader.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplatesLoader.java index 6e7deed2b82d..6a46323290f8 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplatesLoader.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplatesLoader.java @@ -22,14 +22,11 @@ import com.intellij.ide.plugins.cl.PluginClassLoader; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.lang.UrlClassLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; import java.io.IOException; import java.net.URL; import java.text.MessageFormat; @@ -90,7 +87,7 @@ public class FileTemplatesLoader { loadDefaultTemplates(); for (FTManager child : myAllManagers) { - loadCustomizedContent(child); + child.loadCustomizedContent(); } } @@ -193,57 +190,6 @@ public class FileTemplatesLoader { } } - void loadCustomizedContent(FTManager manager) { - final File configRoot = manager.getConfigRoot(false); - final File[] configFiles = configRoot.listFiles(); - if (configFiles == null) { - return; - } - - final List templateWithDefaultExtension = new ArrayList(); - final Set processedNames = new HashSet(); - - for (File file : configFiles) { - if (file.isDirectory() || myTypeManager.isFileIgnored(file.getName()) || file.isHidden()) { - continue; - } - final String name = file.getName(); - if (name.endsWith(FTManager.TEMPLATE_EXTENSION_SUFFIX)) { - templateWithDefaultExtension.add(file); - } - else { - processedNames.add(name); - addTemplateFromFile(manager, name, file); - } - } - - for (File file : templateWithDefaultExtension) { - String name = file.getName(); - // cut default template extension - name = name.substring(0, name.length() - FTManager.TEMPLATE_EXTENSION_SUFFIX.length()); - if (!processedNames.contains(name)) { - addTemplateFromFile(manager, name, file); - } - FileUtil.delete(file); - } - } - - private static void addTemplateFromFile(FTManager manager, String fileName, File file) { - Pair nameExt = FTManager.decodeFileName(fileName); - final String extension = nameExt.second; - final String templateQName = nameExt.first; - if (templateQName.length() == 0) { - return; - } - try { - final String text = FileUtil.loadFile(file, CharsetToolkit.UTF8_CHARSET); - manager.addTemplate(templateQName, extension).setText(text); - } - catch (IOException e) { - LOG.error(e); - } - } - private static boolean matchesPrefix(String path, String prefix) { if (prefix.length() == 0) { return !path.contains("/"); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java index a2f88cd80d12..2ae403a68ddd 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/ui/ConfigureTemplatesDialog.java @@ -33,7 +33,7 @@ public class ConfigureTemplatesDialog extends SingleConfigurableEditor{ private static final String DIMENSION_KEY = "#com.intellij.ide.fileTemplates.ui.ConfigureTemplatesDialog"; public ConfigureTemplatesDialog(Project project){ - this(project, new AllFileTemplatesConfigurable()); + this(project, new AllFileTemplatesConfigurable(project)); } public ConfigureTemplatesDialog(Project project, AllFileTemplatesConfigurable fileTemplatesConfigurable){ diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 5b3ad5302bee..7c9f92ba094e 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -25,8 +25,8 @@ - + @@ -370,7 +370,7 @@ serviceImplementation="com.intellij.codeInsight.template.impl.TemplateManagerImpl"/> - diff --git a/platform/platform-tests/testSrc/com/intellij/ide/LightFileTemplatesTest.java b/platform/platform-tests/testSrc/com/intellij/ide/LightFileTemplatesTest.java new file mode 100644 index 000000000000..828fa399034c --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/ide/LightFileTemplatesTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplatesScheme; +import com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl; +import com.intellij.testFramework.LightPlatformTestCase; +import com.intellij.testFramework.PlatformTestCase; + +/** + * @author Dmitry Avdeev + */ +public class LightFileTemplatesTest extends LightPlatformTestCase { + + public static final String TEST_TEMPLATE_TXT = "testTemplate.txt"; + + public LightFileTemplatesTest() { + PlatformTestCase.initPlatformLangPrefix(); + } + + public void testSchemas() throws Exception { + assertEquals(FileTemplatesScheme.DEFAULT, myTemplateManager.getCurrentScheme()); + + FileTemplate template = myTemplateManager.getTemplate(TEST_TEMPLATE_TXT); + assertEquals("hi there", template.getText()); + template.setText("good bye"); + assertEquals("good bye", myTemplateManager.getTemplate(TEST_TEMPLATE_TXT).getText()); + + myTemplateManager.setCurrentScheme(myTemplateManager.getProjectScheme()); + assertEquals("hi there", myTemplateManager.getDefaultTemplate(TEST_TEMPLATE_TXT).getText()); + + getProject().save(); + } + + private FileTemplateManagerImpl myTemplateManager; + + @Override + public void setUp() throws Exception { + super.setUp(); + myTemplateManager = FileTemplateManagerImpl.getInstanceImpl(getProject()); + } +} diff --git a/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java b/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java index 3d35c5aca2b3..78ff37e7eca6 100644 --- a/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java @@ -35,7 +35,7 @@ public class SearchableOptionsTest extends LightPlatformLangTestCase { SearchableOptionsRegistrar.getInstance().getConfigurables(new ConfigurableGroup[]{new IdeConfigurablesGroup()}, DocumentEvent.EventType.INSERT, null, "method", getProject()); final Set configurableSet = configurables.getAll(); for (Configurable configurable : configurableSet) { - if (configurable.getDisplayName().equals(new AllFileTemplatesConfigurable().getDisplayName())) { + if (configurable.getDisplayName().equals(new AllFileTemplatesConfigurable(getProject()).getDisplayName())) { return; } } diff --git a/platform/platform-tests/testSrc/fileTemplates/testTemplate.txt.ft b/platform/platform-tests/testSrc/fileTemplates/testTemplate.txt.ft new file mode 100644 index 000000000000..6d20e91bdfb6 --- /dev/null +++ b/platform/platform-tests/testSrc/fileTemplates/testTemplate.txt.ft @@ -0,0 +1 @@ +hi there \ No newline at end of file