import java.util.regex.Pattern;
// ------------------ Custom Exception ------------------
class InvalidInputException
extends Exception { public InvalidInputException
(String message
) { super(message);
}
}
// ------------------ Utility Class ------------------
class StringValidator {
public static boolean isEmail
(String input
) throws InvalidInputException
{ if (input == null) throw new InvalidInputException("Email cannot be null");
assert input.length() < 500 : "Email too long";
String emailRegex
= "^[\\w._%+-]+@[\\w.-]+\\.[A-Za-z]{2,6}$"; return Pattern.matches(emailRegex, input);
}
public static boolean isPhoneNumber
(String input
) throws InvalidInputException
{ if (input == null) throw new InvalidInputException("Phone number cannot be null");
String phoneRegex
= "^\\+?[0-9]{10,15}$"; return Pattern.matches(phoneRegex, input);
}
public static boolean isAlphanumeric
(String input
) throws InvalidInputException
{ if (input == null) throw new InvalidInputException("Input cannot be null");
String alphaNumRegex
= "^[A-Za-z0-9]+$"; return Pattern.matches(alphaNumRegex, input);
}
}
// ------------------ Manual Test Runner ------------------
public class Main {
private static int passed = 0;
private static int failed = 0;
private static void runTest
(String testName,
boolean result
) { if (result) {
System.
out.
println("[PASS] " + testName
); passed++;
} else {
System.
out.
println("[FAIL] " + testName
); failed++;
}
}
public static void main
(String[] args
) { try {
// Email tests
runTest("Valid Email", StringValidator.isEmail("test@example.com"));
runTest("Invalid Email", !StringValidator.isEmail("invalid-email"));
// Phone tests
runTest("Valid Phone", StringValidator.isPhoneNumber("+12345678901"));
runTest("Invalid Phone", !StringValidator.isPhoneNumber("123-abc-7890"));
// Alphanumeric tests
runTest("Valid Alphanumeric", StringValidator.isAlphanumeric("Test123"));
runTest("Invalid Alphanumeric", !StringValidator.isAlphanumeric("Test 123"));
// Exception tests
boolean exceptionThrown;
exceptionThrown = false;
try { StringValidator.isEmail(null); } catch (InvalidInputException e) { exceptionThrown = true; }
runTest("Email Null Exception", exceptionThrown);
exceptionThrown = false;
try { StringValidator.isPhoneNumber(null); } catch (InvalidInputException e) { exceptionThrown = true; }
runTest("Phone Null Exception", exceptionThrown);
exceptionThrown = false;
try { StringValidator.isAlphanumeric(null); } catch (InvalidInputException e) { exceptionThrown = true; }
runTest("Alphanumeric Null Exception", exceptionThrown);
System.
out.
println("Unexpected Exception: " + e.
getMessage()); failed++;
}
// Summary
System.
out.
println("\n--- Test Summary ---"); System.
out.
println("Passed: " + passed
); System.
out.
println("Failed: " + failed
); }
}
aW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tIEN1c3RvbSBFeGNlcHRpb24gLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIEludmFsaWRJbnB1dEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CiAgICBwdWJsaWMgSW52YWxpZElucHV0RXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CiAgICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICB9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLSBVdGlsaXR5IENsYXNzIC0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBTdHJpbmdWYWxpZGF0b3IgewoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VtYWlsKFN0cmluZyBpbnB1dCkgdGhyb3dzIEludmFsaWRJbnB1dEV4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGlucHV0ID09IG51bGwpIHRocm93IG5ldyBJbnZhbGlkSW5wdXRFeGNlcHRpb24oIkVtYWlsIGNhbm5vdCBiZSBudWxsIik7CiAgICAgICAgYXNzZXJ0IGlucHV0Lmxlbmd0aCgpIDwgNTAwIDogIkVtYWlsIHRvbyBsb25nIjsKICAgICAgICBTdHJpbmcgZW1haWxSZWdleCA9ICJeW1xcdy5fJSstXStAW1xcdy4tXStcXC5bQS1aYS16XXsyLDZ9JCI7CiAgICAgICAgcmV0dXJuIFBhdHRlcm4ubWF0Y2hlcyhlbWFpbFJlZ2V4LCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzUGhvbmVOdW1iZXIoU3RyaW5nIGlucHV0KSB0aHJvd3MgSW52YWxpZElucHV0RXhjZXB0aW9uIHsKICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgdGhyb3cgbmV3IEludmFsaWRJbnB1dEV4Y2VwdGlvbigiUGhvbmUgbnVtYmVyIGNhbm5vdCBiZSBudWxsIik7CiAgICAgICAgU3RyaW5nIHBob25lUmVnZXggPSAiXlxcKz9bMC05XXsxMCwxNX0kIjsKICAgICAgICByZXR1cm4gUGF0dGVybi5tYXRjaGVzKHBob25lUmVnZXgsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBbHBoYW51bWVyaWMoU3RyaW5nIGlucHV0KSB0aHJvd3MgSW52YWxpZElucHV0RXhjZXB0aW9uIHsKICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgdGhyb3cgbmV3IEludmFsaWRJbnB1dEV4Y2VwdGlvbigiSW5wdXQgY2Fubm90IGJlIG51bGwiKTsKICAgICAgICBTdHJpbmcgYWxwaGFOdW1SZWdleCA9ICJeW0EtWmEtejAtOV0rJCI7CiAgICAgICAgcmV0dXJuIFBhdHRlcm4ubWF0Y2hlcyhhbHBoYU51bVJlZ2V4LCBpbnB1dCk7CiAgICB9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLSBNYW51YWwgVGVzdCBSdW5uZXIgLS0tLS0tLS0tLS0tLS0tLS0tCnB1YmxpYyBjbGFzcyBNYWluIHsKICAgIHByaXZhdGUgc3RhdGljIGludCBwYXNzZWQgPSAwOwogICAgcHJpdmF0ZSBzdGF0aWMgaW50IGZhaWxlZCA9IDA7CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBydW5UZXN0KFN0cmluZyB0ZXN0TmFtZSwgYm9vbGVhbiByZXN1bHQpIHsKICAgICAgICBpZiAocmVzdWx0KSB7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiW1BBU1NdICIgKyB0ZXN0TmFtZSk7CiAgICAgICAgICAgIHBhc3NlZCsrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiW0ZBSUxdICIgKyB0ZXN0TmFtZSk7CiAgICAgICAgICAgIGZhaWxlZCsrOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gRW1haWwgdGVzdHMKICAgICAgICAgICAgcnVuVGVzdCgiVmFsaWQgRW1haWwiLCBTdHJpbmdWYWxpZGF0b3IuaXNFbWFpbCgidGVzdEBleGFtcGxlLmNvbSIpKTsKICAgICAgICAgICAgcnVuVGVzdCgiSW52YWxpZCBFbWFpbCIsICFTdHJpbmdWYWxpZGF0b3IuaXNFbWFpbCgiaW52YWxpZC1lbWFpbCIpKTsKCiAgICAgICAgICAgIC8vIFBob25lIHRlc3RzCiAgICAgICAgICAgIHJ1blRlc3QoIlZhbGlkIFBob25lIiwgU3RyaW5nVmFsaWRhdG9yLmlzUGhvbmVOdW1iZXIoIisxMjM0NTY3ODkwMSIpKTsKICAgICAgICAgICAgcnVuVGVzdCgiSW52YWxpZCBQaG9uZSIsICFTdHJpbmdWYWxpZGF0b3IuaXNQaG9uZU51bWJlcigiMTIzLWFiYy03ODkwIikpOwoKICAgICAgICAgICAgLy8gQWxwaGFudW1lcmljIHRlc3RzCiAgICAgICAgICAgIHJ1blRlc3QoIlZhbGlkIEFscGhhbnVtZXJpYyIsIFN0cmluZ1ZhbGlkYXRvci5pc0FscGhhbnVtZXJpYygiVGVzdDEyMyIpKTsKICAgICAgICAgICAgcnVuVGVzdCgiSW52YWxpZCBBbHBoYW51bWVyaWMiLCAhU3RyaW5nVmFsaWRhdG9yLmlzQWxwaGFudW1lcmljKCJUZXN0IDEyMyIpKTsKCiAgICAgICAgICAgIC8vIEV4Y2VwdGlvbiB0ZXN0cwogICAgICAgICAgICBib29sZWFuIGV4Y2VwdGlvblRocm93bjsKICAgICAgICAgICAgZXhjZXB0aW9uVGhyb3duID0gZmFsc2U7CiAgICAgICAgICAgIHRyeSB7IFN0cmluZ1ZhbGlkYXRvci5pc0VtYWlsKG51bGwpOyB9IGNhdGNoIChJbnZhbGlkSW5wdXRFeGNlcHRpb24gZSkgeyBleGNlcHRpb25UaHJvd24gPSB0cnVlOyB9CiAgICAgICAgICAgIHJ1blRlc3QoIkVtYWlsIE51bGwgRXhjZXB0aW9uIiwgZXhjZXB0aW9uVGhyb3duKTsKCiAgICAgICAgICAgIGV4Y2VwdGlvblRocm93biA9IGZhbHNlOwogICAgICAgICAgICB0cnkgeyBTdHJpbmdWYWxpZGF0b3IuaXNQaG9uZU51bWJlcihudWxsKTsgfSBjYXRjaCAoSW52YWxpZElucHV0RXhjZXB0aW9uIGUpIHsgZXhjZXB0aW9uVGhyb3duID0gdHJ1ZTsgfQogICAgICAgICAgICBydW5UZXN0KCJQaG9uZSBOdWxsIEV4Y2VwdGlvbiIsIGV4Y2VwdGlvblRocm93bik7CgogICAgICAgICAgICBleGNlcHRpb25UaHJvd24gPSBmYWxzZTsKICAgICAgICAgICAgdHJ5IHsgU3RyaW5nVmFsaWRhdG9yLmlzQWxwaGFudW1lcmljKG51bGwpOyB9IGNhdGNoIChJbnZhbGlkSW5wdXRFeGNlcHRpb24gZSkgeyBleGNlcHRpb25UaHJvd24gPSB0cnVlOyB9CiAgICAgICAgICAgIHJ1blRlc3QoIkFscGhhbnVtZXJpYyBOdWxsIEV4Y2VwdGlvbiIsIGV4Y2VwdGlvblRocm93bik7CgogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVW5leHBlY3RlZCBFeGNlcHRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIGZhaWxlZCsrOwogICAgICAgIH0KCiAgICAgICAgLy8gU3VtbWFyeQogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG4tLS0gVGVzdCBTdW1tYXJ5IC0tLSIpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGFzc2VkOiAiICsgcGFzc2VkKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWxlZDogIiArIGZhaWxlZCk7CiAgICB9Cn0K