EventHandler.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. package com.example;
  2. import java.awt.image.BufferedImage;
  3. import java.io.ByteArrayInputStream;
  4. import java.util.ArrayList;
  5. import java.util.Base64;
  6. import java.util.Collections;
  7. import java.util.List;
  8. import java.util.concurrent.atomic.AtomicInteger;
  9. import javax.imageio.ImageIO;
  10. import org.json.JSONArray;
  11. import org.json.JSONObject;
  12. import com.machinezoo.sourceafis.FingerprintImage;
  13. import com.machinezoo.sourceafis.FingerprintMatcher;
  14. import com.machinezoo.sourceafis.FingerprintTemplate;
  15. import com.fasterxml.jackson.databind.ObjectMapper;
  16. public class EventHandler {
  17. private static final double MATCH_THRESHOLD = 40.0;
  18. public static String handleEvent(String rawMessage) {
  19. try {
  20. // System.err.println(rawMessage); // Log raw message for debugging
  21. JSONObject message = new JSONObject(rawMessage);
  22. // Extract key fields from the JSON payload
  23. String id = message.optString("id", "unknown");
  24. String cmd = message.optString("cmd", "").toLowerCase(); // Normalize command
  25. String imageBase64 = message.optString("fpScan", null); // Base64 fingerprint image
  26. int fingerPosition = message.optInt("fingerPosition", -1); // Optional finger position
  27. JSONArray templateArray = message.optJSONArray("fpTemplateArray"); // Existing templates
  28. JSONObject personInfoPayload = message.optJSONObject("personInfo"); // Optional person metadata This should be PersonFingerprintData
  29. PersonFingerprintData personInfo = new PersonFingerprintData(
  30. personInfoPayload.optString("id"),
  31. personInfoPayload.optString("name"),
  32. personInfoPayload.optString("org"),
  33. personInfoPayload.optString("code"),
  34. new ArrayList<Fingerprint>()
  35. );
  36. FingerprintCompareListItem[] fpTemplateList = new FingerprintCompareListItem[templateArray.length()];
  37. for (int i = 0; i < templateArray.length(); i++) {
  38. JSONObject obj = templateArray.getJSONObject(i);
  39. String name = obj.optString("name");
  40. int fpPosition = obj.optInt("fpPosition");
  41. String fpTemplateString = obj.optString("fpTemplate");
  42. // Decoding it back to fingeprintTemplate so that afis can compare
  43. // byte[] templateBytes = Base64.getDecoder().decode(fpTemplateString);
  44. // FingerprintTemplate fpTemplate = new FingerprintTemplate(templateBytes);
  45. try {
  46. byte[] templateBytes = Base64.getDecoder().decode(fpTemplateString);
  47. System.out.println("Decoded bytes length: " + templateBytes.length);
  48. FingerprintTemplate fpTemplate = new FingerprintTemplate(templateBytes);
  49. System.out.println("Successfully created FingerprintTemplate!");
  50. fpTemplateList[i] = new FingerprintCompareListItem(name, fpPosition, fpTemplate);
  51. } catch (Exception e) {
  52. System.err.println("Error decoding or constructing FingerprintTemplate: " + e.getMessage());
  53. e.printStackTrace();
  54. }
  55. // fpTemplateList[i] = new FingerprintCompareListItem(name, fpPosition, fpTemplate);
  56. };
  57. if (imageBase64 == null || imageBase64.isEmpty()) {
  58. throw new IllegalArgumentException("Missing fpScan (base64 image) data.");
  59. }
  60. // Route command to appropriate handler
  61. switch (cmd) {
  62. case "registration":
  63. return handleRegistration(id, imageBase64, fpTemplateList, personInfo, fingerPosition);
  64. case "verification":
  65. return handleVerification(id, imageBase64, fpTemplateList, personInfo, fingerPosition);
  66. case "qualityassurance":
  67. return handleQualityAssurance(id, imageBase64, fpTemplateList, personInfo, fingerPosition);
  68. default:
  69. // Unknown command fallback
  70. JSONObject unknown = new JSONObject();
  71. unknown.put("id", id);
  72. unknown.put("message", "Unknown command: " + cmd);
  73. return unknown.toString();
  74. }
  75. } catch (Exception e) {
  76. // Generic error response
  77. JSONObject error = new JSONObject();
  78. error.put("message", "Failed to process message: " + e.getMessage());
  79. return error.toString();
  80. }
  81. }
  82. public static String handleRegistration(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) {
  83. try {
  84. // Decode the fingerprint image from base64
  85. Integer edgeScore = null;
  86. byte[] imageBytes = Base64.getDecoder().decode(imageBase64);
  87. BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
  88. if (image == null) {
  89. throw new IllegalArgumentException("Invalid image format.");
  90. }
  91. // Create a FingerprintTemplate from the imageBytes
  92. FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes));
  93. // Logic for transparency goes here
  94. // ... <Edge Number Must be 250 to be considered success>
  95. try (TransparencyContents transparency = new TransparencyContents()) {
  96. FingerprintTemplate probe = new FingerprintTemplate(imageBytes);
  97. transparency.accepts("edge-table");
  98. transparency.take("edge-table", "application/cbor", imageBytes);
  99. edgeScore = transparency.countEdgeNumber();
  100. } catch (Exception e) {
  101. System.out.println("Error: " + e.getMessage());
  102. }
  103. // If no existing templates are provided, register the new one
  104. if (templateArray == null || templateArray.length <= 0) {
  105. // Register this new template
  106. String response = buildJavaResponse(id, "Registration", "Success", "No existing templates. Registered as new.", probeTemplate, 100.0, edgeScore, personInfo, fingerPosition);
  107. return response.toString(); // Return the response as a JSON string
  108. }
  109. // Compare with existing templates
  110. double bestScore = 0;
  111. String matchedPerson = null;
  112. for (FingerprintCompareListItem entry : templateArray) {
  113. String personName = entry.getName();
  114. FingerprintTemplate candidate = entry.getFingerprint();
  115. double score = new FingerprintMatcher(probeTemplate).match(candidate);
  116. if (score > bestScore) {
  117. bestScore = score;
  118. matchedPerson = personName;
  119. }
  120. }
  121. // Return response based on score
  122. if (bestScore >= MATCH_THRESHOLD) {
  123. // Match found
  124. return buildJavaResponse(id, "Registration", "Registered", "Existing Fingerprint template found for " + matchedPerson + "!", probeTemplate, bestScore, edgeScore, personInfo, fingerPosition).toString();
  125. } else {
  126. // Register new template
  127. String response = buildJavaResponse(id, "Registration", "Success", "New fingerprint template constructed.", probeTemplate, 100.0, edgeScore, personInfo, fingerPosition);
  128. return response.toString();
  129. }
  130. } catch (Exception e) {
  131. // Handle errors during registration
  132. String errorResponse = buildJavaResponse(id, "Registration", "Failed", "Template Construction Failed: " + e.getMessage(), null, 0.0, null, personInfo, fingerPosition);
  133. return errorResponse.toString();
  134. }
  135. }
  136. public static String handleVerification(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) {
  137. try {
  138. // Decode the fingerprint image from base64
  139. Integer edgeScore = null;
  140. byte[] imageBytes = Base64.getDecoder().decode(imageBase64);
  141. BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
  142. if (image == null) {
  143. throw new IllegalArgumentException("Invalid image format.");
  144. }
  145. // Create a FingerprintTemplate from the imageBytes
  146. FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes));
  147. // Logic for transparency goes here
  148. // ... <Edge Number Must be 250 to be considered success>
  149. try (TransparencyContents transparency = new TransparencyContents()) {
  150. FingerprintTemplate probe = new FingerprintTemplate(imageBytes);
  151. transparency.accepts("edge-table");
  152. transparency.take("edge-table", "application/cbor", imageBytes);
  153. edgeScore = transparency.countEdgeNumber();
  154. } catch (Exception e) {
  155. System.out.println("Error: " + e.getMessage());
  156. }
  157. double bestScore = 0;
  158. int matchedFingerprintPosition = 0; // just put 0 as default value for now
  159. String matchedPerson = null;
  160. FingerprintTemplate matchedFingerprintTemplate = null;
  161. for (int i = 0; i < templateArray.length; i++) {
  162. FingerprintCompareListItem entry = templateArray[i];
  163. String personName = entry.getName();
  164. int fpPosition = entry.getFingerPosition();
  165. FingerprintTemplate candidateTemplate = entry.getFingerprint();
  166. // Maybe there's no need to check? will see about it later
  167. if (candidateTemplate == null) {
  168. continue;
  169. }
  170. double score = new FingerprintMatcher(probeTemplate).match(candidateTemplate);
  171. if (score > bestScore) {
  172. bestScore = score;
  173. matchedFingerprintPosition = fpPosition;
  174. matchedPerson = personName;
  175. matchedFingerprintTemplate = candidateTemplate;
  176. }
  177. }
  178. if (bestScore >= MATCH_THRESHOLD) {
  179. // Match found
  180. Fingerprint matchedFingerprint = new Fingerprint(matchedPerson, matchedFingerprintPosition, Base64.getEncoder().encodeToString(matchedFingerprintTemplate.toByteArray()));
  181. List<Fingerprint> fingerprints = Collections.singletonList(matchedFingerprint);
  182. PersonFingerprintData matchedData = new PersonFingerprintData(
  183. personInfo.getId(),
  184. matchedPerson,
  185. personInfo.getOrg(),
  186. personInfo.getCode(),
  187. fingerprints
  188. );
  189. // JavaResponse response = new JavaResponse(id, "Verification", "Match found.", matchedData, bestScore);
  190. String response = buildJavaResponse(id, "Verification", "Registered", "Match found.", matchedFingerprintTemplate, bestScore, null, matchedData, matchedFingerprintPosition);
  191. return response.toString();
  192. } else {
  193. // No match
  194. PersonFingerprintData noMatchData = new PersonFingerprintData(
  195. personInfo.getId(),
  196. personInfo.getName(),
  197. personInfo.getOrg(),
  198. personInfo.getCode(),
  199. new ArrayList<Fingerprint>()
  200. );
  201. String response = buildJavaResponse(id, "Verification", "Not Registered", "No Match found.", probeTemplate, bestScore, null, noMatchData, fingerPosition); // defaul value
  202. return response.toString();
  203. }
  204. } catch (Exception e) {
  205. PersonFingerprintData errorData = new PersonFingerprintData(
  206. personInfo.getId(),
  207. personInfo.getName(),
  208. personInfo.getOrg(),
  209. personInfo.getCode(),
  210. new ArrayList<Fingerprint>()
  211. );
  212. String errorResponse = buildJavaResponse(id, "Verification", "Failed", "No Match found.", null, 0, null, personInfo, fingerPosition); // defaul value
  213. return errorResponse.toString();
  214. }
  215. }
  216. public static String handleQualityAssurance(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) {
  217. try {
  218. Integer edgeScore = null;
  219. double bestScore = 0;
  220. // Decode the fingerprint image from base64
  221. byte[] imageBytes = Base64.getDecoder().decode(imageBase64);
  222. BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
  223. if (image == null) {
  224. throw new IllegalArgumentException("Invalid image format.");
  225. }
  226. // Create a FingerprintTemplate from the imageBytes
  227. FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes));
  228. // Logic for transparency goes here
  229. // ... <Edge Number Must be 250 to be considered success>
  230. try (TransparencyContents transparency = new TransparencyContents()) {
  231. transparency.accepts("edge-table");
  232. transparency.take("edge-table", "application/cbor", imageBytes);
  233. edgeScore = transparency.countEdgeNumber();
  234. // Addition features to verify against existing fingerprint data
  235. String response = buildJavaResponse(id, "QualityAssurance", "Success", "Edge score result: " + bestScore, probeTemplate, bestScore, edgeScore, personInfo, fingerPosition); // defaul value
  236. return response.toString();
  237. } catch (Exception e) {
  238. System.out.println("Error: " + e.getMessage());
  239. String response = buildJavaResponse(id, "QualityAssurance", "Failed", "Edge score result: " + bestScore, probeTemplate, bestScore, edgeScore, personInfo, fingerPosition); // defaul value
  240. return response.toString();
  241. }
  242. } catch (Exception e) {
  243. // Handle errors during checking
  244. String errorResponse = buildJavaResponse(id, "QualityAssurance", "Failed", "Unable to produce Edge score... " + e.getMessage(), null, 0.0, null, personInfo, fingerPosition);
  245. return errorResponse.toString();
  246. }
  247. }
  248. public static String buildJavaResponse(
  249. String id,
  250. String operation,
  251. String status,
  252. String message,
  253. FingerprintTemplate fingerprintTemplate,
  254. double score,
  255. Integer edgeScore,
  256. PersonFingerprintData personInfo,
  257. int fingerPosition) {
  258. // Convert the FingerprintTemplate to a base64-encoded string (assuming `FingerprintTemplate` has a way to do this)
  259. String templateBase64 = (fingerprintTemplate != null) ? Base64.getEncoder().encodeToString(fingerprintTemplate.toByteArray()) : "";
  260. // Construct the fingerprint data (if there is a fingerprint template)
  261. Fingerprint fingerprint = new Fingerprint(personInfo.getName(), fingerPosition, templateBase64);
  262. // Add the fingerprint to the personInfo
  263. personInfo.addFingerprint(fingerprint);
  264. // Build the JavaResponse
  265. JavaResponse javaResponse = new JavaResponse(id, operation, status, message, personInfo, score, edgeScore);
  266. // System.out.println("Java Response: " + javaResponse.toString());
  267. // Serialize JavaResponse to JSON string using Jackson
  268. try {
  269. ObjectMapper mapper = new ObjectMapper();
  270. String jsonResponse = mapper.writeValueAsString(javaResponse);
  271. return jsonResponse;
  272. } catch (Exception e) {
  273. // Handle exception if serialization fails
  274. e.printStackTrace();
  275. return "{\"error\":\"Failed to serialize response\"}";
  276. }
  277. }
  278. }