KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: EAN13LogicImpl.java,v 1.9 2003/06/11 09:25:12 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 EAN-13 barcode.
66  *
67  * @author Jeremias Maerki
68  */

69 public class EAN13LogicImpl extends UPCEANLogicImpl {
70
71     private static final byte A = LEFT_HAND_A;
72     private static final byte B = LEFT_HAND_B;
73
74     private static final byte[][] FIRSTFLAG = {{A, A, A, A, A},
75                                                {A, B, A, B, B},
76                                                {A, B, B, A, B},
77                                                {A, B, B, B, A},
78                                                {B, A, A, B, B},
79                                                {B, B, A, A, B},
80                                                {B, B, B, A, A},
81                                                {B, A, B, A, B},
82                                                {B, A, B, B, A},
83                                                {B, B, A, B, A}};
84
85     /**
86      * Main constructor
87      * @param mode the checksum mode
88      */

89     public EAN13LogicImpl(ChecksumMode mode) {
90         super(mode);
91     }
92     
93     /**
94      * Validates a EAN-13 message. The method throws IllegalArgumentExceptions
95      * if an invalid message is passed.
96      * @param msg the message to validate
97      */

98     public static void validateMessage(String JavaDoc msg) {
99         UPCEANLogicImpl.validateMessage(msg);
100         if ((msg.length() < 12) || (msg.length() > 13)) {
101             throw new IllegalArgumentException JavaDoc(
102                 "Message must be 11 or 12 characters long. Message: " + msg);
103         }
104     }
105     
106     private String JavaDoc handleChecksum(String JavaDoc msg) {
107         ChecksumMode mode = getChecksumMode();
108         if (mode == ChecksumMode.CP_AUTO) {
109             if (msg.length() == 12) {
110                 mode = ChecksumMode.CP_ADD;
111             } else if (msg.length() == 13) {
112                 mode = ChecksumMode.CP_CHECK;
113             } else {
114                 //Shouldn't happen because of validateMessage
115
throw new RuntimeException JavaDoc("Internal error");
116             }
117         }
118         if (mode == ChecksumMode.CP_ADD) {
119             if (msg.length() > 12) {
120                 throw new IllegalArgumentException JavaDoc(
121                     "Message is too long (max. 12 characters)");
122             }
123             if (msg.length() < 12) {
124                 throw new IllegalArgumentException JavaDoc(
125                     "Message must be 12 characters long");
126             }
127             return msg + calcChecksum(msg);
128         } else if (mode == ChecksumMode.CP_CHECK) {
129             if (msg.length() > 13) {
130                 throw new IllegalArgumentException JavaDoc(
131                     "Message is too long (max. 13 characters)");
132             }
133             if (msg.length() < 13) {
134                 throw new IllegalArgumentException JavaDoc(
135                     "Message must be 13 characters long");
136             }
137             char check = msg.charAt(12);
138             char expected = calcChecksum(msg.substring(0, 12));
139             if (check != expected) {
140                 throw new IllegalArgumentException JavaDoc(
141                     "Checksum is bad (" + check + "). Expected: " + expected);
142             }
143             return msg;
144         } else if (mode == ChecksumMode.CP_IGNORE) {
145             return msg;
146         } else {
147             throw new UnsupportedOperationException JavaDoc(
148                 "Unknown checksum mode: " + mode);
149         }
150     }
151     
152     /** @see org.krysalis.barcode.impl.UPCEANLogicImpl */
153     public void generateBarcodeLogic(ClassicBarcodeLogicHandler logic, String JavaDoc msg) {
154         String JavaDoc supp = retrieveSupplemental(msg);
155         String JavaDoc s = removeSupplemental(msg);
156         validateMessage(s);
157         s = handleChecksum(s);
158
159         String JavaDoc canonicalMessage = s;
160         if (supp != null) {
161             canonicalMessage = canonicalMessage + "+" + supp;
162         }
163         logic.startBarcode(canonicalMessage);
164         
165         //Left guard
166
drawSideGuard(logic);
167
168         logic.startBarGroup(BarGroup.UPC_EAN_GROUP, s.charAt(0) + ":" + s.substring(1, 7));
169         
170         //Number system character
171
encodeChar(logic, s.charAt(1), LEFT_HAND_A);
172
173         //First five data characters
174
byte flag = (byte)Character.digit(s.charAt(0), 10);
175         for (int i = 2; i < 7; i++) {
176             encodeChar(logic, s.charAt(i),
177                     FIRSTFLAG[flag][i - 2]);
178         }
179
180         logic.endBarGroup();
181         
182         //Center guard
183
drawCenterGuard(logic);
184
185         logic.startBarGroup(BarGroup.UPC_EAN_GROUP, s.substring(7, 13));
186
187         //Last five data characters
188
for (int i = 7; i < 12; i++) {
189             encodeChar(logic, s.charAt(i), RIGHT_HAND);
190         }
191
192         //Checksum
193
final char check = s.charAt(12);
194         logic.startBarGroup(BarGroup.UPC_EAN_CHECK, new Character JavaDoc(check).toString());
195         encodeChar(logic, check, RIGHT_HAND);
196         logic.endBarGroup();
197
198         logic.endBarGroup();
199         
200         //Right guard
201
drawSideGuard(logic);
202
203         //Optional Supplemental
204
if (supp != null) {
205             drawSupplemental(logic, supp);
206         }
207         logic.endBarcode();
208     }
209
210 }
211
Popular Tags