All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.derquinse.common.meta.MetaFlag Maven / Gradle / Ivy

Go to download

Module containing support classes depending on Java SE 6, Guava 11 and Joda-Time 2.0

There is a newer version: 1.0.37
Show newest version
/*
 * Copyright (C) the original author or authors.
 *
 * 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 net.derquinse.common.meta;

import java.util.Arrays;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;

/**
 * Base class for flag descriptors.
 * @author Andres Rodriguez
 * @param  Containing type.
 */
public abstract class MetaFlag extends MetaField implements Predicate {
	/** Default value. */
	private final boolean defaultValue;
	/** Property view. Preinstantiated to guarantee constant identity. */
	private final FlagProperty property;

	/**
	 * Default constructor.
	 * @param name Property name.
	 * @param defaultValue Default value for the flag.
	 */
	protected MetaFlag(String name, boolean defaultValue) {
		super(name);
		this.defaultValue = defaultValue;
		this.property = new FlagProperty();
	}

	/**
	 * Constructor with a default value of false.
	 * @param name Property name.
	 */
	protected MetaFlag(String name) {
		this(name, false);
	}

	/**
	 * Returns the default value.
	 */
	public final boolean getDefaultValue() {
		return defaultValue;
	}

	/**
	 * Returns a view of the flag as a Boolean property.
	 */
	public final BooleanMetaProperty asProperty() {
		return property;
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if this flag evaluates to {@code false}.
	 */
	public final Predicate not() {
		return Predicates.not(this);
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if this flag and each of the provided
	 * components evaluates to {@code true}. The components are evaluated in order (after the flag),
	 * and evaluation will be "short-circuited" as soon as a false predicate is found. It defensively
	 * copies the iterable passed in, so future changes to it won't alter the behavior of this
	 * predicate.
	 */
	public final Predicate and(Iterable> components) {
		return Predicates.and(Iterables.concat(ImmutableList.of(this), components));
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if this flag and each of the provided
	 * components components evaluates to {@code true}. The components are evaluated in order (after
	 * the flag), and evaluation will be "short-circuited" as soon as a false predicate is found. It
	 * defensively copies the array passed in, so future changes to it won't alter the behavior of
	 * this predicate.
	 */
	public final Predicate and(Predicate... components) {
		return and(Arrays.asList(components));
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if both this flag and the provided predicate
	 * evaluate to {@code true}. The component is evaluated after the flag and evaluation will be
	 * "short-circuited" as soon as a false predicate is found.
	 */
	public final Predicate and(Predicate other) {
		return and(ImmutableList.of(other));
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if any one of this flag or the provided
	 * components evaluates to {@code true}. The components are evaluated in order (after the flag),
	 * and evaluation will be "short-circuited" as soon as a true predicate is found. It defensively
	 * copies the iterable passed in, so future changes to it won't alter the behavior of this
	 * predicate.
	 */
	public final Predicate or(Iterable> components) {
		return Predicates.or(Iterables.concat(ImmutableList.of(this), components));
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if any one of this flag or the provided
	 * components evaluates to {@code true}. The components are evaluated in order (after the flag),
	 * and evaluation will be "short-circuited" as soon as a true predicate is found. It defensively
	 * copies the iterable passed in, so future changes to it won't alter the behavior of this
	 * predicate.
	 */
	public final Predicate or(Predicate... components) {
		return or(Arrays.asList(components));
	}

	/**
	 * Returns a predicate that evaluates to {@code true} if any of this flag or the provided
	 * predicate evaluate to {@code true}. The argument is evaluated after the flag and evaluation
	 * will be "short-circuited" as soon as a true predicate is found.
	 */
	public final Predicate or(Predicate other) {
		return or(ImmutableList.of(other));
	}

	/**
	 * Flag view as a property.
	 */
	private final class FlagProperty extends BooleanMetaProperty {
		FlagProperty() {
			super(MetaFlag.this.getName(), true, Predicates.alwaysTrue(), defaultValue);
		}

		private MetaFlag get() {
			return MetaFlag.this;
		}

		public Boolean apply(C input) {
			return get().apply(input);
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof MetaFlag.FlagProperty) {
				return get() == getClass().cast(obj).get();
			}
			return false;
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy