Package org.msgpack.template.builder

Source Code of org.msgpack.template.builder.DefaultBuildContext

//
// 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.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

import org.msgpack.*;
import org.msgpack.packer.Packer;
import org.msgpack.template.*;
import org.msgpack.unpacker.Unpacker;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtNewConstructor;
import javassist.NotFoundException;

public class DefaultBuildContext extends BuildContext<FieldEntry> {
    protected FieldEntry[] entries;

    protected Class<?> origClass;

    protected String origName;

    protected Template<?>[] templates;

    public DefaultBuildContext(JavassistTemplateBuilder director) {
  super(director);
    }

    public Template buildTemplate(Class targetClass, FieldEntry[] entries, Template[] templates) {
  this.entries = entries;
  this.templates = templates;
  this.origClass = targetClass;
  this.origName = origClass.getName();
  return build(origName);
    }

    protected void setSuperClass() throws CannotCompileException, NotFoundException {
  tmplCtClass.setSuperclass(director.getCtClass(
    JavassistTemplateBuilder.JavassistTemplate.class.getName()));
    }

    protected void buildConstructor() throws CannotCompileException,
      NotFoundException {
  // Constructor(Class targetClass, Template[] templates)
  CtConstructor newCtCons = CtNewConstructor.make(
    new CtClass[] {
      director.getCtClass(Class.class.getName()),
      director.getCtClass(Template.class.getName() + "[]")
    }, new CtClass[0], tmplCtClass);
  tmplCtClass.addConstructor(newCtCons);
    }

    protected Template buildInstance(Class<?> c) throws NoSuchMethodException,
      InstantiationException, IllegalAccessException, InvocationTargetException {
  Constructor<?> cons = c.getConstructor(new Class[] { Class.class, Template[].class });
  Object tmpl = cons.newInstance(new Object[] { origClass, templates });
  return (Template) tmpl;
    }

    protected void buildMethodInit() {
    }

    protected String buildWriteMethodBody() {
  resetStringBuilder();
  buildString("\n{\n");

        buildString("  if ($2 == null) {\n");
        buildString("    if ($3) {\n");
        buildString("      throw new %s(\"Attempted to write null\");\n", MessageTypeException.class.getName());
        buildString("    }\n");
        buildString("    $1.writeNil();\n");
        buildString("    return;\n");
        buildString("  }\n");

  buildString("  %s _$$_t = (%s) $2;\n", origName, origName);
  buildString("  $1.writeArrayBegin(%d);\n", entries.length);

  for (int i = 0; i < entries.length; i++) {
      FieldEntry e = entries[i];
      if (!e.isAvailable()) {
    buildString("  $1.writeNil();\n");
    continue;
      }
      DefaultFieldEntry de = (DefaultFieldEntry) e;
      boolean isPrivate = Modifier.isPrivate(de.getField().getModifiers());
      Class<?> type = de.getType();
      if (type.isPrimitive()) { // primitive types
    if (!isPrivate) {
        buildString("  $1.%s(_$$_t.%s);\n", primitiveWriteName(type), de.getName());
    } else {
        buildString("  %s.writePrivateField($1, _$$_t, \"%s\", templates[%d]);\n",
          DefaultBuildContext.class.getName(), de.getName(), i);
    }
      } else { // reference types
    buildString("  if (_$$_t.%s == null) {\n", de.getName());
    if (de.isNotNullable()) {
        buildString("    throw new %s();\n", MessageTypeException.class.getName());
    } else {
        buildString("    $1.writeNil();\n");
    }
    buildString("  } else {\n");
    if (!isPrivate) {
        buildString("    templates[%d].write($1, _$$_t.%s);\n", i, de.getName());
        buildString("  }\n");
    } else {
        buildString("    %s.writePrivateField($1, _$$_t, \"%s\", templates[%d]);\n",
          DefaultBuildContext.class.getName(), de.getName(), i);
    }
      }
  }

  buildString("  $1.writeArrayEnd();\n");
  buildString("}\n");
  return getBuiltString();
    }

    public static void writePrivateField(Packer packer, Object target, String fieldName, Template tmpl) {
  try {
      Field field = target.getClass().getDeclaredField(fieldName);
      field.setAccessible(true);
      Object valueReference = field.get(target);
      tmpl.write(packer, valueReference);
      field.setAccessible(false);
  } catch (Exception e) {
      throw new MessageTypeException(e);
  }
    }

    protected String buildReadMethodBody() {
  resetStringBuilder();
  buildString("\n{\n");

        buildString("  if (!$3 && $1.trySkipNil()) {\n");
        buildString("    return null;\n");
        buildString("  }\n");

  buildString("  %s _$$_t;\n", origName);
  buildString("  if ($2 == null) {\n");
  buildString("    _$$_t = new %s();\n", origName);
  buildString("  } else {\n");
  buildString("    _$$_t = (%s) $2;\n", origName);
  buildString("  }\n");
  buildString("  $1.readArrayBegin();\n");

  int i;
  for (i = 0; i < entries.length; i++) {
      FieldEntry e = entries[i];
      if (!e.isAvailable()) {
    buildString("  $1.skip();\n");
    continue;
      }

            if (e.isOptional()) {
          buildString("  if ($1.trySkipNil()) {");
    buildString("    _$$_t.%s = null;\n", e.getName());
          buildString("  } else {\n");
            }

      DefaultFieldEntry de = (DefaultFieldEntry) e;
      boolean isPrivate = Modifier.isPrivate(de.getField().getModifiers());
      Class<?> type = de.getType();
      if (type.isPrimitive()) {
    if (!isPrivate) {
        buildString("    _$$_t.%s = $1.%s();\n", de.getName(), primitiveReadName(type));
    } else {
        buildString("    %s.readPrivateField($1, _$$_t, \"%s\", templates[%d]);\n",
          DefaultBuildContext.class.getName(), de.getName(), i);
    }
      } else {
    if (!isPrivate) {
        buildString("    _$$_t.%s = (%s) this.templates[%d].read($1, _$$_t.%s);\n",
          de.getName(), de.getJavaTypeName(), i, de.getName());
    } else {
        buildString("    %s.readPrivateField($1, _$$_t, \"%s\", templates[%d]);\n",
          DefaultBuildContext.class.getName(), de.getName(), i);
    }
      }

            if (de.isOptional()) {
          buildString("  }\n");
            }
  }

  buildString("  $1.readArrayEnd();\n");
  buildString("  return _$$_t;\n");

  buildString("}\n");
  return getBuiltString();
    }

    public static void readPrivateField(Unpacker unpacker, Object target, String fieldName, Template tmpl) {
  try {
      Field field = target.getClass().getDeclaredField(fieldName);
      field.setAccessible(true);
      Object fieldReference = field.get(target);
      Object valueReference = tmpl.read(unpacker, fieldReference);
      if (valueReference != fieldReference) {
    field.set(target, valueReference);
      }
      field.setAccessible(false);
  } catch (Exception e) {
      throw new MessageTypeException(e);
  }
    }

    @Override
    public void writeTemplate(Class<?> targetClass, FieldEntry[] entries, Template[] templates, String directoryName) {
  this.entries = entries;
  this.templates = templates;
  this.origClass = targetClass;
  this.origName = origClass.getName();
  write(origName, directoryName);
    }

    @Override
    public Template loadTemplate(Class<?> targetClass, FieldEntry[] entries, Template[] templates) {
  this.entries = entries;
  this.templates = templates;
  this.origClass = targetClass;
  this.origName = origClass.getName();
  return load(origName);
    }
}
TOP

Related Classes of org.msgpack.template.builder.DefaultBuildContext

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.