Java tutorial
/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package works.chatterbox.hooks.ircchannels.channels.modes; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import org.apache.commons.lang.builder.HashCodeBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; import java.util.function.Function; public abstract class AnnotationMode<T> implements Mode<T> { @Nullable private ModeInfo getModeInfo() { return this.getClass().getAnnotation(ModeInfo.class); } private <F> F withModeInfo(@NotNull final Function<ModeInfo, F> function, final F def) { Preconditions.checkNotNull(function, "function was null"); final ModeInfo modeInfo = this.getModeInfo(); if (modeInfo == null) return def; return function.apply(modeInfo); } private <F> F withModeInfo(@NotNull final Function<ModeInfo, F> function) { Preconditions.checkNotNull(function, "function was null"); final ModeInfo modeInfo = this.getModeInfo(); Preconditions.checkState(modeInfo != null, "No ModeInfo"); return function.apply(modeInfo); } @Override public int getArgumentLength() { return this.withModeInfo(ModeInfo::argumentLength); } @Override public List<T> getArguments() { return Lists.newArrayListWithCapacity(this.getArgumentLength()); } @Override public char[] getModes() { return this.withModeInfo(ModeInfo::modes); } @Override public int hashCode() { return new HashCodeBuilder(17, 31).append(this.getArguments()).append(this.getModes()).hashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) return true; if (obj == null || !(obj instanceof AnnotationMode)) return false; final AnnotationMode other = (AnnotationMode) obj; return Arrays.equals(other.getModes(), this.getModes()) && other.getArguments().equals(this.getArguments()); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append(this.getModes()[0]); if (this.getArgumentLength() > 0) { for (int i = 0; i < this.getArgumentLength(); i++) { final T arg = this.getArguments().get(i); sb.append(" ").append(arg.toString()); } } return sb.toString(); } }