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.producer;
22  
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.OutputStream;
26  import java.lang.annotation.Annotation;
27  import java.lang.reflect.Type;
28  import java.util.Map;
29  import java.util.WeakHashMap;
30  
31  import javax.ws.rs.Produces;
32  import javax.ws.rs.WebApplicationException;
33  import javax.ws.rs.core.MediaType;
34  import javax.ws.rs.core.MultivaluedMap;
35  import javax.ws.rs.ext.MessageBodyWriter;
36  import javax.ws.rs.ext.Provider;
37  
38  import org.apache.hadoop.hbase.rest.Constants;
39  import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
40  
41  /**
42   * An adapter between Jersey and ProtobufMessageHandler implementors. Hooks up
43   * protobuf output producing methods to the Jersey content handling framework.
44   * Jersey will first call getSize() to learn the number of bytes that will be
45   * sent, then writeTo to perform the actual I/O.
46   */
47  @Provider
48  @Produces(Constants.MIMETYPE_PROTOBUF)
49  public class ProtobufMessageBodyProducer
50    implements MessageBodyWriter<ProtobufMessageHandler> {
51  
52    private Map<Object, byte[]> buffer = new WeakHashMap<Object, byte[]>();
53  
54  	@Override
55  	public boolean isWriteable(Class<?> type, Type genericType, 
56  	  Annotation[] annotations, MediaType mediaType) {
57        return ProtobufMessageHandler.class.isAssignableFrom(type);
58    }
59  
60  	@Override
61  	public long getSize(ProtobufMessageHandler m, Class<?> type, Type genericType,
62  	    Annotation[] annotations, MediaType mediaType) {
63  	  ByteArrayOutputStream baos = new ByteArrayOutputStream();
64  	  try {
65  	    baos.write(m.createProtobufOutput());
66  	  } catch (IOException e) {
67  	    return -1;
68  	  }
69  	  byte[] bytes = baos.toByteArray();
70  	  buffer.put(m, bytes);
71  	  return bytes.length;
72  	}
73  
74  	public void writeTo(ProtobufMessageHandler m, Class<?> type, Type genericType,
75  	    Annotation[] annotations, MediaType mediaType, 
76  	    MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) 
77  	    throws IOException, WebApplicationException {
78  	  entityStream.write(buffer.remove(m));
79  	}
80  }