Created
March 16, 2016 15:14
-
-
Save FrantisekGazo/f62ece65fbed2dc1b8c8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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