Skip to content

Commit 290294c

Browse files
author
John Hunt
committed
Added event priorities and provider event priority filtering. Removed explicit provider inclusion.
1 parent 662eec6 commit 290294c

File tree

26 files changed

+773
-261
lines changed

26 files changed

+773
-261
lines changed

.idea/gradle.xml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/runConfigurations/Unit_Tests___Analytics_Kit.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ allprojects {
1515
In your module's build.gradle file, add the dependency:
1616
```groovy
1717
dependencies {
18-
compile 'com.github.busybusy.AnalyticsKit-Android:analyticskit:0.4.0'
18+
compile 'com.github.busybusy.AnalyticsKit-Android:analyticskit:0.5.0'
1919
...
2020
}
2121
```
@@ -24,7 +24,7 @@ You can include the implemented providers you want by adding them to the same de
2424
```groovy
2525
dependencies {
2626
...
27-
compile 'com.github.busybusy.AnalyticsKit-Android:answers-provider:0.4.0'
27+
compile 'com.github.busybusy.AnalyticsKit-Android:answers-provider:0.5.0'
2828
}
2929
```
3030

@@ -53,24 +53,33 @@ new ContentViewEvent()
5353
.send();
5454
```
5555

56-
You can restrict events only to certain providers:
56+
### Event Priorities
57+
By default, AnalyticsEvent objects have priority 0. However, you can
58+
set any integer priority on your events. It is up to you to decide on your priority scheme
59+
and provider filtering.
5760
```java
58-
new AnalyticsEvent(PredefinedEvents.ADD_TO_CART)
59-
.addProvider(Providers.ANSWERS)
60-
.putAttribute(Attributes.AddToCart.ITEM_PRICE, BigDecimal.valueOf(17.99))
61-
.putAttribute(Attributes.AddToCart.CURRENCY, Currency.getInstance("USD"))
62-
.putAttribute(Attributes.AddToCart.ITEM_NAME, "Android T-shirt")
63-
.putAttribute(Attributes.AddToCart.ITEM_TYPE, "Clothing")
64-
.putAttribute(Attributes.AddToCart.ITEM_ID, "sku-01443")
65-
.send();
66-
67-
new AnalyticsEvent("Google and Mixpanel only Event")
68-
.addProvider(Providers.GOOGLE_ANALYTICS)
69-
.addProvider(Providers.MIXPANEL)
70-
.putAttribute("key", "value")
61+
new AnalyticsEvent("Readme Read Event")
62+
.putAttribute("read", true)
63+
.setPriority(7)
7164
.send();
7265
```
7366

67+
By default, providers will log all events regardless of priority. If desired, you can
68+
configure providers with a ```PriorityFilter``` so that only events that pass the
69+
```PriorityFilter```'s shouldLog() filter method will be logged by that provider.
70+
In the following example, only AnalyticsEvent objects with priority less than 10 will be
71+
logged by the Answers provider:
72+
```java
73+
answersProvider.setPriorityFilter(new AnalyticsKitProvider.PriorityFilter()
74+
{
75+
@Override
76+
public boolean shouldLog(int priorityLevel)
77+
{
78+
return priorityLevel < 10;
79+
}
80+
});
81+
```
82+
7483
## License
7584

7685
Licensed under the Apache License, Version 2.0 (the "License");

analyticskit/analyticskit.iml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@
9696
<orderEntry type="sourceFolder" forTests="false" />
9797
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
9898
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
99-
<orderEntry type="library" exported="" name="support-annotations-23.2.0" level="project" />
99+
<orderEntry type="library" exported="" name="support-annotations-23.2.1" level="project" />
100100
</component>
101101
</module>

analyticskit/src/main/java/com/busybusy/analyticskit_android/AnalyticsEvent.java

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class AnalyticsEvent
3030
final String name;
3131
HashMap<String, Object> attributes;
3232
boolean timed;
33-
int providersMask = 0;
33+
int priorityLevel = 0;
3434

3535
/**
3636
* Instantiates a new {@code AnalyticsEvent} object
@@ -75,36 +75,24 @@ public AnalyticsEvent putAttribute(@NonNull String attributeName, @NonNull Objec
7575
}
7676

7777
/**
78-
* Restricts this event from being sent to all registered analytics providers.
79-
* <p/>
80-
* For example, if you have five registered providers, but only want to send this event to Google Analytics, call
81-
* {@code specifyProviders(Providers.GOOGLE_ANALYTICS)}. To send this event to only Google Analytics and Answers,
82-
* call {@code specifyProviders(Providers.GOOGLE_ANALYTICS | Providers.ANSWERS)}.
83-
*
84-
* @param providersMask an int value that contains the bitwise OR of the provider(s) to which you DO wish to send the event.
85-
*
86-
* @return the {@link AnalyticsEvent} instance
78+
* Gets the priority of this event.
79+
* @return the priority of the event. Returns {@code 0} when {@link #setPriority(int)} has not been called.
8780
*/
88-
@NonNull
89-
public AnalyticsEvent specifyProviders(int providersMask)
81+
public int getPriority()
9082
{
91-
this.providersMask = providersMask;
92-
93-
return this;
83+
return priorityLevel;
9484
}
9585

9686
/**
97-
* Specifies a certain provider to which this event will be sent (restricts this event from being sent to all registered analytics providers).
87+
* Sets the priority of the event. The event defaults to {@code 0} when this method is not called.
9888
* <p/>
99-
* For example, if you have five registered providers, but only want to send this event to Google Analytics, call
100-
* {@code event.addProvider(Providers.GOOGLE_ANALYTICS)}. To send this event to only Google Analytics and Answers,
101-
* call {@code event.addProvider(Providers.GOOGLE_ANALYTICS).addProvider(Providers.ANSWERS)}.
102-
* @param providerMask an int value that contains the type of provider to which you DO wish to send the event.
103-
* @return the {@link AnalyticsEvent} instance
89+
* <b>Note:</b> It is up to the developer to define what priority scheme to use (if any).
90+
* @param priorityLevel the priority the event should use
91+
* @return the {@link AnalyticsEvent} instance (for builder-style convenience)
10492
*/
105-
public AnalyticsEvent addProvider(int providerMask)
93+
public AnalyticsEvent setPriority(int priorityLevel)
10694
{
107-
this.providersMask |= providerMask;
95+
this.priorityLevel = priorityLevel;
10896
return this;
10997
}
11098

analyticskit/src/main/java/com/busybusy/analyticskit_android/AnalyticsKit.java

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public AnalyticsKit registerProvider(@NonNull AnalyticsKitProvider provider)
7474
* Sends the given event to all registered analytics providers (OR just to select providers if the event has been set to restrict the providers).
7575
* @param event the event to capture with analytics tools
7676
*/
77-
public void logEvent(AnalyticsEvent event)
77+
public void logEvent(AnalyticsEvent event) throws IllegalStateException
7878
{
7979
if (event.isTimed())
8080
{
@@ -91,20 +91,18 @@ public void logEvent(AnalyticsEvent event)
9191
{
9292
for (AnalyticsKitProvider provider : providers)
9393
{
94-
if (event.providersMask != 0)
94+
// guard clause
95+
//noinspection ConstantConditions
96+
if (provider.getPriorityFilter() == null)
9597
{
96-
// the user has chosen to restrict the providers to which this event is sent
97-
if ((provider.getType() & event.providersMask) != 0)
98-
{
99-
provider.sendEvent(event);
100-
}
101-
// No else needed: the current provider has not been chosen - better luck next time
98+
throw new IllegalStateException("Your provider doesn't have a valid PriorityFilter set. Please update your provider implementation.");
10299
}
103-
else
100+
101+
if (provider.getPriorityFilter().shouldLog(event.getPriority()))
104102
{
105-
// no restrictions - send the event to all registered providers
106103
provider.sendEvent(event);
107104
}
105+
// No else needed: the provider doesn't care about logging events of the specified priority
108106
}
109107
}
110108
}
@@ -125,20 +123,18 @@ public void endTimedEvent(@NonNull String eventName) throws IllegalStateExceptio
125123
{
126124
for (AnalyticsKitProvider provider : providers)
127125
{
128-
if (timedEvent.providersMask != 0)
126+
// guard clause
127+
//noinspection ConstantConditions
128+
if (provider.getPriorityFilter() == null)
129129
{
130-
// the user has chosen to restrict the providers to which this event is sent
131-
if ((provider.getType() & timedEvent.providersMask) != 0)
132-
{
133-
provider.endTimedEvent(timedEvent);
134-
}
135-
// No else needed: the current provider has not been chosen - better luck next time
130+
throw new IllegalStateException("Your provider doesn't have a valid PriorityFilter set. Please update your provider implementation.");
136131
}
137-
else
132+
133+
if (provider.getPriorityFilter().shouldLog(timedEvent.getPriority()))
138134
{
139-
// no restrictions - send the event to all registered providers
140135
provider.endTimedEvent(timedEvent);
141136
}
137+
// No else needed: the provider doesn't care about logging events of the specified priority
142138
}
143139
}
144140
}

analyticskit/src/main/java/com/busybusy/analyticskit_android/AnalyticsKitProvider.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@
2929
public interface AnalyticsKitProvider
3030
{
3131
/**
32-
* Returns the type of the provider. This value should be a power of two between 2^0 and 2^30.
33-
* Please use values in the range [2^0 , 2^7] for your own custom provider implementations.
34-
* Some popular providers have already been defined as constants in {@link Providers}.
35-
* @return the specified type mask of the analytics provider.
36-
* @see Providers
32+
* Returns the filter used to restrict events by priority
33+
* @return the {@link PriorityFilter} instance the provider is using to determine if an event of a given priority should be logged
3734
*/
38-
int getType();
35+
@NonNull
36+
PriorityFilter getPriorityFilter();
3937

4038
/**
4139
* Sends the event using provider-specific code
@@ -48,4 +46,20 @@ public interface AnalyticsKitProvider
4846
* @param timedEvent the event which has finished
4947
*/
5048
void endTimedEvent(@NonNull AnalyticsEvent timedEvent);
49+
50+
/**
51+
* Defines the 'callback' interface providers will use to determine
52+
* how to handle events of various priorities.
53+
*/
54+
interface PriorityFilter
55+
{
56+
/**
57+
* Determines if a provider should log an event with a given priority
58+
* @param priorityLevel the priority value from an {@link AnalyticsEvent} object
59+
* (Generally {@link AnalyticsEvent#getPriority()})
60+
* @return {@code true} if the event should be logged by the provider.
61+
* Returns {@code false} otherwise.
62+
*/
63+
boolean shouldLog(int priorityLevel);
64+
}
5165
}

analyticskit/src/main/java/com/busybusy/analyticskit_android/CommonEvents.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
*/
2525
public interface CommonEvents
2626
{
27-
String CONTENT_VIEW = "Content View";
27+
String CONTENT_VIEW = "Content View";
28+
String ERROR = "Error";
2829
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 2016 Busy, LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.busybusy.analyticskit_android;
18+
19+
import android.support.annotation.NonNull;
20+
import android.support.annotation.Nullable;
21+
22+
/**
23+
* Defines information that is needed to distribute an "Error" event to the registered analytics providers.
24+
* @author John Hunt on 4/6/16.
25+
*/
26+
public class ErrorEvent extends AnalyticsEvent
27+
{
28+
public final String ERROR_MESSAGE = "error_message";
29+
public final String EXCEPTION_OBJECT = "exception_object";
30+
public final String ERROR_OBJECT = "error_object";
31+
32+
/**
33+
* Initializes a new {@code ErrorEvent} object.
34+
*/
35+
public ErrorEvent()
36+
{
37+
super(CommonEvents.ERROR);
38+
}
39+
40+
/**
41+
* Initializes a new {@code ErrorEvent} object.
42+
* @param eventName the name of the {@code ErrorEvent}
43+
*/
44+
public ErrorEvent(@NonNull String eventName)
45+
{
46+
super(eventName);
47+
}
48+
49+
/**
50+
* Sets an error message on the {@code ErrorEvent}
51+
* @param errorMessage the message to set
52+
* @return the {@code ErrorEvent} instance (for builder-style convenience)
53+
*/
54+
public ErrorEvent setMessage(@NonNull String errorMessage)
55+
{
56+
putAttribute(ERROR_MESSAGE, errorMessage);
57+
return this;
58+
}
59+
60+
/**
61+
* Access the error message
62+
*
63+
* @return the error message set on this event. Returns {@code null} if the message was not set.
64+
*/
65+
@Nullable
66+
public String message()
67+
{
68+
Object value = attributes != null ? attributes.get(ERROR_MESSAGE) : null;
69+
return value != null ? String.valueOf(value) : null;
70+
}
71+
72+
/**
73+
* Sets an {@code Exception} object to associate with this event
74+
* @param exception the Exception object to store
75+
* @return the {@code ErrorEvent} instance (for builder-style convenience)
76+
*/
77+
public ErrorEvent setException(@NonNull Exception exception)
78+
{
79+
putAttribute(EXCEPTION_OBJECT, exception);
80+
return this;
81+
}
82+
83+
/**
84+
* Access the {@link Exception} object
85+
*
86+
* @return the {@code Exception} set on this event. Returns {@code null} if the exception was not set.
87+
*/
88+
@Nullable
89+
public Exception exception()
90+
{
91+
Object value = attributes != null ? attributes.get(EXCEPTION_OBJECT) : null;
92+
return value != null ? (Exception) value : null;
93+
}
94+
95+
/**
96+
* Sets an {@code Error} object to associate with this event
97+
* @param error the Error object to store
98+
* @return the {@code ErrorEvent} instance (for builder-style convenience)
99+
*/
100+
public ErrorEvent setError(@NonNull Error error)
101+
{
102+
putAttribute(ERROR_OBJECT, error);
103+
return this;
104+
}
105+
106+
/**
107+
* Access the {@link Error} object
108+
*
109+
* @return the {@code Error} set on this event. Returns {@code null} if the error was not set.
110+
*/
111+
@Nullable
112+
public Error error()
113+
{
114+
Object value = attributes != null ? attributes.get(ERROR_OBJECT) : null;
115+
return value != null ? (Error) value : null;
116+
}
117+
}

0 commit comments

Comments
 (0)