org.aspectj.weaver.patterns.HandlerPointcut.java Source code

Java tutorial

Introduction

Here is the source code for org.aspectj.weaver.patterns.HandlerPointcut.java

Source

/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved. 
 * This program and the accompanying materials are made available 
 * under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors: 
 *     PARC     initial implementation 
 * ******************************************************************/

package org.aspectj.weaver.patterns;

import java.io.IOException;
import java.util.Map;

import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;

/**
 * This is a kind of KindedPointcut. This belongs either in a hierarchy with it or in a new place to share code with other potential
 * future statement-level pointcuts like synchronized and throws
 */
public class HandlerPointcut extends Pointcut {
    TypePattern exceptionType;

    private static final int MATCH_KINDS = Shadow.ExceptionHandler.bit;

    public HandlerPointcut(TypePattern exceptionType) {
        this.exceptionType = exceptionType;
        this.pointcutKind = HANDLER;
    }

    public int couldMatchKinds() {
        return MATCH_KINDS;
    }

    public FuzzyBoolean fastMatch(FastMatchInfo type) {
        // ??? should be able to do better by finding all referenced types in type
        return FuzzyBoolean.MAYBE;
    }

    protected FuzzyBoolean matchInternal(Shadow shadow) {
        if (shadow.getKind() != Shadow.ExceptionHandler) {
            return FuzzyBoolean.NO;
        }

        exceptionType.resolve(shadow.getIWorld());

        // we know we have exactly one parameter since we're checking an exception handler
        return exceptionType.matches(shadow.getSignature().getParameterTypes()[0].resolve(shadow.getIWorld()),
                TypePattern.STATIC);
    }

    public Pointcut parameterizeWith(Map typeVariableMap, World w) {
        HandlerPointcut ret = new HandlerPointcut(exceptionType.parameterizeWith(typeVariableMap, w));
        ret.copyLocationFrom(this);
        return ret;
    }

    public boolean equals(Object other) {
        if (!(other instanceof HandlerPointcut)) {
            return false;
        }
        HandlerPointcut o = (HandlerPointcut) other;
        return o.exceptionType.equals(this.exceptionType);
    }

    public int hashCode() {
        int result = 17;
        result = 37 * result + exceptionType.hashCode();
        return result;
    }

    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("handler(");
        buf.append(exceptionType.toString());
        buf.append(")");
        return buf.toString();
    }

    public void write(CompressingDataOutputStream s) throws IOException {
        s.writeByte(Pointcut.HANDLER);
        exceptionType.write(s);
        writeLocation(s);
    }

    public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException {
        HandlerPointcut ret = new HandlerPointcut(TypePattern.read(s, context));
        ret.readLocation(context, s);
        return ret;
    }

    // XXX note: there is no namebinding in any kinded pointcut.
    // still might want to do something for better error messages
    // We want to do something here to make sure we don't sidestep the parameter
    // list in capturing type identifiers.
    public void resolveBindings(IScope scope, Bindings bindings) {
        exceptionType = exceptionType.resolveBindings(scope, bindings, false, false);
        boolean invalidParameterization = false;
        if (exceptionType.getTypeParameters().size() > 0) {
            invalidParameterization = true;
        }
        UnresolvedType exactType = exceptionType.getExactType();
        if (exactType != null && exactType.isParameterizedType()) {
            invalidParameterization = true;
        }
        if (invalidParameterization) {
            // no parameterized or generic types for handler
            scope.message(
                    MessageUtil.error(WeaverMessages.format(WeaverMessages.HANDLER_PCD_DOESNT_SUPPORT_PARAMETERS),
                            getSourceLocation()));
        }
        // XXX add error if exact binding and not an exception
    }

    protected Test findResidueInternal(Shadow shadow, ExposedState state) {
        return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
    }

    public Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) {
        Pointcut ret = new HandlerPointcut(exceptionType);
        ret.copyLocationFrom(this);
        return ret;
    }

    public Object accept(PatternNodeVisitor visitor, Object data) {
        return visitor.visit(this, data);
    }
}