Merge pull request #41 from ThomasRubini/reformat

This commit is contained in:
Thomas Rubini 2022-12-15 20:17:22 +01:00 committed by GitHub
commit 737b23f5a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 545 additions and 535 deletions

View File

@ -5,18 +5,20 @@ import com.beust.jcommander.JCommander;
/** /**
* Class to parse the command line arguments given by the user * Class to parse the command line arguments given by the user
*
* @author Capelier-Marla * @author Capelier-Marla
*/ */
public class ArgParse { public class ArgParse {
/* distribution the user want */ /* distribution the user want */
private static String distribution; private static String distribution;
private static String packet; private static String packet;
/** /**
* Get the command line argument given by the user, parse it with the parser and store it in the corresponding variable * Get the command line argument given by the user, parse it with the parser and store it in the corresponding variable
* @author Capelier-Marla *
* @param args the command line arguments given by the user * @param args the command line arguments given by the user
* @author Capelier-Marla
*/ */
static void parseArguments(String[] args) { static void parseArguments(String[] args) {
// create JCommander and CommandLineParams objects // create JCommander and CommandLineParams objects
@ -24,43 +26,45 @@ public class ArgParse {
CommandLineParams params = new CommandLineParams(); CommandLineParams params = new CommandLineParams();
// add argument required by the params to the JCommander object // add argument required by the params to the JCommander object
jCommander.addObject(params); jCommander.addObject(params);
try { try {
// parse the argument from list of String // parse the argument from list of String
jCommander.parse(args); jCommander.parse(args);
if(params.help) { if (params.help) {
jCommander.setProgramName("PackageViewer"); jCommander.setProgramName("PackageViewer");
jCommander.usage(); jCommander.usage();
System.exit(0); System.exit(0);
} else { } else {
// store the argument parsed in the variable // store the argument parsed in the variable
packet = params.packet; packet = params.packet;
distribution = params.distribution; distribution = params.distribution;
} }
} catch (Exception e) { } catch (Exception e) {
// if the parsing failed, print the error message and exit the program // if the parsing failed, print the error message and exit the program
System.out.println("You forgot something, please enter the package name and the distribution name if you want to search in a specific one"); System.out.println("You forgot something, please enter the package name and the distribution name if you want to search in a specific one");
jCommander.setProgramName("PackageViewer"); jCommander.setProgramName("PackageViewer");
jCommander.usage(); jCommander.usage();
System.exit(0); System.exit(0);
} }
} }
/** /**
* Get the distribution name. If the user didn't give any or if we didn't parse it, return null * Get the distribution name. If the user didn't give any or if we didn't parse it, return null
* @author Capelier-Marla *
* @return String: the distribution name * @return String: the distribution name
*/ * @author Capelier-Marla
public static String getDistribution() { */
return distribution; public static String getDistribution() {
} return distribution;
}
/** /**
* Get the packet name, this one isn't optional * Get the packet name, this one isn't optional
* @author Capelier-Marla *
* @return String: the packet name * @return String: the packet name
*/ * @author Capelier-Marla
public static String getPacket() { */
return packet; public static String getPacket() {
} return packet;
}
} }

View File

@ -4,29 +4,30 @@ import com.beust.jcommander.Parameter;
/** /**
* Class to store and get the command line arguments given by the user * Class to store and get the command line arguments given by the user
*
* @author Capelier-Marla * @author Capelier-Marla
*/ */
public class CommandLineParams { public class CommandLineParams {
/** /**
* Packet the user want to search, only parameter without names * Packet the user want to search, only parameter without names
*/ */
@Parameter(description = "Package to search", @Parameter(description = "Package to search",
required = true) required = true)
public String packet; public String packet;
/** /**
* Distribution the user want to search packages in * Distribution the user want to search packages in
*/ */
@Parameter(names = {"--distro", "-d"}, @Parameter(names = {"--distro", "-d"},
description = "Linux distribution to search in") description = "Linux distribution to search in")
public String distribution; public String distribution;
/** /**
* Displays the help * Displays the help
*/ */
@Parameter(names = {"--help", "-h"}, @Parameter(names = {"--help", "-h"},
description = "Display this help", description = "Display this help",
help = true) help = true)
public boolean help = false; public boolean help = false;
} }

View File

@ -9,55 +9,59 @@ import java.util.List;
/** /**
* Enum containing distribution information to get them by their name * Enum containing distribution information to get them by their name
*
* @author Capelier-Marla * @author Capelier-Marla
*/ */
public enum DistributionEnum { public enum DistributionEnum {
ARCH("arch", new ArchDistribution()), ARCH("arch", new ArchDistribution()),
FEDORA("fedora", new FedoraDistribution()), FEDORA("fedora", new FedoraDistribution()),
; ;
private final String name; private final String name;
private final Distribution distributionConstructor; private final Distribution distributionConstructor;
/** /**
* Constructor for enums * Constructor for enums
* @param name the name of the distribution *
* @param distributionConstructor the instance of the distribution * @param name the name of the distribution
* @author Capelier-Marla * @param distributionConstructor the instance of the distribution
*/ * @author Capelier-Marla
DistributionEnum(String name, Distribution distributionConstructor) { */
this.name = name; DistributionEnum(String name, Distribution distributionConstructor) {
this.distributionConstructor = distributionConstructor; this.name = name;
} this.distributionConstructor = distributionConstructor;
}
/** /**
* Get the distribution instance for the distribution requested in String * Get the distribution instance for the distribution requested in String
* @param name name of the distribution requested *
* @return the instance of the distribution requested * @param name name of the distribution requested
* @author Capelier-Marla * @return the instance of the distribution requested
*/ * @author Capelier-Marla
public static Distribution getDistributionConstructorByName(String name) { */
// loop for all distributions stored in enum public static Distribution getDistributionConstructorByName(String name) {
for(var distrib : values()) { // loop for all distributions stored in enum
// return the instance if it's the same as enum name for (var distrib : values()) {
if(distrib.name.equals(name)) { // return the instance if it's the same as enum name
return distrib.distributionConstructor; if (distrib.name.equals(name)) {
} return distrib.distributionConstructor;
} }
return null; }
} return null;
}
/** /**
* Get all distribution instances available in this enum * Get all distribution instances available in this enum
* @return the list of distribution instances *
*/ * @return the list of distribution instances
public static List<Distribution> getAllDistributionsInstances() { */
// create the set that will be returned public static List<Distribution> getAllDistributionsInstances() {
List<Distribution> result = new ArrayList<>(); // create the set that will be returned
// add all the distribution instances in the set List<Distribution> result = new ArrayList<>();
for(var distrib : values()) { // add all the distribution instances in the set
result.add(distrib.distributionConstructor); for (var distrib : values()) {
} result.add(distrib.distributionConstructor);
return result; }
} return result;
}
} }

View File

@ -5,7 +5,7 @@ import java.util.logging.*;
/** /**
* The LoggerManager class allows for basic debug output management using * The LoggerManager class allows for basic debug output management using
* Java's default logging class. * Java's default logging class.
* *
* @author R.Thomas * @author R.Thomas
* @version 1.0 * @version 1.0
*/ */
@ -17,7 +17,7 @@ public class LoggerManager {
/** /**
* Static factory for the Logger class * Static factory for the Logger class
* *
* @param name String, of the logger to create * @param name String, of the logger to create
* @return Logger, a new logger * @return Logger, a new logger
*/ */
@ -41,7 +41,7 @@ public class LoggerManager {
Handler handler = new StreamHandler(System.err, new SimpleFormatter()); Handler handler = new StreamHandler(System.err, new SimpleFormatter());
logger.addHandler(handler); logger.addHandler(handler);
logger.setUseParentHandlers(false); logger.setUseParentHandlers(false);
return logger; return logger;
} }

View File

@ -2,7 +2,7 @@ package fr.packageviewer;
/** /**
* The Pair class stores two objects of distinct type * The Pair class stores two objects of distinct type
* *
* @author R.Thomas * @author R.Thomas
* @version 1.0 * @version 1.0
*/ */
@ -19,7 +19,7 @@ public class Pair<K, V> {
/** /**
* Main Constructor for the Pair class * Main Constructor for the Pair class
* *
* @param first, the first object to be stored * @param first, the first object to be stored
* @param second the second object to be stored * @param second the second object to be stored
*/ */
@ -30,7 +30,7 @@ public class Pair<K, V> {
/** /**
* Getter for the attribute first * Getter for the attribute first
* *
* @return the object stored in the attribute first * @return the object stored in the attribute first
*/ */
public K getFirst() { public K getFirst() {
@ -39,7 +39,7 @@ public class Pair<K, V> {
/** /**
* Setter for the attribute first * Setter for the attribute first
* *
* @param first Store the given object in the attribute first * @param first Store the given object in the attribute first
*/ */
public void setFirst(K first) { public void setFirst(K first) {
@ -48,7 +48,7 @@ public class Pair<K, V> {
/** /**
* Getter for the attribute second * Getter for the attribute second
* *
* @return the object stored in the attribute second * @return the object stored in the attribute second
*/ */
public V getSecond() { public V getSecond() {
@ -57,7 +57,7 @@ public class Pair<K, V> {
/** /**
* Setter for the attribute second * Setter for the attribute second
* *
* @param second Store the given object in the attribute second * @param second Store the given object in the attribute second
*/ */
public void setSecond(V second) { public void setSecond(V second) {
@ -65,10 +65,10 @@ public class Pair<K, V> {
} }
/** /**
* Returns a string representation of the pair * Returns a string representation of the pair
* *
* @return String, string representation of the pair * @return String, string representation of the pair
*/ */
@Override @Override
public String toString() { public String toString() {
return "Pair{key=%s,value=%s}".formatted(first, second); return "Pair{key=%s,value=%s}".formatted(first, second);

View File

@ -20,6 +20,7 @@ public class Searcher {
/** /**
* Get the list of all packages in the distribution set before * Get the list of all packages in the distribution set before
*
* @param packageName the name of the package wanted * @param packageName the name of the package wanted
* @return the list of all packages found * @return the list of all packages found
* @author Capelier-Marla * @author Capelier-Marla
@ -28,11 +29,11 @@ public class Searcher {
// we add all instanced constructors in a list, only one if defined at creation of the object // we add all instanced constructors in a list, only one if defined at creation of the object
List<Distribution> distributions; List<Distribution> distributions;
if(distributionName == null) { if (distributionName == null) {
distributions = DistributionEnum.getAllDistributionsInstances(); distributions = DistributionEnum.getAllDistributionsInstances();
} else { } else {
distributions = Collections.singletonList(DistributionEnum.getDistributionConstructorByName(distributionName)); distributions = Collections.singletonList(DistributionEnum.getDistributionConstructorByName(distributionName));
if(distributions.get(0) == null) { if (distributions.get(0) == null) {
System.out.println("Distribution non trouvée"); System.out.println("Distribution non trouvée");
System.exit(0); System.exit(0);
} }
@ -48,7 +49,7 @@ public class Searcher {
} }
// we get all packages waiting for them to be received // we get all packages waiting for them to be received
for(Future<List<SearchedPackage>> futurePackageList : listFuturePackagesList ) { for (Future<List<SearchedPackage>> futurePackageList : listFuturePackagesList) {
try { try {
List<SearchedPackage> tempList = futurePackageList.get(); List<SearchedPackage> tempList = futurePackageList.get();
allPackages.addAll(tempList); allPackages.addAll(tempList);
@ -61,7 +62,7 @@ public class Searcher {
public Package getPackage(SearchedPackage packetInput) { public Package getPackage(SearchedPackage packetInput) {
if(distributionName == null) { if (distributionName == null) {
distributionName = packetInput.getDistribution(); distributionName = packetInput.getDistribution();
} }
String packageName = packetInput.getName(); String packageName = packetInput.getName();

View File

@ -19,129 +19,129 @@ import java.util.logging.Logger;
/** /**
* This class handles package requests for Arch linux. All return objects in * This class handles package requests for Arch linux. All return objects in
* this class are wrapped by a CompletableFuture to ensure async workload. * this class are wrapped by a CompletableFuture to ensure async workload.
* *
* @author C.Marla, R.Thomas * @author C.Marla, R.Thomas
* @version 1.0 * @version 1.0
*/ */
public class ArchDistribution extends AsyncRequestsParser implements Distribution { public class ArchDistribution extends AsyncRequestsParser implements Distribution {
/** /**
* Logger object used to split debug output and the application output * Logger object used to split debug output and the application output
*/ */
private static final Logger logger = LoggerManager.getLogger("ArchDistribution"); private static final Logger logger = LoggerManager.getLogger("ArchDistribution");
/** /**
* This method remove all characters in the first string passed as * This method remove all characters in the first string passed as
* parameter after one of the character in the second string if found * parameter after one of the character in the second string if found
* in the first string * in the first string
* *
* @param str String, the string to trim * @param str String, the string to trim
* @param trimAfterCharacters String, the character that delimits our string * @param trimAfterCharacters String, the character that delimits our string
* @return the string after being trimmed * @return the string after being trimmed
*/ */
private static String trimAfterCharacters(String str, String trimAfterCharacters) { private static String trimAfterCharacters(String str, String trimAfterCharacters) {
for (char c : trimAfterCharacters.toCharArray()) { for (char c : trimAfterCharacters.toCharArray()) {
int index = str.indexOf(c); int index = str.indexOf(c);
if (index > 0) if (index > 0)
str = str.substring(index); str = str.substring(index);
} }
return str; return str;
} }
/** /**
* This function return a package from arch package api in the form of a Pair * This function return a package from arch package api in the form of a Pair
* Composed of a Package object, and a set of string containing the names of * Composed of a Package object, and a set of string containing the names of
* the dependencies of the package. * the dependencies of the package.
* *
* @param packageName String, The package's exact name * @param packageName String, The package's exact name
* @return Pair of Package and Set of String * @return Pair of Package and Set of String
*/ */
@Override @Override
public CompletableFuture<Pair<Package, Set<String>>> getPackageFromAPI(String packageName) { public CompletableFuture<Pair<Package, Set<String>>> getPackageFromAPI(String packageName) {
// create a new http client and make a request to the arch research api // create a new http client and make a request to the arch research api
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest HttpRequest request = HttpRequest
.newBuilder(URI.create("https://archlinux.org/packages/search/json/?name=" + packageName)).build(); .newBuilder(URI.create("https://archlinux.org/packages/search/json/?name=" + packageName)).build();
CompletableFuture<Pair<Package, Set<String>>> futureResult = new CompletableFuture<>(); CompletableFuture<Pair<Package, Set<String>>> futureResult = new CompletableFuture<>();
// send the request and when there's a response // send the request and when there's a response
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> { client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> {
//parse the json response //parse the json response
JSONObject json = new JSONObject(result.body()); JSONObject json = new JSONObject(result.body());
// check if the response contains something
JSONArray resultsArrayJson = json.getJSONArray("results");
if (resultsArrayJson.length() == 0) {
// unknown package, probably an abstract dependency
futureResult.complete(null);
return;
}
JSONObject resultJson = resultsArrayJson.getJSONObject(0);
Set<String> dependenciesNames = new HashSet<>();
// parse dependencies without version requirements (bash >= 3.0) -> (bash)
for (Object dependency : resultJson.getJSONArray("depends")) {
dependenciesNames.add(trimAfterCharacters((String) dependency, "<>="));
}
//Create the package and store it and its set of deps in a pair
futureResult.complete(new Pair<>(
new Package(
resultJson.getString("pkgname"),
resultJson.getString("pkgver"),
resultJson.getString("repo"),
resultJson.getString("pkgdesc"),
"arch"),
dependenciesNames));
}).exceptionally(error -> {
error.printStackTrace();
logger.warning("Error while fetching package %s from the API : \n%s".formatted(packageName, error));
futureResult.complete(null);
return null;
});
return futureResult; // check if the response contains something
JSONArray resultsArrayJson = json.getJSONArray("results");
if (resultsArrayJson.length() == 0) {
// unknown package, probably an abstract dependency
futureResult.complete(null);
return;
}
JSONObject resultJson = resultsArrayJson.getJSONObject(0);
Set<String> dependenciesNames = new HashSet<>();
// parse dependencies without version requirements (bash >= 3.0) -> (bash)
for (Object dependency : resultJson.getJSONArray("depends")) {
dependenciesNames.add(trimAfterCharacters((String) dependency, "<>="));
}
//Create the package and store it and its set of deps in a pair
futureResult.complete(new Pair<>(
new Package(
resultJson.getString("pkgname"),
resultJson.getString("pkgver"),
resultJson.getString("repo"),
resultJson.getString("pkgdesc"),
"arch"),
dependenciesNames));
}).exceptionally(error -> {
error.printStackTrace();
logger.warning("Error while fetching package %s from the API : \n%s".formatted(packageName, error));
futureResult.complete(null);
return null;
});
} return futureResult;
/** }
* Search for a package matching a pattern and return a list of packages and
* return a list of string matching this pattern.
*
* @param packageName String, the pattern to search in the repositories
* @return List of SearchedPackage objects
*/
public CompletableFuture<List<SearchedPackage>> searchPackage(String packageName) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://archlinux.org/packages/search/json/?q=" + packageName))
.build();
CompletableFuture<List<SearchedPackage>> futureSearchedPackages = new CompletableFuture<>(); /**
* Search for a package matching a pattern and return a list of packages and
* return a list of string matching this pattern.
*
* @param packageName String, the pattern to search in the repositories
* @return List of SearchedPackage objects
*/
public CompletableFuture<List<SearchedPackage>> searchPackage(String packageName) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://archlinux.org/packages/search/json/?q=" + packageName))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> { CompletableFuture<List<SearchedPackage>> futureSearchedPackages = new CompletableFuture<>();
List<SearchedPackage> searchedPackagesList = new ArrayList<>(); client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> {
JSONObject json = new JSONObject(result.body());
// iterate for every package in the list List<SearchedPackage> searchedPackagesList = new ArrayList<>();
for (Object searchResultObj : json.getJSONArray("results")) { JSONObject json = new JSONObject(result.body());
// convert object into String
JSONObject searchResultJson = (JSONObject) searchResultObj;
// add package into to list
searchedPackagesList.add(new SearchedPackage(
searchResultJson.getString("pkgname"),
searchResultJson.getString("pkgver"),
searchResultJson.getString("repo"),
searchResultJson.getString("pkgdesc"),
"arch"));
}
futureSearchedPackages.complete(searchedPackagesList);
}).exceptionally(error -> {
error.printStackTrace();
futureSearchedPackages.complete(Collections.emptyList());
return null;
});
return futureSearchedPackages; // iterate for every package in the list
for (Object searchResultObj : json.getJSONArray("results")) {
// convert object into String
JSONObject searchResultJson = (JSONObject) searchResultObj;
// add package into to list
searchedPackagesList.add(new SearchedPackage(
searchResultJson.getString("pkgname"),
searchResultJson.getString("pkgver"),
searchResultJson.getString("repo"),
searchResultJson.getString("pkgdesc"),
"arch"));
}
futureSearchedPackages.complete(searchedPackagesList);
}).exceptionally(error -> {
error.printStackTrace();
futureSearchedPackages.complete(Collections.emptyList());
return null;
});
} return futureSearchedPackages;
}
} }

View File

@ -8,7 +8,7 @@ import java.util.concurrent.Future;
/** /**
* This interface specifies the methods needed by a distribution to be parsable. * This interface specifies the methods needed by a distribution to be parsable.
* *
* @author R.Thomas * @author R.Thomas
* @version 1.0 * @version 1.0
*/ */
@ -16,7 +16,7 @@ public interface Distribution {
/** /**
* Search for a package matching a pattern and return a list of packages and * Search for a package matching a pattern and return a list of packages and
* return a list of string matching this pattern. * return a list of string matching this pattern.
* *
* @param packageName String, the pattern to search in the repositories * @param packageName String, the pattern to search in the repositories
* @return List of SearchedPackage objects * @return List of SearchedPackage objects
*/ */
@ -28,7 +28,7 @@ public interface Distribution {
* parameter, the package contains in its dependency list fully formed * parameter, the package contains in its dependency list fully formed
* packages that also contains its dependencies, the dependency depth is * packages that also contains its dependencies, the dependency depth is
* specified by the parameter with the same name. * specified by the parameter with the same name.
* *
* @param packageName String, The package's exact name * @param packageName String, The package's exact name
* @param depth int, the depth of the dependency tree * @param depth int, the depth of the dependency tree
* @return Package, the fully completed package * @return Package, the fully completed package

View File

@ -24,128 +24,128 @@ import java.util.logging.Logger;
*/ */
public class FedoraDistribution extends AsyncRequestsParser implements Distribution { public class FedoraDistribution extends AsyncRequestsParser implements Distribution {
/** /**
* Logger object used to split debug output and the application output * Logger object used to split debug output and the application output
*/ */
private static final Logger logger = LoggerManager.getLogger("FedoraDistribution"); private static final Logger logger = LoggerManager.getLogger("FedoraDistribution");
/** /**
* This function return a package from Fedora metadata api in the form of a * This function return a package from Fedora metadata api in the form of a
* Pair Composed of a Package object, and a set of string containing the * Pair Composed of a Package object, and a set of string containing the
* names of the dependencies of the package. * names of the dependencies of the package.
* *
* @param packageName String, The package's exact name * @param packageName String, The package's exact name
* @return Pair of Package and Set of String * @return Pair of Package and Set of String
*/ */
protected CompletableFuture<Pair<Package, Set<String>>> getPackageFromAPI(String packageName) { protected CompletableFuture<Pair<Package, Set<String>>> getPackageFromAPI(String packageName) {
// create a new http client // create a new http client
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
// and create its url // and create its url
String url = "https://mdapi.fedoraproject.org/rawhide/pkg/" + packageName + ""; String url = "https://mdapi.fedoraproject.org/rawhide/pkg/" + packageName + "";
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
CompletableFuture<Pair<Package, Set<String>>> futureResult = new CompletableFuture<>(); CompletableFuture<Pair<Package, Set<String>>> futureResult = new CompletableFuture<>();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> { client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> {
String body = result.body(); String body = result.body();
if (body.contains("404: Not Found")) { if (body.contains("404: Not Found")) {
futureResult.complete(null); futureResult.complete(null);
return; return;
} }
JSONObject json = new JSONObject(result.body()); JSONObject json = new JSONObject(result.body());
// get infos // get infos
Set<String> dependenciesNames = new HashSet<>(); Set<String> dependenciesNames = new HashSet<>();
for (Object depPackageObj : json.getJSONArray("requires")) { for (Object depPackageObj : json.getJSONArray("requires")) {
// convert object into String // convert object into String
JSONObject depPackageJson = (JSONObject) depPackageObj; JSONObject depPackageJson = (JSONObject) depPackageObj;
// add package into Package List // add package into Package List
String depName = depPackageJson.getString("name"); String depName = depPackageJson.getString("name");
if (depName.contains(".so")) if (depName.contains(".so"))
continue; continue;
if (depName.contains("/")) if (depName.contains("/"))
continue; continue;
dependenciesNames.add(depName); dependenciesNames.add(depName);
} }
futureResult.complete(new Pair<>( futureResult.complete(new Pair<>(
new Package( new Package(
json.getString("basename"), json.getString("basename"),
json.getString("version"), json.getString("version"),
"rawhide", "rawhide",
json.getString("summary"), json.getString("summary"),
"fedora" "fedora"
), ),
dependenciesNames dependenciesNames
)); ));
}).exceptionally(error->{ }).exceptionally(error -> {
error.printStackTrace(); error.printStackTrace();
logger.warning("Error while fetching package %s from the API : \n%s".formatted(packageName, error)); logger.warning("Error while fetching package %s from the API : \n%s".formatted(packageName, error));
futureResult.complete(null); futureResult.complete(null);
return null; return null;
}); });
// if there's an error, return an empty string // if there's an error, return an empty string
return futureResult; return futureResult;
} }
/** /**
* Search for a package matching a pattern and return a list of packages and * Search for a package matching a pattern and return a list of packages and
* return a list of string matching this pattern. * return a list of string matching this pattern.
* *
* @param packageName String, the pattern to search in the repositories * @param packageName String, the pattern to search in the repositories
* @return List of SearchedPackage objects * @return List of SearchedPackage objects
*/ */
@Override @Override
public CompletableFuture<List<SearchedPackage>> searchPackage(String packageName) { public CompletableFuture<List<SearchedPackage>> searchPackage(String packageName) {
// create a new http client and make a request to the fedora research api // create a new http client and make a request to the fedora research api
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create( .uri(URI.create(
"https://src.fedoraproject.org/api/0/projects?namepace=rpms&per_page=100&short=true&pattern=*" "https://src.fedoraproject.org/api/0/projects?namepace=rpms&per_page=100&short=true&pattern=*"
+ packageName + "*")) + packageName + "*"))
.build(); .build();
CompletableFuture<List<SearchedPackage>> futureSearchedPackages = new CompletableFuture<>(); CompletableFuture<List<SearchedPackage>> futureSearchedPackages = new CompletableFuture<>();
// send the request and when there's a response // send the request and when there's a response
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> { client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> {
//parse the json response //parse the json response
JSONObject json = new JSONObject(result.body()); JSONObject json = new JSONObject(result.body());
List<SearchedPackage> searchedPackagesList = new ArrayList<>(); List<SearchedPackage> searchedPackagesList = new ArrayList<>();
// iterate for every package in the list // iterate for every package in the list
for (Object searchResultObj : json.getJSONArray("projects")) { for (Object searchResultObj : json.getJSONArray("projects")) {
// convert object into String // convert object into String
JSONObject searchResultJson = (JSONObject) searchResultObj; JSONObject searchResultJson = (JSONObject) searchResultObj;
// get infos // get infos
String name = searchResultJson.getString("name"); String name = searchResultJson.getString("name");
// do not include fork projects in the list // do not include fork projects in the list
if(!name.startsWith("fork/")){ if (!name.startsWith("fork/")) {
// add package into to list // add package into to list
searchedPackagesList.add(new SearchedPackage( searchedPackagesList.add(new SearchedPackage(
name, name,
null, null,
"rawhide", "rawhide",
searchResultJson.getString("description"), searchResultJson.getString("description"),
"fedora" "fedora"
)); ));
} }
} }
futureSearchedPackages.complete(searchedPackagesList); futureSearchedPackages.complete(searchedPackagesList);
}).exceptionally(error -> { }).exceptionally(error -> {
error.printStackTrace(); error.printStackTrace();
futureSearchedPackages.complete(Collections.emptyList()); futureSearchedPackages.complete(Collections.emptyList());
return null; return null;
}); });
return futureSearchedPackages; return futureSearchedPackages;
} }
} }

View File

@ -6,6 +6,7 @@ import fr.packageviewer.pack.SearchedPackage;
import java.util.List; import java.util.List;
public interface Frontend { public interface Frontend {
SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets); SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets);
void showPackageTree(Package packet, int depth);
void showPackageTree(Package packet, int depth);
} }

View File

@ -2,15 +2,11 @@ package fr.packageviewer.frontend;
public class FrontendFactory { public class FrontendFactory {
public static Frontend get(String name){ public static Frontend get(String name) {
switch(name){ if (name.equals("terminal")) {
case "terminal":{ return new FrontendTerminal();
return new FrontendTerminal(); }
} throw new IllegalArgumentException("Invalid frontend");
default:{ }
throw new IllegalArgumentException("Invalid frontend");
}
}
}
} }

View File

@ -6,15 +6,16 @@ import fr.packageviewer.pack.SearchedPackage;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class FrontendTerminal implements Frontend{ public class FrontendTerminal implements Frontend {
/** /**
* Check if the String given is a number * Check if the String given is a number
*
* @param i the String given * @param i the String given
* @return true if the String is a number * @return true if the String is a number
* @author Capelier-Marla * @author Capelier-Marla
*/ */
private static boolean isNumeric(String i) { private static boolean isNumeric(String i) {
try { try {
Integer.parseInt(i); Integer.parseInt(i);
return true; return true;
@ -23,21 +24,21 @@ public class FrontendTerminal implements Frontend{
} }
} }
@Override @Override
public SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets) { public SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets) {
// list all packages in reverse order // list all packages in reverse order
for (int i = packets.size(); i-- > 0; ) { for (int i = packets.size(); i-- > 0; ) {
SearchedPackage searchedPacket = packets.get(i); SearchedPackage searchedPacket = packets.get(i);
System.out.printf("%s - %s/%s/%s %s%n\t%s%n", System.out.printf("%s - %s/%s/%s %s%n\t%s%n",
i, i,
searchedPacket.getDistribution(), searchedPacket.getDistribution(),
searchedPacket.getRepo(), searchedPacket.getRepo(),
searchedPacket.getName(), searchedPacket.getName(),
searchedPacket.getVersion()==null?"":searchedPacket.getVersion(), searchedPacket.getVersion() == null ? "" : searchedPacket.getVersion(),
searchedPacket.getDescription()); searchedPacket.getDescription());
} }
System.out.printf("Pick a package to see in details (0-%s) : ", packets.size()-1); System.out.printf("Pick a package to see in details (0-%s) : ", packets.size() - 1);
Scanner input = new Scanner(System.in); Scanner input = new Scanner(System.in);
// we create vars for the loop // we create vars for the loop
@ -49,9 +50,9 @@ public class FrontendTerminal implements Frontend{
packetNumberString = input.nextLine(); packetNumberString = input.nextLine();
// reset notValid to false, we set it in true only if something is wrong // reset notValid to false, we set it in true only if something is wrong
notValid = false; notValid = false;
if(isNumeric(packetNumberString)) { if (isNumeric(packetNumberString)) {
packetNumber = Integer.parseInt(packetNumberString); packetNumber = Integer.parseInt(packetNumberString);
if(packetNumber < 0 || packetNumber >= packets.size()) { if (packetNumber < 0 || packetNumber >= packets.size()) {
// this number is too big or too small // this number is too big or too small
System.out.println("Enter a valid number"); System.out.println("Enter a valid number");
notValid = true; notValid = true;
@ -61,22 +62,22 @@ public class FrontendTerminal implements Frontend{
System.out.println("Enter a valid number"); System.out.println("Enter a valid number");
notValid = true; notValid = true;
} }
} while(notValid); } while (notValid);
input.close(); input.close();
return packets.get(packetNumber); return packets.get(packetNumber);
} }
@Override @Override
public void showPackageTree(Package packet, int depth) { public void showPackageTree(Package packet, int depth) {
System.out.printf("%s%s / %s : %s%n", System.out.printf("%s%s / %s : %s%n",
" ".repeat(depth), " ".repeat(depth),
packet.getName(), packet.getName(),
packet.getVersion(), packet.getVersion(),
packet.getDescription()); packet.getDescription());
for (Package dep : packet.getDeps()) { for (Package dep : packet.getDeps()) {
showPackageTree(dep, depth+1); showPackageTree(dep, depth + 1);
} }
} }
} }

View File

@ -5,73 +5,73 @@ import java.util.List;
/** /**
* The Package class stores all metadata needed for a fully completed package. * The Package class stores all metadata needed for a fully completed package.
* *
* @author C.Marla, R.Thomas, S.Djalim * @author C.Marla, R.Thomas, S.Djalim
* @version 1.0 * @version 1.0
*/ */
public class Package extends SearchedPackage { public class Package extends SearchedPackage {
/** /**
* List of package storing all the dependencies of the package * List of package storing all the dependencies of the package
*/ */
private final List<Package> deps; private final List<Package> deps;
/** /**
* Getter for the deps attribute * Getter for the deps attribute
* *
* @return List, List of package storing all the dependencies of the package * @return List, List of package storing all the dependencies of the package
*/ */
public List<Package> getDeps() { public List<Package> getDeps() {
return deps; return deps;
} }
/** /**
* This method adds to the dependency list the package passed as parameter. * This method adds to the dependency list the package passed as parameter.
* *
* @param pack Package, the package to add as dependency * @param pack Package, the package to add as dependency
*/ */
public void addDep(Package pack) { public void addDep(Package pack) {
deps.add(pack); deps.add(pack);
} }
/** /**
* Second constructor for the Package class, allows to create a package * Second constructor for the Package class, allows to create a package
* without supplying a list of dependencies. * without supplying a list of dependencies.
* *
* @param name String, name of the package * @param name String, name of the package
* @param version String, version of the package * @param version String, version of the package
* @param repo String, repository where the package is located * @param repo String, repository where the package is located
* @param description String, description of the package * @param description String, description of the package
* @param distribution String, the distribution where this specific package * @param distribution String, the distribution where this specific package
* belongs * belongs
*/ */
public Package(String name, String version, String repo, String description, String distribution) { public Package(String name, String version, String repo, String description, String distribution) {
this(name, version, repo, description, distribution, new ArrayList<>()); this(name, version, repo, description, distribution, new ArrayList<>());
} }
/** /**
* Main constructor for the Package class * Main constructor for the Package class
* *
* @param name String, name of the package * @param name String, name of the package
* @param version String, version of the package * @param version String, version of the package
* @param repo String, repository where the package is located * @param repo String, repository where the package is located
* @param description String, description of the package * @param description String, description of the package
* @param distribution String, the distribution where this specific package * @param distribution String, the distribution where this specific package
* belongs * belongs
* @param deps List of Package, dependencies of the package * @param deps List of Package, dependencies of the package
*/ */
public Package(String name, String version, String repo, String description, String distribution, public Package(String name, String version, String repo, String description, String distribution,
List<Package> deps) { List<Package> deps) {
super(name, version, repo, description, distribution); super(name, version, repo, description, distribution);
this.deps = deps; this.deps = deps;
} }
/** /**
* Returns a string representation of the package * Returns a string representation of the package
* *
* @return String, string representation of the package * @return String, string representation of the package
*/ */
@Override @Override
public String toString() { public String toString() {
return "Package{%s,deps=%s}".formatted(super.toString(), deps); return "Package{%s,deps=%s}".formatted(super.toString(), deps);
} }
} }

View File

@ -3,103 +3,103 @@ package fr.packageviewer.pack;
/** /**
* The SearchedPackage class stores metadata found when searching for a * The SearchedPackage class stores metadata found when searching for a
* package. * package.
* *
* @author C.Marla, R.Thomas, S.Djalim * @author C.Marla, R.Thomas, S.Djalim
* @version 1.0 * @version 1.0
*/ */
public class SearchedPackage { public class SearchedPackage {
/** /**
* Name of the package * Name of the package
*/ */
private final String name; private final String name;
/** /**
* Version of the package * Version of the package
*/ */
private final String version; private final String version;
/** /**
* Repository where the package is located * Repository where the package is located
*/ */
private final String repo; private final String repo;
/** /**
* Description of the package * Description of the package
*/ */
private final String description; private final String description;
/** /**
* Distribution where this specific package belongs * Distribution where this specific package belongs
*/ */
private final String distribution; private final String distribution;
/** /**
* Getter for the name attribute * Getter for the name attribute
* *
* @return String, the name of the package * @return String, the name of the package
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* Getter for the version attribute * Getter for the version attribute
* *
* @return String, the version of the package * @return String, the version of the package
*/ */
public String getVersion() { public String getVersion() {
return version; return version;
} }
/** /**
* Getter for the repo attribute * Getter for the repo attribute
* *
* @return String, repository where the package is located * @return String, repository where the package is located
*/ */
public String getRepo() { public String getRepo() {
return repo; return repo;
} }
/** /**
* Getter for the description attribute * Getter for the description attribute
* *
* @return String, Description of the package * @return String, Description of the package
*/ */
public String getDescription() { public String getDescription() {
return description; return description;
} }
/** /**
* Getter for the distribution attribute * Getter for the distribution attribute
* *
* @return String, distribution where this specific package belongs * @return String, distribution where this specific package belongs
*/ */
public String getDistribution() { public String getDistribution() {
return distribution; return distribution;
} }
/** /**
* Constructor for the SearchedPackage class * Constructor for the SearchedPackage class
* *
* @param name String, name of the package * @param name String, name of the package
* @param version String, version of the package * @param version String, version of the package
* @param repo String, repository where the package is located * @param repo String, repository where the package is located
* @param description String, description of the package * @param description String, description of the package
* @param distribution String, the distribution where this specific package * @param distribution String, the distribution where this specific package
* belongs * belongs
*/ */
public SearchedPackage(String name, String version, String repo, String description, String distribution) { public SearchedPackage(String name, String version, String repo, String description, String distribution) {
this.name = name; this.name = name;
this.version = version; this.version = version;
this.repo = repo; this.repo = repo;
this.description = description; this.description = description;
this.distribution = distribution; this.distribution = distribution;
} }
/** /**
* Returns a string representation of the package * Returns a string representation of the package
* *
* @return String, string representation of the package * @return String, string representation of the package
*/ */
@Override @Override
public String toString() { public String toString() {
return "SearchedPackage{name=%s,version=%s,repo=%s,description=%s,distribution=%s}".formatted(name, version, return "SearchedPackage{name=%s,version=%s,repo=%s,description=%s,distribution=%s}".formatted(name, version,
repo, description, distribution); repo, description, distribution);
} }
} }

View File

@ -15,10 +15,9 @@ import java.util.logging.Logger;
* This abstract class defines the method that a distribution will use * This abstract class defines the method that a distribution will use
* in order to get a package and fill its dependency list. It does all that * in order to get a package and fill its dependency list. It does all that
* in an asynchronous manner * in an asynchronous manner
* *
* @author R.Thomas * @author R.Thomas
* @version 1.0 * @version 1.0
*
*/ */
public abstract class AsyncRequestsParser { public abstract class AsyncRequestsParser {
/** /**
@ -30,7 +29,7 @@ public abstract class AsyncRequestsParser {
* This function returns a package from the distribution's api in the form * This function returns a package from the distribution's api in the form
* of a Pair Composed of a Package object and a set of string containing * of a Pair Composed of a Package object and a set of string containing
* the names of the dependencies of the package. * the names of the dependencies of the package.
* *
* @param packageName String, The package's exact name * @param packageName String, The package's exact name
* @return Pair of Package and Set of String * @return Pair of Package and Set of String
*/ */
@ -42,7 +41,7 @@ public abstract class AsyncRequestsParser {
* parameter, the package contains in its dependency list fully formed * parameter, the package contains in its dependency list fully formed
* packages that also contains its dependencies, the dependency depth is * packages that also contains its dependencies, the dependency depth is
* specified by the parameter with the same name. * specified by the parameter with the same name.
* *
* @param packageName String, The package's exact name * @param packageName String, The package's exact name
* @param depth int, the depth of the dependency tree * @param depth int, the depth of the dependency tree
* @return Package, the fully completed package * @return Package, the fully completed package

View File

@ -14,19 +14,21 @@ import java.util.concurrent.Future;
public abstract class DistroTest<T extends Distribution> { public abstract class DistroTest<T extends Distribution> {
protected abstract T createInstance(); protected abstract T createInstance();
protected List<SearchedPackage> helperSearchPackage(String packageName){
protected List<SearchedPackage> helperSearchPackage(String packageName) {
Distribution distribution = createInstance(); Distribution distribution = createInstance();
Future<List<SearchedPackage>> future = distribution.searchPackage(packageName); Future<List<SearchedPackage>> future = distribution.searchPackage(packageName);
try{ try {
return future.get(); return future.get();
} catch (ExecutionException | InterruptedException e) { } catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
protected Package helperGetPackageTree(String packageName, int depth){
protected Package helperGetPackageTree(String packageName, int depth) {
Distribution distribution = createInstance(); Distribution distribution = createInstance();
Future<Package> future = distribution.getPackageTree(packageName, depth); Future<Package> future = distribution.getPackageTree(packageName, depth);
try{ try {
return future.get(); return future.get();
} catch (ExecutionException | InterruptedException e) { } catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -34,7 +36,7 @@ public abstract class DistroTest<T extends Distribution> {
} }
@Test @Test
public void testBasicQueryDoNotFail(){ public void testBasicQueryDoNotFail() {
helperGetPackageTree("bash", 0); helperGetPackageTree("bash", 0);
} }
@ -56,7 +58,7 @@ public abstract class DistroTest<T extends Distribution> {
public void testQueryWithDepth1hasOneLevelOfDeps() { public void testQueryWithDepth1hasOneLevelOfDeps() {
Package pack = helperGetPackageTree("bash", 1); Package pack = helperGetPackageTree("bash", 1);
Assertions.assertNotEquals(pack.getDeps().size(), 0); Assertions.assertNotEquals(pack.getDeps().size(), 0);
for(Package dep : pack.getDeps()){ for (Package dep : pack.getDeps()) {
Assertions.assertEquals(dep.getDeps().size(), 0); Assertions.assertEquals(dep.getDeps().size(), 0);
} }
} }
@ -83,10 +85,11 @@ public abstract class DistroTest<T extends Distribution> {
public void testThatBashSearchReturnsResults() { public void testThatBashSearchReturnsResults() {
Assertions.assertNotEquals(helperSearchPackage("bash").size(), 0); Assertions.assertNotEquals(helperSearchPackage("bash").size(), 0);
} }
@Test @Test
public void testThatBashSearchContainsBash() { public void testThatBashSearchContainsBash() {
for(SearchedPackage pack : helperSearchPackage("bash")){ for (SearchedPackage pack : helperSearchPackage("bash")) {
if(pack.getName().equals("bash")){ if (pack.getName().equals("bash")) {
Assertions.assertTrue(true); Assertions.assertTrue(true);
return; return;
} }