IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

MDA par la pratique


précédentsommairesuivant

V. Trucs et astuces : finition du client console

Dans cette section, nous allons enrichir l'application console pour créer et lire des fiches de temps en utilisant le service TimeTrackingService. Nous allons devoir ajouter du code personnalisé aux couches métier et d'accès aux données afin de faire fonctionner l'application.

 
Sélectionnez
public static void main(String[] args) {
    // Get services
    serviceLocator = ServiceLocator.instance();
    peopleService = serviceLocator.getPeopleService();
    timeTrackingService = serviceLocator.getTimeTrackingService();
 
    // Create people
    PersonVO naresh = createPerson("nbhatia", "Naresh", "Bhatia");
    PersonVO louis = createPerson("lcoude", "Louis", "Coude");
    PersonVO john = createPerson("jsmith", "John", "Smith");
 
    // Create tasks
    TaskVO research = createTask("Research");
    TaskVO development = createTask("Development");
 
    // Create timecards
    TimecardVO timecard1 = createTimecard(naresh, john);
    TimecardVO timecard2 = createTimecard(naresh, john);
    TimecardVO timecard3 = createTimecard(louis, john);
    TimecardVO timecard4 = createTimecard(louis, john);
 
    // Fetch and show all objects created above
    PersonVO[] people = peopleService.getAllPeople();
    showPeople(people);
    TaskVO[] tasks = timeTrackingService.getAllTasks();
    showTasks(tasks);
    TimecardSummaryVO[] timecards = timeTrackingService.getAllTimecardSummaries();
    showTimecardSummaries(timecards);
 
    // Fetch and show timecard1 details
    System.out.println("Timecard " + timecard1.getId() + " Details:");
    TimecardVO timecard1FromDB = timeTrackingService.getTimecard(timecard1.getId());
    showTimecard(timecard1FromDB);
}

Comme vous pouvez le voir, nous pouvons maintenant créer des tâches et des fiches en plus des personnes. Les méthodes createTask() et createTimecard() appellent le service TimeTrackingService pour réaliser ces opérations. Ensuite nous récupérons toutes les personnes, toutes les tâches et toutes les fiches de temps qui existent dans la base de données, et nous les affichons.

Assurez-vous que l'application console compile en exécutant la cible ttconsole comme suit: maven -o ttconsole. Bien sûr, il n'y a aucun espoir de pouvoir exécuter cette application avec succès pour l'instant puisque la plus grande partie de la couche métier n'a pas encore été implémentée (en particulier les méthodes de TimeTrackingService que nous avons modélisées à l'étape précédente). Nous allons maintenant essayer de rendre l'application exécutable, mais une étape à la fois.

V-A. Création des tâches

La méthode createTask() de TimeTrackerConsole appelle simplement la méthode createTask() de TimeTrackingService, que nous n'avons pas encore implémentée. Alors implémentons cette méthode pour commencer. Ouvrez le fichier TimeTrackingServiceImpl.java et remplissez la méthode handleCreateTask() comme suit:

 
Sélectionnez
protected java.lang.Long handleCreateTask(org.andromda.timetracker.vo.TaskVO taskVO)
    throws java.lang.Exception
{
    Task task = Task.Factory.newInstance();
    getTaskDao().taskVOToEntity(taskVO, task, true);
    getTaskDao().create(task);
    return task.getId();
}

Vérifiez l'implémentation par défaut de taskVOToEntity dans TaskDaoBase.java. Cette implémentation devrait fonctionner parfaitement.

Ajoutez maintenant les instructions import ci-dessous dans TimeTrackingServiceImpl.java (juste en dessous de l'instruction package):

 
Sélectionnez
package org.andromda.timetracker.service;
 
import java.util.Collection;
import org.andromda.timetracker.domain.*;
import org.andromda.timetracker.vo.*;

Nous devrions pouvoir créer des tâches maintenant. Compilez le module code en exécutant la commande « maven -o core », puis exécutez l'application grâce à la commande « maven -o run ». La sortie correspondante est recopiée ci-dessous.

 
Sélectionnez
C:/timetracker>maven -o run
    ...
    [java] Person 1 created - nbhatia
    [java] Person 2 created - lcoude
    [java] Person 3 created - jsmith
    [java] Task 1 created - Research
    [java] Task 2 created - Development
    [java] Exception in thread "main" java.lang.NullPointerException
    [java]      at org.andromda.timetracker.console.TimeTrackerConsole.createTimecard(TimeTrackerConsole.java:94)
    [java]      at org.andromda.timetracker.console.TimeTrackerConsole.main(TimeTrackerConsole.java:42)
    [java] [ERROR] Java Result: 1

Notez que les tâches sont bien créées avec succès. Vous pouvez le vérifier en jetant un œil à votre base de données. Toutefois, nous obtenons une NullPointerException dans TimeTrackerConsole.java. Après avoir regardé dans le code à la ligne spécifiée, il est clair que timeTrackingService.getAllTasks() retourne null. Et cela est tout à fait normal puisque cette méthode n'a pas encore été implémentée. Implémentez cette méthode comme indiqué ci-dessous en appelant TaskDao.loadAll():

 
Sélectionnez
protected org.andromda.timetracker.vo.TaskVO[] handleGetAllTasks()
    throws java.lang.Exception
{
    Collection tasks = getTaskDao().loadAll(TaskDao.TRANSFORM_TASKVO);
    return (TaskVO[])tasks.toArray(new TaskVO[tasks.size()]);
}

Compilez le module core en exécutant la commande « maven -o core ». Avant que nous ne puissions exécuter l'application à nouveau, nous devons réinitialiser la base de données en supprimant le schéma et en le recréant. Exécutez la commande « maven -o drop-schema create-schema » pour démarrer avec une nouvelle base de données. Ensuite, exécutez l'application grâce à la commande « maven -o run ». La sortie correspondante est reproduite ci-dessous.

 
Sélectionnez
C:/timetracker>maven -o run
    ...
    [java] Person 1 created - nbhatia
    [java] Person 2 created - lcoude
    [java] Person 3 created - jsmith
    [java] Task 1 created - Research
    [java] Task 2 created - Development
    [java] Timecard null created with 3 allocations
    [java] Timecard null created with 1 allocations
    [java] Timecard null created with 1 allocations
    [java] Timecard null created with 1 allocations
    ...

Beaucoup mieux! Il semble que les tâches soient bien créées à présent. Le prochain obstacle à franchir est la création de fiches de temps.

V-B. Création de fiches de temps

En analysant le code dans TimeTrackerConsole.createTimecard(), il est clair que timeTrackingService.createTimecard() retourne null. Cela vient bien sûr du fait que createTimecard() n'a pas été implémentée dans TimeTrackingService. Il va donc vous falloir ouvrir TimeTrackingServiceImpl.java sous C:/timetracker/core/src/java/org/andromda/timetracker/service et implémenter handleCreateTimecard() comme suit:

 
Sélectionnez
protected java.lang.Long handleCreateTimecard(org.andromda.timetracker.vo.TimecardVO timecardVO)
        throws java.lang.Exception
{
    // Create new timecard from timecardVO
 
    Timecard timecard = Timecard.Factory.newInstance();
    getTimecardDao().timecardVOToEntity(timecardVO, timecard, true);
 
    // Set submitter and approver associations
    timecard.setSubmitter(getPersonDao().findByUsername(timecardVO.getSubmitterName()));
    timecard.setApprover(getPersonDao().findByUsername(timecardVO.getApproverName()));
    // Set allocations
    TimeAllocationVO allocations[] = timecardVO.getAllocations();
    for(int i=0; i<allocations.length; i++) {            
        // Create TimeAllocation from TimeAllocationVO
        TimeAllocationVO allocationVO = allocations[i];
        TimeAllocation allocation = TimeAllocation.Factory.newInstance();
        getTimeAllocationDao().timeAllocationVOToEntity(allocationVO, allocation, true);
 
        // Connect to timecard
        timecard.addTimeAllocation(allocation);
        // Connect to task
        allocation.setTask(getTaskDao().load(allocationVO.getTaskId()));
    }
    // Create the timecard
    getTimecardDao().create(timecard);
    return timecard.getId();
}

En analysant TimeAllocationDaoBase.java, il est clair qu'AndroMDA ne gère pas la conversion de valeurs imbriquées lorsqu'il génère les méthodes de conversion d'objets de valeurs en entités, et vice-versa. Nous allons donc devoir ajouter du code dans TimeAllocationDaoImpl.java pour effectuer cette conversion. Ce fichier est généré dans le répertoire C:/timetracker/core/src/java/org/andromda/timetracker/domain. Apportez les modifications suivantes au fichier :

  • ajoutez les instructions import suivantes après l'instruction package.
 
Sélectionnez
package org.andromda.timetracker.domain;
 
import org.andromda.timetracker.vo.TimeAllocationVO;
import org.andromda.timetracker.vo.TimePeriodVO;
  • implémentez les deux méthodes toTimeAllocationVO() comme suit:
 
Sélectionnez
public void toTimeAllocationVO(org.andromda.timetracker.domain.TimeAllocation sourceEntity, org.andromda.timetracker.vo.TimeAllocationVO targetVO)
{
    super.toTimeAllocationVO(sourceEntity, targetVO);
    TimePeriod timePeriod = sourceEntity.getTimePeriod();
    targetVO.setTimePeriodVO(new TimePeriodVO(timePeriod.getStartTime(), timePeriod.getEndTime()));
    targetVO.setTaskId(sourceEntity.getTask().getId());
}
 
public org.andromda.timetracker.vo.TimeAllocationVO toTimeAllocationVO(final org.andromda.timetracker.domain.TimeAllocation entity)
{
    TimeAllocationVO targetVO = new TimeAllocationVO();
    toTimeAllocationVO(entity, targetVO);        
    return targetVO;
}
  • implémentez la méthode timeAllocationVOToEntity() comme suit (attention à implémenter la bonne méthode, c'est-à-dire celle qui prend un paramètre copyIfNull):
 
Sélectionnez
public void timeAllocationVOToEntity(
    org.andromda.timetracker.vo.TimeAllocationVO sourceVO,
    org.andromda.timetracker.domain.TimeAllocation targetEntity,
    boolean copyIfNull)
{
    super.timeAllocationVOToEntity(sourceVO, targetEntity, copyIfNull);
    TimePeriodVO timePeriodVO = sourceVO.getTimePeriodVO();
    targetEntity.setTimePeriod(TimePeriod.newInstance(timePeriodVO.getStartTime(), timePeriodVO.getEndTime()));
}

Nous devons apporter des changements similaires à la classe TimecardDaoImpl :

  • ajoutez les instructions import suivantes après l'instruction package.
 
Sélectionnez
package org.andromda.timetracker.domain;
 
import java.util.ArrayList;
import java.util.Collection;
 
import org.andromda.timetracker.ServiceLocator;
import org.andromda.timetracker.vo.TimeAllocationVO;
import org.andromda.timetracker.vo.TimecardSummaryVO;
import org.andromda.timetracker.vo.TimecardVO;
  • implémentez les deux méthodes toTimecardSummaryVO() comme suit:
 
Sélectionnez
public void toTimecardVO(
    org.andromda.timetracker.domain.Timecard sourceEntity, 
    org.andromda.timetracker.vo.TimecardVO targetVO)
{
    toTimecardSummaryVO(sourceEntity, targetVO);
    // Create allocations
    Collection allocations = new ArrayList(sourceEntity.getAllocations());
    ((TimeAllocationDao)ServiceLocator.instance().getService("timeAllocationDao")).toTimeAllocationVOCollection(allocations);
    targetVO.setAllocations((TimeAllocationVO[])allocations.toArray(new TimeAllocationVO[allocations.size()]));
}
 
public org.andromda.timetracker.vo.TimecardVO toTimecardVO(final org.andromda.timetracker.domain.Timecard entity)
{
    TimecardVO targetVO = new TimecardVO();
    toTimecardVO(entity, targetVO);
    return targetVO;
}

Nous allons enfin implémenter deux méthodes dans TimeTrackingServiceImpl.java de façon à ce que les timecards puissent être retrouvées pour être affichées. Voici ces deux méthodes:

 
Sélectionnez
protected org.andromda.timetracker.vo.TimecardVO handleGetTimecard(java.lang.Long id)
    throws java.lang.Exception
{
    return (TimecardVO)getTimecardDao().load(TimecardDao.TRANSFORM_TIMECARDVO, id);
}
 
protected org.andromda.timetracker.vo.TimecardSummaryVO[] handleGetAllTimecardSummaries()
    throws java.lang.Exception
{
    Collection timecards = getTimecardDao().loadAll(TimecardDao.TRANSFORM_TIMECARDSUMMARYVO);
    return (TimecardSummaryVO[])timecards.toArray(new TimecardSummaryVO[timecards.size()]);
}

Compilez l'application en exécutant la commande « maven -o clean install ». Avant de pouvoir exécuter l'application à nouveau, nous devons encore effacer la base de données et recréer le schéma. Exécutez la commande « maven -o drop-schema create-schema » pour démarrer avec une base de données vide. Ensuite, exécutez l'application grâce à la commande « maven -o run ». L'application s'exécute avec succès jusqu'au bout! La sortie est reproduite ci-dessous.

 
Sélectionnez
    [java] Person 1 created - nbhatia
    [java] Person 2 created - lcoude
    [java] Person 3 created - jsmith
    [java] Task 1 created - Research
    [java] Task 2 created - Development
    [java] Timecard 1 created with 3 allocations
    [java] Timecard 2 created with 1 allocations
    [java] Timecard 3 created with 2 allocations
    [java] Timecard 4 created with 2 allocations
    [java] People:
    [java] 1: nbhatia - Naresh Bhatia
    [java] 2: lcoude - Louis Coude
    [java] 3: jsmith - John Smith
    [java]
    [java] Tasks:
    [java] 1: Research
    [java] 2: Development
    [java]
    [java] Timecards:
    [java] 1: status=DRAFT, begin date=2006-02-01 04:23:33.0, comments=On track!, submitter=nbhatia, approver=jsmith
    [java] 2: status=DRAFT, begin date=2006-02-01 04:23:33.0, comments=On track!, submitter=nbhatia, approver=jsmith
    [java] 3: status=DRAFT, begin date=2006-02-01 04:23:34.0, comments=On track!, submitter=lcoude, approver=jsmith
    [java] 4: status=DRAFT, begin date=2006-02-01 04:23:34.0, comments=On track!, submitter=lcoude, approver=jsmith
    [java]
    [java] Timecard 1 Details:
    [java] 1: status=DRAFT, begin date=2006-02-01 04:23:33.0, comments=On track!, submitter=nbhatia, approver=jsmith
    [java]     1: start time=2006-02-03 04:23:33.0, end time=2006-02-04 04:23:33.0, task id=2
    [java]     2: start time=2006-02-02 04:23:33.0, end time=2006-02-03 04:23:33.0, task id=1
    [java]     3: start time=2006-02-01 04:23:33.0, end time=2006-02-02 04:23:33.0, task id=1

V-C. La suite des évènements

Dans ce tutoriel, nous nous sommes assurés d'avoir tout l'environnement installé pour pouvoir démarrer l'écriture de projets MDA en utilisant AndroMDA, mais ce n'est que le début. Il y a plusieurs cartridges différentes que vous pouvez utiliser, ou peut-être, si vous n'en trouvez aucune qui correspond à vos besoins, pourrez-vous en écrire une vous-même et la proposer à l'intégration dans le projet AndroMDA.

Une autre chose que vous pourrez essayer sera de construire une interface graphique utilisateur pour l'application TimeTracker. Vous pouvez vous référer aux guides pratiques (http://galaxy.andromda.org/docs/howto-guides.html) pour en savoir plus sur la cartridge Bpm4Struts qui peut être utilisée pour développer des interfaces web.

Quoi qu'il en soit, vous devrez en apprendre plus sur UML, MDA, les techniques et les meilleures pratiques de modélisation. Une bonne idée pourrait être également de jeter un œil aux exemples compris dans la distribution binaire, et notamment au modèle inclus dans chacun d'entre eux. Cette distribution peut être téléchargée depuis la page du projet AndroMDA: http://sourceforge.net/project/showfiles.php?group_id=73047. Notez toutefois que les exemples de la distribution doivent être construits si vous désirez voir les sources générées ou avant de les déployer. Pour ce faire, rendez-vous dans le dossier de l'exemple et invoquez maven, c'est tout.


précédentsommairesuivant