All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.eg.agent.android.analytics.BaseController Maven / Gradle / Ivy

The newest version!
package com.eg.agent.android.analytics;



import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.json.JSONException;
import org.json.JSONObject;

import com.eg.agent.android.gestures.GestureReporter;
import com.eg.agent.android.harvest.DataReaper;
import com.eg.agent.android.harvest.HttpData;
import com.eg.agent.android.harvest.ReapData;
import com.eg.agent.android.harvest.Reaper;
import com.eg.agent.android.harvest.ReaperAdapter;
import com.eg.agent.android.harvest.ReaperLifecycle;
import com.eg.agent.android.logging.EGAgentLog;
import com.eg.agent.android.logging.EGAgentLogManager;
import com.eg.agent.android.BaseAndroidAgent;
import com.eg.agent.android.DeviceData;
import com.eg.agent.android.EGAgentConfig;
import com.eg.agent.android.Features;
import com.eg.agent.android.Queue;
import com.eg.agent.android.trace.ActivityTracer;
import com.eg.agent.android.trace.TracerLifecycle;
import com.eg.agent.android.trace.TracerMachine;

public class BaseController extends ReaperAdapter implements Controller {
    
    private static final String EG_PREFIX = "eg.";
    private static final String EGURKHA_PREFIX = "eGurkha";
    private static final AtomicBoolean initialized = new AtomicBoolean(false);
    private static final BaseController instance = new BaseController();
    static final EGAgentLog log = EGAgentLogManager.getAgentLog();
    private static final List reservedNames = new ArrayList();
    private EGAgentConfig agentConfiguration;
    private BaseAndroidAgent agentImpl;
    private BaseEventManager eventManager = new BaseEventManager();
    private AtomicBoolean isEnabled;
    private InteractionCompleteListener listener = new InteractionCompleteListener();
    private Set systemAttributes = Collections.synchronizedSet(new HashSet());
    private Set userAttributes = Collections.synchronizedSet(new HashSet());

    class InteractionCompleteListener implements TracerLifecycle {
        InteractionCompleteListener() {
        }

        public void onEnterMethod() {
        }

        public void onExitMethod() {
        }

        public void onTraceStart(ActivityTracer activityTrace) {
        }

        public void onTraceComplete(ActivityTracer activityTrace) {
            BaseController.log.verbose("BaseController.InteractionCompleteListener.onTraceComplete invoke.");
            BaseController.getInstance().addEvent(createTraceEvent(activityTrace));
        }

        private Event createTraceEvent(ActivityTracer activityTrace) {
            float durationInSec = activityTrace.rootTrace.getDurationAsSeconds();
            Set attrs = new HashSet();
            attrs.add(new Attributes(Attributes.INTERACTION_DURATION_ATTRIBUTE, durationInSec));
            return EventsFactory.createEvent(activityTrace.rootTrace.displayName, EventCategory.Interaction, Attributes.EVENT_TYPE_ATTRIBUTE_MOBILE, attrs);
        }

		@Override
		public void onTraceRename(ActivityTracer var1) {
			// TODO Auto-generated method stub
			
		}
    }

    public static void initialize(EGAgentConfig agentConfiguration, BaseAndroidAgent agentImpl) {
        log.debug("BaseController.initialize.::initialized::"+initialized.get());
        if (initialized.compareAndSet(false, true)) {
            instance.clear();
            reservedNames.add(Attributes.EVENT_TYPE_ATTRIBUTE);
            reservedNames.add(Attributes.TYPE_ATTRIBUTE);
            reservedNames.add(Attributes.EVENT_TIMESTAMP_ATTRIBUTE);
            reservedNames.add(Attributes.EVENT_CATEGORY_ATTRIBUTE);
            reservedNames.add(Attributes.ACCOUNT_ID_ATTRIBUTE);
            reservedNames.add(Attributes.APP_ID_ATTRIBUTE);
            reservedNames.add(Attributes.APP_NAME_ATTRIBUTE);
            reservedNames.add(Attributes.UUID_ATTRIBUTE);
//            reservedNames.add(Attributes.SESSION_ID_ATTRIBUTE);
            reservedNames.add(Attributes.OS_NAME_ATTRIBUTE);
            reservedNames.add(Attributes.OS_VERSION_ATTRIBUTE);
            reservedNames.add(Attributes.OS_MAJOR_VERSION_ATTRIBUTE);
            reservedNames.add(Attributes.DEVICE_MANUFACTURER_ATTRIBUTE);
            reservedNames.add(Attributes.DEVICE_MODEL_ATTRIBUTE);
            reservedNames.add(Attributes.MEM_USAGE_MB_ATTRIBUTE);
            reservedNames.add(Attributes.CARRIER_ATTRIBUTE);
            reservedNames.add(Attributes.EG_VERSION_ATTRIBUTE);
            reservedNames.add(Attributes.INTERACTION_DURATION_ATTRIBUTE);
            reservedNames.add(Attributes.APP_INSTALL_ATTRIBUTE);
            reservedNames.add(Attributes.APP_UPGRADE_ATTRIBUTE);
            reservedNames.add(Attributes.APPLICATION_PLATFORM_ATTRIBUTE);
            reservedNames.add(Attributes.APPLICATION_PLATFORM_VERSION_ATTRIBUTE);
            reservedNames.add("osBuild");
            reservedNames.add("runTime");
            reservedNames.add("architecture");
            reservedNames.add("appBuild");
            
            instance.reinitialize(agentConfiguration, agentImpl);
            TracerMachine.addTraceListener(instance.listener);
            DataReaper.addHarvestListener((ReaperLifecycle)instance);
            //log.info("Analytics Controller started.");
            return;
        }
        log.verbose("BaseController has already been initialized.  Bypassing..");
    }

