Package org.msgpack.template.builder

Source Code of org.msgpack.template.builder.ReflectionTemplateBuilder$ByteFieldEntry

//
// MessagePack for Java
//
// Copyright (C) 2009-2011 FURUHASHI Sadayuki
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//
package org.msgpack.template.builder;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.msgpack.AbstractTemplate;
import org.msgpack.MessagePackObject;
import org.msgpack.MessageTypeException;
import org.msgpack.Packer;
import org.msgpack.Template;
import org.msgpack.Unpacker;
import org.msgpack.template.FieldEntry;
import org.msgpack.template.FieldEntryReader;
import org.msgpack.template.IFieldEntry;
import org.msgpack.template.IFieldEntryReader;
import org.msgpack.template.TemplateRegistry;

public class ReflectionTemplateBuilder extends CustomTemplateBuilder {
  IFieldEntryReader reader = new FieldEntryReader();
 
  @Override
  public IFieldEntryReader getFieldEntryReader(){
    return reader;
  }

  public ReflectionTemplateBuilder() {
  }

  static abstract class ReflectionFieldEntry extends FieldEntry {
    ReflectionFieldEntry(FieldEntry e) {
      super(e.getField(), e.getOption());
    }

    public abstract void pack(Object target, Packer pac) throws IOException;

    public abstract void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException;

    public abstract void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException;

    public void setNull(Object target) throws IllegalAccessException {
      getField().set(target, null);
    }
  }

  static class NullFieldEntry extends ReflectionFieldEntry {
    NullFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException { }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { }
  }

  static class ObjectFieldEntry extends ReflectionFieldEntry {
    private Template template;

    ObjectFieldEntry(FieldEntry e, Template template) {
      super(e);
      this.template = template;
    }

