/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.openapi.util; import com.intellij.reference.SoftReference; import com.intellij.util.ArrayUtilRt; import org.jetbrains.annotations.NotNull; import java.util.HashMap; /** * @author max */ public class Conditions { private Conditions() {} @NotNull public static Condition alwaysTrue() { return (Condition)TRUE; } @NotNull public static Condition alwaysFalse() { return (Condition)FALSE; } public static Condition instanceOf(final Class clazz) { return new Condition() { @Override public boolean value(T t) { return clazz.isInstance(t); } }; } public static Condition is(final T option) { return new Condition() { @Override public boolean value(T t) { return Comparing.equal(t, option); } }; } public static Condition oneOf(final T... options) { return new Condition() { @Override public boolean value(T t) { return ArrayUtilRt.find(options, t) >= 0; } }; } public static Condition not(Condition c) { return new Not(c); } public static Condition and(Condition c1, Condition c2) { return new And(c1, c2); } public static Condition or(Condition c1, Condition c2) { return new Or(c1, c2); } public static Condition cached(Condition c) { return new SoftRefCache(c); } private static class Not implements Condition { private final Condition myCondition; public Not(Condition condition) { myCondition = condition; } @Override public boolean value(T value) { return !myCondition.value(value); } } private static class And implements Condition { private final Condition t1; private final Condition t2; public And(final Condition t1, final Condition t2) { this.t1 = t1; this.t2 = t2; } @Override public boolean value(final T object) { return t1.value(object) && t2.value(object); } } private static class Or implements Condition { private final Condition t1; private final Condition t2; public Or(final Condition t1, final Condition t2) { this.t1 = t1; this.t2 = t2; } @Override public boolean value(final T object) { return t1.value(object) || t2.value(object); } } public static Condition TRUE = new Condition() { @Override public boolean value(final Object object) { return true; } }; public static Condition FALSE = new Condition() { @Override public boolean value(final Object object) { return false; } }; private static class SoftRefCache implements Condition { private final HashMap, Boolean>> myCache = new HashMap, Boolean>>(); private final Condition myCondition; public SoftRefCache(Condition condition) { myCondition = condition; } @Override public final boolean value(T object) { final int key = object.hashCode(); final Pair, Boolean> entry = myCache.get(key); if (entry == null || entry.first.get() != object) { boolean value = myCondition.value(object); myCache.put(key, Pair.create(new SoftReference(object), value)); return value; } else { return entry.second; } } } }