Dépôt officiel du code source de l'ERP OpenConcerto
Rev 153 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.openconcerto.modules.badge;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.sql.SQLException;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.customerrelationship.customer.element.CustomerSQLElement;
import org.openconcerto.erp.modules.ModuleVersion;
import org.openconcerto.erp.utils.HeadlessGestion;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.cc.ITransformer;
public class BadgeListener implements Runnable {
private static final int UDP_PORT = 1470;
private String doorIp;
private int relai;
private ComptaPropsConfiguration conf;
private Preferences modulePrefs;
protected TrayIcon trayIcon;
public BadgeListener() {
}
public void init(String id) throws Exception {
final HeadlessGestion headlessGestion = new HeadlessGestion();
headlessGestion.setupGlobalState(2, Integer.valueOf(id));
this.conf = headlessGestion.getComptaPropsConfiguration();
final String moduleID = "org.openconcerto.modules.badge";
final ModuleVersion vers = this.conf.getModuleManager().getDBInstalledModuleVersion(moduleID);
this.modulePrefs = this.conf.getModuleManager().getFactories().get(moduleID).get(vers).getSQLPreferences(this.conf.getModuleManager().getRoot());
}
private PopupMenu createTrayMenu() {
ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Bye from the tray");
System.exit(0);
}
};
ActionListener executeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
openDoor(4);
}
};
PopupMenu menu = new PopupMenu();
MenuItem execItem = new MenuItem("Ouvrir la porte");
execItem.addActionListener(executeListener);
menu.add(execItem);
MenuItem exitItem = new MenuItem("Quitter");
exitItem.addActionListener(exitListener);
menu.add(exitItem);
return menu;
}
private TrayIcon createTrayIcon() {
Image image = new ImageIcon(this.getClass().getResource("badge.png")).getImage();
PopupMenu popup = createTrayMenu();
TrayIcon ti = new TrayIcon(image, "Service de badge", popup);
ti.setImageAutoSize(true);
return ti;
}
public static void main(String[] args) throws Exception {
BadgeListener bl = new BadgeListener();
bl.readConfiguration();
bl.initUI();
bl.startDaemon();
}
public void startDaemon() {
Thread t = new Thread(this);
t.setName("UDP Listener");
t.start();
}
public void initUI() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!SystemTray.isSupported()) {
try {
JOptionPane.showMessageDialog(new JFrame(), "System tray not supported on this platform");
} catch (Exception e) {
System.out.println("System tray not supported on this platform");
}
} else {
try {
final SystemTray sysTray = SystemTray.getSystemTray();
trayIcon = createTrayIcon();
sysTray.add(trayIcon);
displayMessage("Service de badge", "Ecoute sur port " + UDP_PORT);
} catch (AWTException e) {
System.out.println("Unable to add icon to the system tray");
}
}
}
});
}
public void readConfiguration() throws Exception {
final Properties props = new Properties();
final File file = new File("badge.properties");
System.out.println("Reading from: " + file.getAbsolutePath());
try {
final FileInputStream inStream = new FileInputStream(file);
props.load(inStream);
this.doorIp = props.getProperty("ip").trim();
this.relai = Integer.parseInt(props.getProperty("relai", "1"));
inStream.close();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(new JFrame(), "Fichier manquant\n" + file.getAbsolutePath());
} catch (IOException e) {
JOptionPane.showMessageDialog(new JFrame(), e.getMessage());
}
System.err.println("BadgeListener.readConfiguration() door ip : " + doorIp + ", index :" + relai);
init(props.getProperty("idSociete"));
}
@Override
public void run() {
while (true) {
DatagramSocket serverSocket = null;
try {
final byte[] receiveData = new byte[1024];
serverSocket = new DatagramSocket(UDP_PORT);
while (true) {
final DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
final String sentence = new String(receivePacket.getData()).trim();
cardIdReceived(sentence);
}
} catch (Throwable e) {
e.printStackTrace();
displayError("Erreur", (e == null) ? "" : e.getMessage());
} finally {
if (serverSocket != null) {
serverSocket.close();
}
}
try {
System.out.println("Waiting 10s");
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
System.err.println(e.getMessage());
}
}
}
public void cardIdReceived(final String sentence) {
if (isBadgeAllowed(sentence)) {
boolean b = openDoor(4);
if (b) {
displayMessage("Ouverture", "Ouverture de la porte OK");
} else {
displayError("Erreur", "Impossible d'ouvrir la porte");
}
} else {
displayMessage("Carte refusée", "Carte " + sentence + " non acceptée");
}
}
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
public void displayMessage(String title, String txt) {
displayMessage(title, txt, TrayIcon.MessageType.INFO);
}
private void displayMessage(String title, String txt, final TrayIcon.MessageType msgType) {
if (this.trayIcon != null) {
this.trayIcon.displayMessage(title, txt, msgType);
} else {
System.out.println("[" + msgType.name() + "] " + DATE_FMT.format(LocalDateTime.now()) + " " + title + " : " + txt);
}
}
public void displayError(String title, String txt) {
displayMessage(title, txt, TrayIcon.MessageType.ERROR);
}
public boolean isBadgeAllowed(final String cardNumber) {
final CustomerSQLElement clientElem = this.conf.getDirectory().getElement(CustomerSQLElement.class);
final String clientAdhFieldName = "ID_ADHERENT";
final SQLTable tableAdh = clientElem.getForeignElement(clientAdhFieldName).getTable();
// TODO use createFetcher()
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(clientElem.createGraph());
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(SQLSelect sel) {
sel.andWhere(new Where(sel.getAlias(tableAdh).getField("NUMERO_CARTE"), "=", cardNumber));
return sel;
}
});
final List<SQLRowValues> list = fetcher.fetch();
String motif = "";
boolean allow = false;
SQLRowValues adh = null;
String name = null;
// Aucun adhérent assigné à cette carte
if (list == null || list.isEmpty()) {
motif = "Aucun adhérent associé à la carte " + cardNumber;
displayError("Erreur", motif);
} else if (list.size() > 1) {
motif = list.size() + " adhérents sont liés à la même carte " + cardNumber;
displayError("Erreur", motif);
Thread.dumpStack();
} else {
for (SQLRowValues clientR : list) {
name = clientR.getString("NOM");
adh = (SQLRowValues) clientR.getForeign(clientAdhFieldName);
// Admin toujours autorisé
if (adh.getBoolean("ADMIN")) {
allow = true;
motif = "Administrateur toujours autorisé";
break;
}
// get up to date values
try {
this.modulePrefs.sync();
} catch (BackingStoreException e) {
e.printStackTrace();
}
final boolean onlyAdmin = this.modulePrefs.getBoolean(Module.ENTREE_PREF, false);
if (onlyAdmin) {
motif = "Seul les membres administrateurs sont autorisés!";
break;
}
if (!adh.getBoolean("ACTIF")) {
motif = "La carte de l'adhérent n'est pas active dans sa fiche";
break;
}
Calendar cal = Calendar.getInstance();
final Date d = cal.getTime();
final Calendar dateValidite = adh.getDate("DATE_VALIDITE_INSCRIPTION");
if (dateValidite != null && dateValidite.before(cal)) {
motif = "La date d'autorisation est expirée";
break;
}
SQLRow rowPlage = adh.asRow().getForeignRow("ID_PLAGE_HORAIRE");
if (rowPlage != null) {
Time time = new Time(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE");
String day = dateFormat.format(d).toUpperCase();
{
Time d1 = (Time) rowPlage.getObject("DEBUT_1_" + day);
Time f1 = (Time) rowPlage.getObject("FIN_1_" + day);
if (d1 != null && f1 != null) {
if (time.after(d1) && time.before(f1)) {
allow = true;
motif = "Autorisé sur la plage " + rowPlage.getString("NOM") + " 1";
break;
}
}
}
{
Time d1 = (Time) rowPlage.getObject("DEBUT_2_" + day);
Time f1 = (Time) rowPlage.getObject("FIN_2_" + day);
if (d1 != null && f1 != null) {
if (time.after(d1) && time.before(f1)) {
allow = true;
motif = "Autorisé sur la plage " + rowPlage.getString("NOM") + " 2";
break;
}
}
}
{
Time d1 = (Time) rowPlage.getObject("DEBUT_3_" + day);
Time f1 = (Time) rowPlage.getObject("FIN_3_" + day);
if (d1 != null && f1 != null) {
if (time.after(d1) && time.before(f1)) {
allow = true;
motif = "Autorisé sur la plage " + rowPlage.getString("NOM") + " 3";
break;
}
}
}
motif = "Non autorisé sur la plage horaire " + rowPlage.getString("NOM");
} else {
motif = "Aucune plage horaire associée";
}
}
}
// Création de l'entrée dans la table
SQLTable tableEntree = this.conf.getDirectory().getElement("ENTREE").getTable();
SQLRowValues rowVals = new SQLRowValues(tableEntree);
rowVals.put("DATE", new Date());
rowVals.put("NUMERO_CARTE", cardNumber);
rowVals.put("ACCEPTE", allow);
rowVals.put("MOTIF", motif);
if (name != null) {
rowVals.put("ADHERENT", name);
}
try {
rowVals.commit();
} catch (SQLException exn) {
exn.printStackTrace();
}
return allow;
}
public boolean openDoor(int seconds) {
final Relai r = new Relai(doorIp, relai);
try {
r.pulse(seconds);
return true;
} catch (Throwable ex) {
return false;
}
}
public String getDoorIp() {
return doorIp;
}
}