package org.aim.cswrapper.aspect; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.aim.artifacts.events.probes.MonitorWaitingTimeProbe; import org.aim.artifacts.probes.ResponsetimeProbe; import org.aim.artifacts.probes.SQLQueryProbe; import org.aim.artifacts.scopes.EntryPointScope; import org.aim.artifacts.scopes.JDBCScope; import org.aim.description.InstrumentationEntity; import org.aim.description.probes.MeasurementProbe; import org.aim.description.restrictions.Restriction; import org.aim.description.scopes.APIScope; import org.aim.description.scopes.MethodScope; import org.aim.description.scopes.Scope; import org.aim.description.scopes.SynchronizedScope; public class AspectDescriptionUtils { public static List<AspectDescription> convert(InstrumentationEntity<?> entity) { List<AspectDescription> retList = new ArrayList<>(); boolean responseSQL = false; boolean containsRP = false; boolean containsSP = false; for (MeasurementProbe<?> probe : entity.getProbes()) { if (probe.equals(ResponsetimeProbe.MODEL_PROBE)) { if (containsSP){ responseSQL = true; }else { containsRP = true; } } if (probe.equals(SQLQueryProbe.MODEL_PROBE)) { if (containsRP){ responseSQL = true; } else { containsSP = true; } } } if (responseSQL) { MeasurementProbe<?> probe = entity.getProbes().iterator().next(); addProbe(probe, entity, retList, "ResponseTimeSQLQueryAspect"); } else { for (MeasurementProbe<?> probe : entity.getProbes()) { addProbe(probe, entity, retList, null); } } return retList; } private static void addProbe(MeasurementProbe<?> probe, InstrumentationEntity<?> entity, List<AspectDescription> retList, String aspectName) { AspectDescription aspect = new AspectDescription(); Restriction restriction = entity.getLocalRestriction(); // Aspect class if (aspectName == null) aspect.setAspectClass(propeToAspect(entity.getScope(), probe)); else aspect.setAspectClass(aspectName); // Modifiers setModifiers(aspect, restriction.getModifierIncludes()); // Packages if (!restriction.getPackageIncludes().isEmpty()) { StringBuilder incPackages = new StringBuilder("regex:"); Iterator<String> iterator = restriction.getPackageIncludes().iterator(); while (iterator.hasNext()) { incPackages.append(iterator.next()); if (iterator.hasNext()) { incPackages.append("|"); } } aspect.setTargetTypes(incPackages.toString()); } // Translate scope into the aspect description if (entity.getScope() instanceof SynchronizedScope) { // SynchronizedScope aspect.setOnSynchronized(true); } else if (entity.getScope() instanceof APIScope) { // APIScope APIScope apiScope = (APIScope) entity.getScope(); // EntryPointScope if (apiScope.getApiName().equals(EntryPointScope.class.getName())) { aspect.setSuperClass("System.Web.Mvc.Controller"); aspect.setSuperClassAssembly("System.Web.Mvc"); } // JDBCScope if (apiScope.getApiName().equals(JDBCScope.class.getName())) { //aspect.setTargetAssemblies("EntityFramework"); aspect.setTargetTypes("Nop.Data.NopObjectContext"); aspect.setTargetMembers("regex:.*Sql.*"); } } else if (entity.getScope() instanceof MethodScope) { // TODO only 1 method is supported at the moment! // MethodScope // Assembly:Class.Path:Method // Class.Path:Method # Local Assembly MethodScope methodScopehodScope = (MethodScope) entity.getScope(); for (String methodPattern : methodScopehodScope.getMethods()) { String split[] = methodPattern.split(":"); if (split.length == 2) { aspect.setTargetTypes(split[0]); aspect.setTargetMembers(split[1]); } else if (split.length == 3) { aspect.setTargetAssemblies(split[0]); aspect.setTargetTypes(split[1]); aspect.setTargetMembers(split[2]); } } } retList.add(aspect); /* * Excluding */ if (!restriction.getModifierExcludes().isEmpty() || !restriction.getPackageExcludes().isEmpty()) { AspectDescription aspectExclude = new AspectDescription(); // Aspect class aspectExclude.setAspectClass(propeToAspect(entity.getScope(), probe)); // Modifiers setModifiers(aspectExclude, restriction.getModifierExcludes()); // Packages if (!restriction.getPackageExcludes().isEmpty()) { StringBuilder excPackages = new StringBuilder("regex:"); Iterator<String> iterator = restriction.getPackageExcludes().iterator(); while (iterator.hasNext()) { excPackages.append(iterator.next()); if (iterator.hasNext()) { excPackages.append("|"); } } aspectExclude.setTargetTypes(excPackages.toString()); } aspectExclude.setAttributeExclude(true); aspect.setPriority(1); aspectExclude.setPriority(2); // Adding retList.add(aspectExclude); } } /** * Sets the given modifiers in the targetAspect. * * @param targetAspect * aspect that receives the given modifiers * @param modifiers * modifiers that are applied to the aspect */ private static void setModifiers(AspectDescription targetAspect, Set<Integer> modifiers) { for (Integer mod : modifiers) { if (Modifier.isAbstract(mod)) { targetAspect.setOnAbstract(true); } if (Modifier.isPrivate(mod)) { targetAspect.setOnPrivate(true); } if (Modifier.isProtected(mod)) { targetAspect.setOnProtected(true); } if (Modifier.isPublic(mod)) { targetAspect.setOnPublic(true); } if (Modifier.isStatic(mod)) { targetAspect.setOnStatic(true); } } } /** * Returns a String which represents the Class name of an aspect related to * the given probe and scope. * * @param scope * @param probe * @return Name of the aspect class */ private static String propeToAspect(Scope scope, MeasurementProbe<?> probe) { if (probe.equals(ResponsetimeProbe.MODEL_PROBE) || ResponsetimeProbe.class.isAssignableFrom(probe.getClass())) { return "ResponseTimeAspect"; } if (scope instanceof SynchronizedScope && probe.equals(MonitorWaitingTimeProbe.MODEL_PROBE)) { return "ResponseTimeAspect"; } if (probe.equals(SQLQueryProbe.MODEL_PROBE)) { return "SQLQueryAspect"; } throw new UnsupportedPropeException(probe); } }