3e3fd51c9df713ee23b588f083184d28790919a2
[zxing.git] / core / src / com / google / zxing / client / result / ExpandedProductResultParser.java
1 /*
2  * Copyright (C) 2010 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * These authors would like to acknowledge the Spanish Ministry of Industry,
19  * Tourism and Trade, for the support in the project TSI020301-2008-2
20  * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
21  * Mobile Dynamic Environments", led by Treelogic
22  * ( http://www.treelogic.com/ ):
23  *
24  *   http://www.piramidepse.com/
25  */
26
27 package com.google.zxing.client.result;
28
29 import java.util.Hashtable;
30
31 import com.google.zxing.BarcodeFormat;
32 import com.google.zxing.Result;
33
34 /**
35  * Parses strings of digits that represent a RSS Extended code.
36  * 
37  * @author Antonio Manuel Benjumea Conde, Servinform, S.A.
38  * @author Agustín Delgado, Servinform, S.A.
39  */
40 final class ExpandedProductResultParser extends ResultParser {
41
42   private ExpandedProductResultParser() {
43   }
44
45   // Treat all RSS EXPANDED, in the sense that they are all
46   // product barcodes with complementary data.
47   public static ExpandedProductParsedResult parse(Result result) {
48     BarcodeFormat format = result.getBarcodeFormat();
49     if (!(BarcodeFormat.RSS_EXPANDED.equals(format))) {
50       // ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
51       return null;
52     }
53     // Really neither of these should happen:
54     String rawText = result.getText();
55     if (rawText == null) {
56       // ExtendedProductParsedResult NOT created. Input text is NULL
57       return null;
58     }
59
60     String productID = "-";
61     String sscc = "-";
62     String lotNumber = "-";
63     String productionDate = "-";
64     String packagingDate = "-";
65     String bestBeforeDate = "-";
66     String expirationDate = "-";
67     String weight = "-";
68     String weightType = "-";
69     String weightIncrement = "-";
70     String price = "-";
71     String priceIncrement = "-";
72     String priceCurrency = "-";
73     Hashtable uncommonAIs = new Hashtable();
74
75     int i = 0;
76
77     while (i < rawText.length()) {
78       String ai = findAIvalue(i, rawText);
79       if ("ERROR".equals(ai)) {
80         // Error. Code doesn't match with RSS expanded pattern
81         // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
82         return null;
83       }
84       i += ai.length() + 2;
85       String value = findValue(i, rawText);
86       i += value.length();
87
88       if ("00".equals(ai)) {
89         sscc = value;
90       } else if ("01".equals(ai)) {
91         productID = value;
92       } else if ("10".equals(ai)) {
93         lotNumber = value;
94       } else if ("11".equals(ai)) {
95         productionDate = value;
96       } else if ("13".equals(ai)) {
97         packagingDate = value;
98       } else if ("15".equals(ai)) {
99         bestBeforeDate = value;
100       } else if ("17".equals(ai)) {
101         expirationDate = value;
102       } else if ("3100".equals(ai) || "3101".equals(ai)
103           || "3102".equals(ai) || "3103".equals(ai)
104           || "3104".equals(ai) || "3105".equals(ai)
105           || "3106".equals(ai) || "3107".equals(ai)
106           || "3108".equals(ai) || "3109".equals(ai)) {
107         weight = value;
108         weightType = ExpandedProductParsedResult.KILOGRAM;
109         weightIncrement = ai.substring(3);
110       } else if ("3200".equals(ai) || "3201".equals(ai)
111           || "3202".equals(ai) || "3203".equals(ai)
112           || "3204".equals(ai) || "3205".equals(ai)
113           || "3206".equals(ai) || "3207".equals(ai)
114           || "3208".equals(ai) || "3209".equals(ai)) {
115         weight = value;
116         weightType = ExpandedProductParsedResult.POUND;
117         weightIncrement = ai.substring(3);
118       } else if ("3920".equals(ai) || "3921".equals(ai)
119           || "3922".equals(ai) || "3923".equals(ai)) {
120         price = value;
121         priceIncrement = ai.substring(3);
122       } else if ("3930".equals(ai) || "3931".equals(ai)
123           || "3932".equals(ai) || "3933".equals(ai)) {
124         if (value.length() < 4) {
125           // The value must have more of 3 symbols (3 for currency and
126           // 1 at least for the price)
127           // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
128           return null;
129         }
130         price = value.substring(3);
131         priceCurrency = value.substring(0, 3);
132         priceIncrement = ai.substring(3);
133       } else {
134         // No match with common AIs
135         uncommonAIs.put(ai, value);
136       }
137     }
138
139     return new ExpandedProductParsedResult(productID, sscc, lotNumber,
140         productionDate, packagingDate, bestBeforeDate, expirationDate,
141         weight, weightType, weightIncrement, price, priceIncrement,
142         priceCurrency, uncommonAIs);
143   }
144
145   private static String findAIvalue(int i, String rawText) {
146     StringBuffer buf = new StringBuffer();
147     char c = rawText.charAt(i);
148     // First character must be a open parenthesis.If not, ERROR
149     if (c != '(') {
150       return "ERROR";
151     }
152
153     String rawTextAux = rawText.substring(i + 1);
154
155     for (int index = 0; index < rawTextAux.length(); index++) {
156       char currentChar = rawTextAux.charAt(index);
157       switch (currentChar){
158         case '0':
159         case '1':
160         case '2':
161         case '3':
162         case '4':
163         case '5':
164         case '6':
165         case '7':
166         case '8':
167         case '9':
168           buf.append(currentChar);
169           break;
170         case ')':
171           return buf.toString();
172         default:
173           return "ERROR";
174       }
175     }
176     return buf.toString();
177   }
178
179   private static String findValue(int i, String rawText) {
180     StringBuffer buf = new StringBuffer();
181     String rawTextAux = rawText.substring(i);
182
183     for (int index = 0; index < rawTextAux.length(); index++) {
184       char c = rawTextAux.charAt(index);
185       if (c == '(') {
186         // We look for a new AI. If it doesn't exist (ERROR), we coninue
187         // with the iteration
188         if ("ERROR".equals(findAIvalue(index, rawTextAux))) {
189           buf.append(c);
190         } else {
191           break;
192         }
193       } else {
194         buf.append(c);
195       }
196     }
197     return buf.toString();
198   }
199 }