mardi 25 septembre 2012

Kde 4.9 vs Windows 7

Quelques années se sont écoulées depuis la comparaison de Kde 3.4 et de Windows XP. Les deux systèmes ont grandement évolués.

L'expérience est renouvelée cette fois-ci avec Kde 4.9 et Windows 7.
Les interfaces ont évolué, des programmes ont été enlevés, d'autres ajoutés.

Le but étant de comparant l'environnement graphique d'un des bureaux les plus populaires sous Linux à celui de Windows.

Poste de travail




Tableau de bord (barre des tâches)

Les deux barres affichent les applications en cours, raccourcies ainsi que la barre d'état.


Menu

Les programmes affichés dans le menu de Kde sont affichés dans des catégories.





Boîte de dialogue




Centre de configuration






Explorateur de fichier




Gérer les tâches







 

Recherche de fichier

L'interface plus conventionnelle






Similarité des programmes




Même s'il est possible d'écouter de la musique avec ce lecteur vidéo, un autre lecteur est installé pour l'audio.


Le même outil est utilisé pour l'audio et la vidéo.







 

Personnalisation de l'interface












Autres

Windows Messenger, Outlook Express, Galerie de photo, Windows Movie Maker ainsi que le carnet d'adresses ne sont plus compris dans Windows 7. Soit vous cherchez des produits similaires de d'autres fournisseurs soit vous optez pour Windows live.

Le client mail par défaut est Kmail qui gère les email, flux RSS, les contacts, les notes, le carnet d'adresses.

Le client de messagerie instantanée gère de multiples protocoles. 


K3b sert à graver des cd, dvd.



Ark est un logiciel de compression, décompression.



Nous avons pu remarquer que chacun des environnements graphiques a évolué au cours des quelques années de la précédente comparaison.

Certains trouvent parfois l'environnement graphique Kde complexe, nous avons vu qu'il était similaire à ce que Microsoft propose.

dimanche 23 septembre 2012

Gwt: requestFactory et spring

Avant la version 2.1, il n'y avait que les RPC pour communiquer avec le serveur en Gwt. Depuis cette version, un nouveau api est disponible, Request Factory.

Cet api permet de n'envoyer que les informations nécessaires au client et au serveur. Il y a économie de bande passante. Au niveau du code, beaucoup de changement sont à prévoir. J'ai passé beaucoup de temps à essayer d'utiliser cet api avec Spring.

La base de donnée h2, spring 3.1 ainsi que gwt 2.4 ont été utilisé pour cet exemple.

L'interface graphique comporte deux boutons, un pour charger toutes les données de la base de donnée et l'autre pour y ajouter un élément.




Le fichier web.xml

<web -app="-app" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 
    <context -param="-param">
        <param -name="-name" />contextConfigLocation
        <param -value="-value" />/WEB-INF/applicationContext.xml
    </context>
    <listener>
        <listener -class="-class">org.springframework.web.context.ContextLoaderListener</listener>
    </listener>
    <servlet>
        <servlet -name="-name">requestFactoryServlet</servlet>
        <servlet -class="-class">com.google.web.bindery.requestfactory.server.RequestFactoryServlet</servlet>
    </servlet>
    <servlet -mapping="-mapping">
        <servlet -name="-name">requestFactoryServlet</servlet>
        <url -pattern="-pattern">/gwtRequest</url>
    </servlet>
    <welcome -file-list="-file-list">
        <welcome -file="-file">welcomeGWT.html</welcome>
    </welcome>
</web>


Dans le fichier applicationContext.xml, je n'ai que

<context:annotation -config="-config">
<context:component -scan="-scan" base-package="org.calibra">


<bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          p:location="/WEB-INF/jdbc.properties" />

    <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="${jdbc.driverClassName}"
      p:url="${jdbc.url}"
      p:username="${jdbc.username}"
      p:password="${jdbc.password}" />


Dans le fichier Main.gwt.xml, il faut ajouter

<inherits name="javax.validation.Validation"/>
<inherits name='com.google.web.bindery.requestfactory.RequestFactory'/>

Dans le package Domain

public class Account {
    private Long id;
    private String username;
    private Integer version;

    ....
}

Dans le package server


La classe AccountLocator est nécessaire afin de ne pas mettre ces opérations directement dans la classe Account.

public class AccountLocator extends Locator<Account, Long> {

    @Autowired
    private AccountDAO accountDAO;

    @Override
    public Account create(Class<? extends Account> clazz) {
        return new Account();
    }

    @Override
    public Account find(Class<? extends Account> clazz, Long id) {

        if (accountDAO == null) {
            HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
            ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
            accountDAO =context.getBean(AccountDAO.class);
        }
        return accountDAO.findAccount(id);
    }

