com.nginious.http.serialize.Serialization.java Source code

Java tutorial

Introduction

Here is the source code for com.nginious.http.serialize.Serialization.java

Source

/**
 * Copyright 2012 NetDigital Sweden AB
 *
 * 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 com.nginious.http.serialize;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import com.nginious.http.annotation.Serializable;

/**
 * Provides common methods used by serializer and deserializer creator classes.
 * 
 * @author Bojan Pisler, NetDigital Sweden AB
 *
 */
class Serialization {

    /**
     * Creates bytecode for a no argument constructor. The created bytecode also calls the no argument constructor
     * in the superclass with the specified name.
     * 
     * @param writer bytecode writer
     * @param superclassName binary name of superclass
     */
    static void createConstructor(ClassWriter writer, String superclassName) {
        MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        visitor.visitCode();
        visitor.visitVarInsn(Opcodes.ALOAD, 0);
        visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassName, "<init>", "()V");
        visitor.visitInsn(Opcodes.RETURN);
        visitor.visitMaxs(1, 1);
        visitor.visitEnd();
    }

    /**
     * Creates binary class name from the specified class.
     * 
     * @param clazz the class to create a binary class name for
     * @return the binary class name
     */
    static String createInternalClassName(Class<?> clazz) {
        return clazz.getName().replace('.', '/');
    }

    /**
     * Creates binary class signature for a serializer or deserializer class using the specified bean class name
     * as type parameter and the specified class name.
     * 
     * @param clazzName the class name
     * @param beanClazzName the parameter type
     * @return the created class signature
     */
    static String createClassSignature(String clazzName, String beanClazzName) {
        StringBuffer signature = new StringBuffer("L");
        signature.append(clazzName);
        signature.append("<L");
        signature.append(beanClazzName);
        signature.append(";>;");
        return signature.toString();
    }

    /**
     * Creates property name from bean get or set method. The property name is created by removing the "get"
     * or "set" part then lowercasing the first word.
     * 
     * @param methodName the method name to create property name
     * @return the created property name
     */
    static String createPropertyNameFromMethodName(String methodName) {
        return methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
    }

    /**
     * Creates property name from the specified class name. The property is the same as the class name with the
     * first character in lower case.
     * 
     * @param className the given class name
     * @return the property name
     */
    static String createPropertyNameFromClass(Class<?> beanClazz) {
        Serializable info = beanClazz.getAnnotation(Serializable.class);

        if (info != null && !info.name().equals("")) {
            return info.name();
        }

        String className = beanClazz.getSimpleName();
        return className.substring(0, 1).toLowerCase() + className.substring(1);
    }

    /**
     * Uses the specified class loader to load created bytecode in a class with the specified class name.
     * 
     * @param loader the class loader to load class with
     * @param className the class name
     * @param b the created bytecode
     * @return the loaded class
     */
    static Class<?> loadClass(ClassLoader loader, String className, byte[] b) {
        Class<?> clazz = null;

        try {
            Class<?> cls = Class.forName("java.lang.ClassLoader");
            java.lang.reflect.Method method = cls.getDeclaredMethod("defineClass",
                    new Class[] { String.class, byte[].class, int.class, int.class });

            // protected method invocaton
            method.setAccessible(true);

            try {
                Object[] args = new Object[] { className, b, new Integer(0), new Integer(b.length) };
                clazz = (Class<?>) method.invoke(loader, args);
            } finally {
                method.setAccessible(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return clazz;
    }
}