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.IOException;
26 import java.io.InputStream;
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.HColumnDescriptor;
46 import org.apache.hadoop.hbase.HConstants;
47 import org.apache.hadoop.hbase.HRegionInfo;
48 import org.apache.hadoop.hbase.HServerAddress;
49 import org.apache.hadoop.hbase.HServerInfo;
50 import org.apache.hadoop.hbase.HServerLoad;
51 import org.apache.hadoop.hbase.HServerLoadWithSeqIds;
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
280 int negativeCode = -2;
281 addToMap(HServerLoadWithSeqIds.class, negativeCode--);
282
283
284 NEXT_CLASS_CODE = code;
285 }
286
287 private Class<?> declaredClass;
288 private Object instance;
289 private Configuration conf;
290
291
292 public HbaseObjectWritable() {
293 super();
294 }
295
296
297
298
299 public HbaseObjectWritable(Object instance) {
300 set(instance);
301 }
302
303
304
305
306
307 public HbaseObjectWritable(Class<?> declaredClass, Object instance) {
308 this.declaredClass = declaredClass;
309 this.instance = instance;
310 }
311
312
313 public Object get() { return instance; }
314
315
316 public Class<?> getDeclaredClass() { return declaredClass; }
317
318
319
320
321
322 public void set(Object instance) {
323 this.declaredClass = instance.getClass();
324 this.instance = instance;
325 }
326
327
328
329
330 @Override
331 public String toString() {
332 return "OW[class=" + declaredClass + ",value=" + instance + "]";
333 }
334
335
336 public void readFields(DataInput in) throws IOException {
337 readObject(in, this, this.conf);
338 }
339
340 public void write(DataOutput out) throws IOException {
341 writeObject(out, instance, declaredClass, conf);
342 }
343
344 public long getWritableSize() {
345 return getWritableSize(instance, declaredClass, conf);
346 }
347
348 private static class NullInstance extends Configured implements Writable {
349 Class<?> declaredClass;
350
351 @SuppressWarnings("unused")
352 public NullInstance() { super(null); }
353
354
355
356
357
358 public NullInstance(Class<?> declaredClass, Configuration conf) {
359 super(conf);
360 this.declaredClass = declaredClass;
361 }
362
363 public void readFields(DataInput in) throws IOException {
364 this.declaredClass = CODE_TO_CLASS.get(WritableUtils.readVInt(in));
365 }
366
367 public void write(DataOutput out) throws IOException {
368 writeClassCode(out, this.declaredClass);
369 }
370 }
371
372 static Integer getClassCode(final Class<?> c)
373 throws IOException {
374 Integer code = CLASS_TO_CODE.get(c);
375 if (code == null ) {
376 if (List.class.isAssignableFrom(c)) {
377 code = CLASS_TO_CODE.get(List.class);
378 } else if (Writable.class.isAssignableFrom(c)) {
379 code = CLASS_TO_CODE.get(Writable.class);
380 } else if (c.isArray()) {
381 code = CLASS_TO_CODE.get(Array.class);
382 } else if (Message.class.isAssignableFrom(c)) {
383 code = CLASS_TO_CODE.get(Message.class);
384 } else if (Serializable.class.isAssignableFrom(c)){
385 code = CLASS_TO_CODE.get(Serializable.class);
386 }
387 }
388 return code;
389 }
390
391
392
393
394 static int getNextClassCode(){
395 return NEXT_CLASS_CODE;
396 }
397
398
399
400
401
402
403
404 static void writeClassCode(final DataOutput out, final Class<?> c)
405 throws IOException {
406 Integer code = getClassCode(c);
407
408 if (code == null) {
409 LOG.error("Unsupported type " + c);
410 StackTraceElement[] els = new Exception().getStackTrace();
411 for(StackTraceElement elem : els) {
412 LOG.error(elem.getMethodName());
413 }
414 throw new UnsupportedOperationException("No code for unexpected " + c);
415 }
416 WritableUtils.writeVInt(out, code);
417 }
418
419 public static long getWritableSize(Object instance, Class declaredClass,
420 Configuration conf) {
421 long size = Bytes.SIZEOF_BYTE;
422 if (instance == null) {
423 return 0L;
424 }
425
426 if (declaredClass.isArray()) {
427 if (declaredClass.equals(Result[].class)) {
428
429 return size + Result.getWriteArraySize((Result[])instance);
430 }
431 }
432 if (declaredClass.equals(Result.class)) {
433 Result r = (Result) instance;
434
435 return r.getWritableSize() + size + Bytes.SIZEOF_BYTE;
436 }
437 return 0L;
438 }
439
440
441
442
443
444
445
446
447
448 @SuppressWarnings("unchecked")
449 public static void writeObject(DataOutput out, Object instance,
450 Class declaredClass,
451 Configuration conf)
452 throws IOException {
453
454 Object instanceObj = instance;
455 Class declClass = declaredClass;
456
457 if (instanceObj == null) {
458 instanceObj = new NullInstance(declClass, conf);
459 declClass = Writable.class;
460 }
461 writeClassCode(out, declClass);
462 if (declClass.isArray()) {
463
464
465 if (declClass.equals(byte [].class)) {
466 Bytes.writeByteArray(out, (byte [])instanceObj);
467 } else if(declClass.equals(Result [].class)) {
468 Result.writeArray(out, (Result [])instanceObj);
469 } else {
470
471 if (getClassCode(declaredClass) == GENERIC_ARRAY_CODE) {
472 Class<?> componentType = declaredClass.getComponentType();
473 writeClass(out, componentType);
474 }
475
476 int length = Array.getLength(instanceObj);
477 out.writeInt(length);
478 for (int i = 0; i < length; i++) {
479 Object item = Array.get(instanceObj, i);
480 writeObject(out, item,
481 item.getClass(), conf);
482 }
483 }
484 } else if (List.class.isAssignableFrom(declClass)) {
485 List list = (List)instanceObj;
486 int length = list.size();
487 out.writeInt(length);
488 for (int i = 0; i < length; i++) {
489 Object elem = list.get(i);
490 writeObject(out, elem,
491 elem == null ? Writable.class : elem.getClass(), conf);
492 }
493 } else if (declClass == String.class) {
494 Text.writeString(out, (String)instanceObj);
495 } else if (declClass.isPrimitive()) {
496 if (declClass == Boolean.TYPE) {
497 out.writeBoolean(((Boolean)instanceObj).booleanValue());
498 } else if (declClass == Character.TYPE) {
499 out.writeChar(((Character)instanceObj).charValue());
500 } else if (declClass == Byte.TYPE) {
501 out.writeByte(((Byte)instanceObj).byteValue());
502 } else if (declClass == Short.TYPE) {
503 out.writeShort(((Short)instanceObj).shortValue());
504 } else if (declClass == Integer.TYPE) {
505 out.writeInt(((Integer)instanceObj).intValue());
506 } else if (declClass == Long.TYPE) {
507 out.writeLong(((Long)instanceObj).longValue());
508 } else if (declClass == Float.TYPE) {
509 out.writeFloat(((Float)instanceObj).floatValue());
510 } else if (declClass == Double.TYPE) {
511 out.writeDouble(((Double)instanceObj).doubleValue());
512 } else if (declClass == Void.TYPE) {
513 } else {
514 throw new IllegalArgumentException("Not a primitive: "+declClass);
515 }
516 } else if (declClass.isEnum()) {
517 Text.writeString(out, ((Enum)instanceObj).name());
518 } else if (Message.class.isAssignableFrom(declaredClass)) {
519 Text.writeString(out, instanceObj.getClass().getName());
520 ((Message)instance).writeDelimitedTo(
521 DataOutputOutputStream.constructOutputStream(out));
522 } else if (Writable.class.isAssignableFrom(declClass)) {
523 Class <?> c = instanceObj.getClass();
524 Integer code = CLASS_TO_CODE.get(c);
525 if (code == null) {
526 out.writeByte(NOT_ENCODED);
527 Text.writeString(out, c.getName());
528 } else {
529 writeClassCode(out, c);
530 }
531 ((Writable)instanceObj).write(out);
532 } else if (Serializable.class.isAssignableFrom(declClass)) {
533 Class <?> c = instanceObj.getClass();
534 Integer code = CLASS_TO_CODE.get(c);
535 if (code == null) {
536 out.writeByte(NOT_ENCODED);
537 Text.writeString(out, c.getName());
538 } else {
539 writeClassCode(out, c);
540 }
541 ByteArrayOutputStream bos = null;
542 ObjectOutputStream oos = null;
543 try{
544 bos = new ByteArrayOutputStream();
545 oos = new ObjectOutputStream(bos);
546 oos.writeObject(instanceObj);
547 byte[] value = bos.toByteArray();
548 out.writeInt(value.length);
549 out.write(value);
550 } finally {
551 if(bos!=null) bos.close();
552 if(oos!=null) oos.close();
553 }
554 } else {
555 throw new IOException("Can't write: "+instanceObj+" as "+declClass);
556 }
557 }
558
559
560
561
562 static void writeClass(DataOutput out, Class<?> c) throws IOException {
563 Integer code = CLASS_TO_CODE.get(c);
564 if (code == null) {
565 WritableUtils.writeVInt(out, NOT_ENCODED);
566 Text.writeString(out, c.getName());
567 } else {
568 WritableUtils.writeVInt(out, code);
569 }
570 }
571
572
573 static Class<?> readClass(Configuration conf, DataInput in) throws IOException {
574 Class<?> instanceClass = null;
575 int b = WritableUtils.readVInt(in);
576 if (b == NOT_ENCODED) {
577 String className = Text.readString(in);
578 try {
579 instanceClass = getClassByName(conf, className);
580 } catch (ClassNotFoundException e) {
581 LOG.error("Can't find class " + className, e);
582 throw new IOException("Can't find class " + className, e);
583 }
584 } else {
585 instanceClass = CODE_TO_CLASS.get(b);
586 }
587 return instanceClass;
588 }
589
590
591
592
593
594
595
596
597
598 public static Object readObject(DataInput in, Configuration conf)
599 throws IOException {
600 return readObject(in, null, conf);
601 }
602
603
604
605
606
607
608
609
610
611
612 @SuppressWarnings("unchecked")
613 public static Object readObject(DataInput in,
614 HbaseObjectWritable objectWritable, Configuration conf)
615 throws IOException {
616 Class<?> declaredClass = CODE_TO_CLASS.get(WritableUtils.readVInt(in));
617 Object instance;
618 if (declaredClass.isPrimitive()) {
619 if (declaredClass == Boolean.TYPE) {
620 instance = Boolean.valueOf(in.readBoolean());
621 } else if (declaredClass == Character.TYPE) {
622 instance = Character.valueOf(in.readChar());
623 } else if (declaredClass == Byte.TYPE) {
624 instance = Byte.valueOf(in.readByte());
625 } else if (declaredClass == Short.TYPE) {
626 instance = Short.valueOf(in.readShort());
627 } else if (declaredClass == Integer.TYPE) {
628 instance = Integer.valueOf(in.readInt());
629 } else if (declaredClass == Long.TYPE) {
630 instance = Long.valueOf(in.readLong());
631 } else if (declaredClass == Float.TYPE) {
632 instance = Float.valueOf(in.readFloat());
633 } else if (declaredClass == Double.TYPE) {
634 instance = Double.valueOf(in.readDouble());
635 } else if (declaredClass == Void.TYPE) {
636 instance = null;
637 } else {
638 throw new IllegalArgumentException("Not a primitive: "+declaredClass);
639 }
640 } else if (declaredClass.isArray()) {
641 if (declaredClass.equals(byte [].class)) {
642 instance = Bytes.readByteArray(in);
643 } else if(declaredClass.equals(Result [].class)) {
644 instance = Result.readArray(in);
645 } else {
646 int length = in.readInt();
647 instance = Array.newInstance(declaredClass.getComponentType(), length);
648 for (int i = 0; i < length; i++) {
649 Array.set(instance, i, readObject(in, conf));
650 }
651 }
652 } else if (declaredClass.equals(Array.class)) {
653 Class<?> componentType = readClass(conf, in);
654 int length = in.readInt();
655 instance = Array.newInstance(componentType, length);
656 for (int i = 0; i < length; i++) {
657 Array.set(instance, i, readObject(in, conf));
658 }
659 } else if (List.class.isAssignableFrom(declaredClass)) {
660 int length = in.readInt();
661 instance = new ArrayList(length);
662 for (int i = 0; i < length; i++) {
663 ((ArrayList)instance).add(readObject(in, conf));
664 }
665 } else if (declaredClass == String.class) {
666 instance = Text.readString(in);
667 } else if (declaredClass.isEnum()) {
668 instance = Enum.valueOf((Class<? extends Enum>) declaredClass,
669 Text.readString(in));
670 } else if (declaredClass == Message.class) {
671 String className = Text.readString(in);
672 try {
673 declaredClass = getClassByName(conf, className);
674 instance = tryInstantiateProtobuf(declaredClass, in);
675 } catch (ClassNotFoundException e) {
676 LOG.error("Can't find class " + className, e);
677 throw new IOException("Can't find class " + className, e);
678 }
679 } else {
680 Class instanceClass = null;
681 int b = (byte)WritableUtils.readVInt(in);
682 if (b == NOT_ENCODED) {
683 String className = Text.readString(in);
684 try {
685 instanceClass = getClassByName(conf, className);
686 } catch (ClassNotFoundException e) {
687 LOG.error("Can't find class " + className, e);
688 throw new IOException("Can't find class " + className, e);
689 }
690 } else {
691 instanceClass = CODE_TO_CLASS.get(b);
692 }
693 if(Writable.class.isAssignableFrom(instanceClass)){
694 Writable writable = WritableFactories.newInstance(instanceClass, conf);
695 try {
696 writable.readFields(in);
697 } catch (Exception e) {
698 LOG.error("Error in readFields", e);
699 throw new IOException("Error in readFields" , e);
700 }
701 instance = writable;
702 if (instanceClass == NullInstance.class) {
703 declaredClass = ((NullInstance)instance).declaredClass;
704 instance = null;
705 }
706 } else {
707 int length = in.readInt();
708 byte[] objectBytes = new byte[length];
709 in.readFully(objectBytes);
710 ByteArrayInputStream bis = null;
711 ObjectInputStream ois = null;
712 try {
713 bis = new ByteArrayInputStream(objectBytes);
714 ois = new ObjectInputStream(bis);
715 instance = ois.readObject();
716 } catch (ClassNotFoundException e) {
717 LOG.error("Class not found when attempting to deserialize object", e);
718 throw new IOException("Class not found when attempting to " +
719 "deserialize object", e);
720 } finally {
721 if(bis!=null) bis.close();
722 if(ois!=null) ois.close();
723 }
724 }
725 }
726 if (objectWritable != null) {
727 objectWritable.declaredClass = declaredClass;
728 objectWritable.instance = instance;
729 }
730 return instance;
731 }
732
733
734
735
736
737
738
739
740
741
742 private static Message tryInstantiateProtobuf(
743 Class<?> protoClass,
744 DataInput dataIn) throws IOException {
745
746 try {
747 if (dataIn instanceof InputStream) {
748
749
750 Method parseMethod = getStaticProtobufMethod(protoClass,
751 "parseDelimitedFrom", InputStream.class);
752 return (Message)parseMethod.invoke(null, (InputStream)dataIn);
753 } else {
754
755
756
757
758 int size = ProtoUtil.readRawVarint32(dataIn);
759 if (size < 0) {
760 throw new IOException("Invalid size: " + size);
761 }
762
763 byte[] data = new byte[size];
764 dataIn.readFully(data);
765 Method parseMethod = getStaticProtobufMethod(protoClass,
766 "parseFrom", byte[].class);
767 return (Message)parseMethod.invoke(null, data);
768 }
769 } catch (InvocationTargetException e) {
770
771 if (e.getCause() instanceof IOException) {
772 throw (IOException)e.getCause();
773 } else {
774 throw new IOException(e.getCause());
775 }
776 } catch (IllegalAccessException iae) {
777 throw new AssertionError("Could not access parse method in " +
778 protoClass);
779 }
780 }
781
782 static Method getStaticProtobufMethod(Class<?> declaredClass, String method,
783 Class<?> ... args) {
784
785 try {
786 return declaredClass.getMethod(method, args);
787 } catch (Exception e) {
788
789 throw new AssertionError("Protocol buffer class " + declaredClass +
790 " does not have an accessible parseFrom(InputStream) method!");
791 }
792 }
793
794 @SuppressWarnings("unchecked")
795 private static Class getClassByName(Configuration conf, String className)
796 throws ClassNotFoundException {
797 if(conf != null) {
798 return conf.getClassByName(className);
799 }
800 ClassLoader cl = Thread.currentThread().getContextClassLoader();
801 if(cl == null) {
802 cl = HbaseObjectWritable.class.getClassLoader();
803 }
804 return Class.forName(className, true, cl);
805 }
806
807 private static void addToMap(final Class<?> clazz, final int code) {
808 CLASS_TO_CODE.put(clazz, code);
809 CODE_TO_CLASS.put(code, clazz);
810 }
811
812 public void setConf(Configuration conf) {
813 this.conf = conf;
814 }
815
816 public Configuration getConf() {
817 return this.conf;
818 }
819 }