ObjectWritable.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:9k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.io;
  19. import java.lang.reflect.Array;
  20. import java.io.*;
  21. import java.util.*;
  22. import org.apache.hadoop.conf.*;
  23. /** A polymorphic Writable that writes an instance with it's class name.
  24.  * Handles arrays, strings and primitive types without a Writable wrapper.
  25.  */
  26. public class ObjectWritable implements Writable, Configurable {
  27.   private Class declaredClass;
  28.   private Object instance;
  29.   private Configuration conf;
  30.   public ObjectWritable() {}
  31.   
  32.   public ObjectWritable(Object instance) {
  33.     set(instance);
  34.   }
  35.   public ObjectWritable(Class declaredClass, Object instance) {
  36.     this.declaredClass = declaredClass;
  37.     this.instance = instance;
  38.   }
  39.   /** Return the instance, or null if none. */
  40.   public Object get() { return instance; }
  41.   
  42.   /** Return the class this is meant to be. */
  43.   public Class getDeclaredClass() { return declaredClass; }
  44.   
  45.   /** Reset the instance. */
  46.   public void set(Object instance) {
  47.     this.declaredClass = instance.getClass();
  48.     this.instance = instance;
  49.   }
  50.   
  51.   public String toString() {
  52.     return "OW[class=" + declaredClass + ",value=" + instance + "]";
  53.   }
  54.   
  55.   public void readFields(DataInput in) throws IOException {
  56.     readObject(in, this, this.conf);
  57.   }
  58.   
  59.   public void write(DataOutput out) throws IOException {
  60.     writeObject(out, instance, declaredClass, conf);
  61.   }
  62.   private static final Map<String, Class<?>> PRIMITIVE_NAMES = new HashMap<String, Class<?>>();
  63.   static {
  64.     PRIMITIVE_NAMES.put("boolean", Boolean.TYPE);
  65.     PRIMITIVE_NAMES.put("byte", Byte.TYPE);
  66.     PRIMITIVE_NAMES.put("char", Character.TYPE);
  67.     PRIMITIVE_NAMES.put("short", Short.TYPE);
  68.     PRIMITIVE_NAMES.put("int", Integer.TYPE);
  69.     PRIMITIVE_NAMES.put("long", Long.TYPE);
  70.     PRIMITIVE_NAMES.put("float", Float.TYPE);
  71.     PRIMITIVE_NAMES.put("double", Double.TYPE);
  72.     PRIMITIVE_NAMES.put("void", Void.TYPE);
  73.   }
  74.   private static class NullInstance extends Configured implements Writable {
  75.     private Class<?> declaredClass;
  76.     public NullInstance() { super(null); }
  77.     public NullInstance(Class declaredClass, Configuration conf) {
  78.       super(conf);
  79.       this.declaredClass = declaredClass;
  80.     }
  81.     public void readFields(DataInput in) throws IOException {
  82.       String className = UTF8.readString(in);
  83.       declaredClass = PRIMITIVE_NAMES.get(className);
  84.       if (declaredClass == null) {
  85.         try {
  86.           declaredClass = getConf().getClassByName(className);
  87.         } catch (ClassNotFoundException e) {
  88.           throw new RuntimeException(e.toString());
  89.         }
  90.       }
  91.     }
  92.     public void write(DataOutput out) throws IOException {
  93.       UTF8.writeString(out, declaredClass.getName());
  94.     }
  95.   }
  96.   /** Write a {@link Writable}, {@link String}, primitive type, or an array of
  97.    * the preceding. */
  98.   public static void writeObject(DataOutput out, Object instance,
  99.                                  Class declaredClass, 
  100.                                  Configuration conf) throws IOException {
  101.     if (instance == null) {                       // null
  102.       instance = new NullInstance(declaredClass, conf);
  103.       declaredClass = Writable.class;
  104.     }
  105.     UTF8.writeString(out, declaredClass.getName()); // always write declared
  106.     if (declaredClass.isArray()) {                // array
  107.       int length = Array.getLength(instance);
  108.       out.writeInt(length);
  109.       for (int i = 0; i < length; i++) {
  110.         writeObject(out, Array.get(instance, i),
  111.                     declaredClass.getComponentType(), conf);
  112.       }
  113.       
  114.     } else if (declaredClass == String.class) {   // String
  115.       UTF8.writeString(out, (String)instance);
  116.       
  117.     } else if (declaredClass.isPrimitive()) {     // primitive type
  118.       if (declaredClass == Boolean.TYPE) {        // boolean
  119.         out.writeBoolean(((Boolean)instance).booleanValue());
  120.       } else if (declaredClass == Character.TYPE) { // char
  121.         out.writeChar(((Character)instance).charValue());
  122.       } else if (declaredClass == Byte.TYPE) {    // byte
  123.         out.writeByte(((Byte)instance).byteValue());
  124.       } else if (declaredClass == Short.TYPE) {   // short
  125.         out.writeShort(((Short)instance).shortValue());
  126.       } else if (declaredClass == Integer.TYPE) { // int
  127.         out.writeInt(((Integer)instance).intValue());
  128.       } else if (declaredClass == Long.TYPE) {    // long
  129.         out.writeLong(((Long)instance).longValue());
  130.       } else if (declaredClass == Float.TYPE) {   // float
  131.         out.writeFloat(((Float)instance).floatValue());
  132.       } else if (declaredClass == Double.TYPE) {  // double
  133.         out.writeDouble(((Double)instance).doubleValue());
  134.       } else if (declaredClass == Void.TYPE) {    // void
  135.       } else {
  136.         throw new IllegalArgumentException("Not a primitive: "+declaredClass);
  137.       }
  138.     } else if (declaredClass.isEnum()) {         // enum
  139.       UTF8.writeString(out, ((Enum)instance).name());
  140.     } else if (Writable.class.isAssignableFrom(declaredClass)) { // Writable
  141.       UTF8.writeString(out, instance.getClass().getName());
  142.       ((Writable)instance).write(out);
  143.     } else {
  144.       throw new IOException("Can't write: "+instance+" as "+declaredClass);
  145.     }
  146.   }
  147.   
  148.   
  149.   /** Read a {@link Writable}, {@link String}, primitive type, or an array of
  150.    * the preceding. */
  151.   public static Object readObject(DataInput in, Configuration conf)
  152.     throws IOException {
  153.     return readObject(in, null, conf);
  154.   }
  155.     
  156.   /** Read a {@link Writable}, {@link String}, primitive type, or an array of
  157.    * the preceding. */
  158.   @SuppressWarnings("unchecked")
  159.   public static Object readObject(DataInput in, ObjectWritable objectWritable, Configuration conf)
  160.     throws IOException {
  161.     String className = UTF8.readString(in);
  162.     Class<?> declaredClass = PRIMITIVE_NAMES.get(className);
  163.     if (declaredClass == null) {
  164.       try {
  165.         declaredClass = conf.getClassByName(className);
  166.       } catch (ClassNotFoundException e) {
  167.         throw new RuntimeException("readObject can't find class " + className, e);
  168.       }
  169.     }    
  170.     Object instance;
  171.     
  172.     if (declaredClass.isPrimitive()) {            // primitive types
  173.       if (declaredClass == Boolean.TYPE) {             // boolean
  174.         instance = Boolean.valueOf(in.readBoolean());
  175.       } else if (declaredClass == Character.TYPE) {    // char
  176.         instance = Character.valueOf(in.readChar());
  177.       } else if (declaredClass == Byte.TYPE) {         // byte
  178.         instance = Byte.valueOf(in.readByte());
  179.       } else if (declaredClass == Short.TYPE) {        // short
  180.         instance = Short.valueOf(in.readShort());
  181.       } else if (declaredClass == Integer.TYPE) {      // int
  182.         instance = Integer.valueOf(in.readInt());
  183.       } else if (declaredClass == Long.TYPE) {         // long
  184.         instance = Long.valueOf(in.readLong());
  185.       } else if (declaredClass == Float.TYPE) {        // float
  186.         instance = Float.valueOf(in.readFloat());
  187.       } else if (declaredClass == Double.TYPE) {       // double
  188.         instance = Double.valueOf(in.readDouble());
  189.       } else if (declaredClass == Void.TYPE) {         // void
  190.         instance = null;
  191.       } else {
  192.         throw new IllegalArgumentException("Not a primitive: "+declaredClass);
  193.       }
  194.     } else if (declaredClass.isArray()) {              // array
  195.       int length = in.readInt();
  196.       instance = Array.newInstance(declaredClass.getComponentType(), length);
  197.       for (int i = 0; i < length; i++) {
  198.         Array.set(instance, i, readObject(in, conf));
  199.       }
  200.       
  201.     } else if (declaredClass == String.class) {        // String
  202.       instance = UTF8.readString(in);
  203.     } else if (declaredClass.isEnum()) {         // enum
  204.       instance = Enum.valueOf((Class<? extends Enum>) declaredClass, UTF8.readString(in));
  205.     } else {                                      // Writable
  206.       Class instanceClass = null;
  207.       String str = "";
  208.       try {
  209.         str = UTF8.readString(in);
  210.         instanceClass = conf.getClassByName(str);
  211.       } catch (ClassNotFoundException e) {
  212.         throw new RuntimeException("readObject can't find class " + str, e);
  213.       }
  214.       
  215.       Writable writable = WritableFactories.newInstance(instanceClass, conf);
  216.       writable.readFields(in);
  217.       instance = writable;
  218.       if (instanceClass == NullInstance.class) {  // null
  219.         declaredClass = ((NullInstance)instance).declaredClass;
  220.         instance = null;
  221.       }
  222.     }
  223.     if (objectWritable != null) {                 // store values
  224.       objectWritable.declaredClass = declaredClass;
  225.       objectWritable.instance = instance;
  226.     }
  227.     return instance;
  228.       
  229.   }
  230.   public void setConf(Configuration conf) {
  231.     this.conf = conf;
  232.   }
  233.   public Configuration getConf() {
  234.     return this.conf;
  235.   }
  236.   
  237. }