    public void pack(Object target, Packer pac) throws IOException {
      template.pack(pac, target);
    }

    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      Field f = getField();
      Class<Object> type = (Class<Object>)f.getType();
      Object fieldReference = f.get(target);
      Object valueReference = template.convert(obj, fieldReference);
      if(valueReference != fieldReference) {
        f.set(target, valueReference);
      }
    }

    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      Field f = getField();
      Class<Object> type = (Class<Object>)f.getType();
      Object fieldReference = f.get(target);
      Object valueReference = template.unpack(pac, fieldReference);
      if(valueReference != fieldReference) {
        f.set(target, valueReference);
      }
    }
  }

  static class BooleanFieldEntry extends ReflectionFieldEntry {
    BooleanFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((boolean)(Boolean)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setBoolean(target, obj.asBoolean());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setBoolean(target, pac.unpackBoolean());
    }
  }

  static class ByteFieldEntry extends ReflectionFieldEntry {
    ByteFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((byte)(Byte)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setByte(target, obj.asByte());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setByte(target, pac.unpackByte());
    }
  }

  static class ShortFieldEntry extends ReflectionFieldEntry {
    ShortFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((short)(Short)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setShort(target, obj.asShort());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setShort(target, pac.unpackShort());
    }
  }

  static class IntFieldEntry extends ReflectionFieldEntry {
    IntFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((int)(Integer)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setInt(target, obj.asInt());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setInt(target, pac.unpackInt());
    }
  }

  static class LongFieldEntry extends ReflectionFieldEntry {
    LongFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((long)(Long)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setLong(target, obj.asLong());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setLong(target, pac.unpackLong());
    }
  }

  static class FloatFieldEntry extends ReflectionFieldEntry {
    FloatFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((float)(Float)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setFloat(target, obj.asFloat());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setFloat(target, pac.unpackFloat());
    }
  }

  static class DoubleFieldEntry extends ReflectionFieldEntry {
    DoubleFieldEntry(FieldEntry e) {
      super(e);
    }
    public void pack(Object target, Packer pac) throws IOException {
      pac.pack((double)(Double)target);
    }
    public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException {
      getField().setDouble(target, obj.asDouble());
    }
    public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException {
      getField().setDouble(target, pac.unpackDouble());
    }
  }

  static class ReflectionTemplate extends AbstractTemplate {
    protected Class<?> targetClass;
    protected ReflectionFieldEntry[] entries;
    protected int minimumArrayLength;

    ReflectionTemplate(Class<?> targetClass, ReflectionFieldEntry[] entries) {
      this.targetClass = targetClass;
      this.entries = entries;
      this.minimumArrayLength = 0;
      for(int i=0; i < entries.length; i++) {
        ReflectionFieldEntry e = entries[i];
        if(e.isRequired() || e.isNullable()) {
          this.minimumArrayLength = i+1;
        }
      }
    }

    public void pack(Packer pk, Object target) throws IOException {
      try {
        pk.packArray(entries.length);
        for(ReflectionFieldEntry e : entries) {
          if(!e.isAvailable()) {
            pk.packNil();
            continue;
          }
          Object obj = e.getField().get(target);
          if(obj == null) {
            if(!e.isNullable() && !e.isOptional()) {
              throw new MessageTypeException();
            }
            pk.packNil();
          } else {
            e.pack(obj, pk);
          }
        }

      } catch (MessageTypeException e) {
        throw e;
      } catch (IOException e) {
        throw e;
      } catch (Exception e) {
        throw new MessageTypeException(e);
      }
    }

    public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
      try {
        if(to == null) {
          to = targetClass.newInstance();
        }

        int length = pac.unpackArray();
        if(length < minimumArrayLength) {
          throw new MessageTypeException();
        }

        int i;
        for(i=0; i < minimumArrayLength; i++) {
          ReflectionFieldEntry e = entries[i];
          if(!e.isAvailable()) {
            pac.unpackObject();
            continue;
          }

          if(pac.tryUnpackNull()) {
            if(e.isRequired()) {
              // Required + nil => exception
              throw new MessageTypeException();
            } else if(e.isOptional()) {
              // Optional + nil => keep default value
            } else // Nullable
              // Nullable + nil => set null
              e.setNull(to);
            }
          } else {
            e.unpack(to, pac);
          }
        }

        int max = length < entries.length ? length : entries.length;
        for(; i < max; i++) {
          ReflectionFieldEntry e = entries[i];
          if(!e.isAvailable()) {
            pac.unpackObject();
            continue;
          }

          if(pac.tryUnpackNull()) {
            // this is Optional field becaue i >= minimumArrayLength
            // Optional + nil => keep default value
          } else {
            e.unpack(to, pac);
          }
        }

        // latter entries are all Optional + nil => keep default value

        for(; i < length; i++) {
          pac.unpackObject();
        }

        return to;

      } catch (MessageTypeException e) {
        throw e;
      } catch (IOException e) {
        throw e;
      } catch (Exception e) {
        throw new MessageTypeException(e);
      }
    }

    public Object convert(MessagePackObject from, Object to) throws MessageTypeException {
      try {
        if(to == null) {
          to = targetClass.newInstance();
        }

        MessagePackObject[] array = from.asArray();
        int length = array.length;
        if(length < minimumArrayLength) {
          throw new MessageTypeException();
        }

        int i;
        for(i=0; i < minimumArrayLength; i++) {
          ReflectionFieldEntry e = entries[i];
          if(!e.isAvailable()) {
            continue;
          }

          MessagePackObject obj = array[i];
          if(obj.isNil()) {
            if(e.isRequired()) {
              // Required + nil => exception
              throw new MessageTypeException();
            } else if(e.isOptional()) {
              // Optional + nil => keep default value
            } else // Nullable
              // Nullable + nil => set null
              e.setNull(to);
            }
          } else {
            e.convert(to, obj);
          }
        }

        int max = length < entries.length ? length : entries.length;
        for(; i < max; i++) {
          ReflectionFieldEntry e = entries[i];
          if(!e.isAvailable()) {
            continue;
          }

          MessagePackObject obj = array[i];
          if(obj.isNil()) {
            // this is Optional field becaue i >= minimumArrayLength
            // Optional + nil => keep default value
          } else {
            e.convert(to, obj);
          }
        }

        // latter entries are all Optional + nil => keep default value

        return to;

      } catch (MessageTypeException e) {
        throw e;
      } catch (Exception e) {
        throw new MessageTypeException(e);
      }
    }
  }

  public Template buildTemplate(Class<?> targetClass, IFieldEntry[] entries) {
    // TODO Now it is simply cast.
    for(IFieldEntry e : entries) {
      Field f = ((FieldEntry)e).getField();
      int mod = f.getModifiers();
      if(!Modifier.isPublic(mod)) {
        f.setAccessible(true);
      }
    }

    ReflectionFieldEntry[] res = new ReflectionFieldEntry[entries.length];
    for(int i=0; i < entries.length; i++) {
      FieldEntry e = (FieldEntry)entries[i];
      Class<?> type = e.getType();
      if(!e.isAvailable()) {
        res[i] = new NullFieldEntry(e);
      } else if(type.equals(boolean.class)) {
        res[i] = new BooleanFieldEntry(e);
      } else if(type.equals(byte.class)) {
        res[i] = new ByteFieldEntry(e);
      } else if(type.equals(short.class)) {
        res[i] = new ShortFieldEntry(e);
      } else if(type.equals(int.class)) {
        res[i] = new IntFieldEntry(e);
      } else if(type.equals(long.class)) {
        res[i] = new LongFieldEntry(e);
      } else if(type.equals(float.class)) {
        res[i] = new FloatFieldEntry(e);
      } else if(type.equals(double.class)) {
        res[i] = new DoubleFieldEntry(e);
      } else {
        Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true);
        res[i] = new ObjectFieldEntry(e, tmpl);
      }
    }
    return new ReflectionTemplate(targetClass, res);
  }
}
TOP

Related Classes of org.msgpack.template.builder.ReflectionTemplateBuilder$ByteFieldEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.