forked from molgenis/molgenis
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
48912f0
commit 84e491a
Showing
9 changed files
with
642 additions
and
0 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
molgenis-data-icd10/src/main/java/org/molgenis/data/icd10/CollectionsQueryTransformer.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import org.molgenis.data.Entity; | ||
import org.molgenis.data.Query; | ||
|
||
/** | ||
* Transforms a query on an attribute that refers to a ICD-10 repository | ||
*/ | ||
public interface CollectionsQueryTransformer | ||
{ | ||
/** | ||
* @param query the query to transform | ||
* @param icd10EntityTypeId the EntityType that contains the ICD-10 identifiers | ||
* @param expandAttribute the attribute on which to apply the query transformation | ||
* @return a query containing expanded ICD-10 codes | ||
*/ | ||
Query<Entity> transformQuery(Query<Entity> query, String icd10EntityTypeId, String expandAttribute); | ||
} |
86 changes: 86 additions & 0 deletions
86
...nis-data-icd10/src/main/java/org/molgenis/data/icd10/CollectionsQueryTransformerImpl.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import com.google.common.collect.TreeTraverser; | ||
import org.molgenis.data.DataService; | ||
import org.molgenis.data.Entity; | ||
import org.molgenis.data.Query; | ||
import org.molgenis.data.QueryRule; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
import static java.util.Collections.singletonList; | ||
import static java.util.Objects.requireNonNull; | ||
import static java.util.stream.Collectors.toList; | ||
|
||
@Component | ||
public class CollectionsQueryTransformerImpl implements CollectionsQueryTransformer | ||
{ | ||
private static final TreeTraverser<QueryRule> RULE_TRAVERSER = TreeTraverser.using(QueryRule::getNestedRules); | ||
|
||
private final Icd10ClassExpander icd10ClassExpander; | ||
private final DataService dataService; | ||
|
||
CollectionsQueryTransformerImpl(Icd10ClassExpander icd10ClassExpander, DataService dataService) | ||
{ | ||
this.icd10ClassExpander = requireNonNull(icd10ClassExpander); | ||
this.dataService = requireNonNull(dataService); | ||
} | ||
|
||
@Override | ||
public Query<Entity> transformQuery(Query<Entity> query, String icd10EntityTypeId, String expandAttribute) | ||
{ | ||
if (query != null && query.getRules() != null && !query.getRules().isEmpty()) | ||
{ | ||
query.getRules() | ||
.forEach(rule -> RULE_TRAVERSER.preOrderTraversal(rule) | ||
.filter(nestedRule -> isTransformableRule(nestedRule, expandAttribute)) | ||
.forEach(nestedRule -> transformQueryRule(nestedRule, | ||
icd10EntityTypeId))); | ||
} | ||
|
||
return query; | ||
} | ||
|
||
private void transformQueryRule(QueryRule rule, String icd10EntityTypeId) | ||
{ | ||
List<Object> queryValues; | ||
|
||
switch (rule.getOperator()) | ||
{ | ||
case EQUALS: | ||
queryValues = singletonList(rule.getValue()); | ||
rule.setOperator(QueryRule.Operator.IN); | ||
break; | ||
case IN: | ||
//noinspection unchecked | ||
queryValues = (List<Object>) rule.getValue(); | ||
break; | ||
default: | ||
throw new IllegalStateException("Can't expand queries other than IN or EQUALS"); | ||
} | ||
|
||
List<Entity> diseaseTypes = dataService.findAll(icd10EntityTypeId, queryValues.stream()).collect(toList()); | ||
|
||
rule.setValue(expandDiseaseTypes(diseaseTypes)); | ||
} | ||
|
||
/** | ||
* Returns <code>true</code> if a rule is 'IN' or 'EQUALS' on the attribute that should be expanded | ||
*/ | ||
private boolean isTransformableRule(QueryRule nestedRule, String expandAttribute) | ||
{ | ||
return nestedRule != null && nestedRule.getField() != null && nestedRule.getField().equals(expandAttribute) && ( | ||
nestedRule.getOperator() == QueryRule.Operator.IN | ||
|| nestedRule.getOperator() == QueryRule.Operator.EQUALS); | ||
} | ||
|
||
/** | ||
* Expand ICD-10 entities with all their children, grandchildren, etc. | ||
*/ | ||
private Collection<Entity> expandDiseaseTypes(List<Entity> diseaseTypes) | ||
{ | ||
return icd10ClassExpander.expandClasses(diseaseTypes); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
molgenis-data-icd10/src/main/java/org/molgenis/data/icd10/Icd10ClassExpander.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import org.molgenis.data.Entity; | ||
|
||
import java.util.Collection; | ||
|
||
/** | ||
* Expands a list of 'eu_bbmri_eric_disease_types' entities to include all of their children. | ||
*/ | ||
public interface Icd10ClassExpander | ||
{ | ||
Collection<Entity> expandClasses(Collection<Entity> diseaseClasses); | ||
} |
89 changes: 89 additions & 0 deletions
89
molgenis-data-icd10/src/main/java/org/molgenis/data/icd10/Icd10ClassExpanderImpl.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import com.google.common.collect.TreeTraverser; | ||
import org.molgenis.data.Entity; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.Collection; | ||
import java.util.stream.Stream; | ||
import java.util.stream.StreamSupport; | ||
|
||
import static java.util.stream.Collectors.toList; | ||
|
||
@Component | ||
public class Icd10ClassExpanderImpl implements Icd10ClassExpander | ||
{ | ||
private static final String DISEASE_CLASS_CHILDREN_ATTRIBUTE_NAME = "children"; | ||
|
||
@Override | ||
public Collection<Entity> expandClasses(Collection<Entity> diseaseClasses) | ||
{ | ||
return diseaseClasses.stream() | ||
.flatMap(this::expandClass) | ||
.map(this::toDiseaseClass) | ||
.distinct() | ||
.map(this::toEntity) | ||
.collect(toList()); | ||
} | ||
|
||
private Stream<Entity> expandClass(Entity diseaseClass) | ||
{ | ||
Iterable<Entity> diseaseClasses = new DiseaseClassTreeTraverser().postOrderTraversal(diseaseClass); | ||
return StreamSupport.stream(diseaseClasses.spliterator(), false); | ||
} | ||
|
||
private DiseaseClass toDiseaseClass(Entity entity) | ||
{ | ||
return new DiseaseClass(entity); | ||
} | ||
|
||
private Entity toEntity(DiseaseClass diseaseClass) | ||
{ | ||
return diseaseClass.getEntity(); | ||
} | ||
|
||
/** | ||
* Disease class entity wrapper with equals and hashCode implementation. | ||
*/ | ||
private static class DiseaseClass | ||
{ | ||
private final Entity entity; | ||
|
||
private DiseaseClass(Entity entity) | ||
{ | ||
this.entity = entity; | ||
} | ||
|
||
private Entity getEntity() | ||
{ | ||
return entity; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) | ||
{ | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
|
||
DiseaseClass that = (DiseaseClass) o; | ||
|
||
return entity.getIdValue().equals(that.entity.getIdValue()); | ||
} | ||
|
||
@Override | ||
public int hashCode() | ||
{ | ||
return entity.getIdValue().hashCode(); | ||
} | ||
} | ||
|
||
private static class DiseaseClassTreeTraverser extends TreeTraverser<Entity> | ||
{ | ||
@Override | ||
public Iterable<Entity> children(@Nonnull Entity diseaseClassEntity) | ||
{ | ||
return diseaseClassEntity.getEntities(DISEASE_CLASS_CHILDREN_ATTRIBUTE_NAME); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
molgenis-data-icd10/src/main/java/org/molgenis/data/icd10/Icd10ExpanderDecorator.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import org.molgenis.data.AbstractRepositoryDecorator; | ||
import org.molgenis.data.Entity; | ||
import org.molgenis.data.Query; | ||
import org.molgenis.data.Repository; | ||
import org.molgenis.data.aggregation.AggregateQuery; | ||
import org.molgenis.data.aggregation.AggregateResult; | ||
import org.molgenis.data.support.AggregateQueryImpl; | ||
|
||
import java.util.stream.Stream; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
class Icd10ExpanderDecorator extends AbstractRepositoryDecorator<Entity> | ||
{ | ||
private final CollectionsQueryTransformer queryTransformer; | ||
private final String icd10EntityTypeId; | ||
private final String expandAttribute; | ||
|
||
Icd10ExpanderDecorator(Repository<Entity> delegateRepository, CollectionsQueryTransformer queryTransformer, | ||
String icd10EntityTypeId, String expandAttribute) | ||
{ | ||
super(delegateRepository); | ||
this.queryTransformer = requireNonNull(queryTransformer); | ||
this.icd10EntityTypeId = requireNonNull(icd10EntityTypeId); | ||
this.expandAttribute = requireNonNull(expandAttribute); | ||
} | ||
|
||
@Override | ||
public long count(Query<Entity> query) | ||
{ | ||
query = query != null ? transformQuery(query) : null; | ||
return delegate().count(query); | ||
} | ||
|
||
@Override | ||
public Entity findOne(Query<Entity> query) | ||
{ | ||
query = query != null ? transformQuery(query) : null; | ||
return delegate().findOne(query); | ||
} | ||
|
||
@Override | ||
public Stream<Entity> findAll(Query<Entity> query) | ||
{ | ||
query = query != null ? transformQuery(query) : null; | ||
return delegate().findAll(query); | ||
} | ||
|
||
@Override | ||
public AggregateResult aggregate(AggregateQuery aggregateQuery) | ||
{ | ||
Query<Entity> q = aggregateQuery.getQuery(); | ||
Query<Entity> transformedQuery = q != null ? transformQuery(q) : null; | ||
aggregateQuery = new AggregateQueryImpl(aggregateQuery.getAttributeX(), aggregateQuery.getAttributeY(), | ||
aggregateQuery.getAttributeDistinct(), transformedQuery); | ||
return delegate().aggregate(aggregateQuery); | ||
} | ||
|
||
private Query<Entity> transformQuery(Query<Entity> query) | ||
{ | ||
return queryTransformer.transformQuery(query, icd10EntityTypeId, expandAttribute); | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
molgenis-data-icd10/src/main/java/org/molgenis/data/icd10/Icd10ExpanderDecoratorFactory.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.molgenis.data.icd10; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.gson.Gson; | ||
import org.molgenis.data.Entity; | ||
import org.molgenis.data.Repository; | ||
import org.molgenis.data.decorator.DynamicRepositoryDecoratorFactory; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Map; | ||
|
||
import static com.google.common.collect.ImmutableMap.of; | ||
import static java.util.Objects.requireNonNull; | ||
|
||
@Component | ||
@SuppressWarnings("unused") | ||
public class Icd10ExpanderDecoratorFactory implements DynamicRepositoryDecoratorFactory<Entity> | ||
{ | ||
private static final String ID = "icd10expander"; | ||
private static final String ICD10_ENTITY_TYPE_ID = "icd10EntityTypeId"; | ||
private static final String EXPAND_ATTRIBUTE = "expandAttribute"; | ||
|
||
private final Gson gson; | ||
private final CollectionsQueryTransformer queryTransformer; | ||
|
||
public Icd10ExpanderDecoratorFactory(Gson gson, CollectionsQueryTransformer queryTransformer) | ||
{ | ||
this.gson = requireNonNull(gson); | ||
this.queryTransformer = requireNonNull(queryTransformer); | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("unchecked") | ||
public Repository createDecoratedRepository(Repository<Entity> repository, Map<String, Object> parameters) | ||
{ | ||
return new Icd10ExpanderDecorator(repository, queryTransformer, parameters.get(ICD10_ENTITY_TYPE_ID).toString(), | ||
parameters.get(EXPAND_ATTRIBUTE).toString()); | ||
} | ||
|
||
@Override | ||
public String getId() | ||
{ | ||
return ID; | ||
} | ||
|
||
@Override | ||
public String getLabel() | ||
{ | ||
return "ICD-10 Query Expander"; | ||
} | ||
|
||
@Override | ||
public String getDescription() | ||
{ | ||
return "Expands queries on an attribute that refers to an entity type with ICD-10 codes."; | ||
} | ||
|
||
@Override | ||
public String getSchema() | ||
{ | ||
return gson.toJson(of("title", "Icd10Expander", "type", "object", "properties", of(ICD10_ENTITY_TYPE_ID, | ||
of("type", "string", "description", "The entity type containing the ICD-10 data."), EXPAND_ATTRIBUTE, | ||
of("type", "string", "description", "The attribute on which the query expansion will be applied.")), | ||
"required", ImmutableList.of(ICD10_ENTITY_TYPE_ID, EXPAND_ATTRIBUTE))); | ||
} | ||
} | ||
|
Oops, something went wrong.