diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java index fe34cc6c6aa6..7b200641b945 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java @@ -82,7 +82,7 @@ public class PsiElementRenameHandler implements RenameHandler { } } - public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, Editor editor) { + public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, @Nullable Editor editor) { if (element != null && !canRename(project, editor, element)) { return; } diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java index 48f4b05adfb2..1e71e5d1ce50 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java @@ -144,7 +144,7 @@ public class InconsistentResourceBundleInspection extends GlobalSimpleInspection ResourceBundle resourceBundle = propertiesFile.getResourceBundle(); assert visitedBundles != null; if (!visitedBundles.add(resourceBundle)) return; - List files = resourceBundle.getPropertiesFiles(manager.getProject()); + List files = resourceBundle.getPropertiesFiles(); if (files.size() < 2) return; BidirectionalMap parents = new BidirectionalMap(); for (PropertiesFile f : files) { diff --git a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties index 0864d1e31206..06e0c2e3ae03 100644 --- a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties +++ b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties @@ -4,7 +4,9 @@ properties.files.file.type.description=Properties files remove.property.intention.text=Remove property rename.bundle.enter.new.resource.bundle.base.name.prompt.text=Enter new resource bundle base name rename.bundle.enter.new.resource.bundle.key.name.prompt.text=Enter new resource bundle key name +rename.bundle.enter.new.resource.bundle.section.name.prompt.text=Enter new resource bundle section name rename.resource.bundle.dialog.title=Rename Resource Bundle +rename.resource.bundle.section.dialog.title=Rename Resource Bundle Section rename.resource.bundle.key.dialog.title=Rename Resource Bundle Key properties.files.inspection.group.display.name=Properties Files unused.property.inspection.display.name=Unused Property @@ -40,4 +42,12 @@ options.properties.attribute.descriptor.property.value=Property value options.properties.attribute.descriptor.key.value.separator=Key/value separator options.properties.attribute.descriptor.comment=Comment options.properties.attribute.descriptor.valid.string.escape=Valid string escape -options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape \ No newline at end of file +options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape + +new.property.dialog.title=New Property Key +new.property.dialog.name.prompt.text=Enter new property key name + +resource.bundle.renamer=Rename resource bundle properties files +resource.bundle.renamer.dialog.description=Rename resource bundle properties files with the following names to: +resource.bundle.renamer.entity.name=Resource bundle +resource.bundle.renamer.option=Rename bound &resource bundle \ No newline at end of file diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java index 17858a2ca77d..a343ad34b477 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java @@ -18,6 +18,7 @@ package com.intellij.lang.properties; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -31,15 +32,29 @@ public class EmptyResourceBundle { private static class Holder { private static final ResourceBundle NULL = new ResourceBundle() { @NotNull - public List getPropertiesFiles(final Project project) { + @Override + public List getPropertiesFiles() { return Collections.emptyList(); } @NotNull - public PropertiesFile getDefaultPropertiesFile(final Project project) { + @Override + public List getPropertiesFiles(final Project project) { + return getPropertiesFiles(); + } + + @NotNull + @Override + public PropertiesFile getDefaultPropertiesFile() { throw new IllegalStateException(); } + @NotNull + @Override + public PropertiesFile getDefaultPropertiesFile(final Project project) { + return getDefaultPropertiesFile(); + } + @NotNull public String getBaseName() { return ""; @@ -49,6 +64,12 @@ public class EmptyResourceBundle { public VirtualFile getBaseDirectory() { throw new IllegalStateException(); } + + @NotNull + @Override + public Project getProject() { + throw new IllegalStateException(); + } }; } public static ResourceBundle getInstance() { diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java index abc281f7ea82..9ccd7569aba3 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,8 +42,16 @@ public class PropertiesUtil { private final static Locale DEFAULT_LOCALE = new Locale("", "", ""); - public static boolean isPropertyComplete(final Project project, ResourceBundle resourceBundle, String propertyName) { - List propertiesFiles = resourceBundle.getPropertiesFiles(project); + /** + * @deprecated use PropertiesUtil.isPropertyComplete(ResourceBundle resourceBundle, String propertyName) + */ + @Deprecated + public static boolean isPropertyComplete(final Project project, final ResourceBundle resourceBundle, final String propertyName) { + return isPropertyComplete(resourceBundle, propertyName); + } + + public static boolean isPropertyComplete(final ResourceBundle resourceBundle, final String propertyName) { + List propertiesFiles = resourceBundle.getPropertiesFiles(); for (PropertiesFile propertiesFile : propertiesFiles) { if (propertiesFile.findPropertyByKey(propertyName) == null) return false; } @@ -50,8 +59,13 @@ public class PropertiesUtil { } @NotNull - public static String getBaseName(@NotNull VirtualFile virtualFile) { - String name = virtualFile.getName(); + public static String getBaseName(@NotNull PsiFile file) { + return getBaseName(file.getContainingFile().getVirtualFile()); + } + + @NotNull + public static String getBaseName(@NotNull VirtualFile file) { + final String name = file.getName(); final Matcher matcher = LOCALE_PATTERN.matcher(name); final String baseNameWithExtension; if (matcher.find()) { @@ -92,10 +106,10 @@ public class PropertiesUtil { } @Nullable - public static String getFullName(final PropertiesFile psiFile) { + public static String getFullName(final PropertiesFile propertiesFile) { return ApplicationManager.getApplication().runReadAction(new NullableComputable() { public String compute() { - PsiDirectory directory = psiFile.getParent(); + PsiDirectory directory = propertiesFile.getParent(); String packageQualifiedName = getPackageQualifiedName(directory); if (packageQualifiedName == null) { return null; @@ -104,9 +118,7 @@ public class PropertiesUtil { if (qName.length() > 0) { qName.append("."); } - final VirtualFile virtualFile = psiFile.getVirtualFile(); - assert virtualFile != null; - qName.append(getBaseName(virtualFile)); + qName.append(getBaseName(propertiesFile.getContainingFile())); return qName.toString(); } }); @@ -132,7 +144,7 @@ public class PropertiesUtil { @NotNull public static List findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) { List result = new SmartList(); - List propertiesFiles = resourceBundle.getPropertiesFiles(project); + List propertiesFiles = resourceBundle.getPropertiesFiles(); for (PropertiesFile propertiesFile : propertiesFiles) { result.addAll(propertiesFile.findPropertiesByKey(key)); } diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java index d4a43a522b04..7ea56269949d 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java @@ -26,6 +26,7 @@ import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -33,9 +34,23 @@ import java.util.List; public abstract class ResourceBundle { public static final DataKey ARRAY_DATA_KEY = DataKey.create("resource.bundle.array"); + @NotNull + public abstract List getPropertiesFiles(); + + /** + * @deprecated, use getPropertiesFiles() instead this method + */ + @Deprecated @NotNull public abstract List getPropertiesFiles(final Project project); + @NotNull + public abstract PropertiesFile getDefaultPropertiesFile(); + + /** + * @deprecated, use getDefaultPropertiesFile() instead this method + */ + @Deprecated @NotNull public abstract PropertiesFile getDefaultPropertiesFile(final Project project); @@ -44,4 +59,7 @@ public abstract class ResourceBundle { @NotNull public abstract VirtualFile getBaseDirectory(); + + @NotNull + public abstract Project getProject(); } diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java index 43ffb513a4b2..ebe28b38b37e 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java @@ -15,7 +15,6 @@ */ package com.intellij.lang.properties; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.Nullable; @@ -26,11 +25,6 @@ public interface BundleNameEvaluator { @Nullable public String evaluateBundleName(final PsiFile psiFile) { - final VirtualFile virtualFile = psiFile == null ? null : psiFile.getOriginalFile().getVirtualFile(); - if (virtualFile == null) { - return null; - } - final PsiDirectory directory = psiFile.getParent(); if (directory == null) { return null; @@ -43,7 +37,7 @@ public interface BundleNameEvaluator { if (qName.length() > 0) { qName.append("."); } - qName.append(PropertiesUtil.getBaseName(virtualFile)); + qName.append(PropertiesUtil.getBaseName(psiFile)); return qName.toString(); } return null; diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java index 118437e942aa..5908219098b7 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java @@ -23,44 +23,64 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Konstantin Bulenkov */ public class PropertiesImplUtil extends PropertiesUtil { - public static ResourceBundle getResourceBundle(final PsiFile containingFile) { - VirtualFile virtualFile = containingFile.getVirtualFile(); - if (!containingFile.isValid() || virtualFile == null) { + + @Nullable + public static ResourceBundle getResourceBundle(@NotNull final PropertiesFile representative) { + final PsiFile containingFile = representative.getContainingFile(); + if (!containingFile.isValid()) { return EmptyResourceBundle.getInstance(); } - String baseName = getBaseName(virtualFile); - PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable() { + final String baseName = getBaseName(containingFile); + final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable() { @Nullable public PsiDirectory compute() { return containingFile.getContainingDirectory(); }}); if (directory == null) return EmptyResourceBundle.getInstance(); - - return new ResourceBundleImpl(directory.getVirtualFile(), baseName); + return getResourceBundle(baseName, directory); } - public static boolean isPropertiesFile(VirtualFile file, Project project) { + @Nullable + private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) { + PropertiesFile defaultPropertiesFile = null; + for (final PsiFile psiFile : baseDirectory.getFiles()) { + if (baseName.equals(getBaseName(psiFile))) { + final PropertiesFile propertiesFile = getPropertiesFile(psiFile); + if (propertiesFile != null) { + if (defaultPropertiesFile == null || defaultPropertiesFile.getName().compareTo(propertiesFile.getName()) < 0) { + defaultPropertiesFile = propertiesFile; + } + } + } + } + if (defaultPropertiesFile == null) { + return null; + } + return new ResourceBundleImpl(defaultPropertiesFile); + } + + public static boolean isPropertiesFile(@NotNull VirtualFile file, @NotNull Project project) { return getPropertiesFile(PsiManager.getInstance(project).findFile(file)) != null; } - public static boolean isPropertiesFile(PsiFile file) { + public static boolean isPropertiesFile(@Nullable PsiFile file) { return getPropertiesFile(file) != null; } @@ -70,8 +90,6 @@ public class PropertiesImplUtil extends PropertiesUtil { return file instanceof PropertiesFile ? (PropertiesFile)file : XmlPropertiesFileImpl.getPropertiesFile(file); } - - @NotNull public static List findPropertiesByKey(final Project project, final String key) { final GlobalSearchScope scope = GlobalSearchScope.allScope(project); @@ -94,4 +112,23 @@ public class PropertiesImplUtil extends PropertiesUtil { return properties; } + @Nullable + public static ResourceBundle createByUrl(final @NotNull String url, final @NotNull Project project) { + if (!url.startsWith(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX)) return null; + + final String defaultPropertiesUrl = url.substring(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX.length()); + final int idx = defaultPropertiesUrl.lastIndexOf('/'); + if (idx == -1) return null; + final String baseDirectoryName = defaultPropertiesUrl.substring(0, idx); + final String baseName = defaultPropertiesUrl.substring(idx + 1); + final VirtualFile baseDirectoryVirtualFile = VirtualFileManager.getInstance().findFileByUrl(baseDirectoryName); + if (baseDirectoryVirtualFile == null) { + return null; + } + final PsiFile baseDirectory = PsiManager.getInstance(project).findFile(baseDirectoryVirtualFile); + if (baseDirectory == null || !(baseDirectory instanceof PsiDirectory)) { + return null; + } + return getResourceBundle(baseName, (PsiDirectory)baseDirectory); + } } diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java index 1ac96a96f6af..d257824166e9 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java @@ -23,36 +23,32 @@ import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; import com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Comparator; import java.util.List; public class ResourceBundleImpl extends ResourceBundle { - @NonNls private static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:"; - @NotNull protected final VirtualFile myBaseDirectory; - @NotNull protected final String myBaseName; + @NonNls public static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:"; + @NotNull private final PropertiesFile myDefaultPropertiesFile; - public ResourceBundleImpl(@NotNull VirtualFile baseDirectory, @NotNull String baseName) { - myBaseDirectory = baseDirectory; - myBaseName = baseName; + public ResourceBundleImpl(@NotNull final PropertiesFile defaultPropertiesFile) { + myDefaultPropertiesFile = defaultPropertiesFile; } @NotNull - public List getPropertiesFiles(final Project project) { - VirtualFile[] children = myBaseDirectory.getChildren(); + @Override + public List getPropertiesFiles() { + PsiFile[] children = myDefaultPropertiesFile.getParent().getFiles(); + final String baseName = getBaseName(); List result = new SmartList(); - PsiManager psiManager = PsiManager.getInstance(project); - for (VirtualFile file : children) { - if (!file.isValid() || file.getExtension() == null) continue; - if (Comparing.strEqual(PropertiesUtil.getBaseName(file), myBaseName)) { - PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(file)); + for (PsiFile file : children) { + if (!file.isValid() || file.getVirtualFile().getExtension() == null) continue; + if (Comparing.strEqual(PropertiesUtil.getBaseName(file), baseName)) { + PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file); if (propertiesFile != null) { result.add(propertiesFile); } @@ -62,20 +58,38 @@ public class ResourceBundleImpl extends ResourceBundle { } @NotNull - public PropertiesFile getDefaultPropertiesFile(final Project project) { - List files = getPropertiesFiles(project); - // put default properties file first - ContainerUtil.quickSort(files, new Comparator() { - public int compare(final PropertiesFile o1, final PropertiesFile o2) { - return Comparing.compare(o1.getName(), o2.getName()); - } - }); - return files.get(0); + @Override + public List getPropertiesFiles(final Project project) { + return getPropertiesFiles(); } @NotNull + @Override + public PropertiesFile getDefaultPropertiesFile() { + return myDefaultPropertiesFile; + } + + @NotNull + @Override + public PropertiesFile getDefaultPropertiesFile(final Project project) { + return getDefaultPropertiesFile(); + } + + @NotNull + @Override public String getBaseName() { - return myBaseName; + return PropertiesUtil.getBaseName(myDefaultPropertiesFile.getContainingFile()); + } + + @NotNull + public VirtualFile getBaseDirectory() { + return myDefaultPropertiesFile.getParent().getVirtualFile(); + } + + @NotNull + @Override + public Project getProject() { + return myDefaultPropertiesFile.getProject(); } public boolean equals(final Object o) { @@ -83,42 +97,15 @@ public class ResourceBundleImpl extends ResourceBundle { if (o == null || getClass() != o.getClass()) return false; final ResourceBundleImpl resourceBundle = (ResourceBundleImpl)o; - - if (!myBaseDirectory.equals(resourceBundle.myBaseDirectory)) return false; - if (!myBaseName.equals(resourceBundle.myBaseName)) return false; - + if (!myDefaultPropertiesFile.equals(resourceBundle.myDefaultPropertiesFile)) return false; return true; } public int hashCode() { - int result = myBaseDirectory.hashCode(); - result = 29 * result + myBaseName.hashCode(); - return result; - } - - @Nullable - public static ResourceBundle createByUrl(String url) { - if (!url.startsWith(RESOURCE_BUNDLE_PREFIX)) return null; - - String defaultPropertiesUrl = url.substring(RESOURCE_BUNDLE_PREFIX.length()); - final int idx = defaultPropertiesUrl.lastIndexOf('/'); - if (idx == -1) return null; - String baseDir = defaultPropertiesUrl.substring(0, idx); - String baseName = defaultPropertiesUrl.substring(idx + 1); - VirtualFile baseDirectory = VirtualFileManager.getInstance().findFileByUrl(baseDir); - if (baseDirectory != null) { - return new ResourceBundleImpl(baseDirectory, baseName); - } - return null; + return myDefaultPropertiesFile.hashCode(); } public String getUrl() { - return RESOURCE_BUNDLE_PREFIX +getBaseDirectory() + "/" + getBaseName(); + return RESOURCE_BUNDLE_PREFIX + getBaseDirectory() + "/" + getBaseName(); } - - @NotNull - public VirtualFile getBaseDirectory() { - return myBaseDirectory; - } - } \ No newline at end of file diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java index f46d207dc935..36915e7e6962 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java @@ -19,31 +19,50 @@ */ package com.intellij.lang.properties.editor; +import com.intellij.ide.presentation.Presentation; +import com.intellij.lang.properties.PropertiesImplUtil; +import com.intellij.lang.properties.PropertiesUtil; import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +@Presentation(icon = "AllIcons.Nodes.ResourceBundle") public class ResourceBundleAsVirtualFile extends VirtualFile { - private final ResourceBundle myResourceBundle; + private final VirtualFile myBasePropertiesFile; - public ResourceBundleAsVirtualFile(@NotNull ResourceBundle resourceBundle) { - myResourceBundle = resourceBundle; + private ResourceBundleAsVirtualFile(@NotNull final VirtualFile basePropertiesFile) { + myBasePropertiesFile = basePropertiesFile; } @NotNull - public ResourceBundle getResourceBundle() { - return myResourceBundle; + public static ResourceBundleAsVirtualFile fromResourceBundle(final @NotNull ResourceBundle resourceBundle) { + return new ResourceBundleAsVirtualFile(resourceBundle.getDefaultPropertiesFile().getVirtualFile()); + } + + @Nullable + public ResourceBundle getResourceBundle(final Project project) { + final PsiManager psiManager = PsiManager.getInstance(project); + final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(myBasePropertiesFile)); + if (file == null) { + return null; + } + return PropertiesImplUtil.getResourceBundle(file); } @Override @NotNull public VirtualFileSystem getFileSystem() { - return myResourceBundle.getBaseDirectory().getFileSystem(); + return LocalFileSystem.getInstance(); } @Override @@ -55,7 +74,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile { @Override @NotNull public String getName() { - return myResourceBundle.getBaseName(); + return PropertiesUtil.getBaseName(myBasePropertiesFile); } public boolean equals(final Object o) { @@ -64,17 +83,18 @@ public class ResourceBundleAsVirtualFile extends VirtualFile { final ResourceBundleAsVirtualFile resourceBundleAsVirtualFile = (ResourceBundleAsVirtualFile)o; - if (!myResourceBundle.equals(resourceBundleAsVirtualFile.myResourceBundle)) return false; + if (!myBasePropertiesFile.equals(resourceBundleAsVirtualFile.myBasePropertiesFile)) return false; return true; } public int hashCode() { - return myResourceBundle.hashCode(); + return myBasePropertiesFile.hashCode(); } @Override public void rename(Object requestor, @NotNull String newName) throws IOException { + throw new UnsupportedOperationException(); } @Override @@ -94,7 +114,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile { @Override public VirtualFile getParent() { - return myResourceBundle.getBaseDirectory(); + return myBasePropertiesFile.getParent(); } @Override diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java new file mode 100644 index 000000000000..00c21d8d3811 --- /dev/null +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.lang.properties.editor; + + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Batkovich + */ +public interface ResourceBundleEditorViewElement { + + PsiElement[] getPsiElements(@NotNull Project project); + +} diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java index 2a1f94af4c95..25220d35311a 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java @@ -26,6 +26,9 @@ import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -34,36 +37,35 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement { - private final Project myProject; +public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement { private final ResourceBundle myResourceBundle; - public ResourceBundleFileStructureViewElement(final Project project, final ResourceBundle resourceBundle) { - myProject = project; + public ResourceBundleFileStructureViewElement(final ResourceBundle resourceBundle) { myResourceBundle = resourceBundle; } + @Override public ResourceBundle getValue() { return myResourceBundle; } @NotNull public StructureViewTreeElement[] getChildren() { - List propertiesFiles = myResourceBundle.getPropertiesFiles(myProject); + List propertiesFiles = myResourceBundle.getPropertiesFiles(); Map propertyNames = new LinkedHashMap(); for (PropertiesFile propertiesFile : propertiesFiles) { List properties = propertiesFile.getProperties(); for (IProperty property : properties) { - String name = property.getUnescapedKey(); + String name = property.getKey(); if (!propertyNames.containsKey(name)) { propertyNames.put(name, property); } } } List result = new ArrayList(propertyNames.size()); - for (String property : propertyNames.keySet()) { - //result.add(new PropertiesStructureViewElement(property)); - result.add(new ResourceBundlePropertyStructureViewElement(myProject, myResourceBundle, property)); + for (Map.Entry propertyEntry : propertyNames.entrySet()) { + //result.add(new PropertiesStructureViewElement(propertyEntry)); + result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, propertyEntry.getValue())); } return result.toArray(new StructureViewTreeElement[result.size()]); } @@ -85,6 +87,17 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree }; } + @Override + public PsiElement[] getPsiElements(@NotNull Project project) { + final List propertiesFiles = getValue().getPropertiesFiles(); + return ContainerUtil.map2Array(propertiesFiles, new PsiElement[propertiesFiles.size()], new Function() { + @Override + public PsiElement fun(PropertiesFile propertiesFile) { + return propertiesFile.getContainingFile(); + } + }); + } + public void navigate(boolean requestFocus) { } diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java index e521047cb9ba..8b387e802597 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java @@ -20,6 +20,7 @@ package com.intellij.lang.properties.editor; import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.PropertiesHighlighter; import com.intellij.lang.properties.PropertiesUtil; import com.intellij.lang.properties.ResourceBundle; @@ -29,16 +30,16 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement { - private final String myPropertyName; - private final Project myProject; +public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement { private final ResourceBundle myResourceBundle; + private final IProperty myProperty; private String myPresentableName; private static final TextAttributesKey INCOMPLETE_PROPERTY_KEY; @@ -49,10 +50,19 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView INCOMPLETE_PROPERTY_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_PROPERTY_KEY", textAttributes); } - public ResourceBundlePropertyStructureViewElement(final Project project, final ResourceBundle resourceBundle, String propertyName) { - myProject = project; + + public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final IProperty property) { myResourceBundle = resourceBundle; - myPropertyName = propertyName; + myProperty = property; + } + + public IProperty getProperty() { + return myProperty; + } + + @Override + public PsiElement[] getPsiElements(final @NotNull Project project) { + return new PsiElement[] {getProperty().getPsiElement()}; } public void setPresentableName(final String presentableName) { @@ -61,7 +71,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView @Override public String getValue() { - return myPropertyName; + return myProperty.getName(); } @Override @@ -76,7 +86,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView return new ColoredItemPresentation() { @Override public String getPresentableText() { - return myPresentableName == null ? myPropertyName : myPresentableName; + return myPresentableName == null ? myProperty.getName() : myPresentableName; } @Override @@ -91,7 +101,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView @Override public TextAttributesKey getTextAttributesKey() { - boolean isComplete = PropertiesUtil.isPropertyComplete(myProject, myResourceBundle, myPropertyName); + boolean isComplete = PropertiesUtil.isPropertyComplete(myResourceBundle, myProperty.getName()); if (isComplete) { return PropertiesHighlighter.PROPERTY_KEY; @@ -115,5 +125,4 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView public boolean canNavigateToSource() { return false; } - } diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java index 24ba3c513c38..fc1aa60d4ac9 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java @@ -25,7 +25,6 @@ import com.intellij.ide.util.treeView.smartTree.Sorter; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.structureView.GroupByWordPrefixes; import com.intellij.lang.properties.structureView.PropertiesSeparatorManager; -import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; /** @@ -33,23 +32,24 @@ import org.jetbrains.annotations.NotNull; */ public class ResourceBundleStructureViewModel implements PropertiesGroupingStructureViewModel, StructureViewModel.ExpandInfoProvider { private final ResourceBundle myResourceBundle; - private final GroupByWordPrefixes myGroupByWordPrefixes; + private final GroupByWordPrefixes myByWordPrefixesGrouper; private final StructureViewTreeElement myRoot; - public ResourceBundleStructureViewModel(final Project project, ResourceBundle root) { + public ResourceBundleStructureViewModel(ResourceBundle root) { myResourceBundle = root; - String separator = PropertiesSeparatorManager.getInstance().getSeparator(project, new ResourceBundleAsVirtualFile(myResourceBundle)); - myGroupByWordPrefixes = new GroupByWordPrefixes(separator); - myRoot = new ResourceBundleFileStructureViewElement(project, myResourceBundle); + String separator = PropertiesSeparatorManager.getInstance(root.getProject()). + getSeparator(myResourceBundle); + myByWordPrefixesGrouper = new GroupByWordPrefixes(separator); + myRoot = new ResourceBundleFileStructureViewElement(myResourceBundle); } public void setSeparator(String separator) { - myGroupByWordPrefixes.setSeparator(separator); - PropertiesSeparatorManager.getInstance().setSeparator(new ResourceBundleAsVirtualFile(myResourceBundle), separator); + myByWordPrefixesGrouper.setSeparator(separator); + PropertiesSeparatorManager.getInstance(myResourceBundle.getProject()).setSeparator(myResourceBundle, separator); } public String getSeparator() { - return myGroupByWordPrefixes.getSeparator(); + return myByWordPrefixesGrouper.getSeparator(); } @NotNull @@ -59,7 +59,7 @@ public class ResourceBundleStructureViewModel implements PropertiesGroupingStruc @NotNull public Grouper[] getGroupers() { - return new Grouper[]{myGroupByWordPrefixes}; + return new Grouper[]{myByWordPrefixesGrouper}; } @NotNull diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java index 53a9bd4dc31a..e4a35e7e677c 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java @@ -54,10 +54,10 @@ public class ResourceBundleUtil { if (virtualFile == null) { return null; } - if (virtualFile instanceof ResourceBundleAsVirtualFile) { - return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (virtualFile instanceof ResourceBundleAsVirtualFile && project != null) { + return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(project); } - Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null) { final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile instanceof PropertiesFile) { diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java index 77be36abc7a7..759ce6cb46fb 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java @@ -114,7 +114,7 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { @Override @NotNull public ResourceBundle getResourceBundle() { - return PropertiesImplUtil.getResourceBundle(getContainingFile()); + return PropertiesImplUtil.getResourceBundle(this); } @Override diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java index a740d8ece66f..2cc4851b012f 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java index d0a203a7644f..432739c9df96 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java @@ -18,9 +18,12 @@ package com.intellij.lang.properties.structureView; import com.intellij.ide.structureView.StructureViewTreeElement; import com.intellij.ide.structureView.impl.common.PsiTreeElementBase; import com.intellij.lang.properties.IProperty; +import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement; import com.intellij.lang.properties.psi.Property; import com.intellij.lang.properties.psi.impl.PropertiesFileImpl; import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -31,7 +34,7 @@ import java.util.List; /** * @author max */ -public class PropertiesFileStructureViewElement extends PsiTreeElementBase { +public class PropertiesFileStructureViewElement extends PsiTreeElementBase implements ResourceBundleEditorViewElement { protected PropertiesFileStructureViewElement(PropertiesFileImpl propertiesFile) { super(propertiesFile); @@ -48,6 +51,11 @@ public class PropertiesFileStructureViewElement extends PsiTreeElementBase myProperties; private final @NotNull String myPrefix; private final String myPresentableName; private final @NotNull String mySeparator; - public PropertiesPrefixGroup(final Collection properties, String prefix, String presentableName, final String separator) { + public PropertiesPrefixGroup(final Collection properties, + final @NotNull String prefix, + final String presentableName, + final @NotNull String separator) { myProperties = properties; myPrefix = prefix; myPresentableName = presentableName; mySeparator = separator; } + public String getPresentableName() { + return myPresentableName; + } + + @NotNull + public String getSeparator() { + return mySeparator; + } + + @NotNull + public String getPrefix() { + return myPrefix; + } + @NotNull public ItemPresentation getPresentation() { return new ItemPresentation() { @@ -112,8 +136,24 @@ public class PropertiesPrefixGroup implements Group { return result; } - public String getPrefix() { - return myPrefix; + @Override + public PsiElement[] getPsiElements(final @NotNull Project project) { + final List elements = ContainerUtil.mapNotNull(getChildren(), new NullableFunction() { + @Nullable + @Override + public PsiElement fun(final TreeElement treeElement) { + if (treeElement instanceof PropertiesStructureViewElement) { + PropertiesStructureViewElement propertiesElement = (PropertiesStructureViewElement)treeElement; + IProperty property = propertiesElement.getValue(); + return property.getPsiElement(); + } + else if (treeElement instanceof ResourceBundlePropertyStructureViewElement) { + return ((ResourceBundlePropertyStructureViewElement)treeElement).getPsiElements(project)[0]; + } + return null; + } + }); + return elements.toArray(new PsiElement[elements.size()]); } public boolean equals(final Object o) { diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java index f5e636811b92..cb60de04bc4f 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java @@ -19,28 +19,18 @@ */ package com.intellij.lang.properties.structureView; -import com.intellij.lang.properties.IProperty; -import com.intellij.lang.properties.PropertiesLanguage; -import com.intellij.lang.properties.ResourceBundle; -import com.intellij.lang.properties.ResourceBundleImpl; -import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile; +import com.intellij.lang.properties.*; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.psi.FileViewProvider; -import com.intellij.psi.PsiManager; -import com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import gnu.trove.TIntLongHashMap; import gnu.trove.TIntProcedure; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -48,45 +38,42 @@ import java.util.Map; name="PropertiesSeparatorManager", storages= { @Storage( - file = StoragePathMacros.APP_CONFIG + "/other.xml" + file = StoragePathMacros.PROJECT_FILE )} ) public class PropertiesSeparatorManager implements PersistentStateComponent { @NonNls private static final String FILE_ELEMENT = "file"; @NonNls private static final String URL_ELEMENT = "url"; @NonNls private static final String SEPARATOR_ATTR = "separator"; + private final Project myProject; - public static PropertiesSeparatorManager getInstance() { - return ServiceManager.getService(PropertiesSeparatorManager.class); + public static PropertiesSeparatorManager getInstance(final Project project) { + return ServiceManager.getService(project, PropertiesSeparatorManager.class); } - private final Map mySeparators = new THashMap(); + private final Map mySeparators = new THashMap(); - public String getSeparator(Project project, VirtualFile file) { - String separator = mySeparators.get(file); + public PropertiesSeparatorManager(final Project project) { + myProject = project; + } + + @NotNull + public String getSeparator(final ResourceBundle resourceBundle) { + if (!(resourceBundle instanceof ResourceBundleImpl)) { + return "."; + } + String separator = mySeparators.get(((ResourceBundleImpl)resourceBundle).getUrl()); if (separator == null) { - separator = guessSeparator(project, file); - setSeparator(file, separator); + separator = guessSeparator((ResourceBundleImpl)resourceBundle); + setSeparator(resourceBundle, separator); } return separator; } //returns most probable separator in properties files - private static String guessSeparator(final Project project, final VirtualFile file) { - Collection files; - if (file instanceof ResourceBundleAsVirtualFile) { - files = ((ResourceBundleAsVirtualFile)file).getResourceBundle().getPropertiesFiles(project); - } - else { - PsiManager psiManager = PsiManager.getInstance(project); - final FileViewProvider provider = psiManager.findViewProvider(file); - files = new SmartList(); - if (provider != null) { - ContainerUtil.addIfNotNull((PropertiesFile)provider.getPsi(PropertiesLanguage.INSTANCE), files); - } - } + private static String guessSeparator(final ResourceBundleImpl resourceBundle) { final TIntLongHashMap charCounts = new TIntLongHashMap(); - for (PropertiesFile propertiesFile : files) { + for (PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) { if (propertiesFile == null) continue; List properties = propertiesFile.getProperties(); for (IProperty property : properties) { @@ -119,8 +106,10 @@ public class PropertiesSeparatorManager implements PersistentStateComponent - @@ -44,11 +44,11 @@ - - - + + + + - diff --git a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java index 4b6a574c2024..67ddbf2d10f2 100644 --- a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java +++ b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java @@ -22,13 +22,13 @@ package com.intellij.ide.favoritesTreeView; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.lang.properties.PropertiesImplUtil; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.ResourceBundleImpl; import com.intellij.lang.properties.projectView.ResourceBundleNode; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -64,7 +64,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { public boolean elementContainsFile(final Object element, final VirtualFile vFile) { if (element instanceof ResourceBundle) { ResourceBundle bundle = (ResourceBundle)element; - final List propertiesFiles = bundle.getPropertiesFiles(myProject); + final List propertiesFiles = bundle.getPropertiesFiles(); for (PropertiesFile file : propertiesFiles) { final VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) continue; @@ -87,7 +87,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { public boolean isInvalidElement(final Object element) { if (element instanceof ResourceBundle) { ResourceBundle resourceBundle = (ResourceBundle)element; - List propertiesFiles = resourceBundle.getPropertiesFiles(myProject); + List propertiesFiles = resourceBundle.getPropertiesFiles(); if (propertiesFiles.size() == 1) { //todo result.add(new PsiFileNode(myProject, propertiesFiles.iterator().next(), this)); return true; @@ -113,6 +113,6 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { } public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) { - return new Object[]{ResourceBundleImpl.createByUrl(url)}; + return new Object[]{PropertiesImplUtil.createByUrl(url, project)}; } } diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java b/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java new file mode 100644 index 000000000000..d25b780bd769 --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java @@ -0,0 +1,138 @@ +/* + * 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.lang.properties.editor; + +import com.intellij.icons.AllIcons; +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.lang.properties.structureView.PropertiesPrefixGroup; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* @author Dmitry Batkovich +*/ +class NewPropertyAction extends AnAction { + public NewPropertyAction() { + super("New Property", null, AllIcons.General.Add); + } + + @Override + public void actionPerformed(final AnActionEvent e) { + final Project project = getEventProject(e); + if (project == null) { + return; + } + final FileEditor editor = PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext()); + if (editor == null || !(editor instanceof ResourceBundleEditor)) { + return; + } + final ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)editor; + + final String prefix; + final String separator; + final String place = e.getPlace(); + if (ActionPlaces.STRUCTURE_VIEW_TOOLBAR.equals(place)) { + prefix = null; + separator = null; + } else { + final ResourceBundleEditorViewElement selectedElement = resourceBundleEditor.getSelectedElement(); + if (selectedElement == null) { + return; + } + if (selectedElement instanceof PropertiesPrefixGroup) { + final PropertiesPrefixGroup group = (PropertiesPrefixGroup)selectedElement; + prefix = group.getPrefix(); + separator = group.getSeparator(); + } + else if (selectedElement instanceof ResourceBundlePropertyStructureViewElement || + selectedElement instanceof ResourceBundleFileStructureViewElement) { + prefix = null; + separator = null; + } + else { + throw new IllegalStateException("unsupported type: " + selectedElement.getClass()); + } + } + final ResourceBundle resourceBundle = resourceBundleEditor.getResourceBundle(); + + Messages.showInputDialog(project, + PropertiesBundle.message("new.property.dialog.name.prompt.text"), + PropertiesBundle.message("new.property.dialog.title"), + Messages.getQuestionIcon(), + null, + new NewPropertyNameValidator(resourceBundle, prefix, separator)); + } + + private static class NewPropertyNameValidator implements InputValidator { + private final @NotNull ResourceBundle myResourceBundle; + private final @Nullable String myPrefix; + private final @Nullable String mySeparator; + + + public NewPropertyNameValidator(final @NotNull ResourceBundle resourceBundle, + final @Nullable String prefix, + final @Nullable String separator) { + myResourceBundle = resourceBundle; + myPrefix = prefix; + mySeparator = separator; + } + + @Override + public boolean checkInput(final String inputString) { + return true; + } + + @Override + public boolean canClose(final String inputString) { + final String newPropertyName = myPrefix == null ? inputString : (myPrefix + mySeparator + inputString); + + for (final PropertiesFile propertiesFile : myResourceBundle.getPropertiesFiles()) { + for (final String propertyName : propertiesFile.getNamesMap().keySet()) { + if (newPropertyName.equals(propertyName)) { + Messages.showErrorDialog("Can't add new property. Property with key \'" + newPropertyName + "\' already exists.", "New Property"); + return false; + } + } + } + + final PropertiesFile defaultPropertiesFile = myResourceBundle.getDefaultPropertiesFile(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + @Override + public void run() { + defaultPropertiesFile.addProperty(newPropertyName, ""); + } + }); + } + }); + return true; + } + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java index 8765943c7c4a..733f229bc687 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java @@ -32,6 +32,7 @@ import java.util.Set; * @author cdr */ public class PropertiesGroupingStructureViewComponent extends StructureViewComponent { + protected PropertiesGroupingStructureViewComponent(Project project, FileEditor editor, PropertiesGroupingStructureViewModel structureViewModel) { diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java index b3799a338b8c..1c79c0fd6074 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java @@ -69,10 +69,13 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.TitledBorder; -import javax.swing.event.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.beans.PropertyChangeListener; import java.util.*; import java.util.List; @@ -85,7 +88,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit private final StructureViewComponent myStructureViewComponent; private final Map myEditors; - private String myOldPropertyName; private final ResourceBundle myResourceBundle; private final Map myTitledPanels; private final JComponent myNoPropertySelectedPanel = new NoPropertySelectedPanel().getComponent(); @@ -102,8 +104,8 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit private VirtualFileListener myVfsListener; private Editor mySelectedEditor; - public ResourceBundleEditor(Project project, ResourceBundle resourceBundle) { - myProject = project; + public ResourceBundleEditor(@NotNull ResourceBundle resourceBundle) { + myProject = resourceBundle.getProject(); final JPanel splitPanel = new JPanel(); myValuesPanel = new JPanel(); @@ -118,7 +120,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit splitPanel.add(splitter, BorderLayout.CENTER); myResourceBundle = resourceBundle; - myStructureViewComponent = new ResourceBundleStructureViewComponent(project, myResourceBundle, this); + myStructureViewComponent = new ResourceBundleStructureViewComponent(myResourceBundle, this); myStructureViewPanel.setLayout(new BorderLayout()); myStructureViewPanel.add(myStructureViewComponent, BorderLayout.CENTER); @@ -130,9 +132,8 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit public void valueChanged(TreeSelectionEvent e) { // filter out temp unselect/select events if (getSelectedPropertyName() == null) return; - if (!Comparing.strEqual(selectedPropertyName, getSelectedPropertyName()) - || !Comparing.equal(selectedPropertiesFile, getSelectedPropertiesFile())) - { + if (!Comparing.strEqual(selectedPropertyName, getSelectedPropertyName()) || + !Comparing.equal(selectedPropertiesFile, getSelectedPropertiesFile())) { selectedPropertyName = getSelectedPropertyName(); selectedPropertiesFile = getSelectedPropertiesFile(); selectionChanged(); @@ -153,7 +154,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } myDataProviderPanel = new DataProviderPanel(splitPanel); - project.getMessageBus().connect(project).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { + myProject.getMessageBus().connect(myProject).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { @Override public void selectionChanged(@NotNull FileEditorManagerEvent event) { onSelectionChanged(event); @@ -161,6 +162,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit }); } + public ResourceBundle getResourceBundle() { + return myResourceBundle; + } + private void onSelectionChanged(@NotNull FileEditorManagerEvent event) { // Ignore events which don't target current editor. FileEditor oldEditor = event.getOldEditor(); @@ -194,6 +199,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } private void setStructureViewSelection(@NotNull final String propertyName) { + if (myStructureViewComponent.isDisposed()) { + return; + } JTree tree = myStructureViewComponent.getTree(); if (tree == null) { return; @@ -264,19 +272,24 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit @Nullable private static String getNodeValue(@NotNull DefaultMutableTreeNode node) { + final ResourceBundleEditorViewElement element = getSelectedElement(node); + return element instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement)element).getValue() + : null; + } + + @Nullable + private static ResourceBundleEditorViewElement getSelectedElement(@NotNull DefaultMutableTreeNode node) { Object userObject = node.getUserObject(); if (!(userObject instanceof AbstractTreeNode)) return null; Object value = ((AbstractTreeNode)userObject).getValue(); - return value instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement)value).getValue() - : null; + return value instanceof ResourceBundleEditorViewElement ? (ResourceBundleEditorViewElement) value : null; } private void writeEditorPropertyValue(final Editor editor, final PropertiesFile propertiesFile) { final String currentValue = editor.getDocument().getText(); final String currentSelectedProperty = getSelectedPropertyName(); - final String selectedProperty = myOldPropertyName == null ? currentSelectedProperty : myOldPropertyName; - assert selectedProperty != null; + assert currentSelectedProperty != null; ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -284,10 +297,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit WriteCommandAction.runWriteCommandAction(myProject, new Runnable() { @Override public void run() { - final IProperty property = propertiesFile.findPropertyByKey(selectedProperty); + final IProperty property = propertiesFile.findPropertyByKey(currentSelectedProperty); try { if (property == null) { - propertiesFile.addProperty(selectedProperty, currentValue); + propertiesFile.addProperty(currentSelectedProperty, currentValue); } else { property.setValue(currentValue); @@ -318,7 +331,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit }, VALUES); myValuesPanel.add(myNoPropertySelectedPanel, NO_PROPERTY_SELECTED); - List propertiesFiles = myResourceBundle.getPropertiesFiles(myProject); + List propertiesFiles = myResourceBundle.getPropertiesFiles(); GridBagConstraints gc = new GridBagConstraints(0, 0, 0, 0, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0); @@ -342,6 +355,12 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit writeEditorPropertyValue(editor, propertiesFile); } }); + editor.getComponent().addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + writeEditorPropertyValue(editor, propertiesFile); + } + }); editor.getDocument().putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE); gc.gridx = 0; gc.gridy = y++; @@ -510,18 +529,11 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } private void selectionChanged() { myBackSlashPressed.clear(); - final String currentSelectedPropertyName = getSelectedPropertyName(); UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - if (myOldPropertyName != null && !myOldPropertyName.equals(currentSelectedPropertyName)) { - for (final Map.Entry entry : myEditors.entrySet()) { - writeEditorPropertyValue(entry.getValue(), entry.getKey()); - } - } updateEditorsFromProperties(); - myOldPropertyName = currentSelectedPropertyName; } }); } @@ -537,7 +549,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } @Nullable - private String getSelectedPropertyName() { + public String getSelectedPropertyName() { JTree tree = myStructureViewComponent.getTree(); if (tree == null) return null; TreePath selected = tree.getSelectionModel().getSelectionPath(); @@ -545,6 +557,15 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit return getNodeValue((DefaultMutableTreeNode)selected.getLastPathComponent()); } + @Nullable + public ResourceBundleEditorViewElement getSelectedElement() { + JTree tree = myStructureViewComponent.getTree(); + if (tree == null) return null; + TreePath selected = tree.getSelectionModel().getSelectionPath(); + if (selected == null) return null; + return getSelectedElement((DefaultMutableTreeNode)selected.getLastPathComponent()); + } + @Override @NotNull public JComponent getComponent() { @@ -706,23 +727,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit myEditors.clear(); } - /** - * Renames target property if the one is available. - *

- * Note: is assumed to be called under {@link WriteAction write action}. - * - * @param oldName old property name - * @param newName new property name - */ - public void renameProperty(@NotNull String oldName, @NotNull String newName) { - for (PropertiesFile properties : myResourceBundle.getPropertiesFiles(myProject)) { - IProperty property = properties.findPropertyByKey(oldName); - if (property != null) { - property.setName(newName); - } - } - } - public static class ResourceBundleEditorState implements FileEditorState { private final String myPropertyName; diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java index f29a9cbb7b7a..fdbc2c0c5e59 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java @@ -42,7 +42,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil if (!file.isValid()) return false; PsiFile psiFile = PsiManager.getInstance(project).findFile(file); PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile); - return propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles(project).size() > 1; + return propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles().size() > 1; } @Override @@ -50,7 +50,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file){ ResourceBundle resourceBundle; if (file instanceof ResourceBundleAsVirtualFile) { - resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle(); + resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle(project); } else { PsiFile psiFile = PsiManager.getInstance(project).findFile(file); @@ -60,7 +60,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil resourceBundle = PropertiesImplUtil.getPropertiesFile(psiFile).getResourceBundle(); } - return new ResourceBundleEditor(project, resourceBundle); + return new ResourceBundleEditor(resourceBundle); } @Override diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java index 9289eb24a4cb..ee8e47a446e4 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java @@ -15,25 +15,118 @@ */ package com.intellij.lang.properties.editor; +import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter; +import com.intellij.ide.CopyProvider; +import com.intellij.ide.DeleteProvider; +import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.ResourceBundle; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.lang.properties.psi.Property; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.ui.PopupHandler; +import com.intellij.usages.UsageTarget; +import com.intellij.usages.UsageView; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.awt.datatransfer.StringSelection; +import java.util.ArrayList; +import java.util.List; /** * @author cdr */ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureViewComponent { + private final static Logger LOG = Logger.getInstance(ResourceBundleStructureViewComponent.class); + private final ResourceBundle myResourceBundle; - public ResourceBundleStructureViewComponent(Project project, ResourceBundle resourceBundle, ResourceBundleEditor editor) { - super(project, editor, new ResourceBundleStructureViewModel(project, resourceBundle)); + public ResourceBundleStructureViewComponent(final ResourceBundle resourceBundle, final ResourceBundleEditor editor) { + super(resourceBundle.getProject(), editor, new ResourceBundleStructureViewModel(resourceBundle)); myResourceBundle = resourceBundle; + tunePopupActionGroup(); } - public Object getData(String dataId) { + @Override + protected void addGroupByActions(final DefaultActionGroup result) { + super.addGroupByActions(result); + result.add(new NewPropertyAction(), Constraints.FIRST); + } + + private void tunePopupActionGroup() { + final DefaultActionGroup propertiesPopupGroup = new DefaultActionGroup(); + propertiesPopupGroup.copyFromGroup((DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_STRUCTURE_VIEW_POPUP)); + propertiesPopupGroup.add(Separator.getInstance(), Constraints.FIRST); + propertiesPopupGroup.add(new NewPropertyAction(), Constraints.FIRST); + PopupHandler.installPopupHandler(getTree(), propertiesPopupGroup, IdeActions.GROUP_STRUCTURE_VIEW_POPUP, ActionManager.getInstance()); + } + + public Object getData(final String dataId) { if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) { - return new ResourceBundleAsVirtualFile(myResourceBundle); + return ResourceBundleAsVirtualFile.fromResourceBundle(myResourceBundle); + } else if (PlatformDataKeys.FILE_EDITOR.is(dataId)) { + return getFileEditor(); + } else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { + final ResourceBundleEditorViewElement selectedElement = ((ResourceBundleEditor)getFileEditor()).getSelectedElement(); + if (selectedElement != null) { + final Project project = CommonDataKeys.PROJECT.getData(this); + if (project != null) { + final PsiElement[] psiElements = selectedElement.getPsiElements(project); + if (psiElements != null) { + return psiElements; + } + } + } + } else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { + final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(this); + if (psiElements != null && psiElements.length > 0) { + return new PsiElementsDeleteProvider(psiElements); + } + } else if (UsageView.USAGE_TARGETS_KEY.is(dataId)) { + final PsiElement[] chosenElements = (PsiElement[]) getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName()); + if (chosenElements != null) { + final UsageTarget[] usageTargets = new UsageTarget[chosenElements.length]; + for (int i = 0; i < chosenElements.length; i++) { + usageTargets[i] = new PsiElement2UsageTargetAdapter(chosenElements[i]); + } + return usageTargets; + } + } else if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { + return new CopyProvider() { + @Override + public void performCopy(@NotNull final DataContext dataContext) { + final PsiElement[] selectedPsiElements = (PsiElement[])getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName()); + if (selectedPsiElements != null) { + final List names = new ArrayList(selectedPsiElements.length); + for (final PsiElement element : selectedPsiElements) { + if (element instanceof PsiNamedElement) { + names.add(((PsiNamedElement)element).getName()); + } + } + CopyPasteManager.getInstance().setContents(new StringSelection(StringUtil.join(names, "\n"))); + } + } + + @Override + public boolean isCopyEnabled(@NotNull final DataContext dataContext) { + return true; + } + + @Override + public boolean isCopyVisible(@NotNull final DataContext dataContext) { + return true; + } + }; } return super.getData(dataId); } @@ -41,5 +134,40 @@ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureVi protected boolean showScrollToFromSourceActions() { return false; } + + private class PsiElementsDeleteProvider implements DeleteProvider { + private final PsiElement[] myElements; + + private PsiElementsDeleteProvider(final PsiElement[] elements) { + myElements = elements; + } + + @Override + public void deleteElement(@NotNull final DataContext dataContext) { + final List bundlePropertiesFiles = myResourceBundle.getPropertiesFiles(); + + final List toDelete = new ArrayList(); + for (PsiElement element : myElements) { + final Property property = (Property) element; + final String key = property.getKey(); + if (key == null) { + LOG.error("key must be not null " + element); + } else { + for (PropertiesFile propertiesFile : bundlePropertiesFiles) { + for (final IProperty iProperty : propertiesFile.findPropertiesByKey(key)) { + toDelete.add(iProperty.getPsiElement()); + } + } + } + } + + new SafeDeleteHandler().invoke(myElements[0].getProject(), PsiUtilCore.toPsiElementArray(toDelete), dataContext); + } + + @Override + public boolean canDeleteElement(@NotNull final DataContext dataContext) { + return true; + } + } } diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java index 7ba44a86c2bd..a681e10f3af1 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java @@ -48,7 +48,7 @@ class ResourceBundleDeleteProvider implements DeleteProvider { public void deleteElement(@NotNull DataContext dataContext) { final Project project = CommonDataKeys.PROJECT.getData(dataContext); - List propertiesFiles = myResourceBundle.getPropertiesFiles(project); + List propertiesFiles = myResourceBundle.getPropertiesFiles(); assert project != null; new SafeDeleteHandler().invoke(project, ContainerUtil.map2Array(propertiesFiles, PsiElement.class, MAPPER), dataContext); } diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java index a2b1b621f068..d61282aefba2 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java @@ -57,7 +57,7 @@ public class ResourceBundleMoveProvider extends MoveHandlerDelegate { final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext); LOG.assertTrue(bundles != null); for (ResourceBundle bundle : bundles) { - List propertiesFiles = bundle.getPropertiesFiles(CommonDataKeys.PROJECT.getData(dataContext)); + List propertiesFiles = bundle.getPropertiesFiles(); for (PropertiesFile propertiesFile : propertiesFiles) { filesOrDirs.add(propertiesFile.getContainingFile()); } diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java index 7de856226e01..a415e4544aa0 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java @@ -25,9 +25,7 @@ import com.intellij.ide.projectView.ProjectViewNode; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.PsiFileNode; import com.intellij.ide.util.treeView.AbstractTreeNode; -import com.intellij.lang.properties.PropertiesBundle; -import com.intellij.lang.properties.PropertiesImplUtil; -import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.*; import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.fileEditor.FileEditorManager; @@ -50,7 +48,7 @@ public class ResourceBundleNode extends ProjectViewNode{ @NotNull public Collection getChildren() { - List propertiesFiles = getValue().getPropertiesFiles(myProject); + List propertiesFiles = getValue().getPropertiesFiles(); Collection children = new ArrayList(); for (PropertiesFile propertiesFile : propertiesFiles) { AbstractTreeNode node = new PsiFileNode(myProject, propertiesFile.getContainingFile(), getSettings()); @@ -63,11 +61,11 @@ public class ResourceBundleNode extends ProjectViewNode{ if (!file.isValid()) return false; PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file); PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile); - return propertiesFile != null && getValue().getPropertiesFiles(myProject).contains(propertiesFile); + return propertiesFile != null && getValue().getPropertiesFiles().contains(propertiesFile); } public VirtualFile getVirtualFile() { - final List list = getValue().getPropertiesFiles(myProject); + final List list = getValue().getPropertiesFiles(); if (!list.isEmpty()) { return list.get(0).getVirtualFile(); } @@ -88,7 +86,7 @@ public class ResourceBundleNode extends ProjectViewNode{ } public void navigate(final boolean requestFocus) { - OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), new ResourceBundleAsVirtualFile(getValue())); + OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), ResourceBundleAsVirtualFile.fromResourceBundle(getValue())); FileEditorManager.getInstance(getProject()).openTextEditor(descriptor, requestFocus); } diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java deleted file mode 100644 index 99355d34bc6e..000000000000 --- a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java +++ /dev/null @@ -1,69 +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.lang.properties.refactoring; - -import com.intellij.codeInsight.TargetElementUtilBase; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ScrollType; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; -import com.intellij.refactoring.rename.PsiElementRenameHandler; -import com.intellij.lang.properties.references.PropertyReferenceBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author Dmitry Avdeev - */ -public class PropertyRenameHandler extends PsiElementRenameHandler { - - public boolean isAvailableOnDataContext(final DataContext dataContext) { - final Editor editor = LangDataKeys.EDITOR.getData(dataContext); - if (editor != null) { - if (getPsiElement(editor) != null) return true; - } - return false; - } - - @Nullable - private static PsiElement getPsiElement(final Editor editor) { - final PsiReference reference = TargetElementUtilBase.findReference(editor); - if (reference instanceof PropertyReferenceBase) { - final ResolveResult[] resolveResults = ((PropertyReferenceBase)reference).multiResolve(false); - return resolveResults.length > 0 ? resolveResults[0].getElement() : null; - } else if (reference instanceof PsiMultiReference) { - final PsiReference[] references = ((PsiMultiReference)reference).getReferences(); - for (PsiReference psiReference : references) { - if (psiReference instanceof PropertyReferenceBase) { - final ResolveResult[] resolveResults = ((PropertyReferenceBase)psiReference).multiResolve(false); - if (resolveResults.length > 0) return resolveResults[0].getElement(); - } - } - } - return null; - } - - @Override - public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) { - PsiElement element = getPsiElement(editor); - editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset()); - invoke(element, project, nameSuggestionContext, editor); - } -} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java deleted file mode 100644 index 7d7dbc14aead..000000000000 --- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.lang.properties.refactoring; - -import com.intellij.lang.properties.IProperty; -import com.intellij.lang.properties.PropertiesBundle; -import com.intellij.lang.properties.ResourceBundle; -import com.intellij.lang.properties.editor.ResourceBundleEditor; -import com.intellij.lang.properties.editor.ResourceBundleEditorUtil; -import com.intellij.lang.properties.editor.ResourceBundleUtil; -import com.intellij.lang.properties.psi.PropertiesFile; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorStateLevel; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.InputValidator; -import com.intellij.openapi.ui.Messages; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.refactoring.rename.RenameHandler; -import com.intellij.util.containers.HashSet; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -/** - * Encapsulates logic of renaming resource bundle property key. - * - * @author Denis Zhdanov - * @since 11/9/10 4:13 PM - */ -public class ResourceBundleKeyRenameHandler implements RenameHandler { - - @Override - public boolean isAvailableOnDataContext(DataContext dataContext) { - ResourceBundleEditor editor = ResourceBundleEditorUtil.getEditor(dataContext); - if (editor == null) { - return false; - } - return editor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName() != null; - } - - @Override - public boolean isRenaming(DataContext dataContext) { - return isAvailableOnDataContext(dataContext); - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { - ResourceBundleEditor bundleEditor = ResourceBundleEditorUtil.getEditor(dataContext); - if (bundleEditor == null) { - return; - } - - String propertyName = bundleEditor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName(); - if (propertyName == null) { - return; - } - - ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); - if (bundle == null) { - return; - } - Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.key.name.prompt.text"), - PropertiesBundle.message("rename.resource.bundle.key.dialog.title"), Messages.getQuestionIcon(), propertyName, - new ResourceBundleKeyRenameValidator(project, bundleEditor, bundle, propertyName)); - } - - @Override - public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - invoke(project, null, null, dataContext); - } - - private static class ResourceBundleKeyRenameValidator implements InputValidator { - - private final Set myExistingProperties = new HashSet(); - - private final ResourceBundleEditor myEditor; - private final String myOldPropertyName; - - ResourceBundleKeyRenameValidator(Project project, ResourceBundleEditor editor, ResourceBundle bundle, String oldPropertyName) { - myEditor = editor; - myOldPropertyName = oldPropertyName; - for (PropertiesFile file : bundle.getPropertiesFiles(project)) { - for (IProperty property : file.getProperties()) { - myExistingProperties.add(property.getKey()); - } - } - myExistingProperties.remove(oldPropertyName); - } - - @Override - public boolean checkInput(String inputString) { - return inputString != null && !inputString.isEmpty() && !myExistingProperties.contains(inputString); - } - - @Override - public boolean canClose(final String inputString) { - if (!checkInput(inputString)) { - return false; - } - - if (myOldPropertyName.equals(inputString)) { - return true; - } - - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myEditor.renameProperty(myOldPropertyName, inputString); - } - }); - return true; - } - } -} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java deleted file mode 100644 index fe555a7a2ca7..000000000000 --- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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. - */ - -/** - * @author Alexey - */ -package com.intellij.lang.properties.refactoring; - -import com.intellij.codeInsight.FileModificationService; -import com.intellij.lang.properties.PropertiesBundle; -import com.intellij.lang.properties.ResourceBundle; -import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile; -import com.intellij.lang.properties.editor.ResourceBundleEditor; -import com.intellij.lang.properties.editor.ResourceBundleEditorUtil; -import com.intellij.lang.properties.editor.ResourceBundleUtil; -import com.intellij.lang.properties.psi.PropertiesFile; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorStateLevel; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.InputValidator; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.refactoring.rename.RenameHandler; -import com.intellij.refactoring.rename.RenameProcessor; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; - -public class ResourceBundleRenameHandler implements RenameHandler { - private static final Logger LOG = Logger.getInstance("#" + ResourceBundleRenameHandler.class.getName()); - - public boolean isAvailableOnDataContext(DataContext dataContext) { - final Project project = CommonDataKeys.PROJECT.getData(dataContext); - if (project == null) { - return false; - } - final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); - if (bundle == null) { - return false; - } - - final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); - - ResourceBundleEditor editor = ResourceBundleEditorUtil.getEditor(dataContext); - return (editor == null || editor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName() == null /* user selected non-bundle key element */) - && bundle.getPropertiesFiles(project).size() > 1 && (virtualFile instanceof ResourceBundleAsVirtualFile || virtualFile == null); - } - - public boolean isRenaming(DataContext dataContext) { - return isAvailableOnDataContext(dataContext); - } - - public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { - ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); - - assert resourceBundle != null; - Messages.showInputDialog(project, - PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.base.name.prompt.text"), - PropertiesBundle.message("rename.resource.bundle.dialog.title"), - Messages.getQuestionIcon(), - resourceBundle.getBaseName(), - new MyInputValidator(project, resourceBundle)); - } - - public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - invoke(project, null, null, dataContext); - } - - private static class MyInputValidator implements InputValidator { - private final Project myProject; - private final ResourceBundle myResourceBundle; - - public MyInputValidator(final Project project, final ResourceBundle resourceBundle) { - myProject = project; - myResourceBundle = resourceBundle; - } - - public boolean checkInput(String inputString) { - return inputString.indexOf(File.separatorChar) < 0 && inputString.indexOf('/') < 0; - } - - public boolean canClose(final String inputString) { - return doRename(inputString); - } - private boolean doRename(final String inputString) { - final List propertiesFiles = myResourceBundle.getPropertiesFiles(myProject); - for (PropertiesFile propertiesFile : propertiesFiles) { - if (!FileModificationService.getInstance().prepareFileForWrite(propertiesFile.getContainingFile())) return false; - } - - RenameProcessor renameProcessor = null; - String baseName = myResourceBundle.getBaseName(); - for (PropertiesFile propertiesFile : propertiesFiles) { - final VirtualFile virtualFile = propertiesFile.getVirtualFile(); - if (virtualFile == null) { - continue; - } - final String newName = inputString + virtualFile.getNameWithoutExtension().substring(baseName.length()) + "." - + virtualFile.getExtension(); - if (renameProcessor == null) { - renameProcessor = new RenameProcessor(myProject, propertiesFile.getContainingFile(), newName, false, false); - continue; - } - renameProcessor.addElement(propertiesFile.getContainingFile(), newName); - } - if (renameProcessor == null) { - LOG.assertTrue(false); - return true; - } - renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.dialog.title")); - renameProcessor.doRun(); - return true; - } - } -} \ No newline at end of file diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java similarity index 59% rename from plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java rename to plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java index 6bdaa0957133..f3c81736673f 100644 --- a/plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.lang.properties.refactoring; +package com.intellij.lang.properties.refactoring.rename; import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.PropertiesUtil; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.lang.properties.refactoring.PropertiesRefactoringSettings; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.psi.PsiElement; import com.intellij.refactoring.rename.RenamePsiElementProcessor; @@ -26,6 +28,7 @@ import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo; import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.NotNull; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -36,12 +39,17 @@ public class RenamePropertyProcessor extends RenamePsiElementProcessor { public void prepareRenaming(final PsiElement element, final String newName, final Map allRenames) { - IProperty property = (IProperty) element; - ResourceBundle resourceBundle = property.getPropertiesFile().getResourceBundle(); - List properties = PropertiesUtil.findAllProperties(element.getProject(), resourceBundle, property.getUnescapedKey()); + final Project project = element.getProject(); + ResourceBundle resourceBundle = ((IProperty) element).getPropertiesFile().getResourceBundle(); + + final Map allRenamesCopy = new LinkedHashMap(allRenames); allRenames.clear(); - for (IProperty otherProperty : properties) { - allRenames.put(otherProperty.getPsiElement(), newName); + for (final Map.Entry e : allRenamesCopy.entrySet()) { + final IProperty property = (IProperty) e.getKey(); + final List properties = PropertiesUtil.findAllProperties(project, resourceBundle, property.getUnescapedKey()); + for (final IProperty toRename : properties) { + allRenames.put(toRename.getPsiElement(), e.getValue()); + } } } @@ -50,14 +58,16 @@ public class RenamePropertyProcessor extends RenamePsiElementProcessor { final String newName, Map allRenames, List result) { - for (IProperty property : ((PropertiesFile)element.getContainingFile()).getProperties()) { - if (Comparing.strEqual(newName, property.getKey())) { - result.add(new UnresolvableCollisionUsageInfo(property.getPsiElement(), element) { - @Override - public String getDescription() { - return "New property name \'" + newName + "\' hides existing property"; - } - }); + for (final Map.Entry e: allRenames.entrySet()) { + for (IProperty property : ((PropertiesFile)e.getKey().getContainingFile()).getProperties()) { + if (Comparing.strEqual(e.getValue(), property.getKey())) { + result.add(new UnresolvableCollisionUsageInfo(property.getPsiElement(), e.getKey()) { + @Override + public String getDescription() { + return "New property name \'" + e.getValue() + "\' hides existing property"; + } + }); + } } } } diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java new file mode 100644 index 000000000000..0c04bec80620 --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java @@ -0,0 +1,120 @@ +/* + * 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. + */ + +/** + * @author Alexey + */ +package com.intellij.lang.properties.refactoring.rename; + +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.editor.*; +import com.intellij.lang.properties.structureView.PropertiesPrefixGroup; +import com.intellij.lang.properties.structureView.PropertiesStructureViewElement; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.rename.RenameHandler; +import com.intellij.util.NullableFunction; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleFromEditorRenameHandler implements RenameHandler { + + @Override + public boolean isAvailableOnDataContext(DataContext dataContext) { + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return false; + } + final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); + if (bundle == null) { + return false; + } + final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext); + if (fileEditor == null || !(fileEditor instanceof ResourceBundleEditor)) { + return false; + } + final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); + return !(virtualFile == null || !(virtualFile instanceof ResourceBundleAsVirtualFile)); + } + + @Override + public boolean isRenaming(DataContext dataContext) { + return isAvailableOnDataContext(dataContext); + } + + @Override + public void invoke(final @NotNull Project project, Editor editor, final PsiFile file, DataContext dataContext) { + final ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)PlatformDataKeys.FILE_EDITOR.getData(dataContext); + assert resourceBundleEditor != null; + final ResourceBundleEditorViewElement selectedElement = resourceBundleEditor.getSelectedElement(); + if (selectedElement != null) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + @Override + public void run() { + if (selectedElement instanceof PropertiesPrefixGroup) { + final PropertiesPrefixGroup group = (PropertiesPrefixGroup)selectedElement; + ResourceBundleRenameUtil.renameResourceBundleKeySection(getPsiElementsFromGroup(group), + group.getPresentableName(), + group.getPrefix().length() - group.getPresentableName().length()); + } else if (selectedElement instanceof ResourceBundlePropertyStructureViewElement) { + final PsiElement psiElement = ((ResourceBundlePropertyStructureViewElement)selectedElement).getProperty().getPsiElement(); + ResourceBundleRenameUtil.renameResourceBundleKey(psiElement, project); + } else if (selectedElement instanceof ResourceBundleFileStructureViewElement) { + ResourceBundleRenameUtil.renameResourceBundleBaseName(((ResourceBundleFileStructureViewElement)selectedElement).getValue(), project); + } else { + throw new IllegalStateException("unsupported type: " + selectedElement.getClass()); + } + } + }); + } + } + + @Override + public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { + invoke(project, null, null, dataContext); + } + + private static List getPsiElementsFromGroup(final PropertiesPrefixGroup propertiesPrefixGroup) { + return ContainerUtil.mapNotNull(propertiesPrefixGroup.getChildren(), new NullableFunction() { + @Nullable + @Override + public PsiElement fun(TreeElement treeElement) { + if (treeElement instanceof PropertiesStructureViewElement) { + return ((PropertiesStructureViewElement)treeElement).getValue().getPsiElement(); + } + if (treeElement instanceof ResourceBundlePropertyStructureViewElement) { + return ((ResourceBundlePropertyStructureViewElement)treeElement).getProperty().getPsiElement(); + } + return null; + } + }); + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java new file mode 100644 index 000000000000..f2cbca033b6b --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java @@ -0,0 +1,65 @@ +/* + * 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.lang.properties.refactoring.rename; + +import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.editor.*; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.RefactoringActionHandlerFactory; +import com.intellij.refactoring.rename.RenameHandler; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleFromProjectViewRenameHandler implements RenameHandler { + + @Override + public boolean isAvailableOnDataContext(DataContext dataContext) { + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return false; + } + final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); + if (bundle == null || bundle.getPropertiesFiles().size() < 2) { + return false; + } + return PlatformDataKeys.FILE_EDITOR.getData(dataContext) == null && CommonDataKeys.VIRTUAL_FILE.getData(dataContext) == null; + } + + @Override + public boolean isRenaming(DataContext dataContext) { + return isAvailableOnDataContext(dataContext); + } + + @Override + public void invoke(final @NotNull Project project, Editor editor, final PsiFile file, DataContext dataContext) { + final ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext); + assert resourceBundle != null; + RefactoringActionHandlerFactory.getInstance().createRenameHandler().invoke(project, new PsiElement[] {resourceBundle.getDefaultPropertiesFile().getContainingFile()}, dataContext); + } + + @Override + public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { + invoke(project, null, null, dataContext); + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java new file mode 100644 index 000000000000..79694f7ae35a --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java @@ -0,0 +1,152 @@ +/* + * 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.lang.properties.refactoring.rename; + +import com.intellij.codeInsight.FileModificationService; +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.refactoring.rename.PsiElementRenameHandler; +import com.intellij.refactoring.rename.RenameProcessor; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.List; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleRenameUtil { + private final static Logger LOG = Logger.getInstance(ResourceBundleRenameUtil.class); + + public static void renameResourceBundleKey(final @NotNull PsiElement psiElement, final @NotNull Project project) { + PsiElementRenameHandler.invoke(psiElement, project, psiElement.getContainingFile(), null); + } + + public static void renameResourceBundleBaseName(final @NotNull ResourceBundle resourceBundle, final @NotNull Project project) { + Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.base.name.prompt.text"), + PropertiesBundle.message("rename.resource.bundle.dialog.title"), Messages.getQuestionIcon(), + resourceBundle.getBaseName(), new ResourceBundleBaseNameInputValidator(project, resourceBundle)); + } + + public static void renameResourceBundleKeySection(final List psiElements, final String section, final int sectionPosition) { + if (psiElements.isEmpty()) { + return; + } + final Project project = psiElements.get(0).getProject(); + Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.section.name.prompt.text"), + PropertiesBundle.message("rename.resource.bundle.section.dialog.title"), Messages.getQuestionIcon(), section, + new ResourceBundleKeySectionInputValidator(psiElements, section, sectionPosition, project)); + } + + private static class ResourceBundleKeySectionInputValidator implements InputValidator { + + private final List myPsiElements; + private final String mySection; + private final int mySectionPosition; + private final Project myProject; + + private ResourceBundleKeySectionInputValidator(final List psiElements, + final String section, + final int sectionPosition, + final Project project) { + myPsiElements = psiElements; + mySection = section; + mySectionPosition = sectionPosition; + myProject = project; + } + + @Override + public boolean checkInput(final String inputString) { + return inputString.indexOf('.') < 0; + } + + @Override + public boolean canClose(final String inputString) { + RenameProcessor renameProcessor = null; + for (final PsiElement psiElement : myPsiElements) { + assert psiElement instanceof PsiNamedElement; + final String oldName = ((PsiNamedElement)psiElement).getName(); + assert oldName != null; + final String newName = + oldName.substring(0, mySectionPosition) + inputString + oldName.substring(mySectionPosition + mySection.length()); + if (renameProcessor == null) { + renameProcessor = new RenameProcessor(myProject, psiElement, newName, false, false); + } + else { + renameProcessor.addElement(psiElement, newName); + } + } + assert renameProcessor != null; + renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.section.dialog.title")); + renameProcessor.doRun(); + return true; + } + } + + private static class ResourceBundleBaseNameInputValidator implements InputValidator { + private final Project myProject; + private final ResourceBundle myResourceBundle; + + public ResourceBundleBaseNameInputValidator(final Project project, final ResourceBundle resourceBundle) { + myProject = project; + myResourceBundle = resourceBundle; + } + + public boolean checkInput(String inputString) { + return inputString.indexOf(File.separatorChar) < 0 && inputString.indexOf('/') < 0; + } + + public boolean canClose(final String inputString) { + final List propertiesFiles = myResourceBundle.getPropertiesFiles(); + for (PropertiesFile propertiesFile : propertiesFiles) { + if (!FileModificationService.getInstance().prepareFileForWrite(propertiesFile.getContainingFile())) return false; + } + + RenameProcessor renameProcessor = null; + final String baseName = myResourceBundle.getBaseName(); + for (PropertiesFile propertiesFile : propertiesFiles) { + final VirtualFile virtualFile = propertiesFile.getVirtualFile(); + if (virtualFile == null) { + continue; + } + final String newName = + inputString + virtualFile.getNameWithoutExtension().substring(baseName.length()) + "." + virtualFile.getExtension(); + if (renameProcessor == null) { + renameProcessor = new RenameProcessor(myProject, propertiesFile.getContainingFile(), newName, false, false); + continue; + } + renameProcessor.addElement(propertiesFile.getContainingFile(), newName); + } + if (renameProcessor == null) { + LOG.assertTrue(false); + return true; + } + + renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.dialog.title")); + renameProcessor.doRun(); + + return true; + } + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java new file mode 100644 index 000000000000..ab1b4391b0f6 --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java @@ -0,0 +1,74 @@ +/* + * 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.lang.properties.refactoring.rename; + +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.PropertiesUtil; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiNamedElement; +import com.intellij.refactoring.rename.naming.AutomaticRenamer; +import org.jetbrains.annotations.NonNls; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleRenamer extends AutomaticRenamer { + + public ResourceBundleRenamer(final PropertiesFile propertiesFile, final String newName) { + for (final PropertiesFile file : propertiesFile.getResourceBundle().getPropertiesFiles()) { + if (file.equals(propertiesFile)) { + continue; + } + final PsiFile containingFile = file.getContainingFile(); + myElements.add(containingFile); + } + suggestAllNames(propertiesFile.getName(), newName); + } + + @Override + protected String nameToCanonicalName(@NonNls final String name, final PsiNamedElement element) { + return PropertiesUtil.getBaseName((PsiFile)element); + } + + @Override + protected String canonicalNameToName(@NonNls final String canonicalName, final PsiNamedElement element) { + final String oldCanonicalName = PropertiesUtil.getBaseName((PsiFile)element); + final String oldName = element.getName(); + assert oldName != null; + return canonicalName + oldName.substring(oldCanonicalName.length()); + } + + @Override + public boolean isSelectedByDefault() { + return true; + } + + @Override + public String getDialogTitle() { + return PropertiesBundle.message("resource.bundle.renamer"); + } + + @Override + public String getDialogDescription() { + return PropertiesBundle.message("resource.bundle.renamer.dialog.description"); + } + + @Override + public String entityName() { + return PropertiesBundle.message("resource.bundle.renamer.entity.name"); + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java new file mode 100644 index 000000000000..ec4bd31acbf3 --- /dev/null +++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java @@ -0,0 +1,64 @@ +/* + * 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.lang.properties.refactoring.rename; + +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.PropertiesImplUtil; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.rename.naming.AutomaticRenamer; +import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory; +import com.intellij.usageView.UsageInfo; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleRenamerFactory implements AutomaticRenamerFactory { + @Override + public boolean isApplicable(final PsiElement element) { + if (!(element instanceof PsiFile)) { + return false; + } + return PropertiesImplUtil.isPropertiesFile((PsiFile)element); + } + + + @Nullable + @Override + public String getOptionName() { + return PropertiesBundle.message("resource.bundle.renamer.option"); + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public void setEnabled(final boolean enabled) { + } + + @Override + public AutomaticRenamer createRenamer(final PsiElement element, final String newName, final Collection usages) { + final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile)element); + assert propertiesFile != null; + return new ResourceBundleRenamer(propertiesFile, newName); + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java b/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java index b19510be034b..f044a6db681c 100644 --- a/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java +++ b/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java @@ -275,7 +275,7 @@ public class I18nizeQuickFixDialog extends DialogWrapper implements I18nizeQuick private void propertiesFileChanged() { PropertiesFile propertiesFile = getPropertiesFile(); boolean hasResourceBundle = - propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles(propertiesFile.getProject()).size() > 1; + propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles().size() > 1; myUseResourceBundle.setEnabled(hasResourceBundle); } @@ -497,7 +497,7 @@ public class I18nizeQuickFixDialog extends DialogWrapper implements I18nizeQuick if (propertiesFile == null) return Collections.emptySet(); Collection propertiesFiles; if (isUseResourceBundle()) { - propertiesFiles = propertiesFile.getResourceBundle().getPropertiesFiles(myProject); + propertiesFiles = propertiesFile.getResourceBundle().getPropertiesFiles(); } else { propertiesFiles = Collections.singleton(propertiesFile); diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java index 5ebf25d4258f..ec1ae720e129 100644 --- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java +++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java @@ -16,13 +16,16 @@ package com.intellij.lang.properties; import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.FakePsiElement; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; /** * @author Dmitry Batkovich */ -public class PropertiesUtilTest extends TestCase { +public class PropertiesUtilTest extends LightPlatformCodeInsightFixtureTestCase { public void testBaseNameWithoutLocale() { assertBaseNameEquals("property-file.properties", "property-file"); @@ -62,14 +65,8 @@ public class PropertiesUtilTest extends TestCase { assertBaseNameEquals("Base_Page.utf8.properties", "Base_Page.utf8"); } - private static void assertBaseNameEquals(final String propertyFileName, final String expectedBaseName) { - final String actualBaseName = PropertiesUtil.getBaseName(new StubVirtualFile() { - @NotNull - @Override - public String getName() { - return propertyFileName; - } - }); + private void assertBaseNameEquals(final String propertyFileName, final String expectedBaseName) { + final String actualBaseName = PropertiesUtil.getBaseName(myFixture.configureByText(propertyFileName, "")); assertEquals(expectedBaseName, actualBaseName); } } diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java new file mode 100644 index 000000000000..f8c435817ea4 --- /dev/null +++ b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java @@ -0,0 +1,51 @@ +/* + * 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.lang.properties; + +import com.intellij.lang.properties.refactoring.rename.ResourceBundleRenamerFactory; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.rename.RenameProcessor; +import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; + +/** + * @author Dmitry Batkovich + */ +public class ResourceBundleRenameTest extends LightPlatformCodeInsightFixtureTestCase { + + public void testRenameResourceBundleEntryFile() { + final PsiFile toRenameFile = myFixture.addFileToProject("old_p.properties", ""); + final PsiFile toCheck = myFixture.addFileToProject("old_p_en.properties", ""); + + final RenameProcessor processor = new RenameProcessor(getProject(), toRenameFile, "new_p.properties", true, true); + for (AutomaticRenamerFactory factory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) { + if (factory instanceof ResourceBundleRenamerFactory) { + processor.addRenamerFactory(factory); + } + } + processor.run(); + + assertEquals("new_p_en.properties", toCheck.getName()); + } + + public void testRenamePropertyKey() { + final PsiFile toCheckFile = myFixture.addFileToProject("p.properties", "key=value"); + myFixture.configureByText("p_en.properties", "key=en_value"); + myFixture.renameElementAtCaret("new_key"); + assertEquals(toCheckFile.getText(), "new_key=value"); + } +}