/*
* AbstractPrinter.java
*
* Created on 21 février 2002, 20:57
*/
package fr.mch.mdo.client.printer;
import gnu.io.CommDriver;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.BufferedOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.StringTokenizer;
/**
* In oder to used this class in Linux OS, we have to give permission for connected user by following these 2 steps:
* 1) adduser $connectedUser uucp
* 2) adduser $connectedUser dialout
*
* In the jre/lib/security/java.policy file, we have to add these following lines:
* For Ubuntu sun JDK 6:
* permission java.lang.RuntimePermission "loadLibrary.rxtxSerial";
* permission java.io.FilePermission "/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/ext/amd64/librxtxSerial.so", "read";
* permission java.io.FilePermission "/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/ext/librxtxSerial.so", "read";
* permission java.io.FilePermission "/usr/java/packages/lib/ext/amd64/librxtxSerial.so", "read";
* permission java.io.FilePermission "/usr/java/packages/lib/ext/librxtxSerial.so", "read";
* permission java.util.PropertyPermission "gnu.io.log.mode", "read";
*
* PropertyPermission "gnu.io.log.mode" ==> Required by RXTX
*
* @author mathieu ma
* @version
*/
public abstract class AbstractPrinter implements IPrinter
{
/** Output charset. */
private String charset = "UTF-8";
/** Debugging. */
protected boolean debug = false;
/** Communication Driver. */
private static CommDriver driver = null;
/** Communication port. */
private static CommPortIdentifier portId = null;
/** Serial Port Bauds. */
private static int serialportBauds = 9600;
/** Serial Port Bits. */
private static int serialportBits = 8;
/** Serial Port Stop Bits. */
private static int serialportStopBits = 1;
/** Serial Port Parity. */
private static int serialportParity = 0;
/**
* public static final int DATABITS_5 = 5; public static final int
* DATABITS_6 = 6; public static final int DATABITS_7 = 7; public static
* final int DATABITS_8 = 8; public static final int STOPBITS_1 = 1; public
* static final int STOPBITS_2 = 2; public static final int STOPBITS_1_5 =
* 3; public static final int PARITY_NONE = 0; public static final int
* PARITY_ODD = 1; public static final int PARITY_EVEN = 2; public static
* final int PARITY_MARK = 3; public static final int PARITY_SPACE = 4;
*/
private static HashMap<String, String> specialCharacters = null;
/** Number of chars for each data packet. */
private static int packet = 50;
/** Pause in millisecond. */
private static int pause = 1500;
/**
* Used to know if we have to check DSR: for USB printer no DSR to check but for Serial Port Printer we must check DSR.
* Default value is false, it means that we have to check the DSR.
**/
private boolean noCheckDsr = false;;
/** Data container to be printed. */
private StringBuffer dataBuffer = new StringBuffer();
/** Printer loaded. */
private boolean loaded = false;
/** Printer. */
private Printer printer = null;
/**
* Initialization method that will be called after the applet is loaded into the browser.
* TODO Add a new parameter named noCheckDsr for USB Epson Printer ==> See Old java code
*
* In the java.policy file we MUST be updated with the
* following lines:
* permission java.lang.RuntimePermission "loadLibrary.rxtxSerial";
* permission java.io.FilePermission "C:/Program Files/Java/jre6/lib/ext/x86/rxtxSerial.dll", "read";
* permission java.io.FilePermission "C:/Program Files/Java/jre6/lib/ext/rxtxSerial.dll", "read";
* permission java.util.PropertyPermission "gnu.io.log.mode", "read";
*
* The permission java.util.PropertyPermission "gnu.io.log.mode", "read" must be set for applet.
*/
public void init() {
String os = System.getProperty("os.name");
if (!loaded) {
debug = Boolean.TRUE.toString().equalsIgnoreCase(this.getParameter(IPrinter.PARAMETER_DEBUG_KEY, Boolean.TRUE.toString()));
charset = this.getParameter(IPrinter.PARAMETER_CHARSET_KEY, IPrinter.DEFAULT_CHARSET);
String specialCharactersString = this.getParameter(IPrinter.PARAMETER_SPECIAL_CHARACTERS_STRING_KEY, IPrinter.DEFAULT_SPECIAL_CHARACTERS_STRING);
StringTokenizer specialCharactersStk = new StringTokenizer(specialCharactersString, ";");
String bindSpecialCharactersString = this.getParameter(IPrinter.PARAMETER_BIND_SPECIAL_CHARACTERS_STRING_KEY, IPrinter.DEFAULT_BIND_SPECIAL_CHARACTERS_STRING);
StringTokenizer bindSpecialCharactersStk = new StringTokenizer(bindSpecialCharactersString, ";");
if (specialCharactersStk != null && bindSpecialCharactersStk != null) {
specialCharacters = new HashMap<String, String>(specialCharactersStk.countTokens());
if (specialCharactersStk.countTokens() <= bindSpecialCharactersStk.countTokens()) {
while (specialCharactersStk.hasMoreTokens()) {
specialCharacters.put(specialCharactersStk.nextToken(), bindSpecialCharactersStk.nextToken());
}
}
}
String driverName = IPrinter.DEFAULT_WINDOWS_DRIVER_NAME;
String portCom = IPrinter.DEFAULT_WINDOWS_PORT_COM;
try {
if (os.toLowerCase().matches("linux")) {
driverName = this.getParameter(IPrinter.PARAMETER_LINUX_DRIVER_NAME_KEY, IPrinter.DEFAULT_LINUX_DRIVER_NAME);
portCom = this.getParameter(IPrinter.PARAMETER_LINUX_PORT_COM_KEY, IPrinter.DEFAULT_LINUX_PORT_COM);
} else {
driverName = this.getParameter(IPrinter.PARAMETER_WINDOWS_DRIVER_NAME_KEY, IPrinter.DEFAULT_WINDOWS_DRIVER_NAME);
portCom = this.getParameter(IPrinter.PARAMETER_WINDOWS_PORT_COM_KEY, IPrinter.DEFAULT_WINDOWS_PORT_COM);
}
String serialportBaudsString = this.getParameter(IPrinter.PARAMETER_SERIAL_PORT_BAUDS_KEY, IPrinter.DEFAULT_SERIAL_PORT_BAUDS);
serialportBauds = Integer.parseInt(serialportBaudsString);
String serialportBitsString = this.getParameter(IPrinter.PARAMETER_SERIAL_PORT_BITS_KEY, IPrinter.DEFAULT_SERIAL_PORT_BITS);
serialportBits = Integer.parseInt(serialportBitsString);
String serialportStopBitsString = this.getParameter(IPrinter.PARAMETER_SERIAL_PORT_STOP_BITS_KEY, IPrinter.DEFAULT_SERIAL_PORT_STOP_BITS);
serialportStopBits = Integer.parseInt(serialportStopBitsString);
String serialportParityString = this.getParameter(IPrinter.PARAMETER_SERIAL_PORT_PARITY_KEY, IPrinter.DEFAULT_SERIAL_PORT_PARITY);
serialportParity = Integer.parseInt(serialportParityString);
String packetString = this.getParameter(IPrinter.PARAMETER_PACKET_KEY, IPrinter.DEFAULT_PACKET);
packet = Integer.parseInt(packetString);
String pauseString = this.getParameter(IPrinter.PARAMETER_PAUSE_KEY, IPrinter.DEFAULT_PAUSE);
pause = Integer.parseInt(pauseString);
String noCheckDsrString = this.getParameter(IPrinter.PARAMETER_NO_CHECK_DSR_KEY, IPrinter.DEFAULT_NO_CHECK_DSR);
this.noCheckDsr = ((noCheckDsrString != null) && (noCheckDsrString.equals("true")));
} catch (Exception e) {
// debug = true;
//System.out.println("Erreur de récupération des paramètres de l'imprimante série");
System.out.println("Error in getting printer parameters.");
e.printStackTrace();
}
/*
* if (debug) {
* System.out.println("Initialisation de l'applet ImpressionApplet : "
* ); System.out.println("driver.name : " + driverName);
* System.out.println("imprimante.portcom : " + portCom);
* System.out.println("serialport.bauds : " + serialportBauds);
* System.out.println("serialport.bits : " + serialportBits);
* System.out.println("serialport.stopbits : " +
* serialportStopBits); System.out.println("serialport.parity : " +
* serialportParity); System.out.println("packet : " + packet);
* System.out.println("pause : " + pause);
* System.out.println("imprimante.caracteresSpeciaux : " +
* specialCharactersString);
* System.out.println("imprimante.bindCaracteresSpeciaux : " +
* bindCaracteresSpeciauxStr); }
*/
try {
driver = (CommDriver) Class.forName(driverName).newInstance();
driver.initialize();
} catch (Exception e) {
// debug = true;
//System.out.println("Erreur d'instanciation du driver");
System.out.println("Error instanciation driver.");
e.printStackTrace();
}
boolean flagNoPortComFound = false;
try {
portId = CommPortIdentifier.getPortIdentifier(portCom);
if (debug) {
//System.out.println("Identifiant du port de communication trouvé sur " + portCom);
System.out.println("Identifier port communication found " + portCom);
}
} catch (Exception e) {
flagNoPortComFound = true;
//System.out.println("Erreur de récupération de l'identifiant du port de communication " + portCom + " : premier essai");
System.out.println("Error getting identifier port communication " + portCom + " : fisrt try.");
e.printStackTrace();
}
int attempt = 0;
if (flagNoPortComFound) {
Enumeration<?> enumeration = CommPortIdentifier.getPortIdentifiers();
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
CommPortIdentifier searchedPortId = (CommPortIdentifier) enumeration.nextElement();
if (searchedPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
attempt++;
if (!searchedPortId.isCurrentlyOwned()) {
portId = searchedPortId;
flagNoPortComFound = false;
if (debug) {
//System.out.println("Identifiant du port de communication trouvé sur " + portCom);
System.out.println("Identifier port communication found " + portId.getName() + " after " + attempt + " tries");
}
break;
}
}
}
}
}
if (flagNoPortComFound) {
//System.out.println("Impossible de récupérer de l'identifiant du port série de communication après " + attempt + " tentative(s)");
System.out.println("Unable to get identifier port communication " + portCom + " after " + attempt + " tries.");
}
printer = new Printer();
loaded = true;
}
}
@Override
public void reload() {
loaded = false;
init();
}
/**
* @return the printer
*/
public Printer getPrinter() {
return printer;
}
/**
* @param printer the printer to set
*/
public void setPrinter(Printer printer) {
this.printer = printer;
}
/**
* This method check the value of key applet parameter name and returns it
* if this not null else it returns the default value
*
* @param key
* applet parameter name
* @param defaultValue
* default value if there is no value with key applet parameter
* name
* @return the value of key applet parameter name if this is not null else
* the default value
*/
public abstract String getParameter(String key, String defaultValue);
private byte[] getLine(String line, int size) {
byte[] result = null;
StringBuffer strBuff = new StringBuffer();
if (size == 2) {
// Format de la police en gras et avec une taille double en largeur et en longueur
// POS(point of sale) byte code for font bold, font size double.
strBuff.append((char) 0x1B);
strBuff.append((char) 0x21);
strBuff.append((char) 0x38);
}
if (line.equals(""))
line += " ";
strBuff.append(bindSpecialCharacters(line));
if (size == 2) {
// Format de la police par défaut
strBuff.append((char) 0x1B);
strBuff.append((char) 0x21);
strBuff.append((char) 0x01);
}
// Saut de ligne
strBuff.append((char) 0x0A);
try {
result = strBuff.toString().getBytes(charset);
} catch (UnsupportedEncodingException uee) {
result = strBuff.toString().getBytes();
}
result = strBuff.toString().getBytes();
return result;
}
public void print() {
// Initialisation imprimante
dataBuffer.insert(0, new String(INITIALIZE_PRINTER_INTERNATIONAL_CHARACTER));
// dataBuffer.append(new String(PRINT_FEED_PAPER_CUT_SHEET));
if (debug) {
System.out.println("Data dans le buffer avant envoie vers imprimante : \n" + dataBuffer.toString());
}
byte[] dataBytes = null;
try {
dataBytes = dataBuffer.toString().getBytes(charset);
} catch (UnsupportedEncodingException uee) {
if (debug) {
System.out.println("Charset impossible d'encoder : " + charset);
}
dataBytes = dataBuffer.toString().getBytes();
}
byte[] dataPlusCutPaper = new byte[dataBytes.length + IPrinter.PRINT_FEED_PAPER_CUT_SHEET.length];
System.arraycopy(dataBytes, 0, dataPlusCutPaper, 0, dataBytes.length);
System.arraycopy(PRINT_FEED_PAPER_CUT_SHEET, 0, dataPlusCutPaper, dataBytes.length, IPrinter.PRINT_FEED_PAPER_CUT_SHEET.length);
ThreadPrinter tp = new ThreadPrinter(printer, dataPlusCutPaper);
dataBuffer = new StringBuffer();
tp.start();
}
@Override
public void stop() {
if (printer != null && !printer.isStop()) {
printer.setStop(true);
}
}
public void resetDataBuffer() {
dataBuffer = new StringBuffer();
}
public void addData1(String data) {
dataBuffer.append(new String(getLine(data, 1)));
}
public void addData2(String data) {
dataBuffer.append(new String(getLine(data, 2)));
}
private String bindSpecialCharacters(String data) {
Object[] specialCharactersArray = specialCharacters.keySet().toArray();
for (int i = 0; i < specialCharactersArray.length; i++) {
data = data.replace(((String) specialCharactersArray[i]).charAt(0), (char) Integer.parseInt((String) specialCharacters.get(specialCharactersArray[i]), 16));
}
return data;
}
public void close() {
if (printer != null) {
printer.closeSerialPort();
}
}
class Printer
{
private boolean stop = false;
private SerialPort serialport = null;
public Printer() {
}
/**
* @param stop the stop to set
*/
public void setStop(boolean stop) {
this.stop = stop;
}
/**
* @return the stop
*/
public boolean isStop() {
return stop;
}
private boolean openSerialPort() {
boolean result = false;
if (portId != null && serialport == null) {
try {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
serialport = (SerialPort) portId.open("montagnesdor", 2 * pause);
serialport.setSerialPortParams(serialportBauds, serialportBits, serialportStopBits, serialportParity);
serialport.setDTR(true);
result = true;
}
} catch (Exception e) {
System.out.println("Could Not Get Serial Port " + e);
e.printStackTrace();
}
}
return result;
}
public void closeSerialPort() {
try {
serialport.close();
} catch (Exception e) {
System.out.println("Could Not Close Serial Port " + e);
e.printStackTrace();
}
serialport = null;
try {
Thread.sleep(2 * pause);
} catch (Exception e) {
System.out.println("Impossible de faire la pause de " + (2 * pause) + "\n" + e);
}
}
public synchronized void printData(byte[] data) {
if (openSerialPort()) {
stop = false;
BufferedOutputStream out = null;
try {
out = new BufferedOutputStream(serialport.getOutputStream());
int lastLength = data.length % packet;
int indexDataBegin = 0;
while (indexDataBegin < data.length) {
if (noCheckDsr || serialport.isDSR()) {
if (indexDataBegin + packet <= data.length) {
out.write(data, indexDataBegin, packet);
if (debug) {
System.out.println("Data sent to printer: \n" + new String(data, indexDataBegin, packet));
}
} else {
out.write(data, indexDataBegin, lastLength);
if (debug) {
System.out.println("Data sent to printer: \n" + new String(data, indexDataBegin, lastLength));
}
}
out.flush();
try {
Thread.sleep(pause / 5);
} catch (Exception e) {
System.out.println("Impossible de faire la pause de " + (pause / 5) + " " + e);
}
indexDataBegin += packet;
} else {
System.out.println("Imprimante occupée !!! ");
try {
Thread.sleep(pause);
} catch (Exception e) {
System.out.println("Impossible de faire la pause de " + (pause) + " " + e);
}
}
if (stop) {
System.out.println("Stop printing by user");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (Exception e) {
System.out.println("Could not close the printer output " + e);
}
closeSerialPort();
}
}
}
}
class ThreadPrinter extends Thread
{
Printer printer = null;
byte[] data = null;
public ThreadPrinter(Printer printer, byte[] data) {
this.printer = printer;
this.data = data;
}
public void run() {
printer.printData(data);
}
}
}