    public static void shutdown() {
        TracerMachine.removeTraceListener(instance.listener);
        initialized.compareAndSet(true, false);
        instance.getEventManager().shutdown();
    }

    private BaseController() {
    	this.isEnabled = new AtomicBoolean(false);
    }

    void reinitialize(EGAgentConfig agentConfiguration, BaseAndroidAgent agentImpl) {
        String osMajorVersion;
        this.agentImpl = agentImpl;
        this.agentConfiguration = agentConfiguration;
        this.eventManager.initialize();
        this.isEnabled.set(agentConfiguration.getEnableAnalyticsEvents());
        loadPersistentAttributes();
        DeviceData deviceInformation = agentImpl.getDeviceInformation();
        String osVersion = deviceInformation.getOsVersion().replace(" ", "");
        String[] osMajorVersionArr = osVersion.split("[.:-]");
        if (osMajorVersionArr.length > 0) {
            osMajorVersion = osMajorVersionArr[0];
        } else {
            osMajorVersion = osVersion;
        }
        this.systemAttributes.add(new Attributes(Attributes.OS_NAME_ATTRIBUTE, deviceInformation.getOsName()));
        this.systemAttributes.add(new Attributes(Attributes.OS_VERSION_ATTRIBUTE, osVersion));
        this.systemAttributes.add(new Attributes(Attributes.OS_MAJOR_VERSION_ATTRIBUTE, osMajorVersion));
        this.systemAttributes.add(new Attributes(Attributes.DEVICE_MANUFACTURER_ATTRIBUTE, deviceInformation.getManufacturer()));
        this.systemAttributes.add(new Attributes(Attributes.DEVICE_MODEL_ATTRIBUTE, deviceInformation.getModel()));
        this.systemAttributes.add(new Attributes(Attributes.UUID_ATTRIBUTE, deviceInformation.getDeviceId()));
        this.systemAttributes.add(new Attributes(Attributes.CARRIER_ATTRIBUTE, agentImpl.getNetworkCarrier()));
        this.systemAttributes.add(new Attributes(Attributes.EG_VERSION_ATTRIBUTE, deviceInformation.getAgentVersion()));
//        this.systemAttributes.add(new Attributes(Attributes.SESSION_ID_ATTRIBUTE, agentConfiguration.getSessionID()));
        this.systemAttributes.add(new Attributes(Attributes.APPLICATION_PLATFORM_ATTRIBUTE, agentConfiguration.getApplicationPlatform().toString()));
        this.systemAttributes.add(new Attributes(Attributes.APPLICATION_PLATFORM_VERSION_ATTRIBUTE, agentConfiguration.getApplicationPlatformVersion()));
    }

    public Attributes getAttribute(String name) {
        //log.verbose("BaseController.getAttribute - retrieving " + name);
        Attributes attribute = getUserAttribute(name);
        if (attribute == null) {
            return getSystemAttribute(name);
        }
        return attribute;
    }

    public Set getSystemAttributes() {
        Set attrs = new HashSet(this.systemAttributes.size());
        for (Attributes attr : this.systemAttributes) {
            attrs.add(new Attributes(attr));
        }
        return Collections.unmodifiableSet(attrs);
    }

    public Set getUserAttributes() {
//        Set attrs = new HashSet(this.userAttributes.size());
//        for (Attributes attr : this.userAttributes) {
//            attrs.add(new Attributes(attr));
//        }
    	log.debug("BaseController::getUserAttributes:::userAttributes:::"+userAttributes);
        return Collections.unmodifiableSet(this.userAttributes);
    }

    public Set getSessionAttributes() {
        Set attrs = new HashSet();
        attrs.addAll(getSystemAttributes());
        attrs.addAll(getUserAttributes());
        return Collections.unmodifiableSet(attrs);
    }

    public int getSystemAttributeCount() {
        return this.systemAttributes.size();
    }

    public int getUserAttributeCount() {
        return this.userAttributes.size();
    }

    public int getSessionAttributeCount() {
        return this.systemAttributes.size() + this.userAttributes.size();
    }

    public boolean setAttribute(String name, String value) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value);
        return setAttribute(name, value, true);
    }

    public boolean setAttribute(String name, String value, boolean persistent) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
        if (!isInitializedAndEnabled() || !isAttributeNameValid(name) || !isStringValueValid(name, value)) {
            return false;
        }
        Attributes attribute = getAttribute(name);
        boolean stored;
        if (attribute != null) {
            attribute.setStringValue(value);
            attribute.setPersistent(persistent);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            } else {
            	this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
            }
            
        } else if (this.userAttributes.size() < 64) {
            attribute = new Attributes(name, value, persistent);
            this.userAttributes.add(attribute);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            }
        } else {
            //log.warning("Attribute limit exceeded: at most 64 are allowed.");
            //log.warning("Currently defined attributes:");
            for (Attributes attr : this.userAttributes) {
                log.warning("\t" + attr.getName() + ": " + attr.valueAsString());
            }
        }
        return true;
    }

    public boolean setAttribute(String name, float value) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value);
        return setAttribute(name, value, true);
    }

    public boolean setAttribute(String name, float value, boolean persistent) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
        if (!isInitializedAndEnabled() || !isAttributeNameValid(name)) {
            return false;
        }
        Attributes attribute = getAttribute(name);
        boolean stored;
        if (attribute != null) {
            attribute.setFloatValue(value);
            attribute.setPersistent(persistent);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            } else {
            	this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
            }
        } else if (this.userAttributes.size() < 64) {
            attribute = new Attributes(name, value, persistent);
            this.userAttributes.add(attribute);
            if (attribute.isPersistent()) {
                this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            }
        } else {
            //log.warning("Attribute limit exceeded: at most 64 are allowed.");
            //log.warning("Currently defined attributes:");
            for (Attributes attr : this.userAttributes) {
                //log.warning("\t" + attr.getName() + ": " + attr.valueAsString());
            }
        }
        return true;
    }

    public boolean setAttribute(String name, boolean value) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value);
        return setAttribute(name, value, true);
    }

    public boolean setAttribute(String name, boolean value, boolean persistent) {
        log.verbose("BaseController.setAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
        if (!isInitializedAndEnabled() || !isAttributeNameValid(name)) {
            return false;
        }
        Attributes attribute = getAttribute(name);
        boolean stored;
        if (attribute != null) {
            attribute.setBooleanValue(value);
            attribute.setPersistent(persistent);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            } else {
            	this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
            }
        } else if (this.userAttributes.size() < 64) {
            attribute = new Attributes(name, value, persistent);
            this.userAttributes.add(attribute);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            }
        } else {
            //log.warning("Attribute limit exceeded: at most 64 are allowed.");
            //log.warning("Currently defined attributes:");
            for (Attributes attr : this.userAttributes) {
              //  log.warning("\t" + attr.getName() + ": " + attr.valueAsString());
            }
        }
        return true;
    }
    
    public boolean setAttribute(String name, double value) {
        log.debug("BaseController.setAttribute - " + name + ": " + value);
        return setAttribute(name, value, true);
      }
      
      public boolean setAttribute(String name, double value, boolean persistent) {
        log.debug("BaseController.setAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
        if (!isInitializedAndEnabled())
          return false; 
        if (!isAttributeNameValid(name))
          return false; 
        Attributes attribute = getAttribute(name);
        log.debug("BaseController.setAttribute::attribute::"+attribute);
        if (attribute == null) {
        	attribute = new Attributes(name, value, persistent);
            this.userAttributes.add(attribute);
        } else {
        	 attribute.setDoubleValue(value);
             attribute.setPersistent(persistent);
        }
        log.debug("BaseController.setAttribute::userAttributes::"+userAttributes);
       
        if (attribute.isPersistent()) {
          if (!this.agentConfiguration.getAnalyticAttributeStore().store(attribute)) {
            log.error("Failed to store attribute " + attribute + " to attribute store.");
            return false;
          } 
        } else {
        	this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
        } 
        return true;
      }

      
      public boolean incrementAttribute(String name, double value) {
    	    log.debug("BaseController.incrementAttribute - " + name + ": " + value);
    	    return incrementAttribute(name, value, true);
    	  }
    	  
    	  public boolean incrementAttribute(String name, double value, boolean persistent) {
    	    log.debug("BaseController.incrementAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
    	    if (!isInitializedAndEnabled())
    	      return false; 
    	    if (!isAttributeNameValid(name))
    	      return false; 
    	    Attributes attribute = getAttribute(name);
    	    if (attribute != null && attribute.isDoubleAttribute()) {
    	      attribute.setDoubleValue(attribute.getDoubleValue() + value);
    	      attribute.setPersistent(persistent);
    	      if (attribute.isPersistent() && 
    	        !this.agentConfiguration.getAnalyticAttributeStore().store(attribute)) {
    	        log.error("Failed to store attribute " + attribute + " to attribute store.");
    	        return false;
    	      } 
    	    } else {
    	    	if (attribute == null) {
    	    		addNewUserAttribute(new Attributes(name, value, persistent));
//    	            this.userAttributes.add(attribute);
    	        }
    	      log.warning("Cannot increment attribute " + name + ": the attribute is already defined as a non-float value.");
    	      return false;
    	    } 
    	    return true;
    	  }
      
    	  private boolean addNewUserAttribute(Attributes attribute) {
    		    if (this.userAttributes.size() < 128) {
    		      this.userAttributes.add(attribute);
    		      if (attribute.isPersistent() && 
    		        !this.agentConfiguration.getAnalyticAttributeStore().store(attribute)) {
    		        log.error("Failed to store attribute " + attribute + " to attribute store.");
    		        return false;
    		      } 
    		    } else {
    		      log.warning("Attribute limit exceeded: at most 128 are allowed.");
    		      log.debug("Currently defined attributes:");
    		      for (Attributes attr : this.userAttributes)
    		        log.debug("\t" + attr.getName() + ": " + attr.valueAsString()); 
    		    } 
    		    return true;
    		  }
    	  
    public boolean addAttributeUnchecked(Attributes attribute, boolean persistent) {
        String name = attribute.getName();
        //log.verbose("BaseController.setAttributeUnchecked - " + name + ": " + attribute.valueAsString() + (persistent ? " (persistent)" : " (transient)"));
        if (!initialized.get()) {
            log.warning("Analytics controller is not initialized!");
            return false;
        } else if (!this.isEnabled.get()) {
            log.warning("Analytics controller is not enabled!");
            return false;
        } else if (!isNameValid(name)) {
            return false;
        } else {
            Attributes foundAttribute = getAttribute(attribute.getName());
            boolean stored;
            if (foundAttribute == null) {
                this.userAttributes.add(attribute);
                if (attribute.isPersistent()) {
                    this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                    stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                    if (!stored) {
                        log.error("Failed to store attribute " + attribute + " to attribute store.");
                        return stored;
                    }
                }
            }
            switch (attribute.getAttributeDataType()) {
                case STRING:
                    foundAttribute.setStringValue(attribute.getStringValue());
                    break;
                case FLOAT:
                    foundAttribute.setFloatValue(attribute.getFloatValue());
                    break;
                case BOOLEAN:
                    foundAttribute.setBooleanValue(attribute.getBooleanValue());
                    break;
            }
            foundAttribute.setPersistent(persistent);
            if (foundAttribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(foundAttribute);
                if (!stored) {
                    log.error("Failed to store attribute " + foundAttribute + " to attribute store.");
                    return stored;
                }
            }
            this.agentConfiguration.getAnalyticAttributeStore().delete(foundAttribute);
            return true;
        }
    }

    public boolean incrementAttribute(String name, float value) {
        //log.verbose("BaseController.incrementAttribute - " + name + ": " + value);
        return incrementAttribute(name, value, true);
    }

    public boolean incrementAttribute(String name, float value, boolean persistent) {
        //log.verbose("BaseController.incrementAttribute - " + name + ": " + value + (persistent ? " (persistent)" : " (transient)"));
        if (!isInitializedAndEnabled() || !isAttributeNameValid(name)) {
            return false;
        }
        Attributes attribute = getAttribute(name);
        boolean stored;
        if (attribute != null && attribute.isFloatAttribute()) {
            attribute.setFloatValue(attribute.getFloatValue() + value);
            attribute.setPersistent(persistent);
            if (attribute.isPersistent()) {
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            }
        } else if (attribute != null) {
            log.warning("Cannot increment attribute " + name + ": the attribute is already defined as a non-float value.");
            return false;
        } else if (this.userAttributes.size() < 64) {
            attribute = new Attributes(name, value, persistent);
            this.userAttributes.add(attribute);
            if (attribute.isPersistent()) {
                this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                stored = this.agentConfiguration.getAnalyticAttributeStore().store(attribute);
                if (!stored) {
                    log.error("Failed to store attribute " + attribute + " to attribute store.");
                    return stored;
                }
            }
            this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
        }
        return true;
    }

    public boolean removeAttribute(String name) {
        //log.verbose("BaseController.removeAttribute - " + name);
        if (!isInitializedAndEnabled()) {
            return false;
        }
        Attributes attribute = getAttribute(name);
        if (attribute != null) {
            this.userAttributes.remove(attribute);
            if (attribute.isPersistent()) {
                this.agentConfiguration.getAnalyticAttributeStore().delete(attribute);
            }
        }
        return true;
    }

    public boolean removeAllAttributes() {
        //log.verbose("BaseController.removeAttributes - ");
        if (isInitializedAndEnabled()) {
            this.agentConfiguration.getAnalyticAttributeStore().clear();
            this.userAttributes.clear();
        }
        return false;
    }

    public boolean addEvent(String name, Set eventAttributes) {
        return addEvent(name, EventCategory.Custom, Attributes.EVENT_TYPE_ATTRIBUTE_MOBILE, eventAttributes);
    }

    public boolean addEvent(String name, EventCategory eventCategory, String eventType, Set eventAttributes) {
        //log.verbose("BaseController.addEvent - " + name + ": category=" + eventCategory + ", eventType: " + eventType + ", eventAttributes:" + eventAttributes);
        if (!isInitializedAndEnabled()) {
            return false;
        }
        Set validatedAttributes = new HashSet();
        for (Attributes attribute : eventAttributes) {
            if (isAttributeNameValid(attribute.getName())) {
                validatedAttributes.add(attribute);
            }
        }
        return addEvent(EventsFactory.createEvent(name, eventCategory, eventType, validatedAttributes));
    }

    public boolean addEvent(Event event) {
    	log.debug("BaseController::addEvent:::isInitializedAndEnabled:::"+isInitializedAndEnabled());
    	log.debug("BaseController::addEvent:::event:::"+event);
        if (!isInitializedAndEnabled() || event == null) {
            return false;
        }
        Set sessionAttributes = new HashSet();
        long sessionDuration = this.agentImpl.getSessionDurationMillis();
        if (0 == sessionDuration) {
            log.error("Harvest instance is not running! Session duration will be invalid");
        } else {
            sessionAttributes.add(new Attributes("timeSinceLoad", (((float) sessionDuration) / 1000.0f)+" (in Secs)"));
            event.addAttributes(sessionAttributes);
        }
        log.debug("BaseController::addEvent:::eventManager:::"+eventManager);
//        Queue.queue(GestureReporter.getJSONObject(event.getAttributeSet()));
//        return true;
        return this.eventManager.addEvent(event);
    }

    public int getMaxEventPoolSize() {
        return this.eventManager.getMaxEventPoolSize();
    }

    public void setMaxEventPoolSize(int maxSize) {
        this.eventManager.setMaxEventPoolSize(maxSize);
    }

    public void setMaxEventBufferTime(int maxBufferTimeInSec) {
        this.eventManager.setMaxEventBufferTime(maxBufferTimeInSec);
    }

    public int getMaxEventBufferTime() {
        return this.eventManager.getMaxEventBufferTime();
    }

    public EventManager getEventManager() {
        return this.eventManager;
    }

    public static BaseController getInstance() {
        return instance;
    }
    public boolean internalRecordEvent(String name, EventCategory eventCategory, String eventType, Map eventAttributes)
    {
//        log.verbose("BaseController.recordEvent - " + name + ": " + eventAttributes.size() + " attributes");
    	log.info("internalRecordEvent - " + name + ": " + eventAttributes+", Category: "+eventCategory+", type:"+eventType);
    	log.debug("isInitializedAndEnabled:::"+isInitializedAndEnabled());
    	log.debug("this.eventManager.isEventTypeValid("+eventType+") :: "+this.eventManager.isEventTypeValid(eventType));
        if (!isInitializedAndEnabled()) {
            return false;
        }
        if (!this.eventManager.isEventTypeValid(eventType)) {
            return false;
        }
        Set attributes = new HashSet();
        try
        {
            for (String key : eventAttributes.keySet())
            {
                Object value = eventAttributes.get(key);
                Attributes attr = createAttribute(key, value);
                if (attr == null) {
                    continue;
                }
                attributes.add(attr);
            }
        }
        catch (Exception e)
        {
            log.error(String.format("Error occurred while recording event [%s]: ", new Object[] { name }), e);
        }
        log.debug("attributes.isEmpty() "+attributes.isEmpty());
        if(attributes.isEmpty()) {
        	return false;
        }
        return addEvent(name, eventCategory, eventType, attributes, false);
    }

    void loadPersistentAttributes() {
        //log.verbose("BaseController.loadPersistentAttributes - loading userAttributes from the attribute store...");
        List storedAttrs = this.agentConfiguration.getAnalyticAttributeStore() == null? new ArrayList(): this.agentConfiguration.getAnalyticAttributeStore().fetchAll();
        //log.verbose("BaseController.loadPersistentAttributes - found " + storedAttrs.size() + " userAttributes in the attribute store...");
        for (Attributes attr : storedAttrs) {
            this.userAttributes.add(attr);
        }
    }

    private Attributes getSystemAttribute(String name) {
        for (Attributes nextAttribute : this.systemAttributes) {
            if (nextAttribute.getName().equals(name)) {
                return nextAttribute;
            }
        }
        return null;
    }

    private Attributes getUserAttribute(String name) {
        for (Attributes nextAttribute : this.userAttributes) {
            if (nextAttribute.getName().equals(name)) {
                return nextAttribute;
            }
        }
        return null;
    }

    private void clear() {
        //log.verbose("BaseController.clear - clearing out attributes and events");
        this.systemAttributes.clear();
        this.userAttributes.clear();
        this.eventManager.empty();
    }

    private boolean isAttributeNameValid(String name) {
        boolean valid = isNameValid(name);
        if (valid) {
            valid = !isNameReserved(name);
            if (!valid) {
                log.error("Attribute name " + name + " is reserved for internal use and will be ignored.");
            }
        }
        return valid;
    }

    private boolean isNameValid(String name) {
        boolean valid = (name == null || name.equals("") || name.length() >= 256) ? false : true;
        if (!valid) {
            log.error("Attribute name " + name + " is null, empty, or exceeds the maximum length of " + 256 + " characters.");
        }
        return valid;
    }

    private boolean isStringValueValid(String name, String value) {
        boolean valid = (value == null || value.equals("") || value.getBytes().length >= 4096) ? false : true;
        if (!valid) {
            log.error("Attribute value for name " + name + " is null, empty, or exceeds the maximum length of " + 4096 + " bytes.");
        }
        return valid;
    }

    private boolean isNameReserved(String name) {
        boolean isReserved = reservedNames.contains(name);
        if (isReserved) {
            //log.verbose("Name " + name + " is in the reserved names list.");
            return isReserved;
        }
        if (isReserved || name.startsWith(EG_PREFIX)) {
            isReserved = true;
        } else {
            isReserved = false;
        }
        if (isReserved) {
            return isReserved;
        }
        if (isReserved || name.startsWith(EGURKHA_PREFIX)) {
            isReserved = true;
        } else {
            isReserved = false;
        }
        if (isReserved) {
            //log.verbose("Name " + name + " starts with reserved prefix " + EG_PREFIX);
        }
        return isReserved;
    }

    public boolean recordEvent(String name, Map eventAttributes) {
//        log.verbose("BaseController.recordEvent - " + name + ": " + eventAttributes.size() + " attributes");
    	log.info("recordEvent - " + name + ": " + eventAttributes);
        if (!isInitializedAndEnabled()) {
            return false;
        }
        Set attributes = new HashSet();
        try {
            for (String key : eventAttributes.keySet()) {
                Object value = eventAttributes.get(key);
                try {
                    if (value instanceof String) {
                        attributes.add(new Attributes(key, String.valueOf(value)));
                    } else if (value instanceof Float) {
                        attributes.add(new Attributes(key, Float.valueOf(((Float) value).floatValue()).floatValue()));
                    } else if (value instanceof Double) {
                        attributes.add(new Attributes(key, Float.valueOf(((Double) value).floatValue()).floatValue()));
                    } else if (value instanceof Integer) {
                        attributes.add(new Attributes(key, Float.valueOf((float) ((Integer) value).intValue()).floatValue()));
                    } else if (value instanceof Short) {
                        attributes.add(new Attributes(key, Float.valueOf((float) ((Short) value).shortValue()).floatValue()));
                    } else if (value instanceof Long) {
                        attributes.add(new Attributes(key, Float.valueOf((float) ((Long) value).longValue()).floatValue()));
                    } else if (value instanceof BigDecimal) {
                        attributes.add(new Attributes(key, Float.valueOf(((BigDecimal) value).floatValue()).floatValue()));
                    } else if (value instanceof BigInteger) {
                        attributes.add(new Attributes(key, Float.valueOf(((BigInteger) value).floatValue()).floatValue()));
                    } else if (value instanceof Boolean) {
                        attributes.add(new Attributes(key, Boolean.valueOf(((Boolean) value).booleanValue()).booleanValue()));
                    } else {
                        //log.error("Unsupported event attribute type for key [" + key + "]: " + value.getClass().getName());
                        return false;
                    }
                } catch (ClassCastException e) {
                    log.error(String.format("Error casting attribute [%s] to String or Float: ", new Object[]{key}), e);
                }
            }
        } catch (Exception e2) {
            log.error(String.format("Error occurred while recording event [%s]: ", new Object[]{name}), e2);
        }
        return addEvent(name, EventCategory.Custom, Attributes.EVENT_TYPE_ATTRIBUTE_MOBILE, attributes);
    }
    
    public boolean recordCustomEvent(String eventType, Map eventAttributes) {
        try {
          log.debug("BaseController.recordCustomEvent - " + eventType + ": " + eventAttributes.size() + " attributes");
          if (!isInitializedAndEnabled())
            return false; 
          if (this.eventManager.isEventTypeReserved(eventType) || !this.eventManager.isEventTypeValid(eventType))
            return false; 
          String eventName = eventType;
          Set attributes = new HashSet<>();
          for (String key : eventAttributes.keySet()) {
            Object value = eventAttributes.get(key);
            Attributes attr = createAttribute(key, value);
            if (attr != null) {
              if (attr.getName().equals("name")) {
                String name = attr.getStringValue();
                if (name != null && !name.isEmpty())
                  eventName = attr.getStringValue(); 
              } 
              attributes.add(attr);
            } 
          } 
          return addEvent(eventName, EventCategory.Custom, eventType, attributes);
        } catch (Exception e) {
          log.error(String.format("Error occurred while recording custom event [%s]: ", new Object[] { eventType }), e);
          return false;
        } 
      }
      
      public boolean recordBreadcrumb(String name, Map eventAttributes) {
        try {
          if (!isInitializedAndEnabled())
            return false; 
          Set attributes = new HashSet<>();
          for (String key : eventAttributes.keySet()) {
            Object value = eventAttributes.get(key);
            Attributes attr = createAttribute(key, value);
            if (attr != null)
              attributes.add(attr); 
          } 
          return addEvent(name, EventCategory.Breadcrumb, "MobileBreadcrumb", attributes);
        } catch (Exception e) {
          log.error(String.format("Error occurred while recording Breadcrumb event [%s]: ", new Object[] { name }), e);
          return false;
        } 
      }
      
//      public boolean internalRecordEvent(String name, EventCategory eventCategory, String eventType, Map eventAttributes) {
//        try {
//          log.debug("BaseController.recordEvent - " + name + ": " + eventAttributes.size() + " attributes");
//          if (!isInitializedAndEnabled())
//            return false; 
//          if (!this.eventManager.isEventTypeValid(eventType))
//            return false; 
//          Set attributes = new HashSet<>();
//          for (String key : eventAttributes.keySet()) {
//            Object value = eventAttributes.get(key);
//            Attributes attr = createAttribute(key, value);
//            if (attr != null)
//              attributes.add(attr); 
//          } 
//          return addEvent(name, eventCategory, eventType, attributes, false);
//        } catch (Exception e) {
//          log.error(String.format("Error occurred while recording event [%s]: ", new Object[] { name }), e);
//          return false;
//        } 
//      }
      
      public boolean recordEvent(String name, EventCategory eventCategory, String eventType, Map eventAttributes) {
        try {
          log.debug("BaseController.recordEvent - " + name + ": " + eventAttributes.size() + " attributes");
          if (!isInitializedAndEnabled())
            return false; 
          if (!this.eventManager.isEventTypeValid(eventType))
            return false; 
          Set attributes = new HashSet<>();
          for (String key : eventAttributes.keySet()) {
            Object value = eventAttributes.get(key);
            Attributes attr = createAttribute(key, value);
            if (attr != null)
              attributes.add(attr); 
          } 
          return addEvent(name, eventCategory, eventType, attributes);
        } catch (Exception e) {
          log.error(String.format("Error occurred while recording event [%s]: ", new Object[] { name }), e);
          return false;
        } 
      }
      
     
      
      void createHttpErrorEvent(HttpData txn) {
        if (isInitializedAndEnabled())
          NetworkEventController.createHttpErrorEvent(txn); 
      }
      
      void createNetworkFailureEvent(HttpData txn) {
        if (isInitializedAndEnabled())
          NetworkEventController.createNetworkFailureEvent(txn); 
      }
      
      void createNetworkRequestEvent(HttpData txn) {
        if (isInitializedAndEnabled())
          NetworkEventController.createNetworkRequestEvent(txn); 
      }
      
      public void createNetworkRequestEvents(HttpData txn) {
        if (isInitializedAndEnabled())
          if (isHttpError(txn)) {
            NetworkEventController.createHttpErrorEvent(txn);
          } else if (isNetworkFailure(txn)) {
            NetworkEventController.createNetworkFailureEvent(txn);
          } else if (isSuccessfulRequest(txn)) {
            NetworkEventController.createNetworkRequestEvent(txn);
          }  
      }
      
      private boolean isNetworkFailure(HttpData txn) {
        return (txn.getErrorCode() != 0);
      }
      
      private boolean isHttpError(HttpData txn) {
        return (txn.getStatusCode() >= 400L);
      }
      
      private boolean isSuccessfulRequest(HttpData txn) {
        return (txn.getStatusCode() > 0 && txn.getStatusCode() < 400);
      }

    private boolean isInitializedAndEnabled() {
        if (!initialized.get()) {
            log.warning("Analytics controller is not initialized!");
            return false;
        } else if (this.isEnabled.get()) {
            return true;
        } else {
            log.warning("Analytics controller is not enabled!");
            return false;
        }
    }

   

    Attributes createAttribute(String key, Object value)
    {
    	if(value == null) {
    		return null;
    	}
        try
        {
            if ((value instanceof String)) {
                return new Attributes(key, String.valueOf(value));
            }
            if ((value instanceof Float)) {
                return new Attributes(key, Float.valueOf(((Float)value).floatValue()).floatValue());
            }
            if ((value instanceof Double)) {
                return new Attributes(key, Float.valueOf(((Double)value).floatValue()).floatValue());
            }
            if ((value instanceof Integer)) {
                return new Attributes(key, Float.valueOf(((Integer)value).intValue()).floatValue());
            }
            if ((value instanceof Short)) {
                return new Attributes(key, Float.valueOf(((Short)value).shortValue()).floatValue());
            }
            if ((value instanceof Long)) {
                return new Attributes(key, Float.valueOf((float)((Long)value).longValue()).floatValue());
            }
            if ((value instanceof BigDecimal)) {
                return new Attributes(key, Float.valueOf(((BigDecimal)value).floatValue()).floatValue());
            }
            if ((value instanceof BigInteger)) {
                return new Attributes(key, Float.valueOf(((BigInteger)value).floatValue()).floatValue());
            }
            if ((value instanceof Boolean)) {
                return new Attributes(key, Boolean.valueOf(((Boolean)value).booleanValue()).booleanValue());
            }
            if(value instanceof JSONObject) {
            	JSONObject gesture = (JSONObject) value;
            	try {
					gesture.put( "orientation", GestureReporter.getOrientation());
				} catch (JSONException e) {
					log.error("Adding orientation:: "+e.getMessage());
				}
            	return new Attributes(key, gesture.toString());
            }
            log.error("Unsupported event attribute type for key [" + key + "]: " + value.getClass().getName());
            return null;
        }
        catch (ClassCastException e)
        {
            log.error(String.format("Error casting attribute [%s] to String or Float: ", new Object[] { key }), e);
        }
        return null;
    }
    boolean addEvent(String name, EventCategory eventCategory, String eventType, Set eventAttributes, boolean validate)
    {
//        log.verbose("BaseController.addEvent - " + name + ": category=" + eventCategory + ", eventType: " + eventType + ", eventAttributes:" + eventAttributes);
    	log.verbose("BaseController::addEvent - " + name + ": category=" + eventCategory + ", eventType: " + eventType + ", eventAttributes:" + eventAttributes);
    	log.debug("BaseController::addEvent:::isInitializedAndEnabled:::"+isInitializedAndEnabled());
        if (!isInitializedAndEnabled()) {
            return false;
        }
        Set validatedAttributes = new HashSet();
        log.debug("BaseController::addEvent:::validate:::"+validate);
        if (validate) {
            for (Attributes attribute : eventAttributes) {
                if (isAttributeNameValid(attribute.getName())) {
                    validatedAttributes.add(attribute);
                }
            }
        } else {
            for (Attributes attribute : eventAttributes) {
                if (isNameValid(attribute.getName())) {
                    validatedAttributes.add(attribute);
                }
            }
        }
        
        Event event = EventsFactory.createEvent(name, eventCategory, eventType, validatedAttributes);
        log.debug("BaseController::addEvent:::event:::"+event);
        return addEvent(event);
    }
    
    public void onHarvest() {
        ReapData harvestData = DataReaper.getInstance().getHarvestData();
        log.debug("BaseController::onHarvest:::harvestData:::"+harvestData);
        if (harvestData != null) {
        	log.debug("BaseController::onHarvest:::isEnabled.get():::"+this.isEnabled.get());
        	log.debug("BaseController::onHarvest:::Features.featureEnabled(Features.AnalyticsEvents):::"+Features.featureEnabled(Features.AnalyticsEvents));
          harvestData.setAnalyticsEnabled(this.isEnabled.get());
          if (this.isEnabled.get() && Features.featureEnabled(Features.AnalyticsEvents))
        	  log.debug("BaseController::onHarvest:::eventManager.isTransmitRequired():::"+this.eventManager.isTransmitRequired());
          
              Set sessionAttributes = new HashSet<>();
              sessionAttributes.addAll(getSystemAttributes());
              sessionAttributes.addAll(getUserAttributes());
//              for(Object value :BaseAndroidAgent.getInstance().getUserdata().values()) {
//            	  sessionAttributes.add(new Attributes("userData", value.toString()));
//              }
            if (this.eventManager.isTransmitRequired()) {
              harvestData.setSessionAttributes(sessionAttributes);
              Collection pendingEvents = this.eventManager.getQueuedEventsSnapshot();
              if (pendingEvents.size() > 0) {
                harvestData.getAnalyticsEvents().addAll(pendingEvents);
                log.debug("EventManager: [" + pendingEvents.size() + "] events moved from buffer to HarvestData");
              } 
              if (this.eventManager.getQueuedEvents().size() > 0)
                log.error("EventManager: [" + this.eventManager.getQueuedEvents().size() + "] events remain in buffer after hand-off"); 
            }  
        } 
      }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy