io.yawp.repository.IdRef Maven / Gradle / Ivy
package io.yawp.repository;
import io.yawp.commons.http.HttpVerb;
import io.yawp.repository.actions.ActionKey;
import io.yawp.repository.models.ObjectModel;
import io.yawp.repository.query.QueryBuilder;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class IdRef implements Comparable> {
private Repository r;
private Class clazz;
private ObjectModel model;
private Long id;
private String name;
private IdRef> parentId;
private boolean shuffled;
protected IdRef(Repository r, Class clazz, Long id) {
this.r = r;
this.clazz = clazz;
this.id = id;
this.model = new ObjectModel(clazz);
}
public IdRef(Repository r, Class clazz, String name) {
this.r = r;
this.clazz = clazz;
this.name = name;
this.model = new ObjectModel(clazz);
}
public void setParentId(IdRef> parentId) {
this.parentId = parentId;
}
public T fetch() {
return fetch(clazz);
}
public TT fetch(Class childClazz) {
return r.query(childClazz).fetch(this);
}
public TT child(Class childClazz) {
QueryBuilder q = r.query(childClazz).from(this);
return q.only();
}
public Long asLong() {
return id;
}
public String asString() {
return name;
}
public Repository getRepository() {
return r;
}
public Class getClazz() {
return clazz;
}
public Class> getParentClazz() {
return model.getParentClazz();
}
public ObjectModel getModel() {
return new ObjectModel(clazz);
}
@SuppressWarnings("unchecked")
public IdRef getParentId() {
return (IdRef) parentId;
}
@SuppressWarnings("unchecked")
public IdRef getAncestorId(int ancestor) {
IdRef> ancestorId = this;
for (int i = 0; i <= ancestor; i++) {
ancestorId = ancestorId.getParentId();
}
return (IdRef) ancestorId;
}
public IdRef createChildId(Class clazz, Long id) {
IdRef idRef = new IdRef(r, clazz, id);
idRef.setParentId(this);
return idRef;
}
public IdRef createChildId(Class clazz, String name) {
IdRef idRef = new IdRef(r, clazz, name);
idRef.setParentId(this);
return idRef;
}
public static IdRef create(Repository r, Class clazz, Long id) {
return new IdRef(r, clazz, id);
}
public static IdRef create(Repository r, Class clazz, String name) {
return new IdRef(r, clazz, name);
}
public static List> create(Repository r, Class clazz, Long... ids) {
List> idRefs = new ArrayList>();
for (int i = 0; i < ids.length; i++) {
idRefs.add(create(r, clazz, ids[i]));
}
return idRefs;
}
@SuppressWarnings("unchecked")
public static IdRef parse(Repository r, HttpVerb verb, String path) {
if (StringUtils.isBlank(path)) {
return null;
}
String[] parts = path.substring(1).split("/");
if (parts.length < 2) {
return null;
}
IdRef lastIdRef = null;
for (int i = 0; i < parts.length; i += 2) {
if (isActionOrCollection(r, verb, parts, i)) {
break;
}
String endpointPath = "/" + parts[i];
IdRef currentIdRef = null;
if (!isString(parts[i + 1])) {
Long asLong = Long.valueOf(parts[i + 1]);
currentIdRef = (IdRef) create(r, getIdRefClazz(r, endpointPath), asLong);
} else {
String asString = parts[i + 1];
currentIdRef = (IdRef) create(r, getIdRefClazz(r, endpointPath), asString);
}
currentIdRef.setParentId(lastIdRef);
lastIdRef = currentIdRef;
validateParentId(currentIdRef, path);
}
return lastIdRef;
}
public static IdRef> parse(Repository r, String id) {
return parse(r, HttpVerb.GET, id);
}
public static IdRef parse(Class clazz, Repository r, String idString) {
return parse(r, HttpVerb.GET, idString);
}
public static List> parse(Class clazz, Repository r, List idsString) {
ArrayList> ids = new ArrayList>();
for (String idString : idsString) {
ids.add(parse(clazz, r, idString));
}
return ids;
}
private static void validateParentId(IdRef> id, String path) {
Class> parentClazz = id.getParentClazz();
if (parentClazz == null) {
return;
}
if (id.getParentId() == null) {
throw new RuntimeException("Invalid parent structure for id: " + path);
}
if (!parentClazz.equals(id.getParentId().getClazz())) {
throw new RuntimeException("Invalid parent structure for id: " + path);
}
}
private static Class> getIdRefClazz(Repository r, String endpointPath) {
return r.getFeatures().getByPath(endpointPath).getClazz();
}
private static boolean isActionOrCollection(Repository r, HttpVerb verb, String[] parts, int i) {
if (i < parts.length - 2) {
return false;
}
if (i == parts.length - 1) {
return true;
}
if (!isString(parts[parts.length - 1])) {
return false;
}
String endpointPath = "/" + parts[parts.length - 2];
String possibleAction = parts[parts.length - 1];
ActionKey actionKey = new ActionKey(verb, possibleAction, true);
return r.getFeatures().hasCustomAction(endpointPath, actionKey);
}
private static boolean isString(String s) {
try {
Long.valueOf(s);
return false;
} catch (NumberFormatException e) {
return true;
}
}
public void delete() {
r.destroy(this);
}
public Object getSimpleValue() {
if (id != null) {
return id;
}
return name;
}
public String getName() {
return name;
}
public Long getId() {
return id;
}
public boolean isShuffled() {
return model.isIdShuffled();
}
public boolean isAncestorId(IdRef> childId) {
IdRef> currentId = childId;
while (currentId.getParentId() != null) {
if (currentId.getParentId().getClazz().equals(this.getClazz())) {
return this.equals(currentId.getParentId());
}
currentId = currentId.getParentId();
}
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parentId == null) ? 0 : parentId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IdRef> other = (IdRef>) obj;
if (clazz == null) {
if (other.clazz != null)
return false;
} else if (!clazz.equals(other.clazz))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (parentId == null) {
if (other.parentId != null)
return false;
} else if (!parentId.equals(other.parentId))
return false;
return true;
}
@Override
public int compareTo(IdRef o) {
if (id != null && o.id != null) {
return id.compareTo(o.id);
}
return idOrNameAsString().compareTo(o.idOrNameAsString());
}
private String idOrNameAsString() {
return id != null ? String.valueOf(id) : name;
}
@Override
public String toString() {
return getUri();
}
public String getUri() {
StringBuilder sb = new StringBuilder();
if (parentId != null) {
sb.append(parentId.toString());
}
sb.append(r.getFeatures().getByClazz(clazz).getEndpointPath());
sb.append("/");
sb.append(id != null ? id : name);
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy