001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.commons.ensure;
021
022import org.hamcrest.Matcher;
023import org.hamcrest.StringDescription;
024
025/**
026 * Uses the {@link Matcher Hamcrest API} as a means of verifying arguments and
027 * so on.
028 */
029public final class Ensure {
030
031    private Ensure() {
032    }
033
034    /**
035     * To ensure that the provided assertion is true
036     * 
037     * @throws IllegalArgumentException
038     */
039    public static void ensure(final String expectation, final boolean expression) {
040        if (!expression) {
041            throw new IllegalArgumentException("illegal argument, expected: " + expectation);
042        }
043    }
044
045    /**
046     * To ensure that the provided argument is correct.
047     * 
048     * @see #ensureThatArg(Object, Matcher,State)
049     * @see #ensureThatState(Object, Matcher, String)
050     * @see #ensureThatContext(Object, Matcher)
051     * 
052     * @throws IllegalArgumentException
053     *             if matcher does not {@link Matcher#matches(Object) match}.
054     */
055    public static <T> T ensureThatArg(final T object, final Matcher<T> matcher) {
056        if (!matcher.matches(object)) {
057            throw new IllegalArgumentException("illegal argument, expected: " + descriptionOf(matcher));
058        }
059        return object;
060    }
061
062
063    /**
064     * To ensure that the provided argument is correct.
065     * 
066     * @see #ensureThatArg(Object, Matcher)
067     * @see #ensureThatState(Object, Matcher, String)
068     * @see #ensureThatContext(Object, Matcher)
069     * 
070     * @throws IllegalArgumentException
071     *             if matcher does not {@link Matcher#matches(Object) match}.
072     */
073    public static <T> T ensureThatArg(final T arg, final Matcher<T> matcher, final String message) {
074        if (!matcher.matches(arg)) {
075            throw new IllegalArgumentException(message);
076        }
077        return arg;
078    }
079
080    /**
081     * To ensure that the current state of this object (instance fields) is
082     * correct.
083     * 
084     * @see #ensureThatArg(Object, Matcher)
085     * @see #ensureThatContext(Object, Matcher)
086     * @see #ensureThatState(Object, Matcher, String)
087     * 
088     * @throws IllegalStateException
089     *             if matcher does not {@link Matcher#matches(Object) match}.
090     */
091    public static <T> T ensureThatState(final T field, final Matcher<T> matcher) {
092        if (!matcher.matches(field)) {
093            throw new IllegalStateException("illegal argument, expected: " + descriptionOf(matcher));
094        }
095        return field;
096    }
097
098    /**
099     * To ensure that the current state of this object (instance fields) is
100     * correct.
101     * 
102     * @see #ensureThatArg(Object, Matcher)
103     * @see #ensureThatContext(Object, Matcher)
104     * @see #ensureThatState(Object, Matcher)
105     * 
106     * @throws IllegalStateException
107     *             if matcher does not {@link Matcher#matches(Object) match}.
108     */
109    public static <T> T ensureThatState(final T field, final Matcher<T> matcher, final String message) {
110        if (!matcher.matches(field)) {
111            throw new IllegalStateException(message);
112        }
113        return field;
114    }
115
116    /**
117     * To ensure that the current context (<tt>IsisContext</tt>) is correct.
118     * 
119     * @see #ensureThatArg(Object, Matcher)
120     * @see #ensureThatState(Object, Matcher)
121     * @see #ensureThatContext(Object, Matcher, String)
122     * 
123     * @throws IllegalThreadStateException
124     *             if matcher does not {@link Matcher#matches(Object) match}.
125     */
126    public static <T> T ensureThatContext(final T contextProperty, final Matcher<T> matcher) {
127        if (!matcher.matches(contextProperty)) {
128            throw new IllegalThreadStateException("illegal argument, expected: " + descriptionOf(matcher));
129        }
130        return contextProperty;
131    }
132
133    /**
134     * To ensure that the current context (<tt>IsisContext</tt>) is correct.
135     * 
136     * @see #ensureThatArg(Object, Matcher)
137     * @see #ensureThatState(Object, Matcher)
138     * @see #ensureThatContext(Object, Matcher, String)
139     * 
140     * @throws IllegalThreadStateException
141     *             if matcher does not {@link Matcher#matches(Object) match}.
142     */
143    public static <T> T ensureThatContext(final T contextProperty, final Matcher<T> matcher, final String message) {
144        if (!matcher.matches(contextProperty)) {
145            throw new IllegalThreadStateException(message);
146        }
147        return contextProperty;
148    }
149
150    private static <T> String descriptionOf(final Matcher<T> matcher) {
151        final StringDescription stringDescription = new StringDescription();
152        matcher.describeTo(stringDescription);
153        final String description = stringDescription.toString();
154        return description;
155    }
156
157}