001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.console.widgets;
018
019/**
020 * The comparison operator of a declarative single-field rule.
021 *
022 * <p>
023 * One vocabulary, one place.  Every rule in the toolkit that tests one row field against one value shares these
024 * constants &mdash; {@link ActionRef#enabledWhen(String,Op,Object,String) the action-bar state rule} here, and the
025 * {@code RowClassRule} row decorator in the views module, and the views module's {@code VisibilityRule}.  It lives in this module because the widgets&rarr;views
026 * dependency does not exist, so the shared type has to sit on the side both can see.
027 *
028 * <p>
029 * {@link #IN}/{@link #CONTAINS} are collection operators (the value is a list, or the tested field is) used by
030 * visibility rules only.
031 *
032 * <p>
033 * {@link #EQ}/{@link #NE}/{@link #IN}/{@link #CONTAINS} <b>require</b> a comparison value; {@link #PRESENT}/{@link #ABSENT} test only whether the
034 * field is non-null/non-empty and therefore <b>omit</b> one.  {@link #requiresValue()} is the discriminator, and
035 * every host is expected to reject the mismatched form rather than ignore the surplus value.
036 *
037 * <p>
038 * Each constant also carries its lowercase wire token, for the hosts that do serialize a rule.
039 *
040 * @since 10.0.0
041 */
042public enum Op {
043
044   /** Matches when the tested field equals the rule value. */
045   EQ("eq"),
046
047   /** Matches when the tested field does not equal the rule value. */
048   NE("ne"),
049
050   /** Matches when the tested field is non-null/non-empty (no value needed). */
051   PRESENT("present"),
052
053   /** Matches when the tested field is missing/null (no value needed). */
054   ABSENT("absent"),
055
056   /** Matches when the tested field equals one of the values in the rule's value list (the value is a list). */
057   IN("in"),
058
059   /** Matches when the tested field (itself a list) contains the rule's value. */
060   CONTAINS("contains");
061
062   private final String wire;
063
064   Op(String wire) {
065      this.wire = wire;
066   }
067
068   /**
069    * Returns the lowercase wire token for this operator.
070    *
071    * @return The wire token (e.g. <c>"eq"</c>).
072    */
073   public String wire() {
074      return wire;
075   }
076
077   /**
078    * Whether this operator requires a comparison value ({@link #EQ}/{@link #NE}/{@link #IN}/{@link #CONTAINS}).
079    *
080    * @return <jk>true</jk> for {@link #EQ}, {@link #NE}, {@link #IN} and {@link #CONTAINS}, <jk>false</jk> for {@link #PRESENT} and
081    *    {@link #ABSENT}.
082    */
083   public boolean requiresValue() {
084      return this == EQ || this == NE || this == IN || this == CONTAINS;
085   }
086
087   /**
088    * Whether this operator is a collection operator ({@link #IN}/{@link #CONTAINS}).
089    *
090    * <p>
091    * Only the visibility rule evaluator understands these; the disable-with-reason rules accept the original four.
092    *
093    * @return <jk>true</jk> for {@link #IN} and {@link #CONTAINS}.
094    */
095   public boolean isCollectionOp() {
096      return this == IN || this == CONTAINS;
097   }
098}