summaryrefslogtreecommitdiff
path: root/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
blob: b29fc4f78141c65b13cb2f9ef2f2da7ba135d2dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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.lang.properties.psi.PropertyKeyIndex;
import com.intellij.lang.properties.xml.XmlPropertiesFileImpl;
import com.intellij.lang.properties.xml.XmlPropertiesIndex;
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.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;

/**
 * @author Konstantin Bulenkov
 */
public class PropertiesImplUtil extends PropertiesUtil {

  @Nullable
  public static ResourceBundle getResourceBundle(@NotNull final PropertiesFile representative) {
    final PsiFile containingFile = representative.getContainingFile();
    if (!containingFile.isValid()) {
      return EmptyResourceBundle.getInstance();
    }
    final String baseName = getBaseName(containingFile);
    final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
      @Nullable
      public PsiDirectory compute() {
        return containingFile.getContainingDirectory();
      }});
    if (directory == null) return EmptyResourceBundle.getInstance();
    return getResourceBundle(baseName, directory);
  }

  @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(@Nullable PsiFile file) {
    return getPropertiesFile(file) != null;
  }

  @Nullable
  public static PropertiesFile getPropertiesFile(@Nullable PsiFile file) {
    if (file == null) return null;
    return file instanceof PropertiesFile ? (PropertiesFile)file : XmlPropertiesFileImpl.getPropertiesFile(file);
  }

  @NotNull
  public static List<IProperty> findPropertiesByKey(@NotNull final Project project, @NotNull final String key) {
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
    final ArrayList<IProperty> properties =
      new ArrayList<IProperty>(PropertyKeyIndex.getInstance().get(key, project, scope));
    final Set<VirtualFile> files = new HashSet<VirtualFile>();
    FileBasedIndex.getInstance().processValues(XmlPropertiesIndex.NAME, new XmlPropertiesIndex.Key(key), null, new FileBasedIndex.ValueProcessor<String>() {
      @Override
      public boolean process(VirtualFile file, String value) {
        if (files.add(file)) {
          PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
          PropertiesFile propertiesFile = XmlPropertiesFileImpl.getPropertiesFile(psiFile);
          if (propertiesFile != null) {
            properties.addAll(propertiesFile.findPropertiesByKey(key));
          }
        }
        return false;
      }
    }, scope);
    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);
  }
}