summaryrefslogtreecommitdiff
path: root/plugins/properties/properties-psi-impl/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/properties/properties-psi-impl/src')
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java109
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java93
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java30
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java20
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java256
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java72
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java11
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java3
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java4
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java2
11 files changed, 568 insertions, 34 deletions
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 ebe28b38b37e..52b57238d138 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
@@ -37,7 +37,7 @@ public interface BundleNameEvaluator {
if (qName.length() > 0) {
qName.append(".");
}
- qName.append(PropertiesUtil.getBaseName(psiFile));
+ qName.append(ResourceBundleManager.getInstance(psiFile.getProject()).getBaseName(psiFile));
return qName.toString();
}
return null;
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java
new file mode 100644
index 000000000000..d712dc3d8655
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundle.java
@@ -0,0 +1,109 @@
+/*
+ * 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.psi.PropertiesFile;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class CustomResourceBundle extends ResourceBundle {
+ private final static Logger LOG = Logger.getInstance(CustomResourceBundle.class);
+
+ private final List<PropertiesFile> myFiles;
+ private final String myBaseName;
+
+ private CustomResourceBundle(final List<PropertiesFile> files, final @NotNull String baseName) {
+ LOG.assertTrue(!files.isEmpty());
+ myFiles = new ArrayList<PropertiesFile>(files);
+ Collections.sort(myFiles, new Comparator<PropertiesFile>() {
+ @Override
+ public int compare(PropertiesFile f1, PropertiesFile f2) {
+ return f1.getName().compareTo(f2.getName());
+ }
+ });
+ myBaseName = baseName;
+ }
+
+ public static CustomResourceBundle fromState(final CustomResourceBundleState state, final Project project) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final List<PropertiesFile> files =
+ ContainerUtil.map(state.getFiles(VirtualFileManager.getInstance()), new Function<VirtualFile, PropertiesFile>() {
+ @Override
+ public PropertiesFile fun(VirtualFile virtualFile) {
+ return PropertiesImplUtil.getPropertiesFile(psiManager.findFile(virtualFile));
+ }
+ });
+ return files.size() < 2 ? null : new CustomResourceBundle(files, state.getBaseName());
+ }
+
+ @NotNull
+ @Override
+ public List<PropertiesFile> getPropertiesFiles() {
+ return myFiles;
+ }
+
+ @NotNull
+ @Override
+ public PropertiesFile getDefaultPropertiesFile() {
+ return ContainerUtil.getFirstItem(myFiles);
+ }
+
+ @NotNull
+ @Override
+ public String getBaseName() {
+ return myBaseName;
+ }
+
+ @Nullable
+ @Override
+ public VirtualFile getBaseDirectory() {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public Project getProject() {
+ return getDefaultPropertiesFile().getProject();
+ }
+
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final CustomResourceBundle resourceBundle = (CustomResourceBundle)o;
+ return resourceBundle.getPropertiesFiles().equals(resourceBundle.getPropertiesFiles()) &&
+ resourceBundle.getBaseName().equals(getBaseName());
+ }
+
+ public int hashCode() {
+ return myFiles.hashCode() * 31 + myBaseName.hashCode();
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java
new file mode 100644
index 000000000000..9be149d6a4db
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/CustomResourceBundleState.java
@@ -0,0 +1,93 @@
+/*
+ * 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.openapi.util.Condition;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Property;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.Transient;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich
+ */
+@Tag("custom-resource-bundle")
+public class CustomResourceBundleState {
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(surroundWithTag = false, elementTag = "file", elementValueAttribute = "value")
+ public Set<String> myFileUrls = new HashSet<String>();
+
+ @Tag("base-name")
+ public String myBaseName;
+
+ @Transient
+ @NotNull
+ public String getBaseName() {
+ return myBaseName;
+ }
+
+ public Set<String> getFileUrls() {
+ return myFileUrls;
+ }
+
+ public List<VirtualFile> getFiles(@NotNull final VirtualFileManager manager) {
+ return ContainerUtil.mapNotNull(getFileUrls(), new Function<String, VirtualFile>() {
+ @Override
+ public VirtualFile fun(String url) {
+ return manager.findFileByUrl(url);
+ }
+ });
+ }
+
+ @Nullable
+ public CustomResourceBundleState removeNonExistentFiles(final VirtualFileManager virtualFileManager) {
+ final List<String> existentFiles = ContainerUtil.filter(myFileUrls, new Condition<String>() {
+ @Override
+ public boolean value(String url) {
+ return virtualFileManager.findFileByUrl(url) != null;
+ }
+ });
+ if (existentFiles.isEmpty()) {
+ return null;
+ }
+ final CustomResourceBundleState customResourceBundleState = new CustomResourceBundleState();
+ customResourceBundleState.myFileUrls.addAll(existentFiles);
+ customResourceBundleState.myBaseName = myBaseName;
+ return customResourceBundleState;
+ }
+
+ public CustomResourceBundleState addAll(final Collection<String> urls) {
+ myFileUrls.addAll(urls);
+ return this;
+ }
+
+ public CustomResourceBundleState setBaseName(String baseName) {
+ myBaseName = baseName;
+ return this;
+ }
+}
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 f667b1a93da0..15e73791f8ea 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
@@ -15,6 +15,7 @@
*/
package com.intellij.lang.properties;
+import com.intellij.lang.HtmlScriptContentProvider;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.PropertyKeyIndex;
import com.intellij.lang.properties.xml.XmlPropertiesFileImpl;
@@ -48,7 +49,23 @@ public class PropertiesImplUtil extends PropertiesUtil {
if (!containingFile.isValid()) {
return EmptyResourceBundle.getInstance();
}
- final String baseName = getBaseName(containingFile);
+ final ResourceBundleManager manager = ResourceBundleManager.getInstance(representative.getProject());
+ final CustomResourceBundle customResourceBundle =
+ manager.getCustomResourceBundle(representative);
+ if (customResourceBundle != null) {
+ return customResourceBundle;
+ }
+
+ final VirtualFile virtualFile = representative.getVirtualFile();
+ if (virtualFile == null) {
+ return EmptyResourceBundle.getInstance();
+ }
+ if (manager.isDefaultDissociated(virtualFile)) {
+ return new ResourceBundleImpl(representative);
+ }
+
+
+ final String baseName = manager.getBaseName(containingFile);
final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
@Nullable
public PsiDirectory compute() {
@@ -61,14 +78,9 @@ public class PropertiesImplUtil extends PropertiesUtil {
@Nullable
private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) {
PropertiesFile defaultPropertiesFile = null;
- final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
- @Override
- public PsiFile[] compute() {
- return baseDirectory.getFiles();
- }
- });
- for (final PsiFile psiFile : files) {
- if (baseName.equals(getBaseName(psiFile))) {
+ final ResourceBundleManager bundleBaseNameManager = ResourceBundleManager.getInstance(baseDirectory.getProject());
+ for (final PsiFile psiFile : baseDirectory.getFiles()) {
+ if (baseName.equals(bundleBaseNameManager.getBaseName(psiFile))) {
final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
if (propertiesFile != null) {
if (defaultPropertiesFile == null || defaultPropertiesFile.getName().compareTo(propertiesFile.getName()) > 0) {
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 ca5c8aa39a36..bad9957f7523 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
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
import java.util.List;
public class ResourceBundleImpl extends ResourceBundle {
@@ -39,12 +40,15 @@ public class ResourceBundleImpl extends ResourceBundle {
@NotNull
@Override
public List<PropertiesFile> getPropertiesFiles() {
+ if (ResourceBundleManager.getInstance(getProject()).isDefaultDissociated(myDefaultPropertiesFile.getVirtualFile())) {
+ return Collections.singletonList(myDefaultPropertiesFile);
+ }
PsiFile[] children = myDefaultPropertiesFile.getParent().getFiles();
final String baseName = getBaseName();
List<PropertiesFile> result = new SmartList<PropertiesFile>();
for (PsiFile file : children) {
if (!file.isValid() || file.getVirtualFile().getExtension() == null) continue;
- if (Comparing.strEqual(PropertiesUtil.getBaseName(file), baseName)) {
+ if (Comparing.strEqual(PropertiesUtil.getDefaultBaseName(file.getVirtualFile()), baseName)) {
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
if (propertiesFile != null) {
result.add(propertiesFile);
@@ -56,26 +60,14 @@ public class ResourceBundleImpl extends ResourceBundle {
@NotNull
@Override
- public List<PropertiesFile> 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 PropertiesUtil.getBaseName(myDefaultPropertiesFile.getContainingFile());
+ return ResourceBundleManager.getInstance(getProject()).getBaseName(myDefaultPropertiesFile.getContainingFile());
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java
new file mode 100644
index 000000000000..a01c123f8763
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManager.java
@@ -0,0 +1,256 @@
+/*
+ * 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.psi.PropertiesFile;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.NullableComputable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+
+/**
+ * @author Dmitry Batkovich
+ */
+@State(
+ name = "ResourceBundleManager",
+ storages = {
+ @Storage(file = StoragePathMacros.PROJECT_FILE),
+ @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/resourceBundles.xml", scheme = StorageScheme.DIRECTORY_BASED)
+ })
+public class ResourceBundleManager implements PersistentStateComponent<ResourceBundleManagerState> {
+ private final static Logger LOG = Logger.getInstance(ResourceBundleManager.class);
+ private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
+
+ private ResourceBundleManagerState myState = new ResourceBundleManagerState();
+
+ public ResourceBundleManager(final PsiManager manager) {
+ manager.addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
+ @Override
+ public void childMoved(@NotNull PsiTreeChangeEvent event) {
+ final PsiElement child = event.getChild();
+ if (!(child instanceof PsiFile)) {
+ return;
+ }
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile)child);
+ if (propertiesFile == null) {
+ return;
+ }
+ final String oldParentUrl = getUrl(event.getOldParent());
+ final String newParentUrl = getUrl(event.getNewParent());
+ if (oldParentUrl == null || newParentUrl == null) {
+ return;
+ }
+ final String newUrl = propertiesFile.getVirtualFile().getUrl();
+ final String oldUrl = oldParentUrl + newUrl.substring(newParentUrl.length());
+ if (myState.getDissociatedFiles().remove(oldUrl)) {
+ myState.getDissociatedFiles().add(newUrl);
+ }
+
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().remove(oldUrl)) {
+ customResourceBundleState.getFileUrls().add(newUrl);
+ break;
+ }
+ }
+ }
+
+ @Nullable
+ private String getUrl(PsiElement element) {
+ return !(element instanceof PsiDirectory) ? null : ((PsiDirectory)element).getVirtualFile().getUrl();
+ }
+
+ @Override
+ public void childReplaced(@NotNull PsiTreeChangeEvent event) {
+ super.childReplaced(event);
+ }
+
+ @Override
+ public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
+ super.beforeChildMovement(event);
+ }
+
+ @Override
+ public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
+ super.propertyChanged(event);
+ }
+
+ @Override
+ public void childRemoved(@NotNull PsiTreeChangeEvent event) {
+ final PsiElement child = event.getChild();
+ if (!(child instanceof PsiFile)) {
+ return;
+ }
+ PropertiesFile file = PropertiesImplUtil.getPropertiesFile((PsiFile)child);
+ if (file == null) {
+ return;
+ }
+ final VirtualFile virtualFile = file.getVirtualFile();
+ final String url = virtualFile.getUrl();
+ myState.getDissociatedFiles().remove(url);
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().remove(url)) {
+ if (customResourceBundleState.getFileUrls().size() < 2) {
+ myState.getCustomResourceBundles().remove(customResourceBundleState);
+ }
+ break;
+ }
+ }
+ }
+ });
+ }
+
+ public static ResourceBundleManager getInstance(final Project project) {
+ return ServiceManager.getService(project, ResourceBundleManager.class);
+ }
+
+ @Nullable
+ public String getFullName(final @NotNull PropertiesFile propertiesFile) {
+ return ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
+ public String compute() {
+ final PsiDirectory directory = propertiesFile.getParent();
+ final String packageQualifiedName = PropertiesUtil.getPackageQualifiedName(directory);
+ if (packageQualifiedName == null) {
+ return null;
+ }
+ final StringBuilder qName = new StringBuilder(packageQualifiedName);
+ if (qName.length() > 0) {
+ qName.append(".");
+ }
+ qName.append(getBaseName(propertiesFile.getContainingFile()));
+ return qName.toString();
+ }
+ });
+ }
+
+ @NotNull
+ public Locale getLocale(final @NotNull VirtualFile propertiesFile) {
+ final String customResourceBundleName = getCustomResourceBundleName(propertiesFile);
+
+ String name = propertiesFile.getName();
+ if (customResourceBundleName != null) {
+ name = name.substring(customResourceBundleName.length());
+ }
+
+ final Matcher matcher = PropertiesUtil.LOCALE_PATTERN.matcher(name);
+ if (matcher.find()) {
+ final String rawLocale = matcher.group(1);
+ final String[] splittedRawLocale = rawLocale.split("_");
+ if (splittedRawLocale.length > 1 && splittedRawLocale[1].length() >= 2) {
+ final String language = splittedRawLocale[1];
+ final String country = splittedRawLocale.length > 2 ? splittedRawLocale[2] : "";
+ final String variant = splittedRawLocale.length > 3 ? splittedRawLocale[3] : "";
+ return new Locale(language, country, variant);
+ }
+ }
+ return DEFAULT_LOCALE;
+ }
+
+ @NotNull
+ public String getBaseName(@NotNull final PsiFile file) {
+ return getBaseName(file.getVirtualFile());
+ }
+
+ @NotNull
+ private String getBaseName(@NotNull final VirtualFile file) {
+ final CustomResourceBundleState customResourceBundle = getCustomResourceBundleState(file);
+ if (customResourceBundle != null) {
+ return customResourceBundle.getBaseName();
+ }
+ if (isDefaultDissociated(file)) {
+ return file.getNameWithoutExtension();
+ }
+ return PropertiesUtil.getDefaultBaseName(file);
+ }
+
+
+ public void dissociateResourceBundle(final @NotNull ResourceBundle resourceBundle) {
+ if (resourceBundle instanceof CustomResourceBundle) {
+ final CustomResourceBundleState state =
+ getCustomResourceBundleState(resourceBundle.getDefaultPropertiesFile().getVirtualFile());
+ LOG.assertTrue(state != null);
+ myState.getCustomResourceBundles().remove(state);
+ } else {
+ for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
+ final VirtualFile file = propertiesFile.getContainingFile().getVirtualFile();
+ myState.getDissociatedFiles().add(file.getUrl());
+ }
+ }
+ }
+
+ public void combineToResourceBundle(final @NotNull List<PropertiesFile> propertiesFiles, final String baseName) {
+ myState.getCustomResourceBundles()
+ .add(new CustomResourceBundleState().addAll(ContainerUtil.map(propertiesFiles, new Function<PropertiesFile, String>() {
+ @Override
+ public String fun(PropertiesFile file) {
+ return file.getVirtualFile().getUrl();
+ }
+ })).setBaseName(baseName));
+ }
+
+ @Nullable
+ public CustomResourceBundle getCustomResourceBundle(final @NotNull PropertiesFile file) {
+ final VirtualFile virtualFile = file.getVirtualFile();
+ if (virtualFile == null) {
+ return null;
+ }
+ final CustomResourceBundleState state = getCustomResourceBundleState(virtualFile);
+ return state == null ? null : CustomResourceBundle.fromState(state, file.getProject());
+ }
+
+ public boolean isDefaultDissociated(final @NotNull VirtualFile virtualFile) {
+ final String url = virtualFile.getUrl();
+ return myState.getDissociatedFiles().contains(url) || getCustomResourceBundleState(virtualFile) != null;
+ }
+
+ @Nullable
+ private String getCustomResourceBundleName(final @NotNull VirtualFile virtualFile) {
+ final CustomResourceBundleState customResourceBundle = getCustomResourceBundleState(virtualFile);
+ return customResourceBundle == null ? null : customResourceBundle.getBaseName();
+ }
+
+ @Nullable
+ private CustomResourceBundleState getCustomResourceBundleState(final @NotNull VirtualFile virtualFile) {
+ final String url = virtualFile.getUrl();
+ for (CustomResourceBundleState customResourceBundleState : myState.getCustomResourceBundles()) {
+ if (customResourceBundleState.getFileUrls().contains(url)) {
+ return customResourceBundleState;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public ResourceBundleManagerState getState() {
+ return myState.isEmpty() ? null : myState;
+ }
+
+ @Override
+ public void loadState(ResourceBundleManagerState state) {
+ myState = state.removeNonExistentFiles();
+ }
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java
new file mode 100644
index 000000000000..c4d1e5c5cb2d
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleManagerState.java
@@ -0,0 +1,72 @@
+/*
+ * 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.openapi.vfs.VirtualFileManager;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Property;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleManagerState {
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(elementValueAttribute = "url", elementTag = "file", surroundWithTag = false)
+ public Set<String> myDissociatedFiles = new HashSet<String>();
+
+ @Property(surroundWithTag = false)
+ @AbstractCollection(elementTag = "custom-rb", surroundWithTag = false)
+ public List<CustomResourceBundleState> myCustomResourceBundles = new ArrayList<CustomResourceBundleState>();
+
+ public Set<String> getDissociatedFiles() {
+ return myDissociatedFiles;
+ }
+
+ public List<CustomResourceBundleState> getCustomResourceBundles() {
+ return myCustomResourceBundles;
+ }
+
+ public boolean isEmpty() {
+ return myCustomResourceBundles.isEmpty() && myDissociatedFiles.isEmpty();
+ }
+
+ public ResourceBundleManagerState removeNonExistentFiles() {
+ final ResourceBundleManagerState newState = new ResourceBundleManagerState();
+
+ final VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
+
+ for (final String dissociatedFileUrl : myDissociatedFiles) {
+ if (virtualFileManager.findFileByUrl(dissociatedFileUrl) != null) {
+ newState.myDissociatedFiles.add(dissociatedFileUrl);
+ }
+ }
+
+ for (CustomResourceBundleState customResourceBundle : myCustomResourceBundles) {
+ final CustomResourceBundleState updatedCustomResourceBundle = customResourceBundle.removeNonExistentFiles(virtualFileManager);
+ if (updatedCustomResourceBundle != null) {
+ newState.myCustomResourceBundles.add(updatedCustomResourceBundle);
+ }
+ }
+
+ return newState;
+ }
+}
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 724a794ca3bb..14cb1cb940c4 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,11 +20,8 @@
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.*;
import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.psi.Property;
import com.intellij.navigation.ColoredItemPresentation;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -62,7 +59,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
@Override
public PsiElement[] getPsiElements() {
- return new PsiElement[] {getProperty().getPsiElement()};
+ return new PsiElement[] {getValue()};
}
public void setPresentableName(final String presentableName) {
@@ -70,8 +67,8 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
}
@Override
- public Property getValue() {
- return (Property)myProperty.getPsiElement();
+ public PsiElement getValue() {
+ return myProperty.getPsiElement();
}
@Override
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 759ce6cb46fb..99d06e8da06b 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
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
import com.intellij.lang.properties.*;
import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.parsing.PropertiesElementTypes;
import com.intellij.lang.properties.psi.PropertiesElementFactory;
import com.intellij.lang.properties.psi.PropertiesFile;
@@ -120,7 +121,7 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
@Override
@NotNull
public Locale getLocale() {
- return PropertiesUtil.getLocale(getVirtualFile());
+ return ResourceBundleManager.getInstance(getProject()).getLocale(getVirtualFile());
}
@Override
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
index 4b8953f47e9c..6c2453b94144 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
@@ -17,8 +17,8 @@ package com.intellij.lang.properties.xml;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesImplUtil;
-import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.project.Project;
@@ -107,7 +107,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@NotNull
@Override
public Locale getLocale() {
- return PropertiesUtil.getLocale(getVirtualFile());
+ return ResourceBundleManager.getInstance(getProject()).getLocale(getVirtualFile());
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
index f946e41c26ae..52d4d5934b40 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
@@ -25,6 +25,7 @@ import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.lang.properties.*;
+import com.intellij.lang.properties.ResourceBundleManager;
import com.intellij.lang.properties.editor.PropertiesFoldingBuilder;
import com.intellij.lang.properties.findUsages.PropertiesFindUsagesProvider;
import com.intellij.lang.properties.parsing.PropertiesElementTypes;
@@ -87,6 +88,7 @@ public class PropertiesCoreEnvironment {
public ProjectEnvironment(CoreProjectEnvironment projectEnvironment) {
projectEnvironment.getProject().registerService(PropertiesReferenceManager.class);
projectEnvironment.getProject().registerService(PropertiesSeparatorManager.class);
+ projectEnvironment.getProject().registerService(ResourceBundleManager.class);
}
}
}