Refactored to avoid use of exceptions in parsing, at the suggestion of Jeff Griffin...
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 3 Mar 2008 21:37:40 +0000 (21:37 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 3 Mar 2008 21:37:40 +0000 (21:37 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@239 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/client/result/AbstractDoCoMoResult.java
core/src/com/google/zxing/client/result/AddressBookDoCoMoResult.java
core/src/com/google/zxing/client/result/BookmarkDoCoMoResult.java
core/src/com/google/zxing/client/result/EmailAddressResult.java
core/src/com/google/zxing/client/result/EmailDoCoMoResult.java
core/src/com/google/zxing/client/result/ParsedReaderResult.java
core/src/com/google/zxing/client/result/TextParsedResult.java
core/src/com/google/zxing/client/result/UPCParsedResult.java
core/src/com/google/zxing/client/result/URIParsedResult.java
core/src/com/google/zxing/client/result/URLTOResult.java

index 668071e..f9436a0 100644 (file)
@@ -19,9 +19,12 @@ package com.google.zxing.client.result;
 import java.util.Vector;
 
 /**
- * See
+ * <p>See
  * <a href="http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html">
- * DoCoMo's documentation</a> about the result types represented by subclasses of this class.
+ * DoCoMo's documentation</a> about the result types represented by subclasses of this class.</p>
+ *
+ * <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
+ * on exception-based mechanisms during parsing.</p>
  *
  * @author srowen@google.com (Sean Owen)
  */
@@ -66,7 +69,7 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
         }
       }
     }
-    if (matches == null) {
+    if (matches == null || matches.isEmpty()) {
       return null;
     }
     int size = matches.size();
@@ -82,14 +85,6 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
     return matches == null ? null : matches[0];
   }
 
