/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.patient.impl; import org.openmrs.patient.IdentifierValidator; import org.openmrs.patient.UnallowedIdentifierException; /** * An abstract class for identifier validators for identifiers that have a hyphen before a single * check digit. Identifiers can not be null, must have at least one character before the check * digit, and can not contain white space. Integers 0-9 or characters A-J are allowed for the check * digit. A character is used by default. */ public abstract class BaseHyphenatedIdentifierValidator implements IdentifierValidator { protected abstract int getCheckDigit(String undecoratedIdentifier); /** * @see org.openmrs.patient.IdentifierValidator#getAllowedCharacters() */ public abstract String getAllowedCharacters(); /** * @see org.openmrs.patient.IdentifierValidator#getName() */ public abstract String getName(); /** * @see org.openmrs.patient.IdentifierValidator#getValidIdentifier(java.lang.String) */ public String getValidIdentifier(String undecoratedIdentifier) throws UnallowedIdentifierException { checkAllowedIdentifier(undecoratedIdentifier); char checkLetter = convertCheckDigitToChar(getCheckDigit(undecoratedIdentifier)); String result = undecoratedIdentifier + "-" + checkLetter; return result; } /** * @see org.openmrs.patient.IdentifierValidator#isValid(java.lang.String) */ public boolean isValid(String identifier) throws UnallowedIdentifierException { if (identifier.indexOf("-") < 1) { throw new UnallowedIdentifierException("Identifier must contain something besides the check digit."); } String idWithoutCheckDigit = identifier.substring(0, identifier.indexOf("-")); checkAllowedIdentifier(idWithoutCheckDigit); int computedCheckDigit = getCheckDigit(idWithoutCheckDigit); String checkDigit = identifier.substring(identifier.indexOf("-") + 1, identifier.length()); if (checkDigit.length() != 1) throw new UnallowedIdentifierException("Identifier must have a check digit of length 1."); if (checkDigit.equalsIgnoreCase("A")) checkDigit = "0"; if (checkDigit.equalsIgnoreCase("B")) checkDigit = "1"; if (checkDigit.equalsIgnoreCase("C")) checkDigit = "2"; if (checkDigit.equalsIgnoreCase("D")) checkDigit = "3"; if (checkDigit.equalsIgnoreCase("E")) checkDigit = "4"; if (checkDigit.equalsIgnoreCase("F")) checkDigit = "5"; if (checkDigit.equalsIgnoreCase("G")) checkDigit = "6"; if (checkDigit.equalsIgnoreCase("H")) checkDigit = "7"; if (checkDigit.equalsIgnoreCase("I")) checkDigit = "8"; if (checkDigit.equalsIgnoreCase("J")) checkDigit = "9"; int givenCheckDigit = 10; try { givenCheckDigit = Integer.valueOf(checkDigit); } catch (NumberFormatException e) { throw new UnallowedIdentifierException( "Check digit must either be a character from A to J or a single digit integer."); } return (computedCheckDigit == givenCheckDigit); } /** * @param undecoratedIdentifier * @throws UnallowedIdentifierException if identifier contains unallowed characters or is * otherwise invalid. */ protected void checkAllowedIdentifier(String undecoratedIdentifier) throws UnallowedIdentifierException { if (undecoratedIdentifier == null) throw new UnallowedIdentifierException("Identifier can not be null."); if (undecoratedIdentifier.length() == 0) throw new UnallowedIdentifierException("Identifier must contain at least one character."); if (undecoratedIdentifier.contains(" ")) throw new UnallowedIdentifierException("Identifier may not contain white space."); for (int i = 0; i < undecoratedIdentifier.length(); i++) { if (getAllowedCharacters().indexOf(undecoratedIdentifier.charAt(i)) == -1) throw new UnallowedIdentifierException("\"" + undecoratedIdentifier.charAt(i) + "\" is an invalid character."); } } /** * Not doing this with ASCII math to be extra careful. * * @param checkDigit * @return */ private char convertCheckDigitToChar(int checkDigit) { switch (checkDigit) { case 0: return 'A'; case 1: return 'B'; case 2: return 'C'; case 3: return 'D'; case 4: return 'E'; case 5: return 'F'; case 6: return 'G'; case 7: return 'H'; case 8: return 'I'; case 9: return 'J'; default: return 'X'; } } }