@Override
 protected void endObject(String name) {
   try {
     writer.write("}");
   } catch (IOException e) {
     throw Exceptions.handle(e);
   }
 }
 /**
  * Generates a new output, writing to the given output stream.
  *
  * @param out the destination for the generated output
  * @param callback name of the callback function for JSONP requests
  * @param encoding the character encoding to use
  */
 public JSONStructuredOutput(OutputStream out, @Nullable String callback, String encoding) {
   try {
     this.callback = callback;
     writer = new OutputStreamWriter(out, encoding);
   } catch (UnsupportedEncodingException e) {
     throw Exceptions.handle(e);
   }
 }
 private void addRequiredComma() {
   if (!isCurrentObjectEmpty()) {
     try {
       writer.write(",");
     } catch (IOException e) {
       throw Exceptions.handle(e);
     }
   }
 }
 public BizController() {
   Optional<Method> defaultMethod =
       Arrays.stream(getClass().getDeclaredMethods())
           .filter(m -> m.isAnnotationPresent(DefaultRoute.class))
           .findFirst();
   if (!defaultMethod.isPresent()) {
     throw new IllegalStateException(
         Strings.apply("Controller %s has no default route!", getClass().getName()));
   }
   this.defaultRoute =
       ctx -> {
         try {
           defaultMethod.get().invoke(this, ctx);
         } catch (IllegalAccessException e) {
           throw Exceptions.handle(e);
         } catch (InvocationTargetException e) {
           throw Exceptions.handle(e.getTargetException());
         }
       };
 }
 protected <E extends BizEntity> E find(Class<E> type, String id) {
   if (BizEntity.NEW.equals(id)) {
     try {
       return type.newInstance();
     } catch (Throwable e) {
       throw Exceptions.handle()
           .to(LOG)
           .error(e)
           .withSystemErrorMessage("Cannot create a new instance of '%s'", type.getName())
           .handle();
     }
   }
   Optional<E> result = oma.find(type, id);
   if (!result.isPresent()) {
     throw Exceptions.createHandled()
         .withNLSKey("BizController.unknownObject")
         .set("id", id)
         .handle();
   }
   return result.get();
 }
 @Override
 public void endResult() {
   try {
     endObject();
     super.endResult();
     if (Strings.isFilled(callback)) {
       writer.write(")");
     }
     writer.close();
   } catch (IOException e) {
     throw Exceptions.handle(e);
   }
 }
 @Override
 protected void startArray(String name) {
   try {
     addRequiredComma();
     if (getCurrentType() == ElementType.OBJECT) {
       writer.write(string(name));
       writer.write(":[");
     } else {
       writer.write("[");
     }
   } catch (IOException e) {
     throw Exceptions.handle(e);
   }
 }
  @Override
  public StructuredOutput beginResult() {
    try {
      if (Strings.isFilled(callback)) {
        writer.write(callback);
        writer.write("(");
      }
      beginObject("result");
    } catch (IOException e) {
      throw Exceptions.handle(e);
    }

    return this;
  }
 @Override
 protected void startObject(String name, Attribute... attributes) {
   try {
     addRequiredComma();
     if (getCurrentType() == ElementType.OBJECT) {
       writer.write(string(name));
       writer.write(":{");
     } else {
       writer.write("{");
     }
     if (attributes != null) {
       for (Attribute attr : attributes) {
         property(attr.getName(), attr.getValue());
       }
     }
   } catch (IOException e) {
     throw Exceptions.handle(e);
   }
 }
 @Override
 public void writeProperty(String name, Object data) {
   try {
     addRequiredComma();
     if (getCurrentType() == ElementType.OBJECT) {
       writer.write(string(name));
       writer.write(":");
     }
     if (data == null) {
       writer.write("null");
     } else if (data instanceof Boolean || data instanceof Number) {
       writer.write(data.toString());
     } else {
       writer.write(string(data.toString()));
     }
   } catch (IOException e) {
     throw Exceptions.handle(e);
   }
 }