-  static String[] matchRequiredPrefixedField(String prefix, String rawText) {
-    String[] result = matchPrefixedField(prefix, rawText);
-    if (result == null) {
-      throw new IllegalArgumentException("Did not match prefix " + prefix);
-    }
-    return result;
-  }
-
   private static String unescape(String escaped) {
     if (escaped != null) {
       int backslash = escaped.indexOf((int) '\\');
index d05ff38..f57a3c7 100644 (file)
@@ -34,16 +34,29 @@ public final class AddressBookDoCoMoResult extends AbstractDoCoMoResult {
   private final String note;
   private final String address;
 
-  public AddressBookDoCoMoResult(String rawText) {
+  private AddressBookDoCoMoResult(String name, String[] phoneNumbers, String email, String note, String address) {
     super(ParsedReaderResultType.ADDRESSBOOK);
+    this.name = name;
+    this.phoneNumbers = phoneNumbers;
+    this.email = email;
+    this.note = note;
+    this.address = address;
+  }
+
+  public static AddressBookDoCoMoResult parse(String rawText) {
     if (!rawText.startsWith("MECARD:")) {
-      throw new IllegalArgumentException("Does not begin with MECARD");
+      return null;
+    }
+    String[] rawName = matchPrefixedField("N:", rawText);
+    if (rawName == null) {
+      return null;
     }
-    name = parseName(matchRequiredPrefixedField("N:", rawText)[0]);
-    phoneNumbers = matchPrefixedField("TEL:", rawText);
-    email = matchSinglePrefixedField("EMAIL:", rawText);
-    note = matchSinglePrefixedField("NOTE:", rawText);
-    address = matchSinglePrefixedField("ADR:", rawText);
+    String name = parseName(rawName[0]);
+    String[] phoneNumbers = matchPrefixedField("TEL:", rawText);
+    String email = matchSinglePrefixedField("EMAIL:", rawText);
+    String note = matchSinglePrefixedField("NOTE:", rawText);
+    String address = matchSinglePrefixedField("ADR:", rawText);
+    return new AddressBookDoCoMoResult(name, phoneNumbers, email, note, address);
   }
 
   public String getName() {
index 57e1a59..f137a35 100644 (file)
@@ -24,17 +24,26 @@ public final class BookmarkDoCoMoResult extends AbstractDoCoMoResult {
   private final String title;
   private final String uri;
 
-  public BookmarkDoCoMoResult(String rawText) {
+  private BookmarkDoCoMoResult(String title, String uri) {
     super(ParsedReaderResultType.BOOKMARK);
+    this.title = title;
+    this.uri = uri;
+  }
+
+  public static BookmarkDoCoMoResult parse(String rawText) {
     if (!rawText.startsWith("MEBKM:")) {
-      throw new IllegalArgumentException("Does not begin with MEBKM");
+      return null;
+    }
+    String title = matchSinglePrefixedField("TITLE:", rawText);
+    String[] rawUri = matchPrefixedField("URL:", rawText);
+    if (rawUri == null) {
+      return null;
     }
-    title = matchSinglePrefixedField("TITLE:", rawText);
-    String uriString = matchRequiredPrefixedField("URL:", rawText)[0];
-    if (!URIParsedResult.isBasicallyValidURI(uriString)) {
-      throw new IllegalArgumentException("Invalid URI: " + uriString);
+    String uri = rawUri[0];
+    if (!URIParsedResult.isBasicallyValidURI(uri)) {
+      return null;
     }
-    uri = uriString;
+    return new BookmarkDoCoMoResult(title, uri);
   }
 
   public String getTitle() {
index c87da90..62d6abc 100644 (file)
@@ -26,17 +26,23 @@ public final class EmailAddressResult extends AbstractDoCoMoResult {
 
   private final String emailAddress;
 
-  public EmailAddressResult(String rawText) {
+  private EmailAddressResult(String emailAddress) {
     super(ParsedReaderResultType.EMAIL_ADDRESS);
+    this.emailAddress = emailAddress;
+  }
+
+  public static EmailAddressResult parse(String rawText) {
+    String emailAddress;
     if (rawText.startsWith("mailto:")) {
       // If it starts with mailto:, assume it is definitely trying to be an email address
       emailAddress = rawText.substring(7);
     } else {
       if (!EmailDoCoMoResult.isBasicallyValidEmailAddress(rawText)) {
-        throw new IllegalArgumentException("Invalid email address: " + rawText);
+        return null;
       }
       emailAddress = rawText;
     }
+    return new EmailAddressResult(emailAddress);
   }
 
   public String getEmailAddress() {
index 9b941a0..6161d42 100644 (file)
@@ -29,17 +29,28 @@ public final class EmailDoCoMoResult extends AbstractDoCoMoResult {
   private final String subject;
   private final String body;
 
-  public EmailDoCoMoResult(String rawText) {
+  private EmailDoCoMoResult(String to, String subject, String body) {
     super(ParsedReaderResultType.EMAIL);
+    this.to = to;
+    this.subject = subject;
+    this.body = body;
+  }
+
+  public static EmailDoCoMoResult parse(String rawText) {
     if (!rawText.startsWith("MATMSG:")) {
-      throw new IllegalArgumentException("Does not begin with MATMSG");
+      return null;
+    }
+    String[] rawTo = matchPrefixedField("TO:", rawText);
+    if (rawTo == null) {
+      return null;
     }
-    to = matchRequiredPrefixedField("TO:", rawText)[0];
+    String to = rawTo[0];
     if (!isBasicallyValidEmailAddress(to)) {
-      throw new IllegalArgumentException("Invalid email address: " + to);
+      return null;
     }
-    subject = matchSinglePrefixedField("SUB:", rawText);
-    body = matchSinglePrefixedField("BODY:", rawText);
+    String subject = matchSinglePrefixedField("SUB:", rawText);
+    String body = matchSinglePrefixedField("BODY:", rawText);
+    return new EmailDoCoMoResult(to, subject, body);
   }
 
   public String getTo() {
index d4ec515..18950c5 100644 (file)
 package com.google.zxing.client.result;
 
 /**
+ * <p>Abstract class representing the result of decoding a barcode, as more than
+ * a String -- as some type of structured data. This might be a subclass which represents
+ * a URL, or an e-mail address. {@link #parseReaderResult(String)} will turn a raw
+ * decoded string into the most appropriate type of structured representation.</p>
+ *
+ * <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
+ * on exception-based mechanisms during parsing.</p>
+ *
  * @author srowen@google.com (Sean Owen)
  */
 public abstract class ParsedReaderResult {
@@ -37,42 +45,23 @@ public abstract class ParsedReaderResult {
     // This is a bit messy, but given limited options in MIDP / CLDC, this may well be the simplest
     // way to go about this. For example, we have no reflection available, really.
     // Order is important here.
-    try {
-      return new BookmarkDoCoMoResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new AddressBookDoCoMoResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new EmailDoCoMoResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new EmailAddressResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new URLTOResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new URIParsedResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
-    }
-    try {
-      return new UPCParsedResult(rawText);
-    } catch (IllegalArgumentException iae) {
-      // continue
+    ParsedReaderResult result;
+    if ((result = BookmarkDoCoMoResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = AddressBookDoCoMoResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = EmailDoCoMoResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = EmailAddressResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = URLTOResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = URIParsedResult.parse(rawText)) != null) {
+      return result;
+    } else if ((result = UPCParsedResult.parse(rawText)) != null) {
+      return result;
     }
-    return new TextParsedResult(rawText);
+    return TextParsedResult.parse(rawText);
   }
 
   public String toString() {
index a64a046..79739b5 100644 (file)
@@ -23,9 +23,13 @@ public final class TextParsedResult extends ParsedReaderResult {
 
   private final String text;
 
-  public TextParsedResult(String rawText) {
+  private TextParsedResult(String text) {
     super(ParsedReaderResultType.TEXT);
-    text = rawText;
+    this.text = text;
+  }
+
+  public static TextParsedResult parse(String rawText) {
+    return new TextParsedResult(rawText);
   }
 
   public String getText() {
index 6cb2c04..1884821 100644 (file)
@@ -23,19 +23,24 @@ public final class UPCParsedResult extends ParsedReaderResult {
 
   private final String upc;
 
-  public UPCParsedResult(String rawText) {
+  private UPCParsedResult(String upc) {
     super(ParsedReaderResultType.UPC);
+    this.upc = upc;
+  }
+
+  public static UPCParsedResult parse(String rawText) {
     int length = rawText.length();
     if (length != 12 && length != 13) {
-      throw new IllegalArgumentException("Wrong number of digits for UPC");
+      return null;
     }
     for (int x = 0; x < length; x++) {
       char c = rawText.charAt(x);
       if (c < '0' || c > '9') {
-        throw new IllegalArgumentException("Invalid character found in UPC");
+        return null;
       }
     }
-    upc = rawText;
+    // Not actually checking the checkusm again here
+    return new UPCParsedResult(rawText);
   }
 
   public String getUPC() {
index 922a313..da59712 100644 (file)
@@ -23,13 +23,17 @@ public final class URIParsedResult extends ParsedReaderResult {
 
   private final String uri;
 
-  public URIParsedResult(String rawText) {
+  private URIParsedResult(String uri) {
     super(ParsedReaderResultType.URI);
+    this.uri = uri;
+  }
+
+  public static URIParsedResult parse(String rawText) {
     if (!isBasicallyValidURI(rawText)) {
-      throw new IllegalArgumentException("Invalid URI: " + rawText);
+      return null;
     }
-    uri = massagePossibleURI(rawText);
-
+    String uri = massagePossibleURI(rawText);
+    return new URIParsedResult(uri);
   }
 
   public String getURI() {
index eca1dc2..a854bee 100644 (file)
@@ -28,14 +28,23 @@ public final class URLTOResult extends ParsedReaderResult {
   private final String title;
   private final String uri;
 
-  public URLTOResult(String rawText) {
+  private URLTOResult(String title, String uri) {
     super(ParsedReaderResultType.URLTO);
+    this.title = title;
+    this.uri = uri;
+  }
+
+  public static URLTOResult parse(String rawText) {
     if (!rawText.startsWith("URLTO:")) {
-      throw new IllegalArgumentException("Does not begin with URLTO");
+      return null;
     }
     int titleEnd = rawText.indexOf(':', 6);
-    title = rawText.substring(6, titleEnd);
-    uri = rawText.substring(titleEnd + 1);
+    if (titleEnd < 0) {
+      return null;
+    }
+    String title = rawText.substring(6, titleEnd);
+    String uri = rawText.substring(titleEnd + 1);
+    return new URLTOResult(title, uri);
   }
 
   public String getTitle() {