Steve Jobs Project/POS/Documentation:fr

From iDempiere
Jump to navigation Jump to search
This is a work in progress by Trigger. There is an English version of this by TheD.

Bonjour à tous!!! Ceci est un essaie de documentation technique de "OpenBravo POS".

Ce tutoriel est réaliser avec l'EDI Netbeans, mais vous êtes libre d'utiliser l'EDI qui vous convient.

Comment telecharger et modifier le code source de OpenBravo POS?

Pour toutes informations permettant d'installer et modifier le code source de OpenBravo POS avec l'IDE Netbeans suivez le lien suivant :

Comment POS initialise les paramètres de la base de données par défaut?

Lors du lancement de l'application, si elle ne trouve pas de base de données, elle vous notifie de la création automatique d'une base de données par défaut. Dans cette section, nous verrons comment le script initialise la base de données. La section suivante concernera la connexion à la base de données et la création du schéma c'est-à-dire des différentes tables et des contraintes. Notification.png
AppConfig-UML-Model.png La classe responsable de l'initialisation des paramètres de la base de données à utiliser est com.openbravo.pos.forms.AppConfig. Voici, pour une vue générale de cette classe, un diagramme UML simplifier.

La méthode responsable de l'initialisation des parametres de la base de donnée par défaut est loadDefault().

private void loadDefault() {

       m_propsconfig = new Properties();

       String dirname = System.getProperty("dirname.path");
       dirname = dirname == null ? "./" : dirname;

       m_propsconfig.setProperty("db.driverlib", 
         new File(new File(dirname), "lib/derby.jar").getAbsolutePath());
       m_propsconfig.setProperty("db.driver", "org.apache.derby.jdbc.EmbeddedDriver");
       m_propsconfig.setProperty("db.URL", 
         "jdbc:derby:" + new File(new File(System.getProperty("user.home")),
           AppLocal.APP_ID + "-database").getAbsolutePath() + ";create=true");
       m_propsconfig.setProperty("db.user", "");
       m_propsconfig.setProperty("db.password", "");
       ...
}
Pour ceux qui veulent aller plus loin, vous pouvez voir les valeurs de ces variables en utilisant le debugger. Il suffit de placer un breakpoint, lancer le debugger et consulter l'état des différentes variables. Sur ma machine, voici le resultat. Il est important de noter que ce résultat dépend des plateformes utilisées (Windows, Mac, Linux,...). Defautl-variable-values.png

Vous l'avez certainement remarqué!!! la suite de la méthode a pour but l'initialisation des autres paramètres de configuration de l'application. Une fois les paramètres initialisés, voyons comment le script crée le schéma de la base de données.

Comment POS cré automatiquement la base de données par défaut?

La classe responsable de la création des tables dans la base de données est com.openbravo.pos.forms.JRootApp. La méthode qui nous interesse dans cette classe, initApp, est chargée de créer une session et le schéma de la base de données.

Creation d'une session et initialisation des reqêtes

com.openbravo.pos.JRootApp utilise la classe com.openbravo.pos.forms.AppViewConnection pour se connecter à la base de données par la methode getSession(). Ensuite JRootApp appelle la méthode magique!!! getBean qui permet d'instancier dynamiquement la classe com.openbravo.pos.forms.DataLogicSystem. CreateSession.png


Initialisation.png La méthode getBean crée un objet de type com.openbravo.pos.forms.DataLogicSystem, qui hérite de la classe com.openbravo.pos.forms.BeanFactoryDataSingle, qui à son tour implémente l'interface com.openbravo.pos.forms.BeanFactoryApp, puis appelle la méthode init(session s) déclarer dans l'interface BeanFactoryApp. C'est ce dernier appel qui initialise les requêtes d'interrogation de la base de données (SELECT).


Initialisation et affichage de la fenêtre d'authentification

Un coup d'oeil sur la méthode main de la classe com.openbravo.pos.form.StartPOS!!!
Comme nous pouvons l'observer, la méthode main instancie un objet config de la classe AppConfig. AppConfig implémente l'interface AppProperties qui offre les méthodes getConfigFile(), getHost() et getProperty(java.lang.String sKey).
AppProperties.png

