Java tutorial
/** * Copyright (C) 2010-16 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 com.github.rvesse.airline.restrictions.common; import java.util.Collection; import java.util.Set; import java.util.TreeSet; import org.apache.commons.collections4.CollectionUtils; import com.github.rvesse.airline.help.sections.HelpFormat; import com.github.rvesse.airline.help.sections.HelpHint; import com.github.rvesse.airline.model.ArgumentsMetadata; import com.github.rvesse.airline.model.OptionMetadata; import com.github.rvesse.airline.parser.ParseState; import com.github.rvesse.airline.restrictions.AbstractCommonRestriction; import com.github.rvesse.airline.restrictions.ArgumentsRestriction; import com.github.rvesse.airline.restrictions.OptionRestriction; import com.github.rvesse.airline.utils.AirlineUtils; import com.github.rvesse.airline.utils.predicates.parser.ParsedOptionFinder; public class PartialRestriction extends AbstractCommonRestriction implements HelpHint { private final Set<Integer> indices = new TreeSet<>(); private final OptionRestriction optionRestriction; private final ArgumentsRestriction argumentsRestriction; private final HelpHint hint; private PartialRestriction(OptionRestriction optionRestriction) { this.optionRestriction = optionRestriction; this.argumentsRestriction = optionRestriction instanceof ArgumentsRestriction ? (ArgumentsRestriction) optionRestriction : null; this.hint = optionRestriction instanceof HelpHint ? (HelpHint) optionRestriction : null; } private PartialRestriction(ArgumentsRestriction argumentsRestriction) { this.optionRestriction = argumentsRestriction instanceof OptionRestriction ? (OptionRestriction) argumentsRestriction : null; this.argumentsRestriction = argumentsRestriction; this.hint = argumentsRestriction instanceof HelpHint ? (HelpHint) argumentsRestriction : null; } public PartialRestriction(int[] indices, OptionRestriction optionRestriction) { this(optionRestriction); for (int i : indices) { this.indices.add(i); } } public PartialRestriction(int[] indices, ArgumentsRestriction argumentsRestriction) { this(argumentsRestriction); for (int i : indices) { this.indices.add(i); } } public PartialRestriction(Collection<Integer> indices, OptionRestriction optionRestriction) { this(optionRestriction); this.indices.addAll(indices); } public PartialRestriction(Collection<Integer> indices, ArgumentsRestriction argumentsRestriction) { this(argumentsRestriction); this.indices.addAll(indices); } private <T> boolean isApplicableToOption(ParseState<T> state, OptionMetadata option) { int index = CollectionUtils.countMatches(state.getParsedOptions(), new ParsedOptionFinder(option)) % option.getArity(); return indices.contains(index); } @Override public <T> void preValidate(ParseState<T> state, OptionMetadata option, String value) { if (optionRestriction == null) return; if (!isApplicableToOption(state, option)) return; this.optionRestriction.preValidate(state, option, value); } @Override public <T> void postValidate(ParseState<T> state, OptionMetadata option, Object value) { if (optionRestriction == null) return; if (!isApplicableToOption(state, option)) return; this.optionRestriction.postValidate(state, option, value); } private <T> boolean isApplicableToArgument(ParseState<T> state) { int index = state.getParsedArguments().size(); return indices.contains(index); } @Override public <T> void preValidate(ParseState<T> state, ArgumentsMetadata arguments, String value) { if (argumentsRestriction == null) return; if (!isApplicableToArgument(state)) return; this.argumentsRestriction.preValidate(state, arguments, value); } @Override public <T> void postValidate(ParseState<T> state, ArgumentsMetadata arguments, Object value) { if (argumentsRestriction == null) return; if (!isApplicableToArgument(state)) return; this.argumentsRestriction.postValidate(state, arguments, value); } @Override public String getPreamble() { if (this.hint == null) return null; // Add a note about the restriction to the specific arguments StringBuilder builder = new StringBuilder(); builder.append("The following restriction only applies to the "); int count = 0; for (int i : this.indices) { if (count > 0) builder.append(", "); builder.append(AirlineUtils.toOrdinal(i + 1)); count++; } builder.append(" value"); if (this.indices.size() > 1) builder.append('s'); builder.append(": "); if (this.hint.getPreamble() != null) builder.append(this.hint.getPreamble()); return builder.toString(); } @Override public HelpFormat getFormat() { return this.hint != null ? this.hint.getFormat() : HelpFormat.NONE_PRINTABLE; } @Override public int numContentBlocks() { return this.hint != null ? this.hint.numContentBlocks() : 0; } @Override public String[] getContentBlock(int blockNumber) { if (this.hint != null) { return this.hint.getContentBlock(blockNumber); } else { throw new IndexOutOfBoundsException(); } } }