Throw a specific exception type on invalid GitilesViews

This is an unchecked exception because generally programmers are
responsible for maintaining view invariants themselves, but sometimes
due to complex logic this is not always achievable.

Change-Id: Ie14503eca0c13b3c07b110961739e5032ca11757
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
index 1239ac7..df6e1ef 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
@@ -16,7 +16,6 @@
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
 import static com.google.gitiles.GitilesUrls.NAME_ESCAPER;
 import static com.google.gitiles.RevisionParser.PATH_SPLITTER;
 
@@ -58,6 +57,15 @@
     LOG;
   }
 
+  /** Exception thrown when building a view that is invalid. */
+  public static class InvalidViewException extends IllegalStateException {
+    private static final long serialVersionUID = 1L;
+
+    public InvalidViewException(String msg) {
+      super(msg);
+    }
+  }
+
   /** Builder for views. */
   public static class Builder {
     private final Type type;
@@ -271,13 +279,19 @@
       return build().toUrl();
     }
 
+    private void checkView(boolean expr, String msg, Object... args) {
+      if (!expr) {
+        throw new InvalidViewException(String.format(msg, args));
+      }
+    }
+
     private void checkHostIndex() {
-      checkState(hostName != null, "missing hostName on %s view", type);
-      checkState(servletPath != null, "missing hostName on %s view", type);
+      checkView(hostName != null, "missing hostName on %s view", type);
+      checkView(servletPath != null, "missing hostName on %s view", type);
     }
 
     private void checkRepositoryIndex() {
-      checkState(repositoryName != null, "missing repository name on %s view", type);
+      checkView(repositoryName != null, "missing repository name on %s view", type);
       checkHostIndex();
     }
 
@@ -286,7 +300,7 @@
     }
 
     private void checkRevision() {
-      checkState(revision != Revision.NULL, "missing revision on %s view", type);
+      checkView(revision != Revision.NULL, "missing revision on %s view", type);
       checkRepositoryIndex();
     }
 
@@ -299,7 +313,7 @@
     }
 
     private void checkPath() {
-      checkState(path != null, "missing path on %s view", type);
+      checkView(path != null, "missing path on %s view", type);
       checkRevision();
     }
   }