/******************************************************************************* * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.internal.xpand2.ast; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.internal.xpand2.model.XpandAdvice; import org.eclipse.internal.xpand2.model.XpandDefinition; import org.eclipse.internal.xpand2.type.DefinitionType; import org.eclipse.internal.xtend.expression.ast.DeclaredParameter; import org.eclipse.internal.xtend.expression.ast.Identifier; import org.eclipse.xpand2.XpandExecutionContext; import org.eclipse.xtend.expression.AnalysationIssue; import org.eclipse.xtend.expression.ExecutionContext; import org.eclipse.xtend.expression.Variable; import org.eclipse.xtend.typesystem.Type; /** * @author Sven Efftinge (http://www.efftinge.de) * */ public class Advice extends AbstractDefinition implements XpandAdvice { public final static String DEF_VAR_NAME = "targetDef"; public Advice(final Identifier pointCut, final Identifier type, final DeclaredParameter[] params, final boolean wildParams, final Statement[] body) { super(pointCut, type, params, body); this.wildParams = wildParams; } public Identifier getPointCut() { return getDefName(); } @Override public void analyze(XpandExecutionContext ctx, final Set<AnalysationIssue> issues) { ctx = (XpandExecutionContext) ctx.cloneWithVariable(new Variable(DEF_VAR_NAME, ctx.getTypeForName(DefinitionType.TYPE_NAME))); super.analyze(ctx, issues); } private Pattern p = null; public boolean isWildcardParams () { return wildParams; } public boolean matches(final XpandDefinition def, XpandExecutionContext ctx) { if (p == null) { p = Pattern.compile(getName().replaceAll("\\*", ".*")); } final Matcher m = p.matcher(def.getQualifiedName()); if (m.matches()) { ctx = (XpandExecutionContext) ctx.cloneWithResource(def.getOwner()); final Type t = ctx.getTypeForName(def.getTargetType()); final Type[] paramTypes = new Type[def.getParams().length]; for (int i = 0; i < paramTypes.length; i++) { paramTypes[i] = ctx.getTypeForName(def.getParams()[i].getType().getValue()); } if (getParams().length == paramTypes.length || (wildParams && getParams().length <= paramTypes.length)) { ctx = (XpandExecutionContext) ctx.cloneWithResource(def.getOwner()); final Type at = ctx.getTypeForName(getTargetType()); if (at.isAssignableFrom(t)) { for (int i = 0; i < getParams().length; i++) { final Type pt = ctx.getTypeForName(getParams()[i].getType().getValue()); if (!pt.isAssignableFrom(paramTypes[i])) return false; } return true; } } } return false; } @Override public String getNameString(ExecutionContext context) { return "AROUND"; } @Override public String toString() { if (_stringRepresentation == null) { _stringRepresentation = getName() + getParamString(false) + " : " + getType().getValue(); } return _stringRepresentation; } @Override public boolean equals(Object obj) { return super.equals(obj) && getOwner().getFullyQualifiedName().equals(((Advice)obj).getOwner().getFullyQualifiedName()); } @Override public int hashCode() { return super.hashCode() + getOwner().getFullyQualifiedName().hashCode(); } }