├── .gitignore
├── .hgignore
├── README.md
├── license.txt
├── nbactions.xml
├── pom.xml
└── src
├── docs
└── images
│ ├── actionPlan.png
│ ├── configuration.png
│ ├── contextMenu.png
│ ├── custom.png
│ ├── issues.png
│ ├── ruleDialog.png
│ ├── sourcesMenu.png
│ └── summary.png
├── main
├── java
│ └── qubexplorer
│ │ ├── AuthorizationException.java
│ │ ├── Classifier.java
│ │ ├── ClassifierSummary.java
│ │ ├── ClassifierType.java
│ │ ├── ConfigurationFactory.java
│ │ ├── GenericSonarQubeProjectConfiguration.java
│ │ ├── IssueType.java
│ │ ├── IssuesContainer.java
│ │ ├── MvnModelFactory.java
│ │ ├── MvnModelInputException.java
│ │ ├── NoSuchProjectException.java
│ │ ├── PassEncoder.java
│ │ ├── PlainDirectoryProject.java
│ │ ├── ProjectNotFoundException.java
│ │ ├── RadarIssue.java
│ │ ├── ResourceKey.java
│ │ ├── Rule.java
│ │ ├── Severity.java
│ │ ├── SonarMvnProject.java
│ │ ├── SonarQubeProjectConfiguration.java
│ │ ├── SonarQubeProjectException.java
│ │ ├── Summary.java
│ │ ├── SummaryOptions.java
│ │ ├── UserCredentials.java
│ │ ├── filter
│ │ ├── AssigneesFilter.java
│ │ ├── IssueFilter.java
│ │ ├── RuleFilter.java
│ │ ├── SeverityFilter.java
│ │ └── TypeFilter.java
│ │ ├── runner
│ │ ├── Module.java
│ │ ├── SonarRunnerCancelledException.java
│ │ ├── SonarRunnerClassifierSummary.java
│ │ ├── SonarRunnerException.java
│ │ ├── SonarRunnerProccess.java
│ │ ├── SonarRunnerResult.java
│ │ ├── SourcesNotFoundException.java
│ │ ├── VersionConfig.java
│ │ ├── VersionConfigLessThan4.java
│ │ ├── VersionConfigLessThan5Point2.java
│ │ ├── VersionConfigMoreThan5Point2.java
│ │ └── ui
│ │ │ ├── SonarRunnerAction.java
│ │ │ └── SonarRunnerTask.java
│ │ ├── server
│ │ ├── Component.java
│ │ ├── ComponentSearchResult.java
│ │ ├── IssuesSearchResult.java
│ │ ├── Paging.java
│ │ ├── Resource.java
│ │ ├── RuleResult.java
│ │ ├── ServerStatus.java
│ │ ├── SimpleClassifierSummary.java
│ │ ├── SonarQube.java
│ │ ├── Version.java
│ │ └── ui
│ │ │ ├── CustomServerIssuesAction.java
│ │ │ ├── ServerConnectionDialog.form
│ │ │ ├── ServerConnectionDialog.java
│ │ │ ├── ServerIssuesAction.java
│ │ │ ├── SonarQubeFactory.java
│ │ │ ├── SummarySettingsDialog.form
│ │ │ └── SummarySettingsDialog.java
│ │ └── ui
│ │ ├── AuthDialog.form
│ │ ├── AuthDialog.java
│ │ ├── FileOpenedNotifier.java
│ │ ├── IssueEditorAnnotationAttacher.java
│ │ ├── PopupAction.java
│ │ ├── ProjectContext.java
│ │ ├── ProjectRenderer.java
│ │ ├── RuleDialog.form
│ │ ├── RuleDialog.java
│ │ ├── RuleTask.java
│ │ ├── SeverityIconRenderer.java
│ │ ├── SonarIssuesTopComponent.form
│ │ ├── SonarIssuesTopComponent.java
│ │ ├── SonarQubeOptionsPanel.form
│ │ ├── SonarQubeOptionsPanel.java
│ │ ├── SonarQubeOptionsPanelController.java
│ │ ├── UserCredentialsRepository.java
│ │ ├── issues
│ │ ├── FileObjectOpenedListener.java
│ │ ├── IssueLocation.java
│ │ ├── IssuesTableModel.java
│ │ ├── IssuesTask.java
│ │ ├── LocationRenderer.java
│ │ └── SonarQubeEditorAnnotation.java
│ │ ├── summary
│ │ ├── ClassifierSummaryModel.java
│ │ ├── SummaryTask.java
│ │ └── SummaryTreeCellRenderer.java
│ │ └── task
│ │ ├── Task.java
│ │ ├── TaskExecutionException.java
│ │ └── TaskExecutor.java
├── nbm
│ └── manifest.mf
└── resources
│ └── qubexplorer
│ ├── server
│ └── ui
│ │ └── Bundle.properties
│ ├── sonarqubeexplorer
│ ├── Bundle.properties
│ ├── blocker-annotation.xml
│ ├── critical-annotation.xml
│ ├── info-annotation.xml
│ ├── layer.xml
│ ├── major-annotation.xml
│ └── minor-annotation.xml
│ └── ui
│ ├── Bundle.properties
│ ├── images
│ ├── application_view_list.png
│ ├── arrow_refresh_small.png
│ ├── blocker.png
│ ├── critical.png
│ ├── eye.png
│ ├── info.png
│ ├── information.png
│ ├── major.png
│ ├── minor.png
│ ├── page_gear.png
│ └── stop.png
│ ├── options
│ └── Bundle.properties
│ └── summary
│ └── Bundle.properties
└── test
└── java
└── qubexplorer
├── PassEncoderTest.java
├── ResourceKeyTest.java
├── runner
└── SonarRunnerProccessTest.java
├── server
├── SimpleClassifierSummaryTest.java
└── VersionTest.java
└── ui
├── AuthenticationRepositoryTest.java
└── task
└── TaskExecutorTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /nbproject/
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | \.orig$
2 | \.orig\..*$
3 | \.chg\..*$
4 | \.rej$
5 | \.conflict\~$
6 | ^hs_err_pid6512\.log$
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Radar
2 |
3 | Radar is a plugin for Netbeans to navigate directly from the issue to the code without leaving your IDE.
4 |
5 | You can retrieve issues from a server or you can run a local analysis.
6 |
7 | ## Configuration
8 |
9 | 
10 |
11 | You can configure the url of your SonarQube server (default is localhost, port 9000).
12 |
13 | For local analysis, you can choose if you want to use preview or incremental mode. See more information about SonarQube Runner analysis mode in: http://docs.codehaus.org/display/SONAR/Concepts#Concepts-AnalysisModes
14 |
15 | Also, you can set JVM arguments for sonar runner proccess (For example, max memory heap space).
16 |
17 | ## Seeing issues
18 |
19 | To see the SonarQube issues just invoke the contextual menu in your Java project and choose how you get your issues.
20 |
21 | 
22 |
23 | These are the ways to retrieve the issues:
24 |
25 | ### Get Issues From Server
26 |
27 | Get the issues from a remote server. The analysis was previous done and statistics are already in the server. Uses the url already configured.
28 | The key of the project is automatically generated from the maven pom.
29 |
30 | For a multimodule project you have to invoke the action in the main parent project.
31 |
32 | ### Get Issues From Server ...
33 |
34 | Same as previous but a dialog appears that allows you to use a different server url and choose a different project key in the server.
35 |
36 | 
37 |
38 | Same note for multimodule project applies too.
39 |
40 | ### Get Issues with Sonar Runner
41 |
42 | This analysis is made locally with SonarQube Runner. A connection to the server is yet required to download the quality profile.
43 |
44 | ## See the issues
45 |
46 | So, after choosing the way to retrieve issues and some processing, a count of your issues will appear. The count is shown by severity and by rule.
47 |
48 | 
49 |
50 | Note: For remote retrieving of issues, you can filter your issues by action plan if there is any.
51 |
52 | 
53 |
54 | To see the issues for a particular category, select and click in List issues and a table with the issues will be shown. From here you can go to the code
55 | right-clicking a row.
56 |
57 | 
58 |
59 | If you wanna see more information about a rule, select it from the Summary view and click the button *Show Information*. A dialog will open and show more documentation about the rule.
60 |
61 | 
62 |
63 | # Notes
64 |
65 | Before calling Sonar runner from this plugin, clean and build the project.
66 |
67 | The plugin uses de web service API of sonar for remote retrieving of issues, so there can be some limitations on amount of displayed information. For example, at this moment, the maximum number of retrieved issues per request is 10,000.
68 |
69 | It works from SonarQube 3.7 to SonarQube 6.2.
70 |
71 | # Download
72 |
73 | You can download Radar [Here](http://plugins.netbeans.org/plugin/51532/radar-netbeans here)
74 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright [2013] [Victor Hugo Herrera Maldonado]
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CUSTOM-Sonar
5 | Sonar
6 |
7 | sonar:sonar
8 |
9 |
10 |
11 | CUSTOM-Clean & Run
12 | Clean & Run
13 |
14 | clean
15 | install
16 | nbm:cluster
17 | nbm:run-ide
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/docs/images/actionPlan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/actionPlan.png
--------------------------------------------------------------------------------
/src/docs/images/configuration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/configuration.png
--------------------------------------------------------------------------------
/src/docs/images/contextMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/contextMenu.png
--------------------------------------------------------------------------------
/src/docs/images/custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/custom.png
--------------------------------------------------------------------------------
/src/docs/images/issues.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/issues.png
--------------------------------------------------------------------------------
/src/docs/images/ruleDialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/ruleDialog.png
--------------------------------------------------------------------------------
/src/docs/images/sourcesMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/sourcesMenu.png
--------------------------------------------------------------------------------
/src/docs/images/summary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmvictor/radar-netbeans/194293611f23494365e9e34b59ede77ef97bc9f9/src/docs/images/summary.png
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/AuthorizationException.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | /**
4 | *
5 | * @author Victor
6 | */
7 | public class AuthorizationException extends RuntimeException{
8 |
9 | public AuthorizationException() {
10 | }
11 |
12 | public AuthorizationException(Throwable thrwbl) {
13 | super(thrwbl);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/Classifier.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import javax.swing.Icon;
4 | import qubexplorer.filter.IssueFilter;
5 |
6 | /**
7 | *
8 | * @author Víctor
9 | */
10 | public interface Classifier {
11 |
12 | IssueFilter createFilter();
13 |
14 | Icon getIcon();
15 |
16 | String getUserDescription();
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/ClassifierSummary.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | *
7 | * @author Victor
8 | */
9 | public interface ClassifierSummary{
10 |
11 | int getCount(T classifier);
12 |
13 | int getCount(Rule rule);
14 |
15 | int getCount();
16 |
17 | Set getRules(T classifier);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/ClassifierType.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | *
7 | * @author Víctor
8 | */
9 | public interface ClassifierType {
10 |
11 | T valueOf(RadarIssue issue);
12 |
13 | List getValues();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/ConfigurationFactory.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import org.netbeans.api.project.Project;
4 |
5 | /**
6 | *
7 | * @author Victor
8 | */
9 | public final class ConfigurationFactory {
10 |
11 | private ConfigurationFactory() {
12 | }
13 |
14 | public static SonarQubeProjectConfiguration createDefaultConfiguration(Project project) {
15 | if (SonarMvnProject.isMvnProject(project)) {
16 | return new SonarMvnProject(project);
17 | } else {
18 | return new PlainDirectoryProject(project);
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/GenericSonarQubeProjectConfiguration.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.Properties;
4 | import org.netbeans.api.project.Project;
5 |
6 |
7 | public class GenericSonarQubeProjectConfiguration implements SonarQubeProjectConfiguration {
8 | private String name;
9 | private ResourceKey key;
10 | private String version;
11 |
12 | public GenericSonarQubeProjectConfiguration(String name, ResourceKey key, String version) {
13 | this.name = name;
14 | this.key = key;
15 | this.version = version;
16 | }
17 |
18 | public GenericSonarQubeProjectConfiguration() {
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public void setKey(ResourceKey key) {
26 | this.key = key;
27 | }
28 |
29 | public void setVersion(String version) {
30 | this.version = version;
31 | }
32 |
33 | @Override
34 | public String getName() {
35 | return name;
36 | }
37 |
38 | @Override
39 | public ResourceKey getKey() {
40 | return key;
41 | }
42 |
43 | @Override
44 | public String getVersion() {
45 | return version;
46 | }
47 |
48 | @Override
49 | public SonarQubeProjectConfiguration createConfiguration(Project subproject) {
50 | throw new UnsupportedOperationException();
51 | }
52 |
53 | @Override
54 | public Properties getProperties() {
55 | throw new UnsupportedOperationException();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/IssueType.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import javax.swing.Icon;
6 | import qubexplorer.filter.IssueFilter;
7 | import qubexplorer.filter.TypeFilter;
8 |
9 | /**
10 | *
11 | * @author Victor
12 | */
13 | public enum IssueType implements Classifier {
14 |
15 | BUG("Bug"),
16 | VULNERABILITY("Vulnerability"),
17 | CODE_SMELL("Code smell");
18 |
19 | private final String userDescription;
20 |
21 | private IssueType(String userDescription) {
22 | this.userDescription = userDescription;
23 | }
24 |
25 | @Override
26 | public IssueFilter createFilter() {
27 | return new TypeFilter(this);
28 | }
29 |
30 | @Override
31 | public Icon getIcon() {
32 | return null;
33 | }
34 |
35 | @Override
36 | public String getUserDescription() {
37 | return userDescription;
38 | }
39 |
40 | public static ClassifierType getType() {
41 | return INSTANCE;
42 | }
43 |
44 | private static final ClassifierType INSTANCE=new IssueTypeClassifier();
45 |
46 | private static class IssueTypeClassifier implements ClassifierType{
47 |
48 | @Override
49 | public IssueType valueOf(RadarIssue issue) {
50 | return IssueType.valueOf(issue.type().toUpperCase());
51 | }
52 |
53 | @Override
54 | public List getValues() {
55 | return Arrays.asList(IssueType.values());
56 | }
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/IssuesContainer.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.List;
4 | import qubexplorer.filter.IssueFilter;
5 |
6 | /**
7 | *
8 | * @author Victor
9 | */
10 | public interface IssuesContainer {
11 |
12 | List getIssues(UserCredentials auth, ResourceKey projectKey, List filters);
13 |
14 | ClassifierSummary getSummary(ClassifierType classifierType, UserCredentials authentication, ResourceKey projectKey, List filters);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/MvnModelFactory.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.io.Reader;
7 | import org.apache.maven.model.Model;
8 | import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
9 | import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
10 | import org.netbeans.api.project.Project;
11 | import org.openide.filesystems.FileObject;
12 |
13 | /**
14 | *
15 | * @author Victor
16 | */
17 | public class MvnModelFactory {
18 |
19 | public Model createModel(Project project) throws MvnModelInputException{
20 | return createModel(project.getProjectDirectory());
21 | }
22 |
23 | public Model createModel(FileObject projectDir) throws MvnModelInputException {
24 | FileObject pomFile = projectDir.getFileObject("pom.xml");
25 | MavenXpp3Reader mavenreader = new MavenXpp3Reader();
26 | try(Reader reader=new InputStreamReader(pomFile.getInputStream())){
27 | Model model = mavenreader.read(reader);
28 | model.setPomFile(new File(pomFile.getPath()));
29 | return model;
30 | }catch(XmlPullParserException | IOException ex) {
31 | throw new MvnModelInputException(ex);
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/MvnModelInputException.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | /**
4 | *
5 | * @author Victor
6 | */
7 | public class MvnModelInputException extends Exception{
8 |
9 | public MvnModelInputException(Throwable cause) {
10 | super(cause);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/NoSuchProjectException.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | /**
4 | *
5 | * @author Victor
6 | */
7 | public class NoSuchProjectException extends RuntimeException{
8 | private final ResourceKey projectKey;
9 |
10 | public NoSuchProjectException(ResourceKey projectKey) {
11 | this.projectKey = projectKey;
12 | }
13 |
14 | public ResourceKey getProjectKey() {
15 | return projectKey;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/PassEncoder.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.nio.charset.StandardCharsets;
4 | import org.apache.commons.codec.binary.Base64;
5 |
6 | /**
7 | *
8 | * @author Victor
9 | */
10 | public final class PassEncoder {
11 |
12 | private PassEncoder() {
13 |
14 | }
15 |
16 | public static char[] encode(char[] chars){
17 | return new String(Base64.encodeBase64(new String(chars).getBytes(StandardCharsets.UTF_8))).toCharArray();
18 | }
19 |
20 | public static char[] decode(char[] chars){
21 | return decodeAsString(chars).toCharArray();
22 | }
23 |
24 | public static String decodeAsString(char[] chars){
25 | return new String(Base64.decodeBase64(new String(chars).getBytes()), StandardCharsets.UTF_8);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/PlainDirectoryProject.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.nio.charset.StandardCharsets;
7 | import java.util.Properties;
8 | import org.netbeans.api.project.Project;
9 | import org.netbeans.api.project.ProjectUtils;
10 | import org.openide.filesystems.FileObject;
11 |
12 | public class PlainDirectoryProject implements SonarQubeProjectConfiguration {
13 |
14 | private final Project project;
15 | private Properties properties;
16 |
17 | public PlainDirectoryProject(Project project){
18 | this.project = project;
19 | try {
20 | loadProjectProperties();
21 | } catch (IOException ex) {
22 | throw new SonarQubeProjectException(ex);
23 | }
24 | }
25 |
26 | private void loadProjectProperties() throws IOException {
27 | properties = new Properties();
28 | FileObject fileObject = project.getProjectDirectory().getFileObject("sonar.properties");
29 | if (fileObject != null) {
30 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(fileObject.getInputStream(), StandardCharsets.UTF_8))) {
31 | properties.load(reader);
32 | }
33 | }
34 | }
35 |
36 | @Override
37 | public String getName() {
38 | return properties.getProperty(SonarMvnProject.PROPERTY_NAME, ProjectUtils.getInformation(project).getName());
39 | }
40 |
41 | @Override
42 | public ResourceKey getKey() {
43 | String propertyValue = properties.getProperty(SonarMvnProject.PROPERTY_KEY);
44 | if (propertyValue != null) {
45 | return ResourceKey.valueOf(propertyValue);
46 | } else {
47 | return new ResourceKey(getName());
48 | }
49 | }
50 |
51 | @Override
52 | public String getVersion() {
53 | return properties.getProperty(SonarMvnProject.PROPERTY_VERSION, "1.0");
54 | }
55 |
56 | @Override
57 | public SonarQubeProjectConfiguration createConfiguration(Project subproject) {
58 | return new PlainDirectoryProject(subproject);
59 | }
60 |
61 | @Override
62 | public Properties getProperties() {
63 | return properties;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/ProjectNotFoundException.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | /**
4 | *
5 | * @author Victor
6 | */
7 | public class ProjectNotFoundException extends RuntimeException{
8 | private final String shortProjectKey;
9 |
10 | public ProjectNotFoundException(String shortProjectKey) {
11 | this.shortProjectKey = shortProjectKey;
12 | }
13 |
14 | public String getShortProjectKey() {
15 | return shortProjectKey;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/RadarIssue.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import java.util.Collections;
6 | import java.util.Date;
7 | import java.util.Map;
8 | import qubexplorer.ui.issues.IssueLocation;
9 |
10 | /**
11 | *
12 | * @author Victor
13 | */
14 | @JsonIgnoreProperties(ignoreUnknown = true)
15 | public class RadarIssue {
16 |
17 | private String key;
18 | @JsonProperty("component")
19 | private String componentKey;
20 | private Integer line;
21 | private String message;
22 | private String severity;
23 | @JsonProperty("rule")
24 | private String ruleKey;
25 | private String status;
26 | private Date creationDate;
27 | private Date updateDate;
28 | private Rule rule;
29 | private String type;
30 |
31 | public RadarIssue() {
32 | }
33 |
34 | public void setKey(String key) {
35 | this.key = key;
36 | }
37 |
38 | public void setComponentKey(String componentKey) {
39 | this.componentKey = componentKey;
40 | }
41 |
42 | public void setLine(Integer line) {
43 | this.line = line;
44 | }
45 |
46 | public void setMessage(String message) {
47 | this.message = message;
48 | }
49 |
50 | public void setSeverity(String severity) {
51 | this.severity = severity;
52 | }
53 |
54 | public void setRuleKey(String ruleKey) {
55 | this.ruleKey = ruleKey;
56 | }
57 |
58 | public void setStatus(String status) {
59 | this.status = status;
60 | }
61 |
62 | public void setCreationDate(Date creationDate) {
63 | this.creationDate = creationDate;
64 | }
65 |
66 | public void setUpdateDate(Date updateDate) {
67 | this.updateDate = updateDate;
68 | }
69 |
70 | public String key() {
71 | return key;
72 | }
73 |
74 | public String componentKey() {
75 | return componentKey;
76 | }
77 |
78 | public String projectKey() {
79 | throw new UnsupportedOperationException("Not yet implemented");
80 | }
81 |
82 | public String ruleKey() {
83 | return ruleKey;
84 | }
85 |
86 | public String severity() {
87 | return severity;
88 | }
89 |
90 | public String message() {
91 | return message;
92 | }
93 |
94 | public Integer line() {
95 | return line;
96 | }
97 |
98 | public String status() {
99 | return status;
100 | }
101 |
102 | public String resolution() {
103 | return "";
104 | }
105 |
106 | public String reporter() {
107 | return "";
108 | }
109 |
110 | public String assignee() {
111 | return "";
112 | }
113 |
114 | public String author() {
115 | return "";
116 | }
117 |
118 | public String actionPlan() {
119 | return "";
120 | }
121 |
122 | public Date creationDate() {
123 | return creationDate;
124 | }
125 |
126 | public Date updateDate() {
127 | return updateDate;
128 | }
129 |
130 | public Date closeDate() {
131 | return null;
132 | }
133 |
134 | public String attribute(String key) {
135 | return "";
136 | }
137 |
138 | public Map attributes() {
139 | return Collections.emptyMap();
140 | }
141 |
142 | public Long componentId() {
143 | return 0L;
144 | }
145 |
146 | public String debt() {
147 | return "";
148 | }
149 |
150 | public void setRule(Rule rule) {
151 | this.rule = rule;
152 | }
153 |
154 | public Rule rule() {
155 | return rule;
156 | }
157 |
158 | public Severity severityObject() {
159 | return Severity.valueOf(severity());
160 | }
161 |
162 | public IssueLocation getLocation() {
163 | int lineNumber = line() == null ? 0 : line();
164 | return new IssueLocation(componentKey(), lineNumber);
165 | }
166 |
167 | public String type() {
168 | return type;
169 | }
170 |
171 | public void setType(String type) {
172 | this.type = type;
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/ResourceKey.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.io.Serializable;
4 | import java.util.Arrays;
5 |
6 | /**
7 | *
8 | * @author Victor
9 | */
10 | public class ResourceKey implements Serializable {
11 |
12 | private final String[] parts;
13 |
14 | public ResourceKey(String... parts) {
15 | this.parts = parts;
16 | }
17 |
18 | public String getPart(int index) {
19 | return parts[index];
20 | }
21 |
22 | public int getPartsCount() {
23 | return parts.length;
24 | }
25 |
26 | public String toString(int begin, int end) {
27 | StringBuilder builder = new StringBuilder();
28 | for (int i = begin; i < end; i++) {
29 | if (builder.length() > 0) {
30 | builder.append(':');
31 | }
32 | builder.append(parts[i]);
33 | }
34 | return builder.toString();
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return toString(0, parts.length);
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | return Arrays.hashCode(parts);
45 | }
46 |
47 | @Override
48 | public boolean equals(Object obj) {
49 | if (!(obj instanceof ResourceKey)) {
50 | return false;
51 | }
52 | ResourceKey anotherKey = (ResourceKey) obj;
53 | return Arrays.equals(parts, anotherKey.parts);
54 | }
55 |
56 | public String getLastPart() {
57 | return parts[parts.length - 1];
58 | }
59 |
60 | public ResourceKey subkey(int start, int end) {
61 | return new ResourceKey(Arrays.copyOfRange(parts, start, end));
62 | }
63 |
64 | public ResourceKey concat(ResourceKey tempKey) {
65 | String[] newKeyParts=new String[parts.length+tempKey.parts.length];
66 | System.arraycopy(parts, 0, newKeyParts, 0, parts.length);
67 | System.arraycopy(tempKey.parts, 0, newKeyParts, parts.length, tempKey.parts.length);
68 | return new ResourceKey(newKeyParts);
69 | }
70 |
71 | public static ResourceKey valueOf(String key) {
72 | return new ResourceKey(key.split(":"));
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/Rule.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import java.util.Objects;
6 |
7 | /**
8 | *
9 | * @author Víctor
10 | */
11 | @JsonIgnoreProperties(ignoreUnknown = true)
12 | public class Rule {
13 | private String key;
14 | private String name;
15 | @JsonProperty("htmlDesc")
16 | private String description;
17 |
18 | public Rule(String key) {
19 | this.key = key;
20 | }
21 |
22 | public Rule() {
23 | }
24 |
25 | public String getKey() {
26 | return key;
27 | }
28 |
29 | public void setKey(String key) {
30 | this.key = key;
31 | }
32 |
33 | public String getName() {
34 | return name;
35 | }
36 |
37 | public void setName(String name) {
38 | this.name = name;
39 | }
40 |
41 | public String getDescription() {
42 | return description;
43 | }
44 |
45 | public void setDescription(String description) {
46 | this.description = description;
47 | }
48 |
49 | @Override
50 | public int hashCode() {
51 | int hash = 5;
52 | hash = 17 * hash + Objects.hashCode(this.key);
53 | return hash;
54 | }
55 |
56 | @Override
57 | public boolean equals(Object obj) {
58 | if (this == obj) {
59 | return true;
60 | }
61 | if (obj == null) {
62 | return false;
63 | }
64 | if (getClass() != obj.getClass()) {
65 | return false;
66 | }
67 | final Rule other = (Rule) obj;
68 | if (!Objects.equals(this.key, other.key)) {
69 | return false;
70 | }
71 | return true;
72 | }
73 |
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/Severity.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import javax.swing.Icon;
6 | import javax.swing.ImageIcon;
7 | import qubexplorer.filter.IssueFilter;
8 | import qubexplorer.filter.SeverityFilter;
9 |
10 | /**
11 | *
12 | * @author Victor
13 | */
14 | public enum Severity implements Classifier {
15 |
16 | BLOCKER("Blocker", "/qubexplorer/ui/images/blocker.png"),
17 | CRITICAL("Critical", "/qubexplorer/ui/images/critical.png"),
18 | MAJOR("Major", "/qubexplorer/ui/images/major.png"),
19 | MINOR("Minor", "/qubexplorer/ui/images/minor.png"),
20 | INFO("Info", "/qubexplorer/ui/images/info.png");
21 |
22 | private final String userDescription;
23 | private final String resourcePath;
24 |
25 | private Severity(String userDescription, String resourcePath) {
26 | this.userDescription = userDescription;
27 | this.resourcePath = resourcePath;
28 | }
29 |
30 | @Override
31 | public IssueFilter createFilter() {
32 | return new SeverityFilter(this);
33 | }
34 |
35 | @Override
36 | public Icon getIcon() {
37 | return new ImageIcon(getClass().getResource(resourcePath));
38 | }
39 |
40 | @Override
41 | public String getUserDescription() {
42 | return userDescription;
43 | }
44 |
45 | public static ClassifierType getType() {
46 | return TYPE;
47 | }
48 |
49 | private static final SeverityType TYPE=new SeverityType();
50 |
51 | private static class SeverityType implements ClassifierType {
52 |
53 | @Override
54 | public Severity valueOf(RadarIssue issue) {
55 | return Severity.valueOf(issue.severity().toUpperCase());
56 | }
57 |
58 | @Override
59 | public List getValues() {
60 | return Arrays.asList(Severity.values());
61 | }
62 |
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/qubexplorer/SonarMvnProject.java:
--------------------------------------------------------------------------------
1 | package qubexplorer;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.io.Reader;
7 | import java.util.Map;
8 | import java.util.Properties;
9 | import org.apache.maven.model.Build;
10 | import org.apache.maven.model.Model;
11 | import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
12 | import org.apache.maven.project.MavenProject;
13 | import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
14 | import org.netbeans.api.project.Project;
15 | import org.openide.filesystems.FileObject;
16 | import org.openide.filesystems.FileUtil;
17 |
18 | /**
19 | *
20 | * @author Victor
21 | */
22 | public class SonarMvnProject implements SonarQubeProjectConfiguration {
23 |
24 | public static final String PROPERTY_NAME = "sonar.projectName";
25 | public static final String PROPERTY_VERSION = "sonar.projectVersion";
26 | public static final String PROPERTY_KEY = "sonar.projectKey";
27 |
28 | private final Model model;
29 |
30 | public SonarMvnProject(Project project) {
31 | try {
32 | this.model = createModel(project);
33 | } catch (MvnModelInputException ex) {
34 | throw new SonarQubeProjectException(ex);
35 | }
36 | }
37 |
38 | @Override
39 | public String getName() {
40 | String projectName = model.getProperties().getProperty(PROPERTY_NAME);
41 | if (projectName != null) {
42 | return projectName;
43 | }
44 | return model.getName() != null ? model.getName() : model.getArtifactId();
45 | }
46 |
47 | @Override
48 | public ResourceKey getKey() {
49 | String projectKey = model.getProperties().getProperty(PROPERTY_KEY);
50 | if (projectKey != null) {
51 | return ResourceKey.valueOf(projectKey);
52 | }
53 | String groupId = model.getGroupId();
54 | if (groupId == null && model.getParent() != null) {
55 | groupId = model.getParent().getGroupId();
56 | }
57 | return new ResourceKey(groupId, model.getArtifactId());
58 | }
59 |
60 | @Override
61 | public String getVersion() {
62 | String projectVersion = model.getProperties().getProperty(PROPERTY_VERSION);
63 | if (projectVersion != null) {
64 | return projectVersion;
65 | }
66 | String version = model.getVersion();
67 | if (version == null && model.getParent() != null) {
68 | version = model.getParent().getVersion();
69 | }
70 | return version;
71 | }
72 |
73 | public static Model createModel(Project project) throws MvnModelInputException {
74 | FileObject pomFile = getPomFileObject(project);
75 | MavenXpp3Reader mavenreader = new MavenXpp3Reader();
76 | try (Reader reader = new InputStreamReader(pomFile.getInputStream())) {
77 | Model model = mavenreader.read(reader);
78 | model.setPomFile(new File(pomFile.getPath()));
79 | return model;
80 | } catch (XmlPullParserException | IOException ex) {
81 | throw new MvnModelInputException(ex);
82 | }
83 | }
84 |
85 | public static boolean isMvnProject(Project project) {
86 | return getPomFileObject(project) != null;
87 | }
88 |
89 | public static FileObject getPomFileObject(Project project) {
90 | return project.getProjectDirectory().getFileObject("pom.xml");
91 | }
92 |
93 | public static MavenProject createMavenProject(Project project) throws MvnModelInputException {
94 | return new MavenProject(createModel(project));
95 | }
96 |
97 | public static File getOutputDirectory(Project project) throws MvnModelInputException {
98 | MavenProject mavenProject = SonarMvnProject.createMavenProject(project);
99 | Build build = mavenProject.getBuild();
100 | String path = null;
101 | if (build != null) {
102 | path = build.getDirectory();
103 | }
104 | File outputDirectory;
105 | if (path != null) {
106 | outputDirectory = FileUtil.normalizeFile(new File(path));
107 | } else {
108 | outputDirectory = new File(project.getProjectDirectory().getPath(), "target");
109 | }
110 | return outputDirectory;
111 | }
112 |
113 | @Override
114 | public SonarQubeProjectConfiguration createConfiguration(Project subproject) {
115 | return new SonarMvnProject(subproject);
116 | }
117 |
118 | @Override
119 | public Properties getProperties() {
120 | Properties properties = new Properties();
121 | for (Map.Entry