package rocks.inspectit.server.instrumentation.config.applier; import rocks.inspectit.shared.all.instrumentation.classcache.ClassType; import rocks.inspectit.shared.all.instrumentation.classcache.MethodType; import rocks.inspectit.shared.all.instrumentation.config.impl.AgentConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodInstrumentationConfig; import rocks.inspectit.shared.cs.ci.Environment; /** * Base class for all instrumentation appliers. * * @author Ivan Senic * */ public abstract class AbstractInstrumentationApplier extends GenericApplier implements IInstrumentationApplier { /** * Default constructor. * * @param environment * Environment belonging to the assignment. */ public AbstractInstrumentationApplier(Environment environment) { super(environment); } /** * {@inheritDoc} */ @Override public boolean addInstrumentationPoints(AgentConfig agentConfiguration, ClassType classType) { boolean added = false; if (matches(classType)) { for (MethodType methodType : classType.getMethods()) { if (matches(methodType)) { MethodInstrumentationConfig methodInstrumentationConfig = getOrCreateMethodInstrumentationConfig(methodType); applyAssignment(agentConfiguration, methodType, methodInstrumentationConfig); added = true; } } } return added; } /** * {@inheritDoc} */ @Override public boolean removeInstrumentationPoints(ClassType classType) { if (!classType.hasInstrumentationPoints()) { return false; } boolean removed = false; if (matches(classType)) { for (MethodType methodType : classType.getMethods()) { if (matches(methodType)) { methodType.setMethodInstrumentationConfig(null); removed = true; } } } return removed; } /** * If the {@link ClassType} matches the assignment in the applier. * * @param classType * ClassType to check. * @return <code>true</code> if matches, <code>false</code> otherwise */ protected abstract boolean matches(ClassType classType); /** * If the {@link MethodType} matches the assignment in the applier. * * @param methodType * MethoType to check. * @return <code>true</code> if matches, <code>false</code> otherwise */ protected abstract boolean matches(MethodType methodType); /** * Applies the assignment of this applier to the {@link MethodInstrumentationConfig}. * * @param agentConfiguration * Agent configuration being used. * @param methodType * MethodType being instrumented. * @param methodInstrumentationConfig * {@link MethodInstrumentationConfig}. */ protected abstract void applyAssignment(AgentConfig agentConfiguration, MethodType methodType, MethodInstrumentationConfig methodInstrumentationConfig); /** * Creates method instrumentation configuration for the given {@link MethodType} or returns * existing one. * * @param methodType * {@link MethodType} to get {@link MethodInstrumentationConfig} for. * @return Existing or new {@link MethodInstrumentationConfig}. */ private MethodInstrumentationConfig getOrCreateMethodInstrumentationConfig(MethodType methodType) { // check for existing MethodInstrumentationConfig methodInstrumentationConfig = methodType.getMethodInstrumentationConfig(); // if not create new one if (null == methodInstrumentationConfig) { methodInstrumentationConfig = new MethodInstrumentationConfig(methodType); methodType.setMethodInstrumentationConfig(methodInstrumentationConfig); } return methodInstrumentationConfig; } }