/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java

https://bitbucket.org/nbargnesi/idea · Java · 139 lines · 106 code · 18 blank · 15 comment · 13 complexity · 03b6da5437b316ea7ee8e6e3b7909c3e MD5 · raw file

  1. /*
  2. * Copyright 2000-2009 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jetbrains.idea.maven.dom;
  17. import com.intellij.javaee.ExternalResourceManager;
  18. import com.intellij.openapi.components.ServiceManager;
  19. import com.intellij.openapi.diagnostic.Logger;
  20. import com.intellij.openapi.project.Project;
  21. import com.intellij.openapi.vfs.VfsUtil;
  22. import com.intellij.openapi.vfs.VirtualFile;
  23. import com.intellij.psi.PsiFile;
  24. import com.intellij.psi.PsiManager;
  25. import com.intellij.psi.util.CachedValue;
  26. import com.intellij.psi.util.CachedValueProvider;
  27. import com.intellij.psi.util.CachedValuesManager;
  28. import com.intellij.psi.util.PsiModificationTracker;
  29. import com.intellij.psi.xml.XmlFile;
  30. import com.intellij.psi.xml.XmlTag;
  31. import com.intellij.xml.XmlElementDescriptor;
  32. import com.intellij.xml.impl.schema.XmlNSDescriptorImpl;
  33. import gnu.trove.THashMap;
  34. import org.jetbrains.annotations.NotNull;
  35. import org.jetbrains.annotations.Nullable;
  36. import java.net.MalformedURLException;
  37. import java.net.URL;
  38. import java.util.Map;
  39. public class MavenDomElementDescriptorHolder {
  40. private static final Logger LOG = Logger.getInstance(MavenDomElementDescriptorHolder.class);
  41. private enum FileKind {
  42. PROJECT_FILE {
  43. public String getSchemaUrl() {
  44. return MavenSchemaProvider.MAVEN_PROJECT_SCHEMA_URL;
  45. }
  46. },
  47. PROFILES_FILE {
  48. public String getSchemaUrl() {
  49. return MavenSchemaProvider.MAVEN_PROFILES_SCHEMA_URL;
  50. }
  51. },
  52. SETTINGS_FILE {
  53. public String getSchemaUrl() {
  54. return MavenSchemaProvider.MAVEN_SETTINGS_SCHEMA_URL;
  55. }
  56. };
  57. public abstract String getSchemaUrl();
  58. }
  59. private final Project myProject;
  60. private final Map<FileKind, CachedValue<XmlNSDescriptorImpl>> myDescriptorsMap =
  61. new THashMap<FileKind, CachedValue<XmlNSDescriptorImpl>>();
  62. public MavenDomElementDescriptorHolder(Project project) {
  63. myProject = project;
  64. }
  65. public static MavenDomElementDescriptorHolder getInstance(@NotNull Project project) {
  66. return ServiceManager.getService(project, MavenDomElementDescriptorHolder.class);
  67. }
  68. @Nullable
  69. public XmlElementDescriptor getDescriptor(@NotNull XmlTag tag) {
  70. FileKind kind = getFileKind(tag.getContainingFile());
  71. if (kind == null) return null;
  72. XmlNSDescriptorImpl desc;
  73. synchronized (this) {
  74. desc = tryGetOrCreateDescriptor(kind);
  75. if (desc == null) return null;
  76. }
  77. LOG.assertTrue(tag.isValid());
  78. LOG.assertTrue(desc.isValid());
  79. return desc.getElementDescriptor(tag.getName(), desc.getDefaultNamespace());
  80. }
  81. @Nullable
  82. private XmlNSDescriptorImpl tryGetOrCreateDescriptor(final FileKind kind) {
  83. CachedValue<XmlNSDescriptorImpl> result = myDescriptorsMap.get(kind);
  84. if (result == null) {
  85. result = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<XmlNSDescriptorImpl>() {
  86. @Override
  87. public Result<XmlNSDescriptorImpl> compute() {
  88. return Result.create(doCreateDescriptor(kind), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
  89. }
  90. }, false);
  91. myDescriptorsMap.put(kind, result);
  92. }
  93. return result.getValue();
  94. }
  95. @Nullable
  96. private XmlNSDescriptorImpl doCreateDescriptor(FileKind kind) {
  97. String schemaUrl = kind.getSchemaUrl();
  98. String location = ExternalResourceManager.getInstance().getResourceLocation(schemaUrl);
  99. if (schemaUrl.equals(location)) return null;
  100. VirtualFile schema;
  101. try {
  102. schema = VfsUtil.findFileByURL(new URL(location));
  103. }
  104. catch (MalformedURLException ignore) {
  105. return null;
  106. }
  107. if (schema == null) return null;
  108. PsiFile psiFile = PsiManager.getInstance(myProject).findFile(schema);
  109. if (!(psiFile instanceof XmlFile)) return null;
  110. XmlNSDescriptorImpl result = new XmlNSDescriptorImpl();
  111. result.init(psiFile);
  112. return result;
  113. }
  114. @Nullable
  115. private FileKind getFileKind(PsiFile file) {
  116. if (MavenDomUtil.isProjectFile(file)) return FileKind.PROJECT_FILE;
  117. if (MavenDomUtil.isProfilesFile(file)) return FileKind.PROFILES_FILE;
  118. if (MavenDomUtil.isSettingsFile(file)) return FileKind.SETTINGS_FILE;
  119. return null;
  120. }
  121. }