1 /***********************************************************************************************************************
2 Copyright (c) 2003, International Barcode Consortium
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this list of
11 conditions and the following disclaimer in the documentation and/or other materials
12 provided with the distribution.
13 * Neither the name of the International Barcode Consortium nor the names of any contributors may be used to endorse
14 or promote products derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 POSSIBILITY OF SUCH DAMAGE.
25 ***********************************************************************************************************************/
26
27 package net.sourceforge.barbecue.linear.code39;
28
29 import net.sourceforge.barbecue.Module;
30
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 /**
37 * The Code 39 barcode module definitions.
38 *
39 * @author <a href="mailto:opensource@ianbourke.com">Ian Bourke</a>
40 */
41 public final class ModuleFactory {
42
43 /**
44 * The start and stop character for the barcode
45 */
46 public static final Module START_STOP = new Module(new int[]{1, 2, 1, 1, 2, 1, 2, 1, 1});
47
48 private static final List KEYS = new ArrayList();
49 private static final Map SET = new HashMap();
50 private static final Map EXT_CHARS = new HashMap();
51 private static final List ESCAPE_CHARS = new ArrayList();
52
53 static {
54 initBaseSet();
55 initExtendedSet();
56 }
57
58
59 /**
60 * Cannot construct.
61 */
62 private ModuleFactory() {
63 }
64
65
66 /**
67 * Initialise the module definitions.
68 */
69 private static void initBaseSet() {
70 KEYS.add("0");
71 SET.put("0", new Module(new int[]{1, 1, 1, 2, 2, 1, 2, 1, 1}));
72 KEYS.add("1");
73 SET.put("1", new Module(new int[]{2, 1, 1, 2, 1, 1, 1, 1, 2}));
74 KEYS.add("2");
75 SET.put("2", new Module(new int[]{1, 1, 2, 2, 1, 1, 1, 1, 2}));
76 KEYS.add("3");
77 SET.put("3", new Module(new int[]{2, 1, 2, 2, 1, 1, 1, 1, 1}));
78 KEYS.add("4");
79 SET.put("4", new Module(new int[]{1, 1, 1, 2, 2, 1, 1, 1, 2}));
80 KEYS.add("5");
81 SET.put("5", new Module(new int[]{2, 1, 1, 2, 2, 1, 1, 1, 1}));
82 KEYS.add("6");
83 SET.put("6", new Module(new int[]{1, 1, 2, 2, 2, 1, 1, 1, 1}));
84 KEYS.add("7");
85 SET.put("7", new Module(new int[]{1, 1, 1, 2, 1, 1, 2, 1, 2}));
86 KEYS.add("8");
87 SET.put("8", new Module(new int[]{2, 1, 1, 2, 1, 1, 2, 1, 1}));
88 KEYS.add("9");
89 SET.put("9", new Module(new int[]{1, 1, 2, 2, 1, 1, 2, 1, 1}));
90 KEYS.add("A");
91 SET.put("A", new Module(new int[]{2, 1, 1, 1, 1, 2, 1, 1, 2}));
92 KEYS.add("B");
93 SET.put("B", new Module(new int[]{1, 1, 2, 1, 1, 2, 1, 1, 2}));
94 KEYS.add("C");
95 SET.put("C", new Module(new int[]{2, 1, 2, 1, 1, 2, 1, 1, 1}));
96 KEYS.add("D");
97 SET.put("D", new Module(new int[]{1, 1, 1, 1, 2, 2, 1, 1, 2}));
98 KEYS.add("E");
99 SET.put("E", new Module(new int[]{2, 1, 1, 1, 2, 2, 1, 1, 1}));
100 KEYS.add("F");
101 SET.put("F", new Module(new int[]{1, 1, 2, 1, 2, 2, 1, 1, 1}));
102 KEYS.add("G");
103 SET.put("G", new Module(new int[]{1, 1, 1, 1, 1, 2, 2, 1, 2}));
104 KEYS.add("H");
105 SET.put("H", new Module(new int[]{2, 1, 1, 1, 1, 2, 2, 1, 1}));
106 KEYS.add("I");
107 SET.put("I", new Module(new int[]{1, 1, 2, 1, 1, 2, 2, 1, 1}));
108 KEYS.add("J");
109 SET.put("J", new Module(new int[]{1, 1, 1, 1, 2, 2, 2, 1, 1}));
110 KEYS.add("K");
111 SET.put("K", new Module(new int[]{2, 1, 1, 1, 1, 1, 1, 2, 2}));
112 KEYS.add("L");
113 SET.put("L", new Module(new int[]{1, 1, 2, 1, 1, 1, 1, 2, 2}));
114 KEYS.add("M");
115 SET.put("M", new Module(new int[]{2, 1, 2, 1, 1, 1, 1, 2, 1}));
116 KEYS.add("N");
117 SET.put("N", new Module(new int[]{1, 1, 1, 1, 2, 1, 1, 2, 2}));
118 KEYS.add("O");
119 SET.put("O", new Module(new int[]{2, 1, 1, 1, 2, 1, 1, 2, 1}));
120 KEYS.add("P");
121 SET.put("P", new Module(new int[]{1, 1, 2, 1, 2, 1, 1, 2, 1}));
122 KEYS.add("Q");
123 SET.put("Q", new Module(new int[]{1, 1, 1, 1, 1, 1, 2, 2, 2}));
124 KEYS.add("R");
125 SET.put("R", new Module(new int[]{2, 1, 1, 1, 1, 1, 2, 2, 1}));
126 KEYS.add("S");
127 SET.put("S", new Module(new int[]{1, 1, 2, 1, 1, 1, 2, 2, 1}));
128 KEYS.add("T");
129 SET.put("T", new Module(new int[]{1, 1, 1, 1, 2, 1, 2, 2, 1}));
130 KEYS.add("U");
131 SET.put("U", new Module(new int[]{2, 2, 1, 1, 1, 1, 1, 1, 2}));
132 KEYS.add("V");
133 SET.put("V", new Module(new int[]{1, 2, 2, 1, 1, 1, 1, 1, 2}));
134 KEYS.add("W");
135 SET.put("W", new Module(new int[]{2, 2, 2, 1, 1, 1, 1, 1, 1}));
136 KEYS.add("X");
137 SET.put("X", new Module(new int[]{1, 2, 1, 1, 2, 1, 1, 1, 2}));
138 KEYS.add("Y");
139 SET.put("Y", new Module(new int[]{2, 2, 1, 1, 2, 1, 1, 1, 1}));
140 KEYS.add("Z");
141 SET.put("Z", new Module(new int[]{1, 2, 2, 1, 2, 1, 1, 1, 1}));
142 KEYS.add("-");
143 SET.put("-", new Module(new int[]{1, 2, 1, 1, 1, 1, 2, 1, 2}));
144 KEYS.add(".");
145 SET.put(".", new Module(new int[]{2, 2, 1, 1, 1, 1, 2, 1, 1}));
146 KEYS.add(" ");
147 SET.put(" ", new Module(new int[]{1, 2, 2, 1, 1, 1, 2, 1, 1}));
148 KEYS.add("$");
149 SET.put("$", new Module(new int[]{1, 2, 1, 2, 1, 2, 1, 1, 1}));
150 KEYS.add("/");
151 SET.put("/", new Module(new int[]{1, 2, 1, 2, 1, 1, 1, 2, 1}));
152 KEYS.add("+");
153 SET.put("+", new Module(new int[]{1, 2, 1, 1, 1, 2, 1, 2, 1}));
154 KEYS.add("%");
155 SET.put("%", new Module(new int[]{1, 1, 1, 2, 1, 2, 1, 2, 1}));
156 }
157
158 /**
159 * Initialise the extended ASCII set lookup table.
160 */
161 private static void initExtendedSet() {
162 ESCAPE_CHARS.add("$");
163 ESCAPE_CHARS.add("/");
164 ESCAPE_CHARS.add("+");
165 ESCAPE_CHARS.add("%");
166
167 EXT_CHARS.put(new Character('\000'), "%U");
168 EXT_CHARS.put(new Character('\001'), "$A");
169 EXT_CHARS.put(new Character('\002'), "$B");
170 EXT_CHARS.put(new Character('\003'), "$C");
171 EXT_CHARS.put(new Character('\004'), "$D");
172 EXT_CHARS.put(new Character('\005'), "$E");
173 EXT_CHARS.put(new Character('\006'), "$F");
174 EXT_CHARS.put(new Character('\007'), "$G");
175 EXT_CHARS.put(new Character('\010'), "$H");
176 EXT_CHARS.put(new Character('\011'), "$I");
177 EXT_CHARS.put(new Character('\012'), "$J");
178 EXT_CHARS.put(new Character('\013'), "$K");
179 EXT_CHARS.put(new Character('\014'), "$L");
180 EXT_CHARS.put(new Character('\015'), "$M");
181 EXT_CHARS.put(new Character('\016'), "$N");
182 EXT_CHARS.put(new Character('\017'), "$O");
183 EXT_CHARS.put(new Character('\020'), "$P");
184 EXT_CHARS.put(new Character('\021'), "$Q");
185 EXT_CHARS.put(new Character('\022'), "$R");
186 EXT_CHARS.put(new Character('\023'), "$S");
187 EXT_CHARS.put(new Character('\024'), "$T");
188 EXT_CHARS.put(new Character('\025'), "$U");
189 EXT_CHARS.put(new Character('\026'), "$V");
190 EXT_CHARS.put(new Character('\027'), "$W");
191 EXT_CHARS.put(new Character('\030'), "$X");
192 EXT_CHARS.put(new Character('\031'), "$Y");
193 EXT_CHARS.put(new Character('\032'), "$Z");
194 EXT_CHARS.put(new Character('\033'), "%A");
195 EXT_CHARS.put(new Character('\034'), "%B");
196 EXT_CHARS.put(new Character('\035'), "%C");
197 EXT_CHARS.put(new Character('\036'), "%D");
198 EXT_CHARS.put(new Character('\037'), "%E");
199 EXT_CHARS.put(new Character('\177'), "%T");
200
201 EXT_CHARS.put(new Character('!'), "/A");
202 EXT_CHARS.put(new Character('"'), "/B");
203 EXT_CHARS.put(new Character('#'), "/C");
204 EXT_CHARS.put(new Character('$'), "/D");
205 EXT_CHARS.put(new Character('%'), "/E");
206 EXT_CHARS.put(new Character('&'), "/F");
207 EXT_CHARS.put(new Character('\''), "/G");
208 EXT_CHARS.put(new Character('('), "/H");
209 EXT_CHARS.put(new Character(')'), "/I");
210 EXT_CHARS.put(new Character('*'), "/J");
211 EXT_CHARS.put(new Character('+'), "/K");
212 EXT_CHARS.put(new Character(','), "/L");
213 EXT_CHARS.put(new Character('/'), "/O");
214 EXT_CHARS.put(new Character(':'), "/Z");
215 EXT_CHARS.put(new Character(';'), "%F");
216 EXT_CHARS.put(new Character('«'), "%G");
217 EXT_CHARS.put(new Character('='), "%H");
218 EXT_CHARS.put(new Character('>'), "%I");
219 EXT_CHARS.put(new Character('?'), "%J");
220 EXT_CHARS.put(new Character('@'), "%V");
221 EXT_CHARS.put(new Character('['), "%K");
222 EXT_CHARS.put(new Character('\\'), "%L");
223 EXT_CHARS.put(new Character(']'), "%M");
224 EXT_CHARS.put(new Character('^'), "%N");
225 EXT_CHARS.put(new Character('_'), "%O");
226 EXT_CHARS.put(new Character('`'), "%W");
227 EXT_CHARS.put(new Character('{'), "%P");
228 EXT_CHARS.put(new Character('|'), "%Q");
229 EXT_CHARS.put(new Character('}'), "%R");
230 EXT_CHARS.put(new Character('~'), "%S");
231
232 EXT_CHARS.put(new Character('a'), "+A");
233 EXT_CHARS.put(new Character('b'), "+B");
234 EXT_CHARS.put(new Character('c'), "+C");
235 EXT_CHARS.put(new Character('d'), "+D");
236 EXT_CHARS.put(new Character('e'), "+E");
237 EXT_CHARS.put(new Character('f'), "+F");
238 EXT_CHARS.put(new Character('g'), "+G");
239 EXT_CHARS.put(new Character('h'), "+H");
240 EXT_CHARS.put(new Character('i'), "+I");
241 EXT_CHARS.put(new Character('j'), "+J");
242 EXT_CHARS.put(new Character('k'), "+K");
243 EXT_CHARS.put(new Character('l'), "+L");
244 EXT_CHARS.put(new Character('m'), "+M");
245 EXT_CHARS.put(new Character('n'), "+N");
246 EXT_CHARS.put(new Character('o'), "+O");
247 EXT_CHARS.put(new Character('p'), "+P");
248 EXT_CHARS.put(new Character('q'), "+Q");
249 EXT_CHARS.put(new Character('r'), "+R");
250 EXT_CHARS.put(new Character('s'), "+S");
251 EXT_CHARS.put(new Character('t'), "+T");
252 EXT_CHARS.put(new Character('u'), "+U");
253 EXT_CHARS.put(new Character('v'), "+V");
254 EXT_CHARS.put(new Character('w'), "+W");
255 EXT_CHARS.put(new Character('x'), "+X");
256 EXT_CHARS.put(new Character('y'), "+Y");
257 EXT_CHARS.put(new Character('z'), "+Z");
258 }
259
260 /**
261 * Returns the module that represents the specified character.
262 *
263 * @param key The data character to get the encoding module for
264 * @return The module that encodes the given char
265 */
266 public static Module getModule(String key) {
267 Module module = null;
268 module = (Module) SET.get(key);
269 module.setSymbol(key);
270 return module;
271 }
272
273 /**
274 * Returns the index of the given character in the encoding tables. This is used
275 * when calculating the checksum.
276 *
277 * @param key The data character sequence to get the index for
278 * @return The index for the given key
279 */
280 public static int getIndex(String key) {
281 return KEYS.indexOf(key);
282 }
283
284 /**
285 * Indicates whether the given key is represented in the default encoding
286 * table that this module factory contains.
287 *
288 * @return True if the key has a direct module encoding, false if not
289 */
290 public static boolean hasModule(String key, boolean extendedMode) {
291 if (extendedMode && ESCAPE_CHARS.contains(key)) {
292 return false;
293 }
294 return getIndex(key) != -1;
295 }
296
297 /**
298 * Returns the encoded module at the given index position. This is used to
299 * get the encoded checksum character.
300 *
301 * @param index The index to get the module for
302 * @return The module at the specified index
303 */
304 public static Module getModuleForIndex(int index) {
305 return getModule((String) KEYS.get(index));
306 }
307
308 /**
309 * Returns the string of characters from the standard encoding table that encode
310 * the given extended character set character.
311 *
312 * @param c The character from the extended ASCII set to encode
313 * @return The string of characters from the default Code 39 encoding table that represent the given character
314 */
315 public static String getExtendedCharacter(char c) {
316 return (String) EXT_CHARS.get(new Character(c));
317 }
318 }