Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
PrefixedLeftPaddedNumericGenerator |
|
| 2.375;2.375 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | package org.apache.commons.id.serial; | |
18 | ||
19 | import org.apache.commons.id.AbstractStringIdentifierGenerator; | |
20 | ||
21 | /** | |
22 | * <code>PrefixedLeftPaddedNumericGenerator</code> is an Identifier Generator | |
23 | * that generates a left-padded incrementing number with a prefix as a String object. | |
24 | * | |
25 | * <p>All generated ids have the same length (prefixed and padded with 0's | |
26 | * on the left), which is determined by the <code>size</code> parameter passed | |
27 | * to the constructor.<p> | |
28 | * | |
29 | * <p>The <code>wrap</code> property determines whether or not the sequence wraps | |
30 | * when it reaches the largest value that can be represented in <code>size</code> | |
31 | * base 10 digits. If <code>wrap</code> is false and the the maximum representable | |
32 | * value is exceeded, an {@link IllegalStateException} is thrown.</p> | |
33 | * | |
34 | * @author Commons-Id team | |
35 | * @version $Id$ | |
36 | */ | |
37 | public class PrefixedLeftPaddedNumericGenerator extends AbstractStringIdentifierGenerator { | |
38 | ||
39 | /** Prefix. */ | |
40 | private final String prefix; | |
41 | ||
42 | /** Should the counter wrap. */ | |
43 | 13 | private boolean wrap = true; |
44 | ||
45 | /** The counter. */ | |
46 | 13 | private char[] count = null; |
47 | ||
48 | /** '9' char. */ | |
49 | private static final char NINE_CHAR = '9'; | |
50 | ||
51 | ||
52 | /** | |
53 | * Create a new prefixed left-padded numeric generator with the specified prefix. | |
54 | * | |
55 | * @param prefix prefix, must not be null or empty | |
56 | * @param wrap should the factory wrap when it reaches the maximum | |
57 | * value that can be represented in <code>size</code> base 10 digits | |
58 | * (or throw an exception) | |
59 | * @param size the size of the identifier, including prefix length | |
60 | * @throws IllegalArgumentException if size less prefix length is not at least one | |
61 | * @throws NullPointerException if prefix is <code>null</code> | |
62 | */ | |
63 | public PrefixedLeftPaddedNumericGenerator(String prefix, boolean wrap, int size) { | |
64 | 13 | super(); |
65 | ||
66 | 13 | if (prefix == null) { |
67 | 1 | throw new NullPointerException("prefix must not be null"); |
68 | } | |
69 | 12 | if (size < 1) { |
70 | 2 | throw new IllegalArgumentException("size must be at least one"); |
71 | } | |
72 | 10 | if (size <= prefix.length()) { |
73 | 2 | throw new IllegalArgumentException("size less prefix length must be at least one"); |
74 | } | |
75 | 8 | this.wrap = wrap; |
76 | 8 | this.prefix = prefix; |
77 | ||
78 | 8 | int countLength = size - prefix.length(); |
79 | 8 | this.count = new char[countLength]; |
80 | 74 | for (int i = 0; i < countLength; i++) { |
81 | 66 | count[i] = '0'; |
82 | } | |
83 | 8 | } |
84 | ||
85 | ||
86 | /** | |
87 | * Return the prefix for this prefixed numeric generator. | |
88 | * | |
89 | * @return the prefix for this prefixed numeric generator | |
90 | */ | |
91 | public String getPrefix() { | |
92 | 1 | return prefix; |
93 | } | |
94 | ||
95 | public long maxLength() { | |
96 | 1 | return this.count.length + prefix.length(); |
97 | } | |
98 | ||
99 | public long minLength() { | |
100 | 1 | return this.count.length + prefix.length(); |
101 | } | |
102 | ||
103 | /** | |
104 | * Returns the (constant) size of the strings generated by this generator. | |
105 | * | |
106 | * @return the size of generated identifiers | |
107 | */ | |
108 | public int getSize() { | |
109 | 1 | return this.count.length + prefix.length(); |
110 | } | |
111 | ||
112 | /** | |
113 | * Getter for property wrap. | |
114 | * | |
115 | * @return <code>true</code> if this generator is set up to wrap | |
116 | */ | |
117 | public boolean isWrap() { | |
118 | 3 | return wrap; |
119 | } | |
120 | ||
121 | /** | |
122 | * Setter for property wrap. | |
123 | * | |
124 | * @param wrap should the factory wrap when it reaches the maximum | |
125 | * value that can be represented in <code>size</code> base 10 digits | |
126 | * (or throw an exception) | |
127 | */ | |
128 | public void setWrap(boolean wrap) { | |
129 | 2 | this.wrap = wrap; |
130 | 2 | } |
131 | ||
132 | public String nextStringIdentifier() { | |
133 | 64 | for (int i = count.length - 1; i >= 0; i--) { |
134 | 33 | switch (count[i]) { |
135 | case NINE_CHAR: // 9 | |
136 | 3 | count[i] = '0'; |
137 | 3 | if (i == 0 && !wrap) { |
138 | 1 | throw new IllegalStateException |
139 | ("The maximum number of identifiers has been reached"); | |
140 | } | |
141 | break; | |
142 | ||
143 | default: | |
144 | 30 | count[i]++; |
145 | 30 | i = -1; |
146 | break; | |
147 | } | |
148 | } | |
149 | ||
150 | 31 | StringBuffer sb = new StringBuffer(prefix); |
151 | 31 | sb.append(count); |
152 | 31 | return sb.toString(); |
153 | } | |
154 | } |