9e55c009dd2987cc68fcf97000ae68abe822ec41
[fedora-idea.git] / plugins / maven / src / main / java / org / jetbrains / idea / maven / dom / MavenDomUtil.java
blob9e55c009dd2987cc68fcf97000ae68abe822ec41
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.jetbrains.idea.maven.dom;
18 import com.intellij.lang.properties.psi.PropertiesFile;
19 import com.intellij.lang.properties.psi.Property;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.util.Pair;
22 import com.intellij.openapi.util.io.FileUtil;
23 import com.intellij.openapi.util.text.StringUtil;
24 import com.intellij.openapi.vfs.LocalFileSystem;
25 import com.intellij.openapi.vfs.VfsUtil;
26 import com.intellij.openapi.vfs.VirtualFile;
27 import com.intellij.openapi.vfs.VirtualFileSystem;
28 import com.intellij.psi.PsiElement;
29 import com.intellij.psi.PsiFile;
30 import com.intellij.psi.PsiManager;
31 import com.intellij.psi.util.PsiTreeUtil;
32 import com.intellij.psi.search.GlobalSearchScope;
33 import com.intellij.psi.xml.XmlElement;
34 import com.intellij.psi.xml.XmlFile;
35 import com.intellij.psi.xml.XmlTag;
36 import com.intellij.util.xml.*;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
39 import org.jetbrains.idea.maven.dom.model.*;
40 import org.jetbrains.idea.maven.project.MavenId;
41 import org.jetbrains.idea.maven.project.MavenProject;
42 import org.jetbrains.idea.maven.project.MavenProjectsManager;
43 import org.jetbrains.idea.maven.project.MavenResource;
44 import org.jetbrains.idea.maven.utils.MavenConstants;
45 import org.jetbrains.idea.maven.vfs.MavenPropertiesVirtualFileSystem;
47 import java.io.File;
48 import java.util.List;
49 import java.util.regex.Matcher;
50 import java.util.regex.Pattern;
52 public class MavenDomUtil {
53 public static boolean isMavenFile(PsiFile file) {
54 return isProjectFile(file) || isProfilesFile(file) || isSettingsFile(file);
57 public static boolean isProjectFile(PsiFile file) {
58 if (!(file instanceof XmlFile)) return false;
60 String name = file.getName();
61 return name.equals(MavenConstants.POM_XML)
62 || name.endsWith("." + MavenConstants.POM_EXTENSION)
63 || name.equals(MavenConstants.SUPER_POM_XML);
66 public static boolean isProfilesFile(PsiFile file) {
67 if (!(file instanceof XmlFile)) return false;
69 String name = file.getName();
70 return name.equals(MavenConstants.PROFILES_XML);
73 public static boolean isSettingsFile(PsiFile file) {
74 if (!(file instanceof XmlFile)) return false;
76 String name = file.getName();
77 return name.equals(MavenConstants.SETTINGS_XML);
80 public static boolean isMavenFile(PsiElement element) {
81 return isMavenFile(element.getContainingFile());
84 public static boolean isMavenProperty(PsiElement target) {
85 XmlTag tag = PsiTreeUtil.getParentOfType(target, XmlTag.class, false);
86 if (tag == null) return false;
87 return DomUtil.findDomElement(tag, MavenDomProperties.class) != null;
90 public static String calcRelativePath(VirtualFile parent, VirtualFile child) {
91 String result = FileUtil.getRelativePath(new File(parent.getPath()),
92 new File(child.getPath()));
93 return FileUtil.toSystemIndependentName(result);
96 public static MavenDomParent updateMavenParent(MavenDomProjectModel mavenModel, MavenProject parentProject) {
97 MavenDomParent result = mavenModel.getMavenParent();
99 VirtualFile pomFile = DomUtil.getFile(mavenModel).getVirtualFile();
100 Project project = mavenModel.getXmlElement().getProject();
102 MavenId parentId = parentProject.getMavenId();
103 result.getGroupId().setStringValue(parentId.getGroupId());
104 result.getArtifactId().setStringValue(parentId.getArtifactId());
105 result.getVersion().setStringValue(parentId.getVersion());
107 if (pomFile.getParent().getParent() != parentProject.getDirectoryFile()) {
108 result.getRelativePath().setValue(PsiManager.getInstance(project).findFile(parentProject.getFile()));
111 return result;
114 public static <T> T getImmediateParent(ConvertContext context, Class<T> clazz) {
115 DomElement parentElement = context.getInvocationElement().getParent();
116 return clazz.isInstance(parentElement) ? (T)parentElement : null;
119 @Nullable
120 public static VirtualFile getVirtualFile(@NotNull DomElement element) {
121 PsiFile psiFile = DomUtil.getFile(element);
122 return getVirtualFile(psiFile);
125 @Nullable
126 public static VirtualFile getVirtualFile(@NotNull PsiElement element) {
127 PsiFile psiFile = element.getContainingFile();
128 return getVirtualFile(psiFile);
131 @Nullable
132 private static VirtualFile getVirtualFile(PsiFile psiFile) {
133 if (psiFile == null) return null;
134 psiFile = psiFile.getOriginalFile();
135 return psiFile.getVirtualFile();
138 @Nullable
139 public static MavenProject findProject(@NotNull MavenDomProjectModel projectDom) {
140 XmlElement element = projectDom.getXmlElement();
141 if (element == null) return null;
143 VirtualFile file = getVirtualFile(element);
144 if (file == null) return null;
145 MavenProjectsManager manager = MavenProjectsManager.getInstance(element.getProject());
146 return manager.findProject(file);
149 @Nullable
150 public static MavenProject findContainingProject(@NotNull PsiElement element) {
151 VirtualFile file = getVirtualFile(element);
152 if (file == null) return null;
153 MavenProjectsManager manager = MavenProjectsManager.getInstance(element.getProject());
154 return manager.findContainingProject(file);
157 @Nullable
158 public static MavenDomProjectModel getMavenDomProjectModel(@NotNull Project project, @NotNull VirtualFile file) {
159 return getMavenDomModel(project, file, MavenDomProjectModel.class);
162 @Nullable
163 public static MavenDomProfiles getMavenDomProfilesModel(@NotNull Project project, @NotNull VirtualFile file) {
164 MavenDomProfilesModel model = getMavenDomModel(project, file, MavenDomProfilesModel.class);
165 if (model != null) return model.getProfiles();
166 return getMavenDomModel(project, file, MavenDomProfiles.class); // try old-style model
169 @Nullable
170 public static <T extends MavenDomElement> T getMavenDomModel(@NotNull Project project,
171 @NotNull VirtualFile file,
172 @NotNull Class<T> clazz) {
173 PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
174 if (psiFile == null) return null;
175 return getMavenDomModel(psiFile, clazz);
178 @Nullable
179 public static <T extends MavenDomElement> T getMavenDomModel(@NotNull PsiFile file, @NotNull Class<T> clazz) {
180 DomFileElement<T> fileElement = getMavenDomFile(file, clazz);
181 return fileElement == null ? null : fileElement.getRootElement();
184 @Nullable
185 private static <T extends MavenDomElement> DomFileElement<T> getMavenDomFile(@NotNull PsiFile file, @NotNull Class<T> clazz) {
186 if (!(file instanceof XmlFile)) return null;
187 return DomManager.getDomManager(file.getProject()).getFileElement((XmlFile)file, clazz);
190 @Nullable
191 public static XmlTag findTag(@NotNull DomElement domElement, @NotNull String path) {
192 List<String> elements = StringUtil.split(path, ".");
193 if (elements.isEmpty()) return null;
195 Pair<String, Integer> nameAndIndex = translateTagName(elements.get(0));
196 String name = nameAndIndex.first;
197 Integer index = nameAndIndex.second;
199 XmlTag result = domElement.getXmlTag();
200 if (result == null || !name.equals(result.getName())) return null;
201 result = getIndexedTag(result, index);
203 for (String each : elements.subList(1, elements.size())) {
204 nameAndIndex = translateTagName(each);
205 name = nameAndIndex.first;
206 index = nameAndIndex.second;
208 result = result.findFirstSubTag(name);
209 if (result == null) return null;
210 result = getIndexedTag(result, index);
212 return result;
215 private static final Pattern XML_TAG_NAME_PATTERN = Pattern.compile("(\\S*)\\[(\\d*)\\]\\z");
217 private static Pair<String, Integer> translateTagName(String text) {
218 String tagName = text.trim();
219 Integer index = null;
221 Matcher matcher = XML_TAG_NAME_PATTERN.matcher(tagName);
222 if (matcher.find()) {
223 tagName = matcher.group(1);
224 try {
225 index = Integer.parseInt(matcher.group(2));
227 catch (NumberFormatException e) {
228 return null;
232 return Pair.create(tagName, index);
235 private static XmlTag getIndexedTag(XmlTag parent, Integer index) {
236 if (index == null) return parent;
238 XmlTag[] children = parent.getSubTags();
239 if (index < 0 || index >= children.length) return null;
240 return children[index];
243 @Nullable
244 public static PropertiesFile getPropertiesFile(@NotNull Project project, @NotNull String fileName) {
245 VirtualFileSystem fs = MavenPropertiesVirtualFileSystem.getInstance();
246 VirtualFile file = fs.findFileByPath(fileName);
247 if (file == null) return null;
248 return getPropertiesFile(project, file);
251 @Nullable
252 public static PropertiesFile getPropertiesFile(@NotNull Project project, @NotNull VirtualFile file) {
253 PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
254 if (!(psiFile instanceof PropertiesFile)) return null;
255 return (PropertiesFile)psiFile;
258 @Nullable
259 public static Property findProperty(@NotNull Project project, @NotNull String fileName, @NotNull String propName) {
260 PropertiesFile propertiesFile = getPropertiesFile(project, fileName);
261 return propertiesFile == null ? null : propertiesFile.findPropertyByKey(propName);
264 @Nullable
265 public static Property findProperty(@NotNull Project project, @NotNull VirtualFile file, @NotNull String propName) {
266 PropertiesFile propertiesFile = getPropertiesFile(project, file);
267 return propertiesFile == null ? null : propertiesFile.findPropertyByKey(propName);
270 @Nullable
271 public static PsiElement findPropertyValue(@NotNull Project project, @NotNull VirtualFile file, @NotNull String propName) {
272 Property prop = findProperty(project, file, propName);
273 return prop == null ? null : prop.getFirstChild().getNextSibling().getNextSibling();
276 public static boolean isFiltererResourceFile(PsiElement element) {
277 MavenProject project = findContainingProject(element);
278 if (project == null) return false;
280 VirtualFile file = MavenDomUtil.getVirtualFile(element);
281 if (file == null) return false;
283 for (MavenResource each : project.getResources()) {
284 VirtualFile resourceDir = LocalFileSystem.getInstance().findFileByPath(each.getDirectory());
285 if (resourceDir == null) continue;
286 if (!VfsUtil.isAncestor(resourceDir, file, true)) continue;
287 return each.isFiltered();
289 return false;
292 public static List<DomFileElement<MavenDomProjectModel>> collectProjectModels(Project p) {
293 return DomService.getInstance().getFileElements(MavenDomProjectModel.class, p, GlobalSearchScope.projectScope(p));
296 public static MavenId describe(PsiFile psiFile) {
297 MavenDomProjectModel model = getMavenDomModel(psiFile, MavenDomProjectModel.class);
299 String groupId = model.getGroupId().getStringValue();
300 String artifactId = model.getArtifactId().getStringValue();
301 String version = model.getVersion().getStringValue();
303 if (groupId == null) {
304 groupId = model.getMavenParent().getGroupId().getStringValue();
307 if (version == null) {
308 version = model.getMavenParent().getVersion().getStringValue();
311 return new MavenId(groupId, artifactId, version);