Troisième étape : Réseau d`échange de fichiers musicaux

publicité
IFT785 – Approches Orientées Objets
FINAL – Hiver 2006
Début : Vendredi 21 avril 2006 à 12h00 midi
GIROUX
Remise : Lundi 24 avril 2006 à 12h00 midi
Professeur : Sylvain
Note :…/100 points
Remarques :
 Les énoncés sont flous à dessein. Il y aura plusieurs alternatives possibles. Vous aurez
donc plusieurs décisions de design à prendre. N’hésitez pas à les prendre.

L’examen est secret. Vous ne devez pas en dévoiler le contenu avant la fin de la seconde
session d’examen afin de s’assurer que le processus reste équitable pour tous.

L’examen est individuel.

Vous pouvez en tout temps demander des clarifications sur les questions, par contre
aucune explication ne sera donnée sur la matière en tant que telle.

Vous aurez besoin de programmer en Java. Pour ce faire, vous pouvez utiliser Eclipse ou
tout autre environnement de développement.

Vous devez utiliser JUnit pour écrire des tests. Je m’attends à ce que des tests (pas
nécessairement exhaustifs) soient écrit pour toutes les questions.

Vous devez remettre vos réponses par e-mail avant 12h00 (midi) le 24 avril.

Vous devrez remettre par e-mail [email protected]
1. un fichier jar contenant les programmes que vous aurez développés
2. un document texte contenant
a. vos réponses aux questions théoriques
b. pour la partie pratique, les noms des patrons de conceptions que vous avez
utilisés.
PARTIE THEORIQUE (30 points)
ObjVlisp : Métaclasses, classes et instances terminales
Question 1
Expliquer l’affirmation suivante :
En ObjVlisp, la différence entre instance terminale, classe et méta-classes en est une de
comportement et non de nature.
Utiliser des schémas et un exemple pour appuyer votre argumentation.
Question 2
a) Ecrire les classes et méta-classes nécessaires pour permettre à une instance ou une classe
d’avoir des variables indexées. Une variable indexée est une variable qui est accédée à
l’aide d’un indice. Le nombre de variables indexée sera fixé à la création de l’instance.
Les indices seront numérotés à partir de 1.
b) Implémenter la classe Fifa dont les instances possèdent 11 variables indexées pour
représenter les 11 joueurs sur le terrain. La classe Fifa possède elle-même 17 variables
indexées qui représentent les 17 règles. Ainsi nous pourrons écrire
(send ??? ‘new :name ‘EquipeDeFootball:supers ’( ??? ))
(send Fifa ‘?← 1 ‘(Loi 1 : Terrain de jeu….))
(send Fifa ‘?← 2 ‘(Loi 2 : Ballon ….))
(setq Italie (send EquipeDeFootball ‘new))
(send Italie ‘? 10)
Si vous ne connaissez pas Lisp, vous pouvez utiliser du pseudo-code et/ou des figures pour
décrire votre réponse.
Rappels :
 l’accès à la valeur d’une variable d’instance se fait via la méthode « ? » définie dans la
classe Object.
 l’accès à la valeur d’une variable d’instance se fait via la méthode « ?← » définie dans la
classe Object. Il faudra redéfinir cette méthode.
 En ObjVlisp, l’héritage multiple est permis.
PARTIE PRATIQUE (70 points)
Étude de cas : Du multimédia partagé…
Vous avez été engagé par XULIN pour faire un système d’échange P2P (peer-to-peer) de
contenu multimédia. Ce système comporte les éléments suivants :


Une place centrale Agora où les agents se connectent
Pour chaque nœud participant, un agent MultimediaP2P qui sert de point d’entrée au
nœud. Cet agent gère trois sous-agents :
o AgentDeRecherche
o AgentPlayerMultimedia
o AgentRepertoire
Joindre, quitter,
trouver les pairs
Joindre, quitter,
trouver les pairs
AGORA
MultimediaP2P
AgentDeRecherche
MultimediaP2P
Rechercher
Echanger
AgentDeRecherche
AgentRépertoire
AgentRépertoire
AgentPlayerMultimedia
AgentPlayerMultimedia
Première étape : Ecouter du multimédia
Question 1 : Refactorisation et poly morphisme
Comme première étape, vous devez construire un agent capable d’utiliser le « player » approprié
(vidéo, MP3, WAV, etc.) pour la plateforme où il s’exécute (Apple, Windows, etc.). Cet agent
est capable de contrôler le nombre d’utilisation du contenu. Les contenus multimédias sont soit
vendus ou gratuits (nombre illimité d’utilisation), soit loué pour un certain nombre d’utilisation.
Une utilisation correspond soit à une écoute complète (i.e. la fonction « stop » du lecteur a été
invoquée), soit à une écoute incomplète non reprise, i.e. l’utilisateur a appuyé sur la fonction
« pause » et n’a jamais repris l’écoute). Ainsi la séquence PLAY, PAUSE, RESUME, PAUSE
correspond à une utilisation.
Refactoriser le programme suivant de manière à faire disparaître, autant que faire se peut, les
conditionnelles qu’il contient en les remplaçant par du polymorphisme.
Avant de commencer la refactorisation, écrire au moins 10 tests unitaires pour s’assurer que le
comportement du programme sera préservé. Il se peut que à la suite des autres questions, vous
ayez à modifier et adapter vos tests.
public class AgentPlayerMultiMedia {
final static private int VIDEO = 0;
final static private int MUSIQUE = 1;
final
final
final
final
final
static
static
static
static
static
private
private
private
private
private
private
private
private
private
int
int
int
int
int
CREATED = 0;
STARTED = 1;
PAUSED = 2;
RESUMED = 3;
STOPPED = 4;
int etat_;
int maximum_;
boolean location_;
Object contents_;
private int type_;
private int joue_;
private String titre_;
private MediaPlayer player_;
public AgentPlayerMultiMedia( boolean location, int nbFois,
int type, String titre,
Object contents) {
location_ = location;
maximum_ = nbFois;
titre_ = titre;
contents_ = contents;
joue_ = 0;
etat_ = CREATED;
}
public void start() {
if (etat_ != CREATED) { return; // on commence à jouer le contenu
}
if (location_ && joue_ < maximum_) { return;
}
if (type_ == MUSIQUE) { player_ = new iTunes();
player_.play(this);
etat_ = STARTED;
}
if (type_ == VIDEO) { player_ = new QuickTime();
player_.play(this);
etat_ = STARTED;
}
}
public void pause() {
//le contenu doit jouer pour que cette opération soit valide
if (etat_ == PAUSED) { return;
}
if (etat_ == STOPPED_) { return;
}
if (type_ == MUSIQUE) { player_.pause(this);
if (location_) { joue_ = joue_ + 1; }
etat_ = PAUSED;
}
if (type_ == VIDEO) { player_.pause(this);
if (location_) { joue_ = joue_ + 1; }
etat_ = PAUSED;
}
}
public
//
if
}
if
}
if
void resume() {
cette opération n’est valide qu’après une pause
(etat_ != PAUSED) { return;
(location_) { { joue_ = joue_ - 1; }
(type_ == MUSIQUE) {
}
if (type_ == VIDEO) {
}
player_.play(this);
etat_ = RESUMED;
player_.play(this);
}
public void stop() {
//le contenu doit jouer pour que cette opération soit valide
if (etat_ == PAUSED) { return;
}
if (etat_ == STOPPED) { return;
}
if (type_ == MUSIQUE) { player_.close(this);
if (location_) { joue_ = joue_ + 1; }
}
if (type_ == VIDEO) {
player_.close(this);
if (location_) { joue_ = joue_ + 1; }
}
}
}
Question 2 : Multi-plateforme
Actuellement le système ne fonctionne que pour MAC OS X (les players utilisés sont itunes et
Quicktime). Modifier ce programme pour le faire fonctionner sur de nouveaux systèmes
d’exploitation. Par exemple sous Windows, les lecteurs audio et vidéo seraient alors « Windows
Media Player »
En Java, les propriétés du système permettent d’avoir de l’information sur le système
d’exploitation utilisé.
System.getProperty("os.name")
http://java.sun.com/docs/books/tutorial/essential/system/properties.html
Remarque : Vous n’avez pas à utiliser ou exécuter les « players » réels.
Question 3 : Suivi de la lecture du document Multimedia
Vous disposez d’une classe Afficheur ci-dessous qui permet de suivre sur la console
l’exécution des contenus multimédia.

Complétez la classe Afficheur pour qu’elle implémente un Singleton.

Modifiez le programme pour faire en sorte que l’agent AgentPlayerMultimedia informe
l’afficheur de son changement d’état. Mis à part les modifications pour implémenter le
singleton, vous NE devez PAS modifier la classe Afficheur pour implémenter cette
fonctionnalité.
public class Afficheur {
static public Afficheur getAfficheur() {…}
//Singleton
public void display(String titre, String etat)
System.out.println(titre + " >>> " + etat);
}
{
}

Modifiez maintenant la classe Afficheur pour qu’elle s’affiche sur une autre sortie
par exemple un fichier de Log.
Question 4 : Ajout d’un nouveau type de média
Un nouveau type de média « 3Dmov » a été développé. Il s’agit de vidéo 3D ayant comme
particularité de permettre de modifier le point de vue du spectateur. Lorsque le film joue (état
STARTED ou RESUMED, on peut passer en mode « GLOBAL_SCENE ». Lorsque l’on est
en mode « GLOBAL_SCENE », la seule opération valide est « resume ». Le mode
« GLOBAL_SCENE » n’est valide que pour ce type de média. Modifiez le programme en
conséquence.
Deuxième étape : Recherches de fichiers multimédia
A l’étape suivante, vous devrez implémenter un agent AgentRecherche qui reçoit des
requêtes et qui interroge les agents répertoires des sites participants au réseau. Pour le moment, il
s’agit de construire la partie qui permettra d’effectuer les requêtes.
Question 5 : Spécification d’une requête
Une requête simple correspond à un prédicat spécifiant l’auteur, le titre ou le statut (gratuit,
location, vente). Une requête complexe correspond à des conjonctions / des disjonctions de
prédicats. Par exemple, pour avoir toutes les chansons gratuites de Eminem, la requête serait


mm.getAuteur() == « Eminem » AND mm.isGratuit()
mm étant ici une instance de Multimedia (voir plus bas)
Implémenter un système permettant de construire et exécuter des requêtes simples et complexes.
On devra pouvoir ajouter ultérieurement (mais vous n’avez pas à le faire pour l’examen) des
nouveaux prédicats, par exemple « catégorie » et de nouveaux opérateurs logiques, par exemple
NOT.
Remarque :
 une requête complexe peut être représenté par un arbre.
 Vous disposez des interfaces suivantes
public interface Multimedia {
String getTitre();
String getAuteur();
boolean isGratuit();
boolean isLocation();
boolean isAchat();
String getProprietaire();
}
public interface Predicat {
Multimedia searchTitre(String unTitre);
Vector searchAuteur(String unTitre);
Vector searchGratuit();
Vector searchLocation();
Vector searchAchat();
Vector searchProprietaire(Vector owners);
}
Troisième étape : Réseau d’échange de fichiers musicaux
Question 6 : Réseau d’échanges P2P
Dans cette section, vous devez implémenter un réseau d’échanges P2P de fichiers musicaux.
Chaque participant MultimediaP2P possédera trois agents internes: AgentDeRecherche,
AgentRepertoire, AgentPlayerMultimedia.
Un registre central unique des agents participants Agora maintiendra à jour la liste des
participants. Le registre central assume les fonctions suivantes :
 fournir la liste de tous les participants sur demande
 informer les participants de la connexion d’un nouveau participant
 informer les participants de la déconnexion d’un participant
Les fonctionnalités d’un participant MultimediaP2P sont
 A sa création,
o il crée ses trois agents internes
o il se connecter au réseau d’échange
 Pendant sa vie active,
o il donne accès à l’agent interne approprié pour faire des recherches, répondre aux
requêtes, jouer des contenus multimédias.
o imposer un veto sur l’échange de certains documents multimédias, par exemple si
le demandeur fait partie d’une liste noire.
 A sa destruction,
o il se déconnecte du réseau d’échange
o il arrête ses agents internes
Les fonctionnalités d’un agent AgentRepertoire sont
 Répondre aux requêtes des autres participants
 Gérer la liste des documents multimédia
 Échanger des fichiers multimédia.
o Un document qui est en train de jouer ne peut pas être échangé
o Lorsque le fichier est gratuit, il en transmet une copie au demandeur.
o Lorsque le fichier est loué ou acheté, il transmet le fichier au demandeur et efface
le fichier de son répertoire
 Supprimer un document loué dont le nombre d’écoute permise a été utilisé.
Les fonctionnalités d’un agent AgentDeRecherche sont
 effectuer des recherches de documents multimédia chez les autres participants
 obtenir les fichiers multimédia rendus par la recherche,
o Si le fichier existe sur plusieurs sites, il ne faut en obtenir qu’un seul exemplaire.
Téléchargement