1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.io;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.DataInput;
24 import java.io.DataOutput;
25 import java.io.InputStream;
26 import java.io.IOException;
27 import java.io.ObjectInputStream;
28 import java.io.ObjectOutputStream;
29 import java.io.Serializable;
30 import java.lang.reflect.Array;
31 import java.lang.reflect.InvocationTargetException;
32 import java.lang.reflect.Method;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.NavigableSet;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.hadoop.conf.Configurable;
42 import org.apache.hadoop.conf.Configuration;
43 import org.apache.hadoop.conf.Configured;
44 import org.apache.hadoop.hbase.ClusterStatus;
45 import org.apache.hadoop.hbase.DoNotRetryIOException;
46 import org.apache.hadoop.hbase.HColumnDescriptor;
47 import org.apache.hadoop.hbase.HConstants;
48 import org.apache.hadoop.hbase.HRegionInfo;
49 import org.apache.hadoop.hbase.HServerAddress;
50 import org.apache.hadoop.hbase.HServerInfo;
51 import org.apache.hadoop.hbase.HServerLoad;
52 import org.apache.hadoop.hbase.HTableDescriptor;
53 import org.apache.hadoop.hbase.KeyValue;
54 import org.apache.hadoop.hbase.client.Action;
55 import org.apache.hadoop.hbase.client.Append;
56 import org.apache.hadoop.hbase.client.Delete;
57 import org.apache.hadoop.hbase.client.Get;
58 import org.apache.hadoop.hbase.client.Increment;
59 import org.apache.hadoop.hbase.client.MultiAction;
60 import org.apache.hadoop.hbase.client.MultiResponse;
61 import org.apache.hadoop.hbase.client.Put;
62 import org.apache.hadoop.hbase.client.Result;
63 import org.apache.hadoop.hbase.client.Row;
64 import org.apache.hadoop.hbase.client.RowMutations;
65 import org.apache.hadoop.hbase.client.Scan;
66 import org.apache.hadoop.hbase.client.coprocessor.Exec;
67 import org.apache.hadoop.hbase.filter.BinaryComparator;
68 import org.apache.hadoop.hbase.filter.BitComparator;
69 import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
70 import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;
71 import org.apache.hadoop.hbase.filter.ColumnRangeFilter;
72 import org.apache.hadoop.hbase.filter.CompareFilter;
73 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
74 import org.apache.hadoop.hbase.filter.DependentColumnFilter;
75 import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
76 import org.apache.hadoop.hbase.filter.FuzzyRowFilter;
77 import org.apache.hadoop.hbase.filter.InclusiveStopFilter;
78 import org.apache.hadoop.hbase.filter.KeyOnlyFilter;
79 import org.apache.hadoop.hbase.filter.PageFilter;
80 import org.apache.hadoop.hbase.filter.PrefixFilter;
81 import org.apache.hadoop.hbase.filter.QualifierFilter;
82 import org.apache.hadoop.hbase.filter.RandomRowFilter;
83 import org.apache.hadoop.hbase.filter.RowFilter;
84 import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;
85 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
86 import org.apache.hadoop.hbase.filter.SkipFilter;
87 import org.apache.hadoop.hbase.filter.ValueFilter;
88 import org.apache.hadoop.hbase.filter.WhileMatchFilter;
89 import org.apache.hadoop.hbase.filter.WritableByteArrayComparable;
90 import org.apache.hadoop.hbase.regionserver.HRegion;
91 import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
92 import org.apache.hadoop.hbase.regionserver.wal.HLog;
93 import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
94 import org.apache.hadoop.hbase.snapshot.HSnapshotDescription;
95 import org.apache.hadoop.hbase.util.Bytes;
96 import org.apache.hadoop.hbase.util.ProtoUtil;
97 import org.apache.hadoop.io.MapWritable;
98 import org.apache.hadoop.io.ObjectWritable;
99 import org.apache.hadoop.io.Text;
100 import org.apache.hadoop.io.Writable;
101 import org.apache.hadoop.io.WritableFactories;
102 import org.apache.hadoop.io.WritableUtils;
103
104 import com.google.protobuf.Message;
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 public class HbaseObjectWritable implements Writable, WritableWithSize, Configurable {
122 protected final static Log LOG = LogFactory.getLog(HbaseObjectWritable.class);
123
124
125
126
127 static final Map<Integer, Class<?>> CODE_TO_CLASS =
128 new HashMap<Integer, Class<?>>();
129 static final Map<Class<?>, Integer> CLASS_TO_CODE =
130 new HashMap<Class<?>, Integer>();
131
132
133 private static final byte NOT_ENCODED = 0;
134
135
136
137 private static final int GENERIC_ARRAY_CODE;
138 private static final int NEXT_CLASS_CODE;
139 static {
140
141
142
143
144
145
146
147
148 int code = NOT_ENCODED + 1;
149
150 addToMap(Boolean.TYPE, code++);
151 addToMap(Byte.TYPE, code++);
152 addToMap(Character.TYPE, code++);
153 addToMap(Short.TYPE, code++);
154 addToMap(Integer.TYPE, code++);
155 addToMap(Long.TYPE, code++);
156 addToMap(Float.TYPE, code++);
157 addToMap(Double.TYPE, code++);
158 addToMap(Void.TYPE, code++);
159
160
161 addToMap(String.class, code++);
162 addToMap(byte [].class, code++);
163 addToMap(byte [][].class, code++);
164
165
166 addToMap(Text.class, code++);
167 addToMap(Writable.class, code++);
168 addToMap(Writable [].class, code++);
169 addToMap(HbaseMapWritable.class, code++);
170 addToMap(NullInstance.class, code++);
171
172
173 addToMap(HColumnDescriptor.class, code++);
174 addToMap(HConstants.Modify.class, code++);
175
176
177
178
179
180 addToMap(Integer.class, code++);
181 addToMap(Integer[].class, code++);
182
183 addToMap(HRegion.class, code++);
184 addToMap(HRegion[].class, code++);
185 addToMap(HRegionInfo.class, code++);
186 addToMap(HRegionInfo[].class, code++);
187 addToMap(HServerAddress.class, code++);
188 addToMap(HServerInfo.class, code++);
189 addToMap(HTableDescriptor.class, code++);
190 addToMap(MapWritable.class, code++);
191
192
193
194
195 addToMap(ClusterStatus.class, code++);
196 addToMap(Delete.class, code++);
197 addToMap(Get.class, code++);
198 addToMap(KeyValue.class, code++);
199 addToMap(KeyValue[].class, code++);
200 addToMap(Put.class, code++);
201 addToMap(Put[].class, code++);
202 addToMap(Result.class, code++);
203 addToMap(Result[].class, code++);
204 addToMap(Scan.class, code++);
205
206 addToMap(WhileMatchFilter.class, code++);
207 addToMap(PrefixFilter.class, code++);
208 addToMap(PageFilter.class, code++);
209 addToMap(InclusiveStopFilter.class, code++);
210 addToMap(ColumnCountGetFilter.class, code++);
211 addToMap(SingleColumnValueFilter.class, code++);
212 addToMap(SingleColumnValueExcludeFilter.class, code++);
213 addToMap(BinaryComparator.class, code++);
214 addToMap(BitComparator.class, code++);
215 addToMap(CompareFilter.class, code++);
216 addToMap(RowFilter.class, code++);
217 addToMap(ValueFilter.class, code++);
218 addToMap(QualifierFilter.class, code++);
219 addToMap(SkipFilter.class, code++);
220 addToMap(WritableByteArrayComparable.class, code++);
221 addToMap(FirstKeyOnlyFilter.class, code++);
222 addToMap(DependentColumnFilter.class, code++);
223
224 addToMap(Delete [].class, code++);
225
226 addToMap(HLog.Entry.class, code++);
227 addToMap(HLog.Entry[].class, code++);
228 addToMap(HLogKey.class, code++);
229
230 addToMap(List.class, code++);
231
232 addToMap(NavigableSet.class, code++);
233 addToMap(ColumnPrefixFilter.class, code++);
234
235
236 addToMap(Row.class, code++);
237 addToMap(Action.class, code++);
238 addToMap(MultiAction.class, code++);
239 addToMap(MultiResponse.class, code++);
240
241
242 addToMap(Exec.class, code++);
243 addToMap(Increment.class, code++);
244
245 addToMap(KeyOnlyFilter.class, code++);
246
247
248 addToMap(Serializable.class, code++);
249
250 addToMap(RandomRowFilter.class, code++);
251
252 addToMap(CompareOp.class, code++);
253
254 addToMap(ColumnRangeFilter.class, code++);
255
256 addToMap(HServerLoad.class, code++);
257
258 addToMap(RegionOpeningState.class, code++);
259
260 addToMap(HTableDescriptor[].class, code++);
261
262 addToMap(Append.class, code++);
263
264 addToMap(RowMutations.class, code++);
265
266 addToMap(Message.class, code++);
267
268
269 GENERIC_ARRAY_CODE = code++;
270 addToMap(Array.class, GENERIC_ARRAY_CODE);
271
272 addToMap(FuzzyRowFilter.class, code++);
273
274
275
276 addToMap(HSnapshotDescription.class, code);
277
278
279 NEXT_CLASS_CODE = code;
280 }
281
282 private Class<?> declaredClass;
283 private Object instance;
284 private Configuration conf;
285
286
287 public HbaseObjectWritable() {
288 super();
289 }
290
291
292
293
294 public HbaseObjectWritable(Object instance) {
295 set(instance);
296 }
297
298
299
300
301
302 public HbaseObjectWritable(Class<?> declaredClass, Object instance) {
303 this.declaredClass = declaredClass;
304 this.instance = instance;
305 }
306
307
308 public Object get() { return instance; }
309
310
311 public Class<?> getDeclaredClass() { return declaredClass; }
312
313
314
315
316
317 public void set(Object instance) {
318 this.declaredClass = instance.getClass();
319 this.instance = instance;
320 }
321
322
323
324
325 @Override
326 public String toString() {
327 return "OW[class=" + declaredClass + ",value=" + instance + "]";
328 }
329
330
331 public void readFields(DataInput in) throws IOException {
332 readObject(in, this, this.conf);
333 }
334
335 public void write(DataOutput out) throws IOException {
336 writeObject(out, instance, declaredClass, conf);
337 }
338
339 public long getWritableSize() {
340 return getWritableSize(instance, declaredClass, conf);
341 }
342
343 private static class NullInstance extends Configured implements Writable {
344 Class<?> declaredClass;
345
346 @SuppressWarnings("unused")
347 public NullInstance() { super(null); }
348
349
350
351
352
353 public NullInstance(Class<?> declaredClass, Configuration conf) {
354 super(conf);
355 this.declaredClass = declaredClass;
356 }
357
358 public void readFields(DataInput in) throws IOException {
359 this.declaredClass = CODE_TO_CLASS.get(WritableUtils.readVInt(in));
360 }
361
362 public void write(DataOutput out) throws IOException {
363 writeClassCode(out, this.declaredClass);
364 }
365 }
366
367 static Integer getClassCode(final Class<?> c)
368 throws IOException {
369 Integer code = CLASS_TO_CODE.get(c);
370 if (code == null ) {
371 if (List.class.isAssignableFrom(c)) {
372 code = CLASS_TO_CODE.get(List.class);
373 } else if (Writable.class.isAssignableFrom(c)) {
374 code = CLASS_TO_CODE.get(Writable.class);
375 } else if (c.isArray()) {
376 code = CLASS_TO_CODE.get(Array.class);
377 } else if (Message.class.isAssignableFrom(c)) {
378 code = CLASS_TO_CODE.get(Message.class);
379 } else if (Serializable.class.isAssignableFrom(c)){
380 code = CLASS_TO_CODE.get(Serializable.class);
381 }
382 }
383 return code;
384 }
385
386
387
388
389 static int getNextClassCode(){
390 return NEXT_CLASS_CODE;
391 }
392
393
394
395
396
397
398
399 static void writeClassCode(final DataOutput out, final Class<?> c)
400 throws IOException {
401 Integer code = getClassCode(c);
402
403 if (code == null) {
404 LOG.error("Unsupported type " + c);
405 StackTraceElement[] els = new Exception().getStackTrace();
406 for(StackTraceElement elem : els) {
407 LOG.error(elem.getMethodName());
408 }
409 throw new UnsupportedOperationException("No code for unexpected " + c);
410 }
411 WritableUtils.writeVInt(out, code);
412 }
413
414 public static long getWritableSize(Object instance, Class declaredClass,
415 Configuration conf) {
416 long size = Bytes.SIZEOF_BYTE;
417 if (instance == null) {
418 return 0L;
419 }
420
421 if (declaredClass.isArray()) {
422 if (declaredClass.equals(Result[].class)) {
423
424 return size + Result.getWriteArraySize((Result[])instance);
425 }
426 }
427 if (declaredClass.equals(Result.class)) {
428 Result r = (Result) instance;
429
430 return r.getWritableSize() + size + Bytes.SIZEOF_BYTE;
431 }
432 return 0L;
433 }
434
435
436
437
438
439
440
441
442
443 @SuppressWarnings("unchecked")
444 public static void writeObject(DataOutput out, Object instance,
445 Class declaredClass,
446 Configuration conf)
447 throws IOException {
448
449 Object instanceObj = instance;
450 Class declClass = declaredClass;
451
452 if (instanceObj == null) {
453 instanceObj = new NullInstance(declClass, conf);
454 declClass = Writable.class;
455 }
456 writeClassCode(out, declClass);
457 if (declClass.isArray()) {
458
459
460 if (declClass.equals(byte [].class)) {
461 Bytes.writeByteArray(out, (byte [])instanceObj);
462 } else if(declClass.equals(Result [].class)) {
463 Result.writeArray(out, (Result [])instanceObj);
464 } else {
465
466 if (getClassCode(declaredClass) == GENERIC_ARRAY_CODE) {
467 Class<?> componentType = declaredClass.getComponentType();
468 writeClass(out, componentType);
469 }
470
471 int length = Array.getLength(instanceObj);
472 out.writeInt(length);
473 for (int i = 0; i < length; i++) {
474 Object item = Array.get(instanceObj, i);
475 writeObject(out, item,
476 item.getClass(), conf);
477 }
478 }
479 } else if (List.class.isAssignableFrom(declClass)) {
480 List list = (List)instanceObj;
481 int length = list.size();
482 out.writeInt(length);
483 for (int i = 0; i < length; i++) {
484 Object elem = list.get(i);
485 writeObject(out, elem,
486 elem == null ? Writable.class : elem.getClass(), conf);
487 }
488 } else if (declClass == String.class) {
489 Text.writeString(out, (String)instanceObj);
490 } else if (declClass.isPrimitive()) {
491 if (declClass == Boolean.TYPE) {
492 out.writeBoolean(((Boolean)instanceObj).booleanValue());
493 } else if (declClass == Character.TYPE) {
494 out.writeChar(((Character)instanceObj).charValue());
495 } else if (declClass == Byte.TYPE) {
496 out.writeByte(((Byte)instanceObj).byteValue());
497 } else if (declClass == Short.TYPE) {
498 out.writeShort(((Short)instanceObj).shortValue());
499 } else if (declClass == Integer.TYPE) {
500 out.writeInt(((Integer)instanceObj).intValue());
501 } else if (declClass == Long.TYPE) {
502 out.writeLong(((Long)instanceObj).longValue());
503 } else if (declClass == Float.TYPE) {
504 out.writeFloat(((Float)instanceObj).floatValue());
505 } else if (declClass == Double.TYPE) {
506 out.writeDouble(((Double)instanceObj).doubleValue());
507 } else if (declClass == Void.TYPE) {
508 } else {
509 throw new IllegalArgumentException("Not a primitive: "+declClass);
510 }
511 } else if (declClass.isEnum()) {
512 Text.writeString(out, ((Enum)instanceObj).name());
513 } else if (Message.class.isAssignableFrom(declaredClass)) {
514 Text.writeString(out, instanceObj.getClass().getName());
515 ((Message)instance).writeDelimitedTo(
516 DataOutputOutputStream.constructOutputStream(out));
517 } else if (Writable.class.isAssignableFrom(declClass)) {
518 Class <?> c = instanceObj.getClass();
519 Integer code = CLASS_TO_CODE.get(c);
520 if (code == null) {
521 out.writeByte(NOT_ENCODED);
522 Text.writeString(out, c.getName());
523 } else {
524 writeClassCode(out, c);
525 }
526 ((Writable)instanceObj).write(out);
527 } else if (Serializable.class.isAssignableFrom(declClass)) {
528 Class <?> c = instanceObj.getClass();
529 Integer code = CLASS_TO_CODE.get(c);
530 if (code == null) {
531 out.writeByte(NOT_ENCODED);
532 Text.writeString(out, c.getName());
533 } else {
534 writeClassCode(out, c);
535 }
536 ByteArrayOutputStream bos = null;
537 ObjectOutputStream oos = null;
538 try{
539 bos = new ByteArrayOutputStream();
540 oos = new ObjectOutputStream(bos);
541 oos.writeObject(instanceObj);
542 byte[] value = bos.toByteArray();
543 out.writeInt(value.length);
544 out.write(value);
545 } finally {
546 if(bos!=null) bos.close();
547 if(oos!=null) oos.close();
548 }
549 } else {
550 throw new IOException("Can't write: "+instanceObj+" as "+declClass);
551 }
552 }
553
554
555
556
557 static void writeClass(DataOutput out, Class<?> c) throws IOException {
558 Integer code = CLASS_TO_CODE.get(c);
559 if (code == null) {
560 WritableUtils.writeVInt(out, NOT_ENCODED);
561 Text.writeString(out, c.getName());
562 } else {
563 WritableUtils.writeVInt(out, code);
564 }
565 }
566
567
568 static Class<?> readClass(Configuration conf, DataInput in) throws IOException {
569 Class<?> instanceClass = null;
570 int b = (byte)WritableUtils.readVInt(in);
571 if (b == NOT_ENCODED) {
572 String className = Text.readString(in);
573 try {
574 instanceClass = getClassByName(conf, className);
575 } catch (ClassNotFoundException e) {
576 LOG.error("Can't find class " + className, e);
577 throw new IOException("Can't find class " + className, e);
578 }
579 } else {
580 instanceClass = CODE_TO_CLASS.get(b);
581 }
582 return instanceClass;
583 }
584
585
586
587
588
589
590
591
592
593 public static Object readObject(DataInput in, Configuration conf)
594 throws IOException {
595 return readObject(in, null, conf);
596 }
597
598
599
600
601
602
603
604
605
606
607 @SuppressWarnings("unchecked")
608 public static Object readObject(DataInput in,
609 HbaseObjectWritable objectWritable, Configuration conf)
610 throws IOException {
611 Class<?> declaredClass = CODE_TO_CLASS.get(WritableUtils.readVInt(in));
612 Object instance;
613 if (declaredClass.isPrimitive()) {
614 if (declaredClass == Boolean.TYPE) {
615 instance = Boolean.valueOf(in.readBoolean());
616 } else if (declaredClass == Character.TYPE) {
617 instance = Character.valueOf(in.readChar());
618 } else if (declaredClass == Byte.TYPE) {
619 instance = Byte.valueOf(in.readByte());
620 } else if (declaredClass == Short.TYPE) {
621 instance = Short.valueOf(in.readShort());
622 } else if (declaredClass == Integer.TYPE) {
623 instance = Integer.valueOf(in.readInt());
624 } else if (declaredClass == Long.TYPE) {
625 instance = Long.valueOf(in.readLong());
626 } else if (declaredClass == Float.TYPE) {
627 instance = Float.valueOf(in.readFloat());
628 } else if (declaredClass == Double.TYPE) {
629 instance = Double.valueOf(in.readDouble());
630 } else if (declaredClass == Void.TYPE) {
631 instance = null;
632 } else {
633 throw new IllegalArgumentException("Not a primitive: "+declaredClass);
634 }
635 } else if (declaredClass.isArray()) {
636 if (declaredClass.equals(byte [].class)) {
637 instance = Bytes.readByteArray(in);
638 } else if(declaredClass.equals(Result [].class)) {
639 instance = Result.readArray(in);
640 } else {
641 int length = in.readInt();
642 instance = Array.newInstance(declaredClass.getComponentType(), length);
643 for (int i = 0; i < length; i++) {
644 Array.set(instance, i, readObject(in, conf));
645 }
646 }
647 } else if (declaredClass.equals(Array.class)) {
648 Class<?> componentType = readClass(conf, in);
649 int length = in.readInt();
650 instance = Array.newInstance(componentType, length);
651 for (int i = 0; i < length; i++) {
652 Array.set(instance, i, readObject(in, conf));
653 }
654 } else if (List.class.isAssignableFrom(declaredClass)) {
655 int length = in.readInt();
656 instance = new ArrayList(length);
657 for (int i = 0; i < length; i++) {
658 ((ArrayList)instance).add(readObject(in, conf));
659 }
660 } else if (declaredClass == String.class) {
661 instance = Text.readString(in);
662 } else if (declaredClass.isEnum()) {
663 instance = Enum.valueOf((Class<? extends Enum>) declaredClass,
664 Text.readString(in));
665 } else if (declaredClass == Message.class) {
666 String className = Text.readString(in);
667 try {
668 declaredClass = getClassByName(conf, className);
669 instance = tryInstantiateProtobuf(declaredClass, in);
670 } catch (ClassNotFoundException e) {
671 LOG.error("Can't find class " + className, e);
672 throw new DoNotRetryIOException("Can't find class " + className, e);
673 }
674 } else {
675 Class instanceClass = null;
676 int b = (byte)WritableUtils.readVInt(in);
677 if (b == NOT_ENCODED) {
678 String className = Text.readString(in);
679 try {
680 instanceClass = getClassByName(conf, className);
681 } catch (ClassNotFoundException e) {
682 LOG.error("Can't find class " + className, e);
683 throw new DoNotRetryIOException("Can't find class " + className, e);
684 }
685 } else {
686 instanceClass = CODE_TO_CLASS.get(b);
687 }
688 if(Writable.class.isAssignableFrom(instanceClass)){
689 Writable writable = WritableFactories.newInstance(instanceClass, conf);
690 try {
691 writable.readFields(in);
692 } catch (IOException io) {
693 LOG.error("Error in readFields", io);
694 throw io;
695 } catch (Exception e) {
696 LOG.error("Error in readFields", e);
697 throw new IOException("Error in readFields" , e);
698 }
699 instance = writable;
700 if (instanceClass == NullInstance.class) {
701 declaredClass = ((NullInstance)instance).declaredClass;
702 instance = null;
703 }
704 } else {
705 int length = in.readInt();
706 byte[] objectBytes = new byte[length];
707 in.readFully(objectBytes);
708 ByteArrayInputStream bis = null;
709 ObjectInputStream ois = null;
710 try {
711 bis = new ByteArrayInputStream(objectBytes);
712 ois = new ObjectInputStream(bis);
713 instance = ois.readObject();
714 } catch (ClassNotFoundException e) {
715 LOG.error("Class not found when attempting to deserialize object", e);
716 throw new DoNotRetryIOException("Class not found when attempting to " +
717 "deserialize object", e);
718 } finally {
719 if(bis!=null) bis.close();
720 if(ois!=null) ois.close();
721 }
722 }
723 }
724 if (objectWritable != null) {
725 objectWritable.declaredClass = declaredClass;
726 objectWritable.instance = instance;
727 }
728 return instance;
729 }
730
731
732
733
734
735
736
737
738
739
740 private static Message tryInstantiateProtobuf(
741 Class<?> protoClass,
742 DataInput dataIn) throws IOException {
743
744 try {
745 if (dataIn instanceof InputStream) {
746
747
748 Method parseMethod = getStaticProtobufMethod(protoClass,
749 "parseDelimitedFrom", InputStream.class);
750 return (Message)parseMethod.invoke(null, (InputStream)dataIn);
751 } else {
752
753
754
755
756 int size = ProtoUtil.readRawVarint32(dataIn);
757 if (size < 0) {
758 throw new IOException("Invalid size: " + size);
759 }
760
761 byte[] data = new byte[size];
762 dataIn.readFully(data);
763 Method parseMethod = getStaticProtobufMethod(protoClass,
764 "parseFrom", byte[].class);
765 return (Message)parseMethod.invoke(null, data);
766 }
767 } catch (InvocationTargetException e) {
768
769 if (e.getCause() instanceof IOException) {
770 throw (IOException)e.getCause();
771 } else {
772 throw new IOException(e.getCause());
773 }
774 } catch (IllegalAccessException iae) {
775 throw new AssertionError("Could not access parse method in " +
776 protoClass);
777 }
778 }
779
780 static Method getStaticProtobufMethod(Class<?> declaredClass, String method,
781 Class<?> ... args) {
782
783 try {
784 return declaredClass.getMethod(method, args);
785 } catch (Exception e) {
786
787 throw new AssertionError("Protocol buffer class " + declaredClass +
788 " does not have an accessible parseFrom(InputStream) method!");
789 }
790 }
791
792 @SuppressWarnings("unchecked")
793 private static Class getClassByName(Configuration conf, String className)
794 throws ClassNotFoundException {
795 if(conf != null) {
796 return conf.getClassByName(className);
797 }
798 ClassLoader cl = Thread.currentThread().getContextClassLoader();
799 if(cl == null) {
800 cl = HbaseObjectWritable.class.getClassLoader();
801 }
802 return Class.forName(className, true, cl);
803 }
804
805 private static void addToMap(final Class<?> clazz, final int code) {
806 CLASS_TO_CODE.put(clazz, code);
807 CODE_TO_CLASS.put(code, clazz);
808 }
809
810 public void setConf(Configuration conf) {
811 this.conf = conf;
812 }
813
814 public Configuration getConf() {
815 return this.conf;
816 }
817 }