io.mosip.kernel.biometrics.commons.CbeffValidator Maven / Gradle / Ivy
/**
*
*/
package io.mosip.kernel.biometrics.commons;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
import org.xml.sax.SAXException;
import io.mosip.kernel.biometrics.constant.BiometricType;
import io.mosip.kernel.biometrics.constant.OtherKey;
import io.mosip.kernel.biometrics.entities.BDBInfo;
import io.mosip.kernel.biometrics.entities.BIR;
import io.mosip.kernel.biometrics.entities.SingleAnySubtypeType;
import io.mosip.kernel.core.cbeffutil.common.CbeffXSDValidator;
import io.mosip.kernel.core.cbeffutil.constant.CbeffConstant;
import io.mosip.kernel.core.cbeffutil.exception.CbeffException;
import io.mosip.kernel.core.util.CryptoUtil;
/**
* @author Ramadurai Pandian
*
* An Utility Class to validate the data before generating an valid
* CBEFF XML and to get all the data based on Type and SubType
*
*/
public class CbeffValidator {
/**
* Method used for custom validation of the BIR
*
* @param birRoot BIR data
*
* @return boolean value if BIR is valid
*
* @exception CbeffException when any condition fails
*
*/
public static boolean validateXML(BIR birRoot) throws CbeffException {
if (birRoot == null) {
throw new CbeffException("BIR value is null");
}
List birList = birRoot.getBirs();
for (BIR bir : birList) {
if (bir != null) {
boolean isException = bir.getOthers() != null && bir.getOthers().entrySet().stream()
.anyMatch(e -> OtherKey.EXCEPTION.equals(e.getKey()) && "true".equals((String) e.getValue()));
if ((bir.getBdb() == null || bir.getBdb().length < 1) && !isException)
throw new CbeffException("BDB value can't be empty");
if (bir.getBdbInfo() == null)
throw new CbeffException("BDB information can't be empty");
BDBInfo bdbInfo = bir.getBdbInfo();
// if (!Long.valueOf(bdbInfo.getFormat().getOrganization()).equals(CbeffConstant.FORMAT_OWNER)) {
// throw new CbeffException("Patron Format Owner should be standard specified of value "
// + CbeffConstant.FORMAT_OWNER);
// }
List biometricTypes = bdbInfo.getType();
if (biometricTypes == null || biometricTypes.isEmpty()) {
throw new CbeffException("Type value needs to be provided");
}
if (!validateFormatType(Long.valueOf(bdbInfo.getFormat().getType()), biometricTypes)) {
throw new CbeffException("Patron Format type is invalid");
}
}
}
return true;
}
/**
* Method used for validation of Format Type
*
* @param formatType format type
*
* @param biometricTypes List of types
*
* @return boolean value if format type is matching with type
*
*/
private static boolean validateFormatType(long formatType, List biometricTypes) {
BiometricType biometricType = biometricTypes.get(0);
switch (biometricType.value()) {
case "Finger":
return formatType == CbeffConstant.FORMAT_TYPE_FINGER
|| formatType == CbeffConstant.FORMAT_TYPE_FINGER_MINUTIAE;
case "Iris":
return formatType == CbeffConstant.FORMAT_TYPE_IRIS;
case "Face":
return formatType == CbeffConstant.FORMAT_TYPE_FACE;
case "HandGeometry":
return formatType == CbeffConstant.FORMAT_TYPE_FACE;
}
return false;
}
/**
* Method used for getting Format Type Id from type string
*
* @param type format type
*
* @return long format type id
*
*/
private static long getFormatType(String type) {
switch (type.toLowerCase()) {
case "finger":
return CbeffConstant.FORMAT_TYPE_FINGER;
case "iris":
return CbeffConstant.FORMAT_TYPE_IRIS;
case "fmr":
return CbeffConstant.FORMAT_TYPE_FINGER_MINUTIAE;
case "face":
return CbeffConstant.FORMAT_TYPE_FACE;
case "handgeometry":
return CbeffConstant.FORMAT_TYPE_FACE;
}
return 0;
}
/**
* Method used for creating XML bytes using JAXB
*
* @param bir BIR type
* @param xsd xml schema definition
* @return byte[] byte array of XML data
*
* @exception Exception exception
*
*/
public static byte[] createXMLBytes(BIR bir, byte[] xsd) throws Exception {
CbeffValidator.validateXML(bir);
JAXBContext jaxbContext = JAXBContext.newInstance(BIR.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(baos);
jaxbMarshaller.marshal(bir, writer);
byte[] savedData = baos.toByteArray();
writer.close();
try {
CbeffXSDValidator.validateXML(xsd, savedData);
} catch (SAXException sax) {
String message = sax.getMessage();
message = message.substring(message.indexOf(":"));
throw new CbeffException("XSD validation failed due to attribute " + message);
}
return savedData;
}
/*
* private static byte[] readXSD(String name) throws IOException { byte[]
* fileContent = Files.readAllBytes(Paths.get(tempPath + "/schema/" + name +
* ".xsd")); return fileContent; }
*/
/**
* Method used for BIR Type
*
* @param fileBytes byte array of XML data
*
* @return BIR BIR data
*
* @exception Exception exception
*
*/
public static BIR getBIRFromXML(byte[] fileBytes) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(BIR.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement jaxBir = unmarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(fileBytes)),
BIR.class);
BIR bir = jaxBir.getValue();
return bir;
}
/**
* Method used for searching Cbeff data based on type and subtype
*
* @param bir BIR data
*
* @param type format type
*
* @param subType format subtype
*
* @return bdbMap
*
* @exception Exception exception
*
*/
public static Map getBDBBasedOnTypeAndSubType(BIR bir, String type, String subType)
throws Exception {
if (type == null && subType == null) {
return getAllLatestDatafromBIR(bir);
}
BiometricType biometricType = null;
SingleAnySubtypeType singleAnySubType = null;
Long formatType = null;
if (type != null) {
biometricType = getBiometricType(type);
formatType = getFormatType(type);
}
if (subType != null) {
singleAnySubType = getSingleAnySubtype(subType);
}
Map bdbMap = new HashMap<>();
if (bir.getBirs() != null && !bir.getBirs().isEmpty()) {
populateBDBMap(bir, biometricType, singleAnySubType, formatType, bdbMap);
}
Map map = new TreeMap<>(bdbMap);
Map finalMap = new HashMap<>();
for (Map.Entry mapEntry : map.entrySet()) {
String pattern = mapEntry.getKey().substring(0, mapEntry.getKey().lastIndexOf("_"));
if (mapEntry.getKey().contains(pattern)) {
finalMap.put(mapEntry.getKey().substring(0, mapEntry.getKey().lastIndexOf("_")), mapEntry.getValue());
}
}
return finalMap;
}
private static void populateBDBMap(BIR birRoot, BiometricType biometricType, SingleAnySubtypeType singleAnySubType,
Long formatType, Map bdbMap) {
for (BIR bir : birRoot.getBirs()) {
BDBInfo bdbInfo = bir.getBdbInfo();
if (bdbInfo != null) {
List singleSubTypeList = bdbInfo.getSubtype() == null ? List.of() : bdbInfo.getSubtype();
List biometricTypes = bdbInfo.getType();
String bdbFormatType = bdbInfo.getFormat().getType();
boolean formatMatch = Long.valueOf(bdbFormatType).equals(formatType);
if (singleAnySubType == null && biometricTypes.contains(biometricType) && formatMatch) {
bdbMap.put(
(biometricType != null ? biometricType.toString() : null) + "_"
+ String.join(" ", singleSubTypeList) + "_" + String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
CryptoUtil.encodeBase64String(bir.getBdb()));
} else if (biometricType == null
&& singleSubTypeList.contains(singleAnySubType != null ? singleAnySubType.value() : null)) {
List singleTypeStringList = convertToList(biometricTypes);
bdbMap.put(
String.join(" ", singleTypeStringList) + "_" + String.join(" ", singleSubTypeList) + "_"
+ String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
CryptoUtil.encodeBase64String(bir.getBdb()));
} else if (biometricTypes.contains(biometricType)
&& singleSubTypeList.contains(singleAnySubType != null ? singleAnySubType.value() : null)
&& formatMatch) {
bdbMap.put(
(biometricType != null ? biometricType.toString() : null) + "_"
+ (singleAnySubType != null ? singleAnySubType.value() : null) + "_"
+ String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
CryptoUtil.encodeBase64String(bir.getBdb()));
}
}
}
}
private static Map getAllLatestDatafromBIR(BIR birRoot) throws Exception {
Map bdbMap = new HashMap<>();
if (birRoot.getBirs() != null && birRoot.getBirs().size() > 0) {
for (BIR bir : birRoot.getBirs()) {
BDBInfo bdbInfo = bir.getBdbInfo();
if (bdbInfo != null) {
List singleSubTypeList = bdbInfo.getSubtype();
List biometricTypes = bdbInfo.getType();
if (singleSubTypeList.isEmpty()) {
singleSubTypeList = new ArrayList<>();
singleSubTypeList.add("No Subtype");
}
String bdbFormatType = bdbInfo.getFormat().getType();
bdbMap.put(
String.join(" ", biometricTypes.get(0).toString()) + "_"
+ String.join(" ", singleSubTypeList) + "_" + String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
CryptoUtil.encodeBase64String(bir.getBdb()));
}
}
}
Map map = new TreeMap<>(bdbMap);
Map finalMap = new HashMap<>();
for (Map.Entry mapEntry : map.entrySet()) {
String pattern = mapEntry.getKey().substring(0, mapEntry.getKey().lastIndexOf("_"));
if (mapEntry.getKey().contains(pattern)) {
finalMap.put(mapEntry.getKey().substring(0, mapEntry.getKey().lastIndexOf("_")), mapEntry.getValue());
}
}
return finalMap;
}
/**
* Method to convert single type list to string
*
*/
private static List convertToList(List biometricTypeList) {
return biometricTypeList.stream().map(Enum::name).collect(Collectors.toList());
}
/**
* Method to get enum type from string type
*
*/
private static BiometricType getBiometricType(String type) {
if (isInEnum(type, BiometricType.class)) {
return BiometricType.valueOf(type);
} else {
switch (type) {
case "FMR":
return BiometricType.FINGER;
default:
return BiometricType.fromValue(type);
}
}
}
public static > boolean isInEnum(String value, Class enumClass) {
for (E e : enumClass.getEnumConstants()) {
if (e.name().equals(value)) {
return true;
}
}
return false;
}
public static Map getAllBDBData(BIR birRoot, String type, String subType) throws Exception {
BiometricType biometricType = null;
SingleAnySubtypeType singleAnySubType = null;
Long formatType = null;
if (type != null) {
biometricType = getBiometricType(type);
}
if (subType != null) {
singleAnySubType = getSingleAnySubtype(subType);
}
if (type != null) {
formatType = getFormatType(type);
}
Map bdbMap = new HashMap<>();
List birs = birRoot.getBirs();
if (birs != null && !birs.isEmpty()) {
for (BIR bir : birs) {
BDBInfo bdbInfo = bir.getBdbInfo();
if (bdbInfo != null) {
List singleSubTypeList = bdbInfo.getSubtype();
List singleTypeList = bdbInfo.getType();
String bdbFormatType = bdbInfo.getFormat().getType();
boolean formatMatch = Long.valueOf(bdbFormatType).equals(formatType);
if (singleAnySubType == null && singleTypeList.contains(biometricType) && formatMatch) {
bdbMap.put(
(biometricType != null ? biometricType.toString() : null) + "_" + String.join(" ", singleSubTypeList) + "_"
+ String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
new String(bir.getBdb(), "UTF-8"));
} else if (biometricType == null
&& singleSubTypeList.contains(singleAnySubType != null ? singleAnySubType.value() : null)) {
List singleTypeStringList = convertToList(singleTypeList);
bdbMap.put(
String.join(" ", singleSubTypeList) + "_" + String.join(" ", singleTypeStringList) + "_"
+ String.valueOf(bdbFormatType) + "_"
+ bdbInfo.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
new String(bir.getBdb(), "UTF-8"));
} else if (singleTypeList.contains(biometricType)
&& singleSubTypeList.contains(singleAnySubType != null ? singleAnySubType.value() : null)
&& formatMatch) {
bdbMap.put(
(singleAnySubType != null ? singleAnySubType.value() : null) + "_"
+ (biometricType != null ? biometricType.toString() : null) + "_" + String.valueOf(bdbFormatType) + "_" + bdbInfo
.getCreationDate().toInstant(ZoneOffset.UTC).toEpochMilli(),
new String(bir.getBdb(), "UTF-8"));
}
}
}
}
return bdbMap;
}
/**
* Method to get enum sub type from string subtype
*
*/
private static SingleAnySubtypeType getSingleAnySubtype(String subType) {
return subType != null ? SingleAnySubtypeType.fromValue(subType) : null;
}
/*
* private static List getBIRList(List birs) { List birList = new
* ArrayList<>(); for (BIR bir : birs) { RegistryIDType format = new
* RegistryIDType();
* format.setOrganization(bir.getBdbInfo().getFormat().getOrganization());
* format.setType(bir.getBdbInfo().getFormat().getType()); BIR.BIRBuilder
* birBuilder = new BIR.BIRBuilder();
* birBuilder.withBdb(bir.getBdb()).withOther(bir.getOthers()) .withBirInfo(new
* BIRInfo.BIRInfoBuilder().withIntegrity(bir.getBirInfo().getIntegrity()).build
* ()) .withBdbInfo(new BDBInfo.BDBInfoBuilder().withFormat(format)
* .withQuality(bir.getBdbInfo().getQuality()).withType(bir.getBdbInfo().getType
* ()) .withSubtype(bir.getBdbInfo().getSubtype())
* .withPurpose(bir.getBdbInfo().getPurpose()).withLevel(bir.getBdbInfo().
* getLevel()) .withCreationDate(bir.getBdbInfo().getCreationDate()).build());
*
* VersionType versionType = bir.getVersion(); if(versionType != null) {
* birBuilder.withVersion(versionType); }
*
* VersionType cbeffversionType = bir.getCbeffversion(); if(cbeffversionType !=
* null) { birBuilder.withCbeffversion(cbeffversionType); }
*
*
* birList.add(birBuilder.build()); } return birList; }
*/
public static List getBIRDataFromXMLType(byte[] xmlBytes, String type) throws Exception {
BiometricType biometricType = null;
List updatedBIRList = new ArrayList<>();
JAXBContext jaxbContext = JAXBContext.newInstance(BIR.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement jaxBir = unmarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(xmlBytes)),
BIR.class);
BIR birRoot = jaxBir.getValue();
for (BIR bir : birRoot.getBirs()) {
if (type != null) {
biometricType = getBiometricType(type);
BDBInfo bdbInfo = bir.getBdbInfo();
if (bdbInfo != null) {
List biometricTypes = bdbInfo.getType();
if (biometricTypes != null && biometricTypes.contains(biometricType)) {
updatedBIRList.add(bir);
}
}
}
}
return updatedBIRList;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy