diff --git a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.groovy b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.groovy index fb06e42b7416..b0d93afa0691 100644 --- a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/FileTemplatesTest.groovy @@ -1,5 +1,6 @@ package com.intellij.ide.fileTemplates import com.intellij.ide.fileTemplates.impl.CustomFileTemplate +import com.intellij.ide.fileTemplates.impl.FileTemplateTestUtil import com.intellij.openapi.Disposable import com.intellij.openapi.application.ex.PathManagerEx import com.intellij.openapi.roots.ModuleRootManager @@ -16,6 +17,16 @@ import com.intellij.testFramework.PsiTestUtil import com.intellij.util.properties.EncodingAwareProperties public class FileTemplatesTest extends IdeaTestCase { + private File myTestConfigDir; + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + if (myTestConfigDir !=null && myTestConfigDir.exists()) { + FileUtil.delete(myTestConfigDir); + } + } + public void testAllTemplates() throws Exception { final File testsDir = new File(PathManagerEx.getTestDataPath()+"/ide/fileTemplates"); @@ -130,4 +141,38 @@ public class FileTemplatesTest extends IdeaTestCase { template.setText(text); template } + + public void doTestSaveLoadTemplate(String name, String ext) { + FileTemplateTestUtil.TestFTManager templateManager = new FileTemplateTestUtil.TestFTManager("test", "testTemplates", + getTestConfigRoot()); + FileTemplate template = templateManager.addTemplate(name, ext); + String qName = template.getQualifiedName(); + templateManager.saveTemplates(); + templateManager.removeTemplate(qName); + FileTemplateTestUtil.loadCustomizedContent(templateManager); + FileTemplate loadedTemplate = templateManager.findTemplateByName(name); + assertNotNull("Template '" + qName + "' was not found", loadedTemplate); + assertEquals(name, loadedTemplate.getName()); + assertEquals(ext, loadedTemplate.getExtension()); + assertTrue(template != loadedTemplate); + } + + private File getTestConfigRoot() throws Exception { + if (myTestConfigDir == null) { + myTestConfigDir = FileUtil.createTempDirectory(getTestName(true), "config"); + } + return myTestConfigDir; + } + + public void testSaveLoadCustomTemplate() throws Exception { + doTestSaveLoadTemplate("name", "ext"); + } + + public void testSaveLoadCustomTemplateDottedName() throws Exception { + doTestSaveLoadTemplate("name.has.dots", "ext"); + } + + public void testSaveLoadCustomTemplateDottedExt() throws Exception { + doTestSaveLoadTemplate("name", "ext.has.dots"); + } } 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 new file mode 100644 index 000000000000..7dbf802c8c02 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateTestUtil.java @@ -0,0 +1,54 @@ +/* + * 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.fileTypes.ex.FileTypeManagerEx; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * @author Rustam Vishnyakov + */ +public class FileTemplateTestUtil { + public static final class TestFTManager extends FTManager { + private File myTestConfigDir; + + public TestFTManager( + @NotNull @NonNls String name, + @NotNull @NonNls String defaultTemplatesDirName, + @NotNull File testConfigDir) { + super(name, defaultTemplatesDirName); + myTestConfigDir = testConfigDir; + } + + @Override + public File getConfigRoot(boolean create) { + return myTestConfigDir; + } + + @Override + public void saveTemplates() { + super.saveTemplates(); + } + } + + public static void loadCustomizedContent(FTManager templateManager) { + FileTemplatesLoader loader = new FileTemplatesLoader(FileTypeManagerEx.getInstanceEx()); + loader.loadCustomizedContent(templateManager); + } +} 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 8552a5277d6d..3c0d4a4e1f8d 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 @@ -22,6 +22,7 @@ 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.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; @@ -43,6 +44,7 @@ class FTManager { 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 static final String ENCODED_NAME_EXT_DELIMITER = "\u0F0Fext\u0F0F."; private final String myName; private final boolean myInternal; @@ -119,8 +121,11 @@ class FTManager { // 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; + if (qName.startsWith(templateName) && qName.length() > templateName.length()) { + String remainder = qName.substring(templateName.length()); + if (remainder.startsWith(ENCODED_NAME_EXT_DELIMITER) || remainder.charAt(0) == '.') { + return t; + } } } return null; @@ -193,7 +198,7 @@ class FTManager { return bundled; } - void saveTemplates() { + public void saveTemplates() { final File configRoot = getConfigRoot(true); final File[] files = configRoot.listFiles(); @@ -262,7 +267,7 @@ class FTManager { * 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()); + final File templateFile = new File(parentDir, encodeFileName(template.getName(), template.getExtension())); FileOutputStream fileOutputStream; try { @@ -310,4 +315,21 @@ class FTManager { return myName + " file template manager"; } + public static String encodeFileName(String templateName, String extension) { + String nameExtDelimiter = extension.contains(".") ? ENCODED_NAME_EXT_DELIMITER : "."; + return templateName + nameExtDelimiter + extension; + } + + public static Pair decodeFileName(String fileName) { + String name = fileName; + String ext = ""; + String nameExtDelimiter = fileName.contains(ENCODED_NAME_EXT_DELIMITER) ? ENCODED_NAME_EXT_DELIMITER : "."; + int extIndex = fileName.lastIndexOf(nameExtDelimiter); + if (extIndex >= 0) { + name = fileName.substring(0, extIndex); + ext = fileName.substring(extIndex + nameExtDelimiter.length()); + } + return new Pair(name, ext); + } + } 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 index a9f237488ea0..73ee43594f87 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateBase.java @@ -54,7 +54,7 @@ public abstract class FileTemplateBase implements FileTemplate { } public static String getQualifiedName(final String name, final String extension) { - return name + "." + extension; + return FTManager.encodeFileName(name, extension); } @Override 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 944cbc28a5f7..be3be30fc247 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 @@ -26,7 +26,6 @@ import com.intellij.lexer.FlexAdapter; import com.intellij.lexer.Lexer; import com.intellij.lexer.MergingLexerAdapter; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -305,11 +304,6 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc myTemplate.setText(myTemplateEditor.getDocument().getText()); String name = myNameField.getText(); String extension = myExtensionField.getText(); - int lastDotIndex = extension.lastIndexOf("."); - if (lastDotIndex >= 0) { - name += extension.substring(0, lastDotIndex + 1); - extension = extension.substring(lastDotIndex + 1); - } if (name.length() == 0 || !isValidFilename(name + "." + extension)) { throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension")); } 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 a067ed39bc0c..d3c230fe8952 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,6 +22,7 @@ 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.util.lang.UrlClassLoader; import org.jetbrains.annotations.NotNull; @@ -191,7 +192,7 @@ public class FileTemplatesLoader { } } - private void loadCustomizedContent(FTManager manager) { + void loadCustomizedContent(FTManager manager) { final File configRoot = manager.getConfigRoot(false); final File[] configFiles = configRoot.listFiles(); if (configFiles == null) { @@ -226,9 +227,10 @@ public class FileTemplatesLoader { } } - private void addTemplateFromFile(FTManager manager, String templateQName, File file) { - final String extension = myTypeManager.getExtension(templateQName); - templateQName = templateQName.substring(0, templateQName.length() - extension.length() - 1); + 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; }