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.twoOfFive;
28
29 import net.sourceforge.barbecue.BarcodeException;
30 import net.sourceforge.barbecue.BlankModule;
31 import net.sourceforge.barbecue.Module;
32 import net.sourceforge.barbecue.Modulo10;
33 import net.sourceforge.barbecue.SeparatorModule;
34 import net.sourceforge.barbecue.linear.LinearBarcode;
35
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.text.CharacterIterator;
39 import java.text.StringCharacterIterator;
40
41 /**
42 * This is a concrete implementation of the Standard 2 of 5 barcode
43 *
44 * The Standard 2 of 5 barcode requires an even number of characters. At
45 * the same time, a modulo 10 check digit can be used. The default constructor
46 * presumes that if the barcode is of an odd length, then a check digit is
47 * required. This will automaticaly be generated.
48 * If the constructor with the check digit flag is used, the check digit flag is
49 * flase and the length of the barcode is odd, then an exception will be thrown.
50 *
51 * @author <a href="mailto:james@metalskin.com">James Jenner</a>
52 */
53 public class Std2of5Barcode extends LinearBarcode {
54 private String label;
55
56 /**
57 * Constructs a new Standard 2 of 5 barcode with the specified data.
58 * No check digit will be added
59 * @param data The data to encode
60 * @throws BarcodeException If the data is invalid
61 */
62 public Std2of5Barcode(String data) throws BarcodeException {
63 this(data, false);
64 }
65
66 /**
67 * Constructs a new Standard 2 of 5 barcode with thte specified data.
68 * @param data The data to encode
69 * @param checkDigit if true then a check digit is automaticaly appened to data
70 * @throws BarcodeException If the data is invalid
71 */
72 public Std2of5Barcode(String data, boolean checkDigit) throws BarcodeException {
73 super(checkDigit ? data + Modulo10.getMod10CheckDigit(data, 3) : data);
74 this.label = data;
75
76 validateData();
77 }
78
79 /**
80 * Returns the text label to be displayed underneath the barcode.
81 * @return The barcode label
82 */
83 public String getLabel() {
84 return label;
85 }
86
87 /**
88 * Encodes the data of the barcode into bars.
89 * @return The encoded bar data
90 */
91 protected Module[] encodeData() {
92 List modules = new ArrayList();
93
94 for(int i = 0; i < data.length(); i++) {
95 Module module = Std2of5ModuleFactory.getModule(String.valueOf(data.charAt(i)));
96
97 modules.add(module);
98 }
99
100 return (Module[])modules.toArray(new Module[0]);
101 }
102
103 /**
104 * Calculates the check sum digit for the barcode.
105 * @return Null - Standard 2 of 5 has no builtin checksum
106 */
107 protected Module calculateChecksum() {
108 return null;
109 }
110
111 /**
112 * Returns the pre-amble for the barcode.
113 * @return A BlankModule
114 */
115 protected Module getPreAmble() {
116 return Std2of5ModuleFactory.START_CHAR;
117 }
118
119 /**
120 * Returns the post-amble for the barcode.
121 * @return A BlankModule
122 */
123 protected Module getPostAmble() {
124 return Std2of5ModuleFactory.END_CHAR;
125 }
126
127 protected void validateData() throws BarcodeException {
128 int index = 0;
129 StringBuffer buf = new StringBuffer();
130 StringCharacterIterator iter = new StringCharacterIterator(data);
131 for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
132 if (!Character.isWhitespace(c)) {
133 if (!Std2of5ModuleFactory.isValid(String.valueOf(c))) {
134 throw new BarcodeException(c
135 + " is not a valid character for Standard 2 of 5 encoding");
136 }
137 buf.append(c);
138 }
139 index += 1;
140 }
141 data = buf.toString();
142 }
143 }