diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-01-08 17:38:52 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-01-08 17:51:06 +0100 |
commit | e054dc1c096dfd7593d6cf9ff36ce0faa021525d (patch) | |
tree | 310fac534d4f682db2c6196d6262a037eea80ad8 /sonar-plugin-api | |
parent | b8f14b0c67995f3372af529772d91ee9c1af8874 (diff) | |
download | sonarqube-e054dc1c096dfd7593d6cf9ff36ce0faa021525d.tar.gz sonarqube-e054dc1c096dfd7593d6cf9ff36ce0faa021525d.zip |
SONAR-3024 Introduce a path attribute on resource to allow distinguish files
that would have the same key with old key pattern
Diffstat (limited to 'sonar-plugin-api')
6 files changed, 159 insertions, 35 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java index 657ed1d3afa..e37f0714b22 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java @@ -28,6 +28,7 @@ import org.sonar.api.database.BaseIdentifiable; import org.sonar.api.resources.ProjectLink; import org.sonar.api.resources.Resource; +import javax.annotation.Nullable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -54,6 +55,7 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { public static final int DESCRIPTION_COLUMN_SIZE = 2000; public static final int NAME_COLUMN_SIZE = 256; public static final int KEY_SIZE = 400; + public static final int PATH_SIZE = 2000; @Column(name = "name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE) private String name; @@ -82,6 +84,9 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { @Column(name = "root_id", updatable = true, nullable = true) private Integer rootId; + @Column(name = "path", updatable = true, nullable = true, length = PATH_SIZE) + private String path; + @Column(name = "copy_resource_id", updatable = true, nullable = true) private Integer copyResourceId; @@ -103,6 +108,10 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { this.createdAt = new Date(); } + public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) { + this(scope, key, qualifier, rootId, null, name); + } + /** * <p>Creates a resource model</p> * @@ -110,14 +119,16 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { * @param key the rule key. This is the name of the resource, including the path * @param qualifier the resource qualifier * @param rootId the rootId for the resource + * @param path the path of the resource * @param name the short name of the resource */ - public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) { + public ResourceModel(String scope, String key, String qualifier, Integer rootId, @Nullable String path, String name) { // call this to have the "createdAt" field initialized this(); this.scope = scope; this.key = key; this.rootId = rootId; + this.path = path; this.name = name; this.qualifier = qualifier; } @@ -257,6 +268,18 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { this.rootId = rootId; } + public String getPath() { + return path; + } + + public ResourceModel setPath(@Nullable String path) { + if (path != null && path.length() > PATH_SIZE) { + throw new IllegalArgumentException("Resource path is too long, max is " + PATH_SIZE + " characters. Got : " + path); + } + this.path = path; + return this; + } + public String getQualifier() { return qualifier; } @@ -282,43 +305,58 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { return true; } ResourceModel other = (ResourceModel) obj; - return new EqualsBuilder() - .append(key, other.key) + if (StringUtils.isNotBlank(path)) { + return new EqualsBuilder() + .append(path, other.path) .append(enabled, other.enabled) .append(rootId, other.rootId) .isEquals(); + } + return new EqualsBuilder() + .append(key, other.key) + .append(enabled, other.enabled) + .append(rootId, other.rootId) + .isEquals(); } @Override public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(key) + if (StringUtils.isNotBlank(path)) { + return new HashCodeBuilder(17, 37) + .append(path) .append(enabled) .append(rootId) .toHashCode(); + } + return new HashCodeBuilder(17, 37) + .append(key) + .append(enabled) + .append(rootId) + .toHashCode(); } @Override public String toString() { return new ToStringBuilder(this) - .append("id", getId()) - .append("key", key) - .append("scope", scope) - .append("qualifier", qualifier) - .append("name", name) - .append("longName", longName) - .append("lang", languageKey) - .append("enabled", enabled) - .append("rootId", rootId) - .append("copyResourceId", copyResourceId) - .append("personId", personId) - .append("createdAt", createdAt) - .toString(); + .append("id", getId()) + .append("key", key) + .append("scope", scope) + .append("qualifier", qualifier) + .append("name", name) + .append("longName", longName) + .append("lang", languageKey) + .append("enabled", enabled) + .append("rootId", rootId) + .append("path", path) + .append("copyResourceId", copyResourceId) + .append("personId", personId) + .append("createdAt", createdAt) + .toString(); } @Override public Object clone() { - ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getName()); + ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getPath(), getName()); clone.setDescription(getDescription()); clone.setEnabled(getEnabled()); clone.setProjectLinks(getProjectLinks()); @@ -338,6 +376,7 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { model.setEnabled(Boolean.TRUE); model.setDescription(resource.getDescription()); model.setKey(resource.getKey()); + model.setPath(resource.getPath()); if (resource.getLanguage() != null) { model.setLanguageKey(resource.getLanguage().getKey()); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java index b770527dec4..98f9c386bf8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java @@ -98,8 +98,9 @@ public class Directory extends Resource { @Override public String toString() { return new ToStringBuilder(this) - .append("key", getKey()) - .append("language", language) - .toString(); + .append("key", getKey()) + .append("path", getPath()) + .append("language", language) + .toString(); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java index 3e743c1e336..7b0fa721d62 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java @@ -101,6 +101,10 @@ public class File extends Resource { public Directory getParent() { if (parent == null) { parent = new Directory(directoryKey); + String filePath = getPath(); + if (StringUtils.isNotBlank(filePath)) { + parent.setPath(StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR)); + } } return parent; } @@ -187,8 +191,9 @@ public class File extends Resource { /** * Sets the language of the file */ - public void setLanguage(Language language) { + public File setLanguage(Language language) { this.language = language; + return this; } /** @@ -217,6 +222,7 @@ public class File extends Resource { public String toString() { return new ToStringBuilder(this) .append("key", getKey()) + .append("path", getPath()) .append("dir", directoryKey) .append("filename", filename) .append("language", language) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java index 40927c844d9..d3cbf2f88ad 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java @@ -20,6 +20,7 @@ package org.sonar.api.resources; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.WildcardPattern; @@ -33,6 +34,7 @@ import java.util.List; */ public class JavaFile extends Resource { + private static final String JAVA_SUFFIX = ".java"; private String filename; private String longName; private String packageKey; @@ -110,6 +112,10 @@ public class JavaFile extends Resource { public JavaPackage getParent() { if (parent == null) { parent = new JavaPackage(packageKey); + String filePath = getPath(); + if (StringUtils.isNotBlank(filePath)) { + parent.setPath(StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR)); + } } return parent; @@ -176,8 +182,8 @@ public class JavaFile extends Resource { @Override public boolean matchFilePattern(String antPattern) { String fileKey = getKey(); - if (!fileKey.endsWith(".java")) { - fileKey += ".java"; + if (!fileKey.endsWith(JAVA_SUFFIX)) { + fileKey += JAVA_SUFFIX; } // Add wildcard extension if not provided if ((antPattern.contains("/") && StringUtils.substringAfterLast(antPattern, "/").indexOf('.') < 0) || antPattern.indexOf('.') < 0) { @@ -191,6 +197,21 @@ public class JavaFile extends Resource { return matcher.match(fileKey); } + public static JavaFile fromIOFile(File file, Project module, boolean unitTest) { + if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), JAVA_SUFFIX)) { + return null; + } + PathResolver.RelativePath relativePath = new PathResolver().relativePath( + unitTest ? module.getFileSystem().getTestDirs() : module.getFileSystem().getSourceDirs(), + file); + if (relativePath != null) { + JavaFile sonarFile = fromRelativePath(relativePath.path(), unitTest); + sonarFile.setPath(new PathResolver().relativePath(module.getFileSystem().getBasedir(), file)); + return sonarFile; + } + return null; + } + public static JavaFile fromRelativePath(String relativePath, boolean unitTest) { if (relativePath != null) { String pacname = null; @@ -213,7 +234,7 @@ public class JavaFile extends Resource { * @return the JavaFile created if exists, null otherwise */ public static JavaFile fromIOFile(File file, List<File> sourceDirs, boolean unitTest) { - if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), ".java")) { + if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), JAVA_SUFFIX)) { return null; } PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file); @@ -235,7 +256,11 @@ public class JavaFile extends Resource { @Override public String toString() { - return getKey(); + return new ToStringBuilder(this) + .append("key", getKey()) + .append("path", getPath()) + .append("filename", filename) + .toString(); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java index 05e30d30135..6588de10201 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java @@ -19,11 +19,15 @@ */ package org.sonar.api.resources; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.Nullable; + import java.io.Serializable; /** * The interface to implement to create a resource in Sonar - * + * * @since 1.10 */ public abstract class Resource implements Serializable { @@ -122,6 +126,8 @@ public abstract class Resource implements Serializable { private String key = null; + private String path = null; + private String effectiveKey = null; private boolean isExcluded = false; @@ -182,7 +188,7 @@ public abstract class Resource implements Serializable { /** * Check resource against an Ant pattern, like mypackag?/*Foo.java. It's used for example to match resource exclusions. - * + * * @param antPattern Ant-like pattern (with **, * and ?). It includes file suffixes. * @return true if the resource matches the Ant pattern */ @@ -200,6 +206,29 @@ public abstract class Resource implements Serializable { return this; } + public String getPath() { + return path; + } + + public Resource setPath(@Nullable String path) { + this.path = normalize(path); + return this; + } + + private String normalize(@Nullable String path) { + if (path == null) { + return null; + } + String normalizedPath = path; + if (!normalizedPath.startsWith(Directory.SEPARATOR)) { + normalizedPath = Directory.SEPARATOR + normalizedPath; + } + if (normalizedPath.length() > 1 && normalizedPath.endsWith(Directory.SEPARATOR)) { + normalizedPath = normalizedPath.substring(0, normalizedPath.length() - 1); + } + return normalizedPath; + } + public String getEffectiveKey() { return effectiveKey; } @@ -240,7 +269,10 @@ public abstract class Resource implements Serializable { } Resource resource = (Resource) o; - return key.equals(resource.key); + if (StringUtils.isBlank(path)) { + return key.equals(resource.key); + } + return path.equals(resource.path); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java index 256a2f9aa95..c8dd3e3b377 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java @@ -24,9 +24,11 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Collections2; import com.google.common.collect.ListMultimap; import com.google.common.collect.Sets; +import org.apache.commons.lang.builder.EqualsBuilder; import org.sonar.api.scan.filesystem.internal.InputFile; import javax.annotation.Nullable; + import java.io.FileFilter; import java.util.Arrays; import java.util.Collection; @@ -38,6 +40,10 @@ import java.util.Set; */ public class FileQuery { + private final ListMultimap<String, String> attributes = ArrayListMultimap.create(); + private final Set<String> inclusions = Sets.newHashSet(); + private final Set<String> exclusions = Sets.newHashSet(); + public static FileQuery on(FileType... types) { FileQuery query = new FileQuery(); for (FileType type : types) { @@ -54,10 +60,6 @@ public class FileQuery { return on(FileType.TEST); } - private final ListMultimap<String, String> attributes = ArrayListMultimap.create(); - private final Set<String> inclusions = Sets.newHashSet(); - private final Set<String> exclusions = Sets.newHashSet(); - private FileQuery() { } @@ -114,5 +116,24 @@ public class FileQuery { public FileQuery withFilters(FileFilter... filters) { throw new UnsupportedOperationException("TODO"); } -} + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (obj.getClass() != getClass()) { + return false; + } + FileQuery rhs = (FileQuery) obj; + return new EqualsBuilder() + .append(attributes, rhs.attributes) + .append(exclusions, rhs.exclusions) + .append(inclusions, rhs.inclusions) + .isEquals(); + } + +} |