Skip to content

Instantly share code, notes, and snippets.

@MisterRager
Created August 5, 2017 01:14
Show Gist options
  • Save MisterRager/5fe7af7ebf94927ec3bbebf2e0935469 to your computer and use it in GitHub Desktop.
Save MisterRager/5fe7af7ebf94927ec3bbebf2e0935469 to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2017 PlanGrid, Inc. All rights reserved.
*/
package com.plangrid.android.dmodel.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
// Column name
String value() default "";
// Whether to use this column in the "primary key"
boolean isPrimary() default false;
}
/*
* Copyright (c) 2017 PlanGrid, Inc. All rights reserved.
*/
package com.plangrid.android.dmodel.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Data {
// Table name
String value() default "";
}
/*
* Copyright (c) 2017 PlanGrid, Inc. All rights reserved.
*/
package com.plangrid.android.dmodel.mapper;
import android.content.ContentValues;
import android.text.TextUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.plangrid.android.dmodel.annotation.Column;
import com.plangrid.android.parsers.JsonHelper;
import java.lang.reflect.Field;
import rx.Completable;
import rx.Observable;
import rx.exceptions.Exceptions;
public class DataAdapter {
public ContentValues toContentValues(final Object object) {
return Observable.from(object.getClass().getFields())
.filter(field -> field.isAnnotationPresent(Column.class))
.reduce(new ContentValues(),
(cv, field) -> {
try {
final String col = getSqlField(field);
final Object val = field.get(object);
final Throwable err = putValue(cv, col, val).get();
if (err != null) {
throw Exceptions.propagate(err);
}
return cv;
} catch (final IllegalAccessException e) {
throw Exceptions.propagate(e);
}
})
.toBlocking()
.first();
}
private String getSqlField(final Field member) {
final String explicit = member.getAnnotation(Column.class).value();
if (!TextUtils.isEmpty(explicit)) {
return explicit;
}
final JsonProperty prop = member.getAnnotation(JsonProperty.class);
if ((prop != null) && !TextUtils.isEmpty(prop.value())) {
return prop.value();
}
return member.getName();
}
private Completable putValue(final ContentValues cv, final String field, final Object value) {
return Observable.from(ContentValues.class.getMethods())
.filter(method -> "put".equals(method.getName()) && method.getParameterTypes()[2].equals(value.getClass()))
.flatMap(method -> Observable.fromCallable(() -> method.invoke(cv,
field,
method.getParameterTypes()[2].cast(value))))
.first()
.onErrorResumeNext(err -> Observable.fromCallable(() -> {
cv.put(field, JsonHelper.getMapper().writeValueAsString(value));
return true;
}))
.toCompletable();
}
}
@Data(Issue.TABLE)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Issue implements PGDB.Data<Issue>, Assignable {
// Abridged
@Column(PGDB.COLUMN_NUM)
@JsonProperty(Constants.JSON_API.NUM)
@DontCopyPaste
public int num = DEFAULT_NUM;
@Column(PGDB.COLUMN_TITLE)
@JsonProperty(Constants.JSON_API.TITLE)
public String title = "";
@Column(PGDB.COLUMN_DESCRIPTION)
@JsonProperty(Constants.JSON_API.DESCRIPTION)
public String description = "";
@Column(PGDB.COLUMN_STATUS)
@JsonProperty(Constants.JSON_API.STATUS)
public String status = DEFAULT_STATUS;
@Column(value = PGDB.COLUMN_UID, isPrimary = true)
@JsonProperty(Constants.JSON_API.UID)
@DontCopyPaste
public String uid = "";
@Column(PGDB.COLUMN_PROJECT_UID)
@JsonProperty(Constants.JSON_API.PROJECT)
public String projectUid = "";
/**
* Email address of {@link User} this {@link Issue} was created by
*/
@Column(PGDB.COLUMN_CREATED_BY)
@JsonProperty(Constants.JSON_API.CREATED_BY)
@DontCopyPaste
public String createdBy = "";
@Column(PGDB.COLUMN_LOCATION)
@JsonProperty(Constants.JSON_API.ROOM)
public String location = "";
@Column(PGDB.COLUMN_USER_ID)
@JsonProperty(Constants.JSON_API.USER)
@DontCopyPaste
public String user = "";
/**
* Email address of {@link User} this {@link Issue} is assigned to
*/
@Column(PGDB.COLUMN_ASSIGN_TO)
@JsonProperty(Constants.JSON_API.ASSIGNED_TO)
public String assignedTo = "";
@Column(PGDB.COLUMN_USER_CREATED_AT)
@JsonProperty(Constants.JSON_API.USER_CREATED_AT)
@DontCopyPaste
public DateJson userCreatedAt;
@Column(PGDB.COLUMN_CREATED_AT)
@JsonProperty(Constants.JSON_API.CREATED_AT)
public DateJson createdAt;
@Column(PGDB.COLUMN_DUE_DATE)
@JsonProperty(Constants.JSON_API.PUNCH_DUE_AT)
public Long dueDateMilliseconds;
@Column(PGDB.COLUMN_HAS_COST_IMPACT)
@JsonProperty(Constants.JSON_API.HAS_COST_IMPACT)
public boolean hasCostImpact;
@Column(PGDB.COLUMN_COST_IMPACT)
@JsonProperty(Constants.JSON_API.COST_IMPACT)
public BigDecimal costImpactAmount;
@Column(PGDB.COLUMN_HAS_TIME_IMPACT)
@JsonProperty(Constants.JSON_API.HAS_SCHEDULE_IMPACT)
public boolean hasScheduleImpact;
@Column(PGDB.COLUMN_TIME_IMPACT)
@JsonProperty(Constants.JSON_API.SCHEDULE_IMPACT)
public Long scheduleImpactAmount; // interval in TimeUnit.MILLISECONDS
@Column(PGDB.COLUMN_PHOTOS)
@JsonProperty(Constants.JSON_API.PHOTOS)
public List<String> photos;
@Column(PGDB.COLUMN_ISSUE_LIST_UID)
@JsonProperty(Constants.JSON_API.ISSUE_LIST_UID)
public String issueListUid;
// ... abridged
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment