aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2014-01-08 17:38:52 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2014-01-08 17:51:06 +0100
commite054dc1c096dfd7593d6cf9ff36ce0faa021525d (patch)
tree310fac534d4f682db2c6196d6262a037eea80ad8 /sonar-plugin-api
parentb8f14b0c67995f3372af529772d91ee9c1af8874 (diff)
downloadsonarqube-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')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java77
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java8
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java33
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java31
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();
+ }
+
+}