Construction de l'objet config

AppConfig-method.png L'objet config contient deux attributs importants : m_propsconfig et configfile.

Lors de la construction de l'objet config, l'appel suivant est exécuté : init(getDefaultConfig()).

La méthodes imbriquées getDefaultConfig() renvoi un objet de type java.io.File contenant le chemin vers le fichier openbravospos.properties qui se trouve par défaut dans le répertoire « home » sous Linux (ou « user » sous Windows).

private File getDefaultConfig() {
       return new File(new File(System.getProperty("user.home")),
               AppLocal.APP_ID + ".properties");
   }

La méthode init(java.io.File config) initialise l'attribut configfile avec l'objet de type java.io.File renvoyé par la méthode getDefaultConfig() puis l'attribut m_propsconfig avec une instance de type java.util.Properties.

private void init(File configfile) {
       this.configfile = configfile;
       m_propsconfig = new Properties();

       logger.info("Reading configuration file: " + configfile
               .getAbsolutePath());
   }


Après l'instantiation de l'objet config, la méthode main initialise l'attribut m_propsconfig par appel de la méthode load(). Cette dernière initialise m_propsconfig avec les paramètres par défauts (via la méthode privée loadDefault()) ou à partir du fichier openbravospos.properties via l'objet config. Ainsi il est possible de saisir les configurations en modifiant le fichier openbravospos.properties soit directement en utilisant un éditeur de texte, soit via le logiciel (il suffit de cliquer successivement sur Maintenance → Ressources puis sélectionner le fichier openbravospos.properties).
Voici un apercu du contenue du fichier openbravospos.properties

#Openbravo POS. Configuration file.
#Wed Aug 20 19:44:58 WAT 2014
payment.commerceid=
paper.receipt.height=546
format.time=
format.integer=
db.driver=org.apache.derby.jdbc.EmbeddedDriver
payment.gateway=external
format.date=
machine.printer=screen
paper.standard.y=72
paper.standard.x=72
format.datetime=
user.country=US
payment.magcardreader=Not defined
machine.scanner=Not defined
payment.commercepassword=password
db.password=crypt\:2A396841DF90414B
db.URL=jdbc\:derby\:/home/trigger/openbravopos-database;create\=true
db.driverlib=/home/trigger/NetBeansProjects/OpenbravoPOS/./lib/derby.jar
user.variant=
paper.standard.width=451
paper.standard.height=698
format.percent=
machine.scale=Not defined
machine.ticketsbag=standard
machine.screenmode=window
machine.hostname=trigger-VPCEG36EC
machine.display=screen
machine.printer.3=Not defined
paper.standard.mediasizename=A4
machine.printer.2=Not defined
user.language=en
db.user=
swing.defaultlaf=org.jvnet.substance.skin.BusinessBlueSteelSkin
paper.receipt.width=190
machine.printername=(Default)
machine.uniqueinstance=false
format.double=
format.currency=
payment.testmode=false
paper.receipt.y=287
paper.receipt.x=10
paper.receipt.mediasizename=A4

Pour les curieux, voici une partie du script de la méthode loadDefault() chargée d'initialiser les paramètres de configuration par défauts de l'application.

LoadDefault-method.png

Initialisation des composants graphiques et préparation des requêtes

Maintenant, intéressons nous à la dernière instruction de la fonction main :

                if ("fullscreen".equals(screenmode)) {
                   JRootKiosk rootkiosk = new JRootKiosk();
                   rootkiosk.initFrame(config);
               } else {
                   JRootFrame rootframe = new JRootFrame(); 
                   rootframe.initFrame(config);
               }

Par défaut, le mode d'affichage est window. L'expression "fullscreen".equals(screenmode) à donc la valeur false. Ainsi, le bloc else sera exécuté. Ce bloc comporte deux instructions. La première instancie un objet rootframe de type com.openbravo.pos.forms.JRootFrame, qui hérite de la classe javax.swing.JFrame, et la seconde appelle la méthode initFrame(com.openbravo.pos.forms.AppProperties props) sur rootframe

