package org.activityinfo.model.legacy; import com.google.common.base.Strings; import org.activityinfo.model.resource.ResourceId; /** * Provides an adapter between legacy ids, which are either random or sequential 32-bit integers but only * guaranteed to be unique within a table, and Collision Resistant Universal Ids (CUIDs) which * will serve as the identifiers for all user-created objects. */ public class CuidAdapter { public static final char COUNTRY_DOMAIN = 'c'; public static final char SITE_DOMAIN = 's'; public static final char ACTIVITY_DOMAIN = 'a'; public static final char LOCATION_DOMAIN = 'g'; // avoid lower case l ! public static final char LOCATION_TYPE_DOMAIN = 'L'; // avoid lower case l ! public static final char PARTNER_DOMAIN = 'p'; public static final char PARTNER_FORM_CLASS_DOMAIN = 'P'; public static final char INDICATOR_DOMAIN = 'i'; public static final char ATTRIBUTE_GROUP_DOMAIN = 'A'; public static final char ATTRIBUTE_GROUP_FIELD_DOMAIN = 'Q'; public static final char MONTHLY_REPORT = 'm'; public static final char ATTRIBUTE_DOMAIN = 't'; public static final char DATABASE_DOMAIN = 'd'; public static final char ADMIN_LEVEL_DOMAIN = 'E'; public static final char ADMIN_ENTITY_DOMAIN = 'z'; public static final char PROJECT_CLASS_DOMAIN = 'R'; public static final char PROJECT_DOMAIN = 'r'; public static final char ACTIVITY_CATEGORY_DOMAIN = 'C'; public static final char USER_DOMAIN = 'U'; public static final int NAME_FIELD = 1; public static final int ADMIN_PARENT_FIELD = 2; public static final int CODE_FIELD = 3; public static final int AXE_FIELD = 4; public static final int GEOMETRY_FIELD = 5; public static final int ADMIN_FIELD = 6; public static final int PARTNER_FIELD = 7; public static final int PROJECT_FIELD = 8; public static final int DATE_FIELD = 9; public static final int FULL_NAME_FIELD = 10; public static final int LOCATION_FIELD = 11; public static final int START_DATE_FIELD = 12; public static final int END_DATE_FIELD = 13; public static final int COMMENT_FIELD = 14; public static final int LOCATION_NAME_FIELD = 15; public static final int GPS_FIELD = 16; public static final int BLOCK_SIZE = 10; public static final String CLASS_FIELD = "_class"; public static final int[] BUILTIN_FIELDS = new int[] { START_DATE_FIELD, END_DATE_FIELD, PARTNER_FIELD, PROJECT_FIELD, LOCATION_FIELD, COMMENT_FIELD }; /** * Avoid instance creation. */ private CuidAdapter() { } public static ResourceId newLegacyFormInstanceId(ResourceId formClassId) { if (formClassId != null) { final int newId = new KeyGenerator().generateInt(); switch (formClassId.getDomain()) { case ACTIVITY_DOMAIN: return cuid(SITE_DOMAIN, newId); case LOCATION_TYPE_DOMAIN: return locationInstanceId(newId); case ATTRIBUTE_GROUP_DOMAIN: return attributeId(newId); } } return ResourceId.generateId(); } public static final int getLegacyIdFromCuid(String cuid) { return Integer.parseInt(cuid.substring(1), ResourceId.RADIX); } public static final ResourceId cuid(char domain, int id) { return ResourceId.valueOf(domain + block(id)); } public static final ResourceId resourceId(char domain, int id) { return cuid(domain, id); } public static int getLegacyIdFromCuid(ResourceId id) { if(id.getDomain() == '_') { return 0; } else { return getLegacyIdFromCuid(id.asString()); } } public static ResourceId partnerInstanceId(int partnerId) { return cuid(PARTNER_DOMAIN, partnerId); } /** * @return the {@code FormField} ResourceId for the Location field of a given Activity {@code FormClass} */ public static ResourceId locationField(int activityId) { return field(activityFormClass(activityId), LOCATION_FIELD); } /** * @return the {@code FormClass} ResourceId for a given LocationType */ public static ResourceId locationFormClass(int locationTypeId) { return cuid(LOCATION_TYPE_DOMAIN, locationTypeId); } public static ResourceId locationInstanceId(int locationId) { return cuid(LOCATION_DOMAIN, locationId); } public static ResourceId adminLevelFormClass(int adminLevelId) { return cuid(ADMIN_LEVEL_DOMAIN, adminLevelId); } public static ResourceId entity(int adminEntityId) { return cuid(ADMIN_ENTITY_DOMAIN, adminEntityId); } /** * Generates a CUID for a FormField in a given previously-built-in FormClass using * the FormClass's CUID and a field index. * * @param classId * @param fieldIndex * @return */ public static ResourceId field(ResourceId classId, int fieldIndex) { return ResourceId.valueOf(classId.asString() + block(fieldIndex)); } /** * @return the {@code FormClass} ResourceId for a given Activity */ public static ResourceId activityFormClass(int activityId) { return ResourceId.valueOf(ACTIVITY_DOMAIN + block(activityId)); } /** * @return the {@code FormClass} ResourceId for a given Activity */ public static ResourceId commentsField(int activityId) { // return new ResourceId(ACTIVITY_DOMAIN + block(activityId) + "C"); return field(activityFormClass(activityId), COMMENT_FIELD); } /** * @return the {@code FormField} ResourceId for the indicator field within a given * Activity {@code FormClass} */ public static ResourceId indicatorField(int indicatorId) { return cuid(INDICATOR_DOMAIN, indicatorId); } public static ResourceId attributeField(int attributeId) { return cuid(ATTRIBUTE_DOMAIN, attributeId); } public static ResourceId siteField(int siteId) { return cuid(INDICATOR_DOMAIN, siteId); } /** * @return the {@code FormField} ResourceId for the field of a given Activity {@code FormClass} that * references the given AttributeGroup FormClass */ public static ResourceId attributeGroupField(int attributeGroupId) { return cuid(ATTRIBUTE_GROUP_FIELD_DOMAIN, attributeGroupId); } public static ResourceId activityCategoryFolderId(int dbId, String category) { return ResourceId.valueOf(ACTIVITY_CATEGORY_DOMAIN + block(dbId) + block(Math.abs(category.hashCode()))); } public static ResourceId attributeGroupFormClass(int attributeGroupId) { return cuid(ATTRIBUTE_GROUP_DOMAIN, attributeGroupId); } public static ResourceId userId(int userId) { return cuid(USER_DOMAIN, userId); } public static ResourceId attributeId(int attributeId) { return cuid(ATTRIBUTE_DOMAIN, attributeId); } /** * @param partnerId the id of the partner * @return the {@code FormClass} ResourceId for a given database's list of partners. */ public static ResourceId partnerFormClass(int partnerId) { return cuid(PARTNER_FORM_CLASS_DOMAIN, partnerId); } /** * @param databaseId the id of the user database * @return the {@code FormClass} ResourceId for a given database's list of projects. */ public static ResourceId projectFormClass(int databaseId) { return cuid(PROJECT_CLASS_DOMAIN, databaseId); } /** * @return the {@code FormSection} ResourceId for a given indicator category within an * Activity {@code FormClass} */ public static ResourceId activityFormSection(int id, String name) { return ResourceId.valueOf(ACTIVITY_DOMAIN + block(id) + block(name.hashCode())); } private static String block(int id) { return Strings.padStart(Integer.toString(id, ResourceId.RADIX), BLOCK_SIZE, '0'); } public static int getBlock(ResourceId resourceId, int blockIndex) { int startIndex = 1 + (blockIndex * BLOCK_SIZE); String block = resourceId.asString().substring(startIndex, startIndex + BLOCK_SIZE); return Integer.parseInt(block, ResourceId.RADIX); } public static ResourceId databaseId(int databaseId) { return cuid(DATABASE_DOMAIN, databaseId); } public static ResourceId generateLocationCuid() { return locationInstanceId(new KeyGenerator().generateInt()); } public static ResourceId generateSiteCuid() { return cuid(SITE_DOMAIN, new KeyGenerator().generateInt()); } }