public static Tracklytics init(EventSubscriber eventSubscriber) { Tracklytics tracklytics = new Tracklytics(eventSubscriber); TracklyticsAspect.subscribe(tracklytics); return tracklytics; }
private void addMethodAttributes(Method method, Object returnValue, Map<String, Object> attributes, Map<Integer, String> transformMap) { Annotation[] annotations = method.getDeclaredAnnotations(); for (Annotation annotation : annotations) { if (annotation instanceof Attribute) { addAttribute((Attribute) annotation, returnValue, attributes); } if (annotation instanceof FixedAttribute) { addFixedAttribute((FixedAttribute) annotation, attributes); } if (annotation instanceof FixedAttributes) { addFixedAttributes((FixedAttributes) annotation, attributes); } if (annotation instanceof TransformAttributeMap) { TransformAttributeMap transformAttributeMap = (TransformAttributeMap) annotation; int[] keys = transformAttributeMap.keys(); String[] values = transformAttributeMap.values(); if (keys.length != values.length) { throw new IllegalStateException("TransformAttributeMap keys and values must have same length"); } for (int i = 0; i < keys.length; i++) { transformMap.put(keys[i], values[i]); } } if (annotation instanceof TransformAttribute) { addTransformAttribute((TransformAttribute) annotation, returnValue, transformMap, attributes); } } }
@Around("methodAnnotatedWithTrackEvent() || constructorAnnotatedTrackEvent()") public Object weaveJoinPointTrackEvent(ProceedingJoinPoint joinPoint) throws Throwable { Object result = joinPoint.proceed(); // Local attributes final Map<String, Object> attributes = new HashMap<>(); Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); addClassAttributes(method, joinPoint, attributes); // TODO: This creation is most of the time redundant. Find a way to avoid redundant map creation Map<Integer, String> transformMap = new HashMap<>(); addMethodAttributes(method, result, attributes, transformMap); addMethodParameterAttributes(method, joinPoint, attributes, transformMap); // send the results TrackEvent trackEvent = method.getAnnotation(TrackEvent.class); pushEvent(trackEvent, attributes); return result; }
private void addClassAttributes(Method method, JoinPoint joinPoint, Map<String, Object> attributes) { Class<?> declaringClass = method.getDeclaringClass(); if (method.isAnnotationPresent(TrackableAttribute.class) && Trackable.class.isAssignableFrom(declaringClass)) { Trackable trackable = (Trackable) joinPoint.getThis(); if (trackable.getTrackableAttributes() != null) { attributes.putAll(trackable.getTrackableAttributes()); } } while (declaringClass != null) { addFixedAttribute(declaringClass.getAnnotation(FixedAttribute.class), attributes); addFixedAttributes(declaringClass.getAnnotation(FixedAttributes.class), attributes); declaringClass = declaringClass.getEnclosingClass(); } declaringClass = joinPoint.getThis().getClass(); addFixedAttribute(declaringClass.getAnnotation(FixedAttribute.class), attributes); addFixedAttributes(declaringClass.getAnnotation(FixedAttributes.class), attributes); }
@Before public void setup() throws Exception { initMocks(this); aspectListener = new AspectListener() { @Override public void onAspectEventTriggered(TrackEvent trackEvent, Map<String, Object> attributes) { TracklyticsAspectTest.this.trackEvent = trackEvent; TracklyticsAspectTest.this.attributes = attributes; } @Override public void onAspectSuperAttributeAdded(String key, Object value) { superAttributes.put(key, value); } @Override public void onAspectSuperAttributeRemoved(String key) { superAttributes.remove(key); } }; aspect = new TracklyticsAspect(); aspect.subscribe(aspectListener); when(joinPoint.getSignature()).thenReturn(methodSignature); }
private void addTransformAttribute(TransformAttribute attribute, Object result, Map<Integer, String> transformMap, Map<String, Object> attributes) { if (attribute == null) return; Object value = null; if (result != null) { value = transformMap.get(result); } else if (attribute.defaultValue().length() != 0) { value = attribute.defaultValue(); } attributes.put(attribute.value(), value); if (attribute.isSuper()) { addSuperAttribute(attribute.value(), value); } }
@Around("methodAnnotatedWithSuperAttribute() || constructorAnnotatedWithSuperAttribute()") public void weaveJoinPointSuperAttribute(ProceedingJoinPoint joinPoint) throws Throwable { Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); // method parameters Object[] fields = joinPoint.getArgs(); Annotation[][] annotations = method.getParameterAnnotations(); addSuperAttributesFromParameters(annotations, fields); }
private void addAttribute(Attribute attribute, Object methodResult, Map<String, Object> attributes) { if (attribute == null) return; Object value = null; if (methodResult != null) { value = methodResult; } else if (attribute.defaultValue().length() != 0) { value = attribute.defaultValue(); } attributes.put(attribute.value(), value); if (attribute.isSuper()) { addSuperAttribute(attribute.value(), value); } }
private void addSuperAttributesFromParameters(Annotation[][] keys, Object[] values) { if (keys == null || values == null) { return; } for (int i = 0, size = keys.length; i < size; i++) { if (keys[i].length == 0) { continue; } Object value = values[i]; Annotation annotation = keys[i][0]; if (annotation instanceof Attribute) { Attribute attribute = (Attribute) annotation; Object result = null; if (value != null) { result = value; } else if (attribute.defaultValue().length() != 0) { result = attribute.defaultValue(); } addSuperAttribute(attribute.value(), result); } } }
private void addFixedAttribute(FixedAttribute attribute, Map<String, Object> attributes) { if (attribute == null) return; attributes.put(attribute.key(), attribute.value()); if (attribute.isSuper()) { addSuperAttribute(attribute.key(), attribute.value()); } }
private void addFixedAttributes(FixedAttributes fixedAttributes, Map<String, Object> attributes) { if (fixedAttributes == null) return; FixedAttribute[] attributeList = fixedAttributes.value(); for (FixedAttribute attribute : attributeList) { attributes.put(attribute.key(), attribute.value()); if (attribute.isSuper()) { addSuperAttribute(attribute.key(), attribute.value()); } } }
addSuperAttribute(attribute.value(), result); addSuperAttribute(transformAttribute.value(), result);