View Javadoc

1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.rest.provider.consumer;
22  
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.lang.annotation.Annotation;
27  import java.lang.reflect.Type;
28  
29  import javax.ws.rs.Consumes;
30  import javax.ws.rs.WebApplicationException;
31  import javax.ws.rs.core.MediaType;
32  import javax.ws.rs.core.MultivaluedMap;
33  import javax.ws.rs.ext.MessageBodyReader;
34  import javax.ws.rs.ext.Provider;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.hadoop.hbase.rest.Constants;
39  import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
40  
41  /**
42   * Adapter for hooking up Jersey content processing dispatch to
43   * ProtobufMessageHandler interface capable handlers for decoding protobuf input.
44   */
45  @Provider
46  @Consumes({Constants.MIMETYPE_PROTOBUF, Constants.MIMETYPE_PROTOBUF_IETF})
47  public class ProtobufMessageBodyConsumer 
48      implements MessageBodyReader<ProtobufMessageHandler> {
49    private static final Log LOG =
50      LogFactory.getLog(ProtobufMessageBodyConsumer.class);
51  
52    @Override
53    public boolean isReadable(Class<?> type, Type genericType,
54        Annotation[] annotations, MediaType mediaType) {
55      return ProtobufMessageHandler.class.isAssignableFrom(type);
56    }
57  
58    @Override
59    public ProtobufMessageHandler readFrom(Class<ProtobufMessageHandler> type, Type genericType,
60        Annotation[] annotations, MediaType mediaType,
61        MultivaluedMap<String, String> httpHeaders, InputStream inputStream)
62        throws IOException, WebApplicationException {
63      ProtobufMessageHandler obj = null;
64      try {
65        obj = type.newInstance();
66        ByteArrayOutputStream baos = new ByteArrayOutputStream();
67        byte[] buffer = new byte[4096];
68        int read;
69        do {
70          read = inputStream.read(buffer, 0, buffer.length);
71          if (read > 0) {
72            baos.write(buffer, 0, read);
73          }
74        } while (read > 0);
75        if (LOG.isDebugEnabled()) {
76          LOG.debug(getClass() + ": read " + baos.size() + " bytes from " +
77            inputStream);
78        }
79        obj = obj.getObjectFromMessage(baos.toByteArray());
80      } catch (InstantiationException e) {
81        throw new WebApplicationException(e);
82      } catch (IllegalAccessException e) {
83        throw new WebApplicationException(e);
84      }
85      return obj;
86    }
87  }