f.pfister

Aller au contenu | Aller au menu | Aller à la recherche

lundi 29 novembre 2004

Corrigé du jeu d'échecs

TestEchec.java

Corrigé du TP Java: Parking

Le source est accessible ici:parking.zip

jeudi 25 novembre 2004

Corrigé du cas d'utilisation "Exploitant du site"

Le corrigé du cas d'utilisation "Cas de l'exploitant du site" est disponible ici:
petshopcorrige041201.zip Ce corrigé est partiel: On affiche la liste des clients, et, pour un client de cette liste, la liste de ses achats.

Ce fichier peut être dézippé et installé dans le répertoire www. Il crée une base de données nommée petshop01corr.

La phase d'identification n'est pas traitée.

jeudi 18 novembre 2004

Démarrage du projet Petshop

Les tâches à réaliser pour commencer:

Pour chaque cas d'utilisation (ce qui correspond chez nous à un profil de connexion) Réaliser une maquette statique des vues. Définir la navigation dans ces vues.

Tâches générales:

Normaliser la base de données

ici, un squelette pour démarrer http://f.pfister.free.fr/blog/docs/prj_petshop.zip

mercredi 10 novembre 2004

Sybase offre sa base de données

en version Linux... Il y avait déjà une version développeur disponible gratuitement, mais cette version était limitée à 5 connexions simultanées, ce qui la rendait impraticable (sauf pour un développeur isolé).

La version Express Edition peut être utilisée en exploitation, elle a cependant quelques limitations: « Avec ASE Express Edition, l'entreprise peut basculer en production à condition de ne pas dépasser la limite de 5 Go de données, 2 Go de RAM et un seul processeur. Le SGBD n'est pas bridé : la version Express est identique au produit payant » , souligne Éric Foucault, ingénieur avant-vente chez Sybase.

Rappellons que ce produit est du niveau de MS SQL Server (Ils sont tous deux un fork du SGBD Watcom).

Il supporte, entre autres fonctionnalités, les transactions, les triggers, les procédures stockées, la réplication asynchrone bi-directionnelle.

Le but est évidemment de se positionner face à Mysql et autres SAP-DB, ainsi que Microsoft SQL Server 2005 Express Edition, lui aussi gratuit et limité à un processeur.




http://www.sybase.com/linuxpromo

vendredi 5 novembre 2004

Petshop

Réalisation d'un site de vente en ligne

cahier des charges
script de création la base de données

N'hésitez pas à poster des commentaires ou des questions...

Quatre acteurs sont concernés:

  • Le client final du site (le consommateur)
  • L'exploitant du site (gestion commerciale)
  • L'administrateur du site (maintenance de la base de données, extraction de statistiques)
  • Le service de validation des transactions bancaires (acteur non humain)

Il s'agir de gérer un site de vente en ligne d'animaux de compagnie. Le modèle du site est celui du caddie virtuel.

Cas du client final:

Dès qu'un visiteur se présente sur le site, il peut ajouter des articles dans son caddie virtuel.



A tout moment, il peut en visualiser le contenu, supprimer des articles, en modifier les quantités. Le total est recalculé et affiché. Il peut aussi décider de conclure sa transaction. Il saisit alors ses coordonnées (nom, prénom, adresse personnelle, adresse de livraison, adresse de facturation, ainsi que les informations relatives à sa carte bancaire).

Après autorisation délivrée par l'organisme de carte bancaire, la transaction est confirmée et terminée.

L'internaute peut également se connecter au site en donnant son nom de login et son mot de passe s'il est déjà un client enregistré du site. Il peut notamment consulter sa dernière commande.

S'il se déconnecte sans avoir finalisé sa transaction, le contenu de son caddie est perdu.

Il est nécessaire de gérer des erreurs telles que les quantités négatives ou aberrantes (pas plus de dix boas par commande). Il faut vérifier la cohérence du numéro de la carte bancaire.

Cas de l'exploitant du site:

L'exploitant désire se connecter sur le site afin de consulter les statistiques de ventes mensuelles ainsi que le chiffre d'affaires et la marge brute journaliers. Il veut pouvoir consulter le niveau du stock. Il peut enfin consulter la liste des clients et le montant de leurs achats mois par mois.

Cas de l'administrateur du site:

Il assure la maintenance des tables de référence. Il peut aussi connaître le nombre d'accès au site par page visitée. Tous les acteurs, hormis le client final, doivent s'identifier avant d'accéder au site.

Spécificités du catalogue:

Chaque article appartient à un produit, et chaque produit à une catégorie.



Exemple de catégories: chien, chat.

Exemple de produits: dogue, labrador, chihuahua, chat persan, chat angora.

Exemple d'article: dogue noir adulte 80 kg, ou chaton blanc uni de 6 mois.

Une icône de menu graphique est associée à chaque catégorie (par exemple Chiens.gif) ainsi qu'une image illustrative à chaque produit.

L'article possède quatre lignes de description dont une est obligatoire. (voir modèle fourni)

Contraintes non fonctionnelles:

Implémenter en Php Mysql, en utilisant une architecture MVC. Utiliser le schéma de base de données, ainsi que le jeu de données fourni.

Exceptions en java

à partir du corrigé de l'exercice Agence Immobilière, faire l'exercice ci-dessous:

source ici

1) Fixer les constantes MAX_BIENS MAX_CLIENTS attributs d'Agence à 2 afin de mettre en évidence l'erreur qui se produit en cas de dépassement de capacité d'un tableau:

class Agence {
  public static final int MAX_BIENS = 2;
  public static final int MAX_CLIENTS = 2;
etc ....

  BienImmo ajouteBien(BienImmo m) throws ExceptionDepassement {
    if (nbBiens < MAX_BIENS) {
      stocknbBiens++ = m;
    }
    else {
      throw new ExceptionDepassement(nbBiens, m);
    }
    return m;
  }


Que se passerait-il si on ne gérait pas cette erreur avec la classe ExceptionDepassement ?

Tester cette situation.
en supprimant la gestion de l'erreur:

 BienImmo ajouteBien(BienImmo m) {
     stocknbBiens++ = m;
     return m;
 }

2) Fixer maintenant les tailles de tableaux à une valeur supérieure:

class Agence {
  public static final int MAX_BIENS = 20;
  public static final int MAX_CLIENTS = 20;
Mettre hors-service (entre commentaires) la capture des Exceptions génériques dans la fonction main:
   
 /*
    catch (Exception e) {
      System.out.println(e.getMessage());
    }
 */


Ecrire une méthode getPrixAuMetre() qui calcule le prix au mètre-carré d'un bien immobilier et l'appeller dans la fonction main.

System.out.println("prix au mètre carré pour "+b1.getDenomination()+":"+b1.getPrixAuMetre()+" Euros");
System.out.print("prix au mètre carré pour "+b2.getDenomination()+":"+b2.getPrixAuMetre()+" Euros");

Dans quelle condition cette méthode peut-elle provoquer une erreur ?

Expérimenter cette hypothèse:

Affectez une surface nulle au bien b2:

  BienImmo b2 = fnaim.ajouteBien(new Usine("usine récente",
                                               "agro-alimentaire", 10000000,
                                               0,
                                               BienImmo.MODE_VENTE,
                                               "atelier;entrepots", 1000));


Pourquoi l'exception attendue n'est-elle pas levée dans le cas où prix et durface sont des types double?

Modifier la classe BienImmo pour que les attributs prix et surface ne soient plus des types double mais des types int.

Refaire l'expérimentation de la condition d'erreur.

Remplacer l'exception originelle par une nouvelle classe d'exception métier:

class ExceptionZero
    extends Exception {
  public BienImmo enErreur;
  ExceptionZero(String msg, BienImmo enErreur) {
    super("erreur zéro:" + msg + " ! ");
    this.enErreur=enErreur;
  }
}


Capturer cette exception au niveau de la fonction main. Que se passe-t-il lorsque l'exception est levée ?

Est il légitime dans ce cas précis d'interrompre brutalement l'exécution du programme à cause d'une valeur erronnée dans un objet ?

Gérer cette exception de façon à poursuivre le programme malgré l'erreur.

3) Ecrire un méthode valider() pour BienImmo.

Pour une Maison, cette méthode vérifie qu'il y a au moins une salle de bains pour 4 pièces.

Pour une Usine, cette méthode vérifie qu'il y a au moins 1 KWh de puissance électrique installée pour 10 m2 de surface.

Cette méthode sera appelée par une méthode de la classe Agence (sur demande de la fonction main() bien entendu).

Deux stratégies peuvent être mises en oeuvre:

a) retourner une valeur fausse si la condition n'est pas vérifiée.

b) lever une exception métier:

class ExceptionValidationMetier
    extends Exception {
  ExceptionValidationMetier(String msg) {
    super("erreur Validation métier:" + msg + "!");
  }
}


Implémenter chacune de ces stratégies, et dans le cas de l'exception, la capturer de manière pertinente.

/////////////////////////// corrigé de l'exercice précédent ////////////////////

package agence;

////////////////////////////////////////////////////////////////////////////////

class ExceptionZero
    extends Exception {
  public BienImmo enErreur;
  ExceptionZero(String msg, BienImmo enErreur) {
    super("erreur Zero:" + msg + "!");
    this.enErreur = enErreur;
  }
}

class ExceptionValidationMetier
    extends Exception {
  ExceptionValidationMetier(String msg) {
    super("erreur Validation métier:" + msg + "!");
  }
}

