Package org.codehaus.aspectwerkz.annotation.instrumentation.asm

Source Code of org.codehaus.aspectwerkz.annotation.instrumentation.asm.CustomAttributeHelper

/**************************************************************************************
* Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved.                 *
* http://aspectwerkz.codehaus.org                                                    *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the LGPL license      *
* a copy of which has been included with this distribution in the license.txt file.  *
**************************************************************************************/
package org.codehaus.aspectwerkz.annotation.instrumentation.asm;

import org.objectweb.asm.attrs.Annotation;
import org.objectweb.asm.attrs.RuntimeInvisibleAnnotations;
import org.objectweb.asm.Attribute;
import org.codehaus.aspectwerkz.util.Base64;
import org.codehaus.aspectwerkz.util.UnbrokenObjectInputStream;
import org.codehaus.aspectwerkz.util.UnbrokenObjectInputStream;
import org.codehaus.aspectwerkz.annotation.AnnotationInfo;
import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;

import java.io.ByteArrayInputStream;

/**
* Helper class to wrap a custom annotation proxy (1.3/1.4 javadoc annotation) in a RuntimeInvisibleAnnotations.
* <br/>
* The proxy is wrapped in a AnnotationInfo object which is serialized
* and base64 encoded (ASM issue on array types in RIV).
*
* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
*/
public class CustomAttributeHelper {

    /**
     * Annotation parameter - as if it was a single value Tiger annotation
     */
    private final static String VALUE = "value";

    /**
     * Extract the AnnotationInfo from the bytecode Annotation representation.
     *
     * @param annotation must be a valid RIV, of type CustomAttribute.TYPE
     * @return
     */
    public static AnnotationInfo extractCustomAnnotation(final Annotation annotation) {
        byte[] bytes = Base64.decode((String) ((Object[]) annotation.elementValues.get(0))[1]);
        return extractCustomAnnotation(bytes);
    }

    /**
     * Extract the AnnotationInfo from the base64 encoded serialized version.
     *
     * @param bytes
     * @return
     */
    public static AnnotationInfo extractCustomAnnotation(final byte[] bytes) {
        try {
            Object userAnnotation = new UnbrokenObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
            if (userAnnotation instanceof AnnotationInfo) {
                return (AnnotationInfo) userAnnotation;
            } else {
                // should not occur
                throw new RuntimeException(
                        "Custom annotation is not wrapped in AnnotationInfo: " + userAnnotation.getClass().getName() +
                        " [" + AnnotationInfo.class.getClassLoader().toString() + " / " +
                        userAnnotation.getClass().getClassLoader()
                );
            }
        } catch (Exception e) {
            throw new WrappedRuntimeException(e);
        }
    }

    /**
     * Create an Annotation bytecode representation from the serialized version of the custom annotation proxy
     *
     * @param bytes
     * @return
     */
    public static Annotation createCustomAnnotation(final byte[] bytes) {
        Annotation annotation = new Annotation();
        annotation.type = CustomAttribute.TYPE;
        annotation.add(VALUE, Base64.encodeBytes(bytes));
        return annotation;
    }

    /**
     * Helper method to find the first RuntimeInvisibleAnnotations attribute in an Attribute chain.
     * <br/>If no such RIV exists, a new one is created (empty) and added last in the chain.
     * <br/>If the chain is null, a new sole RIV (empty) is created
     *
     * @param attribute
     * @return the RuntimeInvisibleAnnotations to add Annotation to
     */
    public static RuntimeInvisibleAnnotations linkRuntimeInvisibleAnnotations(final Attribute attribute) {
        RuntimeInvisibleAnnotations runtimeInvisibleAnnotations = null;
        Attribute lastAttribute = attribute;
        for (Attribute loop = attribute; loop != null; loop = loop.next) {
            lastAttribute = loop;
            if (loop instanceof RuntimeInvisibleAnnotations) {
                return runtimeInvisibleAnnotations = (RuntimeInvisibleAnnotations) loop;
            }
        }
        // not found, link a new one to lastAttribute
        runtimeInvisibleAnnotations = new RuntimeInvisibleAnnotations();
        runtimeInvisibleAnnotations.next = null;
        if (attribute != null) {
            // if arg is null, we are just adding this annotation as the sole attribute
            lastAttribute.next = runtimeInvisibleAnnotations;
        } else {
            //attribute = runtimeInvisibleAnnotations;
        }
        return runtimeInvisibleAnnotations;
    }
}
TOP

Related Classes of org.codehaus.aspectwerkz.annotation.instrumentation.asm.CustomAttributeHelper

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.