On Fri, Jan 21, 2011 at 4:27 AM, weltermann17 <[email protected]>wrote:

> [...] As stated elsewhere in this forum a basic solution could be to always
> call exhaust and release on a representation after using it (samples in
> Scala):
>
> val representation = response.getEntity
> if (null != representation) {
>  try {
>     // do something with it
>  } finally {
>    representation.exhaust
>    representation.release
>  }
> }
>
> To not clutter our code with this we adopted the "Disposable Pattern"
> for Scala:
> [...]
> This allows cleaner code (many details omitted):
> [...]
> With "using" and "disposable" the compiler ensures that in either
> case (success or failure) the representation is exhausted and released. In
> case of failure the exception is handled elsewhere.
>
> Now this is Scala and doesn't help much in a pure Java environment. I
> think it would be great if this were made part of Restlet, but I'm sure
> it wouldn't be easy.
>

I'm still waiting to hear from Jerome or Thierry about whether explicitly
exhausting and releasing every representation is even a good idea, but doing
it in Java isn't hard to do nicely:

  JsonNode data = consume(clientRes.get(MediaType.APPLICATION_JSON),
      new ReaderRepresentationConsumer<JsonNode>() {
          public JsonNode consume(Reader reader) throws Exception {
              return getObjectMapper() // using Jackson, but same idea
                .readTree(reader)
                .get("response")
                .get("data");
          }
      });

where you've defined the following in a utility package for general use:

  public interface RepresentationConsumer<T> {
      T consume(Representation rep) throws Exception;
  }

  public abstract class ReaderRepresentationConsumer<T>
          implements RepresentationConsumer<T> {
      public final T consume(Representation rep) throws Exception {
          return consume(new InputStreamReader(rep.getStream()));
      }
      public abstract T consume(Reader reader) throws Exception;
  }

  public static <T>
  T consume(Representation rep,
            RepresentationConsumer<T> consumer)
            throws Exception {
      try {
          return consumer.consume(rep);
      } finally {
          rep.exhaust();
          rep.release();
      }
  }

This could be tweaked to handle finer-grained exceptions.

And don't forget the try-with-resources language enhancement coming as part
of JSR 334:

  try (CloseableRepresentation rep = clientRes.get()) {
      // do something with rep
  } // automatically calls rep.close(), which could call exhaust, release.

--tim

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2699618

Reply via email to