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.upc;
28
29 import net.sourceforge.barbecue.Module;
30 import net.sourceforge.barbecue.BlankModule;
31
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 /**
38 * The UPC-A barcode module definitions.
39 *
40 * @author <a href="mailto:james@metalskin.com">James Jenner</a>
41 */
42 public class ModuleFactory {
43
44 /** The guards for the barcode */
45 public static final Module LEFT_GUARD = new Module(new int[] {1, 1, 1});
46 public static final Module CENTRE_GUARD = new Module(new int[] {0, 1, 1, 1, 1, 1});
47 public static final Module RIGHT_GUARD = new Module(new int[] {1, 1, 1});
48
49 public final static Module LEFT_MARGIN = new BlankModule(11);
50 public final static Module RIGHT_MARGIN = new BlankModule(11);;
51
52 protected static final List KEYS_LEFT = new ArrayList();
53 protected static final List KEYS_RIGHT = new ArrayList();
54
55 protected static final Map SET_LEFT = new HashMap();
56 protected static final Map SET_RIGHT = new HashMap();
57
58 public static final int LEFT_WIDTH = 6;
59 public static final int GUARD_CHAR_SIZE = 1;
60
61 static {
62 initBaseSet();
63 }
64
65 /**
66 * Cannot construct.
67 */
68 protected ModuleFactory() {
69 }
70
71
72
73
74 /**
75 * Initialise the module definitions.
76 */
77 protected static void initBaseSet() {
78 initRightSet();
79 initLeftSet();
80 }
81
82 protected static void initRightSet() {
83
84 KEYS_RIGHT.add("0"); SET_RIGHT.put("0", new Module(new int[] {3, 2, 1, 1}));
85 KEYS_RIGHT.add("1"); SET_RIGHT.put("1", new Module(new int[] {2, 2, 2, 1}));
86 KEYS_RIGHT.add("2"); SET_RIGHT.put("2", new Module(new int[] {2, 1, 2, 2}));
87 KEYS_RIGHT.add("3"); SET_RIGHT.put("3", new Module(new int[] {1, 4, 1, 1}));
88 KEYS_RIGHT.add("4"); SET_RIGHT.put("4", new Module(new int[] {1, 1, 3, 2}));
89 KEYS_RIGHT.add("5"); SET_RIGHT.put("5", new Module(new int[] {1, 2, 3, 1}));
90 KEYS_RIGHT.add("6"); SET_RIGHT.put("6", new Module(new int[] {1, 1, 1, 4}));
91 KEYS_RIGHT.add("7"); SET_RIGHT.put("7", new Module(new int[] {1, 3, 1, 2}));
92 KEYS_RIGHT.add("8"); SET_RIGHT.put("8", new Module(new int[] {1, 2, 1, 3}));
93 KEYS_RIGHT.add("9"); SET_RIGHT.put("9", new Module(new int[] {3, 1, 1, 2}));
94 }
95
96 protected static void initLeftSet() {
97
98 KEYS_LEFT.add("0"); SET_LEFT.put("0", new Module(new int[] {0, 3, 2, 1, 1}));
99 KEYS_LEFT.add("1"); SET_LEFT.put("1", new Module(new int[] {0, 2, 2, 2, 1}));
100 KEYS_LEFT.add("2"); SET_LEFT.put("2", new Module(new int[] {0, 2, 1, 2, 2}));
101 KEYS_LEFT.add("3"); SET_LEFT.put("3", new Module(new int[] {0, 1, 4, 1, 1}));
102 KEYS_LEFT.add("4"); SET_LEFT.put("4", new Module(new int[] {0, 1, 1, 3, 2}));
103 KEYS_LEFT.add("5"); SET_LEFT.put("5", new Module(new int[] {0, 1, 2, 3, 1}));
104 KEYS_LEFT.add("6"); SET_LEFT.put("6", new Module(new int[] {0, 1, 1, 1, 4}));
105 KEYS_LEFT.add("7"); SET_LEFT.put("7", new Module(new int[] {0, 1, 3, 1, 2}));
106 KEYS_LEFT.add("8"); SET_LEFT.put("8", new Module(new int[] {0, 1, 2, 1, 3}));
107 KEYS_LEFT.add("9"); SET_LEFT.put("9", new Module(new int[] {0, 3, 1, 1, 2}));
108 }
109
110 /**
111 * Returns the module that represents the specified character.
112 * @param key The data character to get the encoding module for
113 * @param position The position of the data character, starts at 0
114 * @return The module that encodes the given char
115 */
116 public static Module getModule(String key, int position) {
117 Module module = null;
118
119 if(position + 1 > LEFT_WIDTH) {
120 module = (Module)SET_RIGHT.get(key);
121 } else {
122 module = (Module)SET_LEFT.get(key);
123 }
124 module.setSymbol(key);
125 return module;
126 }
127
128 /**
129 * Indicates whether the given key is represented in the default encoding
130 * table that this module factory contains.
131 * @return True if the key has a direct module encoding, false if not
132 */
133 public static boolean hasModule(String key) {
134 if(KEYS_RIGHT.indexOf(key) > -1) {
135 return true;
136 }
137
138 if(KEYS_LEFT.indexOf(key) > -1) {
139 return true;
140 }
141
142 return false;
143 }
144
145 /**
146 * Returns the encoded module at the given index position. This is used to
147 * get the encoded checksum character.
148 * @param index The index of the module required
149 * @return The module at the specified index
150 */
151 public static Module getModuleForIndex(int index) {
152 if(index + 1 > LEFT_WIDTH) {
153 return getModule((String)KEYS_RIGHT.get(index), index);
154 } else {
155 return getModule((String)KEYS_LEFT.get(index), index);
156 }
157 }
158
159 /**
160 * Indicates whether the given character is valid for this barcode or not.
161 * This basically just checks to see whether the key is in the list of
162 * encoded characters.
163 * @param key The key to check for validity
164 * @return True if the key is valid, false otherwise
165 */
166 public static boolean isValid(String key) {
167 if(KEYS_RIGHT.indexOf(key) > -1) {
168 return true;
169 }
170
171 if(KEYS_LEFT.indexOf(key) > -1) {
172 return true;
173 }
174
175 return false;
176 }
177 }