All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.linkare.zas.aspectj.utils.ZasUtils Maven / Gradle / Ivy

Go to download

The AspectJ based implementation of the Zas project. This is the new version of the implementation of Zas which, initially, started as a M.Sc. thesis project by Paulo Zenida at ISCTE.

The newest version!
package com.linkare.zas.aspectj.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.linkare.zas.annotation.AccessControlPolicy;
import com.linkare.zas.annotation.AccessControlPolicyType;
import com.linkare.zas.annotation.AccessControlled;

/**
 * This class provides some static useful methods related to parsing signatures.
 * 
 * @author Paulo Zenida
 */
public class ZasUtils {

    private static final String INIT = "";

    private static final String CLOSE_PARENTHESIS = ")";

    private static final String SPACE = " ";

    private static final String OPEN_PARENTHESIS = "(";

    private static final String DOT = ".";

    /**
     * @param signature
     *            The signature to be parsed.
     * @return Returns the signature for a certain joinpoint without the return type. For example, for the signature 'void pt.iscte.ci.foo.A(String)' it will
     *         return 'pt.iscte.ci.foo.A(String)'.
     */
    public static final String discardReturnTypeFromSignature(final String signature) {
	int indexOfOpenParenthesis = signature.indexOf(OPEN_PARENTHESIS);
	String result = signature;
	if (indexOfOpenParenthesis == -1) { // it is an attribute
	    return signature.substring(signature.lastIndexOf(SPACE) + 1);
	} else {
	    int indexOfSpace = signature.indexOf(SPACE);
	    if (indexOfSpace > indexOfOpenParenthesis || indexOfSpace == -1)
		return result;

	    while (indexOfSpace < indexOfOpenParenthesis && indexOfSpace != -1) {
		result = result.substring(indexOfSpace + 1);
		indexOfSpace = result.indexOf(SPACE);
		indexOfOpenParenthesis = result.indexOf(OPEN_PARENTHESIS);
	    }
	}
	return result;
    }

    /**
     * 
     * @param signature
     *            The signature of this protected object.
     * @param isConstructorSignature
     *            The flag that states if the signature is a of a constructor.
     * @return It returns the class name from the signature, without the return type.
     */
    public static final String getClassNameFromSignatureWithoutReturnType(final String signature, final boolean isConstructorSignature) {
	String result = discardReturnTypeFromSignature(signature);

	if (result.contains(OPEN_PARENTHESIS)) { // it is method
	    result = result.substring(0, result.indexOf(OPEN_PARENTHESIS));
	}
	if (isConstructorSignature) {
	    if (signature.contains(INIT))
		return result.substring(0, result.lastIndexOf(DOT));
	    return result;
	}

	result = result.substring(0, result.lastIndexOf(DOT));
	return result;
    }

    /**
     * 
     * @param signature
     *            The signature of the protected object.
     * @return It returns the argument types names from the signature passed as a parameter.
     */
    public static final String getArgumentTypesNames(final String signature) {
	if (!signature.contains(OPEN_PARENTHESIS)) { // it is an attribute
	    return null;
	}
	return signature.substring(signature.indexOf(OPEN_PARENTHESIS) + 1, signature.indexOf(CLOSE_PARENTHESIS));
    }

    /**
     * 
     * @param signature
     *            The signature of the protected object.
     * @param isConstructorSignature
     *            The flag that states if the signature is a of a constructor.
     * @return It returns the name of the protected object.
     */
    public static final String getMethodOrAttributeName(final String signature, final boolean isConstructorSignature) {
	String result = discardReturnTypeFromSignature(signature);
	if (result.contains(OPEN_PARENTHESIS)) { // it is method
	    if (isConstructorSignature && signature.contains(INIT)) {
		result = result.substring(0, result.indexOf(INIT));
	    } else {
		result = result.substring(0, result.indexOf(OPEN_PARENTHESIS));
	    }
	}
	result = result.substring(result.lastIndexOf(DOT) + 1);
	return result;
    }

    /**
     * @param methods
     * @return Returns a list of AccessControlled annotations according for the list of methods passed in as argument.
     */
    public static List buildDecisionMetaInfoForMethods(final List methods) {
	final List result = new ArrayList();
	Collections.reverse(methods);
	boolean canOverride = false;
	for (int i = 0; i != methods.size(); i++) {
	    final Method method = methods.get(i);
	    AccessControlled accessControlledOnType = null;
	    if (isInherited(method)) {
		accessControlledOnType = (AccessControlled) ReflectionUtils.getAnnotation(method.getDeclaringClass(), AccessControlled.class);
	    }
	    addAccessControlledToResult(accessControlledOnType, method, result, canOverride);
	    final AccessControlPolicy accessControlPolicy = (AccessControlPolicy) ReflectionUtils.getAnnotation(method, AccessControlPolicy.class);

	    canOverride = getCanOverrideFlag(accessControlPolicy);

	    if (accessControlPolicy != null && accessControlPolicy.value() == AccessControlPolicyType.CANNOT_OVERRIDE) {
		break;
	    }
	}
	Collections.reverse(result);
	return result;
    }

