| /* |
| * Copyright (c) 2005, 2008 Sven Efftinge 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: |
| * Sven Efftinge - Initial API and implementation |
| * Artem Tikhomirov (Borland) - Migration to OCL expressions |
| */ |
| package org.eclipse.gmf.internal.xpand.ast; |
| |
| import java.util.Set; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.gmf.internal.xpand.BuiltinMetaModel; |
| import org.eclipse.gmf.internal.xpand.expression.ast.Identifier; |
| import org.eclipse.gmf.internal.xpand.model.AnalysationIssue; |
| import org.eclipse.gmf.internal.xpand.model.Variable; |
| import org.eclipse.gmf.internal.xpand.model.XpandAdvice; |
| import org.eclipse.gmf.internal.xpand.model.XpandDefinition; |
| import org.eclipse.gmf.internal.xpand.model.ExecutionContext; |
| import org.eclipse.gmf.internal.xpand.ocl.DeclaredParameter; |
| import org.eclipse.gmf.internal.xpand.util.TypeNameUtil; |
| import org.eclipse.ocl.cst.TypeCS; |
| |
| /** |
| * @author Sven Efftinge |
| */ |
| public class Advice extends AbstractDefinition implements XpandAdvice { |
| |
| public final static String DEF_VAR_NAME = "targetDef"; |
| |
| private final Identifier pointCut; |
| |
| private final boolean wildParams; |
| |
| public Advice(final int start, final int end, final int line, final Identifier pointCut, final TypeCS type, |
| final DeclaredParameter[] params, final boolean wildParams, final Statement[] body) { |
| super(start, end, line, type, params, body); |
| this.pointCut = pointCut; |
| this.wildParams = wildParams; |
| } |
| |
| public Identifier getPointCut() { |
| return pointCut; |
| } |
| |
| @Override |
| public String toString() { |
| return owner.getFullyQualifiedName() + " " + pointCut.getValue() + getParamString() + " FOR " + type.toString(); |
| } |
| |
| @Override |
| public void analyze(ExecutionContext ctx, final Set<AnalysationIssue> issues) { |
| ctx = ctx.cloneWithVariable(new Variable(DEF_VAR_NAME, BuiltinMetaModel.DEFINITION_TYPE, null)); |
| super.analyze(ctx, issues); |
| } |
| |
| private String getParamString() { |
| if ((params == null) || (params.length == 0)) { |
| return wildParams ? "(*)" : ""; |
| } |
| final StringBuilder buff = new StringBuilder("("); |
| for (int i = 0; i < params.length; i++) { |
| final DeclaredParameter p = params[i]; |
| buff.append(p.getVarName()).append(" ").append(p.getTypeName()); |
| if (i + 1 < params.length) { |
| buff.append(","); |
| } |
| } |
| if (wildParams) { |
| buff.append(",*"); |
| } |
| return buff.append(")").toString(); |
| } |
| |
| private Pattern p = null; |
| |
| public boolean matches(final XpandDefinition def, ExecutionContext ctx) { |
| if (p == null) { |
| p = Pattern.compile(pointCut.getValue().replaceAll("\\*", ".*")); |
| } |
| // 1) AROUND simpleName |
| final Matcher m1 = p.matcher(def.getName()); |
| // 2) AROUND fully::qualified::name |
| final Matcher m2 = p.matcher(def.getOwner().getFullyQualifiedName() + TypeNameUtil.NS_DELIM + def.getName()); |
| if (m1.matches() || m2.matches()) { |
| ctx = ctx.cloneWithResource(def.getOwner()); |
| final EClassifier t = def.getTargetType().getTypeForName(ctx); |
| final EClassifier[] paramTypes = new EClassifier[def.getParams().length]; |
| for (int i = 0; i < paramTypes.length; i++) { |
| paramTypes[i] = def.getParams()[i].getTypeForName(ctx); |
| } |
| // FIXME next check can be done earlier |
| if ((params.length == paramTypes.length) || (wildParams && (params.length <= paramTypes.length))) { |
| |
| ctx = ctx.cloneWithResource(this.owner); //need to resolve in the context of the aspect |
| final EClassifier at = type.getTypeForName(ctx); |
| if (BuiltinMetaModel.isAssignableFrom(ctx, at, t)) { |
| for (int i = 0; i < params.length; i++) { |
| final EClassifier pt = params[i].getTypeForName(ctx); |
| if (!BuiltinMetaModel.isAssignableFrom(ctx, pt, paramTypes[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| } |