Coverage Report - com.lexicalscope.jewel.cli.AbstractOptionSpecification
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractOptionSpecification
90%
60/66
84%
73/86
3.8
 
 1  
 package com.lexicalscope.jewel.cli;
 2  
 
 3  
 import static java.util.Arrays.asList;
 4  
 
 5  
 import java.util.List;
 6  
 
 7  
 import com.lexicalscope.fluentreflection.FluentMethod;
 8  
 import com.lexicalscope.jewel.cli.specification.OptionSpecification;
 9  
 import com.lexicalscope.jewel.cli.specification.SpecificationMultiplicity;
 10  
 
 11  
 /*
 12  
  * Copyright 2012 Tim Wood
 13  
  *
 14  
  * Licensed under the Apache License, Version 2.0 (the "License");
 15  
  * you may not use this file except in compliance with the License.
 16  
  * You may obtain a copy of the License at
 17  
  *
 18  
  * http://www.apache.org/licenses/LICENSE-2.0
 19  
  *
 20  
  * Unless required by applicable law or agreed to in writing, software
 21  
  * distributed under the License is distributed on an "AS IS" BASIS,
 22  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 23  
  * See the License for the specific language governing permissions and
 24  
  * limitations under the License.
 25  
  */
 26  
 
 27  566
 abstract class AbstractOptionSpecification implements OptionSpecification, Comparable<OptionSpecification> {
 28  
     protected final OptionAdapter annotation;
 29  
     private final List<String> defaultValue;
 30  
 
 31  574
     public AbstractOptionSpecification(final OptionAdapter annotation) {
 32  574
         this.annotation = annotation;
 33  
 
 34  574
         if (annotation.defaultToNull() && annotation.hasDefaultValue())
 35  
         {
 36  2
             throw new InvalidOptionSpecificationException("option cannot have null default and non-null default value: "
 37  
                     + annotation.method());
 38  
         }
 39  572
         else if (annotation.defaultToNull())
 40  
         {
 41  26
             if (annotation.isMultiValued())
 42  
             {
 43  16
                 defaultValue = null;
 44  
             }
 45  
             else
 46  
             {
 47  10
                 defaultValue = asList((String) null);
 48  
             }
 49  
         }
 50  546
         else if (annotation.hasDefaultValue())
 51  
         {
 52  34
             defaultValue = asList(annotation.defaultValue());
 53  
         }
 54  
         else
 55  
         {
 56  512
             defaultValue = null;
 57  
         }
 58  
 
 59  572
         if(hasExactCount() && exactly() < minimum() || exactly() > maximum())
 60  
         {
 61  0
             throw new InvalidOptionSpecificationException("option has maximum and minimum and exact count which can never be satisfied: "
 62  
                     + annotation.method());
 63  
         }
 64  572
         else if(minimum() > maximum())
 65  
         {
 66  0
             throw new InvalidOptionSpecificationException("minimum cannot be greater than maximum: "
 67  
                     + annotation.method());
 68  
         }
 69  572
         else if(maximum() < 0)
 70  
         {
 71  0
             throw new InvalidOptionSpecificationException("maximum must not be less than zero: "
 72  
                     + annotation.method());
 73  
         }
 74  572
     }
 75  
 
 76  
     @Override public final List<String> getDefaultValue() {
 77  1392
         return defaultValue;
 78  
     }
 79  
 
 80  
     @Override public final boolean hasDefaultValue() {
 81  1324
         return getDefaultValue() != null || annotation.defaultToNull();
 82  
     }
 83  
 
 84  
     @Override public final String getDescription() {
 85  246
         return annotation.description();
 86  
     }
 87  
 
 88  
     @Override public final Class<?> getType() {
 89  2890
         return annotation.getValueType().classUnderReflection();
 90  
     }
 91  
 
 92  
     @Override public final boolean isMultiValued() {
 93  1110
         return annotation.isMultiValued();
 94  
     }
 95  
 
 96  
     @Override public final boolean isOptional() {
 97  1348
         return getOptionalityMethod() != null || isBoolean() || hasDefaultValue();
 98  
     }
 99  
 
 100  
     public abstract boolean isBoolean();
 101  
 
 102  
     @Override public final String getCanonicalIdentifier() {
 103  1366
         return getMethod().property();
 104  
     }
 105  
 
 106  
     @Override public final FluentMethod getMethod() {
 107  2164
         return annotation.method();
 108  
     }
 109  
 
 110  
     @Override public final FluentMethod getOptionalityMethod() {
 111  1596
         return annotation.correspondingOptionalityMethod();
 112  
     }
 113  
 
 114  
     @Override public final int compareTo(final OptionSpecification other) {
 115  566
         return getCanonicalIdentifier().compareTo(other.getCanonicalIdentifier());
 116  
     }
 117  
 
 118  
     @Override public final boolean isHidden() {
 119  98
         return annotation.isHidden();
 120  
     }
 121  
 
 122  
     @Override public boolean allowedThisManyValues(final int count) {
 123  266
         if(count == 0 && !hasValue())
 124  
         {
 125  36
             return true;
 126  
         }
 127  230
         else if(count == 1 && hasValue() && !isMultiValued())
 128  
         {
 129  132
             return true;
 130  
         }
 131  98
         else if(isMultiValued() && hasExactCount())
 132  
         {
 133  4
             return count == exactly();
 134  
         }
 135  94
         else if(isMultiValued())
 136  
         {
 137  72
             return minimum() <= count && count <= maximum();
 138  
         }
 139  22
         return false;
 140  
     }
 141  
 
 142  
     @Override
 143  
    public final int maximum() {
 144  1810
         return annotation.maximum();
 145  
     }
 146  
 
 147  
     @Override
 148  
    public final int minimum() {
 149  672
         return annotation.minimum();
 150  
     }
 151  
 
 152  
     @Override
 153  
    public final int exactly() {
 154  604
         return annotation.exactly();
 155  
     }
 156  
 
 157  
     @Override
 158  
    public final boolean hasExactCount() {
 159  682
         return annotation.exactly() >= 0;
 160  
     }
 161  
 
 162  
     @Override public <T> T compareCountToSpecification(
 163  
             final int valueCount,
 164  
             final SpecificationMultiplicity<T> specificationMultiplicity) {
 165  68
         if(!hasValue() && valueCount > 0) {
 166  12
             return specificationMultiplicity.expectedNoneGotSome();
 167  56
         } else if(!isMultiValued() && hasValue() && valueCount == 0) {
 168  12
             return specificationMultiplicity.expectedOneGotNone();
 169  44
         } else if(!isMultiValued() && valueCount > 1) {
 170  20
             return specificationMultiplicity.expectedOneGotSome();
 171  24
         } else if(isMultiValued()) {
 172  24
             if(hasExactCount() && valueCount != exactly()) {
 173  8
                 if(valueCount < exactly()) {
 174  0
                     return specificationMultiplicity.expectedExactGotTooFew(exactly(), valueCount);
 175  
                 } else {
 176  8
                     return specificationMultiplicity.expectedExactGotTooMany(exactly(), valueCount);
 177  
                 }
 178  16
             } else if(valueCount < minimum()) {
 179  8
                 return specificationMultiplicity.expectedMinimumGotTooFew(minimum(), valueCount);
 180  8
             } else if(valueCount > maximum()) {
 181  8
                 return specificationMultiplicity.expectedMaximumGotTooMany(maximum(), valueCount);
 182  
             }
 183  
         }
 184  0
         return specificationMultiplicity.allowed();
 185  
     }
 186  
 
 187  
     @Override public int maximumArgumentConsumption() {
 188  24
         if(isMultiValued()) {
 189  10
             if(hasExactCount()) {
 190  0
                 return exactly();
 191  
             } else {
 192  10
                 return maximum();
 193  
             }
 194  14
         } else if (hasValue()) {
 195  8
             return 1;
 196  
         }
 197  6
         return 0;
 198  
     }
 199  
 }