package com.example; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import javax.imageio.ImageIO; import org.json.JSONArray; import org.json.JSONObject; import com.machinezoo.sourceafis.FingerprintImage; import com.machinezoo.sourceafis.FingerprintMatcher; import com.machinezoo.sourceafis.FingerprintTemplate; import com.fasterxml.jackson.databind.ObjectMapper; public class EventHandler { private static final double MATCH_THRESHOLD = 40.0; public static String handleEvent(String rawMessage) { try { // System.err.println(rawMessage); // Log raw message for debugging JSONObject message = new JSONObject(rawMessage); // Extract key fields from the JSON payload String id = message.optString("id", "unknown"); String cmd = message.optString("cmd", "").toLowerCase(); // Normalize command String imageBase64 = message.optString("fpScan", null); // Base64 fingerprint image int fingerPosition = message.optInt("fingerPosition", -1); // Optional finger position JSONArray templateArray = message.optJSONArray("fpTemplateArray"); // Existing templates JSONObject personInfoPayload = message.optJSONObject("personInfo"); // Optional person metadata This should be PersonFingerprintData PersonFingerprintData personInfo = new PersonFingerprintData( personInfoPayload.optString("id"), personInfoPayload.optString("name"), personInfoPayload.optString("org"), personInfoPayload.optString("code"), new ArrayList() ); FingerprintCompareListItem[] fpTemplateList = new FingerprintCompareListItem[templateArray.length()]; for (int i = 0; i < templateArray.length(); i++) { JSONObject obj = templateArray.getJSONObject(i); String name = obj.optString("name"); int fpPosition = obj.optInt("fpPosition"); String fpTemplateString = obj.optString("fpTemplate"); // Decoding it back to fingeprintTemplate so that afis can compare // byte[] templateBytes = Base64.getDecoder().decode(fpTemplateString); // FingerprintTemplate fpTemplate = new FingerprintTemplate(templateBytes); try { byte[] templateBytes = Base64.getDecoder().decode(fpTemplateString); System.out.println("Decoded bytes length: " + templateBytes.length); FingerprintTemplate fpTemplate = new FingerprintTemplate(templateBytes); System.out.println("Successfully created FingerprintTemplate!"); fpTemplateList[i] = new FingerprintCompareListItem(name, fpPosition, fpTemplate); } catch (Exception e) { System.err.println("Error decoding or constructing FingerprintTemplate: " + e.getMessage()); e.printStackTrace(); } // fpTemplateList[i] = new FingerprintCompareListItem(name, fpPosition, fpTemplate); }; if (imageBase64 == null || imageBase64.isEmpty()) { throw new IllegalArgumentException("Missing fpScan (base64 image) data."); } // Route command to appropriate handler switch (cmd) { case "registration": return handleRegistration(id, imageBase64, fpTemplateList, personInfo, fingerPosition); case "verification": return handleVerification(id, imageBase64, fpTemplateList, personInfo, fingerPosition); case "qualityassurance": return handleQualityAssurance(id, imageBase64, fpTemplateList, personInfo, fingerPosition); default: // Unknown command fallback JSONObject unknown = new JSONObject(); unknown.put("id", id); unknown.put("message", "Unknown command: " + cmd); return unknown.toString(); } } catch (Exception e) { // Generic error response JSONObject error = new JSONObject(); error.put("message", "Failed to process message: " + e.getMessage()); return error.toString(); } } public static String handleRegistration(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) { try { // Decode the fingerprint image from base64 Integer edgeScore = null; byte[] imageBytes = Base64.getDecoder().decode(imageBase64); BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); if (image == null) { throw new IllegalArgumentException("Invalid image format."); } // Create a FingerprintTemplate from the imageBytes FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes)); // Logic for transparency goes here // ... try (TransparencyContents transparency = new TransparencyContents()) { FingerprintTemplate probe = new FingerprintTemplate(imageBytes); transparency.accepts("edge-table"); transparency.take("edge-table", "application/cbor", imageBytes); edgeScore = transparency.countEdgeNumber(); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } // If no existing templates are provided, register the new one if (templateArray == null || templateArray.length <= 0) { // Register this new template String response = buildJavaResponse(id, "Registration", "Success", "No existing templates. Registered as new.", probeTemplate, 100.0, edgeScore, personInfo, fingerPosition); return response.toString(); // Return the response as a JSON string } // Compare with existing templates double bestScore = 0; String matchedPerson = null; for (FingerprintCompareListItem entry : templateArray) { String personName = entry.getName(); FingerprintTemplate candidate = entry.getFingerprint(); double score = new FingerprintMatcher(probeTemplate).match(candidate); if (score > bestScore) { bestScore = score; matchedPerson = personName; } } // Return response based on score if (bestScore >= MATCH_THRESHOLD) { // Match found return buildJavaResponse(id, "Registration", "Registered", "Existing Fingerprint template found for " + matchedPerson + "!", probeTemplate, bestScore, edgeScore, personInfo, fingerPosition).toString(); } else { // Register new template String response = buildJavaResponse(id, "Registration", "Success", "New fingerprint template constructed.", probeTemplate, 100.0, edgeScore, personInfo, fingerPosition); return response.toString(); } } catch (Exception e) { // Handle errors during registration String errorResponse = buildJavaResponse(id, "Registration", "Failed", "Template Construction Failed: " + e.getMessage(), null, 0.0, null, personInfo, fingerPosition); return errorResponse.toString(); } } public static String handleVerification(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) { try { // Decode the fingerprint image from base64 Integer edgeScore = null; byte[] imageBytes = Base64.getDecoder().decode(imageBase64); BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); if (image == null) { throw new IllegalArgumentException("Invalid image format."); } // Create a FingerprintTemplate from the imageBytes FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes)); // Logic for transparency goes here // ... try (TransparencyContents transparency = new TransparencyContents()) { FingerprintTemplate probe = new FingerprintTemplate(imageBytes); transparency.accepts("edge-table"); transparency.take("edge-table", "application/cbor", imageBytes); edgeScore = transparency.countEdgeNumber(); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } double bestScore = 0; int matchedFingerprintPosition = 0; // just put 0 as default value for now String matchedPerson = null; FingerprintTemplate matchedFingerprintTemplate = null; for (int i = 0; i < templateArray.length; i++) { FingerprintCompareListItem entry = templateArray[i]; String personName = entry.getName(); int fpPosition = entry.getFingerPosition(); FingerprintTemplate candidateTemplate = entry.getFingerprint(); // Maybe there's no need to check? will see about it later if (candidateTemplate == null) { continue; } double score = new FingerprintMatcher(probeTemplate).match(candidateTemplate); if (score > bestScore) { bestScore = score; matchedFingerprintPosition = fpPosition; matchedPerson = personName; matchedFingerprintTemplate = candidateTemplate; } } if (bestScore >= MATCH_THRESHOLD) { // Match found Fingerprint matchedFingerprint = new Fingerprint(matchedPerson, matchedFingerprintPosition, Base64.getEncoder().encodeToString(matchedFingerprintTemplate.toByteArray())); List fingerprints = Collections.singletonList(matchedFingerprint); PersonFingerprintData matchedData = new PersonFingerprintData( personInfo.getId(), matchedPerson, personInfo.getOrg(), personInfo.getCode(), fingerprints ); // JavaResponse response = new JavaResponse(id, "Verification", "Match found.", matchedData, bestScore); String response = buildJavaResponse(id, "Verification", "Registered", "Match found.", matchedFingerprintTemplate, bestScore, null, matchedData, matchedFingerprintPosition); return response.toString(); } else { // No match PersonFingerprintData noMatchData = new PersonFingerprintData( personInfo.getId(), personInfo.getName(), personInfo.getOrg(), personInfo.getCode(), new ArrayList() ); String response = buildJavaResponse(id, "Verification", "Not Registered", "No Match found.", probeTemplate, bestScore, null, noMatchData, fingerPosition); // defaul value return response.toString(); } } catch (Exception e) { PersonFingerprintData errorData = new PersonFingerprintData( personInfo.getId(), personInfo.getName(), personInfo.getOrg(), personInfo.getCode(), new ArrayList() ); String errorResponse = buildJavaResponse(id, "Verification", "Failed", "No Match found.", null, 0, null, personInfo, fingerPosition); // defaul value return errorResponse.toString(); } } public static String handleQualityAssurance(String id, String imageBase64, FingerprintCompareListItem[] templateArray, PersonFingerprintData personInfo, int fingerPosition) { try { Integer edgeScore = null; double bestScore = 0; // Decode the fingerprint image from base64 byte[] imageBytes = Base64.getDecoder().decode(imageBase64); BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); if (image == null) { throw new IllegalArgumentException("Invalid image format."); } // Create a FingerprintTemplate from the imageBytes FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes)); // Logic for transparency goes here // ... try (TransparencyContents transparency = new TransparencyContents()) { transparency.accepts("edge-table"); transparency.take("edge-table", "application/cbor", imageBytes); edgeScore = transparency.countEdgeNumber(); // Addition features to verify against existing fingerprint data String response = buildJavaResponse(id, "QualityAssurance", "Success", "Edge score result: " + bestScore, probeTemplate, bestScore, edgeScore, personInfo, fingerPosition); // defaul value return response.toString(); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); String response = buildJavaResponse(id, "QualityAssurance", "Failed", "Edge score result: " + bestScore, probeTemplate, bestScore, edgeScore, personInfo, fingerPosition); // defaul value return response.toString(); } } catch (Exception e) { // Handle errors during checking String errorResponse = buildJavaResponse(id, "QualityAssurance", "Failed", "Unable to produce Edge score... " + e.getMessage(), null, 0.0, null, personInfo, fingerPosition); return errorResponse.toString(); } } public static String buildJavaResponse( String id, String operation, String status, String message, FingerprintTemplate fingerprintTemplate, double score, Integer edgeScore, PersonFingerprintData personInfo, int fingerPosition) { // Convert the FingerprintTemplate to a base64-encoded string (assuming `FingerprintTemplate` has a way to do this) String templateBase64 = (fingerprintTemplate != null) ? Base64.getEncoder().encodeToString(fingerprintTemplate.toByteArray()) : ""; // Construct the fingerprint data (if there is a fingerprint template) Fingerprint fingerprint = new Fingerprint(personInfo.getName(), fingerPosition, templateBase64); // Add the fingerprint to the personInfo personInfo.addFingerprint(fingerprint); // Build the JavaResponse JavaResponse javaResponse = new JavaResponse(id, operation, status, message, personInfo, score, edgeScore); // System.out.println("Java Response: " + javaResponse.toString()); // Serialize JavaResponse to JSON string using Jackson try { ObjectMapper mapper = new ObjectMapper(); String jsonResponse = mapper.writeValueAsString(javaResponse); return jsonResponse; } catch (Exception e) { // Handle exception if serialization fails e.printStackTrace(); return "{\"error\":\"Failed to serialize response\"}"; } } }