    /**
     * 
     * @param method
     *            The method to check the annotation.
     * @return Returns true if the method has the annotation AccessControlled with its element isInherited() set to true.
     */
    private static boolean isInherited(final Method method) {
	return method.getAnnotation(AccessControlled.class) != null && ((AccessControlled) method.getAnnotation(AccessControlled.class)).isInherited();
    }

    /**
     * It adds the corresponding access controlled annotation to the list of access controlled annotations associated to the current protected object and all
     * similar parent objects in the object's type hierarchy.
     * 
     * @param accessControlledOnType
     * @param method
     * @param result
     * @param canOverride
     */
    private static void addAccessControlledToResult(final AccessControlled accessControlledOnType, final Method method, final List result,
	    final boolean canOverride) {
	final AccessControlled accessControlled = accessControlledOnType != null ? accessControlledOnType
		: (AccessControlled) ReflectionUtils.getAnnotation(method, AccessControlled.class);
	if (canOverride) {
	    int index = result.size() == 1 ? 0 : result.size() - 1;
	    result.set(index, accessControlled);
	} else {
	    result.add(accessControlled);
	}
    }

    /**
     * @param constructors
     * @return Returns a list of AccessControlled annotations according for the list of constructors passed in as argument.
     */
    public static List buildDecisionMetaInfoForConstructors(final List> constructors) {
	final List result = new java.util.ArrayList();
	Collections.reverse(constructors);
	boolean canOverride = false;
	for (final Constructor constructor : constructors) {
	    AccessControlled accessControlledOnType = null;
	    if (isInherited(constructor)) {
		accessControlledOnType = (AccessControlled) ReflectionUtils.getAnnotation(constructor.getDeclaringClass(), AccessControlled.class);
	    }
	    addAccessControlledToResult(accessControlledOnType, constructor, result, canOverride);
	    final AccessControlPolicy accessControlPolicy = (AccessControlPolicy) ReflectionUtils.getAnnotation(constructor, AccessControlPolicy.class);

	    canOverride = getCanOverrideFlag(accessControlPolicy);

	    if (accessControlPolicy != null && accessControlPolicy.value() == AccessControlPolicyType.CANNOT_OVERRIDE) {
		break;
	    }
	}
	Collections.reverse(result);
	return result;
    }

    /**
     * 
     * @param method
     *            The method to check the annotation.
     * @return Returns true if the method has the annotation AccessControlled with its element isInherited() set to true.
     */
    private static boolean isInherited(final Constructor constructor) {
	return constructor.getAnnotation(AccessControlled.class) != null
		&& ((AccessControlled) constructor.getAnnotation(AccessControlled.class)).isInherited();
    }

    /**
     * It adds the corresponding access controlled annotation to the list of access controlled annotations associated to the current protected object and all
     * similar parent objects in the object's type hierarchy.
     * 
     * @param accessControlledOnType
     * @param constructor
     * @param result
     * @param canOverride
     * @param currentIndex
     */
    private static void addAccessControlledToResult(final AccessControlled accessControlledOnType, final Constructor constructor,
	    final List result, final boolean canOverride) {
	final AccessControlled accessControlled = accessControlledOnType != null ? accessControlledOnType
		: (AccessControlled) ReflectionUtils.getAnnotation(constructor, AccessControlled.class);
	if (canOverride) {
	    result.set(result.size() - 1, accessControlled);
	} else {
	    result.add(accessControlled);
	}
    }

    /**
     * 
     * @param accessControlPolicy
     *            The policy associated to the current protected object.
     * @return Returns true if the accessControlPolicy value is set to CAN_OVERRIIDE. It returns false otherwise.
     */
    private static boolean getCanOverrideFlag(final AccessControlPolicy accessControlPolicy) {
	if (accessControlPolicy != null && accessControlPolicy.value() == AccessControlPolicyType.CAN_OVERRIDE) {
	    return true;
	} else {
	    return false;
	}
    }

    /**
     * @param field
     * @return Returns a singleton list of access control meta info for the field passed in as argument.
     */
    public static List buildDecisionMetaInfoForField(final Field field) {
	AccessControlled accessControlledOnType = null;
	if (isInherited(field)) {
	    accessControlledOnType = (AccessControlled) ReflectionUtils.getAnnotation(field.getDeclaringClass(), AccessControlled.class);
	}
	return accessControlledOnType != null ? Collections.singletonList(accessControlledOnType)
		: Collections.singletonList(field.getAnnotation(AccessControlled.class));
    }

    /**
     * 
     * @param method
     *            The method to check the annotation.
     * @return Returns true if the method has the annotation AccessControlled with its element isInherited() set to true.
     */
    private static boolean isInherited(final Field field) {
	return field.getAnnotation(AccessControlled.class) != null && ((AccessControlled) field.getAnnotation(AccessControlled.class)).isInherited();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy