KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > barcode > impl > CodabarLogicImpl


1 /*
2  * $Id: CodabarLogicImpl.java,v 1.5 2003/04/19 14:06:06 jmaerki Exp $
3  * ============================================================================
4  * The Krysalis Patchy Software License, Version 1.1_01
5  * Copyright (c) 2002-2003 Nicola Ken Barozzi. All rights reserved.
6  *
7  * This Licence is compatible with the BSD licence as described and
8  * approved by http://www.opensource.org/, and is based on the
9  * Apache Software Licence Version 1.1.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution,
24  * if any, must include the following acknowledgment:
25  * "This product includes software developed for project
26  * Krysalis (http://www.krysalis.org/)."
27  * Alternately, this acknowledgment may appear in the software itself,
28  * if and wherever such third-party acknowledgments normally appear.
29  *
30  * 4. The names "Krysalis" and "Nicola Ken Barozzi" and
31  * "Krysalis Barcode" must not be used to endorse or promote products
32  * derived from this software without prior written permission. For
33  * written permission, please contact nicolaken@krysalis.org.
34  *
35  * 5. Products derived from this software may not be called "Krysalis",
36  * "Krysalis Barcode", nor may "Krysalis" appear in their name,
37  * without prior written permission of Nicola Ken Barozzi.
38  *
39  * 6. This software may contain voluntary contributions made by many
40  * individuals, who decided to donate the code to this project in
41  * respect of this licence, and was originally created by
42  * Jeremias Maerki <jeremias@maerki.org>.
43  *
44  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
45  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47  * DISCLAIMED. IN NO EVENT SHALL THE KRYSALIS PROJECT OR
48  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
51  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  * SUCH DAMAGE.
56  * ====================================================================
57  */

58 package org.krysalis.barcode.impl;
59
60 import org.krysalis.barcode.BarGroup;
61 import org.krysalis.barcode.ChecksumMode;
62 import org.krysalis.barcode.ClassicBarcodeLogicHandler;
63
64 /**
65  * This class is an implementation of the Codabar barcode.
66  *
67  * @author Jeremias Maerki
68  * @todo Complete the implementation (checksum, automatic start/stops chars...)
69  */

70 public class CodabarLogicImpl {
71
72     private static final char[] CHARACTERS =
73                             {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
74                              'a', 'b', 'c', 'd', 'e', 'n', 't',
75                              '-', '$', ':', '/', '.', '+', '*'};
76
77     /** Defines the Codabar character set. */
78     protected static final byte[][] CHARSET =
79                                             {{0, 0, 0, 0, 0, 1, 1}, //0
80
{0, 0, 0, 0, 1, 1, 0}, //1
81
{0, 0, 0, 1, 0, 0, 1}, //2
82
{1, 1, 0, 0, 0, 0, 0}, //3
83
{0, 0, 1, 0, 0, 1, 0}, //4
84
{1, 0, 0, 0, 0, 1, 0}, //5
85
{0, 1, 0, 0, 0, 0, 1}, //6
86
{0, 1, 0, 0, 1, 0, 0}, //7
87
{0, 1, 1, 0, 0, 0, 0}, //8
88
{1, 0, 0, 1, 0, 0, 0}, //9
89
{0, 0, 1, 1, 0, 1, 0}, //a
90
{0, 1, 0, 1, 0, 0, 1}, //b
91
{0, 0, 0, 1, 0, 1, 1}, //c
92
{0, 0, 0, 1, 1, 1, 0}, //d
93
{0, 0, 0, 1, 1, 1, 0}, //e
94
{0, 1, 0, 1, 0, 0, 1}, //n
95
{0, 0, 1, 1, 0, 1, 0}, //t
96
{0, 0, 0, 1, 1, 0, 0}, //-
97
{0, 0, 1, 1, 0, 0, 0}, //$
98
{1, 0, 0, 0, 1, 0, 1}, //:
99
{1, 0, 1, 0, 0, 0, 1}, ///
100
{1, 0, 1, 0, 1, 0, 0}, //.
101
{0, 0, 1, 0, 1, 0, 1}, //+
102
{0, 0, 0, 1, 0, 1, 1}}; //*
103

104     private ChecksumMode checksumMode = ChecksumMode.CP_AUTO;
105
106     
107     /**
108      * Main constructor
109      * @param mode Determines how checksums are to be treated.
110      */

111     public CodabarLogicImpl(ChecksumMode mode) {
112         this.checksumMode = mode;
113     }
114
115     /**
116      * Returns the checksum mode.
117      * @return the current checksum mode
118      */

119     public ChecksumMode getChecksumMode() {
120         return this.checksumMode;
121     }
122
123     /**
124      * Returns the index of a character within the character set.
125      * @param ch the character to lookup
126      * @return the index of the character or -1 if it isn't supported
127      */

128     protected static int getCharIndex(char ch) {
129         for (int i = 0; i < CHARACTERS.length; i++) {
130             if (ch == CHARACTERS[i]) {
131                 return i;
132             }
133         }
134         return -1;
135     }
136
137     /**
138      * Determines whether a character is a valid message character.
139      * @param ch the character to check
140      * @return true if it is a valid character, false otherwise
141      */

142     protected static boolean isValidChar(char ch) {
143         return (getCharIndex(ch) >= 0);
144     }
145     
146     /**
147      * Determines whether a character is on of the start/stop characters.
148      * @param ch the character to check
149      * @return true if it is a start/stop character
150      */

151     protected static boolean isStartStopChar(char ch) {
152         return ((ch == 'a') || (ch == 'b')
153              || (ch == 'c') || (ch == 'd')
154              || (ch == 'e') || (ch == '*')
155              || (ch == 'n') || (ch == 't'));
156     }
157
158     private int widthAt(char ch, int index) throws IllegalArgumentException JavaDoc {
159         int chidx = getCharIndex(ch);
160         if (chidx >= 0) {
161             int binary = CHARSET[chidx][index];
162             return binary + 1;
163         } else {
164             throw new IllegalArgumentException JavaDoc("Invalid character: " + ch);
165         }
166     }
167
168     /**
169      * Encodes a character to a logic handler.
170      * @param logic the logic handler to send events to
171      * @param c the character to encode
172      */

173     protected void encodeChar(ClassicBarcodeLogicHandler logic, char c) {
174         logic.startBarGroup(BarGroup.MSG_CHARACTER, new Character JavaDoc(c).toString());
175         for (byte i = 0; i < 7; i++) {
176             final int width = widthAt(c, i);
177             final boolean black = ((i % 2) == 0);
178             logic.addBar(black, width);
179         }
180         logic.endBarGroup();
181     }
182
183     private void handleChecksum(StringBuffer JavaDoc sb) {
184         if ((getChecksumMode() == ChecksumMode.CP_ADD)
185                 || (getChecksumMode() == ChecksumMode.CP_CHECK)) {
186             throw new UnsupportedOperationException JavaDoc(
187                 "No checksums are currently supported for Codabar symbols");
188         } else if (getChecksumMode() == ChecksumMode.CP_IGNORE) {
189             return;
190         } else if (getChecksumMode() == ChecksumMode.CP_AUTO) {
191             return; //equals ignore
192
}
193     }
194     
195     /**
196      * Generates the barcode logic.
197      * @param logic the logic handler to send generated events to
198      * @param msg the message to encode
199      */

200     public void generateBarcodeLogic(ClassicBarcodeLogicHandler logic, String JavaDoc msg) {
201         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(msg);
202         
203         handleChecksum(sb);
204         
205         logic.startBarcode(sb.toString());
206
207         for (int i = 0; i < sb.length(); i++) {
208             if (i > 0) {
209                 //Intercharacter gap
210
logic.addBar(false, 1);
211             }
212             final char ch = sb.charAt(i);
213             if (!isValidChar(ch)) throw new IllegalArgumentException JavaDoc("Invalid character: " + ch);
214             encodeChar(logic, ch);
215         }
216
217         logic.endBarcode();
218     }
219
220 }
221
Popular Tags