La méthode initFrame initialise l'attribut m_rootapp, de la classe JRootFrame, avec une instance de la classe com.openbravo.pos.forms.JRootApp. JRootApp est une classe descendante de javax.swing.JPanel. Elle represente le panneau sur lequel seront greffés les différents composants graphiques de la fenêtre de login, qui sont initialisés, par la methode initComponent(), lors de la construction de m_rootapp.

   /** Creates new form JRootApp */
   public JRootApp() {    

       m_aBeanFactories = new HashMap<String, BeanFactory>();
       
       // Initialize the visual components
       initComponents ();            
       jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35));   
   }

Avant affichage, la classe JRootApp appelle la méthode initApp(com.openbravo.pos.form.AppPropereties props) qui à son tour appelle la méthode getBean(java.lang.String className). Il est important de noter que la méthode getBean renvoie un objet de type java.lang.Object ce qui explique l'opération de changement de type dans l'instruction suivante :

m_dlSystem = (DataLogicSystem) getBean("com.openbravo.pos.forms.DataLogicSystem");

La méthode getBean renvoie la référence d'un objet dont le type est passé en paramètre sous forme de chaîne de caractère. Un regard dans le script de la méthode nous permet de remarquer, just avant l'instruction return bf.getBean(), l'appel de la methode init(com.openbravo.pos.forms.AppView app) de l'interface com.openbravo.pos.forms.BeanFactoryApp. La méthode init est responsable de l'initialisation des requêtes d'intérrogations des données à travers les objets de type PreparedSentence et StaticSentence.

Avant la création ou la mise à jour de la base de donnée, l'objet m_rootapp de la classe JRootApp effectu une lecture de la version de la base de données et effectue, en fonction du résultat d'une comparaison entre la version lue et la version par défaut, la création ou la mise à jour. Dans notre cas, puisque la base de donnée est inexistante, il s'agira de la création.

// Create or upgrade the database if database version is not the expected
       String sDBVersion = readDataBaseVersion();        
       if (!AppLocal.APP_VERSION.equals(sDBVersion)) {
           
           // Create or upgrade database

Avant de voir la création de la base de donnée proprement dite, attardons nous un peu sur la lecture de la version de la base de données (BD).

Lecture de la version de l'application dans la base de données

Le diagramme de séquence suivant représente les interactions, entre les objets de l'application POS, allant de la création de la fenêtre JRootFrame à la lecture de la version de l'application dans la base de données.

DS-readDBVersion.png

Le diagramme précédent nous montre que la méthode chargée de récupérer l'information sur la version dans la base de donnée est find(java.lang.Object params). En fait, cette méthode est déclarée dans l'interface com.openbravo.data.loader.SentenceFind et implémentée dans la classe abstraite com.openbravo.data.loader.BaseSentence. La compréhension profonde de l'exécution de cette méthode fait appel à la notion de polymorphisme. Force est donc, de présenter la classe com.openbravo.data.loader.PreparedSentence et sa hiérarchie.

Tout d'abord, présentons de manière global la hiérarchie des classes de com.openbravo.data.loader.PreparedSentence. La figure suivante est un diagramme de classe UML de cette hiérarchie.

PreparedSentence-hierarchy.png

La méthode find est implémentée dans la classe abstraite BaseSentence du paquet com.openbravo.data.loader. Un coup d'oeuil sur le code nous permet de voir que find utilise la méthode openExec pour interroger la base de données et fetchOne pour récupérer le résultat.

   public final Object find(Object params) throws BasicException {
       // En caso de error o lanza un pepinazo en forma de SQLException          
       DataResultSet SRS = openExec(params);
       Object obj = fetchOne(SRS);
       SRS.close();
       closeExec();
       return obj;
   }

L'implémentation de la méthode openExec, déclarer abstraite dans BaseSentence, se trouve dans la classe PreparedSentence.