001 /* 002 * The MIT License 003 * 004 * Copyright (c) 2013, Ninja Squad 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in 014 * all copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 022 * THE SOFTWARE. 023 */ 024 025 package com.ninja_squad.dbsetup.generator; 026 027 import com.ninja_squad.dbsetup.util.Preconditions; 028 029 /** 030 * A {@link ValueGenerator} that returns a string prefix followed by a sequence number, optionally left-padded 031 * with 0 to ensure a correct ordering (for example: CODE_001, CODE_002, etc.). Instances of this generator 032 * are created by {@link ValueGenerators#stringSequence(String)}. 033 * @author JB 034 */ 035 public final class StringSequenceValueGenerator implements ValueGenerator<String> { 036 private String prefix; 037 private long next; 038 private int increment; 039 040 /** 041 * The length of the number once padded. 0 if no padding must be applied 042 */ 043 private int paddedNumberLength; 044 045 StringSequenceValueGenerator(String prefix) { 046 this(prefix, 1L, 1, 0); 047 } 048 049 private StringSequenceValueGenerator(String prefix, long next, int increment, int paddedNumberLength) { 050 this.prefix = prefix; 051 this.next = next; 052 this.increment = increment; 053 this.paddedNumberLength = paddedNumberLength; 054 } 055 056 /** 057 * Tells the generator to left-pad the number it generates with 0 until the length of the number is the given 058 * length. For example, passing 3 to this method will generate numbers 001, 002, 003, 004, etc. If the generated 059 * number, before padding, has a length already equal or larger that the given length, the number is not padded. 060 * @param paddedNumberLength the length of the number once padded. Must be > 0. 061 * @return this instance, for chaining 062 */ 063 public StringSequenceValueGenerator withLeftPadding(int paddedNumberLength) { 064 Preconditions.checkArgument(paddedNumberLength > 0, "paddedNumberLength must be > 0"); 065 this.paddedNumberLength = paddedNumberLength; 066 return this; 067 } 068 069 /** 070 * Tells the generator to avoid left-padding the number it generates with 0 071 * @return this instance, for chaining 072 */ 073 public StringSequenceValueGenerator withoutLeftPadding() { 074 this.paddedNumberLength = 0; 075 return this; 076 } 077 078 /** 079 * Restarts the sequence at the given value 080 * @param start the new starting value of the sequence 081 * @return this instance, for chaining 082 */ 083 public StringSequenceValueGenerator startingAt(long start) { 084 this.next = start; 085 return this; 086 } 087 088 /** 089 * Increments the number by the given increment. 090 * @return this instance, for chaining 091 */ 092 public StringSequenceValueGenerator incrementingBy(int increment) { 093 this.increment = increment; 094 return this; 095 } 096 097 @Override 098 public String nextValue() { 099 long number = next; 100 next += increment; 101 return prefix + leftPadIfNecessary(number); 102 } 103 104 private String leftPadIfNecessary(long number) { 105 String numberAsString = Long.toString(number); 106 if (numberAsString.length() >= paddedNumberLength) { 107 return numberAsString; 108 } 109 StringBuilder builder = new StringBuilder(paddedNumberLength); 110 for (int i = 0; i < paddedNumberLength - numberAsString.length(); i++) { 111 builder.append('0'); 112 } 113 return builder.append(numberAsString).toString(); 114 } 115 116 @Override 117 public String toString() { 118 return "StringSequenceValueGenerator[" 119 + "prefix='" + prefix + '\'' 120 + ", next=" + next 121 + ", increment=" + increment 122 + ", paddedNumberLength=" + paddedNumberLength 123 + "]"; 124 } 125 }