Commit 2778adee authored by Matija Obreza's avatar Matija Obreza

AccessionOverview: Generic implementation of accessionOverview() method

- Renamed Accession#accessionIprList to #accessionIprs
parent 8c9280c6
......@@ -207,7 +207,7 @@ public class Accession extends CooperatorOwnedModel implements ElasticLoader, El
@OneToMany(fetch = FetchType.LAZY, cascade = {}, mappedBy = "accession")
@JsonIgnore
private List<AccessionIpr> accessionIprList;
private List<AccessionIpr> accessionIprs;
@OneToMany(fetch = FetchType.LAZY, cascade = {}, mappedBy = "accession")
@JsonIgnore
......@@ -428,12 +428,12 @@ public class Accession extends CooperatorOwnedModel implements ElasticLoader, El
this.accessionActions = accessionActions;
}
public List<AccessionIpr> getAccessionIprList() {
return accessionIprList;
public List<AccessionIpr> getAccessionIprs() {
return accessionIprs;
}
public void setAccessionIprList(List<AccessionIpr> accessionIprList) {
this.accessionIprList = accessionIprList;
public void setAccessionIprs(List<AccessionIpr> accessionIprs) {
this.accessionIprs = accessionIprs;
}
public List<AccessionPedigree> getAccessionPedigrees() {
......
......@@ -15,6 +15,8 @@
*/
package org.gringlobal.service.impl;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
......@@ -45,6 +47,7 @@ import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
......@@ -52,6 +55,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.CollectionExpression;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.BeanPath;
import com.querydsl.core.types.dsl.CollectionPathBase;
import com.querydsl.core.types.dsl.NumberPath;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQuery;
......@@ -230,7 +237,7 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
// initialize lazy data
Hibernate.initialize(accession.getAccessionSources());
Hibernate.initialize(accession.getAccessionActions());
Hibernate.initialize(accession.getAccessionIprList());
Hibernate.initialize(accession.getAccessionIprs());
Hibernate.initialize(accession.getAccessionPedigrees());
Hibernate.initialize(accession.getAccessionQuarantines());
Hibernate.initialize(accession.getCitations());
......@@ -239,7 +246,7 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
accessionDetails.accession = accession;
accessionDetails.sources = accession.getAccessionSources();
accessionDetails.actions = accession.getAccessionActions();
accessionDetails.ipr = accession.getAccessionIprList();
accessionDetails.ipr = accession.getAccessionIprs();
accessionDetails.pedigree = accession.getAccessionPedigrees();
accessionDetails.quarantine = accession.getAccessionQuarantines();
accessionDetails.citations = accession.getCitations();
......@@ -307,7 +314,7 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
// FIXME
return null;
}
JPAQuery<?> query = jpaQueryFactory.from(QAccession.accession);
if (filter != null) {
......@@ -316,62 +323,68 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
PathBuilder<Object> groupBy;
// Handle 1-to-many
if (group.startsWith("accessionSources.")) {
group = group.substring("accessionSources.".length());
QAccessionSource joined = new QAccessionSource("joined");
query.join(QAccession.accession.accessionSources, joined);
PathBuilder<?> sourceProp = new PathBuilder<>(AccessionSource.class, "joined");
groupBy = sourceProp.get(group);
} else if (group.startsWith("accessionActions.")) {
group = group.substring("accessionActions.".length());
QAccessionAction joined = new QAccessionAction("joined");
query.join(QAccession.accession.accessionActions, joined);
PathBuilder<?> sourceProp = new PathBuilder<>(AccessionAction.class, "joined");
groupBy = sourceProp.get(group);
} else if (group.startsWith("accessionIpr.")) {
group = group.substring("accessionIpr.".length());
QAccessionIpr joined = new QAccessionIpr("joined");
query.join(QAccession.accession.accessionIprList, joined);
PathBuilder<?> sourceProp = new PathBuilder<>(AccessionIpr.class, "joined");
groupBy = sourceProp.get(group);
} else if (group.startsWith("inventories.")) {
group = group.substring("inventories.".length());
QInventory joined = new QInventory("joined");
query.join(QAccession.accession.inventories, joined);
if (group.startsWith("names.")) {
group = group.substring("names.".length());
QAccessionInvName joined2 = new QAccessionInvName("joined2");
query.join(joined.names, joined2);
PathBuilder<?> sourceProp = new PathBuilder<>(AccessionInvName.class, "joined2");
groupBy = sourceProp.get(group);
} else if (group.startsWith("actions.")) {
group = group.substring("actions.".length());
QInventoryAction joined2 = new QInventoryAction("joined2");
query.join(joined.actions, joined2);
PathBuilder<?> sourceProp = new PathBuilder<>(InventoryAction.class, "joined2");
groupBy = sourceProp.get(group);
} else {
PathBuilder<?> sourceProp = new PathBuilder<>(Inventory.class, "joined");
groupBy = sourceProp.get(group);
}
// fields
String[] groups = group.strip().split("\\.");
Object root = QAccession.accession;
PathBuilder<?> sourceProp = new PathBuilder<>(Accession.class, QAccession.accession.getMetadata());
String currentPath = "";
String lookupField = group;
for (int i = 0; i < groups.length - 1; i++) { // except the last path element
String fieldName = groups[i];
currentPath += fieldName + ".";
LOG.debug("Looking for {} currentPath={}", fieldName, currentPath);
try {
Field field = root.getClass().getField(fieldName);
LOG.debug("Found {} {}", field.getType(), field.getName());
if (BeanPath.class.isAssignableFrom(field.getType())) {
LOG.debug("{} is an entity", fieldName);
// No join, but change root
root = field.get(root);
// Must not change the lookup path!
} else if (CollectionPathBase.class.isAssignableFrom(field.getType())) {
LOG.debug("{} is a collection type, must join", fieldName);
// Figure out what it is
ResolvableType t1 = ResolvableType.forField(field);
Class<?> entityType = t1.resolveGeneric(0); // entity type
Class<?> qdslType = t1.resolveGeneric(1); // it's querydsl counterpart
} else {
PathBuilder<Accession> acce = new PathBuilder<>(Accession.class, QAccession.accession.getMetadata());
groupBy = acce.get(group);
LOG.debug("Got {} and {} for {}", entityType.getName(), qdslType.getName(), field);
// Join
joinQuery(query, entityType, qdslType, (CollectionExpression<?, ?>) field.get(root), "joined" + i);
// Change root
root = qdslType.getDeclaredConstructor(String.class).newInstance("joined" + i);
// update lookup
sourceProp = new PathBuilder<>(entityType, "joined" + i);
LOG.debug("Changing lookup from {} to {}", lookupField, group.substring(currentPath.length()));
lookupField = group.substring(currentPath.length());
} else {
LOG.debug("{} is a regular path", fieldName);
// Must not change the lookup path!
// Should never reach here.
throw new InvalidApiUsageException("Invalid field '" + fieldName + "' in path " + group);
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | InstantiationException | InvocationTargetException
| NoSuchMethodException e) {
LOG.error("Field '{}' not found in {} for path {}: {}", fieldName, root.getClass().getName(), group, e.getMessage(), e);
throw new InvalidApiUsageException("Field '" + fieldName + "' not found in " + root.getClass().getName() + " for path " + group, e);
}
}
LOG.debug("Using field {} for {}", lookupField, group);
groupBy = sourceProp.get(lookupField);
JPAQuery<Tuple> select = query.select(groupBy, QAccession.accession.id.count()).groupBy(groupBy);
Map<Object, Number> results = new HashMap<>();
......@@ -381,4 +394,12 @@ public class AccessionServiceImpl extends FilteredCRUDServiceImpl<Accession, Acc
});
return results;
}
@SuppressWarnings("unchecked")
private <A, E> void joinQuery(JPAQuery<?> query, Class<?> entityType, Class<E> qdslType, CollectionExpression<?, ?> collectionPath, String aliasName)
throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Path<E> alias = (Path<E>) qdslType.getDeclaredConstructor(String.class).newInstance(aliasName);
query.join((CollectionExpression<?, E>) collectionPath, alias);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment