diff --git a/README.md b/README.md
index 1b3245811197d068cd5eba584ad8b2c980aa026d..70ba3591ab4ca8583973078d088d632daf0857fd 100644
--- a/README.md
+++ b/README.md
@@ -12,22 +12,99 @@ Le projet a été construit à partir de Maven. Maven est installable via la lig
Avant de pouvoir lancer le programme, il faut le compiler avec `mvn package`.
-Le programme se lance ensuite en ligne de commande sans argument.
+Le programme se lance ensuite en ligne de commande sans argument avec `mvn exec:java`.
-Exemple d'utilisation : `mvn exec:java`
+Au lancement du programme, `il faut enregistrer des serveurs FTP`.
-Au lancement du programme, `un username et un password seront demandés` afin d'authentifier l'utilisateur. Si ceux-ci ne correspondent à aucun utilisateur autorisé à utiliser la plateforme, le programme le rejectera.
+```sh
+curl --request PUT 'http://localhost:8080/flopbox/{nom du serveur}' --header 'host:{nom de domaine}'
+
+Exemple :
+curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com'
+curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost'
+```
+
+A noter que pour `localhost`, il faudra lancer `un serveur FTP en local`.
+
+```sh
+pip install --user pyftpdlib
+python -m pyftpdlib # localhost:2121 user & pass:anonymous
+```
+
+Il est également possible d'`afficher les serveurs enregistrés` et de `les supprimer`.
+
+```sh
+curl --request GET 'http://localhost:8080/flopbox/'
+curl --request DELETE 'http://localhost:8080/flopbox/{nom du serveur}'
+
+Exemple :
+curl --request GET 'http://localhost:8080/flopbox/'
+curl --request DELETE 'http://localhost:8080/flopbox/ubuntu'
+```
-Si les identifiants correspondent bien à un utilisateur autorisé à utiliser la plateforme, le programme lancera la plateforme à l'adresse `http://localhost:8080/myapp/`.
+Une fois des serveurs enregistrés, il devient possible d'effectuer certaines opérations comme par exemple `lister un fichier ou un dossier distant`.
+
+```sh
+curl --request GET 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
-Afin d'arrêter la plateforme, vous pouvez soit faire un `Ctrl+C` sur le terminal de lancement ou soit envoyer un signal `SIGKILL` au processus. Une solution permettant simplement d'écrire `stop` sur le terminal de lancement a été implémentée mais une exception au niveau du code généré lors de l'initialisation du projet, est levée empêchant cette solution de fonctionner.
+Exemple :
+curl --request GET 'http://localhost:8080/flopbox/ubuntu/' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+`Créer un dossier`.
+
+```sh
+curl --request PUT 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du futur dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
+
+Exemple :
+curl --request PUT 'http://localhost:8080/flopbox/localhost/testFiles/dir_created' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+`Renommer un fichier ou un dossier`.
+
+```sh
+curl --request PATCH 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'to:{nouveau nom du fichier ou dossier}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
+
+
+Exemple :
+curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_rename' --header 'port:2121' --header 'to:dir_renamed' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+`Supprimer un fichier ou un dossier`.
+
+```sh
+curl --request DELETE 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
+
+Exemple :
+curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme01.jpg' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+`Mettre en ligne un fichier`.
+
+```sh
+curl --request POST 'http://localhost:8080/flopbox/{nom du serveur}/{nom du fichier mis en ligne}/upload' --header 'port:{numéro de port dentrée du serveur}' --header 'from:{chemin du fichier à mettre en ligne}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
+
+Exemple :
+curl --request POST 'http://localhost:8080/flopbox/localhost/meme_uploaded/upload' --header 'port:2121' --header 'from:testFiles/Lysithea_meme03.png' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+`Télécharger un fichier`.
+
+```sh
+curl --request GET 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier à télécharger}/download' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}'
+
+Exemple :
+curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html/download' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous'
+```
+
+Pour arrêter la plateforme proprement, vous pouvez simplement appuyer sur la touche `Entrée` de votre clavier. Sinon, vous pouvez faire un `Ctrl+C` sur le terminal de lancement ou bien envoyer un signal `SIGKILL` au processus.
# Architecture
Le projet a été construit à partir de Maven en utilisant la commande suivante :
```sh
-mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=3.0.1
+mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=2.33
```
L'archive du projet, après la compilation, est `target/flopbox-1.0-SNAPSHOT.jar`.
@@ -38,154 +115,143 @@ Les tests se situent dans le dossier `src/test/java/flopbox` depuis la racine du
Le projet contient les packages suivants :
-- **account** -> Le package relatif aux comptes pouvant utiliser la plateforme
+- **client** -> Le package relatif à l'initialisation du client et sa terminaison
- **command** -> Le package relatif aux commandes utilisables par la plateforme
-- **server** -> Le package relatif aux serveurs auxquels peut se connecter la plateforme
-
-# Commandes supportées
-
-La plateforme supporte les commandes curls suivantes :
-
-```curl
-curl -v http://localhost:8080/myapp/myresource/cdup
-curl -v http://localhost:8080/myapp/myresource/connect:{String address}:{int port}
-curl -v http://localhost:8080/myapp/myresource/cwd:{String pathname}
-curl -v http://localhost:8080/myapp/myresource/dele:{String pathname}
-curl -v http://localhost:8080/myapp/myresource/list
-curl -v http://localhost:8080/myapp/myresource/login:{String username}:{String password}
-curl -v http://localhost:8080/myapp/myresource/mkd:{String pathname}
-curl -v http://localhost:8080/myapp/myresource/pasv
-curl -v http://localhost:8080/myapp/myresource/port
-curl -v http://localhost:8080/myapp/myresource/pwd
-curl -v http://localhost:8080/myapp/myresource/quit
-curl -v http://localhost:8080/myapp/myresource/retr:{String pathname}
-curl -v http://localhost:8080/myapp/myresource/rn:{String oldfilename}:{String newfilename}
-curl -v http://localhost:8080/myapp/myresource/stor:{String pathname}
-curl -v http://localhost:8080/myapp/myresource/type:{int type}
-```
-
-**Les informations entre crochets sont des variables à modifier dont le type a été indiqué pour plus de clarté.**
-
-Par exemple, pour se connecter au serveur ftp.ubuntu.com, la commande à utiliser est :
-
-```curl
-curl -v http://localhost:8080/myapp/myresource/connect:ftp.ubuntu.com:21
-```
# Quelques exemples de code
```java
/**
- * Return if the password tried is the password of the account's username.
+ * Register a server and its host in the platform.
*
- * @param username The username registered.
- * @param password The password tried.
+ * @param server The server.
+ * @param host The host of the server.
*
- * @return If the password tried is the password of the username's account.
+ * @return How the command went.
*/
-public static boolean isTheRightPassword(String username, String password)
+public static String register(String server, String host)
{
- if(accounts.containsKey(username))
- return password.equals(accounts.get(username));
+ if(servers.containsKey(server))
+ return "The server \"" + server + "\" is already registered.";
- else
- return username.equals("anonymous");
+ servers.put(server, host);
+
+ return "The association \"" + server + " -> " + host + "\" has been registered.";
}
```
-L'objet `accounts` est une `Map<String,String>` contenant les paires `<username,password>`. Cette fonction a un comportement similaire à celui des serveurs ftp. Elle vérifie tous les utilisateurs tentant de s'enregistrer auprès de la plateforme sauf `anonymous`.
+La gestion des serveurs de la plateforme est très précise. `Le nom des fonctions dédiées à cet objectif représente bien ce qu'elles font`. Ici, l'enregistrement des serveurs sur la plateforme `n'empiète pas sur les autres serveurs` déjà enregistrés. Elle ne gagne donc pas en ambiguïté avec la fonction modify et `respecte bien le principe de responsabilité unique` (SRP).
```java
/**
- * Load the unique aliases in the program.
+ * Connect and log in the FTP server.
+ *
+ * @param client The FTP client.
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ *
+ * @return True if the client could connect and log in the FTP server, otherwise false.
*/
-public static void loadAliases()
+public static boolean connectAndLogin(FTPClient client, String server, int port, String username, String password)
{
- Map<String, String> aliases = Main.getAliases();
-
try
{
- BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt));
+ client.connect(ServerCommands.getServers().get(server), port);
- String line;
- while((line = reader.readLine()) != null)
- {
- int cut = line.indexOf(separator);
-
- String alias = line.substring(0, cut);
-
- /* If a same alias has already been put, we ignore it */
- if(aliases.containsKey(alias))
- continue;
-
- String server = line.substring(cut+1);
-
- aliases.put(alias, server);
- }
+ if(FTPReply.isPositiveCompletion(client.getReplyCode()))
+ if(client.login(username, password))
+ return client.setFileType(FTPClient.BINARY_FILE_TYPE);
- reader.close();
+ return false;
}
catch(IOException e)
{
- /* Do nothing */
+ return false;
}
}
```
-Cette méthode `enregistre tous les alias uniques` des serveurs. Pour cela, elle va lire un fichier nommé `aliases.txt` à la racine du projet. `Pour ajouter ou modifier une association, c'est dans ce fichier que ça se passe.` Un système identique a été mis en place avec le fichier `accounts.txt` pour les `comptes autorisés à se connecter` à la plateforme.
+`La connexion et identification est faite en premier` à chaque récupération de commande. `Le type binaire est également préféré` à celui de base, ascii, par soucis de compatibilité (de plus en plus de serveur le privilégie à l'instar d'ascii).
```java
/**
- * List the files of the working directory.
+ * List information about a file or files in a directory on the FTP server.
*
- * @param client The FTP client.
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param path The path of the file or directory.
*
- * @return How the command went.
+ * @return Information about the file or files in the directory.
*/
@GET
-@Path("list")
+@Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN)
-public String list(FTPClient client)
+public String list(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username, @HeaderParam("password") String password,
+ @PathParam ("path" ) String path )
{
- return LIST.execute(client);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.list(client, path);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ response = "The connection to the server failed.";
+
+
+ return response;
}
```
-La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées avec @GET mais avec un @Path différent` afin de les différencier.
+La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées` avec une méthode de requête HTTP et un chemin et `leur traitement se fait dans une autre classe`. Cette implémentation a l'avantage d'être `plus claire, plus maintenable et plus facilement débuggable`.
```java
/**
- * List the files of the working directory.
+ * List information about a file or files in a directory on the FTP server.
*
* @param client The FTP client.
+ * @param path The path of the file or directory.
*
- * @return How the command went.
+ * @return Information about the file or files in the directory.
*/
-public static String execute(FTPClient client)
+public static String list(FTPClient client, String path)
{
String response = "";
try
{
- FTPFile[] files = client.listFiles();
+ client.enterLocalPassiveMode();
+
+ FTPFile[] files = client.listFiles(path);
for(FTPFile file : files)
{
- response += file.getName() + "\n";
+ response += file.getRawListing();
+ response += "\n";
}
+
+ return response;
}
catch(IOException e)
{
- response = "The command \"" + NAME + "\" failed.";
+ response = "An IO error occured while sending the command or receiving its result.";
}
return response;
}
```
-`Le traitement des commandes est effectué dans des classes propres` aux commandes dans le package `command`. Ce, afin que le code soit plus clair et mieux structuré.
+Le traitement des commandes est effectué dans des `classes regroupant les commandes de par leur objectif` (gestion de la plateforme, FTP, etc...). Ces classes sont dans le package `command` et sont donc séparées de Main et MyResource par soucis de structuration. Elles doivent donc récupérer le client initialisé lors de la récupération des commandes.
# Les tests
@@ -193,10 +259,10 @@ Aucun test n'a été réalisé cette fois-ci.
Les efforts ont été concentrés à rendre la plateforme fonctionnel.
-# Ce que j'aurai amélioré avec le temps
+# Ce que j'aurais amélioré avec le temps
-J'aurais `mieux designé la gestion de l'authentification` auprès de la plateforme.
+J'aurais `terminé la généralisation fichier-dossier des commandes` afin de toutes les rendre universelles.
-J'aurais `expérimenté le multi-threading` de la plateforme.
+J'aurais `expérimenté le postionnement des fonctions dans le répertoire courant du fichier ou dossier visé` afin de voir les avantages que cela aurait pu apporter (maintenabilité, clarté, etc...).
-J'aurais `débuggé les communications plateforme-serveur` (malgré que j'y ai passé déjà plusieurs jours).
\ No newline at end of file
+J'aurais `rendu les retours encore plus précis` si une fonction n'avait pas rendu le résultat escompté.
diff --git a/downloads/FOOTER.html b/downloads/FOOTER.html
new file mode 100644
index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19
--- /dev/null
+++ b/downloads/FOOTER.html
@@ -0,0 +1,25 @@
+</div></div></div></div>
+<footer class="p-footer">
+ <div class="row">
+ <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical
+ are registered trademarks of Canonical Ltd.</small></p>
+ <nav class="p-footer__nav">
+ <ul class="p-footer__links">
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://www.ubuntu.com/legal"><small>Legal
+ information</small></a>
+ </li>
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug">
+ <small>Report a bug on this site</small></a>
+ </li>
+ </ul>
+ <span class="u-off-screen">
+ <a href="#">Go to the top of the page</a>
+ </span>
+ </nav>
+ </div>
+</footer>
+</body></html>
diff --git a/downloads/FOOTER_20210404_022313.html b/downloads/FOOTER_20210404_022313.html
new file mode 100644
index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19
--- /dev/null
+++ b/downloads/FOOTER_20210404_022313.html
@@ -0,0 +1,25 @@
+</div></div></div></div>
+<footer class="p-footer">
+ <div class="row">
+ <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical
+ are registered trademarks of Canonical Ltd.</small></p>
+ <nav class="p-footer__nav">
+ <ul class="p-footer__links">
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://www.ubuntu.com/legal"><small>Legal
+ information</small></a>
+ </li>
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug">
+ <small>Report a bug on this site</small></a>
+ </li>
+ </ul>
+ <span class="u-off-screen">
+ <a href="#">Go to the top of the page</a>
+ </span>
+ </nav>
+ </div>
+</footer>
+</body></html>
diff --git a/downloads/FOOTER_20210404_022322.html b/downloads/FOOTER_20210404_022322.html
new file mode 100644
index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19
--- /dev/null
+++ b/downloads/FOOTER_20210404_022322.html
@@ -0,0 +1,25 @@
+</div></div></div></div>
+<footer class="p-footer">
+ <div class="row">
+ <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical
+ are registered trademarks of Canonical Ltd.</small></p>
+ <nav class="p-footer__nav">
+ <ul class="p-footer__links">
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://www.ubuntu.com/legal"><small>Legal
+ information</small></a>
+ </li>
+ <li class="p-footer__item">
+ <a class="p-footer__link"
+ href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug">
+ <small>Report a bug on this site</small></a>
+ </li>
+ </ul>
+ <span class="u-off-screen">
+ <a href="#">Go to the top of the page</a>
+ </span>
+ </nav>
+ </div>
+</footer>
+</body></html>
diff --git a/downloads/README2.md b/downloads/README2.md
new file mode 100644
index 0000000000000000000000000000000000000000..8927291b44a312449bb64e88f9ae691b6ba98e35
--- /dev/null
+++ b/downloads/README2.md
@@ -0,0 +1,202 @@
+# FlopBox
+
+Par <ins>**Rayane Hamani**</ins>, le <ins>**01 avril 2021**</ins>
+
+# Pré-requis
+
+Le programme a été réalisé sous Java 11. Pour lancer le programme, il va donc falloir cette version de JRE. Elle est trouvable sur [le site officiel d'Oracle](https://www.oracle.com/fr/java/technologies/javase-downloads.html) avec [leur documentation d'installation](https://docs.oracle.com/en/java/javase/11/install/installation-jdk-linux-platforms.html).
+
+Le projet a été construit à partir de Maven. Maven est installable via la ligne de commande `sudo apt install maven` sur Linux ou bien sur Windows en téléchargeant l'archive sur [le site officiel d'Apache](https://maven.apache.org/download.cgi) et en suivant [leur documentation d'installation](https://maven.apache.org/install.html).
+
+# Utilisation
+
+Avant de pouvoir lancer le programme, il faut le compiler avec `mvn package`.
+
+Le programme se lance ensuite en ligne de commande sans argument.
+
+Exemple d'utilisation : `mvn exec:java`
+
+Au lancement du programme, `un username et un password seront demandés` afin d'authentifier l'utilisateur. Si ceux-ci ne correspondent à aucun utilisateur autorisé à utiliser la plateforme, le programme le rejectera.
+
+Si les identifiants correspondent bien à un utilisateur autorisé à utiliser la plateforme, le programme lancera la plateforme à l'adresse `http://localhost:8080/myapp/`.
+
+Afin d'arrêter la plateforme, vous pouvez soit faire un `Ctrl+C` sur le terminal de lancement ou soit envoyer un signal `SIGKILL` au processus. Une solution permettant simplement d'écrire `stop` sur le terminal de lancement a été implémentée mais une exception au niveau du code généré lors de l'initialisation du projet, est levée empêchant cette solution de fonctionner.
+
+# Architecture
+
+Le projet a été construit à partir de Maven en utilisant la commande suivante :
+
+```sh
+mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=2.33
+```
+
+L'archive du projet, après la compilation, est `target/flopbox-1.0-SNAPSHOT.jar`.
+
+Le code se situe dans le dossier `src/main/java/flopbox` depuis la racine du projet.
+
+Les tests se situent dans le dossier `src/test/java/flopbox` depuis la racine du projet.
+
+Le projet contient les packages suivants :
+
+- **account** -> Le package relatif aux comptes pouvant utiliser la plateforme
+- **command** -> Le package relatif aux commandes utilisables par la plateforme
+- **server** -> Le package relatif aux serveurs auxquels peut se connecter la plateforme
+
+# Commandes supportées
+
+La plateforme supporte les commandes curls suivantes :
+
+```curl
+curl -v http://localhost:8080/myapp/myresource/cdup
+curl -v http://localhost:8080/myapp/myresource/connect:{String address}:{int port}
+curl -v http://localhost:8080/myapp/myresource/cwd:{String pathname}
+curl -v http://localhost:8080/myapp/myresource/dele:{String pathname}
+curl -v http://localhost:8080/myapp/myresource/list
+curl -v http://localhost:8080/myapp/myresource/login:{String username}:{String password}
+curl -v http://localhost:8080/myapp/myresource/mkd:{String pathname}
+curl -v http://localhost:8080/myapp/myresource/pasv
+curl -v http://localhost:8080/myapp/myresource/port
+curl -v http://localhost:8080/myapp/myresource/pwd
+curl -v http://localhost:8080/myapp/myresource/quit
+curl -v http://localhost:8080/myapp/myresource/retr:{String pathname}
+curl -v http://localhost:8080/myapp/myresource/rn:{String oldfilename}:{String newfilename}
+curl -v http://localhost:8080/myapp/myresource/stor:{String pathname}
+curl -v http://localhost:8080/myapp/myresource/type:{int type}
+```
+
+**Les informations entre crochets sont des variables à modifier dont le type a été indiqué pour plus de clarté.**
+
+Par exemple, pour se connecter au serveur ftp.ubuntu.com, la commande à utiliser est :
+
+```curl
+curl -v http://localhost:8080/myapp/myresource/connect:ftp.ubuntu.com:21
+```
+
+# Quelques exemples de code
+
+```java
+/**
+ * Return if the password tried is the password of the account's username.
+ *
+ * @param username The username registered.
+ * @param password The password tried.
+ *
+ * @return If the password tried is the password of the username's account.
+ */
+public static boolean isTheRightPassword(String username, String password)
+{
+ if(accounts.containsKey(username))
+ return password.equals(accounts.get(username));
+
+ else
+ return username.equals("anonymous");
+}
+```
+
+L'objet `accounts` est une `Map<String,String>` contenant les paires `<username,password>`. Cette fonction a un comportement similaire à celui des serveurs ftp. Elle vérifie tous les utilisateurs tentant de s'enregistrer auprès de la plateforme sauf `anonymous`.
+
+```java
+/**
+ * Load the unique aliases in the program.
+ */
+public static void loadAliases()
+{
+ Map<String, String> aliases = Main.getAliases();
+
+ try
+ {
+ BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt));
+
+ String line;
+ while((line = reader.readLine()) != null)
+ {
+ int cut = line.indexOf(separator);
+
+ String alias = line.substring(0, cut);
+
+ /* If a same alias has already been put, we ignore it */
+ if(aliases.containsKey(alias))
+ continue;
+
+ String server = line.substring(cut+1);
+
+ aliases.put(alias, server);
+ }
+
+ reader.close();
+ }
+
+ catch(IOException e)
+ {
+ /* Do nothing */
+ }
+}
+```
+
+Cette méthode `enregistre tous les alias uniques` des serveurs. Pour cela, elle va lire un fichier nommé `aliases.txt` à la racine du projet. `Pour ajouter ou modifier une association, c'est dans ce fichier que ça se passe.` Un système identique a été mis en place avec le fichier `accounts.txt` pour les `comptes autorisés à se connecter` à la plateforme.
+
+```java
+/**
+ * List the files of the working directory.
+ *
+ * @param client The FTP client.
+ *
+ * @return How the command went.
+ */
+@GET
+@Path("list")
+@Produces(MediaType.TEXT_PLAIN)
+public String list(FTPClient client)
+{
+ return LIST.execute(client);
+}
+```
+
+La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées avec @GET mais avec un @Path différent` afin de les différencier.
+
+```java
+/**
+ * List the files of the working directory.
+ *
+ * @param client The FTP client.
+ *
+ * @return How the command went.
+ */
+public static String execute(FTPClient client)
+{
+ String response = "";
+
+ try
+ {
+ FTPFile[] files = client.listFiles();
+
+ for(FTPFile file : files)
+ {
+ response += file.getName() + "\n";
+ }
+ }
+
+ catch(IOException e)
+ {
+ response = "The command \"" + NAME + "\" failed.";
+ }
+
+ return response;
+}
+```
+
+`Le traitement des commandes est effectué dans des classes propres` aux commandes dans le package `command`. Ce, afin que le code soit plus clair et mieux structuré.
+
+# Les tests
+
+Aucun test n'a été réalisé cette fois-ci.
+
+Les efforts ont été concentrés à rendre la plateforme fonctionnel.
+
+# Ce que j'aurai amélioré avec le temps
+
+J'aurais `mieux designé la gestion de l'authentification` auprès de la plateforme.
+
+J'aurais `expérimenté le multi-threading` de la plateforme.
+
+J'aurais `débuggé les communications plateforme-serveur` (malgré que j'y ai passé déjà plusieurs jours).
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c34d5b7d34223949be23a2c368a27b89a79ff803..10796916cd1961448fcf78e8a05174a628275a89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,14 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+
<modelVersion>4.0.0</modelVersion>
+
+
<groupId>flopbox</groupId>
<artifactId>flopbox</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>flopbox</name>
+
+
<dependencyManagement>
<dependencies>
<dependency>
@@ -21,11 +27,14 @@
</dependencies>
</dependencyManagement>
+
+
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
+
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
@@ -44,13 +53,6 @@
<scope>test</scope>
</dependency>
- <!-- https://mvnrepository.com/artifact/org.glassfish.grizzly/grizzly-http-server -->
- <dependency>
- <groupId>org.glassfish.grizzly</groupId>
- <artifactId>grizzly-http-server</artifactId>
- <version>3.0.0</version>
- </dependency>
-
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
@@ -59,6 +61,8 @@
</dependency>
</dependencies>
+
+
<build>
<plugins>
<plugin>
@@ -71,6 +75,7 @@
<target>1.7</target>
</configuration>
</plugin>
+
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
@@ -103,8 +108,10 @@
</plugins>
</build>
+
+
<properties>
- <jersey.version>3.0.1</jersey.version>
+ <jersey.version>2.33</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
diff --git a/scripts/delete.sh b/scripts/delete.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8a9e70ce3e21e17dad0ce290bb93b11adc78f74d
--- /dev/null
+++ b/scripts/delete.sh
@@ -0,0 +1,31 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "------------------------------------"
+echo "We can delete any directory we want."
+echo "------------------------------------"
+
+echo ""
+curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_delete' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
+
+echo "------------------------------------"
+echo "We can also delete any file we want."
+echo "------------------------------------"
+
+echo ""
+curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme01.jpg' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/scripts/download.sh b/scripts/download.sh
new file mode 100755
index 0000000000000000000000000000000000000000..af9e8eb37c1af83a970f73130a9f36b088bde9d6
--- /dev/null
+++ b/scripts/download.sh
@@ -0,0 +1,23 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "---------------------------------"
+echo "We can download any file we want."
+echo "---------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html/download' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/scripts/list.sh b/scripts/list.sh
new file mode 100755
index 0000000000000000000000000000000000000000..da774ebf379e0a01c6274b67dc92b1e3a806013c
--- /dev/null
+++ b/scripts/list.sh
@@ -0,0 +1,31 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "----------------------------------"
+echo "We can list any directory we want."
+echo "----------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/ubuntu/' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
+
+echo "----------------------------------"
+echo "We can also list any file we want."
+echo "----------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/scripts/makeDir.sh b/scripts/makeDir.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8bd31066c6e46d4a97103c0b873f71aa3cf59e91
--- /dev/null
+++ b/scripts/makeDir.sh
@@ -0,0 +1,23 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "------------------------------------"
+echo "We can create any directory we want."
+echo "------------------------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/localhost/testFiles/dir_created' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/scripts/rename.sh b/scripts/rename.sh
new file mode 100755
index 0000000000000000000000000000000000000000..895752d5f4b9c2671ff2e6c3e2b12b4423f590ac
--- /dev/null
+++ b/scripts/rename.sh
@@ -0,0 +1,31 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "------------------------------------"
+echo "We can create any directory we want."
+echo "------------------------------------"
+
+echo ""
+curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_rename' --header 'port:2121' --header 'to:dir_renamed' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
+
+echo "------------------------------------"
+echo "We can also rename any file we want."
+echo "------------------------------------"
+
+echo ""
+curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme02.png' --header 'port:2121' --header 'to:meme_renamed' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/scripts/upload.sh b/scripts/upload.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a11a1e39e0d0001ba40588665b2ce7e117ad672f
--- /dev/null
+++ b/scripts/upload.sh
@@ -0,0 +1,23 @@
+echo "---------------------"
+echo "We register a server."
+echo "---------------------"
+
+echo ""
+curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost'
+echo ""
+
+echo "-----------------------------------------"
+echo "We check it is in the registered servers."
+echo "-----------------------------------------"
+
+echo ""
+curl --request GET 'http://localhost:8080/flopbox/'
+echo ""
+
+echo "-------------------------------"
+echo "We can upload any file we want."
+echo "-------------------------------"
+
+echo ""
+curl --request POST 'http://localhost:8080/flopbox/localhost/meme_uploaded/upload' --header 'port:2121' --header 'from:testFiles/Lysithea_meme03.png' --header 'username:anonymous' --header 'password:anonymous'
+echo ""
\ No newline at end of file
diff --git a/src/main/java/flopbox/Main.java b/src/main/java/flopbox/Main.java
index a1b4c4ebd8c4577d09f427a6cb2861c36a0b93eb..a904d8f0aaa0d20d0973bedb2a9e73a95d85c58c 100644
--- a/src/main/java/flopbox/Main.java
+++ b/src/main/java/flopbox/Main.java
@@ -1,82 +1,27 @@
package flopbox;
-
-
-import flopbox.account.AccountUtil;
-
-
-import org.apache.commons.net.ftp.FTPClient;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
/**
* Main class.
- *
*/
public class Main
{
- /* URI the Grizzly HTTP server will listen on */
- private static String uri = "http://localhost:8080/myapp/";
-
- /* Client the platform will use to connect to */
- private static FTPClient client = new FTPClient();
-
- /* Aliases of the servers the platform recognizes */
- private static Map<String, String> aliases = new HashMap<String, String>();
-
- /* Getters */
- public static String getUri() { return uri ; }
- public static FTPClient getClient() { return client ; }
- public static Map<String, String> getAliases() { return aliases ; }
-
-
-
- /**
- * Tell the user how to use the program.
- */
- public static void usage()
- {
- System.out.println("The program should be launched like that : java -jar target/flopbox-1.0-SNAPSHOT.jar [ftp server address] [ftp server port] [flopbox port] [username] [password]");
- }
-
-
-
- /**
- * Log in the platform.
- *
- * @return if
- */
- public static boolean login()
- {
- Scanner scanner = new Scanner(System.in);
-
- /* Set the username and password which will be used to log in the platform and the ftp server */
- System.out.print("Username : ");
- String username = scanner.nextLine();
- System.out.print("Password : ");
- String password = scanner.nextLine();
-
- System.out.println();
-
- scanner.close();
-
- return AccountUtil.isTheRightPassword(username, password);
- }
-
-
-
+ // Base URI the Grizzly HTTP server will listen on
+ public static final String BASE_URI = "http://localhost:8080/flopbox/";
+
+
+
/**
* Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
- *
+ *
* @return Grizzly HTTP server.
*/
public static HttpServer startServer()
@@ -87,32 +32,11 @@ public class Main
// create and start a new instance of grizzly http server
// exposing the Jersey application at BASE_URI
- return GrizzlyHttpServerFactory.createHttpServer(URI.create(uri), rc);
- }
-
-
-
- /**
- * Wait a word from the user.
- */
- public static void waitWord()
- {
- Scanner scanner = new Scanner(System.in);
-
- String wordToGet = "stop";
- String wordGot;
-
- do
- {
- wordGot = scanner.nextLine().toLowerCase();
- }
- while(!wordGot.equals(wordToGet));
-
- scanner.close();
+ return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
+
-
/**
* Main method.
*
@@ -122,25 +46,13 @@ public class Main
*/
public static void main(String[] args) throws IOException
{
- /* Exit the program if the username is unknown or the password is wrong */
- AccountUtil.loadAccounts();
- if(!login())
- {
- System.out.println("Unknown account.");
- usage();
- System.exit(1);
- }
-
- /* Start the server */
final HttpServer server = startServer();
+
System.out.println(String.format("Jersey app started with WADL available at "
- + "%sapplication.wadl\nHit enter to stop it...", uri));
+ + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
System.in.read();
- /* Wait a word from the user to then shutdown the server */
- // waitWord();
-
server.shutdownNow();
}
}
diff --git a/src/main/java/flopbox/MyResource.java b/src/main/java/flopbox/MyResource.java
index 06d77288c09b1b4688e8bf54270b4a7ce711946b..6e66ac58b487856096fc665344b2cbdd779b6c8f 100644
--- a/src/main/java/flopbox/MyResource.java
+++ b/src/main/java/flopbox/MyResource.java
@@ -1,295 +1,287 @@
package flopbox;
-
-
+import flopbox.client.ClientUtil;
import flopbox.command.*;
-import java.net.ServerSocket;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.PATCH;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
import org.apache.commons.net.ftp.FTPClient;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-
/**
- * Root resource (exposed at "myresource" path)
+ * Root resource (exposed at "/" path)
*/
-@Path("myresource")
+@Path("/")
public class MyResource
{
- private FTPClient client = Main.getClient();
- private ServerSocket activeConnection;
-
-
-
/**
- * Change to the parent directory.
- *
- * @param client The FTP client.
+ * Print the registered servers and their hosts.
*
- * @return How the command went.
+ * @return the registered servers and their hosts.
*/
- @GET
- @Path("cdup")
+ @GET
@Produces(MediaType.TEXT_PLAIN)
- public String cdup(FTPClient client)
+ public String printServers()
{
- return CDUP.execute(client);
+ return ServerCommands.print();
}
-
-
-
- /**
- * Connect the client to a ftp server.
+
+ /**
+ * Register a server and its host in the platform.
*
- * @param client The FTP client.
- * @param address The address of the ftp server.
- * @param port The port of the ftp server.
+ * @param server The server.
+ * @param host The host of the server.
*
* @return How the command went.
*/
- @GET
- @Path("connect:{address}:{port}")
+ @PUT
+ @Path("{server}")
@Produces(MediaType.TEXT_PLAIN)
- public String connect(FTPClient client, @PathParam("address") String address, @PathParam("port") int port)
+ public String registerServer(@PathParam("server") String server, @HeaderParam("host") String host)
{
- return CONNECT.execute(client, address, port);
+ return ServerCommands.register(server, host) + "\n";
}
-
-
/**
- * Change the working directory.
+ * Delete a registered server of the platform.
*
- * @param client The FTP client.
- * @param pathname The pathname of the next working directory.
+ * @param server The server.
*
* @return How the command went.
*/
- @GET
- @Path("cwd:{pathname}")
+ @DELETE
+ @Path("{server}")
@Produces(MediaType.TEXT_PLAIN)
- public String cwd(FTPClient client, @PathParam("pathname") String pathname)
+ public String deleteServer(@PathParam("server") String server)
{
- return CWD.execute(client, pathname);
+ return ServerCommands.delete(server) + "\n";
}
-
-
/**
- * Delete a file.
+ * Modify the host of a server of the platform.
*
- * @param client The FTP client.
- * @param pathname The pathname of a file.
+ * @param server The server.
+ * @param host The new host of the server.
*
* @return How the command went.
*/
- @GET
- @Path("dele:{pathname}")
+ @PATCH
+ @Path("{server}")
@Produces(MediaType.TEXT_PLAIN)
- public String dele(FTPClient client, @PathParam("pathname") String pathname)
+ public String modifyServer(@PathParam("server") String server, @HeaderParam("host") String host)
{
- return DELE.execute(client, pathname);
+ return ServerCommands.modify(server, host) + "\n";
}
-
+
/**
- * List the files of the working directory.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- @GET
- @Path("list")
+ * Create a directory on the FTP server.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param path The path of the file directory to create.
+ *
+ * @return How the command went.
+ */
+ @PUT
+ @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN)
- public String list(FTPClient client)
+ public String makeDir(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username, @HeaderParam("password") String password,
+ @PathParam ("path" ) String path )
{
- return LIST.execute(client);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.makeDir(client, path);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ return "The connection to the server failed.";
+
+ return response + "\n";
}
-
-
-
- /**
- * Login with a username and a password.
- *
- * @param client The FTP client.
- * @param username The username.
- * @param password The password.
- *
- * @return How the command went.
- */
- @GET
- @Path("login:{username}:{password}")
- @Produces(MediaType.TEXT_PLAIN)
- public String login(FTPClient client, @PathParam("username") String username, @PathParam("password") String password)
- {
- return LOGIN.execute(client, username, password);
- }
-
-
/**
- * Make a new directory.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the new directory.
- *
- * @return How the command went.
- */
- @GET
- @Path("mkd:{pathname}")
+ * Delete a file or directory on the FTP server.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param path The path of the file or directory to delete.
+ *
+ * @return How the command went.
+ */
+ @DELETE
+ @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN)
- public String mkd(FTPClient client, @PathParam("pathname") String pathname)
+ public String delete(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username, @HeaderParam("password") String password,
+ @PathParam ("path" ) String path )
{
- return MKD.execute(client, pathname);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.delete(client, path);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ return "The connection to the server failed.";
+
+ return response + "\n";
}
-
-
-
- /**
- * Enter in passive mode.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- @GET
- @Path("pasv")
- @Produces(MediaType.TEXT_PLAIN)
- public String pasv(FTPClient client)
+
+ /**
+ * Download a file.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param path The path of the file to download.
+ *
+ * @return How the command went.
+ */
+ @GET
+ @Path("{server}/{path:.*}/download")
+ @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
+ public String download(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username , @HeaderParam("password") String password,
+ @PathParam ("path" ) String path )
{
- return PASV.execute(client);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.download(client, path);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ response = "The connection to the server failed.";
+
+ return response + "\n";
}
-
-
-
- /**
- * Enter in active mode.
- *
- * @param client The FTP client.
- * @param activeConnection The active connection.
- *
- * @return How the command went.
- */
- @GET
- @Path("port")
+
+ /**
+ * List information about a file or files in a directory on the FTP server.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param path The path of the file or directory.
+ *
+ * @return Information about the file or files in the directory.
+ */
+ @GET
+ @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN)
- public String port(FTPClient client)
+ public String list(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username, @HeaderParam("password") String password,
+ @PathParam ("path" ) String path )
{
- return PORT.execute(client, activeConnection);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.list(client, path);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ response = "The connection to the server failed.";
+
+ return response;
}
-
-
/**
- * Print the working directory.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- @GET
- @Path("pwd")
+ * Rename a file or directory on the FTP server.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param from The path of the file or directory to rename.
+ * @param to The new name of the file or directory.
+ *
+ * @return How the command went.
+ */
+ @PATCH
+ @Path("{server}/{from}")
@Produces(MediaType.TEXT_PLAIN)
- public String pwd(FTPClient client)
+ public String rename(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username, @HeaderParam("password") String password,
+ @PathParam ("from" ) String from , @HeaderParam("to" ) String to )
{
- return PWD.execute(client);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.rename(client, from, to);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ response = "The connection to the server failed.";
+
+ return response + "\n";
}
-
-
-
- /**
- * Disconnect from the server.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- @GET
- @Path("quit")
- @Produces(MediaType.TEXT_PLAIN)
- public String quit()
- {
- return QUIT.execute(client);
- }
-
-
-
- /**
- * Retrieve a file.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the file to retrieve.
- *
- * @return How the command went.
- */
- @GET
- @Path("retr:{pathname}")
- @Produces(MediaType.TEXT_PLAIN)
- public String retr(FTPClient client, @PathParam("pathname") String pathname)
- {
- return RETR.execute(client, pathname);
- }
-
-
-
- /**
- * Rename a file.
- *
- * @param client The FTP client.
- * @param oldFilename The old filename.
- * @param newFilename The new filename.
- *
- * @return How the command went.
- */
- @GET
- @Path("rn:{oldFilename}:{newFilename}")
- @Produces(MediaType.TEXT_PLAIN)
- public String rn(FTPClient client, @PathParam("oldFilename") String oldFilename, @PathParam("newFilename") String newFilename)
+
+ /**
+ * Store a file or directory on the FTP server.
+ *
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ * @param from The input stream of the file or directory to upload.
+ * @param to The path where to store the input stream.
+ *
+ * @return How the command went.
+ */
+ @POST
+ @Path("{server}/{to:.*}/upload")
+ @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
+ public String upload(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
+ @HeaderParam("username") String username , @HeaderParam("password") String password,
+ @HeaderParam("from" ) String from , @PathParam ("to" ) String to )
{
- return RN.execute(client, oldFilename, newFilename);
+ FTPClient client = new FTPClient();
+
+ String response;
+
+ if(ClientUtil.connectAndLogin(client, server, port, username, password))
+ {
+ response = FtpCommands.upload(client, from, to);
+ ClientUtil.logoutAndDisconnect(client);
+ }
+ else
+ response = "The connection to the server failed.";
+
+ return response + "\n";
}
-
-
-
- /**
- * Store a file.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the file to store.
- *
- * @return How the command went.
- */
- @GET
- @Path("stor:{pathname}")
- @Produces(MediaType.TEXT_PLAIN)
- public String stor(FTPClient client, @PathParam("pathname") String pathname)
- {
- return STOR.execute(client, pathname);
- }
-
-
-
- /**
- * Set the type.
- *
- * @param client The FTP client.
- * @param type The position of the desired type in the string of types.
- *
- * @return How the command went.
- */
- @GET
- @Path("type:{type}")
- @Produces(MediaType.TEXT_PLAIN)
- public String type(FTPClient client, @PathParam("type") int type)
- {
- return TYPE.execute(client, type);
- }
}
diff --git a/src/main/java/flopbox/account/AccountUtil.java b/src/main/java/flopbox/account/AccountUtil.java
deleted file mode 100644
index ab1633fa5413789669c2bfc994feb3d67592c8cd..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/account/AccountUtil.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package flopbox.account;
-
-
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-
-
-public class AccountUtil
-{
- private static File accountsTxt = new File("accounts.txt");
- private static char separator = ' ';
-
- private static Map<String, String> accounts = new HashMap<String, String>();
-
-
-
- /**
- * Let the other classes to access in read the registered accounts.
- *
- * @return The pair username and password of the accounts.
- */
- public static Map<String, String> getAccounts()
- {
- return accounts;
- }
-
-
-
- /**
- * Load the unique usernames in the program.
- */
- public static void loadAccounts()
- {
- try
- {
- BufferedReader reader = new BufferedReader(new FileReader(accountsTxt));
-
- String line;
- while((line = reader.readLine()) != null)
- {
- int cut = line.indexOf(separator);
-
- String username = line.substring(0, cut);
-
- /* If a same username has already been put, we ignore it */
- if(accounts.containsKey(username))
- continue;
-
- String password = line.substring(cut+1);
-
- accounts.put(username, password);
- }
-
- reader.close();
- }
-
- catch(IOException e)
- {
- /* Do nothing */
- }
- }
-
-
-
- /**
- * Return if the password tried is the password of the account's username.
- *
- * @param username The username registered.
- * @param password The password tried.
- *
- * @return If the password tried is the password of the username's account.
- */
- public static boolean isTheRightPassword(String username, String password)
- {
- if(accounts.containsKey(username))
- return password.equals(accounts.get(username));
-
- else
- return username.equals("anonymous");
- }
-}
\ No newline at end of file
diff --git a/src/main/java/flopbox/client/ClientUtil.java b/src/main/java/flopbox/client/ClientUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..29f4795e09c0a1ec2663613eb0e033d2ca382583
--- /dev/null
+++ b/src/main/java/flopbox/client/ClientUtil.java
@@ -0,0 +1,69 @@
+package flopbox.client;
+
+import java.io.IOException;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPReply;
+
+import flopbox.command.ServerCommands;
+
+
+
+public class ClientUtil
+{
+ /**
+ * Connect and log in the FTP server.
+ *
+ * @param client The FTP client.
+ * @param server The FTP server to connect to.
+ * @param port The port of the FTP server to connect to.
+ * @param username The username of the account to use.
+ * @param password The password of the account to use.
+ *
+ * @return True if the client could connect and log in the FTP server, otherwise false.
+ */
+ public static boolean connectAndLogin(FTPClient client, String server, int port, String username, String password)
+ {
+ try
+ {
+ client.connect(ServerCommands.getServers().get(server), port);
+
+ if(FTPReply.isPositiveCompletion(client.getReplyCode()))
+ if(client.login(username, password))
+ return client.setFileType(FTPClient.BINARY_FILE_TYPE);
+
+ return false;
+ }
+
+ catch(IOException e)
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Log out and disconnect from the FTP server.
+ *
+ * @param client The FTP client.
+ *
+ * @return True if the client could log out and disconnect from the FTP server.
+ */
+ public static boolean logoutAndDisconnect(FTPClient client)
+ {
+ try
+ {
+ if(!client.logout())
+ return false;
+
+ client.disconnect();
+
+ return true;
+ }
+
+ catch(IOException e)
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/flopbox/command/CDUP.java b/src/main/java/flopbox/command/CDUP.java
deleted file mode 100644
index 828fd0f6dd5ff7223ec485cd72dd09c2d8fe016b..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/CDUP.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class CDUP
-{
- private static final String NAME = "CDUP";
-
-
-
- /**
- * Change to the parent directory.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client)
- {
- String response;
-
- try
- {
- if(client.changeToParentDirectory())
- response = "The working directory is now the parent directory.";
-
- else
- response = "The working directory could not be changed.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/CONNECT.java b/src/main/java/flopbox/command/CONNECT.java
deleted file mode 100644
index fd10f34e530fe47431d89333528ded2bc78770c9..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/CONNECT.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-import flopbox.Main;
-import flopbox.server.FtpServerUtil;
-
-public class CONNECT
-{
- private static final String NAME = "CONNECT";
-
-
-
- /**
- * Connect the client to a ftp server.
- *
- * @param client The FTP client.
- * @param address The address of the ftp server.
- * @param port The port of the ftp server.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String address, int port)
- {
- String response;
-
- try
- {
- if(client.isConnected())
- client.disconnect();
-
- if(!FtpServerUtil.isAddressValid(address))
- if(Main.getAliases().containsKey(address))
- address = Main.getAliases().get(address);
-
- if(!FtpServerUtil.isFtpServerPortValid(port))
- response = "The port is wrong.";
- else
- {
- client.connect(address, port);
- response = "Connected.";
- }
- }
-
- catch(UnknownHostException e)
- {
- response = "The address could not be resolved.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/CWD.java b/src/main/java/flopbox/command/CWD.java
deleted file mode 100644
index 80bc022591d2c43705b4c1f722f6d61f7eeb45f4..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/CWD.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class CWD
-{
- private static final String NAME = "CWD";
-
-
-
- /**
- * Change the working directory.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the next working directory.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String pathname)
- {
- String response;
-
- try
- {
- if(client.changeWorkingDirectory(pathname))
- response = "The working directory is : " + pathname;
-
- else
- response = "The working directory could not be changed.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/DELE.java b/src/main/java/flopbox/command/DELE.java
deleted file mode 100644
index 82f6f9b3dcbec3bcb483d359abf720b481c70d9c..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/DELE.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class DELE
-{
- private static final String NAME = "DELE";
-
-
-
- /**
- * Delete a file.
- *
- * @param client The FTP client.
- * @param pathname The pathname of a file.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String pathname)
- {
- String response;
-
- try
- {
- if(client.deleteFile(pathname))
- response = "The file \"" + pathname + "\" has been deleted.";
-
- else
- response = "The file \"" + pathname + "\" could not be deleted.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/FtpCommands.java b/src/main/java/flopbox/command/FtpCommands.java
new file mode 100644
index 0000000000000000000000000000000000000000..1905a6b2e105b3b04a4efcb854c308aa98a72216
--- /dev/null
+++ b/src/main/java/flopbox/command/FtpCommands.java
@@ -0,0 +1,233 @@
+package flopbox.command;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+
+
+
+public class FtpCommands
+{
+ /**
+ * Create a directory on the FTP server.
+ *
+ * @param client The FTP client.
+ * @param path The path of the directory to create.
+ *
+ * @return How the command went.
+ */
+ public static String makeDir(FTPClient client, String path)
+ {
+ String response;
+
+ try
+ {
+ if(client.makeDirectory(path))
+ response = "The directory \"" + path + "\" has been created.";
+ else
+ response = "The directory \"" + path + "\" could not be created.";
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+
+
+
+ /**
+ * Delete a file or directory on the FTP server.
+ *
+ * @param client The FTP client.
+ * @param path The path of the file or directory to delete.
+ *
+ * @return How the command went.
+ */
+ public static String delete(FTPClient client, String path)
+ {
+ String response;
+
+ try
+ {
+ if(client.deleteFile(path) || client.removeDirectory(path))
+ response = "\"" + path + "\" has been deleted.";
+ else
+ response = "\"" + path + "\" could not be deleted or does not exist.";
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+
+
+
+ /**
+ * Download a file.
+ *
+ * @param client The FTP client.
+ * @param path The path of the file to download
+ *
+ * @return How the command went.
+ */
+ public static String download(FTPClient client, String path)
+ {
+ String response;
+
+ try
+ {
+ client.enterLocalPassiveMode();
+
+ /* We take the filename and working directory from the full path */
+ String workingDirectory = path.substring(0, path.lastIndexOf("/"));
+ String filename = path.substring( path.lastIndexOf("/")+1);
+
+ /* We create the file and its data */
+ File file = new File("downloads/" + filename);
+ while(file.exists())
+ {
+ String name = filename.substring(0, filename.lastIndexOf("."));
+ String extension = filename.substring( filename.lastIndexOf("."));
+ file = new File("downloads/" + name + "_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + extension);
+ }
+ OutputStream fileOutputStream = new FileOutputStream(file);
+
+ /* We move to the working directory and retrieve the file */
+ if(client.changeWorkingDirectory(workingDirectory) && client.retrieveFile(filename, fileOutputStream))
+ response = "The download is a success.";
+ else
+ {
+ file.delete();
+ response = "The download failed.";
+ }
+
+ fileOutputStream.close();
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+
+
+
+ /**
+ * List information about a file or files in a directory on the FTP server.
+ *
+ * @param client The FTP client.
+ * @param path The path of the file or directory.
+ *
+ * @return Information about the file or files in the directory.
+ */
+ public static String list(FTPClient client, String path)
+ {
+ String response = "";
+
+ try
+ {
+ client.enterLocalPassiveMode();
+
+ FTPFile[] files = client.listFiles(path);
+
+ for(FTPFile file : files)
+ {
+ response += file.getRawListing();
+ response += "\n";
+ }
+
+ return response;
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+
+
+
+ /**
+ * Rename a file or directory on the FTP server.
+ *
+ * @param client The FTP client.
+ * @param from The path of the file or directory to rename.
+ * @param to The new name of the file or directory.
+ *
+ * @return How the command went.
+ */
+ public static String rename(FTPClient client, String from, String to)
+ {
+ String response;
+
+ try
+ {
+ if(client.rename(from, to))
+ response = "\"" + from + "\" has been renamed to \"" + to + "\".";
+ else
+ response = "\"" + from + "\" could not be renamed.";
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+
+
+
+ /**
+ * Store a file or directory on the FTP server.
+ *
+ * @param client The FTP client.
+ * @param from The input stream of the file or directory to upload.
+ * @param to The path where to store the input stream.
+ *
+ * @return How the command went.
+ */
+ public static String upload(FTPClient client, String from, String to)
+ {
+ String response;
+
+ try
+ {
+ InputStream fileInputStream = new FileInputStream(new File(from));
+
+ client.enterLocalPassiveMode();
+
+ if(client.storeFile(to, fileInputStream))
+ response = "The upload is a success.";
+ else
+ response = "The upload failed.";
+
+ fileInputStream.close();
+ }
+
+ catch(IOException e)
+ {
+ response = "An IO error occured while sending the command or receiving its result.";
+ }
+
+ return response;
+ }
+}
diff --git a/src/main/java/flopbox/command/LIST.java b/src/main/java/flopbox/command/LIST.java
deleted file mode 100644
index 38989be28c55e31d961eea7dd67b589daf94f2e6..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/LIST.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPFile;
-
-
-
-public class LIST
-{
- private static final String NAME = "LIST";
-
-
-
- /**
- * List the files of the working directory.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client)
- {
- String response = "";
-
- try
- {
- FTPFile[] files = client.listFiles();
-
- for(FTPFile file : files)
- {
- response += file.getName() + "\n";
- }
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/LOGIN.java b/src/main/java/flopbox/command/LOGIN.java
deleted file mode 100644
index 19ec2c2148a57cc2a495d99a102a550d880358b2..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/LOGIN.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package flopbox.command;
-
-
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class LOGIN
-{
- private static final String NAME = "LOGIN";
-
-
-
- /**
- * Login with a username and a password.
- *
- * @param client The FTP client.
- * @param username The username.
- * @param password The password.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String username, String password)
- {
- String response;
-
- try
- {
- if(client.login(username, password))
- {
- response = "The login has succeed.";
- }
-
- else
- response = "The login has not succeed.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/MKD.java b/src/main/java/flopbox/command/MKD.java
deleted file mode 100644
index c49643df2c98a4e74be297266b4871a0a3a54fb3..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/MKD.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class MKD
-{
- private static final String NAME = "MKD";
-
-
-
- /**
- * Make a new directory.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the new directory.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String pathname)
- {
- String response;
-
- try
- {
- if(client.makeDirectory(pathname))
- response = "The directory \"" + pathname + "\" has been created.";
-
- else
- response = "The directory \"" + pathname + "\" could not be created.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/PASV.java b/src/main/java/flopbox/command/PASV.java
deleted file mode 100644
index 54f96e8eb03d77ecac9a35595334585ca6b60337..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/PASV.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package flopbox.command;
-
-
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class PASV
-{
- /**
- * Enter in passive mode.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client)
- {
- String response;
-
- if(client.isConnected())
- {
- client.enterLocalPassiveMode();
- response = "The client entered in passive mode.";
- }
-
- else
- response = "The client could not enter in passive mode.";
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/PORT.java b/src/main/java/flopbox/command/PORT.java
deleted file mode 100644
index 404abb781a9513d4aced5e9271c9156a5c745314..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/PORT.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package flopbox.command;
-
-
-
-import java.io.IOException;
-import java.net.ServerSocket;
-
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPReply;
-
-
-
-public class PORT
-{
- private static final String NAME = "PORT";
-
-
-
- /**
- * Enter in active mode.
- *
- * @param client The FTP client.
- * @param activeConnection The active connection.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, ServerSocket activeConnection)
- {
- String response;
-
- try
- {
- if(client.isConnected())
- {
- activeConnection = new ServerSocket(0);
-
- int commandResponse = client.port(client.getRemoteAddress(), activeConnection.getLocalPort());
-
- if(FTPReply.isPositiveCompletion(commandResponse))
- response = "The client entered in active mode.";
-
- else
- response = "The client could not enter in active mode.";
- }
-
- else
- response = "The client could not enter in active mode.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/PWD.java b/src/main/java/flopbox/command/PWD.java
deleted file mode 100644
index 83a230a156fcdc129b9a91d85970978f4a64ddcd..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/PWD.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class PWD
-{
- private static final String NAME = "PWD";
-
-
-
- /**
- * Print the working directory.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client)
- {
- String response;
-
- try
- {
- response = client.printWorkingDirectory();
-
- if(response != null)
- response = "The working directory is : " + response;
-
- else
- response = "The working directory could not be printed.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/QUIT.java b/src/main/java/flopbox/command/QUIT.java
deleted file mode 100644
index 90cb9143cd42e675f402266f4571b855bb1aaf5b..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/QUIT.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPReply;
-
-
-
-public class QUIT
-{
- private static final String NAME = "QUIT";
-
-
-
- /**
- * Disconnect from the server.
- *
- * @param client The FTP client.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client)
- {
- String response;
-
- try
- {
- int commandResponse = client.quit();
-
- if(FTPReply.isPositiveCompletion(commandResponse))
- response = "Quit has succeed.";
-
- else
- response = "Quit has not succeed.";
-
- //client.disconnect(); in case the connection is kept alive by the client.
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/RETR.java b/src/main/java/flopbox/command/RETR.java
deleted file mode 100644
index 04c1f74cd8a43f1c5113f195c27260c36419bf32..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/RETR.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package flopbox.command;
-
-
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPReply;
-
-
-
-public class RETR
-{
- private static final String NAME = "RETR";
-
-
-
- /**
- * Retrieve a file.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the file to retrieve.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String pathname)
- {
- String response;
-
- try
- {
- int commandResponse = client.retr(pathname); /* should either place the file in /tmp or in the root of the project */
-
- if(FTPReply.isPositiveCompletion(commandResponse))
- response = "The file has been retrieved.";
-
- else
- response = "The file could not be retrieved.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/RN.java b/src/main/java/flopbox/command/RN.java
deleted file mode 100644
index 5735ebda163c0f8c150db1069e2ed941d64c534d..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/RN.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package flopbox.command;
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class RN
-{
- private static final String NAME = "RN";
-
-
-
- /**
- * Rename a file.
- *
- * @param client The FTP client.
- * @param oldFilename The old filename.
- * @param newFilename The new filename.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String oldFilename, String newFilename)
- {
- String response;
-
- try
- {
- if(client.rename(oldFilename, newFilename))
- response = "The file \"" + oldFilename + "\" has been renamed to \"" + newFilename + "\".";
-
- else
- response = "The file \"" + oldFilename + "\" could not be renamed.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/STOR.java b/src/main/java/flopbox/command/STOR.java
deleted file mode 100644
index 77e287328c98d9dbe2fdc15062e2dc6d3493c9fa..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/STOR.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package flopbox.command;
-
-
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPReply;
-
-
-
-public class STOR
-{
- private static final String NAME = "STOR";
-
-
-
- /**
- * Store a file.
- *
- * @param client The FTP client.
- * @param pathname The pathname of the file to store.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, String pathname)
- {
- String response;
-
- try
- {
- int commandResponse = client.stor(pathname);
-
- if(FTPReply.isPositiveCompletion(commandResponse))
- response = "The file has been stored.";
-
- else
- response = "The file could not be stored.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/command/ServerCommands.java b/src/main/java/flopbox/command/ServerCommands.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b6efcc7fd8384bbe4dcf738214da0325e81584a
--- /dev/null
+++ b/src/main/java/flopbox/command/ServerCommands.java
@@ -0,0 +1,90 @@
+package flopbox.command;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+public class ServerCommands
+{
+ /* Attributes */
+ private static Map<String,String> servers = new HashMap<String,String>();
+
+ /* Getters */
+ public static Map<String,String> getServers() { return servers; }
+
+
+
+ /**
+ * Print the registered servers and their hosts.
+ *
+ * @return the registered servers and their hosts.
+ */
+ public static String print()
+ {
+ String associations = "";
+
+ for(String server : servers.keySet())
+ {
+ associations += server + " -> " + servers.get(server);
+ associations += "\n";
+ }
+
+ return associations;
+ }
+
+
+
+ /**
+ * Register a server and its host in the platform.
+ *
+ * @param server The server.
+ * @param host The host of the server.
+ *
+ * @return How the command went.
+ */
+ public static String register(String server, String host)
+ {
+ if(servers.containsKey(server))
+ return "The server \"" + server + "\" is already registered.";
+
+ servers.put(server, host);
+
+ return "The association \"" + server + " -> " + host + "\" has been registered.";
+ }
+
+
+
+ /**
+ * Delete a registered server of the platform.
+ *
+ * @param server The server.
+ *
+ * @return How the command went.
+ */
+ public static String delete(String server)
+ {
+ if(servers.remove(server) == null)
+ return "The server \"" + server + "\" is not registered.";
+ else
+ return "The server \"" + server + "\" has been deleted.";
+ }
+
+
+
+ /**
+ * Modify the host of a server of the platform.
+ *
+ * @param server The server.
+ * @param host The new host of the server.
+ *
+ * @return How the command went.
+ */
+ public static String modify(String server, String host)
+ {
+ if(servers.replace(server, host) == null)
+ return "The server \"" + server + "\" is not registered.";
+ else
+ return "The server \"" + server + "\" is now associated with the host \"" + host + "\".";
+ }
+}
diff --git a/src/main/java/flopbox/command/TYPE.java b/src/main/java/flopbox/command/TYPE.java
deleted file mode 100644
index edb9c7601b7a7d763c64847e0ad80ff1ee677096..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/command/TYPE.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package flopbox.command;
-
-
-
-import java.io.IOException;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-
-
-public class TYPE
-{
- private static final String NAME = "TYPE";
-
-
-
- /**
- * Set the type.
- *
- * @param client The FTP client.
- * @param type The position of the desired type in the string of types.
- *
- * @return How the command went.
- */
- public static String execute(FTPClient client, int type)
- {
- String response;
-
- try
- {
- if(client.setFileType(type))
- response = "The type has been set.";
-
- else
- response = "The type could not be set.";
- }
-
- catch(IOException e)
- {
- response = "The command \"" + NAME + "\" failed.";
- }
-
- return response;
- }
-}
diff --git a/src/main/java/flopbox/server/AliasUtil.java b/src/main/java/flopbox/server/AliasUtil.java
deleted file mode 100644
index a2e234225095f446d6b3b9285f33092f71ce9b14..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/server/AliasUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package flopbox.server;
-
-
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Map;
-
-import flopbox.Main;
-
-
-
-public class AliasUtil
-{
- private static File aliasesTxt = new File("aliases.txt");
- private static char separator = ' ';
-
-
-
- /**
- * Load the unique aliases in the program.
- */
- public static void loadAliases()
- {
- Map<String, String> aliases = Main.getAliases();
-
- try
- {
- BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt));
-
- String line;
- while((line = reader.readLine()) != null)
- {
- int cut = line.indexOf(separator);
-
- String alias = line.substring(0, cut);
-
- /* If a same alias has already been put, we ignore it */
- if(aliases.containsKey(alias))
- continue;
-
- String server = line.substring(cut+1);
-
- aliases.put(alias, server);
- }
-
- reader.close();
- }
-
- catch(IOException e)
- {
- /* Do nothing */
- }
- }
-}
diff --git a/src/main/java/flopbox/server/FtpServerUtil.java b/src/main/java/flopbox/server/FtpServerUtil.java
deleted file mode 100644
index 897a7aa4b98e48ad205f1a5962563e792b65e8a2..0000000000000000000000000000000000000000
--- a/src/main/java/flopbox/server/FtpServerUtil.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package flopbox.server;
-
-
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-
-
-public class FtpServerUtil
-{
- /**
- * Tell if an address is resolvable.
- *
- * @param ftpServer The address.
- *
- * @return If an address is resolvable.
- */
- public static boolean isAddressValid(String ftpServer)
- {
- try
- {
- InetAddress.getByName(ftpServer);
- }
-
- catch(UnknownHostException e)
- {
- return false;
- }
-
- return true;
-
- }
-
-
-
- /**
- * Tell if a port is between 1 and 65535.
- *
- * @param port The port.
- *
- * @return If the port is between 1 and 65535.
- */
- public static boolean isFtpServerPortValid(int port)
- {
- if(Math.pow(2, 0) > port || port >= Math.pow(2, 16))
- return false;
-
- return true;
- }
-}
diff --git a/src/test/java/flopbox/MyResourceTest.java b/src/test/java/flopbox/MyResourceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f31f9fb92c03cbba575f2e26f9f5ab8b95a5124
--- /dev/null
+++ b/src/test/java/flopbox/MyResourceTest.java
@@ -0,0 +1,48 @@
+//package flopbox;
+//
+//import javax.ws.rs.client.Client;
+//import javax.ws.rs.client.ClientBuilder;
+//import javax.ws.rs.client.WebTarget;
+//
+//import org.glassfish.grizzly.http.server.HttpServer;
+//
+//import org.junit.After;
+//import org.junit.Before;
+//import org.junit.Test;
+//import static org.junit.Assert.assertEquals;
+//
+//public class MyResourceTest {
+//
+// private HttpServer server;
+// private WebTarget target;
+//
+// @Before
+// public void setUp() throws Exception {
+// // start the server
+// server = Main.startServer();
+// // create the client
+// Client c = ClientBuilder.newClient();
+//
+// // uncomment the following line if you want to enable
+// // support for JSON in the client (you also have to uncomment
+// // dependency on jersey-media-json module in pom.xml and Main.startServer())
+// // --
+// // c.configuration().enable(new org.glassfish.jersey.media.json.JsonJaxbFeature());
+//
+// target = c.target(Main.BASE_URI);
+// }
+//
+// @After
+// public void tearDown() throws Exception {
+// server.shutdownNow();
+// }
+//
+// /**
+// * Test to see that the message "Got it!" is sent in the response.
+// */
+//// @Test
+//// public void testGetIt() {
+//// String responseMsg = target.path("myresource").request().get(String.class);
+//// assertEquals("Got it!", responseMsg);
+//// }
+//}
diff --git a/testFiles/Explication_de_Lysithea_meme.txt b/testFiles/Explication_de_Lysithea_meme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2a641d2578a81f3a5c5774beb5e5b606664e9313
--- /dev/null
+++ b/testFiles/Explication_de_Lysithea_meme.txt
@@ -0,0 +1,25 @@
+Pour faire court, Lysithea est :
+
+- Le personnage le plus jeune de FE3H
+- Le mage le plus puissant du jeu
+- Le personnage qui évolue le plus vite du jeu
+
+Y'a un meme avec elle...
+Death Knight est un ennemi infâme super tanky et qui fait super mal
+L'attaquer c'est garantir la mort à son unité pour au final lui faire que du -5 sur 50pv
+
+Sauf que...
+Il existe une magie super efficace contre lui
+
+Et...
+Lysithea peut la débloquer
+Elle y a accès rapidement puisqu'elle évolue plus rapidement que les autres
+Elle gagne des stats plus rapidement et exactement là où il faut pour augmenter ses dégâts
+A tel point qu'au final elle peut le one-shot avec n'importe quel autre sort :x
+
+Du coup...
+Dès que Death Knight apparait sur le champ de bataille, on fait pop Lysi juste pour se débarasser de lui x)
+
+
+
+NB : Sérieusement, elle cogne vraiment fort
\ No newline at end of file
diff --git a/testFiles/Lysithea_meme01.jpg b/testFiles/Lysithea_meme01.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e62425c4c478ace0b978d93dd51d65e0767787bf
Binary files /dev/null and b/testFiles/Lysithea_meme01.jpg differ
diff --git a/testFiles/Lysithea_meme02.png b/testFiles/Lysithea_meme02.png
new file mode 100644
index 0000000000000000000000000000000000000000..2133aa100b93e18c3598a34de429b81d3ba62576
Binary files /dev/null and b/testFiles/Lysithea_meme02.png differ
diff --git a/testFiles/Lysithea_meme03.png b/testFiles/Lysithea_meme03.png
new file mode 100644
index 0000000000000000000000000000000000000000..20bb707edf6d2555d82608dd0fbd80fdfaaa73f5
Binary files /dev/null and b/testFiles/Lysithea_meme03.png differ