001package gu.sql2java.store;
002
003import java.lang.reflect.InvocationTargetException;
004import javax.annotation.Nullable;
005import com.google.errorprone.annotations.CanIgnoreReturnValue;
006
007/**
008 * 条件检查工具类
009 * @author guyadong
010 *
011 */
012public class ConditionChecks {
013
014        private ConditionChecks() {
015        }
016        /**
017         * 执行表达式,为false时抛出 declareType 异常
018         * @param <X> 抛出异常类型
019         * @param b
020         * @param declareType 异常类型
021         * @param errorMessageTemplate a template for the exception message should the check fail. The
022         *     message is formed by replacing each {@code %s} placeholder in the template with an
023         *     argument. These are matched by position - the first {@code %s} gets {@code
024         *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
025         *     square braces. Unmatched placeholders will be left as-is.
026         * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
027         *     are converted to strings using {@link String#valueOf(Object)}.
028         * @throws X
029         */
030        public static <X extends Throwable> void checkTrue(
031                        boolean b, 
032                        Class<X> declareType, 
033                        @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) throws X {
034                if (!b) {
035                        try {
036                                if(declareType == null){
037                                        throw new NullPointerException("declareType is null");
038                                }
039                                throw declareType.getConstructor(String.class).newInstance(format(errorMessageTemplate, errorMessageArgs));
040                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
041                                        | InvocationTargetException | NoSuchMethodException | SecurityException e) {
042                                e.printStackTrace();
043                        }
044                }
045        }
046        /**
047         * 执行表达式,为false时抛出 declareType 异常
048         *
049         * <p>See {@link #checkTrue(boolean, Class, String, Object...)} for details.
050         * @throws X 
051         */
052        public static <X extends Throwable> void checkTrue(
053                        boolean b, 
054                        Class<X> declareType, 
055                        @Nullable String errorMessageTemplate, @Nullable Object p1) throws X {
056                if (!b) {
057                        try {
058                                if(declareType == null){
059                                        throw new NullPointerException("declareType is null");
060                                }
061                                throw declareType.getConstructor(String.class).newInstance(format(errorMessageTemplate, p1));
062                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
063                                        | InvocationTargetException | NoSuchMethodException | SecurityException e) {
064                                e.printStackTrace();
065                        }       
066                }
067        }
068        /**
069         * reference为{@code null}时抛出 declareType 异常
070         * @param <T> 对象类型
071         * @param <X> 抛出异常类型
072         * @param reference
073         * @param declareType 异常类型
074         * @param errorMessageTemplate a template for the exception message should the check fail. The
075         *     message is formed by replacing each {@code %s} placeholder in the template with an
076         *     argument. These are matched by position - the first {@code %s} gets {@code
077         *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
078         *     square braces. Unmatched placeholders will be left as-is.
079         * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
080         *     are converted to strings using {@link String#valueOf(Object)}.
081         * @return 
082         * @throws X
083         */
084        @CanIgnoreReturnValue
085        public static <T,X extends Throwable> T checkNotNull(
086                        T reference, 
087                        Class<X> declareType, 
088                        @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) throws X {
089                if (null==reference) {
090                        try {
091                                if(declareType == null){
092                                        throw new NullPointerException("declareType is null");
093                                }
094                                throw declareType.getConstructor(String.class).newInstance(format(errorMessageTemplate, errorMessageArgs));
095                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
096                                        | InvocationTargetException | NoSuchMethodException | SecurityException e) {
097                                e.printStackTrace();
098                        }
099                }
100                return reference;
101        }
102        /**
103         * reference为{@code null}时抛出 declareType 异常
104         *
105         * <p>See {@link #checkNotNull(boolean, Class, String, Object...)} for details.
106         * @return 
107         * @throws X 
108         */
109        @CanIgnoreReturnValue
110        public static <T,X extends Throwable> T checkNotNull(
111                        T reference,
112                        Class<X> declareType, 
113                        @Nullable String errorMessageTemplate, @Nullable Object p1) throws X {
114                if (null==reference) {
115                        try {
116                                if(declareType == null){
117                                        throw new NullPointerException("declareType is null");
118                                }
119                                throw declareType.getConstructor(String.class).newInstance(format(errorMessageTemplate, p1));
120                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
121                                        | InvocationTargetException | NoSuchMethodException | SecurityException e) {
122                                e.printStackTrace();
123                        }       
124                }
125                return reference;
126        }
127          /**
128           * Substitutes each {@code %s} in {@code template} with an argument. These are matched by
129           * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than
130           * placeholders, the unmatched arguments will be appended to the end of the formatted message in
131           * square braces.
132           *
133           * @param template a non-null string containing 0 or more {@code %s} placeholders.
134           * @param args the arguments to be substituted into the message template. Arguments are converted
135           *     to strings using {@link String#valueOf(Object)}. Arguments can be null.
136           */
137          // Note that this is somewhat-improperly used from Verify.java as well.
138          static String format(String template, @Nullable Object... args) {
139            template = String.valueOf(template); // null -> "null"
140
141            // start substituting the arguments into the '%s' placeholders
142            StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
143            int templateStart = 0;
144            int i = 0;
145            while (i < args.length) {
146              int placeholderStart = template.indexOf("%s", templateStart);
147              if (placeholderStart == -1) {
148                break;
149              }
150              builder.append(template, templateStart, placeholderStart);
151              builder.append(args[i++]);
152              templateStart = placeholderStart + 2;
153            }
154            builder.append(template, templateStart, template.length());
155
156            // if we run out of placeholders, append the extra args in square braces
157            if (i < args.length) {
158              builder.append(" [");
159              builder.append(args[i++]);
160              while (i < args.length) {
161                builder.append(", ");
162                builder.append(args[i++]);
163              }
164              builder.append(']');
165            }
166
167            return builder.toString();
168          }
169}