001    /**
002     *  This library is free software; you can redistribute it and/or modify it
003     *  under the terms of the GNU Lesser General Public License (LGPL) as
004     *  published by the Free Software Foundation; either version 3.0 of the
005     *  License, or (at your option) any later version.
006     *
007     *  This library is distributed in the hope that it will be useful, but
008     *  WITHOUT ANY WARRANTY; without even the implied warranty of
009     *  MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010     *  Lesser General Public License for more details. 
011     */
012    
013    /**
014     * Title:        JBarcodeBean
015     * Description:  Barcode JavaBeans Component
016     * Copyright:    Copyright (C) 2004
017     * Company:      Dafydd Walters
018     */
019    package net.sourceforge.jbarcodebean.model;
020    
021    import net.sourceforge.jbarcodebean.BarcodeException;
022    
023    /**
024     * This class, which implements the {@link BarcodeStrategy} interface,
025     * knows how to encode the 3:1 (wide)
026     * variant of the Interleaved Code 2 of 5 barcode type.
027     */
028    public class Interleaved25 extends AbstractBarcodeStrategy implements java.io.Serializable {
029    
030      private static CharacterCode[] codes = {
031        new CharacterCode('1', new byte[] {3,1,1,1,3}, 1),
032        new CharacterCode('2', new byte[] {1,3,1,1,3}, 2),
033        new CharacterCode('3', new byte[] {3,3,1,1,1}, 3),
034        new CharacterCode('4', new byte[] {1,1,3,1,3}, 4),
035        new CharacterCode('5', new byte[] {3,1,3,1,1}, 5),
036        new CharacterCode('6', new byte[] {1,3,3,1,1}, 6),
037        new CharacterCode('7', new byte[] {1,1,1,3,3}, 7),
038        new CharacterCode('8', new byte[] {3,1,1,3,1}, 8),
039        new CharacterCode('9', new byte[] {1,3,1,3,1}, 9),
040        new CharacterCode('0', new byte[] {1,1,3,3,1}, 0),
041        new CharacterCode('A', new byte[] {1,1,1,1}, -1),   // Start
042        new CharacterCode('B', new byte[] {3,1,1}, -1)      // Stop
043      };
044    
045      /**
046       * Always returns {@link BarcodeStrategy#OPTIONAL_CHECKSUM}.
047       */
048      public int requiresChecksum() {
049        // Checksum is not mandatory
050        return OPTIONAL_CHECKSUM;
051      }
052    
053      /**
054       * This implementation of <tt>getCodes</tt> returns an array of
055       * {@link AbstractBarcodeStrategy.CharacterCode CharacterCode} objects
056       * for the wide Interleaved Code25 format.
057       */
058      protected CharacterCode[] getCodes() {
059        return Interleaved25.codes;
060      }
061    
062      /**
063       * Returns a String containing the checksum-encoded version of the text passed
064       * to the method.
065       * Start and End sentinels must NOT be included in the text passed to this method.
066       */
067      protected String augmentWithChecksum(String text) throws BarcodeException {
068        int check1 = 0;
069        int check2 = 0;
070        CharacterCode cc;
071        for (int i = 0; i < text.length(); i++) {
072          char ch = text.charAt(i);
073          cc = getCharacterCode(ch);            // get code by character
074          if (cc == null) {
075            throw new BarcodeException("Invalid character in barcode");
076          }
077          // Exclude start and end sentinels from checksum
078          if (cc.check > 0) {
079            if ((i + text.length()) % 2 == 0) {
080              check1 += cc.check;
081            } else {
082              check2 += cc.check;
083            }
084          }
085        }
086        check2 *= 3;
087        int checkDigit = (10 - ((check1 + check2) % 10)) % 10;
088        text = text + new Integer(checkDigit).toString();
089        return text;
090      }
091    
092      /**
093       * Adds a leading zero if the length of <tt>text</tt> is odd.
094       */
095      protected String postprocess(String text) {
096        if (text.length() % 2 != 0) {
097          // Length is odd; add a leading zero.
098          text = "0" + text;
099        }
100        return text;
101      }
102    
103      /**
104       * No preprocessing performed. <tt>text</tt> is returned unmodified.
105       */
106      protected String preprocess(String text) {
107        return text;
108      }
109    
110      /**
111       * Always returns <tt>true</tt>.
112       */
113      protected boolean isInterleaved() {
114        return true;
115      }
116    
117      /**
118       * Always returns 'A'.
119       */
120      protected char getStartSentinel() {
121        return 'A';
122      }
123    
124      /**
125       * Always returns 'B'.
126       */
127      protected char getStopSentinel() {
128        return 'B';
129      }
130    
131      /**
132       * Always returns 11 (eleven).
133       */
134      protected byte getMarginWidth() {
135        return 11;
136      }
137    
138      /**
139       * Returns <tt>text</tt> unmodified.
140       */
141      protected String getBarcodeLabelText(String text) {
142        return text;
143      }
144    
145    }