OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 181 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
181 ilm 1
package org.openconcerto.modules.label.gs1;
2
 
3
import org.openconcerto.modules.label.ISO646;
4
 
5
public class GS1Util {
6
 
7
    // ISO/IEC 15424 symbology identifiers
8
    // ]E0 : EAN-13, UPC-A, or UPC-E : 13 digits
9
    // ]E1 : Two-digit add-on symbol : 2 digits
10
    // ]E2 : Five-digit add-on symbol : 5 digits
11
    // ]E3 : EAN-13, UPC-A, or UPC-E with add-on symbol : 15 or 18 digits
12
    // ]E4 : EAN-8 : 8 digits
13
    // ]I1 : ITF-14 : 14 digits
14
    // ]C1 : GS1-128 : Standard AI element strings
15
    private static final String GS1_128_SCANNER_PREFIX = "]C1";
16
    // ]e0 : GS1 DataBar : Standard AI element strings
17
    private static final String GS1_DATABAR_SCANNER_PREFIX = "]e0";
18
    // ]e1 : GS1 Composite : Data packet containing the data + an encoded symbol separator
19
    // character.
20
    // ]e2 : GS1 Composite : Data packet containing the data following an escape mechanism
21
    // character.
22
    // ]d2 : GS1 DataMatrix : Standard AI element strings
23
    private static final String GS1_DATAMATRIX_SCANNER_PREFIX = "]d2";
183 ilm 24
    private static final String GS1_DATAMATRIX_SCANNER_PREFIX_2 = "]D2";
181 ilm 25
    // ]Q3 : GS1 QR Code : Standard AI element strings
26
    private static final String GS1_QRCODE_SCANNER_PREFIX = "]Q3";
27
    // ]J1 : GS1 DotCode : Standard AI element strings
28
 
29
    static final int ERROR_CODE_INVALID_GS1_SCAN = 0;
30
    static final int ERROR_CODE_UNKNOWN_AI = 1;
31
    static final int ERROR_CODE_INCOMPLETE_AI = 2;
32
    static final int ERROR_CODE_NOT_FOUND_SEPARATOR = 3;
33
    static final int ERROR_CODE_INSUFFICIENT_VALUE_LENGTH = 4;
34
    static final int ERROR_CODE_EXCEEDED_VALUE_LENGTH = 5;
35
    static final int ERROR_CODE_CONVERT_DECIMAL_POINT = 5;
36
    static final int ERROR_CODE_WRONG_DECIMAL_POINT = 6;
37
    static final int ERROR_CODE_CONVERT_DECIMAL_VALUE = 7;
38
 
39
    public static final char GS_SEPARATOR = '\u001D';
40
    // public static final char FNC1_SEPARATOR = 232;
41
 
42
    static final int SPACE_SEPARATOR = ' ';
43
 
44
    int separator;
45
 
46
    public GS1Util() {
47
        this(GS_SEPARATOR);
48
    }
49
 
50
    public GS1Util(int separator) {
51
        this.separator = separator;
52
    }
53
 
54
    public GS1AIElements parseFromScanner(String scan) throws GS1ParseException {
183 ilm 55
        if (scan.startsWith(GS1_DATAMATRIX_SCANNER_PREFIX) || scan.startsWith(GS1_DATAMATRIX_SCANNER_PREFIX_2) || scan.startsWith(GS1_128_SCANNER_PREFIX) || scan.startsWith(GS1_DATABAR_SCANNER_PREFIX)
56
                || scan.startsWith(GS1_QRCODE_SCANNER_PREFIX)) {
181 ilm 57
            return parse(scan.substring(3));
58
        }
59
        return parse(scan);
60
    }
61
 
62
    public GS1AIElements parse(String barcode) throws GS1ParseException {
63
        if (barcode.length() < 3) {
64
            throw new GS1ParseException("", ERROR_CODE_INVALID_GS1_SCAN, "code too short");
65
        }
66
 
67
        System.err.println("GS1Util.parse()" + barcode);
68
        GS1AIElements attr = new GS1AIElements();
69
        StringBuilder ai = new StringBuilder();
70
 
71
        int length = barcode.length();
72
        for (int i = 0; i < length; ++i) {
73
            int aiLength = ai.length();
74
            if (aiLength > 1) {
75
                GS1ApplicationIdentifier aii = GS1AIElements.getApplicationIdentifier(ai.toString());
76
                if (aii == null) {
77
                    if (aiLength < 4)
78
                        ai.append(barcode.charAt(i));
79
                    else
80
                        throw new GS1ParseException(ai.toString(), ERROR_CODE_UNKNOWN_AI, "Unknown AI");
81
                } else {
82
                    int decimalPoint = 0;
83
                    if (aii.decimalPoint) {
84
                        try {
85
                            decimalPoint = Integer.valueOf(String.valueOf(barcode.charAt(i)));
86
                        } catch (NumberFormatException e) {
87
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_CONVERT_DECIMAL_POINT, "Errow convert to decimal point");
88
                        }
89
 
90
                        if (++i >= length)
91
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length");
92
                    }
93
 
94
                    String value;
95
 
96
                    if (aii.variableLength) {
97
                        int separatorIndex = barcode.indexOf(this.separator, i);
98
 
99
                        if (separatorIndex < 0) {
100
                            if (length - i > aii.length)
101
                                throw new GS1ParseException(ai.toString(), ERROR_CODE_NOT_FOUND_SEPARATOR, "Not found separator");
102
                            else if (length - i < aii.minLength)
103
                                throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length");
104
                            else {
105
                                value = barcode.substring(i);
106
                                i = length;
107
                            }
108
                        } else if (separatorIndex - i > aii.length)
109
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_EXCEEDED_VALUE_LENGTH, "Exceeded value length");
110
                        else if (separatorIndex - i < aii.minLength)
111
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length");
112
                        else {
113
                            value = barcode.substring(i, separatorIndex);
114
                            i = separatorIndex;
115
                        }
116
                    } else {
117
                        if (i + aii.length > length) {
118
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_INSUFFICIENT_VALUE_LENGTH, "Insufficient value length");
119
                        }
120
                        value = barcode.substring(i, i + aii.length);
121
                        i += aii.length - 1;
122
                    }
123
 
124
                    if (aii.decimalPoint && decimalPoint > 0) {
125
                        if (decimalPoint >= value.length())
126
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_WRONG_DECIMAL_POINT, "Decimal point more then value length");
127
 
128
                        try {
129
                            value = String.valueOf(Double.valueOf(value.substring(0, value.length() - decimalPoint) + "." + value.substring(value.length() - decimalPoint)));
130
                        } catch (NumberFormatException e) {
131
                            throw new GS1ParseException(ai.toString(), ERROR_CODE_CONVERT_DECIMAL_VALUE, "Error convert decimal point value");
132
                        }
133
                    }
134
 
135
                    attr.put(ai.toString(), value);
136
 
137
                    ai.setLength(0);
138
                }
139
            } else
140
                ai.append(barcode.charAt(i));
141
        }
142
 
143
        if (ai.length() > 0)
144
            throw new GS1ParseException(ai.toString(), ERROR_CODE_INCOMPLETE_AI, "Incomplete AI");
145
 
146
        return attr;
147
    }
148
 
149
    public String format(GS1AIElements values) {
150
 
151
        StringBuilder b = new StringBuilder();
152
        int size = values.size();
153
        for (int i = 0; i < size; i++) {
154
            String k = values.getKey(i);
155
            GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k);
156
            final String value = values.getValue(i);
157
            b.append(k);
158
            b.append(value);
159
            if (ai.variableLength && i < size - 1) {
160
                b.append((char) this.separator);
161
            }
162
        }
163
        return b.toString();
164
    }
165
 
166
    public String formatZPL(GS1AIElements values) {
167
 
168
        StringBuilder b = new StringBuilder();
169
        int size = values.size();
170
        b.append("@1");
171
        for (int i = 0; i < size; i++) {
172
            String k = values.getKey(i);
173
            GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k);
174
            final String value = values.getValue(i);
175
            b.append(k);
176
            b.append(value);
177
            if (ai.variableLength && i < size - 1) {
178
                b.append("@d029");
179
            }
180
        }
181
        return b.toString();
182
    }
183
 
184
    public String formatDataMatrix(GS1AIElements values) {
185
 
186
        StringBuilder b = new StringBuilder();
187
        int size = values.size();
188
        // b.append(FNC1_SEPARATOR);
189
        for (int i = 0; i < size; i++) {
190
            String k = values.getKey(i);
191
            GS1ApplicationIdentifier ai = GS1AIElements.getApplicationIdentifier(k);
192
            final String value = values.getValue(i);
193
            b.append('[');
194
            b.append(k);
195
            b.append(']');
196
            b.append(value);
197
            if (ai.variableLength && i < size - 1) {
198
                // b.append(GS_SEPARATOR);
199
            }
200
        }
201
        return b.toString();
202
    }
203
 
204
    public static void main(String[] args) throws GS1ParseException {
205
        GS1Util p = new GS1Util('_');
206
        System.out.println("GS1Util.main()" + (char) p.separator);
207
        String barcode = "0104607018700852111806051718062910180605_211";
208
        // barcode = "01088888931021461712031510W1040190";
209
        GS1AIElements values = p.parse(barcode);
210
        values.dump(System.out);
211
 
212
        values.put("391", "kookkk");
213
        System.out.println(p.format(values));
214
        System.out.println(values.formatHumanReadable());
215
 
216
        GS1AIElements valuesMax = new GS1AIElements();
217
        valuesMax.put("02", "01234567891234");
218
        valuesMax.put("15", "201202");
219
        valuesMax.put("37", "12345678");
220
        valuesMax.put("10", "12345678901234567890");
221
        GS1Util pStd = new GS1Util();
222
        System.out.println(p.format(valuesMax));
223
        System.out.println(p.format(valuesMax).length());
224
        System.out.println(pStd.format(valuesMax));
225
        System.out.println(pStd.format(valuesMax).length());
226
        System.err.println("GS1Util.main() GS128 from barcode reader");
227
        String gs1128 = "]C10207612345678900152012153745646578";
228
        GS1Util p2 = new GS1Util();
229
        values = p2.parseFromScanner(gs1128);
230
        values.dump(System.out);
231
    }
232
 
233
    public static String showAllChars(String s) {
234
        StringBuilder b = new StringBuilder();
235
        for (int i = 0; i < s.length(); i++) {
236
            if (ISO646.isValid(s.charAt(i))) {
237
                b.append(s.charAt(i));
238
            } else {
239
                b.append("[" + (int) s.charAt(i) + "]");
240
            }
241
        }
242
        return b.toString();
243
    }
244
 
245
}