    @Override
    public Class<Account> getDomainType() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Long getId(Account domainObject) {
        return domainObject.getId();
    }

    @Override
    public Class<Long> getIdType() {
        return Long.class;
    }

    @Override
    public Object getVersion(Account domainObject) {
        return domainObject.getVersion();
    }


La classe SpringServiceLocator est nécessaire afin d'avoir accès au bean.

public class SpringServiceLocator implements ServiceLocator {
    @Override
    public Object getInstance(Class<?> clazz) {
        HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
        ServletContext servletContext = request.getSession().getServletContext();
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        return context.getBean(clazz);
    }
}



Dans le package server.service

public interface AccountService {
    public Account findAccount(Long id);
    public List<Account> loadAllAccounts();
    public void save(Account account);
    public void delete(Account account);
}


 @Service
public class AccountServiceImpl implements AccountService{
  
    @Autowired
    private AccountDAO accountDAO;

    @Override
    public void save(Account account){
        accountDAO.save(account);
    }

    @Override
    public List<Account> loadAllAccounts() {
        return accountDAO.loadAllAccounts();
    }

    @Override
    public Account findAccount(Long id) {
        return accountDAO.findAccount(id);
    }

    @Override
    public void delete(Account account) {
        accountDAO.delete(account);
    }
}



Dans le package server.dao

@Repository
public class AccountDAOImpl implements AccountDAO {

    protected JdbcTemplate jdbcTemplate;

    @Override
    public Account findAccount(Long id) {
        StringBuffer sb = new StringBuffer();
        sb.append("select id, username, version from account where id = ?");
        List<Account> accountList = jdbcTemplate.query(sb.toString(),
                new Object[]{id}, mapper);

        if (accountList != null && accountList.size() > 0) {
            return accountList.get(0);
        }
        return null;
    }

    @Override
    public List<Account> loadAllAccounts() {

        StringBuffer sb = new StringBuffer();
        sb.append("select id, username, version from account");
        List<Account> accountList = jdbcTemplate.query(sb.toString(), mapper);
        return accountList;
    }

    @Override
    public void save(Account account) {
        if (account.getVersion() == null) {
            account.setVersion(0);
            jdbcTemplate.update("insert into account(username, version) values(?, ?)",
                    account.getUsername(), account.getVersion());
        } else {
            account.setVersion(account.getVersion() + 1);
            jdbcTemplate.update("update account(username, version) set username=?, version=? where id=?",
                    account.getUsername(), account.getVersion(), account.getId());
        }
    }

    @Override
    public void delete(Account account) {
        jdbcTemplate.update("delete from account where id = ?", account.getId());
    }

    @Autowired
    public void setDataSource(DataSource datasource) {
        this.jdbcTemplate = new JdbcTemplate(datasource);
    }
    private static ParameterizedRowMapper<Account> mapper = new ParameterizedRowMapper<Account>() {
        @Override
        public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
            Account account = new Account();
            account.setId(rs.getLong("id"));
            account.setUsername(rs.getString("username"));
            account.setVersion(rs.getInt("version"));
            return account;
        }
    };
}


public interface AccountDAO {  
    public Account findAccount(Long id);
    public List<Account> loadAllAccounts(); 
    public void save(Account account);
    public void delete(Account account);
}

 

 Dans le package shared


public interface AccountRequestFactory extends RequestFactory {
    AccountRequest accountRequest();
}


@Service(locator = SpringServiceLocator.class, value =AccountService.class)
public interface AccountRequest extends RequestContext {

    Request<AccountProxy> findAccount(Long id);
    Request<List<AccountProxy>> loadAllAccounts();
    Request<Void> save(AccountProxy accountProxy);
    Request<Void> delete(AccountProxy accountProxy);
}


@ProxyFor(value=Account.class, locator = AccountLocator.class)
public interface AccountProxy extends EntityProxy{
    public Long getId();
    public String getUsername();
    public Integer getVersion();
   
    public void setUsername(String userName);
    public void setId(Long id);
    public void setVersion(Integer version);
 }


Dans le package client

public class MainEntryPoint implements IsWidget, EntryPoint {

    private final AccountRequestFactory requestFactory = GWT.create(AccountRequestFactory.class);
    AccountRequest request;
    AccountProxy newAccount;

    @Override
    public Widget asWidget() {

        Button loadAllButton = new Button("Load all Account");
        final ValueListBox<AccountProxy> accountListBox = new ValueListBox<AccountProxy>(new Renderer<AccountProxy>() {
            @Override
            public String render(AccountProxy object) {
                return object.getUsername();
            }

            @Override
            public void render(AccountProxy object, Appendable appendable) throws IOException {
                appendable.append(object.getUsername());
            }
        });

        loadAllButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                request = requestFactory.accountRequest();
                Request<List<AccountProxy>> loadAllAccounts = request.loadAllAccounts();

                loadAllAccounts.fire(new Receiver<List<AccountProxy>>() {
                    @Override
                    public void onSuccess(List<AccountProxy> response) {
                        accountListBox.setAcceptableValues(response);
                        Window.alert("account ajouté");
                    }
                });
            }
        });

        Button addButton = new Button("Add account");
        addButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                request = requestFactory.accountRequest();
                AccountProxy accountProxy = request.create(AccountProxy.class);
                accountProxy.setUsername("joe");

                request.save(accountProxy).fire(new Receiver<Void>() {
                    @Override
                    public void onSuccess(Void response) {
                        Window.alert("account ajouté");
                    }
                });
            }
        });

        VerticalPanel vp = new VerticalPanel();
        vp.setSpacing(10);
        vp.add(loadAllButton);
        vp.add(accountListBox);
        vp.add(addButton);
        return vp;
    }

    @Override
    public void onModuleLoad() {
        requestFactory.initialize(new SimpleEventBus());
        RootPanel.get().add(asWidget());
    }
}


Liste de jar présent dans WEB-INF/lib/




Les sources de cet exemples est disponible ici.
Ces jar ne sont pas inclus dans les sources.

samedi 22 septembre 2012

Design Pattern Tête la première




Ce livre présente les patrons suivants
  • Observateur
  • Décorateur
  • Fabriques
  • Singleton
  • Commande
  • Adaptateur, Façade
  • Patron de méthode
  • Itérateur, composite
  • État
  • Proxy
  • Composés


Au lieu d'aborder une approche théorique comme de nombreux livres, ils ont opté pour une approche pratique.

Il utilise des techniques afin de rendre plus aisé l'apprentissage. Les informations sont expliquées de diverses façons.

Les images sont abondamment utilisées. Il y a des mini-jeux ainsi que des questions afin de faire réfléchir le lecteur sur la matière vue.
Des conseils sont données tout au long du livre. Des dialogues ainsi que des histoires sont employés afin d'emmener le lecteur à se forger une idée sur les points clés.
Les moyens pédagogiques employés rend  la lecture du livre beaucoup plus agréable, sans compté que ça simplifie la compréhension et la mémorisation des patrons.

Les exemples de code utilisent le langage Java, cependant il devrait être compris sans difficulté par ceux utilisant c#.

Cette approche est employée pour chaque patron. Cette stratégie devrait être employée dans plus de bouquins.

À ce jour, c'est le meilleur livre sur les patrons que j'ai pu lire. Si vous devez en lire qu'un seul, pensez à celui-ci.

Certes seuls les patrons les plus populaires sont présentés, mais vous obtiendrez une base solide afin de les utiliser dans vos développements.

dimanche 16 septembre 2012

Netbeans

Netbeans
Chaque nouvelle version de netbeans apporte un nombre grandissant d'amélioration. Il a quelques années, Eclipse a su s'accaparer une grande part du marché des ide en Java.

Depuis, Oracle travaille d'arrache pied pour remonter la pente. Leur effort semble récompensé, les réactions dans les forums et sondage sont très positif. La facilité de créer des interfaces graphiques depuis la  version 5x à peu aider à contribuer à ce renversement.

Une panoplie de module peuvent être installé à la demande: C/C++, java mobile, php, ruby, grail, groovy. De plus le profiler ainsi le créateur de gui installé par défaut permette de faciliter le développement.

Hudson, Ant, Maven, Bugzilla sont bien intégré à l'outil.

Netbeans possède un éditeur graphique qui utilise le groupLayout. Il permet en quelques cliques de créer des interfaces très complexe.



Il y a certe moins de plugin qu'Eclipse, mais les meilleurs existent aussi pour cet ide.

De multiple wizard existe pour créer les fonctionnalités CRUD.

JavaFX est supporté.

La plateforme Netbeans peut être utilisé afin de créer des applications Swing. Il pousse à utiliser divers principe du génie logiciel tel que les modules, les plugins et les services. Il standardise les tâches courantes de création d'application graphiques: gestion des fenêtres, menu, mise à jour, gestion des langues. La gestion des modèles des composants graphiques est générique. Le même modèle peut être utilisé pour un jtree, jtable...

Si vous n'avez jamais utilisé Netbeans, essaye le, votre expérience de développement en sera grandissante. Autrement, faite la mise à jour.

samedi 30 juin 2012

Programming Language Processors




Programming Language Processors in Java fournie diverses techniques pour concevoir un langage de programmation. Ce livre comporte moins de 450 pages et comporte de multiple exemples pratiques.

Des exemples concrets pour les différentes sections du livre
  • Langage processeur
  • Compilation
  • Analyse synxtaxique
  • Analyse contextuel
  • Géneration de code
  • Interpretation
sont présentés et les liens avec la théorie sont très claire. Les différents chapitres peuvent être lu de façon indépendant ce qui permet d'alléger la lecture et de la rendre plus accesible. Les auteurs ne tombent pas dans le piège d'être trop théorique. Les exemples permettent de mieux comprendre l'aspect théorique et de se faire de meilleur idée sur d'autre approche d'implémentation possible.
 Les analyses de type LL, LR sont présentés et permettent d'avoir une meilleure idées de laquelle employés selon le langage qu'on cherche à créer ou bien à analyser.
Une étude de cas est utilisé en employant le langage Triangle. Il est ainsi possible de comprendre les différentes parties du compilateur qui est fait en Java pour ce langage. Le tout en employant de bonne pratiques du génie logiciel.Ce langague est utilisé pour tous les chapitres.

Divers algorithmes sont présentés pour chaque section du livre.
Le code java employé n'est pas parfait mais il reste de très bonne augure.
Un chapitre peut s'avérer intéressant pour ceux qui n'ont pas de connaissance sur l'architecture de base des cpu. Il permet en autre de comprendre les variables sont mis sur la pile, comment les paramètres sont envoyés au fonction. Ce chapitre est très instructif pour la création d'une machine virtuelle.

L'auteur a su bien dosé chaque aspect, il n'a pas entré dans des détails trop futile.
Après avoir lu le livre, le lecteur pourra être en mesure de créer son propre langage de programmation ou de faire un interpréteur de commande. Surement le livre idéal si on veut apprendre en codant.

vendredi 15 juin 2012

Specification By Example




Ce livre explique l'importance d'insérer le client dans le processus du développement logiciel. Les bénéfices ainsi que les bonnes pratiques sont définis. Le plus intéressant du livre est de mon point de vue les études de cas. Diverses entreprises donnent leur commentaire, comment elle était avant l'emploi de cette méthode et les résultats de son usage.

Des concepts clés tel que définir les spécifications en groupe, mettre des exemples dans les spécifications, valider fréquemment les spécifications ainsi que plusieurs autres bonnes pratique sont élaborés dans ce livre.

Je crois qu'avoir vécu quelques projets informatiques peut contribuer à mieux apprécier ce livre et ainsi remarquer qu'on est pas les seul à avoir des problèmes similaires et à vouloir les fixer.Oui la documentation est importante, mais une image peur remplacer beaucoup de mot et éviter des erreurs.

Les cas concrets ne font que renforcer que les méthodologies agiles peuvent vraiment être un avantage dans la gestion d'un projet informatique. Les cas sont différents ainsi que la structure et la des équipes ce qui permet de mieux pouvoir se projeter dans un de ces exemples C'est un livre qui donne de précieux conseils.

mardi 2 août 2011

Language Implementation Patterns




Ce livre présente différents patrons utilisés pour l'interprétation, analyse et la traduction de langage de programmation. Le livre utiliser ANTLR afin d'aller à l'essentiel et réduire la complexité. Les différentes étapes de la syntaxe du langage à l'exécutable sont passées en revue.

La première partie est consacrer au parsing le langage différente technique sont présenté tel que "backtracking, memoizin, predicated"... La deuxième partie consiste à analyser ce qui a été lu. La troisième partie est liée à la création d'interpréteur (haut niveau et bytecode). La dernière partie consiste à traduire à un langage à un autre.

Ce livre permettra à celui qui veut créer un langage de mieux décerner le patron qu'il pourra utiliser. Certains patrons sont plus adaptés à certains types de syntaxe. Le lecteur pourra avoir une idée pour implémenter un interpréteur pour un langage dynamique.

La traduction d'un langage à un autre permet grâce à l'exemple d'avoir une meilleure idée de la façon de faire pour un langage plus complexe.

J'ai trouvé que les explications n'étaient pas toujours claires et manquaient d'exemple réellement concret. Néanmoins, il constitue une excellente entrée pour quiconque veut implémenter un langage de programmation.

Peu de livres présentent d'une façon si épurée autant de concept, ce livre fait moins de 400 pages. La concurrence fait souvent plus du double ou triple et est axé trop souvent sur la théorie.

C'est un livre à compléter par un livre plus axé sur la pratique.

Migration d’une application Spring Boot 2.2 vers Spring Boot 4.0 : retour d’expérience concret

 En 2019, nous avons développé une application métier basée sur : Java 8 Spring Boot 2.2.7 Gradle 6.6.1 Thymeleaf Boots...