In this challenge the goal is to create a tool which can analyze any given Java code and make certain statements about that code. Tools like this can help if you need to understand new or unknown code.
The provided example code in CodeExamples
contains three open source projects:
- Cron Utils: A utility library for creating crons in Java
- fig: A general-purpose collection with different Java utilities
- Spark: A framework for creating Java web applications
The three projects have been modified so that there are some dependencies between them.
There is no build file provided that builds the example project, as running the project is not part of the assignment.
To get a first idea of the project size it is a good measurement to look at the lines of code it consists of. For this reason the first feature we want for our project is to get the number of source lines for each of the files provided in the input. The project is already setup to automatically give us the input directory which we want to analyze so your task is to write the code which can count the number of source code lines.
The output should be a Map containing the filename of each provided Java file as key and and Output
element as value. The Output should contain the number of source lines of code of the file. (SLOC: lines of code excluding empty lines and lines containing comments).
As a filename you can use the relative path to the file (i.e. file.getPath()
)
For simplicity you can ignore block comments for this task and only exclude line comments (starting with //
) from your count.
Example Code:
Map<String, Output> result = new HashMap<String, Output>();
result.put("file1.java", new Output(123, null));
To better understand how the given projects are dependent on each other our tool should be able to detect, if a file/class is dependent on other files/classes. The goal is to be able to tell if a file is dependent on a file from another project either directly or indirectly through relevant dependencies (dependecies to one of the three example projects).
This means that if A/file1.java
is dependent on A/file2.java
which is dependent on B/file3.java
, both A/file1.java
and A/file2.java
are dependent on project B
.
To detect if a file has dependencies it is sufficient to look at the packages that are imported into the file. It is not nescessary to check if an import statement might be unused, as those could be removed as a first step before running the tool in the real world.
To make the output more readable please only provide a list of project names the file is dependent on and only projects contained inside the CodeExamples
folder.
For this reason it is not nescessary to go through all dependencies, but it is enough to look at dependencies inside the CodeExamples
folder. External dependencies to code outside the known three projects can be ignored.
Additionally you can ignore two special cases for this analysis, which might be more effort to implement:
- You can ignore static imports like
import static ...
- You can ignore wildcard imports like
import x.y.*
- You can ignore dependencies which do not use an
import
statements likejava.util.List<String> list = new java.util.ArrayList<>();
This task should extend the output of Task 1.
Example Code:
Map<String, Output> result = new HashMap<String, Output>();
List<String> dependencies = new ArrayList<String>();
dependencies.add("spark");
result.put("file1.java", new Output(123, dependencies));
In Java programming it is very common pattern to use getters and setters in classes for the properties of that class. The code for these getters and setters is mostly generated automatically by the IDE, so counting them as source code lines might be missleading in an analysis of the results. That's why it makes sense to add an additional field to our output counting the source lines of code without these code blocks.
Additionally we don't want to count block comments for this task, so you need to detect blocks which are comments and exclude them from your count. This also incudes JavaDoc comments. (Block comments are /* ... */
)
The resulting lines should follow the rules of task 1, which means empty lines and comments do not count into the result and additionally we remove lines which are part of a getter and lines which are part of a block comment. Setters can be ignored for this task, as the work is mostly the same, but with more complex detection rules.
To detect if a code-block is a getter you can use the following pattern where <...>
can be anything and (...)?
is optional:
public <...> get<...>(){
return (this.)?<...>;
}
We tried to put as much information in this readme as possible, but if you face any issues with project setup or with understanding the tasks please use the issue page on the template respository or send us a mail to passau@itestra.de
To setup the project you need to have Maven installed on your machine, which should be installed by default if you have installed IntelliJ or Eclipse before, but in case you face an issue with that, see the following guide for installing Maven
- Setup your GitHub classroom assignment and clone the created project
- In Eclipse go to File > Import...
- Select Maven > Existing Maven Projects
- Select the cloned repository containing the
pom.xml
- Wait for Maven to setup the project and start editing the file
SourceCodeAnalyzer.java
- Setup your GitHub classroom assignment and clone the created project
- In IntelliJ go to File > Open...
- Select the
pom.xml
file from the cloned repository found inImplementation/pom.xml
and open it as project - Wait for Maven to setup the project and start editing the file
SourceCodeAnalyzer.java
Running the project without arguments selects the CodeExamples
folder by default. If you want to test your implementation against some other code you can specify a path to that using -i <path>
- Make sure Maven and Java are installed and registered as path variable
mvn clean package
java -jar .\target\SourceCodeAnalyser-1.0-SNAPSHOT.jar
- Right click
SourceCodeAnalyzer.java
and click Run As > Java Application (Alt+Shift+X > J)
- Right click
SourceCodeAnalyzer.java
and click Run (Ctrl+Shift+F10)