<commit_before>package io.telepat.sdk.models;

import android.util.Base64;

import com.google.gson.Gson;
import com.google.gson.JsonElement;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.telepat.sdk.Telepat;
import io.telepat.sdk.data.TelepatInternalDB;
import io.telepat.sdk.networking.CrudOperationsCallback;
import io.telepat.sdk.networking.OctopusApi;
import io.telepat.sdk.networking.responses.GenericApiResponse;
import io.telepat.sdk.networking.responses.TelepatCountCallback;
import io.telepat.sdk.utilities.TelepatLogger;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

/**
 * Created by <NAME>, catalinivan on 09/03/15.
 * Telepat Channel model
 */

public class Channel implements PropertyChangeListener {
	private String mModelName;
	private String mUserId;
	private String mParentModelName;
	private String mParentId;
	private String mSingleObjectId;
	private HashMap<String, Object> mFilters;
	private OnChannelEventListener mChannelEventListener;
	private TelepatContext mTelepatContext;
	private Class objectType;
	private Gson gson = new Gson();
	private HashMap<String, TelepatBaseModel> waitingForCreation = new HashMap<>();
	private TelepatInternalDB dbInstance;
	private OctopusApi apiInstance;

	/**
	 * Possible notification message types arriving from the Telepat cloud
	 */
	public enum NotificationType {
		ObjectAdded,
		ObjectUpdated,
		ObjectDeleted
	}

	public enum AggregationType {
		AverageAggregation,
		SumAggregation,
		None
	}

	/**
	 * Builder pattern implementation for the Channel class
	 */
	public static class Builder {
		private String mModelName, mUserId, mParentModelName, mParentId, mSingleObjectId;
		private HashMap<String, Object> mFilters;
		private TelepatContext mTelepatContext;
		private OnChannelEventListener mChannelEventListener;
		private Class objectType;

		public Builder setModelName(String modelName) { this.mModelName = modelName; return this; }
		public Builder setContext(TelepatContext context) { this.mTelepatContext = context; return this;}
		public Builder setUserFilter(String userId) { this.mUserId = userId; return this;}
		public Builder setParentFilter(String parentModelName, String parentId) { this.mParentModelName = parentModelName; this.mParentId = parentId; return this;}
		public Builder setSingleObjectIdFilter(String singleObjectId) {this.mSingleObjectId = singleObjectId; return this; }
		public Builder setFilters(HashMap<String, Object> filters) { this.mFilters = filters; return this;}
		public Builder setChannelEventListener(OnChannelEventListener listener) {
			this.mChannelEventListener = listener;
			return this;
		}
		public Builder setObjectType(Class objectType) {
			this.objectType = objectType;
			return this;
		}
		public Channel build() {
			return new Channel(this);
		}
	}

	public Channel(String identifier) {
		String[] identifierSegments = identifier.split(":");
		String contextId = identifierSegments[1];
		if(Telepat.getInstance().getContexts()==null) return;
		this.mTelepatContext = Telepat.getInstance().getContexts().get(contextId);
		this.mModelName = identifierSegments[2];
		this.objectType = TelepatBaseModel.class;
		linkExternalDependencies();
	}

	public Channel(Builder builder) {
		this.mModelName = builder.mModelName;
		this.mChannelEventListener = builder.mChannelEventListener;
		this.mTelepatContext = builder.mTelepatContext;
		this.objectType = builder.objectType;
		this.mFilters = builder.mFilters;
		this.mUserId = builder.mUserId;
		this.mParentModelName = builder.mParentModelName;
		this.mParentId = builder.mParentId;
		this.mSingleObjectId = builder.mSingleObjectId;
		this.dbInstance = Telepat.getInstance().getDBInstance();
		linkExternalDependencies();
//		this.notifyStoredObjects();
	}

	/**
	 * Sets the internal DB and OctopusAPI references so that Channel objects are able to
	 * persist data in the internal DB as well as send out Sync API requests.
	 */
	private void linkExternalDependencies() {
		this.dbInstance = Telepat.getInstance().getDBInstance();
		this.apiInstance = Telepat.getInstance().getAPIInstance();
	}

	/**
	 * Create a new subscription with the Telepat Cloud instance.
	 * If the device is already registered, the stored objects will be notified again.
	 */
	public void subscribe() {
		apiInstance.subscribe(
				getSubscribingRequestBody(),
				new Callback<HashMap<String, JsonElement>>() {
					@Override
					public void success(
							HashMap<String, JsonElement> responseHashMap,
							Response response) {

						Integer status = Integer.parseInt(responseHashMap.get("status").toString());
						JsonElement message = responseHashMap.get("content");

						if (status == 200) {
							Telepat.getInstance().registerSubscription(Channel.this);

							for (JsonElement entry
									: message.getAsJsonArray()) {
								processNotification(new TransportNotification(entry));
							}

							if(Channel.this.mChannelEventListener != null) {
								mChannelEventListener.onSubscribeComplete();
							}

						} else {
							if (Channel.this.mChannelEventListener != null)
								Channel.this.mChannelEventListener.onError(status, message.toString());
						}
					}<commit_msg>Bugfix - calling subscribe with a null context<commit_after>package io.telepat.sdk.models;

import android.util.Base64;

import com.google.gson.Gson;
import com.google.gson.JsonElement;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.telepat.sdk.Telepat;
import io.telepat.sdk.data.TelepatInternalDB;
import io.telepat.sdk.networking.CrudOperationsCallback;
import io.telepat.sdk.networking.OctopusApi;
import io.telepat.sdk.networking.responses.GenericApiResponse;
import io.telepat.sdk.networking.responses.TelepatCountCallback;
import io.telepat.sdk.utilities.TelepatLogger;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

/**
 * Created by <NAME>, catalinivan on 09/03/15.
 * Telepat Channel model
 */

public class Channel implements PropertyChangeListener {
	private String mModelName;
	private String mUserId;
	private String mParentModelName;
	private String mParentId;
	private String mSingleObjectId;
	private HashMap<String, Object> mFilters;
	private OnChannelEventListener mChannelEventListener;
	private TelepatContext mTelepatContext;
	private Class objectType;
	private Gson gson = new Gson();
	private HashMap<String, TelepatBaseModel> waitingForCreation = new HashMap<>();
	private TelepatInternalDB dbInstance;
	private OctopusApi apiInstance;

	/**
	 * Possible notification message types arriving from the Telepat cloud
	 */
	public enum NotificationType {
		ObjectAdded,
		ObjectUpdated,
		ObjectDeleted
	}

	public enum AggregationType {
		AverageAggregation,
		SumAggregation,
		None
	}

	/**
	 * Builder pattern implementation for the Channel class
	 */
	public static class Builder {
		private String mModelName, mUserId, mParentModelName, mParentId, mSingleObjectId;
		private HashMap<String, Object> mFilters;
		private TelepatContext mTelepatContext;
		private OnChannelEventListener mChannelEventListener;
		private Class objectType;

		public Builder setModelName(String modelName) { this.mModelName = modelName; return this; }
		public Builder setContext(TelepatContext context) { this.mTelepatContext = context; return this;}
		public Builder setUserFilter(String userId) { this.mUserId = userId; return this;}
		public Builder setParentFilter(String parentModelName, String parentId) { this.mParentModelName = parentModelName; this.mParentId = parentId; return this;}
		public Builder setSingleObjectIdFilter(String singleObjectId) {this.mSingleObjectId = singleObjectId; return this; }
		public Builder setFilters(HashMap<String, Object> filters) { this.mFilters = filters; return this;}
		public Builder setChannelEventListener(OnChannelEventListener listener) {
			this.mChannelEventListener = listener;
			return this;
		}
		public Builder setObjectType(Class objectType) {
			this.objectType = objectType;
			return this;
		}
		public Channel build() {
			return new Channel(this);
		}
	}

	public Channel(String identifier) {
		String[] identifierSegments = identifier.split(":");
		String contextId = identifierSegments[1];
		if(Telepat.getInstance().getContexts()==null) return;
		this.mTelepatContext = Telepat.getInstance().getContexts().get(contextId);
		this.mModelName = identifierSegments[2];
		this.objectType = TelepatBaseModel.class;
		linkExternalDependencies();
	}

	public Channel(Builder builder) {
		this.mModelName = builder.mModelName;
		this.mChannelEventListener = builder.mChannelEventListener;
		this.mTelepatContext = builder.mTelepatContext;
		this.objectType = builder.objectType;
		this.mFilters = builder.mFilters;
		this.mUserId = builder.mUserId;
		this.mParentModelName = builder.mParentModelName;
		this.mParentId = builder.mParentId;
		this.mSingleObjectId = builder.mSingleObjectId;
		this.dbInstance = Telepat.getInstance().getDBInstance();
		linkExternalDependencies();
//		this.notifyStoredObjects();
	}

	/**
	 * Sets the internal DB and OctopusAPI references so that Channel objects are able to
	 * persist data in the internal DB as well as send out Sync API requests.
	 */
	private void linkExternalDependencies() {
		this.dbInstance = Telepat.getInstance().getDBInstance();
		this.apiInstance = Telepat.getInstance().getAPIInstance();
	}

	/**
	 * Create a new subscription with the Telepat Cloud instance.
	 * If the device is already registered, the stored objects will be notified again.
	 */
	public void subscribe() {
		if(mTelepatContext==null) return;
		apiInstance.subscribe(
				getSubscribingRequestBody(),
				new Callback<HashMap<String, JsonElement>>() {
					@Override
					public void success(
							HashMap<String, JsonElement> responseHashMap,
							Response response) {

						Integer status = Integer.parseInt(responseHashMap.get("status").toString());
						JsonElement message = responseHashMap.get("content");

						if (status == 200) {
							Telepat.getInstance().registerSubscription(Channel.this);

							for (JsonElement entry
									: message.getAsJsonArray()) {
								processNotification(new TransportNotification(entry));
							}

							if(Channel.this.mChannelEventListener != null) {
								mChannelEventListener.onSubscribeComplete();
							}

						} else {
							if (Channel.this.mChannelEventListener != null)
								Channel.this.mChannelEventListener.onError(status, message.toString());
						}
					}
{'fraction_non_alphanumeric': 0.09039860075485594, 'fraction_numerical': 0.0023934456411672652, 'mean_word_length': 4.869259859535386, 'pattern_counts': {'":': 2, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4325709', 'n_tokens_mistral': 3389, 'n_tokens_neox': 3010, 'n_words': 748}