summaryrefslogtreecommitdiff
path: root/plugins/properties/src
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2013-02-08 15:14:04 -0800
committerJean-Baptiste Queru <jbq@google.com>2013-02-08 15:14:04 -0800
commit9edc8f6b58f71ec510ba36b838f115718d9a174d (patch)
tree06f6df92024fa534ff27e1c0b5fc8b2002848093 /plugins/properties/src
parentb56ea2a18f232d79481e778085fd64e8ae486fc3 (diff)
downloadidea-9edc8f6b58f71ec510ba36b838f115718d9a174d.tar.gz
Snapshot of commit 84dc01e773388c2c72a1fc437f313dd5747e7809
from branch master of git://git.jetbrains.org/idea/community.git
Diffstat (limited to 'plugins/properties/src')
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/ResourceBundleUtil.java100
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java1
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java8
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java134
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java4
7 files changed, 139 insertions, 112 deletions
diff --git a/plugins/properties/src/com/intellij/lang/properties/ResourceBundleUtil.java b/plugins/properties/src/com/intellij/lang/properties/ResourceBundleUtil.java
deleted file mode 100644
index f13fc908265e..000000000000
--- a/plugins/properties/src/com/intellij/lang/properties/ResourceBundleUtil.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2000-2010 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.editor.ResourceBundleAsVirtualFile;
-import com.intellij.lang.properties.editor.ResourceBundleEditor;
-import com.intellij.lang.properties.psi.PropertiesFile;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-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.psi.PsiManager;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Contains utility methods for resource bundle-related processing.
- * <p/>
- * Thread-safe.
- *
- * @author Denis Zhdanov
- * @since 11/9/10 5:19 PM
- */
-public class ResourceBundleUtil {
-
- private ResourceBundleUtil() {
- }
-
- /**
- * Tries to derive {@link ResourceBundle resource bundle} related to the given context.
- *
- * @param dataContext target context
- * @return {@link ResourceBundle resource bundle} related to the given context if any; <code>null</code> otherwise
- */
- @Nullable
- public static ResourceBundle getResourceBundleFromDataContext(@NotNull DataContext dataContext) {
- PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
- if (element instanceof IProperty) return null; //rename property
- final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext);
- if (bundles != null && bundles.length == 1) return bundles[0];
- VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
- if (virtualFile == null) {
- return null;
- }
- if (virtualFile instanceof ResourceBundleAsVirtualFile) {
- return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle();
- }
- Project project = PlatformDataKeys.PROJECT.getData(dataContext);
- if (project != null) {
- final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
- if (psiFile instanceof PropertiesFile) {
- return ((PropertiesFile)psiFile).getResourceBundle();
- }
- }
- return null;
- }
-
- /**
- * Tries to derive {@link ResourceBundleEditor resource bundle editor} identified by the given context.
- *
- * @param dataContext target data context
- * @return resource bundle editor identified by the given context; <code>null</code> otherwise
- */
- @Nullable
- public static ResourceBundleEditor getEditor(@NotNull DataContext dataContext) {
- Project project = PlatformDataKeys.PROJECT.getData(dataContext);
- if (project == null) {
- return null;
- }
-
- VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
- if (virtualFile == null) {
- return null;
- }
- FileEditor[] editors = FileEditorManager.getInstance(project).getEditors(virtualFile);
- if (editors.length != 1 || (!(editors[0] instanceof ResourceBundleEditor))) {
- return null;
- }
-
- return (ResourceBundleEditor)editors[0];
- }
-}
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 d65ba23d8c0e..cc38c8d74500 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java
@@ -35,6 +35,7 @@ public class PropertiesGroupingStructureViewComponent extends StructureViewCompo
FileEditor editor,
PropertiesGroupingStructureViewModel structureViewModel) {
super(editor, structureViewModel, project);
+ showToolbar();
}
@Override
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 9cd90e1f0b0a..c8136e07144d 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
@@ -60,7 +60,7 @@ import com.intellij.ui.JBSplitter;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.Alarm;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.containers.*;
+import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
@@ -71,8 +71,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.TitledBorder;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -228,7 +226,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}
}
if (nodeToSelect != null) {
- tree.setSelectionPath(new TreePath(nodeToSelect.getPath()));
+ TreePath path = new TreePath(nodeToSelect.getPath());
+ tree.setSelectionPath(path);
+ tree.scrollPathToVisible(path);
}
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
index 99458cf5bed1..d87e60af640d 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
@@ -15,8 +15,23 @@
*/
package com.intellij.lang.properties.editor;
+import com.intellij.lang.properties.IProperty;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+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.psi.PsiManager;
+import com.intellij.util.SystemProperties;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.Writer;
import java.util.Properties;
@@ -27,13 +42,74 @@ import java.util.Properties;
*/
public class ResourceBundleUtil {
+ private static final String NATIVE_2_ASCII_CONVERSION_PATTERN = SystemProperties.getBooleanProperty("idea.native2ascii.lowercase", false)
+ ? "\\u%04x" : "\\u%04X";
+
private static final TIntHashSet SYMBOLS_TO_ESCAPE = new TIntHashSet(new int[]{'#', '!', '=', ':'});
+ private static final TIntHashSet UNICODE_SYMBOLS = new TIntHashSet(new int[]{
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'A', 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F'
+ });
private static final char ESCAPE_SYMBOL = '\\';
-
+
private ResourceBundleUtil() {
}
/**
+ * Tries to derive {@link com.intellij.lang.properties.ResourceBundle resource bundle} related to the given context.
+ *
+ * @param dataContext target context
+ * @return {@link com.intellij.lang.properties.ResourceBundle resource bundle} related to the given context if any;
+ * <code>null</code> otherwise
+ */
+ @Nullable
+ public static ResourceBundle getResourceBundleFromDataContext(@NotNull DataContext dataContext) {
+ PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
+ if (element instanceof IProperty) return null; //rename property
+ final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext);
+ if (bundles != null && bundles.length == 1) return bundles[0];
+ VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
+ if (virtualFile == null) {
+ return null;
+ }
+ if (virtualFile instanceof ResourceBundleAsVirtualFile) {
+ return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle();
+ }
+ Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+ if (project != null) {
+ final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+ if (psiFile instanceof PropertiesFile) {
+ return ((PropertiesFile)psiFile).getResourceBundle();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Tries to derive {@link ResourceBundleEditor resource bundle editor} identified by the given context.
+ *
+ * @param dataContext target data context
+ * @return resource bundle editor identified by the given context; <code>null</code> otherwise
+ */
+ @Nullable
+ public static ResourceBundleEditor getEditor(@NotNull DataContext dataContext) {
+ Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+ if (project == null) {
+ return null;
+ }
+
+ VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
+ if (virtualFile == null) {
+ return null;
+ }
+ FileEditor[] editors = FileEditorManager.getInstance(project).getEditors(virtualFile);
+ if (editors.length != 1 || (!(editors[0] instanceof ResourceBundleEditor))) {
+ return null;
+ }
+
+ return (ResourceBundleEditor)editors[0];
+ }
+
+ /**
* Allows to map given 'raw' property value text to the 'user-friendly' text to show at the resource bundle editor.
* <p/>
* <b>Note:</b> please refer to {@link Properties#store(Writer, String)} contract for the property value escape rules.
@@ -41,6 +117,7 @@ public class ResourceBundleUtil {
* @param text 'raw' property value text
* @return 'user-friendly' text to show at the resource bundle editor
*/
+ @SuppressWarnings("AssignmentToForLoopParameter")
@NotNull
public static String fromPropertyValueToValueEditor(@NotNull String text) {
StringBuilder buffer = new StringBuilder();
@@ -48,7 +125,14 @@ public class ResourceBundleUtil {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == ESCAPE_SYMBOL && !escaped) {
- escaped = true;
+ char[] unicodeSymbols = parseUnicodeLiteral(text, i + 1);
+ if (unicodeSymbols != null) {
+ buffer.append(unicodeSymbols);
+ i += 5;
+ }
+ else {
+ escaped = true;
+ }
continue;
}
if (escaped && c == 'n') {
@@ -61,6 +145,45 @@ public class ResourceBundleUtil {
}
/**
+ * Tries to parse unicode literal contained at the given text at the given offset:
+ * <pre>
+ * "my string to process \uABCD - with unicode literal"
+ * ^
+ * |
+ * offset
+ * </pre>
+ * I.e. this method checks if given text contains u[0123456789AaBbCcDdEeFf]{4} at the given offset; parses target unicode symbol
+ * and returns in case of the positive answer.
+ *
+ * @param text text to process
+ * @param i offset which might point to 'u' part of unicode literal contained at the given text
+ * @return 16-bit char symbols for the target unicode code point located at the given text at the given offset if any;
+ * <code>null</code> otherwise
+ */
+ @Nullable
+ private static char[] parseUnicodeLiteral(@NotNull String text, int i) {
+ if (text.length() < i + 5) {
+ return null;
+ }
+ char c = text.charAt(i);
+ if (c != 'u' && c != 'U') {
+ return null;
+ }
+ for (int j = i + 1; j < i + 5; j++) {
+ if (!UNICODE_SYMBOLS.contains(text.charAt(j))) {
+ return null;
+ }
+ }
+ try {
+ int codePoint = Integer.parseInt(text.substring(i + 1, i + 5), 16);
+ return Character.toChars(codePoint);
+ }
+ catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /**
* Perform reverse operation to {@link #fromPropertyValueToValueEditor(String)}.
*
* @param text 'user-friendly' text shown to the user at the resource bundle editor
@@ -78,8 +201,7 @@ public class ResourceBundleUtil {
{
buffer.append(ESCAPE_SYMBOL);
}
- else if (c == ESCAPE_SYMBOL) // Escaped 'escape' symbol)
- {
+ else if (c == ESCAPE_SYMBOL) { // Escaped 'escape' symbol)
if (text.length() > i + 1) {
final char nextChar = text.charAt(i + 1);
if (nextChar != 'n') {
@@ -89,6 +211,10 @@ public class ResourceBundleUtil {
buffer.append(ESCAPE_SYMBOL);
}
}
+ else if (c > 127) { // Non-ascii symbol
+ buffer.append(String.format(NATIVE_2_ASCII_CONVERSION_PATTERN, (int)c));
+ continue;
+ }
buffer.append(c);
}
return buffer.toString();
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java
index 33954ba0b829..303ed3cfc3b3 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java
@@ -18,8 +18,8 @@ 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.ResourceBundleUtil;
import com.intellij.lang.properties.editor.ResourceBundleEditor;
+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;
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java
index 8597f6dc8bc2..5164276f5323 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java
@@ -22,9 +22,9 @@ package com.intellij.lang.properties.refactoring;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.lang.properties.PropertiesBundle;
import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.ResourceBundleUtil;
import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
import com.intellij.lang.properties.editor.ResourceBundleEditor;
+import com.intellij.lang.properties.editor.ResourceBundleUtil;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
diff --git a/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java b/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
index 1f576524002e..f36749c9593b 100644
--- a/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
+++ b/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
@@ -179,12 +179,12 @@ public class XmlPropertiesIndex extends FileBasedIndexExtension<XmlPropertiesInd
if ("properties".equals(name)) {
accepted = true;
}
- else throw new NanoXmlUtil.ParserStoppedException();
+ else throw NanoXmlUtil.ParserStoppedXmlException.INSTANCE;
}
else {
insideEntry = "entry".equals(name);
}
- if (myStopIfAccepted) throw new NanoXmlUtil.ParserStoppedException();
+ if (myStopIfAccepted) throw NanoXmlUtil.ParserStoppedXmlException.INSTANCE;
}
@Override