001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.bct.assertions; 018import static org.apache.juneau.commons.utils.Shorts.*; 019 020import java.util.function.*; 021 022 023/** 024 * Utility class for performing simple validations on objects. 025 * 026 * <p> 027 * Verifications that pass return a null string. Verifications that don't pass return a string with a useful 028 * error message. 029 * 030 * <h5 class='section'>Example:</h5> 031 * <p class='bjava'> 032 * <jc>// Validates that our POJO is of type MyBean.</jc> 033 * String <jv>errorMessage</jv> = <jsm>verify</jsm>(<jv>myPojo</jv>).isType(MyBean.<jk>class</jk>); 034 * <jk>if</jk> (<jv>errorMessage</jv> != <jk>null</jk>) 035 * <jk>throw new</jk> RuntimeException(<jv>errorMessage</jv>); 036 * </p> 037 * 038 * <h5 class='section'>See Also:</h5><ul> 039 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem</a> 040 * </ul> 041 */ 042@SuppressWarnings({ 043 "java:S115" // Constants use UPPER_snakeCase convention (e.g., MSG_unexpectedType) 044}) 045public class Verify { 046 047 private static final Messages MESSAGES = Messages.of(Verify.class, "Messages"); 048 static final String MSG_unexpectedType = MESSAGES.getString("unexpectedType"); 049 static final String MSG_unexpectedValue = MESSAGES.getString("unexpectedValue"); 050 051 /** 052 * Create a new verifier object. 053 * 054 * @param o The object being verified. 055 * @return A new verifier object. 056 */ 057 public static Verify verify(Object o) { 058 return new Verify(o); 059 } 060 061 private final Object o; 062 private Supplier<String> msg; 063 064 /** 065 * Create a new verifier object. 066 * 067 * @param o The object being verified. 068 */ 069 protected Verify(Object o) { 070 this.o = o; 071 } 072 073 /** 074 * Verifies that this object is equal to the specified object. 075 * 076 * @param expected The object to test against for equality. 077 * @return An error message if the object is not equal to the specified object, otherwise <jk>null</jk>. 078 */ 079 public String is(Object expected) { 080 if (expected == o) 081 return null; 082 if (expected == null || o == null || ! expected.equals(o)) 083 return nn(msg) ? msg.get() : f(MSG_unexpectedValue, r(expected), r(o)); 084 return null; 085 } 086 087 /** 088 * Verifies that this object is equal to {@link Boolean#FALSE}. 089 * 090 * @return An error message if the object is not false, otherwise <jk>null</jk>. 091 */ 092 public String isFalse() { return is(false); } 093 094 /** 095 * Verifies that this object is equal to {@link Boolean#TRUE}. 096 * 097 * @return An error message if the object is not true, otherwise <jk>null</jk>. 098 */ 099 public String isTrue() { return is(true); } 100 101 /** 102 * Verifies that this object is of the specified type. 103 * 104 * @param type The type to test against. 105 * @return An error message if the object is not of the specified type, otherwise <jk>null</jk>. 106 */ 107 @SuppressWarnings({ 108 "null" // Null analysis not applicable to type verification 109 }) 110 public String isType(Class<?> type) { 111 if ((type == null && o == null) || (nn(type) && type.isInstance(o))) 112 return null; 113 var c = o == null ? null : o.getClass(); 114 return nn(msg) ? msg.get() : f(MSG_unexpectedType, cn(type), cn(c)); 115 } 116 117 /** 118 * Overrides the default error message produced by the verification. 119 * 120 * @param msg The error message. 121 * @param args Optional message arguments. 122 * @return This object. 123 */ 124 public Verify msg(String msg, Object args) { 125 this.msg = fs(msg, args); 126 return this; 127 } 128}