/* Copyright (c) 2008 Arno Haase, Andr� Arnold. 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: Arno Haase - initial API and implementation Andr� Arnold */ package org.eclipse.xtend.backend.aop; import java.util.List; import java.util.regex.Pattern; import org.eclipse.xtend.backend.common.BackendType; import org.eclipse.xtend.backend.common.Function; import org.eclipse.xtend.backend.common.QualifiedName; import org.eclipse.xtend.backend.util.Pair; /** * * @author Arno Haase (http://www.haase-consulting.com) */ public final class ExecutionPointcut implements Pointcut { private final String _functionNamePattern; private final boolean _hasCompleteName; private final Pattern _namePattern; private final List<Pair<String, AdviceParamType>> _paramTypes; private final boolean _hasVarArgs; private final AdviceParamType _varArgsType; /** * * @param functionNamePattern is the pattern for the function name that is matched by this pointcut. '*' can * be used as a wildcard. * * @param paramTypes this is the - optionally empty - list of parameters for which an explicit type is given. * * @param hasVarArgs this flag determines if there is a variable number of arguments after the explicitly given * param types. One of the two extreme cases is that all parameters are explicitly given, then this * flag is false. The other extreme case is that the pointcut regardless of * * @param varArgsType */ public ExecutionPointcut (String functionNamePattern, List<Pair<String, AdviceParamType>> paramTypes, boolean hasVarArgs, AdviceParamType varArgsType) { _functionNamePattern = functionNamePattern; if (_functionNamePattern.contains ("*")) { _hasCompleteName = false; _namePattern = Pattern.compile (functionNamePattern.replace ("*", ".*")); } else { _hasCompleteName = true; _namePattern = null; } _paramTypes = paramTypes; _hasVarArgs = hasVarArgs; _varArgsType = varArgsType; } public boolean matches (QualifiedName name, Function function) { if (! matchesName (name)) return false; if (! matchesParamTypes (function.getParameterTypes())) return false; return true; } private boolean matchesParamTypes (List<? extends BackendType> paramTypes) { // check the number of parameters if (_hasVarArgs) { if (paramTypes.size() < _paramTypes.size()) return false; } else { if (paramTypes.size() != _paramTypes.size()) return false; } // check the explicitly given parameter types for (int i=0; i<_paramTypes.size(); i++) if (! _paramTypes.get (i).getSecond().matches (paramTypes.get (i))) return false; // check the var args type against the remaining parameter types for (int i=_paramTypes.size(); i<paramTypes.size(); i++) if (! _varArgsType.matches (paramTypes.get(i))) return false; return true; } private boolean matchesName (QualifiedName functionName) { if (_hasCompleteName) return functionName.getFullQualifiedName().equals (_functionNamePattern); return _namePattern.matcher (functionName.getFullQualifiedName()).matches(); } public List<Pair<String, AdviceParamType>> getParamTypes() { return _paramTypes; } public String getFunctionNamePattern() { return _functionNamePattern; } public boolean isHasVarArgs() { return _hasVarArgs; } public AdviceParamType getVarArgsType() { return _varArgsType; } }