2020import com .optimizely .ab .bucketing .DecisionService ;
2121import com .optimizely .ab .bucketing .FeatureDecision ;
2222import com .optimizely .ab .bucketing .UserProfileService ;
23- import com .optimizely .ab .config .*;
23+ import com .optimizely .ab .config .AtomicProjectConfigManager ;
24+ import com .optimizely .ab .config .DatafileProjectConfig ;
25+ import com .optimizely .ab .config .EventType ;
26+ import com .optimizely .ab .config .Experiment ;
27+ import com .optimizely .ab .config .FeatureFlag ;
28+ import com .optimizely .ab .config .FeatureVariable ;
29+ import com .optimizely .ab .config .FeatureVariableUsageInstance ;
30+ import com .optimizely .ab .config .ProjectConfig ;
31+ import com .optimizely .ab .config .ProjectConfigManager ;
32+ import com .optimizely .ab .config .Variation ;
2433import com .optimizely .ab .config .parser .ConfigParseException ;
2534import com .optimizely .ab .error .ErrorHandler ;
2635import com .optimizely .ab .error .NoOpErrorHandler ;
27- import com .optimizely .ab .event .*;
28- import com .optimizely .ab .event .internal .*;
36+ import com .optimizely .ab .event .EventHandler ;
37+ import com .optimizely .ab .event .EventProcessor ;
38+ import com .optimizely .ab .event .ForwardingEventProcessor ;
39+ import com .optimizely .ab .event .LogEvent ;
40+ import com .optimizely .ab .event .NoopEventHandler ;
41+ import com .optimizely .ab .event .internal .BuildVersionInfo ;
42+ import com .optimizely .ab .event .internal .ClientEngineInfo ;
43+ import com .optimizely .ab .event .internal .EventFactory ;
44+ import com .optimizely .ab .event .internal .UserEvent ;
45+ import com .optimizely .ab .event .internal .UserEventFactory ;
2946import com .optimizely .ab .event .internal .payload .EventBatch ;
3047import com .optimizely .ab .internal .NotificationRegistry ;
31- import com .optimizely .ab .notification .*;
32- import com .optimizely .ab .odp .*;
48+ import com .optimizely .ab .notification .ActivateNotification ;
49+ import com .optimizely .ab .notification .DecisionNotification ;
50+ import com .optimizely .ab .notification .FeatureTestSourceInfo ;
51+ import com .optimizely .ab .notification .NotificationCenter ;
52+ import com .optimizely .ab .notification .NotificationHandler ;
53+ import com .optimizely .ab .notification .RolloutSourceInfo ;
54+ import com .optimizely .ab .notification .SourceInfo ;
55+ import com .optimizely .ab .notification .TrackNotification ;
56+ import com .optimizely .ab .notification .UpdateConfigNotification ;
57+ import com .optimizely .ab .odp .ODPEvent ;
58+ import com .optimizely .ab .odp .ODPManager ;
59+ import com .optimizely .ab .odp .ODPSegmentManager ;
60+ import com .optimizely .ab .odp .ODPSegmentOption ;
3361import com .optimizely .ab .optimizelyconfig .OptimizelyConfig ;
3462import com .optimizely .ab .optimizelyconfig .OptimizelyConfigManager ;
3563import com .optimizely .ab .optimizelyconfig .OptimizelyConfigService ;
36- import com .optimizely .ab .optimizelydecision .*;
64+ import com .optimizely .ab .optimizelydecision .DecisionMessage ;
65+ import com .optimizely .ab .optimizelydecision .DecisionReasons ;
66+ import com .optimizely .ab .optimizelydecision .DecisionResponse ;
67+ import com .optimizely .ab .optimizelydecision .DefaultDecisionReasons ;
68+ import com .optimizely .ab .optimizelydecision .OptimizelyDecideOption ;
69+ import com .optimizely .ab .optimizelydecision .OptimizelyDecision ;
3770import com .optimizely .ab .optimizelyjson .OptimizelyJSON ;
38- import java .util .concurrent .locks .ReentrantLock ;
3971import org .slf4j .Logger ;
4072import org .slf4j .LoggerFactory ;
4173
4274import javax .annotation .Nonnull ;
4375import javax .annotation .Nullable ;
4476import javax .annotation .concurrent .ThreadSafe ;
45-
4677import java .io .Closeable ;
47- import java .util .*;
48- import java .util .stream .Collectors ;
78+ import java .util .ArrayList ;
79+ import java .util .Arrays ;
80+ import java .util .Collections ;
81+ import java .util .HashMap ;
82+ import java .util .List ;
83+ import java .util .Map ;
84+ import java .util .concurrent .locks .ReentrantLock ;
4985
5086import static com .optimizely .ab .internal .SafetyUtils .tryClose ;
5187
5288/**
5389 * Top-level container class for Optimizely functionality.
5490 * Thread-safe, so can be created as a singleton and safely passed around.
55- *
91+ * <p>
5692 * Example instantiation:
5793 * <pre>
5894 * Optimizely optimizely = Optimizely.builder(projectWatcher, eventHandler).build();
5995 * </pre>
60- *
96+ * <p>
6197 * To activate an experiment and perform variation specific processing:
6298 * <pre>
6399 * Variation variation = optimizely.activate(experimentKey, userId, attributes);
@@ -136,7 +172,9 @@ private Optimizely(@Nonnull EventHandler eventHandler,
136172 if (projectConfigManager .getSDKKey () != null ) {
137173 NotificationRegistry .getInternalNotificationCenter (projectConfigManager .getSDKKey ()).
138174 addNotificationHandler (UpdateConfigNotification .class ,
139- configNotification -> { updateODPSettings (); });
175+ configNotification -> {
176+ updateODPSettings ();
177+ });
140178 }
141179
142180 }
@@ -634,6 +672,53 @@ public Integer getFeatureVariableInteger(@Nonnull String featureKey,
634672 return variableValue ;
635673 }
636674
675+ /**
676+ * Get the Long value of the specified variable in the feature.
677+ *
678+ * @param featureKey The unique key of the feature.
679+ * @param variableKey The unique key of the variable.
680+ * @param userId The ID of the user.
681+ * @return The Integer value of the integer single variable feature.
682+ * Null if the feature or variable could not be found.
683+ */
684+ @ Nullable
685+ public Long getFeatureVariableLong (@ Nonnull String featureKey ,
686+ @ Nonnull String variableKey ,
687+ @ Nonnull String userId ) {
688+ return getFeatureVariableLong (featureKey , variableKey , userId , Collections .emptyMap ());
689+ }
690+
691+ /**
692+ * Get the Integer value of the specified variable in the feature.
693+ *
694+ * @param featureKey The unique key of the feature.
695+ * @param variableKey The unique key of the variable.
696+ * @param userId The ID of the user.
697+ * @param attributes The user's attributes.
698+ * @return The Integer value of the integer single variable feature.
699+ * Null if the feature or variable could not be found.
700+ */
701+ @ Nullable
702+ public Long getFeatureVariableLong (@ Nonnull String featureKey ,
703+ @ Nonnull String variableKey ,
704+ @ Nonnull String userId ,
705+ @ Nonnull Map <String , ?> attributes ) {
706+ try {
707+ return getFeatureVariableValueForType (
708+ featureKey ,
709+ variableKey ,
710+ userId ,
711+ attributes ,
712+ FeatureVariable .INTEGER_TYPE
713+ );
714+
715+ } catch (Exception exception ) {
716+ logger .error ("NumberFormatException while trying to parse value as Long. {}" , String .valueOf (exception ));
717+ }
718+
719+ return null ;
720+ }
721+
637722 /**
638723 * Get the String value of the specified variable in the feature.
639724 *
@@ -828,8 +913,13 @@ Object convertStringToType(String variableValue, String type) {
828913 try {
829914 return Integer .parseInt (variableValue );
830915 } catch (NumberFormatException exception ) {
831- logger .error ("NumberFormatException while trying to parse \" " + variableValue +
832- "\" as Integer. " + exception .toString ());
916+ try {
917+ return Long .parseLong (variableValue );
918+ } catch (NumberFormatException longException ) {
919+ logger .error ("NumberFormatException while trying to parse \" {}\" as Integer. {}" ,
920+ variableValue ,
921+ exception .toString ());
922+ }
833923 }
834924 break ;
835925 case FeatureVariable .JSON_TYPE :
@@ -845,11 +935,10 @@ Object convertStringToType(String variableValue, String type) {
845935 /**
846936 * Get the values of all variables in the feature.
847937 *
848- * @param featureKey The unique key of the feature.
849- * @param userId The ID of the user.
938+ * @param featureKey The unique key of the feature.
939+ * @param userId The ID of the user.
850940 * @return An OptimizelyJSON instance for all variable values.
851941 * Null if the feature could not be found.
852- *
853942 */
854943 @ Nullable
855944 public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -860,12 +949,11 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
860949 /**
861950 * Get the values of all variables in the feature.
862951 *
863- * @param featureKey The unique key of the feature.
864- * @param userId The ID of the user.
865- * @param attributes The user's attributes.
952+ * @param featureKey The unique key of the feature.
953+ * @param userId The ID of the user.
954+ * @param attributes The user's attributes.
866955 * @return An OptimizelyJSON instance for all variable values.
867956 * Null if the feature could not be found.
868- *
869957 */
870958 @ Nullable
871959 public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -949,7 +1037,6 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
9491037 * @param attributes The user's attributes.
9501038 * @return List of the feature keys that are enabled for the user if the userId is empty it will
9511039 * return Empty List.
952- *
9531040 */
9541041 public List <String > getEnabledFeatures (@ Nonnull String userId , @ Nonnull Map <String , ?> attributes ) {
9551042 List <String > enabledFeaturesList = new ArrayList ();
@@ -1164,10 +1251,10 @@ public OptimizelyConfig getOptimizelyConfig() {
11641251
11651252 /**
11661253 * Create a context of the user for which decision APIs will be called.
1167- *
1254+ * <p>
11681255 * A user context will be created successfully even when the SDK is not fully configured yet.
11691256 *
1170- * @param userId The user ID to be used for bucketing.
1257+ * @param userId The user ID to be used for bucketing.
11711258 * @param attributes: A map of attribute names to current user attribute values.
11721259 * @return An OptimizelyUserContext associated with this OptimizelyClient.
11731260 */
@@ -1289,15 +1376,15 @@ private OptimizelyDecision createOptimizelyDecision(
12891376 }
12901377
12911378 Map <String , OptimizelyDecision > decideForKeys (@ Nonnull OptimizelyUserContext user ,
1292- @ Nonnull List <String > keys ,
1293- @ Nonnull List <OptimizelyDecideOption > options ) {
1379+ @ Nonnull List <String > keys ,
1380+ @ Nonnull List <OptimizelyDecideOption > options ) {
12941381 return decideForKeys (user , keys , options , false );
12951382 }
12961383
12971384 private Map <String , OptimizelyDecision > decideForKeys (@ Nonnull OptimizelyUserContext user ,
1298- @ Nonnull List <String > keys ,
1299- @ Nonnull List <OptimizelyDecideOption > options ,
1300- boolean ignoreDefaultOptions ) {
1385+ @ Nonnull List <String > keys ,
1386+ @ Nonnull List <OptimizelyDecideOption > options ,
1387+ boolean ignoreDefaultOptions ) {
13011388 Map <String , OptimizelyDecision > decisionMap = new HashMap <>();
13021389
13031390 ProjectConfig projectConfig = getProjectConfig ();
@@ -1308,7 +1395,7 @@ private Map<String, OptimizelyDecision> decideForKeys(@Nonnull OptimizelyUserCon
13081395
13091396 if (keys .isEmpty ()) return decisionMap ;
13101397
1311- List <OptimizelyDecideOption > allOptions = ignoreDefaultOptions ? options : getAllOptions (options );
1398+ List <OptimizelyDecideOption > allOptions = ignoreDefaultOptions ? options : getAllOptions (options );
13121399
13131400 Map <String , FeatureDecision > flagDecisions = new HashMap <>();
13141401 Map <String , DecisionReasons > decisionReasonsMap = new HashMap <>();
@@ -1351,7 +1438,7 @@ private Map<String, OptimizelyDecision> decideForKeys(@Nonnull OptimizelyUserCon
13511438 decisionReasonsMap .get (flagKey ).merge (decision .getReasons ());
13521439 }
13531440
1354- for (String key : validKeys ) {
1441+ for (String key : validKeys ) {
13551442 FeatureDecision flagDecision = flagDecisions .get (key );
13561443 DecisionReasons decisionReasons = decisionReasonsMap .get ((key ));
13571444
@@ -1484,9 +1571,9 @@ public int addLogEventNotificationHandler(NotificationHandler<LogEvent> handler)
14841571 /**
14851572 * Convenience method for adding NotificationHandlers
14861573 *
1487- * @param clazz The class of NotificationHandler
1574+ * @param clazz The class of NotificationHandler
14881575 * @param handler NotificationHandler handler
1489- * @param <T> This is the type parameter
1576+ * @param <T> This is the type parameter
14901577 * @return A handler Id (greater than 0 if succeeded)
14911578 */
14921579 public <T > int addNotificationHandler (Class <T > clazz , NotificationHandler <T > handler ) {
@@ -1535,10 +1622,10 @@ public ODPManager getODPManager() {
15351622 /**
15361623 * Send an event to the ODP server.
15371624 *
1538- * @param type the event type (default = "fullstack").
1539- * @param action the event action name.
1625+ * @param type the event type (default = "fullstack").
1626+ * @param action the event action name.
15401627 * @param identifiers a dictionary for identifiers. The caller must provide at least one key-value pair unless non-empty common identifiers have been set already with {@link ODPManager.Builder#withUserCommonIdentifiers(Map) }.
1541- * @param data a dictionary for associated data. The default event data will be added to this data before sending to the ODP server.
1628+ * @param data a dictionary for associated data. The default event data will be added to this data before sending to the ODP server.
15421629 */
15431630 public void sendODPEvent (@ Nullable String type , @ Nonnull String action , @ Nullable Map <String , String > identifiers , @ Nullable Map <String , Object > data ) {
15441631 ProjectConfig projectConfig = getProjectConfig ();
@@ -1586,7 +1673,7 @@ private void updateODPSettings() {
15861673 * {@link Builder#withDatafile(java.lang.String)} and
15871674 * {@link Builder#withEventHandler(com.optimizely.ab.event.EventHandler)}
15881675 * respectively.
1589- *
1676+ * <p>
15901677 * Example:
15911678 * <pre>
15921679 * Optimizely optimizely = Optimizely.builder()
@@ -1595,7 +1682,7 @@ private void updateODPSettings() {
15951682 * .build();
15961683 * </pre>
15971684 *
1598- * @param datafile A datafile
1685+ * @param datafile A datafile
15991686 * @param eventHandler An EventHandler
16001687 * @return An Optimizely builder
16011688 */
@@ -1644,7 +1731,8 @@ public Builder(@Nonnull String datafile,
16441731 this .datafile = datafile ;
16451732 }
16461733
1647- public Builder () { }
1734+ public Builder () {
1735+ }
16481736
16491737 public Builder withErrorHandler (ErrorHandler errorHandler ) {
16501738 this .errorHandler = errorHandler ;
@@ -1686,7 +1774,7 @@ public Builder withUserProfileService(UserProfileService userProfileService) {
16861774 * Override the SDK name and version (for client SDKs like android-sdk wrapping the core java-sdk) to be included in events.
16871775 *
16881776 * @param clientEngineName the client engine name ("java-sdk", "android-sdk", "flutter-sdk", etc.).
1689- * @param clientVersion the client SDK version.
1777+ * @param clientVersion the client SDK version.
16901778 * @return An Optimizely builder
16911779 */
16921780 public Builder withClientInfo (String clientEngineName , String clientVersion ) {
0 commit comments