1 /* 2 * Copyright 2007 Kasper B. Graversen 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.supercsv.cellprocessor.constraint; 17 18 import java.util.HashSet; 19 import java.util.Set; 20 21 import org.supercsv.cellprocessor.CellProcessorAdaptor; 22 import org.supercsv.cellprocessor.ift.CellProcessor; 23 import org.supercsv.cellprocessor.ift.StringCellProcessor; 24 import org.supercsv.exception.SuperCsvCellProcessorException; 25 import org.supercsv.exception.SuperCsvConstraintViolationException; 26 import org.supercsv.util.CsvContext; 27 28 /** 29 * This processor ensures that the input String has a length equal to any of the supplied lengths. The length 30 * constraints must all be {@code > 0} or an exception is thrown. Lookup time is O(1). 31 * 32 * @author Kasper B. Graversen 33 * @author Dominique De Vito 34 * @author James Bassett 35 */ 36 public class Strlen extends CellProcessorAdaptor implements StringCellProcessor { 37 38 private final Set<Integer> requiredLengths = new HashSet<Integer>(); 39 40 /** 41 * Constructs a new <tt>Strlen</tt> processor, which ensures that the input String has a length equal to any of the 42 * supplied lengths. 43 * 44 * @param requiredLengths 45 * one or more required lengths 46 * @throws NullPointerException 47 * if requiredLengths is null 48 * @throws IllegalArgumentException 49 * if requiredLengths is empty or contains a negative length 50 */ 51 public Strlen(final int... requiredLengths) { 52 super(); 53 checkPreconditions(requiredLengths); 54 checkAndAddLengths(requiredLengths); 55 } 56 57 /** 58 * Constructs a new <tt>Strlen</tt> processor, which ensures that the input String has a length equal to the 59 * supplied length, then calls the next processor in the chain. 60 * 61 * @param requiredLength 62 * the required length 63 * @param next 64 * the next processor in the chain 65 * @throws NullPointerException 66 * if next is null 67 * @throws IllegalArgumentException 68 * if requiredLength is negative 69 */ 70 public Strlen(final int requiredLength, final CellProcessor next) { 71 this(new int[] { requiredLength }, next); 72 } 73 74 /** 75 * Constructs a new <tt>Strlen</tt> processor, which ensures that the input String has a length equal to any of the 76 * supplied lengths, then calls the next processor in the chain. 77 * 78 * @param requiredLengths 79 * one or more required lengths 80 * @param next 81 * the next processor in the chain 82 * @throws NullPointerException 83 * if requiredLengths or next is null 84 * @throws IllegalArgumentException 85 * if requiredLengths is empty or contains a negative length 86 */ 87 public Strlen(final int[] requiredLengths, final CellProcessor next) { 88 super(next); 89 checkPreconditions(requiredLengths); 90 checkAndAddLengths(requiredLengths); 91 } 92 93 /** 94 * Checks the preconditions for creating a new Strlen processor. 95 * 96 * @param requiredLengths 97 * one or more required lengths 98 * @throws NullPointerException 99 * if requiredLengths is null 100 * @throws IllegalArgumentException 101 * if requiredLengths is empty 102 */ 103 private static void checkPreconditions(final int... requiredLengths) { 104 if( requiredLengths == null ) { 105 throw new NullPointerException("requiredLengths should not be null"); 106 } else if( requiredLengths.length == 0 ) { 107 throw new IllegalArgumentException("requiredLengths should not be empty"); 108 } 109 } 110 111 /** 112 * Adds each required length, ensuring it isn't negative. 113 * 114 * @param requiredLengths 115 * one or more required lengths 116 * @throws IllegalArgumentException 117 * if a supplied length is negative 118 */ 119 private void checkAndAddLengths(final int... requiredLengths) { 120 for( final int length : requiredLengths ) { 121 if( length < 0 ) { 122 throw new IllegalArgumentException(String.format("required length cannot be negative but was %d", 123 length)); 124 } 125 this.requiredLengths.add(length); 126 } 127 } 128 129 /** 130 * {@inheritDoc} 131 * 132 * @throws SuperCsvCellProcessorException 133 * if value is null 134 * @throws SuperCsvConstraintViolationException 135 * if the length of value isn't one of the required lengths 136 */ 137 public Object execute(final Object value, final CsvContext context) { 138 validateInputNotNull(value, context); 139 140 final String stringValue = value.toString(); 141 final int length = stringValue.length(); 142 if( !requiredLengths.contains(length) ) { 143 throw new SuperCsvConstraintViolationException(String.format("the length (%d) of value '%s' not any of the required lengths", 144 length, stringValue), context, this); 145 } 146 147 return next.execute(value, context); 148 } 149 150 }