package com.fancl.iloyalty.service.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import android.content.DialogInterface; import com.fancl.iloyalty.AndroidProjectApplication; import com.fancl.iloyalty.ApiConstant; import com.fancl.iloyalty.R; import com.fancl.iloyalty.factory.CustomServiceFactory; import com.fancl.iloyalty.factory.GeneralServiceFactory; import com.fancl.iloyalty.parser.FanclGeneralParser; import com.fancl.iloyalty.service.ILoyaltyTCPSocketService; import com.fancl.iloyalty.service.callback.ILoyaltyTCPSocketServiceCallback; import com.fancl.iloyalty.util.Command; import com.fancl.iloyalty.util.CommandPackage; import com.fancl.iloyalty.util.LogController; import com.fancl.iloyalty.util.XMLUtil; public class ILoyaltyTCPSocketServiceImpl implements ILoyaltyTCPSocketService { private Socket socket; private Timer timer; private InputStream inputStream; private OutputStream outputStream; private boolean isRunning = false; private List<ILoyaltyTCPSocketServiceCallback> callbackList; public ILoyaltyTCPSocketServiceImpl() { callbackList = new ArrayList<ILoyaltyTCPSocketServiceCallback>(); } @Override public void socketConnectRequest() { // TODO Auto-generated method stub try { if (socket == null) { socket = new Socket(ApiConstant.SOCKET_DOMAIN_NAME, ApiConstant.SOCKET_PORT); socket.setReceiveBufferSize(1024); this.inputStream = this.socket.getInputStream(); this.outputStream = this.socket.getOutputStream(); } String memberId = xmlWithTagAndElement("membershipId", CustomServiceFactory.getAccountService().currentMemberId()); String xml = createXMLContent(memberId); try { CommandPackage commandPackage = new CommandPackage(Command.CS_CONNECT_REQUEST, xml); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } isRunning = true; addAcknowkedgeTimer(); readData(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void socketDisconnectRequest() { // TODO Auto-generated method stub if (timer != null) { timer.cancel(); timer.purge(); timer = null; } if (socket == null) { return; } String memberId = xmlWithTagAndElement("membershipId", CustomServiceFactory.getAccountService().currentMemberId()); String xml = createXMLContent(memberId); try { CommandPackage commandPackage = new CommandPackage(Command.CS_DISCONNECT_REQUEST, xml); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } isRunning = false; try { socket.close(); socket = null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void socketAcknowledgeRequest() { // TODO Auto-generated method stub if (!isRunning) { return; } try { CommandPackage commandPackage = new CommandPackage(Command.CS_ACK_REQUEST, null); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void socketTillIdRequest(String aTillId) { // TODO Auto-generated method stub String memberId = xmlWithTagAndElement("membershipId", CustomServiceFactory.getAccountService().currentMemberId()); String tillId = xmlWithTagAndElement("tillId", aTillId); String xmlContent = memberId + tillId; String xml = createXMLContent(xmlContent); try { CommandPackage commandPackage = new CommandPackage(Command.CS_TILL_ID_REQUEST, xml); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void socketPurchaseAcknowledgementResponse() { // TODO Auto-generated method stub try { CommandPackage commandPackage = new CommandPackage(Command.SC_PURCHASE_ACKNOWLEDGE_REQUEST, null); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void socketCancelPurchaseRequest() { // TODO Auto-generated method stub String memberId = xmlWithTagAndElement("membershipId", CustomServiceFactory.getAccountService().currentMemberId()); String xml = createXMLContent(memberId); try { CommandPackage commandPackage = new CommandPackage(Command.CS_CANCEL_PURCHASE_ACKNOWLEDGE_REQUEST, xml); this.sendData(commandPackage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void addAcknowkedgeTimer() { // TODO Auto-generated method stub if (timer != null) { timer.cancel(); timer.purge(); timer = null; } TimerTask timerTask = new TimerTask() { @Override public void run() { // TODO Auto-generated method stub socketAcknowledgeRequest(); } }; timer = new Timer(); timer.schedule(timerTask, 500); // timer.scheduleAtFixedRate(timerTask, 500, 10000); } @Override public void serverResponseWithCommand(String command, Object xmlData) { // TODO Auto-generated method stub } @Override public void serverNoResponse() { // TODO Auto-generated method stub GeneralServiceFactory.getAlertDialogService().makeNativeDialog(AndroidProjectApplication.application.getFrontActivity(), "", "Server No Response (Socket)", AndroidProjectApplication.application.getString(R.string.ok_btn_title), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { dialog.cancel(); } }, "", null, false, false); } // For command with XML private String createXMLContent(String xmlContent) { String xmlString = xmlStart(); xmlString = xmlString + xmlContent; xmlString = xmlEndWithXMLString(xmlString); LogController.log("xmlString: " + xmlString); return xmlString; } private void sendData(CommandPackage commandPackage) throws Exception { this.outputStream.write(commandPackage.getFullByteArray()); } public void readData() { while (isRunning) { try { if (this.inputStream.available() > 0) { LogController.log("readData"); byte[] tmpByte = null; tmpByte = toByteArray(inputStream); if (tmpByte.length > 4) { LogController.log("tmpByte.length > 4"); // LogController.log("tmpByte.length > 4 - readData inputStream-->byte2:"+ tmpByte1); int dataLength = tmpByte.length; LogController.log("tmpByte.length > 4 - readData dataLength int: " + dataLength); byte[] packageLengthInByte = new byte[CommandPackage.PACKAGE_LENGTH_SIZE]; System.arraycopy(tmpByte, 0, packageLengthInByte, 0, CommandPackage.PACKAGE_LENGTH_SIZE); // inputStream.read(packageLengthInByte); int packageLength = packageLengthInByte.length; LogController.log("tmpByte.length > 4 - readData packageLength int: " + packageLength); byte[] commandInByte = new byte[CommandPackage.COMMAND_SIZE]; System.arraycopy(tmpByte, CommandPackage.PACKAGE_LENGTH_SIZE, commandInByte, 0, CommandPackage.COMMAND_SIZE); // inputStream.read(commandInByte); LogController.log("tmpByte.length > 4 - readData commandString: " + CommandPackage.readCommandByte(commandInByte)); byte[] contentInByte = new byte[tmpByte.length - CommandPackage.COMMAND_SIZE - CommandPackage.PACKAGE_LENGTH_SIZE]; System.arraycopy(tmpByte, (CommandPackage.COMMAND_SIZE + CommandPackage.PACKAGE_LENGTH_SIZE), contentInByte, 0, (tmpByte.length - CommandPackage.COMMAND_SIZE - CommandPackage.PACKAGE_LENGTH_SIZE)); // inputStream.read(contentInByte); LogController.log("tmpByte.length > 4 - readData contentString: " + CommandPackage.convertContent2Readable(contentInByte)); this.processDate(packageLengthInByte, commandInByte, contentInByte); } else { } } } catch (Exception e) { e.printStackTrace(); } } try { this.inputStream.close(); this.outputStream.close(); } catch (Exception e) { e.printStackTrace(); } } public static byte[] toByteArray(InputStream input) throws IOException { byte[] buffer = new byte[1024]; // LogController.log("readData toByteArray:111111"); int bytesRead; ByteArrayOutputStream output = new ByteArrayOutputStream(); // LogController.log("readData toByteArray:2222222"); // while ((bytesRead = input.read(buffer)) != -1) // { output.write(buffer, 0, input.read(buffer)); // LogController.log("readData toByteArray:3333333"); // LogController.log("readData toByteArray:4444:"+(bytesRead = input.read(buffer))); // } // LogController.log("readData output.toByteArray():"+ output.toByteArray()); return output.toByteArray(); } public static byte[] stream2Bytes(InputStream ins) { byte [] availableBytes = new byte [0]; try { byte [] buffer = new byte[1024]; ByteArrayOutputStream outs = new ByteArrayOutputStream(); int read = 0; while ((read = ins.read(buffer)) != -1 ) { outs.write(buffer, 0, read); LogController.log("readData toByteArray:4444:"+ (read = ins.read(buffer))); } ins.close(); outs.close(); availableBytes = outs.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return availableBytes; } public static byte[] toByteArrayUsingJava(InputStream is) throws IOException{ ByteArrayOutputStream baos = new ByteArrayOutputStream(); int reads = is.read(); while(reads != -1){ baos.write(reads); reads = is.read(); LogController.log("readData toByteArray:4444:"+ reads); } return baos.toByteArray(); } private void processDate(byte[] packageLengthInByte, byte[] commandInByte, byte[] contentInByte) throws Exception { CommandPackage commandPackage = new CommandPackage(packageLengthInByte, commandInByte, contentInByte); System.out.println("from Server = commandString:" + commandPackage.getCommandString() + ",content: " + commandPackage.getContent() +",contentInByte:"+ contentInByte); if(commandPackage.getCommandString().equals(ApiConstant.COMMAND_PURHCASE_ACK_RESPONSE)){ if(contentInByte != null){ InputStream myInputStream = new ByteArrayInputStream(contentInByte); LogController.log("myInputStream:" + myInputStream); FanclGeneralParser fanclGeneralparser = new FanclGeneralParser(); Boolean posStatus = fanclGeneralparser.checkPosStatus(XMLUtil.toDocument(myInputStream)); LogController.log("posStatus:" + posStatus); if(posStatus){ for(ILoyaltyTCPSocketServiceCallback iLoyaltyTCPSocketServiceCallback : callbackList) { if(iLoyaltyTCPSocketServiceCallback != null) { iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketResult(commandPackage.getContent()); iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketIsSuccess(true); } } }else{ for(ILoyaltyTCPSocketServiceCallback iLoyaltyTCPSocketServiceCallback : callbackList) { if(iLoyaltyTCPSocketServiceCallback != null) { iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketResult(commandPackage.getContent()); iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketIsSuccess(false); } } } }else{ for(ILoyaltyTCPSocketServiceCallback iLoyaltyTCPSocketServiceCallback : callbackList) { if(iLoyaltyTCPSocketServiceCallback != null) { iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketResult(commandPackage.getContent()); iLoyaltyTCPSocketServiceCallback.didReceiveTCPSocketIsSuccess(false); } } } } } // CreateXML private String xmlStart() { String xmlHeader = "<?xml version =\"1.0\" encoding = \"UTF-8\"?><iloyalty>"; return xmlHeader; } private String xmlWithTagAndElement(String tag, String element) { String contentString = "<" + tag + ">" + element + "</" + tag + ">"; return contentString; } private String xmlEndWithXMLString(String xmlString) { String returnString = xmlString + "</iloyalty>"; LogController.log(returnString); return returnString; } @Override public void addCallbackListener( ILoyaltyTCPSocketServiceCallback iLoyaltyTCPSocketServiceCallback) { // TODO Auto-generated method stub if(iLoyaltyTCPSocketServiceCallback != null) { callbackList.add(iLoyaltyTCPSocketServiceCallback); } } @Override public void removeCallbackListener( ILoyaltyTCPSocketServiceCallback iLoyaltyTCPSocketServiceCallback) { // TODO Auto-generated method stub if(iLoyaltyTCPSocketServiceCallback != null) { int i; ILoyaltyTCPSocketServiceCallback callbackInList; for(i = 0 ; i < callbackList.size() ; i++) { callbackInList = callbackList.get(i); if(callbackInList != null) { if(callbackInList.equals(iLoyaltyTCPSocketServiceCallback)) { callbackList.remove(i); i--; } } } } } }