/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.api.batch.bootstrap; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import javax.annotation.CheckForNull; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; /** * Defines project metadata (key, name, source directories, ...). It's generally used by the * {@link org.sonar.api.batch.bootstrap.ProjectBuilder extension point} and must not be used * by other standard extensions. * * @since 2.9 */ public class ProjectDefinition { public static final String SOURCES_PROPERTY = "sonar.sources"; public static final String TESTS_PROPERTY = "sonar.tests"; public static final String BUILD_DIR_PROPERTY = "sonar.buildDir"; private static final char SEPARATOR = ','; private File baseDir; private File workDir; private File buildDir; private Map<String, String> properties = new HashMap<>(); private ProjectDefinition parent = null; private List<ProjectDefinition> subProjects = new ArrayList<>(); private ProjectDefinition(Properties p) { for (Entry<Object, Object> entry : p.entrySet()) { this.properties.put(entry.getKey().toString(), entry.getValue().toString()); } } public static ProjectDefinition create() { return new ProjectDefinition(new Properties()); } public ProjectDefinition setBaseDir(File baseDir) { this.baseDir = baseDir; return this; } public File getBaseDir() { return baseDir; } public ProjectDefinition setWorkDir(File workDir) { this.workDir = workDir; return this; } public File getWorkDir() { return workDir; } /** * @deprecated since 6.1 notion of buildDir is not well defined */ @Deprecated public ProjectDefinition setBuildDir(File d) { this.buildDir = d; return this; } /** * @deprecated since 6.1 notion of buildDir is not well defined */ @Deprecated public File getBuildDir() { return buildDir; } /** * @deprecated since 5.0 use {@link #properties()} */ @Deprecated public Properties getProperties() { Properties result = new Properties(); for (Map.Entry<String, String> entry : properties.entrySet()) { result.setProperty(entry.getKey(), entry.getValue()); } return result; } public Map<String, String> properties() { return properties; } /** * Copies specified properties into this object. * * @since 2.12 * @deprecated since 5.0 use {@link #setProperties(Map)} */ @Deprecated public ProjectDefinition setProperties(Properties properties) { for (Entry<Object, Object> entry : properties.entrySet()) { this.properties.put(entry.getKey().toString(), entry.getValue().toString()); } return this; } public ProjectDefinition setProperties(Map<String, String> properties) { this.properties.putAll(properties); return this; } public ProjectDefinition setProperty(String key, String value) { properties.put(key, value); return this; } public ProjectDefinition setKey(String key) { properties.put(CoreProperties.PROJECT_KEY_PROPERTY, key); return this; } public ProjectDefinition setVersion(String s) { properties.put(CoreProperties.PROJECT_VERSION_PROPERTY, StringUtils.defaultString(s)); return this; } public ProjectDefinition setName(String s) { properties.put(CoreProperties.PROJECT_NAME_PROPERTY, StringUtils.defaultString(s)); return this; } public ProjectDefinition setDescription(String s) { properties.put(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, StringUtils.defaultString(s)); return this; } public String getKey() { return properties.get(CoreProperties.PROJECT_KEY_PROPERTY); } /** * @since 4.5 */ public String getKeyWithBranch() { String branch = getBranch(); String projectKey = getKey(); if (StringUtils.isNotBlank(branch)) { projectKey = String.format("%s:%s", projectKey, branch); } return projectKey; } @CheckForNull public String getBranch() { String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY); if (StringUtils.isNotBlank(branch)) { return branch; } else if (getParent() != null) { return getParent().getBranch(); } return null; } @CheckForNull public String getOriginalVersion() { return properties.get(CoreProperties.PROJECT_VERSION_PROPERTY); } public String getVersion() { String version = properties.get(CoreProperties.PROJECT_VERSION_PROPERTY); if (StringUtils.isBlank(version)) { version = "not provided"; } return version; } @CheckForNull public String getOriginalName() { return properties.get(CoreProperties.PROJECT_NAME_PROPERTY); } public String getName() { String name = properties.get(CoreProperties.PROJECT_NAME_PROPERTY); if (StringUtils.isBlank(name)) { name = getKey(); } return name; } public String getDescription() { return properties.get(CoreProperties.PROJECT_DESCRIPTION_PROPERTY); } private void appendProperty(String key, String value) { String current = (String) ObjectUtils.defaultIfNull(properties.get(key), ""); if (StringUtils.isBlank(current)) { properties.put(key, value); } else { properties.put(key, current + SEPARATOR + value); } } /** * @return Source files and folders. */ public List<String> sources() { String sources = (String) ObjectUtils.defaultIfNull(properties.get(SOURCES_PROPERTY), ""); return trim(StringUtils.split(sources, SEPARATOR)); } /** * @param paths paths to file or directory with main sources. * They can be absolute or relative to project base directory. */ public ProjectDefinition addSources(String... paths) { for (String path : paths) { appendProperty(SOURCES_PROPERTY, path); } return this; } public ProjectDefinition addSources(File... fileOrDirs) { for (File fileOrDir : fileOrDirs) { addSources(fileOrDir.getAbsolutePath()); } return this; } public ProjectDefinition resetSources() { properties.remove(SOURCES_PROPERTY); return this; } public ProjectDefinition setSources(String... paths) { resetSources(); return addSources(paths); } public ProjectDefinition setSources(File... filesOrDirs) { resetSources(); for (File fileOrDir : filesOrDirs) { addSources(fileOrDir.getAbsolutePath()); } return this; } public List<String> tests() { String sources = (String) ObjectUtils.defaultIfNull(properties.get(TESTS_PROPERTY), ""); return trim(StringUtils.split(sources, SEPARATOR)); } /** * @param paths path to files or directories with test sources. * It can be absolute or relative to project directory. */ public ProjectDefinition addTests(String... paths) { for (String path : paths) { appendProperty(TESTS_PROPERTY, path); } return this; } public ProjectDefinition addTests(File... fileOrDirs) { for (File fileOrDir : fileOrDirs) { addTests(fileOrDir.getAbsolutePath()); } return this; } public ProjectDefinition setTests(String... paths) { resetTests(); return addTests(paths); } public ProjectDefinition setTests(File... fileOrDirs) { resetTests(); for (File dir : fileOrDirs) { addTests(dir.getAbsolutePath()); } return this; } public ProjectDefinition resetTests() { properties.remove(TESTS_PROPERTY); return this; } /** * @since 2.8 */ public ProjectDefinition addSubProject(ProjectDefinition child) { subProjects.add(child); child.setParent(this); return this; } public ProjectDefinition getParent() { return parent; } public void remove() { if (parent != null) { parent.subProjects.remove(this); parent = null; subProjects.clear(); } } private void setParent(ProjectDefinition parent) { this.parent = parent; } /** * @since 2.8 */ public List<ProjectDefinition> getSubProjects() { return subProjects; } private static List<String> trim(String[] strings) { List<String> result = new ArrayList<>(); for (String s : strings) { result.add(StringUtils.trim(s)); } return result; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ProjectDefinition that = (ProjectDefinition) o; String key = getKey(); return !((key != null) ? !key.equals(that.getKey()) : (that.getKey() != null)); } @Override public int hashCode() { String key = getKey(); return key != null ? key.hashCode() : 0; } }