NFP121 - JFOD

NFP121
Programmation avancée.
Session de Février 2014-durée : 3 heures
Un corrigé
Tous documents papiers autorisés
Cnam / Paris-HTO & FOD/Nationale
Question1 : Patron MailBox
Question)
Ecrivez une implémentation complète de la classe MailBox. Certaines documentations d’interfaces et de classes
sont en annexe. Vous pouvez détacher la dernière page de cet énoncé, la joindre à votre copie en n'oubliant pas de
reporter le numéro de celle-ci.
public class MailBox implements IMailBox{
/** La file des messages collectés. */
private Map<String,List<LocalMessage>> map;
private class LocalMessage implements Serializable{
// classe interne, 'un wrapper',
// afin de conserver l'état du message (lu ou pas encore lu)
public boolean lu;
public IMessage msg;
public LocalMessage(IMessage msg){
this.msg = msg;
this.lu = false;
}
public IMessage getMsg(){return msg;}
public String toString(){
return "<" + msg + "," + lu + ">";
}
}
public MailBox(){
this.map = new HashMap<String,List<LocalMessage>>();
}
public IMailBox add(String dest) throws Exception{
List<LocalMessage> list = map.get(dest);
if(list!=null) throw new Exception(" déjà inscrit ou un homonyme en place ?");
list = new ArrayList<LocalMessage>();
map.put(dest, list);
return this;
}
public IMailBox post(IMessage message, String dest) throws Exception{
List<LocalMessage> list = map.get(dest);
if(list==null) throw new Exception(" le destinataire " + dest + " est inconnu, pas encore inscrit
?");
list.add(new LocalMessage(message));
map.put(dest, list);
return this;
}
public IMailBox post(IMessage message, String[] destinataires) throws Exception{
String inconnus = new String();
NFP121-examen-février-2014-un-corrigé
1/5
for(String dest : destinataires){
try{
post(message,dest);
}catch(Exception e){
inconnus = inconnus + dest + " ";
}
}
if(inconnus.length()>0) throw new Exception(inconnus);
return this;
}
public List<IMessage> load(String dest) throws Exception{
if(map.get(dest)==null) throw new Exception(" le destinataire " + dest + " est inconnu, pas encore
inscrit ?");
List<IMessage> list = new ArrayList<IMessage>();
for(LocalMessage m : map.get(dest)){
if(!m.lu){
m.lu = true;
list.add(m.getMsg());
}
}
return list;
}
public Iterator<String> iterator(){
return new TreeSet(map.keySet()).iterator();
}
public List<IMessage> getAllMessages(String dest) throws Exception{
if(map.get(dest)==null) throw new Exception(" le destinataire " + dest + " est inconnu, pas encore
inscrit ?");
List<IMessage> list = new ArrayList<IMessage>();
for(LocalMessage m : map.get(dest)){
list.add(m.getMsg());
}
return list;
}
public List<IMessage> getReadMessages(String dest) throws Exception{
if(map.get(dest)==null) throw new Exception(" le destinataire " + dest + " est inconnu, pas encore
inscrit ?");
List<IMessage> list = new ArrayList<IMessage>();
for(LocalMessage m : map.get(dest)){
if(m.lu)list.add(m.getMsg());
}
return list;
}
public String toString(){
StringBuilder sb = new StringBuilder();
for(String dest : this){
sb.append(dest);
sb.append(map.get(dest));
sb.append("\n");
}
return sb.toString();
}
}
Question2 : Patron Observateur
Question)
Ecrivez une implémentation complète de la classe MailBoxNotification. Certaines documentations d’interfaces
et de classes sont en annexe.
public class MailBoxNotification extends MailBox implements IMailBoxNotification{
private Map<String,List<MailBoxListener>> map;
NFP121-examen-février-2014-un-corrigé
2/5
public MailBoxNotification(){
map = new HashMap<String,List<MailBoxListener>>();
}
private boolean contains(String destinataire){
for(String dest : this){
if(dest.equals(destinataire)) return true;
}
return false;
}
public void addMailBoxListener(String destinataire, MailBoxListener listener) throws Exception{
if(!contains(destinataire)) throw new Exception(destinataire + " inconnu...");
List<MailBoxListener> list = map.get(destinataire);
if(list==null){
list = new ArrayList<MailBoxListener>();
}
list.add(listener);
map.put(destinataire,list);
}
@Override
public IMailBoxNotification post(IMessage message, String destinataire) throws Exception{
try{
super.post(message,destinataire);
for(MailBoxListener listener : map.get(destinataire)){
try{
listener.onMessage(message);
}catch(Exception e){
}
}
}catch(Exception e){
throw e;
}
return this;
}
@Override
public IMailBoxNotification post(IMessage message, String[] destinataires) throws Exception{
for(String dest : destinataires){
try{
post(message, dest);
}catch(Exception e){
}
}
return this;
}
Question3 : Persistance
Question 3.1) Ecrivez complètement la classe SerializationMode
public class SerializationMode extends PersistentMode{
public void writeMailBox(MailBox mb, String fileName) throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(fileName));
Map<String,List<IMessage>> map = new HashMap<String,List<IMessage>>();
for(String dest : mb){
List<IMessage> messages = mb.getAllMessages(dest);
messages.removeAll(mb.getReadMessages(dest));
map.put(dest, new ArrayList<IMessage>(messages));
}
oos.writeObject(map);
oos.close();
}
NFP121-examen-février-2014-un-corrigé
3/5
public MailBox readMailBox(String fileName) throws Exception{
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(fileName));
Map<String,List<IMessage>> map = (Map<String,List<IMessage>>)ois.readObject();
MailBox mb = new MailBox();
for(String dest : map.keySet()){
try{
mb.add(dest);
}catch(Exception e){}
for(IMessage msg : map.get(dest)){
mb.post(msg, dest);
}
}
ois.close();
return mb;
}
}
Question 3.2) Ecrivez uniquement la méthode de restitution d'une boîte aux lettres, en complétant la classe
XMLMode ci-dessous:
public class XMLMode extends PersistentMode{
public void writeMailBox(IMailBox mb, String fileName) throws Exception{
// est fournie, n'est pas demandée à cette question
}
public MailBox readMailBox(String fileName) throws Exception{
MailBox mb = new MailBox();
this.parse(mb, fileName);
return mb;
}
private void parse(final IMailBox mb, String fileName) throws SAXException, IOException{
XMLReader saxReader = XMLReaderFactory.createXMLReader();
saxReader.setContentHandler(new DefaultHandler(){
String destinataire;
public void startElement(String uri, String name, String qualif, Attributes at) throws
SAXException{
if(name.equals("destinataire")){
for( int i = 0; i < at.getLength(); i++ ){
if(at.getLocalName(i).equals("nom"))
try{
mb.add(at.getValue(i));
destinataire = at.getValue(i);
}catch(Exception e){}
}
}else if (name.equals("message")){
String className_msg = null; String className_content = null;
String content = null; String source = null;
boolean read = false;
for( int i = 0; i < at.getLength(); i++ ){
if(at.getLocalName(i).equals("class_msg"))
className_msg = at.getValue(i);
else if(at.getLocalName(i).equals("content"))
content = at.getValue(i);
else if(at.getLocalName(i).equals("class_content"))
className_content = at.getValue(i);
else if(at.getLocalName(i).equals("source"))
source = at.getValue(i);
}
// création d'une instance de la classe puis post
if(className_msg != null){ // la balise message a été rencontrée
// alors introspection
try{
Class<?> class_msg = Class.forName(className_msg);
Constructor<?> cons_msg = class_msg.getConstructor(String.class);
NFP121-examen-février-2014-un-corrigé
4/5
IMessage msg = (IMessage)cons_msg.newInstance(source);
Class<?> class_content = Class.forName(className_content);
Constructor<?> cons_content = class_content.getConstructor(String.class);
// cf. énoncé, uniquement des String pour content
String c = (String)cons_content.newInstance(content);
msg.setContent(content);
mb.post(msg, destinataire);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
});
saxReader.parse(fileName);
}
Question4: Une interface graphique
this.envoi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
StringMessage sm = new StringMessage("IHM");
sm.setContent(message.getText());
try{
mb.add(destinataire.getText());
}catch(Exception e){}
try{
mb.post(sm,destinataire.getText());
persistent.writeMailBox(mb,"mailbox_temp.xml");
mb = persistent.readMailBox("mailbox_temp.xml");
resultat.setText(readFile("mailbox_temp.xml"));
}catch(Exception e){
resultat.setText(e.getMessage());
}
IHM.this.pack();
}
});
this.relève.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
List<IMessage> list = null;
try{
list = mb.load(destinataire.getText());
persistent.writeMailBox(mb,"mailbox_temp.xml");
mb = persistent.readMailBox("mailbox_temp.xml");
resultat.setText(list.toString() + "\n" + readFile("mailbox_temp.xml"));
}catch(Exception e){
resultat.setText(e.getMessage());
}
IHM.this.pack();
}
NFP121-examen-février-2014-un-corrigé
5/5