class ExceptionDepassement
    extends Exception {
  ExceptionDepassement(int indice, Object m) {
    super("erreur ajout de \n" + m.toString() + "impossible  à l'indice:" +
          indice + "!");
  }
}

////////////////////////////////////////////////////////////////////////////////

class Client {
  private String nom;
  private boolean particulier; //personne morale ou physique
  private String adresse;
  private String commune;

  public Client(String nom, String adresse, String commune) {
    this.nom = nom;
    this.adresse = adresse;
    this.commune = commune;
  }

  public String toString() {
    return " nom:" + nom + (particulier ? "(particulier)" : "(personne morale)") +
        "; adresse:" + adresse + "; commune:" + commune + "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////

class BienImmo {
  public static final int MODE_LOCATION = 1;
  public static final int MODE_VENTE = 2;
  public static final int MODE_LOCATION_VENTE = 3;
  private String denomination;
  private String nature; //appartement, entrepot, atelier, villa
  private int prix;
  private int surface;
  private int mode; //1= location; 2=vente; 3=location-vente
  private Client proprietaire;
  private Client acquereur;

  public BienImmo() {
  }

  public BienImmo(String denomination, String nature, int prix,
                  int surface, int mode) {
    this.denomination = denomination;
    this.nature = nature;
    this.prix = prix;
    this.surface = surface;
    this.mode = mode;
  }

  public String getDenomination() {
    return denomination;
  }



  public void setProprietaire(Client p) {
    proprietaire = p;
  }

  public void setAcquereur(Client p) {
    acquereur = p;
  }

  public String toString() {
    String mod = "";
    switch (mode) {
      case MODE_LOCATION:
        mod = "location";
        break;
      case MODE_VENTE:
        mod = "vente";
        break;
      case MODE_LOCATION_VENTE:
        mod = "location vente";
        break;
    }
    String prop = "pas de proprio";
    String acq = "pas d'acquéreur";
    if (proprietaire != null) {
      prop = proprietaire.toString();
    }
    if (acquereur != null) {
      acq = acquereur.toString();
    }
    return " dénomination:" + denomination + "; nature:" +
        nature + "; prix:" + prix
        //   + "; prix au mètre:" + getPrixAuMetre()
        + " Euros; mode:" +
        mod + "; propriétaire:" + prop + "; acquéreur:" + acq + "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////

class Maison
    extends BienImmo {
  private int nbPieces;
  private int nbSallesDeBain;
  public Maison(String denomination, String nature, int prix,
                int surface, int mode, int nbPieces, int nbSallesDeBain) {
    super(denomination, nature, prix, surface, mode);
    this.nbPieces = nbPieces;
    this.nbSallesDeBain = nbSallesDeBain;
  }

  public String toString() {
    return super.toString() + " nb de pièces:" + nbPieces +
        "; nb de salles de bains:" + nbSallesDeBain + "\n";
  }


}

////////////////////////////////////////////////////////////////////////////////

class Usine
    extends BienImmo {
  private String equipement; //exemple: pont roulant, vestiaires, réfectoire à séparer par des points-virgules
  private int puissanceElectrique; //en kw

  public Usine() {
  }

  public Usine(String denomination, String nature, int prix, int surface,
               int mode, String equipement, int puissanceElectrique) {
    super(denomination, nature, prix, surface, mode);
    this.equipement = equipement;
    this.puissanceElectrique = puissanceElectrique;
  }

  public String toString() {
    return super.toString() + " équipement:" + equipement +
        "; puissance électrique:" + puissanceElectrique + " kw\n";
  }
}

////////////////////////////////////////////////////////////////////////////////

class Agence {
  public static final int MAX_BIENS = 20;
  public static final int MAX_CLIENTS = 20;
  private int nbBiens = 0;
  private int nbClients = 0;
  private BienImmo stock = new BienImmoMAX_BIENS;
  private Client clientele = new ClientMAX_CLIENTS;

  public Agence() {
  }

  BienImmo ajouteBien_(BienImmo m) {
    stocknbBiens++ = m;
    return m;
  }

  BienImmo ajouteBien(BienImmo m) throws ExceptionDepassement {
    if (nbBiens < MAX_BIENS) {
      stocknbBiens++ = m;
    }
    else {
      throw new ExceptionDepassement(nbBiens, m);
    }
    return m;
  }

  Client ajouteClient(Client m) throws ExceptionDepassement {
    if (nbClients < MAX_CLIENTS) {
      clientelenbClients++ = m;
    }
    else {
      throw new ExceptionDepassement(nbClients, m);
    }
    return m;
  }

  void setProprietaire(BienImmo b, Client c) {
    b.setProprietaire(c);
  }

  void setAcquereur(BienImmo b, Client c) {
    b.setAcquereur(c);
  }

  public String toString() {
    String result = "";
    result += "Stock:\n";
    for (int i = 0; i < nbBiens; i++) {
      result += stocki.toString();
    }
    result += "Clientele:\n";
    for (int i = 0; i < nbClients; i++) {
      result += clientelei.toString();
    }
    return result;
  }

  public static void main(String args) {

  }
}

////////////////////////////////////////////////////////////////////////////////

public class Immo {

  public static void main(String args) {
    Agence fnaim = new Agence();

    try {

      BienImmo b1 = fnaim.ajouteBien(new Maison("appartement ensoleillé", "F3",
                                                100000, 80,
                                                BienImmo.MODE_LOCATION, 3, 1));
      BienImmo b2 = fnaim.ajouteBien(new Usine("usine récente",
                                               "agro-alimentaire", 10000000,
                                               6000,
                                               BienImmo.MODE_VENTE,
                                               "atelier;entrepots", 1000));
      BienImmo b3 = fnaim.ajouteBien(new Maison("appartement exceptionnel",
                                                "F2",
                                                800000, 60, BienImmo.MODE_VENTE,
                                                2, 1));
      BienImmo b4 = fnaim.ajouteBien(new Maison("appartement standing", "T6",
                                                1800000, 160,
                                                BienImmo.MODE_LOCATION_VENTE, 6,
                                                2));
      BienImmo b5 = fnaim.ajouteBien(new Usine("atelier", "électronique",
                                               6000000, 2000,
                                               BienImmo.MODE_VENTE,
                                               "atelier;vestiaires", 100));
      Client c1 = fnaim.ajouteClient(new Client("Dupont", "10 rue des lilas",
                                                "30100 Alès"));
      Client c2 = fnaim.ajouteClient(new Client("Durand", "12 rue des roses",
                                                "30100 Alès"));
      Client c3 = fnaim.ajouteClient(new Client("Trucmuche",
                                                "100 boulevard des fleurs",
                                                "30000 Nimes"));
      fnaim.setProprietaire(b1, c1);
      fnaim.setProprietaire(b2, c3);
      fnaim.setProprietaire(b3, c1);
      fnaim.setAcquereur(b3, c1); //doit provoquer une erreur
      fnaim.setAcquereur(b1, c3);
      System.out.println(fnaim);

     

    }

    catch (ExceptionDepassement e) {
      System.out.println(e.getMessage());
    }
    
    /*
         catch (Exception e) {
      System.out.println(e.getMessage());
         }*/

  }

}

////////////////////////////////////////////////////////////////////////////////

jeudi 4 novembre 2004

Patch Pluto pour Tomcat

Télécharger et installer Tomcat 5

soit rep_tomcat le répertoire où vous avez installé Tomcat, par exemple: E:\jakarta-tomcat-5.0.28

fixez la variable d'environnement JAVA_HOME en modifiant, par exemple, la première ligne de rep_tomcat/bin/catalina.bat:

set JAVA_HOME=C:\j2sdk1.4.2_05

créez deux rôles admin et manager, et un utilisateur admin dans rep_tomcat/conf/tomcat-users.xml

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="admin" password="admin" roles="manager,admin"/>
</tomcat-users>

lancez Tomcat avec rep_tomcat/bin/startup.bat

visitez la page d'administration de Tomcat avec un navigateur:

http://localhost:8080/manager/html

stoppez le serveur avec rep_tomcat/bin/shutdown.bat

copiez les trois répertoires contenus dans tomcat-pluto-patch.zip dans rep_tomcat:

/conf contient pluto.xml, qui définit un contexte pour le conteneur de portlet

/shared contient les archives de pluto: pluto-1.0.1-rc1.jar et portlet-api-1.0.jar

/webapps qui contient le portail Pluto lui-même ainsi que notre portlet de test portletApp

redémarrez Tomcat avec rep_tomcat/bin/startup.bat

visitez le portlet: http://localhost:8080/pluto/portal/portletApp

mercredi 3 novembre 2004

L'applet du jour

Une éternité que je n'avais pas écrit d'applet voir ici

mardi 2 novembre 2004

Mon premier portlet

Ecrire des portlets, c'est très simple. Télécharger et installer Pluto (implémentation de référence de la JSR 168)

Source de ce projet

cela donne:


créer un projet portletApp sous webapps

classpath du projet:

PLUTO_HOME/shared/lib/pluto-1.0.1-rc1.jar
PLUTO_HOME/shared/lib/portlet-api-1.0.jar
PLUTO_HOME/common/lib/servlet-api.jar
WEB-INF/classes

inclure la tld:

PLUTO_HOME/webapps/portletApp/WEB-INF/tldportlet.tld

code du portlet:


code de la jsp:


portlet.xml::


web.xml::


modifier PLUTO_HOME/webapps/pluto/WEB-INF/data/pageregistry.xml:


modifier PLUTO_HOME/webapps/pluto/WEB-INF/data/portletentityregistry.xml: