View Javadoc

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      ///CLOVER:OFF
59      /**
60       * Cannot construct.
61       */
62      private ModuleFactory() {
63      }
64      ///CLOVER:ON
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"); // Also %X, %Y, %Z
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 }