com.github.jramos.snowplow.operators.MobileContextExtractionOp.java Source code

Java tutorial

Introduction

Here is the source code for com.github.jramos.snowplow.operators.MobileContextExtractionOp.java

Source

/**
   Portions of this project are copyright Australian Broadcasting Corporation, 2014.
   All other portions are copyright Justin Ramos, 2015.
    
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
    
http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
package com.github.jramos.snowplow.operators;

import com.github.jramos.snowplow.SnowplowDeviceType;
import com.github.jramos.snowplow.SnowplowEventModel;
import com.github.jramos.snowplow.SnowplowPlatform;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This operator applies to mobile platform events only. The mobile context
 * is parsed and mobile specific fields extracted and added to the event record
 * 
 * A sample context is:
 * 
 * {
   "schema":"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0",
   "data":[ "data":["http://ab.co/1F7MPCB",
        {"schema":"iglu:com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-0",
         "data":{
            "osType":"ios",
            "deviceManufacturer":"Apple Inc.",
            "carrier":"Telstra",
            "deviceModel":"iPhone",
            "osVersion":"8.1.2",
            "appleIdfv":"5AFCF290-516C-4F78-A2A5-F9CA858595A1",
            "appleIdfa":"1E047562-3A79-4510-9FAF-6D8B4C385594"
          }
       }
]
}
* 
 * @author Sam Mason (sam.mason@abc.net.au)
 */

public class MobileContextExtractionOp implements ISnowplowEventOperator {

    private static final Log LOG = LogFactory.getLog(MobileContextExtractionOp.class);

    private static final String JSON_SCHEMA = "schema";
    private static final String SCHEMA_TAG = "mobile_context";

    private static final String TABLET_DETECTION_IOS = "iPad";
    //private static final String TABLET_DETECTION_ANDROID    = "TBD";

    private static final String JSON_DATA = "data";
    private static final String JSON_OS_TYPE = "osType";
    private static final String JSON_DEVICE_MANUFACTURER = "deviceManufacturer";
    private static final String JSON_DEVICE_MODEL = "deviceModel";
    private static final String JSON_OS_VERSION = "osVersion";
    private static final String JSON_OPEN_IDFA = "openIdfa";

    private final JsonParser parser;
    private final StringBuilder osNameBuffer;

    public MobileContextExtractionOp() {
        parser = new JsonParser();
        osNameBuffer = new StringBuilder();
    }

    @Override
    public SnowplowEventModel apply(SnowplowEventModel event) {
        String context = event.getContexts();
        try {
            String platform = event.getPlatform();
            if (platform.equals(SnowplowPlatform.Mobile.toString())) {

                // minimal tablet vs mobile detection
                if (isTablet(event.getUseragent())) {
                    event.setDvce_type(SnowplowDeviceType.Tablet.toString());
                    event.setDvce_ismobile(Boolean.FALSE);
                } else {
                    event.setDvce_type(SnowplowDeviceType.Mobile.toString());
                    event.setDvce_ismobile(Boolean.TRUE);
                }

                JsonObject rootObj = parser.parse(context).getAsJsonObject();
                if (rootObj.has(JSON_DATA)) {
                    JsonArray dataArray = rootObj.getAsJsonArray(JSON_DATA);

                    // find the correct object by matching on the schema
                    JsonObject mobileContextObject = null;
                    for (int i = 0; i < dataArray.size(); i++) {
                        JsonElement element = dataArray.get(i);
                        if (element.isJsonObject()) {
                            JsonObject jsonObject = element.getAsJsonObject();
                            if (jsonObject.has(JSON_SCHEMA)) {
                                String schema = jsonObject.getAsJsonPrimitive(JSON_SCHEMA).getAsString();
                                if (schema.contains(SCHEMA_TAG)) {
                                    mobileContextObject = jsonObject;
                                    break;
                                }
                            }
                        }
                    }

                    // parse out the mobile fields we want
                    if (mobileContextObject != null && mobileContextObject.has(JSON_DATA)) {
                        JsonObject dataObject = mobileContextObject.getAsJsonObject(JSON_DATA);

                        if (dataObject.has(JSON_OPEN_IDFA)) {
                            // use as cross device user id - i.e network user id
                            String openIDFA = dataObject.getAsJsonPrimitive(JSON_OPEN_IDFA).getAsString();
                            event.setNetwork_userid(openIDFA);
                        }

                        String deviceManufacturer = dataObject.getAsJsonPrimitive(JSON_DEVICE_MANUFACTURER)
                                .getAsString();
                        event.setOs_manufacturer(deviceManufacturer);

                        String osType = dataObject.getAsJsonPrimitive(JSON_OS_TYPE).getAsString();
                        event.setOs_family(osType);

                        String osVersion = dataObject.getAsJsonPrimitive(JSON_OS_VERSION).getAsString();
                        String deviceModel = dataObject.getAsJsonPrimitive(JSON_DEVICE_MODEL).getAsString();

                        osNameBuffer.setLength(0);
                        osNameBuffer.append(osType).append(" ").append(osVersion);
                        if (deviceModel != null && deviceModel.trim().length() > 0) {
                            osNameBuffer.append(" (").append(deviceModel.trim()).append(")");
                        }
                        event.setOs_name(osNameBuffer.toString());
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("Exception applying operator to mobile context " + context, e);
        }
        return event;
    }

    ////////////////////////////////////////////////////////////////////////////

    private boolean isTablet(String userAgent) {
        if (userAgent == null) {
            return false;
        } else if (userAgent.contains(TABLET_DETECTION_IOS)) {
            return true;
        }
        // TODO
        //        else if(userAgent.contains(TABLET_DETECTION_ANDROID)){
        //            return true;
        //        } 
        else {
            return false;
        }
    }

    public static void main(String[] args) {
        MobileContextExtractionOp meop = new MobileContextExtractionOp();
        meop.testiOSContext();
    }

    private void testiOSContext() {

        String json = "{'schema':'iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0',";
        json += "'data':['http://ab.co/1F7MPCB', {'schema':'iglu:com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-0',";
        json += "'data':{'deviceManufacturer':'Apple Inc.','osVersion':'8.3','osType':'ios','deviceModel':'iPhone','carrier':'OPTUS',";
        json += "'openIdfa':'2442F29E-9062-16AC-B31F-FD6E78275848'}}]}";

        SnowplowEventModel event = new SnowplowEventModel();
        event.setContexts(json);

        event.setPlatform(SnowplowPlatform.Mobile.toString());
        event.setUseragent("ios");

        event = apply(event);

        System.out.println("DvceType : " + event.getDvce_type());
        System.out.println("DvceIsMobile : " + event.isDvce_ismobile());
        System.out.println("NetUid : " + event.getNetwork_userid());
        System.out.println("Manufacturer : " + event.getOs_manufacturer());
        System.out.println("Os Family : " + event.getOs_family());
        System.out.println("Os Name : " + event.getOs_name());
    }

}