Skip to content

Instantly share code, notes, and snippets.

@FrantisekGazo
Created March 16, 2016 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FrantisekGazo/f62ece65fbed2dc1b8c8 to your computer and use it in GitHub Desktop.
Save FrantisekGazo/f62ece65fbed2dc1b8c8 to your computer and use it in GitHub Desktop.
package eu.f3rog.db;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Class {@link CompositeId}.
*
* @author Frantisek Gazo
* @version 2015-09-09
*/
public class CompositeId {
public static final class Builder {
@Nullable
private CompositeId mCompositeId;
public Builder() {
mCompositeId = new CompositeId();
}
public Builder add(@Nullable Integer id, @NonNull @Tag String idTag) {
return add((id != null) ? "" + id : null, idTag);
}
public Builder add(@Nullable Long id, @NonNull @Tag String idTag) {
return add((id != null) ? "" + id : null, idTag);
}
public Builder add(@Nullable String id, @NonNull @Tag String idTag) {
if (mCompositeId != null && id != null && !id.isEmpty()) {
mCompositeId.add(id, idTag);
} else {
mCompositeId = null;
}
return this;
}
public Builder add(@Nullable CompositeIdObject obj) {
if (mCompositeId != null && obj != null && obj.getDatabaseId() != null && !obj.getDatabaseId().isEmpty()) {
mCompositeId.add(obj.getDatabaseId());
} else {
mCompositeId = null;
}
return this;
}
public Builder add(@Nullable CompositeIdObject obj, @Tag String... onlyIdTags) {
add((obj != null) ? obj.getDatabaseId() : null, onlyIdTags);
return this;
}
public Builder add(@Nullable CompositeId cid, @Tag String... onlyIdTags) {
if (mCompositeId != null && cid != null) {
for (String tag : onlyIdTags) {
String id = cid.getId(tag);
if (id != null) {
mCompositeId.add(id, tag);
} else {
mCompositeId = null;
break;
}
}
} else {
mCompositeId = null;
}
return this;
}
public Builder keep(@NonNull @Tag String... idTags) {
if (mCompositeId != null) {
mCompositeId.keepOnly(idTags);
}
return this;
}
public Builder remove(@NonNull @Tag String... idTags) {
if (mCompositeId != null) {
mCompositeId.remove(idTags);
}
return this;
}
@Nullable
public CompositeId build() {
return mCompositeId;
}
@Nullable
public String buildString() {
return (mCompositeId != null) ? mCompositeId.toString() : null;
}
@Nullable
public String buildRegex() {
if (mCompositeId != null) {
return mCompositeId.createRegexId();
} else {
return null;
}
}
public static CompositeId buildFrom(String stringId) {
if (TextUtils.isEmpty(stringId)) {
return null;
} else {
return new CompositeId(stringId);
}
}
}
//region TAGS ----------------------------------------------
@Retention(RetentionPolicy.SOURCE)
@StringDef({
SOME_TAG,
})
public @interface Tag {
}
// DO NOT CHANGE tags in SubjectFormDatum because filter expects that Subject.COLUMN_DATABASE_ID is contained in SubjectFormDatum.COLUMN_DATABASE_ID as is
public static final String END = "<END>";
public static final String SOME_TAG = "<Tag>";
/**
* ATTENTION : All tags have to be the same length !!!
*/
private static final int TAG_LENGTH = 5;
public static final String SEPARATOR = "#/#";
private static final String REGEX_SEPARATOR = "%";
//endregion TAGS ----------------------------------------------
@Nullable
private String mStringId;
@Nullable
private Map<String, String> mIds;
/**
* Constructs new composite ID.
*/
private CompositeId() {
mStringId = "";
mIds = new HashMap<>();
}
/**
* Constructs new composite ID.
*
* @param stringId String representation of composite ID.
*/
private CompositeId(String stringId) {
mStringId = stringId;
mIds = parseIds(mStringId);
}
/**
* Returns ID part based on given tag.
*/
@Nullable
public String getId(@Tag String idTag) {
return getIds().get(idTag);
}
@Nullable
public Long getLongId(@Tag String idTag) {
String id = getId(idTag);
return (id != null) ? Long.parseLong(id) : null;
}
private void add(@NonNull String id, @Tag String idTag) {
getIds().put(idTag, id);
mStringId = null;
}
private void add(@NonNull CompositeId compositeId) {
getIds().putAll(compositeId.getIds());
mStringId = null;
}
private void remove(@Tag String... idTags) {
getIds().keySet().removeAll(Arrays.asList(idTags));
mStringId = null;
}
private void keepOnly(@Tag String... idTags) {
getIds().keySet().retainAll(Arrays.asList(idTags));
mStringId = null;
}
public boolean containsIdFor(@Tag String idTag) {
return getIds().containsKey(idTag);
}
/**
* Returns all parts of this composite ID.
*/
@NonNull
private Map<String, String> getIds() {
if (mIds == null) {
mIds = parseIds(mStringId);
}
return mIds;
}
@Override
public String toString() {
if (mStringId == null) {
mStringId = buildStringId(mIds, SEPARATOR);
}
return mStringId;
}
@Override
public boolean equals(Object o) {
return o != null && toString().equals(o.toString());
}
@Override
public int hashCode() {
return toString().hashCode();
}
public boolean isEmpty() {
return getIds().isEmpty();
}
private int getPartsCount() {
return getIds().size();
}
/**
* Creates regex for LIKE query operator.
*/
private String createRegexId() {
return REGEX_SEPARATOR + buildStringId(mIds, SEPARATOR + REGEX_SEPARATOR);
}
private Map<String, String> parseIds(String stringId) {
Map<String, String> ids = new HashMap<>();
if (stringId != null) {
String[] splitIds = stringId.split(SEPARATOR);
for (String s : splitIds) {
ids.put(s.substring(0, TAG_LENGTH), s.substring(TAG_LENGTH, s.length()));
}
}
ids.remove(END);
return ids;
}
private String buildStringId(Map<String, String> ids, String separator) {
if (ids == null) {
return "";
}
StringBuilder sb = new StringBuilder();
List<String> tags = new ArrayList<>(ids.keySet());
Collections.sort(tags);
String tag;
for (int i = 0; i < tags.size(); i++) {
tag = tags.get(i);
sb.append(tag).append(ids.get(tag)).append(separator);
}
sb.append(END);
return sb.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment