2323import jpos .config .*;
2424
2525import javax .swing .*;
26+ import java .awt .image .SampleModel ;
2627import java .util .*;
2728
2829/**
3839 * <li>MaximumPINLength: Can be set to one of "1", "2", "3", "4", "5", "6", "7", "8" or "9". Default is "4".</li>
3940 * <li>MinimumPINLength: Can be set to the same values as MaximumPINLength or to "0". Default is "4".
4041 * MaximumPINLength must be greater or equal to MinimumPINLength.</li>
41- * <li>AllowAlwaysSetProperties: Can be TRUE or FALSE. Default is FALSE. If TRUE, the service will throw an exception
42- * if the application tries to change a writable property while the device has not been claimed.</li>
4342 * </ul>
4443 * If CapDisplay will be set to PPAD_DISP_UNRESTRICTED, CapLanguage will be set to PPAD_LANG_NONE and any configuration
4544 * option for CapLanguage will be ignored.
@@ -78,7 +77,7 @@ protected PINPadDevice(String id) throws JposException {
7877 "" ,
7978 "Enter PIN" , // PPAD_MSG_ENTERPIN
8079 "Please Wait" , // PPAD_MSG_PLEASEWAIT
81- "" ,
80+ "Enter Valid PIN" , // PPAD_MSG_ENTERVALIDPIN
8281 "Retries Exceeded" , // PPAD_MSG_RETRIESEXCEEDED
8382 "Approved" , // PPAD_MSG_APPROVED
8483 "Declined" , // PPAD_MSG_DECLINED
@@ -95,7 +94,6 @@ protected PINPadDevice(String id) throws JposException {
9594 private SynchronizedMessageBox TheBox = new SynchronizedMessageBox ();
9695 private Thread TheThread = null ;
9796 private Boolean ToBeFinished ;
98- private Map <PINPadProperties , Boolean > UsePrompt = new HashMap <>();
9997
10098 private Map <String , String []> LastEntries = new HashMap <>();
10199
@@ -124,7 +122,8 @@ else if (capability[PropName].equals("MinimumPINLength"))
124122 }
125123
126124 @ Override
127- public void changeDefaults (PINPadProperties props ) {
125+ public void changeDefaults (PINPadProperties p ) {
126+ SampleProperties props = (SampleProperties ) p ;
128127 props .MinimumPINLength = props .MaximumPINLength = 4 ;
129128 for (String capa : LastEntries .keySet ()) {
130129 try {
@@ -140,14 +139,19 @@ else if (attr[0].equals(PropTypeInt))
140139 } catch (Exception ignored ) {}
141140 }
142141 if (props .CapDisplay == PINPadConst .PPAD_DISP_NONE || props .CapDisplay == PINPadConst .PPAD_DISP_UNRESTRICTED ) {
143- UsePrompt . put ( props , false ) ;
142+ props . UsePrompt = false ;
144143 props .CapLanguage = PINPadConst .PPAD_LANG_NONE ;
145144 } else {
146- UsePrompt .put (props , true );
147- props .Prompt = PINPadConst .PPAD_MSG_NOTREADY ;
145+ props .UsePrompt = true ;
148146 props .AvailableLanguagesList = props .CapLanguage == PINPadConst .PPAD_LANG_ONE ? "EN,US" : "EN,US;EN,UK" ;
149147 props .PromptLanguage = "EN,US" ;
150- props .AvailablePromptsList = props .CapDisplay == PINPadConst .PPAD_DISP_PINRESTRICTED ? "2,4,5,6,7,9,10,11,12" : "1,2,4,5,6,7,9,10,11,12" ;
148+ if (props .CapDisplay == PINPadConst .PPAD_DISP_PINRESTRICTED ) {
149+ props .Prompt = PINPadConst .PPAD_MSG_ENTERPIN ;
150+ props .AvailablePromptsList = "1,3,7" ;
151+ } else {
152+ props .Prompt = PINPadConst .PPAD_MSG_NOTREADY ;
153+ props .AvailablePromptsList = "1,2,3,4,5,6,7,9,10,11,12" ;
154+ }
151155 }
152156 props .SupportedPINPadSystems = "SAMPLE" ;
153157 }
@@ -201,37 +205,25 @@ private int updateShift(SampleProperties props, int shift) {
201205 }
202206
203207 private void pinReadyWithErrorSendDataOrErrorEvent (String [] options , SampleProperties props , boolean noprompt , int result ) {
204- try {
208+ if (noprompt )
209+ Message = Prompts [PINPadConst .PPAD_MSG_DECLINED ];
210+ if (options [result ].equals ("Error" )) {
211+ props .checkResult (null , new PINPadErrorEvent (props .EventSource , JposConst .JPOS_E_FAILURE , 0 , "An error occurred" ));
212+ } else if (options [result ].equals ("OK" )) {
213+ props .checkResult (null , new PINPadErrorEvent (props .EventSource , JposConst .JPOS_E_ILLEGAL , 0 , "Invalid PIN" ));
214+ } else {
205215 if (noprompt )
206- Message = Prompts [PINPadConst .PPAD_MSG_DECLINED ];
207- if (options [result ].equals ("Error" )) {
208- handleEvent (new JposErrorEvent (props .EventSource , JposConst .JPOS_E_FAILURE , 0 , JposConst .JPOS_EL_INPUT , "An error occurred" ));
209- } else if (options [result ].equals ("OK" )) {
210- handleEvent (new JposErrorEvent (props .EventSource , JposConst .JPOS_E_ILLEGAL , 0 , JposConst .JPOS_EL_INPUT , "Invalid PIN" ));
211- } else {
212- if (noprompt )
213- Message = Prompts [PINPadConst .PPAD_MSG_CANCELED ];
214- handleEvent (new PINPadDataEvent (props .EventSource , options [result ].equals ("Cancel" ) ?
215- PINPadConst .PPAD_CANCEL : PINPadDataEvent .PPAD_TIMEOUT , "" , "" ));
216- }
217- } catch (Exception e ) {
218- e .printStackTrace ();
216+ Message = Prompts [PINPadConst .PPAD_MSG_CANCELED ];
217+ props .checkResult (new PINPadDataEvent (props .EventSource , options [result ].equals ("Cancel" ) ?
218+ PINPadConst .PPAD_CANCEL : PINPadDataEvent .PPAD_TIMEOUT , "" , "" ), null );
219219 }
220- props .PINEntryEnabled = false ;
221- props .EventSource .logSet ("PINEntryEnabled" );
222220 }
223221
224222 private void pinReadySendDataEvent (SampleProperties props , String pin , int shift , boolean noprompt ) {
225223 String encryptedpin = encryptPin (pin , shift );
226- try {
227- if (noprompt )
228- Message = Prompts [PINPadConst .PPAD_MSG_APPROVED ];
229- handleEvent (new PINPadDataEvent (props .EventSource , PINPadConst .PPAD_SUCCESS , encryptedpin .substring (0 , 2 ), encryptedpin .substring (2 )));
230- } catch (Exception e ) {
231- e .printStackTrace ();
232- }
233- props .PINEntryEnabled = false ;
234- props .EventSource .logSet ("PINEntryEnabled" );
224+ if (noprompt )
225+ Message = Prompts [PINPadConst .PPAD_MSG_APPROVED ];
226+ props .checkResult (new PINPadDataEvent (props .EventSource , PINPadConst .PPAD_SUCCESS , encryptedpin .substring (0 , 2 ), encryptedpin .substring (2 )), null );
235227 }
236228
237229 private String encryptPin (String pin , int key ) {
@@ -248,6 +240,25 @@ public PINPadProperties getPINPadProperties(int index) {
248240 }
249241
250242 private class SampleProperties extends PINPadProperties {
243+ void checkResult (PINPadDataEvent dev , PINPadErrorEvent eev ) {
244+ synchronized (getDataEventList ()) {
245+ if (PINEntryEnabled ) {
246+ try {
247+ if (dev == null ) {
248+ handleEvent (eev );
249+ } else
250+ handleEvent (dev );
251+ } catch (JposException e ) {
252+ e .printStackTrace ();
253+ }
254+ PINEntryEnabled = false ;
255+ EventSource .logSet ("PINEntryEnabled" );
256+ }
257+ }
258+ }
259+
260+ boolean UsePrompt ;
261+
251262 protected SampleProperties () {
252263 super (0 );
253264 }
@@ -268,7 +279,7 @@ public void open() throws JposException {
268279 if (TheThread == null ) {
269280 TheThread = new Thread (PINPadDevice .this );
270281 TheThread .setName ("PINPadSampleThread" );
271- Message = UsePrompt . get ( this ) ? Prompts [Prompt ] : Prompts [PINPadConst .PPAD_MSG_NOTREADY ];
282+ Message = UsePrompt ? Prompts [Prompt ] : Prompts [PINPadConst .PPAD_MSG_NOTREADY ];
272283 ToBeFinished = false ;
273284 TheThread .start ();
274285 }
@@ -296,16 +307,19 @@ public void close() throws JposException {
296307 @ Override
297308 public void claim (int timeout ) throws JposException {
298309 super .claim (timeout );
299- int prompt = UsePrompt .get (this ) ? Prompt : PINPadConst .PPAD_MSG_IDLE ;
310+ ((PINPadService )EventSource ).resetEFTTransaction ();
311+ int prompt = UsePrompt ? Prompt : PINPadConst .PPAD_MSG_IDLE ;
300312 if (!Message .equals (Prompts [prompt ])) {
301- setPrompt (prompt );
313+ super .setPrompt (prompt );
314+ Message = Prompts [prompt ];
302315 }
316+ TheBox .abortDialog ();
303317 }
304318
305319 @ Override
306320 public void release () throws JposException {
307321 super .release ();
308- if (!UsePrompt . get ( this ) ) {
322+ if (!UsePrompt ) {
309323 setPrompt (PINPadConst .PPAD_MSG_NOTREADY );
310324 }
311325 }
@@ -314,7 +328,7 @@ public void release() throws JposException {
314328 public void beginEFTTransaction (String system , int host ) throws JposException {
315329 super .beginEFTTransaction (system , host );
316330 synchronized (PINPadDevice .this ) {
317- if (!UsePrompt . get ( this ) ) {
331+ if (!UsePrompt ) {
318332 Message = Prompts [PINPadConst .PPAD_MSG_PLEASEWAIT ];
319333 TheBox .abortDialog ();
320334 }
@@ -324,19 +338,31 @@ public void beginEFTTransaction(String system, int host) throws JposException {
324338 @ Override
325339 public void endEFTTransaction (int code ) throws JposException {
326340 synchronized (PINPadDevice .this ) {
327- if (!UsePrompt .get (this )) {
341+ boolean abortDialog = false ;
342+ if (PINEntryEnabled ) {
343+ check (code == PINPadConst .PPAD_EFT_NORMAL , JposConst .JPOS_E_ILLEGAL , "Normal transaction end invalid during PIN entry" );
344+ abortDialog = true ;
345+ }
346+ if (!UsePrompt ) {
328347 Message = Prompts [PINPadConst .PPAD_MSG_IDLE ];
329- TheBox . abortDialog () ;
348+ abortDialog = true ;
330349 }
350+ if (abortDialog )
351+ TheBox .abortDialog ();
331352 }
332353 super .endEFTTransaction (code );
333354 }
334355
335356 @ Override
336357 public void enablePINEntry () throws JposException {
337358 synchronized (PINPadDevice .this ) {
338- if (!UsePrompt .get (this ) || CapDisplay == PINPadConst .PPAD_DISP_PINRESTRICTED )
339- Message = Prompts [PINPadConst .PPAD_MSG_ENTERPIN ];
359+ if (UsePrompt ) {
360+ if (Prompt != PINPadConst .PPAD_MSG_ENTERPIN ) {
361+ Prompt = PINPadConst .PPAD_MSG_ENTERPIN ;
362+ EventSource .logSet ("Prompt" );
363+ }
364+ }
365+ Message = Prompts [PINPadConst .PPAD_MSG_ENTERPIN ];
340366 TheBox .abortDialog ();
341367 }
342368 super .enablePINEntry ();
0 commit comments