| /* |
| * Copyright 2000-2009 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 org.jetbrains.idea.maven.dom; |
| |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.xml.XmlElement; |
| import com.intellij.psi.xml.XmlTag; |
| import org.jdom.Element; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.idea.maven.dom.model.MavenDomProfile; |
| import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; |
| import org.jetbrains.idea.maven.dom.model.MavenDomProperties; |
| import org.jetbrains.idea.maven.dom.references.MavenFilteredPropertyPsiReferenceProvider; |
| import org.jetbrains.idea.maven.model.MavenId; |
| import org.jetbrains.idea.maven.project.MavenProject; |
| import org.jetbrains.idea.maven.project.MavenProjectsManager; |
| import org.jetbrains.idea.maven.server.MavenServerUtil; |
| import org.jetbrains.idea.maven.utils.MavenJDOMUtil; |
| import org.jetbrains.idea.maven.utils.MavenUtil; |
| import org.jetbrains.jps.maven.compiler.MavenEscapeWindowsCharacterUtils; |
| |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| public class MavenPropertyResolver { |
| public static final Pattern PATTERN = Pattern.compile("\\$\\{(.+?)\\}|@(.+?)@"); |
| |
| public static void doFilterText(Module module, |
| String text, |
| Properties additionalProperties, |
| @Nullable String propertyEscapeString, |
| Appendable out) throws IOException { |
| MavenProjectsManager manager = MavenProjectsManager.getInstance(module.getProject()); |
| MavenProject mavenProject = manager.findProject(module); |
| if (mavenProject == null) { |
| out.append(text); |
| return; |
| } |
| |
| Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"); |
| String escapeWindowsPathsStr = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths"); |
| boolean escapeWindowsPath = escapeWindowsPathsStr == null || Boolean.parseBoolean(escapeWindowsPathsStr); |
| |
| doFilterText(MavenFilteredPropertyPsiReferenceProvider.getDelimitersPattern(mavenProject), |
| manager, |
| mavenProject, |
| text, |
| additionalProperties, |
| propertyEscapeString, |
| escapeWindowsPath, |
| null, |
| out); |
| } |
| |
| private static void doFilterText(Pattern pattern, |
| MavenProjectsManager mavenProjectsManager, |
| MavenProject mavenProject, |
| String text, |
| Properties additionalProperties, |
| @Nullable String escapeString, |
| boolean escapeWindowsPath, |
| @Nullable Map<String, String> resolvedPropertiesParam, |
| Appendable out) throws IOException { |
| Map<String, String> resolvedProperties = resolvedPropertiesParam; |
| |
| Matcher matcher = pattern.matcher(text); |
| int groupCount = matcher.groupCount(); |
| |
| int last = 0; |
| while (matcher.find()) { |
| if (escapeString != null) { |
| int escapeStringStartIndex = matcher.start() - escapeString.length(); |
| if (escapeStringStartIndex >= last) { |
| if (text.startsWith(escapeString, escapeStringStartIndex)) { |
| out.append(text, last, escapeStringStartIndex); |
| out.append(matcher.group()); |
| last = matcher.end(); |
| continue; |
| } |
| } |
| } |
| |
| out.append(text, last, matcher.start()); |
| last = matcher.end(); |
| |
| String propertyName = null; |
| |
| for (int i = 0; i < groupCount; i++) { |
| propertyName = matcher.group(i + 1); |
| if (propertyName != null) { |
| break; |
| } |
| } |
| |
| assert propertyName != null; |
| |
| if (resolvedProperties == null) { |
| resolvedProperties = new HashMap<String, String>(); |
| } |
| |
| String propertyValue = resolvedProperties.get(propertyName); |
| if (propertyValue == null) { |
| if (resolvedProperties.containsKey(propertyName)) { // if cyclic property dependencies |
| out.append(matcher.group()); |
| continue; |
| } |
| |
| String resolved = doResolveProperty(propertyName, mavenProjectsManager, mavenProject, additionalProperties); |
| if (resolved == null) { |
| out.append(matcher.group()); |
| continue; |
| } |
| |
| resolvedProperties.put(propertyName, null); |
| |
| StringBuilder sb = new StringBuilder(); |
| doFilterText(pattern, mavenProjectsManager, mavenProject, resolved, additionalProperties, null, escapeWindowsPath, resolvedProperties, sb); |
| propertyValue = sb.toString(); |
| |
| resolvedProperties.put(propertyName, propertyValue); |
| } |
| |
| if (escapeWindowsPath) { |
| MavenEscapeWindowsCharacterUtils.escapeWindowsPath(out, propertyValue); |
| } |
| else { |
| out.append(propertyValue); |
| } |
| } |
| |
| out.append(text, last, text.length()); |
| } |
| |
| public static String resolve(String text, MavenDomProjectModel projectDom) { |
| XmlElement element = projectDom.getXmlElement(); |
| if (element == null) return text; |
| |
| VirtualFile file = MavenDomUtil.getVirtualFile(element); |
| if (file == null) return text; |
| MavenProjectsManager manager = MavenProjectsManager.getInstance(projectDom.getManager().getProject()); |
| |
| MavenProject mavenProject = manager.findProject(file); |
| if (mavenProject == null) return text; |
| |
| StringBuilder res = new StringBuilder(); |
| try { |
| doFilterText(PATTERN, manager, mavenProject, text, collectPropertiesFromDOM(mavenProject, projectDom), null, false, null, res); |
| } |
| catch (IOException e) { |
| throw new RuntimeException(e); // never thrown |
| } |
| |
| return res.toString(); |
| } |
| |
| private static Properties collectPropertiesFromDOM(MavenProject project, MavenDomProjectModel projectDom) { |
| Properties result = new Properties(); |
| |
| collectPropertiesFromDOM(projectDom.getProperties(), result); |
| |
| Collection<String> activeProfiles = project.getActivatedProfilesIds().getEnabledProfiles(); |
| for (MavenDomProfile each : projectDom.getProfiles().getProfiles()) { |
| XmlTag idTag = each.getId().getXmlTag(); |
| if (idTag == null || !activeProfiles.contains(idTag.getValue().getTrimmedText())) continue; |
| collectPropertiesFromDOM(each.getProperties(), result); |
| } |
| |
| return result; |
| } |
| |
| private static void collectPropertiesFromDOM(MavenDomProperties props, Properties result) { |
| XmlTag propsTag = props.getXmlTag(); |
| if (propsTag != null) { |
| for (XmlTag each : propsTag.getSubTags()) { |
| result.setProperty(each.getName(), each.getValue().getTrimmedText()); |
| } |
| } |
| } |
| |
| @Nullable |
| private static String doResolveProperty(String propName, |
| MavenProjectsManager projectsManager, |
| MavenProject mavenProject, |
| Properties additionalProperties) { |
| boolean hasPrefix = false; |
| String unprefixed = propName; |
| |
| if (propName.startsWith("pom.")) { |
| unprefixed = propName.substring("pom.".length()); |
| hasPrefix = true; |
| } |
| else if (propName.startsWith("project.")) { |
| unprefixed = propName.substring("project.".length()); |
| hasPrefix = true; |
| } |
| |
| MavenProject selectedProject = mavenProject; |
| |
| while (unprefixed.startsWith("parent.")) { |
| MavenId parentId = selectedProject.getParentId(); |
| if (parentId == null) return null; |
| |
| unprefixed = unprefixed.substring("parent.".length()); |
| |
| if (unprefixed.equals("groupId")) { |
| return parentId.getGroupId(); |
| } |
| if (unprefixed.equals("artifactId")) { |
| return parentId.getArtifactId(); |
| } |
| if (unprefixed.equals("version")) { |
| return parentId.getVersion(); |
| } |
| |
| selectedProject = projectsManager.findProject(parentId); |
| if (selectedProject == null) return null; |
| } |
| |
| if (unprefixed.equals("basedir") || (hasPrefix && mavenProject == selectedProject && unprefixed.equals("baseUri"))) { |
| return selectedProject.getDirectory(); |
| } |
| |
| if ("java.home".equals(propName)) { |
| String jreDir = MavenUtil.getModuleJreHome(projectsManager, mavenProject); |
| if (jreDir != null) { |
| return jreDir; |
| } |
| } |
| |
| if ("java.version".equals(propName)) { |
| String javaVersion = MavenUtil.getModuleJavaVersion(projectsManager, mavenProject); |
| if (javaVersion != null) { |
| return javaVersion; |
| } |
| } |
| |
| String result; |
| |
| result = MavenUtil.getPropertiesFromMavenOpts().get(propName); |
| if (result != null) return result; |
| |
| result = MavenServerUtil.collectSystemProperties().getProperty(propName); |
| if (result != null) return result; |
| |
| result = selectedProject.getModelMap().get(unprefixed); |
| if (result != null) return result; |
| |
| result = additionalProperties.getProperty(propName); |
| if (result != null) return result; |
| |
| result = mavenProject.getProperties().getProperty(propName); |
| if (result != null) return result; |
| |
| if ("settings.localRepository".equals(propName)) { |
| return mavenProject.getLocalRepository().getAbsolutePath(); |
| } |
| |
| return null; |
| } |
| } |