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

网格计算

开发平台:

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.io.DataInput;
  20. import java.io.DataOutput;
  21. import java.io.IOException;
  22. import org.apache.hadoop.conf.Configurable;
  23. import org.apache.hadoop.conf.Configuration;
  24. import org.apache.hadoop.util.ReflectionUtils;
  25. /**
  26.  * A wrapper for Writable instances.
  27.  * <p>
  28.  * When two sequence files, which have same Key type but different Value
  29.  * types, are mapped out to reduce, multiple Value types is not allowed.
  30.  * In this case, this class can help you wrap instances with different types.
  31.  * </p>
  32.  * 
  33.  * <p>
  34.  * Compared with <code>ObjectWritable</code>, this class is much more effective,
  35.  * because <code>ObjectWritable</code> will append the class declaration as a String 
  36.  * into the output file in every Key-Value pair.
  37.  * </p>
  38.  * 
  39.  * <p>
  40.  * Generic Writable implements {@link Configurable} interface, so that it will be 
  41.  * configured by the framework. The configuration is passed to the wrapped objects
  42.  * implementing {@link Configurable} interface <i>before deserialization</i>. 
  43.  * </p>
  44.  * 
  45.  * how to use it: <br>
  46.  * 1. Write your own class, such as GenericObject, which extends GenericWritable.<br> 
  47.  * 2. Implements the abstract method <code>getTypes()</code>, defines 
  48.  *    the classes which will be wrapped in GenericObject in application.
  49.  *    Attention: this classes defined in <code>getTypes()</code> method, must
  50.  *    implement <code>Writable</code> interface.
  51.  * <br><br>
  52.  * 
  53.  * The code looks like this:
  54.  * <blockquote><pre>
  55.  * public class GenericObject extends GenericWritable {
  56.  * 
  57.  *   private static Class[] CLASSES = {
  58.  *               ClassType1.class, 
  59.  *               ClassType2.class,
  60.  *               ClassType3.class,
  61.  *               };
  62.  *
  63.  *   protected Class[] getTypes() {
  64.  *       return CLASSES;
  65.  *   }
  66.  *
  67.  * }
  68.  * </pre></blockquote>
  69.  * 
  70.  * @since Nov 8, 2006
  71.  */
  72. public abstract class GenericWritable implements Writable, Configurable {
  73.   private static final byte NOT_SET = -1;
  74.   private byte type = NOT_SET;
  75.   private Writable instance;
  76.   private Configuration conf = null;
  77.   
  78.   /**
  79.    * Set the instance that is wrapped.
  80.    * 
  81.    * @param obj
  82.    */
  83.   public void set(Writable obj) {
  84.     instance = obj;
  85.     Class<? extends Writable> instanceClazz = instance.getClass();
  86.     Class<? extends Writable>[] clazzes = getTypes();
  87.     for (int i = 0; i < clazzes.length; i++) {
  88.       Class<? extends Writable> clazz = clazzes[i];
  89.       if (clazz.equals(instanceClazz)) {
  90.         type = (byte) i;
  91.         return;
  92.       }
  93.     }
  94.     throw new RuntimeException("The type of instance is: "
  95.                                + instance.getClass() + ", which is NOT registered.");
  96.   }
  97.   /**
  98.    * Return the wrapped instance.
  99.    */
  100.   public Writable get() {
  101.     return instance;
  102.   }
  103.   
  104.   public String toString() {
  105.     return "GW[" + (instance != null ? ("class=" + instance.getClass().getName() +
  106.         ",value=" + instance.toString()) : "(null)") + "]";
  107.   }
  108.   public void readFields(DataInput in) throws IOException {
  109.     type = in.readByte();
  110.     Class<? extends Writable> clazz = getTypes()[type & 0xff];
  111.     try {
  112.       instance = ReflectionUtils.newInstance(clazz, conf);
  113.     } catch (Exception e) {
  114.       e.printStackTrace();
  115.       throw new IOException("Cannot initialize the class: " + clazz);
  116.     }
  117.     instance.readFields(in);
  118.   }
  119.   public void write(DataOutput out) throws IOException {
  120.     if (type == NOT_SET || instance == null)
  121.       throw new IOException("The GenericWritable has NOT been set correctly. type="
  122.                             + type + ", instance=" + instance);
  123.     out.writeByte(type);
  124.     instance.write(out);
  125.   }
  126.   /**
  127.    * Return all classes that may be wrapped.  Subclasses should implement this
  128.    * to return a constant array of classes.
  129.    */
  130.   abstract protected Class<? extends Writable>[] getTypes();
  131.   public Configuration getConf() {
  132.     return conf;
  133.   }
  134.   public void setConf(Configuration conf) {
  135.     this.conf = conf;
  136.   }
  137.   
  138. }