blob: 516d56a07674facfd2f2efbf4f07e0a825ce5555 [file] [log] [blame]
/*
*
* Copyright (c) 2011 - 2016 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Initial contribution:
* Loetz GmbH & Co. KG
*
*/
package org.eclipse.osbp.abstractstatemachine;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.Timer;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.ui.api.message.MessageEvent;
import org.eclipse.osbp.ui.api.message.MessageEvent.EventType;
import org.eclipse.osbp.ui.api.pos.ISignatureEvent;
import org.eclipse.osbp.ui.api.pos.ISignatureListener;
import org.eclipse.osbp.ui.api.pos.IZVTTransactionData;
import org.eclipse.osbp.ui.api.pos.PenData;
import org.eclipse.osbp.ui.api.statemachine.IBeeper;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.SimpleType;
import com.vaadin.ui.Audio;
import com.vaadin.ui.Video;
import jpos.BaseControl;
import jpos.CashDrawer;
import jpos.CashDrawerConst;
import jpos.CashDrawerControl114;
import jpos.JposException;
import jpos.LineDisplay;
import jpos.LineDisplayConst;
import jpos.LineDisplayControl114;
import jpos.POSPrinter;
import jpos.POSPrinterConst;
import jpos.POSPrinterControl114;
import jpos.Scale;
import jpos.config.JposEntryRegistry;
import jpos.config.simple.SimpleEntry;
import jpos.events.ErrorListener;
import jpos.events.OutputCompleteEvent;
import jpos.events.OutputCompleteListener;
import jpos.events.StatusUpdateEvent;
import jpos.events.StatusUpdateListener;
import jpos.loader.simple.SimpleServiceManager;
import jpos.services.POSPrinterService14;
import jpos.util.DefaultProperties;
import jpos.util.JposProperties;
import jpos.util.JposPropertiesConst;
/**
* PeripheralService is a bridge between javaPOS and the state machine
* participant.
*/
public abstract class AbstractPeripheralService extends AbstractStateMachineParticipant
implements IPeripheral, IPeripheral.Command, StatusUpdateListener, ErrorListener, OutputCompleteListener,
ISignatureListener, ActionListener {
private static final String HTTP = "http";
private static final String APPLICATION_JSON = "application/json";
private static final String ACCEPT = "Accept";
private static final String DEVICE_NAME = "deviceName";
private static final String CASH_DRAWER_CONST = "CashDrawerConst";
private static final String POS_PRINTER_CONST = "POSPrinterConst";
/** The devices. */
protected Map<String, BaseControl> devices = new HashMap<>();
/** The slip notifications enabled. */
private boolean slipNotificationsEnabled = false;
/** The windows created. */
protected int windowsCreated = 0;
/** */
private boolean paymentTerminalIsOpen = false;
private boolean signaturePadIsOpen = false;
private boolean printerBitmapIsSet[] = { false, false, false, false, false };
/** The pt IP. */
protected String ptIP;
/** The pt port. */
protected Integer ptPort;
/** The props. */
protected JposEntryRegistry props;
/** is init done correctly? */
protected boolean initDone = false;
/** The pen data supplied by signature pad. */
private List<PenData> penData = new ArrayList<>();
/** The beeper. */
protected IBeeper beeper;
/** The audio. */
protected Audio audio;
/** The video. */
protected Video video;
/** if javapos is installed remotely. */
protected boolean isRemote = false;
/** The remote host. */
protected String remoteHost;
/** The remote port. */
protected int remotePort = 9090;
/** The devices status poll. */
private Timer statusPoll;
/** The signature status poll. */
private Timer signatureStatusPoll;
/** The fields of CashDrawerConst. */
Field[] cashDrawerFields = CashDrawerConst.class.getDeclaredFields();
/** The pos printer fields. */
Field[] posPrinterFields = POSPrinterConst.class.getDeclaredFields();
private Map<Integer, String> printerBitmaps = new HashMap<>();
private String esc = ((char) 0x1b) + "";
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int hashCode() {
return super.hashCode();
}
/*
* (non-Javadoc)
*
* @see
* foodmartdialogdslplugin.AbstractStateMachineParticipant#setStatemachine
* (org.eclipse.osbp.ui.api.abstractstatemachine.IStateMachine)
*/
@Override
public void setStatemachine(IStateMachine statemachine) {
super.setStatemachine(statemachine);
statemachine.registerPeripheral(this);
if (POSServiceBinder.getPosService() != null) {
POSServiceBinder.getPosService().setStatemachine(statemachine);
}
}
private boolean isJavaPosRemote() {
if( !"null".equals(remoteHost) && remotePort > 0 ) {
String cmd = String.format("http://%s:%d/devices/posParameters", remoteHost, remotePort);
HttpGet get = new HttpGet(cmd);
get.addHeader("Accept", "application/json");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = httpClient.execute(get);
LOGGER.info(EntityUtils.toString(response.getEntity()));
if(response.getEntity().getContentLength()==0) {
return false;
}
return true;
} catch (ParseException | IOException e) {
// it's ok - we have no remote javapos
} finally {
get.releaseConnection();
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see foodmartdialogdslplugin.AbstractStateMachineParticipant#init()
*/
@Override
public void init(String pRemoteHost, int pRemotePort) {
if( pRemoteHost == null )
remoteHost = "null";
else
remoteHost = pRemoteHost;
remotePort = pRemotePort;
isRemote = isJavaPosRemote();
if (!isRemote) {
LOGGER.debug("Library path={}", System.getProperty("java.library.path"));
// load all names of configured devices, instantiate and cache it
String configFile = ProductConfiguration.getJavaPosConfiguration();
if (configFile == null || configFile.length() == 0) {
LOGGER.info("POS setupfile is not registered in product preferences");
return;
}
LOGGER.info("POS setupfile to be used: {}", configFile);
try {
new URL(configFile);
System.setProperty(JposPropertiesConst.JPOS_POPULATOR_FILE_URL_PROP_NAME, configFile);
} catch (MalformedURLException e) {
System.setProperty(JposPropertiesConst.JPOS_POPULATOR_FILE_PROP_NAME, configFile);
}
System.setProperty(JposPropertiesConst.JPOS_REG_POPULATOR_CLASS_PROP_NAME,
"jpos.config.simple.xml.SimpleXmlRegPopulator");
System.setProperty(JposPropertiesConst.JPOS_SERVICE_MANAGER_CLASS_PROP_NAME,
"jpos.loader.simple.SimpleServiceManager");
JposProperties jposProperties = new DefaultProperties();
jposProperties.loadJposProperties();
SimpleServiceManager serviceManager = new SimpleServiceManager(jposProperties);
serviceManager.getEntryRegistry().load();
props = serviceManager.getEntryRegistry();
} else {
LOGGER.debug("Remote POS server active");
initDone = true;
remoteHost = statemachine.getHostName();
remotePort = statemachine.getRemotePort();
URIBuilder builder = new URIBuilder();
builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
if (statusPoll == null) {
statusPoll = new Timer(1000, this);
statusPoll.start();
} else if (!statusPoll.isRunning()) {
statusPoll.restart();
}
}
}
private String doHttpGet(String path) {
return doHttpGet(path, null);
}
private String doHttpGet(String path, Map<String, String> params) {
String responseString = null;
URIBuilder builder = new URIBuilder();
builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
builder.setPath(path);
builder.clearParameters();
if (params != null) {
for (String paramKey : params.keySet()) {
builder.addParameter(paramKey, params.get(paramKey));
}
}
try {
HttpGet get = new HttpGet(builder.build());
get.addHeader(ACCEPT, APPLICATION_JSON);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(get);
responseString = EntityUtils.toString(response.getEntity());
get.releaseConnection();
} catch (URISyntaxException | ParseException | IOException e) {
LOGGER.error("doHttpGet exception: {}", e);
}
return responseString;
}
private void doHttpPut(String path, String paraName1, String para1) {
doHttpPut(path, paraName1, para1, null, null);
}
private void doHttpPut(String path, String paraName1, String para1, String paraName2, String para2) {
URIBuilder builder = new URIBuilder();
builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
builder.setPath(path);
builder.clearParameters();
if (paraName1 != null && para1 != null) {
builder.addParameter(paraName1, para1);
}
if (paraName2 != null && para2 != null) {
builder.addParameter(paraName2, para2);
}
try {
HttpPut put = new HttpPut(builder.build());
put.addHeader(ACCEPT, APPLICATION_JSON);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
httpClient.execute(put);
put.releaseConnection();
} catch (URISyntaxException | ParseException | IOException e) {
LOGGER.error("doHttpPut exception: {}", e);
}
}
private void doHttpPost(String path) {
doHttpPost(path, null, null);
}
private void doHttpPost(String path, String paraName, String para) {
doHttpPost(path, paraName, para, null);
}
private void doHttpPost(String path, String paraName, String para, byte[] image) {
URIBuilder builder = new URIBuilder();
builder.setScheme(HTTP).setHost(remoteHost).setPort(remotePort);
builder.setPath(path);
try {
HttpPost post = new HttpPost(builder.build());
post.addHeader(ACCEPT, APPLICATION_JSON);
if (paraName != null && para != null || image != null) {
MultipartEntityBuilder mpeBuilder = MultipartEntityBuilder.create();
mpeBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if (paraName != null && para != null) {
mpeBuilder.addTextBody(paraName, para);
}
if (image != null) {
mpeBuilder.addBinaryBody("image", image, ContentType.MULTIPART_FORM_DATA, "");
}
post.setEntity(mpeBuilder.build());
}
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
httpClient.execute(post);
post.releaseConnection();
} catch (URISyntaxException | ParseException | IOException e) {
LOGGER.error("doHttpPost exception {}", e);
}
}
public void initDevice(String deviceName ) {
if (isRemote) {
HttpPut put = new HttpPut(String.format("http://%s:%d/devices/claim?deviceName=%s", remoteHost, remotePort, deviceName));
put.addHeader("Accept", "application/json");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = httpClient.execute(put);
LOGGER.info(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
LOGGER.error("Unable to init device {}\n{}", deviceName, e);
} finally {
put.releaseConnection();
}
} else {
BaseControl device = null;
SimpleEntry entry = null;
entry = (SimpleEntry) props.getJposEntry(deviceName);
if(entry == null) {
LOGGER.error("{} is not configured", deviceName);
} else {
try {
device = (BaseControl) Class.forName("jpos." + entry.getProp("deviceCategory").getValueAsString()).getConstructor().newInstance();
device.open(deviceName);
device.claim(1000);
device.setDeviceEnabled(true);
if ( "POSPrinter".equals(entry.getProp("deviceCategory").getValueAsString() ) ) {
((POSPrinter) device).addStatusUpdateListener(this);
((POSPrinter) device).addErrorListener(this);
((POSPrinter) device).addOutputCompleteListener(this);
// Even if using any printer, 0.01mm unit makes it possible to print neatly.
((POSPrinter) device).setMapMode(POSPrinterConst.PTR_MM_METRIC);
// Output by the high quality mode
((POSPrinter) device).setRecLetterQuality(true);
}
devices.put(deviceName, device);
LOGGER.info("device init success: {}", deviceName);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException | ClassNotFoundException | JposException ex) {
LOGGER.error("device init error: {}", ex);
if(ex instanceof JposException && ((JposException)ex).getOrigException()!=null) {
LOGGER.error(((JposException)ex).getOrigException().getMessage());
}
LOGGER.error("check path for dll access:"+ System.getProperty("java.library.path"));
}
}
}
}
@Override
public void releaseDevices() {
if (statusPoll != null && statusPoll.isRunning()) {
statusPoll.stop();
}
if (signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
signatureStatusPoll.stop();
}
if (isRemote) {
HttpPut put;
put = new HttpPut(String.format("http://%s:%d/devices/release", remoteHost, remotePort));
put.addHeader("Accept", "application/json");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = httpClient.execute(put);
LOGGER.info(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
LOGGER.error("{}", e);
} finally {
put.releaseConnection();
}
} else {
// release all devices that have been initialized
for( String d:devices.keySet() ) {
try {
devices.get(d).setDeviceEnabled(false);
SimpleEntry entry = null;
entry = (SimpleEntry) props.getJposEntry(d);
if("POSPrinter".equals(entry.getProp("deviceCategory").getValueAsString() )) {
((POSPrinter) devices.get(d)).removeStatusUpdateListener(this);
}
devices.get(d).release();
devices.get(d).close();
} catch (JposException e) {
LOGGER.error("Error releasing {}", d);
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.ui.api.statemachine.IPeripheral#isInitDone()
*/
@Override
public boolean isInitDone() {
return initDone;
}
public int[] getAllWeights(String deviceName) {
int[] weightData = new int[3];
if (isRemote) {
Map<String, String> params = new LinkedHashMap<>();
params.put(DEVICE_NAME, deviceName);
String result = doHttpGet("/devices/readAllWeights", params);
if( result != null ) {
String[] results = result.split(" ");
for( int i=0 ; i<(results.length<weightData.length?results.length:weightData.length) ; i++ ) {
weightData[i] = Integer.parseInt(results[i]);
}
LOGGER.debug("readAllWeights: {}, {}, {}", weightData[0], weightData[1], weightData[2]);
}
return weightData;
} else if (!initDone || !devices.containsKey(deviceName)) {
return weightData;
}
try {
((Scale) devices.get(deviceName)).readWeight(weightData, 2000);
} catch (JposException e) {
LOGGER.error("general error readAllWeights for device:{} ex:{}", deviceName, e);
} catch (Exception ex) {
LOGGER.error("general error readAllWeights for device:{} ex:{}", deviceName, ex);
}
// net weight in element 0
// gross weight in element 1
// tare weight in element 2
LOGGER.debug("readAllWeights: {}, {}, {}", weightData[0], weightData[1], weightData[2]);
return weightData;
}
public Double getReadWeight(String deviceName) {
if (isRemote) {
Map<String, String> params = new LinkedHashMap<>();
params.put(DEVICE_NAME, deviceName);
String result = doHttpGet("/devices/readNetWeight", params);
if( result != null ) {
if( result.contains("status") ) {
LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, result);
} else {
Double result2 = Double.parseDouble(result.replace(",", "."));
LOGGER.debug("readNetWeight: {}", result2);
return result2;
}
}
return 0.0;
} else if (!initDone || !devices.containsKey(deviceName)) {
return 0.0;
}
int[] weightData = new int[3];
try {
((Scale) devices.get(deviceName)).readWeight(weightData, 2000);
} catch (JposException e) {
LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, e);
} catch (Exception ex) {
LOGGER.error("general error readNetWeight for device:{} ex:{}", deviceName, ex);
}
// net weight in element 0
// gross weight in element 1
// tare weight in element 2
Double result = (1.0*weightData[0]) / 1000.0;
LOGGER.debug("readNetWeight: {}", result);
return result;
}
public Double getReadTareWeight(String deviceName) {
if (isRemote) {
Map<String, String> params = new LinkedHashMap<>();
params.put(DEVICE_NAME, deviceName);
String result = doHttpGet("/devices/readTareWeight", params);
if( result != null ) {
if( result.contains("status") ) {
LOGGER.error("general error getReadTareWeight for device:{} ex:{}", deviceName, result);
} else {
Double result2 = Double.parseDouble(result.replace(",", "."));
LOGGER.debug("readTareWeight: {}", result2);
return result2;
}
}
return 0.0;
} else if (!initDone || !devices.containsKey(deviceName)) {
return 0.0;
}
int tareWeight = 0;
try {
if (((Scale) devices.get(deviceName)).getCapTareWeight()) {
tareWeight = ((Scale) devices.get(deviceName)).getTareWeight();
}
} catch (JposException e) {
LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, e);
} catch (Exception ex) {
LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, ex);
}
Double result = (1.0*tareWeight) / 1000.0;
LOGGER.debug("readTareWeight: {}", result);
return result;
}
public String getWeightUnit(String deviceName) {
if (isRemote) {
Map<String, String> params = new LinkedHashMap<>();
params.put(DEVICE_NAME, deviceName);
String result = doHttpGet("/devices/weightUnit", params);
if( result != null )
if( result.contains("status") ) {
LOGGER.error("general error getReadTareWeight for device:{} ex:{}", deviceName, result);
} else {
LOGGER.debug("getWeightUnit: {}", result);
return result;
}
return null;
} else if (!initDone || !devices.containsKey(deviceName)) {
return null;
}
try {
String result="";
int unitType = ((Scale) devices.get(deviceName)).getWeightUnit();
switch (unitType) {
case 0:
result = "pound 1/8";
break;
case 1:
result = "pound 1/10";
break;
case 2:
result = "pound 1/500";
break;
case 3:
result = "kg";
break;
case 4:
result = "pound";
break;
case 5:
result = "oz";
break;
}
LOGGER.debug("getWeightUnit: {}", result);
return result;
} catch (JposException e) {
LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, e);
} catch (Exception ex) {
LOGGER.error("general error readWeight for device:{} ex:{}", deviceName, ex);
}
return null;
}
public void setScaleDisplayText(String deviceName, String displayText) {
if (isRemote) {
doHttpPut("/devices/scaleDisplayText", DEVICE_NAME, deviceName, "displayText", displayText);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (((Scale) devices.get(deviceName)).getCapDisplayText()) {
((Scale) devices.get(deviceName)).displayText(displayText);
}
} catch (JposException e) {
LOGGER.error("general error scaleDisplayText for device:{} text:{} ex:{}", deviceName, displayText, e);
} catch (Exception ex) {
LOGGER.error("general error scaleDisplayText for device:{} text:{} ex:{}", deviceName, displayText, ex);
}
}
public void setTareWeight(String deviceName, String tareWeightInGramms) {
if(null == tareWeightInGramms)
tareWeightInGramms = "0";
if (isRemote) {
doHttpPut("/devices/tareWeight", DEVICE_NAME, deviceName, "tareWeight", tareWeightInGramms);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (((Scale) devices.get(deviceName)).getCapTareWeight()) {
((Scale) devices.get(deviceName)).setTareWeight(Integer.parseInt(tareWeightInGramms));
}
} catch (JposException e) {
LOGGER.error("general error tareWeight for device:{} text:{} ex:{}", deviceName, tareWeightInGramms, e);
} catch (Exception ex) {
LOGGER.error("general error tareWeight for device:{} text:{} ex:{}", deviceName, tareWeightInGramms, ex);
}
}
public void setZeroScale(String deviceName, String dummy) {
if (isRemote) {
doHttpPost("/devices/zeroScale", DEVICE_NAME, deviceName);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (((Scale) devices.get(deviceName)).getCapZeroScale()) {
((Scale) devices.get(deviceName)).zeroScale();
}
} catch (JposException e) {
LOGGER.error("general error zeroScale for device:{} ex:{}", deviceName, e);
} catch (Exception ex) {
LOGGER.error("general error zeroScale for device:{} ex:{}", deviceName, ex);
}
}
// line display code
/**
* Sets the display line.
*
* @param deviceName
* the device name
* @param displayLine
* the new display line
*/
public void setDisplayLine(String deviceName, String displayLine) {
if( null == displayLine ) {
displayLine="";
}
if (isRemote) {
doHttpPut("/devices/displayLine", DEVICE_NAME, deviceName, "displayLine", displayLine);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
String[] parts = displayLine.split("\\|");
try {
if (parts.length > 1) {
((LineDisplay) devices.get(deviceName)).displayText(parts[0], new Integer(parts[1].trim()));
} else {
((LineDisplay) devices.get(deviceName)).displayText(parts[0], LineDisplayConst.DISP_DT_NORMAL);
}
} catch (JposException e) {
LOGGER.error("general error displayLine for device:{} text:{} ex:{}", deviceName, displayLine, e);
} catch (Exception ex) {
LOGGER.error("general error displayLine for device:{} text:{} ex:{}", deviceName, displayLine, ex);
}
}
/**
* Registers a bitmap to all printers.
*
* @param registerBitmap
* encodes a pipe separated tuple bitmapNumber, bitmapFilename
*/
public void setPrinterBitmap(String registerId, String registerBitmapId) {
int imgWidth = 200;
int imgHeight = 80;
if (isRemote) {
doHttpPut("/devices/uploadedBitmaps", "uploadedBitmaps",
Boolean.toString(ProductConfiguration.hasJavaPosUploadedBitmaps()));
byte[] img = statemachine.getBlobService().getByteArrayImage(registerBitmapId, 0);
doHttpPost("/devices/printerBitmap", "registerId", registerId, img);
return;
} else if (!initDone) {
return;
}
// load the image
BufferedImage img = statemachine.getBlobService().getBufferedImage(registerBitmapId, 0);
// convert it to black/white
BufferedImage blackWhite = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = blackWhite.createGraphics();
g2d.drawImage(img, 0, 0, imgWidth, imgHeight, 0, 0, img.getWidth(), img.getHeight(), null);
g2d.dispose();
// write file in temp dir
File tempFile = null;
try {
tempFile = File.createTempFile("printerBitmap", ".bmp");
ImageIO.write(blackWhite, "BMP", tempFile);
} catch (IOException ioex) {
LOGGER.error("{}", ioex);
return;
}
for (BaseControl device : devices.values()) {
String deviceName = "";
try {
int bitmapIndex = Integer.parseInt(registerId);
String path = tempFile.getPath();
deviceName = device.getPhysicalDeviceName();
if (device instanceof POSPrinter && ((POSPrinterControl114) device).getCapRecBitmap()) {
if (ProductConfiguration.hasJavaPosUploadedBitmaps()) {
((POSPrinterControl114) device).setBitmap(bitmapIndex, POSPrinterConst.PTR_S_RECEIPT, path,
(((POSPrinterControl114) device).getRecLineWidth() / 2), POSPrinterConst.PTR_BM_CENTER);
} else {
printerBitmaps.put(bitmapIndex, path);
}
printerBitmapIsSet[bitmapIndex] = true;
}
} catch (JposException jex) {
LOGGER.error("jpos error setRegisterBitmap for device:{} and:{} ex:{}", deviceName, registerBitmapId,
jex);
} catch (Exception ex) {
LOGGER.error("general error registerBitmap for device:{} text:{} ex:{}", deviceName, registerBitmapId,
ex);
}
}
}
/**
* Sets the device brightness.
*
* @param deviceName
* the device name
* @param deviceBrightness
* the new device brightness
*/
public void setDeviceBrightness(String deviceName, Integer deviceBrightness) {
if (isRemote) {
doHttpPut("/devices/deviceBrightness", DEVICE_NAME, deviceName, "deviceBrightness",
deviceBrightness.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setDeviceBrightness(deviceBrightness);
} catch (JposException e) {
LOGGER.error("jpos error deviceBrightness for device:{} and:{} ex:{}", deviceName, deviceBrightness, e);
}
}
/**
* Sets the blink rate.
*
* @param deviceName
* the device name
* @param blinkRate
* the new blink rate
*/
public void setBlinkRate(String deviceName, Integer blinkRate) {
if (isRemote) {
doHttpPut("/devices/blinkRate", DEVICE_NAME, deviceName, "blinkRate", blinkRate.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setBlinkRate(blinkRate);
} catch (JposException e) {
LOGGER.error("jpos error blinkRate for device:{} and:{} ex:{}", deviceName, blinkRate, e);
}
}
/**
* Sets the cursor type.
*
* @param deviceName
* the device name
* @param cursorType
* see: LineDisplayConst
*/
public void setCursorType(String deviceName, Integer cursorType) {
if (isRemote) {
doHttpPut("/devices/cursorType", DEVICE_NAME, deviceName, "cursorType", cursorType.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setCursorType(cursorType);
} catch (JposException e) {
LOGGER.error("jpos error cursorType for device:{} and:{} ex:{}", deviceName, cursorType, e);
}
}
/**
* Sets the marquee format.
*
* @param deviceName
* the device name
* @param marqueeFormat
* the new marquee format
*/
public void setMarqueeFormat(String deviceName, Integer marqueeFormat) {
if (isRemote) {
doHttpPut("/devices/marqueeFormat", DEVICE_NAME, deviceName, "marqueeFormat", marqueeFormat.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setMarqueeFormat(marqueeFormat);
} catch (JposException e) {
LOGGER.error("jpos error marqueeFormat for device:{} and:{} ex:{}", deviceName, marqueeFormat, e);
}
}
/**
* Sets the marquee repeat wait.
*
* @param deviceName
* the device name
* @param marqueeRepeatWait
* the new marquee repeat wait
*/
public void setMarqueeRepeatWait(String deviceName, Integer marqueeRepeatWait) {
if (isRemote) {
doHttpPut("/devices/marqueeRepeatWait", DEVICE_NAME, deviceName, "marqueeRepeatWait",
marqueeRepeatWait.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setMarqueeRepeatWait(marqueeRepeatWait);
} catch (JposException e) {
LOGGER.error("jpos error marqueeRepeatWait for device:{} and:{} ex:{}", deviceName, marqueeRepeatWait, e);
}
}
/**
* Sets the marquee type.
*
* @param deviceName
* the device name
* @param marqueeType
* the new marquee type
*/
public void setMarqueeType(String deviceName, Integer marqueeType) {
if (isRemote) {
doHttpPut("/devices/marqueeType", DEVICE_NAME, deviceName, "marqueeType", marqueeType.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setMarqueeType(marqueeType);
} catch (JposException e) {
LOGGER.error("jpos error marqueeType for device:{} and:{} ex:{}", deviceName, marqueeType, e);
}
}
/**
* Sets the marquee unit wait.
*
* @param deviceName
* the device name
* @param marqueeUnitWait
* the new marquee unit wait
*/
public void setMarqueeUnitWait(String deviceName, Integer marqueeUnitWait) {
if (isRemote) {
doHttpPut("/devices/marqueeUnitWait", DEVICE_NAME, deviceName, "marqueeUnitWait",
marqueeUnitWait.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setMarqueeUnitWait(marqueeUnitWait);
} catch (JposException e) {
LOGGER.error("jpos error marqueeUnitWait for device:{} and:{} ex:{}", deviceName, marqueeUnitWait, e);
}
}
/**
* wraps: createWindow(int viewportRow, int viewportColumn, int
* viewportHeight , int viewportWidth, int windowHeight, int windowWidth);.
*
* @param deviceName
* the device name
* @param createWindow
* the new creates the window
*/
public void setCreateWindow(String deviceName, String createWindow) {
if (isRemote) {
doHttpPut("/devices/createWindow", DEVICE_NAME, deviceName, "createWindow", createWindow);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
String[] parts = createWindow.split("\\|");
try {
((LineDisplayControl114) devices.get(deviceName)).createWindow(new Integer(parts[0].trim()),
new Integer(parts[1].trim()), new Integer(parts[2].trim()), new Integer(parts[3].trim()),
new Integer(parts[4].trim()), new Integer(parts[5].trim()));
windowsCreated++;
} catch (JposException e) {
LOGGER.error("jpos error createWindow for device:{} and:{} ex:{}", deviceName, createWindow, e);
} catch (Exception ex) {
LOGGER.error("jpos error createWindow for device:{} and:{} genericex:{}", deviceName, createWindow, ex);
}
}
/**
* Sets the destroy window.
*
* @param deviceName
* the device name
* @param destroyWindow
* the new destroy window
*/
public void setDestroyWindow(String deviceName, String destroyWindow) { // NOSONAR
if (isRemote) {
doHttpPut("/devices/destroyWindow", DEVICE_NAME, deviceName, "destroyWindow", destroyWindow);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (windowsCreated > 0) {
((LineDisplayControl114) devices.get(deviceName)).destroyWindow();
windowsCreated--;
}
} catch (JposException e) {
LOGGER.error("jpos error destroyWindow for device:" + deviceName + " {}", e);
}
}
/**
* Sets the scroll.
*
* @param deviceName
* the device name
* @param scroll
* encodes a pipe separated tuple: direction, units
*/
public void setScroll(String deviceName, String scroll) {
if (isRemote) {
doHttpPut("/devices/scroll", DEVICE_NAME, deviceName, "scroll", scroll);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
String[] parts = scroll.split("\\|");
try {
((LineDisplayControl114) devices.get(deviceName)).scrollText(new Integer(parts[0].trim()),
new Integer(parts[1].trim()));
} catch (JposException e) {
LOGGER.error("jpos error scroll for device:{} and:{} ex:{}", deviceName, scroll, e);
} catch (Exception ex) {
LOGGER.error("jpos error scroll for device:{} and:{} genericex:{}", deviceName, scroll, ex);
}
}
/**
* Sets the inter character wait.
*
* @param deviceName
* the device name
* @param interCharacterWait
* the new inter character wait
*/
public void setInterCharacterWait(String deviceName, Integer interCharacterWait) {
if (isRemote) {
doHttpPut("/devices/interCharacterWait", DEVICE_NAME, deviceName, "interCharacterWait",
interCharacterWait.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((LineDisplayControl114) devices.get(deviceName)).setInterCharacterWait(interCharacterWait);
} catch (JposException e) {
LOGGER.error("jpos error interCharacterWait for device:{} and:{} ex:{}", deviceName, interCharacterWait, e);
}
}
/**
* Sets the display at.
*
* @param deviceName
* the device name
* @param displayTextAt
* encodes a pipe separated quadruple: row, column, text,
* attribute
*/
public void setDisplayTextAt(String deviceName, String displayTextAt) {
if (isRemote) {
doHttpPut("/devices/displayTextAt", DEVICE_NAME, deviceName, "displayTextAt", displayTextAt);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
String[] parts = displayTextAt.split("\\|");
try {
if (parts.length > 3) {
((LineDisplayControl114) devices.get(deviceName)).displayTextAt(new Integer(parts[0].trim()),
new Integer(parts[1].trim()), parts[2], new Integer(parts[3].trim()));
} else {
((LineDisplayControl114) devices.get(deviceName)).displayTextAt(new Integer(parts[0].trim()),
new Integer(parts[1].trim()), parts[2], LineDisplayConst.DISP_DT_NORMAL);
}
} catch (JposException e) {
LOGGER.error("jpos error displayTextAt for device:{} and:{} ex:{}", deviceName, displayTextAt, e);
} catch (Exception ex) {
LOGGER.error("jpos error displayTextAt for device:{} and:{} genericex:{}", deviceName, displayTextAt, ex);
}
}
/**
* clears the display.
*
* @param deviceName
* the device name
* @param clearDisplay
* is nt used
*/
public void setClearDisplay(String deviceName, String clearDisplay) {
if (isRemote) {
doHttpPut("/devices/clearDisplay", DEVICE_NAME, deviceName, "clearDisplay", clearDisplay);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (windowsCreated > 0) {
((LineDisplayControl114) devices.get(deviceName)).destroyWindow();
windowsCreated--;
}
((LineDisplayControl114) devices.get(deviceName)).clearText();
} catch (JposException e) {
LOGGER.error("jpos error clearDisplay for device:{} and:{} ex:{}", deviceName, clearDisplay, e);
}
}
/**
* opens the drawer.
*
* @param deviceName
* the device name
* @param openDrawer
* is ignored
*/
public void setOpenDrawer(String deviceName, Integer openDrawer) { // NOSONAR
if (isRemote) {
doHttpPut("/devices/openDrawer", DEVICE_NAME, deviceName, "openDrawer", openDrawer.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((CashDrawerControl114) devices.get(deviceName)).openDrawer();
} catch (JposException e) {
LOGGER.error("jpos error openDrawer for device:" + deviceName + " {}", e);
}
}
/**
* prints to receipt printer in normal mode.
*
* @param deviceName
* the device name
* @param printNormal
* text to print
*/
public void setPrintNormal(String deviceName, String printNormal) {
if (isRemote) {
doHttpPut("/devices/printNormal", DEVICE_NAME, deviceName, "printNormal", printNormal);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT, printNormal);
} catch (JposException e) {
LOGGER.error("jpos error printNormal for device:" + deviceName + " {}", e);
}
}
/**
* start transactional printing
*
* @param deviceName
* the device name
*/
public void setStartTransactionPrint(String deviceName) {
if (isRemote) {
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
if (device.getCapTransaction())
device.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_TRANSACTION);
} catch (Exception e) {
LOGGER.error("jpos error printCut for device:" + deviceName + " {}", e);
}
}
/**
* end transactional printing
*
* @param deviceName
* the device name
*/
public void setEndTransactionPrint(String deviceName) {
if (isRemote) {
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
if (device.getCapTransaction())
device.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_NORMAL);
} catch (Exception e) {
LOGGER.error("jpos error printCut for device:" + deviceName + " {}", e);
}
}
/**
* prints footer, feeds paper and cuts.
*
* @param deviceName
* the device name
* @param footer
* the text to print as footer
*/
public void setPrintCut(String deviceName, String footer) {
if (isRemote) {
doHttpPut("/devices/printCut", DEVICE_NAME, deviceName, "printCut", footer);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
try {
if (!footer.isEmpty()) {
device.printNormal(POSPrinterConst.PTR_S_RECEIPT, footer);
}
if (device.getCapRecPapercut()) {
linefeedToPapercut(device);
}
device.cutPaper(99);
} catch (JposException eAll) {
LOGGER.error("jpos error printCut for device:" + deviceName + " {}", eAll);
try {
device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "i");
} catch (JposException e) {
LOGGER.error("retry jpos error printCut for device:" + deviceName + " {}", e);
}
}
}
private void linefeedToPapercut(POSPrinterControl114 device) throws JposException {
int linesToPaperCut = device.getRecLinesToPaperCut() + 1;
try {
device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "|" + linesToPaperCut + "lF"); // linefeed variant 1
} catch (JposException e) {
LOGGER.debug("jpos error linefeedToPapercut - retry variant 2");
device.printNormal(POSPrinterConst.PTR_S_RECEIPT, esc + "d" + ((char) (linesToPaperCut))); // linefeed variant 2
}
}
/**
* print a pre-loaded bitmap.
*
* @param deviceName
* the device name
* @param printBitmap
* the bitmap-id to print
*/
public void setPrintBitmap(String deviceName, Integer printBitmap) {
if (isRemote) {
doHttpPut("/devices/printBitmap", DEVICE_NAME, deviceName, "printBitmap", printBitmap.toString());
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
try {
if (((POSPrinterControl114) devices.get(deviceName)).getCapRecBitmap()
&& printerBitmaps.containsKey(printBitmap)) {
if (ProductConfiguration.hasJavaPosUploadedBitmaps()) {
((POSPrinterControl114) devices.get(deviceName)).printNormal(POSPrinterConst.PTR_S_RECEIPT,
esc + "|" + printBitmap.toString() + "B");
} else {
((POSPrinterControl114) devices.get(deviceName)).printBitmap(POSPrinterConst.PTR_S_RECEIPT,
printerBitmaps.get(printBitmap), POSPrinterConst.PTR_BM_ASIS,
POSPrinterConst.PTR_BM_CENTER);
}
}
} catch (JposException e) {
LOGGER.error("jpos error setPrintBitmap for device:" + deviceName + " and:" + printBitmap + " {}", e);
printerBitmapIsSet[printBitmap] = false;
}
}
/**
* prints a barcode.
*
* @param deviceName
* the device name
* @param data
* the barcode with pipe encoded barcode-type from
* jpos.POSPrinterConst
*/
public void setPrintBarcode(String deviceName, String data) {
if (isRemote) {
doHttpPut("/devices/printBarcode", DEVICE_NAME, deviceName, "printBarcode", data);
return;
} else if (!initDone || !devices.containsKey(deviceName)) {
return;
}
String[] parts = data.split("\\|");
try {
String value = parts[0];
int code = Integer.parseInt(parts[1].trim());
int height = 0;
if (parts.length > 2) {
height = Integer.parseInt(parts[2].trim());
}
POSPrinterControl114 device = (POSPrinterControl114) devices.get(deviceName);
if (device.getCapRecBarCode()) {
device.printBarCode(POSPrinterConst.PTR_S_RECEIPT, value, code, height, device.getRecLineWidth()-1,
POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW);
}
} catch (JposException e) {
LOGGER.error("jpos error setPrintBarcode for device:" + deviceName + " and:" + data + " {}", e);
}
}
/**
* Sets the slip notifications enabled.
*
* @param slipNotificationsEnabled
* the new slip notifications enabled
*/
public void setSlipNotificationsEnabled(boolean slipNotificationsEnabled) {
if (isRemote) {
doHttpPut("/devices/slipNotificationsEnabled", "slipNotificationsEnabled",
Boolean.toString(slipNotificationsEnabled));
} else {
this.slipNotificationsEnabled = slipNotificationsEnabled;
}
}
/**
* Checks if is slip notifications enabled.
*
* @return true, if is slip notifications enabled
*/
public boolean isSlipNotificationsEnabled() {
if (isRemote) {
return Boolean.getBoolean(doHttpGet("/devices/isSlipNotificationsEnabled"));
} else {
return slipNotificationsEnabled;
}
}
/*
* (non-Javadoc)
*
* @see jpos.events.StatusUpdateListener#statusUpdateOccurred(jpos.events.
* StatusUpdateEvent)
*/
@Override
public void statusUpdateOccurred(StatusUpdateEvent e) { // NOSONAR
Object source = e.getSource();
if (source instanceof POSPrinterService14) {
try {
String serviceDescription = ((POSPrinterService14) source).getPhysicalDeviceDescription();
if (serviceDescription.contains("Cash Drawer")) {
decodeCashDrawerStatus(e.getStatus());
} else {
decodePOSPrinterStatus(e.getStatus());
}
} catch (JposException e1) {
// NOSONAR
}
}
if (source instanceof CashDrawer) {
decodeCashDrawerStatus(e.getStatus());
}
if (source instanceof POSPrinter) {
decodePOSPrinterStatus(e.getStatus());
}
}
private void decodePOSPrinterStatus(int status) {
if (statemachine != null) {
switch (status) {
case POSPrinterConst.PTR_SUE_COVER_OPEN:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "coverOpen"));
break;
case POSPrinterConst.PTR_SUE_COVER_OK:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "coverOpen"));
break;
case POSPrinterConst.PTR_SUE_REC_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "receiptEmpty"));
break;
case POSPrinterConst.PTR_SUE_REC_PAPEROK:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "receiptEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "receiptNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_REC_NEAREMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "receiptNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_SLP_EMPTY:
if (slipNotificationsEnabled) {
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipEmpty"));
}
break;
case POSPrinterConst.PTR_SUE_SLP_PAPEROK:
if (slipNotificationsEnabled) {
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "slipEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "slipNearEmpty"));
}
break;
case POSPrinterConst.PTR_SUE_SLP_NEAREMPTY:
if (slipNotificationsEnabled) {
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipNearEmpty"));
}
break;
case POSPrinterConst.PTR_SUE_JRN_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "journalEmpty"));
break;
case POSPrinterConst.PTR_SUE_JRN_PAPEROK:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "journalEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "journalNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_JRN_NEAREMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "journalNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.MESSAGEOPEN, "receiptCartridgeEmpty"));
break;
case POSPrinterConst.PTR_SUE_REC_CARTRIDGE_NEAREMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSOPEN, "receiptCartridgeNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_REC_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "receiptHeadCleaning"));
break;
case POSPrinterConst.PTR_SUE_REC_CARTDRIGE_OK:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.MESSAGECLOSE, "receiptCartridgeEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "receiptHeadCleaning"));
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSCLOSE, "receiptCartridgeNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "slipCartridgeEmpty"));
break;
case POSPrinterConst.PTR_SUE_SLP_CARTRIDGE_NEAREMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSOPEN, "slipCartridgeNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_SLP_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "slipHeadCleaning"));
break;
case POSPrinterConst.PTR_SUE_SLP_CARTDRIGE_OK:
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "slipCartridgeEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "slipHeadCleaning"));
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSCLOSE, "slipCartridgeNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.MESSAGEOPEN, "journalCartridgeEmpty"));
break;
case POSPrinterConst.PTR_SUE_JRN_CARTRIDGE_NEAREMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSOPEN, "journalCartridgeNearEmpty"));
break;
case POSPrinterConst.PTR_SUE_JRN_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSOPEN, "journalHeadCleaning"));
break;
case POSPrinterConst.PTR_SUE_JRN_CARTDRIGE_OK:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.MESSAGECLOSE, "journalCartridgeEmpty"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.STATUSCLOSE, "journalHeadCleaning"));
statemachine.processEvent(statemachine,
new MessageEvent(EventType.STATUSCLOSE, "journalCartridgeNearEmpty"));
break;
default:
break;
}
}
}
private void decodeCashDrawerStatus(int status) {
switch (status) {
case CashDrawerConst.CASH_SUE_DRAWERCLOSED: // Drawer is closed.
if (statemachine != null) {
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGECLOSE, "drawerOpen"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onDrawerClosed"));
}
break;
case CashDrawerConst.CASH_SUE_DRAWEROPEN: // Drawer is opened.
if (statemachine != null) {
statemachine.processEvent(statemachine, new MessageEvent(EventType.MESSAGEOPEN, "drawerOpen"));
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onDrawerOpened"));
}
break;
default:
break;
}
}
/*
* (non-Javadoc)
*
* @see jpos.events.ErrorListener#errorOccurred(jpos.events.ErrorEvent)
*/
@Override
public void errorOccurred(jpos.events.ErrorEvent e) { // NOSONAR
decodePOSPrinterErrorField(e.getErrorCodeExtended());
}
private void decodePOSPrinterErrorField(int error) {
if (statemachine != null) {
switch (error) {
case POSPrinterConst.JPOS_EPTR_COVER_OPEN:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorCoverOpen"));
break;
case POSPrinterConst.JPOS_EPTR_JRN_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_REC_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_SLP_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_BADFORMAT:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorBadFormat"));
break;
case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.ERROR, "errorJournalCartdridgeEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_EMPTY:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipCartdridgeEmpty"));
break;
case POSPrinterConst.JPOS_EPTR_JRN_CARTRIDGE_REMOVED:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.ERROR, "errorJournalCartdridgeRemoved"));
break;
case POSPrinterConst.JPOS_EPTR_REC_CARTRIDGE_REMOVED:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.ERROR, "errorReceiptCartdridgeRemoved"));
break;
case POSPrinterConst.JPOS_EPTR_SLP_CARTRIDGE_REMOVED:
statemachine.processEvent(statemachine,
new MessageEvent(EventType.ERROR, "errorSlipCartdridgeRemoved"));
break;
case POSPrinterConst.JPOS_EPTR_JRN_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorJournalHeadCleaning"));
break;
case POSPrinterConst.JPOS_EPTR_REC_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorReceiptHeadCleaning"));
break;
case POSPrinterConst.JPOS_EPTR_SLP_HEAD_CLEANING:
statemachine.processEvent(statemachine, new MessageEvent(EventType.ERROR, "errorSlipHeadCleaning"));
break;
default:
break;
}
}
}
/*
* (non-Javadoc)
*
* @see
* jpos.events.OutputCompleteListener#outputCompleteOccurred(jpos.events.
* OutputCompleteEvent)
*/
@Override
public void outputCompleteOccurred(OutputCompleteEvent e) {
// nothing to do
}
/**
* Gets the ptip.
*
* @return the ptip
*/
public String getPTIP() {
return ptIP;
}
/**
* Sets the ptip.
*
* @param ptIP
* the new ptip
*/
public void setPTIP(String ptIP) {
if ("null".equals(ptIP))
this.ptIP = "";
else
this.ptIP = ptIP;
}
/**
* Gets the PT port.
*
* @return the PT port
*/
public Integer getPTPort() {
return ptPort;
}
/**
* Sets the PT port.
*
* @param ptPort
* the new PT port
*/
public void setPTPort(Integer ptPort) {
this.ptPort = ptPort;
}
/**
* Sets the payment terminal open.
*
* @param connectionParameters
* the new payment terminal open
*/
public void setPaymentTerminalOpen(String connectionParameters) {
String[] parts = connectionParameters.split("\\|");
setPTIP(parts[0]);
setPTPort(Integer.parseInt(parts[1]));
if (POSServiceBinder.getPosService() != null && !getPTIP().isEmpty() && getPTPort() > 0
&& POSServiceBinder.getPosService().openZVTChannel(getPTIP(), getPTPort())) {
paymentTerminalIsOpen = true;
return;
}
paymentTerminalIsOpen = false;
LOGGER.error("could not open ZVT socket at '{}:{}'", getPTIP(), getPTPort());
}
/**
* Sets the close payment terminal.
*
* @param close
* the new close payment terminal
*/
public void setClosePaymentTerminal(String close) { // NOSONAR
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
POSServiceBinder.getPosService().closeZVTChannel();
}
}
/**
* Sets the payment terminal acknowledge.
*
* @param dummey
* the new payment terminal acknowledge
*/
public void setPaymentTerminalAcknowledge(String dummey) { // NOSONAR
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
POSServiceBinder.getPosService().zvtAcknowledge();
}
}
/**
* Sets the payment terminal balance request.
*
* @param request
* the new payment terminal balance request
*/
public void setPaymentTerminalBalanceRequest(String request) { // NOSONAR
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
// zvt.balanceRequest();
}
}
/**
* Sets the payment terminal prepaid top up.
*
* @param amount
* the new payment terminal prepaid top up
*/
public void setPaymentTerminalPrepaidTopUp(Double amount) { // NOSONAR
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
/**
* zvt.prepaidTopUp(amount);
*/
}
}
/**
* Sets the payment terminal reversal.
*
* @param reversal
* the new payment terminal reversal
*/
public void setPaymentTerminalReversal(String reversal) {
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
String[] parts = reversal.split("\\|");
if (POSServiceBinder.getPosService() != null) {
POSServiceBinder.getPosService().zvtReversal(parts[0], parts[1]);
}
}
}
/**
* Sets the payment terminal registration.
*
* @param registration
* the new payment terminal registration
*/
public void setPaymentTerminalRegistration(String registration) {
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
String[] parts = registration.split("\\|");
if (POSServiceBinder.getPosService() != null) {
POSServiceBinder.getPosService().zvtRegistration(parts[0], parts[1]);
}
}
}
/**
* Sets the payment terminal authorization.
*
* @param amount
* the new payment terminal authorization
*/
public void setPaymentTerminalAuthorization(Double amount) {
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
POSServiceBinder.getPosService().zvtAuthorization(amount);
}
}
/**
* Gets the payment terminal response.
*
* @return the payment terminal response
*/
public String getPaymentTerminalResponse() {
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
return POSServiceBinder.getPosService().getZvtResponse();
}
return null;
}
/**
* Gets the payment terminal transaction.
*
* @return the payment terminal transaction
*/
public IZVTTransactionData getPaymentTerminalTransaction() {
if (POSServiceBinder.getPosService() != null && paymentTerminalIsOpen) {
return POSServiceBinder.getPosService().getZvtTransactionData();
}
return null;
}
/**
* Sets the prints the report.
*
* @param reportParameters
* the new prints the report
*/
public void setPrintReport(String reportParameters, String printService) {
String[] parts = reportParameters.split("\\|");
String reportName = parts[0];
Map<String, String> filterMap = new HashMap<>();
// the filter is optional
if (parts.length > 1) {
String storageKey = parts[1];
String filterName = null;
String filterValue = null;
for (String attribute : statemachine.getStorageAttributes(parts[1])) {
if ("filterName".equals(attribute)) {
filterName = (String) statemachine.getStorage(storageKey, attribute);
} else if ("filterValue".equals(attribute)) {
filterValue = (String) statemachine.getStorage(storageKey, attribute);
}
if (filterName != null && filterValue != null) {
filterMap.put(filterName, filterValue);
filterName = null;
filterValue = null;
}
}
}
if (statemachine.getReportProvider() != null) {
statemachine.getReportProvider().printReportAsPdf(reportName, statemachine.getEclipseContext(), filterMap,
printService);
}
}
public void setSignatureOpen(String dummy) { // NOSONAR
if (isRemote) {
doHttpPost("/signature/openTablet");
if (signatureStatusPoll == null) {
signatureStatusPoll = new Timer(1000, this);
signatureStatusPoll.start();
} else if (!statusPoll.isRunning()) {
signatureStatusPoll.restart();
}
} else if (POSServiceBinder.getSignatureService() != null) {
try {
if (POSServiceBinder.getSignatureService().openTablet(statemachine.getBlobService())) {
statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, "onSignaturePadOpen"));
signaturePadIsOpen = true;
return;
}
} catch (Exception e) {
LOGGER.error("Initialization of signature pad failed - continue without signature pad");
}
signaturePadIsOpen = false;
}
}
public void setSignatureCapture(String dummy) { // NOSONAR
if (isRemote) {
doHttpPost("/signature/captureTablet");
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().captureTablet();
POSServiceBinder.getSignatureService().addListener(this);
}
}
public void setSignatureIdle(String dummy) { // NOSONAR
if (isRemote) {
doHttpPost("/signature/idleTablet");
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().removeListener(this);
POSServiceBinder.getSignatureService().idleTablet();
}
}
public void setSignatureCaptureImage(String imageId) {
if (isRemote) {
byte[] img = statemachine.getBlobService().getByteArrayImage(imageId, 0);
doHttpPost("/signature/captureImage", null, null, img);
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().setCaptureImage(imageId);
}
}
public void setSignatureAddSlide(String slideId) {
if (isRemote) {
byte[] img = statemachine.getBlobService().getByteArrayImage(slideId, 0);
doHttpPost("/signature/addSlide", null, null, img);
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().addSlideTablet(slideId);
}
}
public void setSignatureSlideDelay(Integer delay) {
if (isRemote) {
doHttpPut("/signature/slideDelay", "delay", delay.toString());
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().setSlideDelay(delay);
}
}
public void setSignatureClose(String dummy) { // NOSONAR
if (isRemote) {
doHttpPost("closeTablet");
if (signatureStatusPoll != null && signatureStatusPoll.isRunning()) {
signatureStatusPoll.stop();
}
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().removeListener(this);
POSServiceBinder.getSignatureService().closeTablet();
}
}
public void setSignatureLabel(String labels) {
if (isRemote) {
doHttpPut("/signature/addLabels", "labels", labels);
} else if (POSServiceBinder.getSignatureService() != null && signaturePadIsOpen) {
POSServiceBinder.getSignatureService().setTabletLabel(labels);
}
}
@Override
public void notifyFinished(ISignatureEvent event) {
if (event.getButtonId() == 1) {
penData.clear();
penData.addAll(event.getPenData());
POSServiceBinder.getSignatureService().removeListener(this);
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onSignatureOk"));
POSServiceBinder.getSignatureService().idleTablet();
}
if (event.getButtonId() == 2 && POSServiceBinder.getSignatureService() != null) {
POSServiceBinder.getSignatureService().clearTablet();
}
if (event.getButtonId() == 3) {
penData.clear();
POSServiceBinder.getSignatureService().removeListener(this);
statemachine.processEvent(statemachine, new MessageEvent(EventType.TRIGGER, "onSignatureCancel"));
POSServiceBinder.getSignatureService().idleTablet();
}
}
public List<PenData> getPenData() {
if (isRemote) {
String jsonString = doHttpGet("/signature/penData");
ObjectMapper mapper = new ObjectMapper();
try {
penData = mapper.readValue(jsonString,
CollectionType.construct(List.class, SimpleType.construct(PenData.class)));
} catch (IOException e) {
LOGGER.error("{}", e);
}
}
return penData;
}
public String getSignatureBlob() {
if (isRemote) {
Map<String, String> params = new LinkedHashMap<>();
params.put("width", Integer.toString(statemachine.getSceenWidth()));
params.put("height", Integer.toString(statemachine.getScreenHeight()));
String base64String = doHttpGet("/signature/signature", params);
if (base64String != null) {
byte[] bytes = Base64.decodeBase64(base64String.getBytes());
return statemachine.getBlobService().createBlobMapping(new ByteArrayInputStream(bytes), "",
"image/jpeg");
}
} else if (POSServiceBinder.getSignatureService() != null) {
return POSServiceBinder.getSignatureService().getSignatureBlob(statemachine.getSceenWidth(),
statemachine.getScreenHeight());
}
return null;
}
public void setBeeper(String parameters) {
Integer duration;
Integer frequency;
String[] parts = parameters.split("\\|");
duration = Integer.parseInt(parts[0]);
frequency = Integer.parseInt(parts[1]);
beeper.beep(duration, frequency);
}
public void setPlayer(String name) {
video.setSources(statemachine.getThemeResourceService().getThemeResource(name, ThemeResourceType.VIDEO));
video.play();
}
public void setSound(String name) {
audio.setSources(statemachine.getThemeResourceService().getThemeResource(name, ThemeResourceType.SOUND));
audio.play();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(statusPoll)) {
decodeRemoteState(doHttpGet("/devices/states"));
decodeRemoteError(doHttpGet("/devices/errors"));
}
if (e.getSource().equals(signatureStatusPoll)) {
decodeRemoteSignatureState(doHttpGet("/signature/states"));
}
}
private void decodeRemoteError(String responseString) {
if (responseString != null) {
List<String> errors = Arrays
.asList(responseString.replace("[", "").replace("]", "").replace("\"", "").split(","));
for (String error : errors) {
if (error.startsWith(POS_PRINTER_CONST)) {
decodeRemoteErrorState(error);
}
}
}
}
private void decodeRemoteErrorState(String error) {
for (Field field : posPrinterFields) {
if (field.getName().equals(error.substring(POS_PRINTER_CONST.length() + 1))) {
field.setAccessible(true);
try {
decodePOSPrinterErrorField((int) field.get(error));
} catch (IllegalArgumentException | IllegalAccessException e1) {
LOGGER.error("{}", e1);
}
break;
}
}
}
private void decodeRemoteState(String responseString) {
if (responseString != null) {
List<String> states = Arrays
.asList(responseString.replace("[", "").replace("]", "").replace("\"", "").split(","));
for (String state : states) {
if (state.startsWith(CASH_DRAWER_CONST)) {
decodeCashDrawerStatusField(state);
} else if (state.startsWith(POS_PRINTER_CONST)) {
decodePOSPrinterStatusField(state);
}
}
}
}
private void decodePOSPrinterStatusField(String state) {
for (Field field : posPrinterFields) {
if (field.getName().equals(state.substring(POS_PRINTER_CONST.length() + 1))) {
field.setAccessible(true);
try {
decodePOSPrinterStatus((int) field.get(state));
} catch (IllegalArgumentException | IllegalAccessException e1) {
LOGGER.error("{}", e1);
}
break;
}
}
}
private void decodeCashDrawerStatusField(String state) {
for (Field field : cashDrawerFields) {
field.setAccessible(true);
if (field.getName().equals(state.substring(CASH_DRAWER_CONST.length() + 1))) {
field.setAccessible(true);
try {
decodeCashDrawerStatus((int) field.get(state));
} catch (IllegalArgumentException | IllegalAccessException e1) {
LOGGER.error("{}", e1);
}
break;
}
}
}
private void decodeRemoteSignatureState(String responseString) {
if (responseString != null) {
List<String> states = Arrays
.asList(responseString.replace("[", "").replace("]", "").replace("\"", "").split(","));
for (String state : states) {
if (!state.isEmpty()) {
statemachine.schedule(statemachine, 500, new MessageEvent(EventType.TRIGGER, state));
}
}
}
}
}