package qubexplorer.ui.issues; import qubexplorer.ProjectNotFoundException; import java.io.File; import java.util.Comparator; import java.util.Set; import org.netbeans.api.java.project.JavaProjectConstants; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; import org.openide.text.Annotation; import org.openide.text.Line; import org.openide.util.Lookup; import qubexplorer.RadarIssue; import qubexplorer.ResourceKey; import qubexplorer.SonarQubeProjectConfiguration; import qubexplorer.ui.ProjectContext; /** * * @author Victor */ public class IssueLocation { private final ResourceKey componentKey; private final int lineNumber; private static final String DEFAULT_EXTENSION = ".java"; public IssueLocation(String componentKey, int lineNumber) { this.lineNumber = lineNumber; this.componentKey = ResourceKey.valueOf(componentKey); } public String getComponentPath() { return componentKey.getLastPart(); } public String getSimpleComponentName() { String extension = ""; char pathSeparator; String componentPath = getComponentPath(); if (componentPath.contains("/")) { pathSeparator = '/'; } else { extension = DEFAULT_EXTENSION; pathSeparator = '.'; } int index = componentPath.lastIndexOf(pathSeparator); if (index < componentPath.length() - 1) { return componentPath.substring(index + 1) + extension; } else { return ""; } } public Integer getLineNumber() { return lineNumber; } public ResourceKey getProjectKey() { return componentKey.subkey(0, componentKey.getPartsCount() - 1); } public Project getProjectOwner(ProjectContext projectContext, ProjectKeyChecker projectKeyChecker) { FileObject projectDir = findProjectDir(projectContext, getProjectKey(), projectKeyChecker); if (projectDir != null) { return FileOwnerQuery.getOwner(projectDir); } else { return null; } } public File getFile(ProjectContext projectContext, ProjectKeyChecker projectKeyChecker) { Project projectOwner = getProjectOwner(projectContext, projectKeyChecker); if (projectOwner == null) { throw new ProjectNotFoundException(getProjectKey().toString()); } File file; String componentPath = getComponentPath(); if (isFilePath(componentPath)) { /* It's a relative file path. Relative to project directory? Example: src/main/java/victor/simpleproject/Persona.java */ // Use project.directory or sources group? file = new File(projectOwner.getProjectDirectory().getPath(), componentPath); } else { /* It's an element name. Assume is a java file. Example: package.subpackage.ClassA */ String filePath = componentPath.replace(".", "/") + DEFAULT_EXTENSION; Sources sources = ProjectUtils.getSources(projectOwner); SourceGroup[] sourceGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); file = new File(sourceGroups[0].getRootFolder().getPath(), filePath); } return file; } private static boolean isFilePath(String componentPath) { return componentPath.contains("/"); } public FileObject getFileObject(ProjectContext projectContext, ProjectKeyChecker projectKeyChecker) { return FileUtil.toFileObject(getFile(projectContext, projectKeyChecker)); } public Annotation attachAnnotation(RadarIssue radarIssue, FileObject fileObject) throws DataObjectNotFoundException { Annotation ann = null; EditorCookie editorCookie = getEditorCookie(fileObject); if (editorCookie != null) { Line line = getLine(editorCookie); if (line != null) { ann = new SonarQubeEditorAnnotation(radarIssue.severityObject(), radarIssue.message()); ann.attach(line); } } return ann; } public Line getLine(EditorCookie editorCookie) { Line.Set lineSet = editorCookie.getLineSet(); int effectiveLineNumber = getLineNumber() <= 0 ? 1 : getLineNumber(); int index = Math.min(effectiveLineNumber, lineSet.getLines().size()) - 1; return lineSet.getCurrent(index); } @Override public String toString() { if (lineNumber <= 0) { return componentKey.toString(); } else { return componentKey.toString() + " [" + lineNumber + "]"; } } public static EditorCookie getEditorCookie(FileObject fileObject) throws DataObjectNotFoundException { DataObject dataObject = DataObject.find(fileObject); Lookup lookup = dataObject.getLookup(); return lookup.lookup(EditorCookie.class); } private static FileObject findProjectDir(ProjectContext projectContext, ResourceKey issueProjectKey, ProjectKeyChecker projectKeyChecker) { if (projectKeyChecker.equals(projectContext.getConfiguration(), issueProjectKey, false) ) { return projectContext.getProject().getProjectDirectory(); } Set<Project> subprojects = ProjectUtils.getContainedProjects(projectContext.getProject(), true); if (subprojects != null) { for (Project subproject : subprojects) { SonarQubeProjectConfiguration subprojectInfo = projectContext.getConfiguration().createConfiguration(subproject); if (projectKeyChecker.equals(subprojectInfo, issueProjectKey, true) ) { return subproject.getProjectDirectory(); } } } return null; } public static class IssueLocationComparator implements Comparator<IssueLocation> { @Override public int compare(IssueLocation t, IssueLocation t1) { int result = t.getComponentPath().compareTo(t1.getComponentPath()); if (result != 0) { return result; } else { return Integer.compare(t.getLineNumber(), t1.getLineNumber()); } } } public static interface ProjectKeyChecker { boolean equals(SonarQubeProjectConfiguration configuration, ResourceKey projectKeyIssue, boolean isSubmodule); } }