Skip to content

Commit 9fcca30

Browse files
committed
Refactor LaboratorySerivce to allow registration of DemographicsProvider and perform minor refactors related to generics
1 parent 01d4c91 commit 9fcca30

20 files changed

+182
-109
lines changed

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/SequenceAnalysisService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.logging.log4j.Logger;
2020
import org.jetbrains.annotations.Nullable;
2121
import org.labkey.api.data.Container;
22+
import org.labkey.api.laboratory.DemographicsProvider;
2223
import org.labkey.api.laboratory.NavItem;
2324
import org.labkey.api.pipeline.PipelineJob;
2425
import org.labkey.api.pipeline.PipelineJobException;
@@ -88,7 +89,7 @@ static public void setInstance(SequenceAnalysisService instance)
8889

8990
abstract public Integer getExpRunIdForJob(PipelineJob job, boolean throwUnlessFound) throws PipelineJobException;
9091

91-
abstract public List<PedigreeRecord> generatePedigree(Collection<String> sampleNames, Container c, User u);
92+
abstract public List<PedigreeRecord> generatePedigree(Collection<String> sampleNames, Container c, User u, DemographicsProvider d);
9293

9394
abstract public String getVCFLineCount(File vcf, Logger log, boolean passOnly) throws PipelineJobException;
9495

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AbstractAlignmentStepProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Date: 6/14/2014
2929
* Time: 2:44 PM
3030
*/
31-
abstract public class AbstractAlignmentStepProvider<StepType extends AlignmentStep> extends AbstractPipelineStepProvider<StepType> implements AlignmentStepProvider
31+
abstract public class AbstractAlignmentStepProvider<StepType extends AlignmentStep> extends AbstractPipelineStepProvider<StepType> implements AlignmentStepProvider<StepType>
3232
{
3333
public static String ALIGNMENT_MODE_PARAM = "alignmentMode";
3434
public static String SUPPORT_MERGED_UNALIGNED = "supportsMergeUnaligned";

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AbstractPipelineStepProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* Date: 6/14/2014
3232
* Time: 12:37 PM
3333
*/
34-
abstract public class AbstractPipelineStepProvider<StepType extends PipelineStep> implements PipelineStepProvider
34+
abstract public class AbstractPipelineStepProvider<StepType extends PipelineStep> implements PipelineStepProvider<StepType>
3535
{
3636
private final String _name;
3737
private final String _label;
@@ -145,7 +145,7 @@ public Class<StepType> getStepClass()
145145
}
146146

147147
@Override
148-
public PipelineStepProvider<StepType> combineSteps(int existingStepIdx, PipelineStepCtx toCombine)
148+
public PipelineStepProvider<StepType> combineSteps(int existingStepIdx, PipelineStepCtx<StepType> toCombine)
149149
{
150150
return null;
151151
}

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AlignmentStepProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.labkey.api.sequenceanalysis.pipeline;
22

3-
public interface AlignmentStepProvider extends PipelineStepProvider
3+
public interface AlignmentStepProvider<StepType extends PipelineStep> extends PipelineStepProvider<StepType>
44
{
55
default boolean shouldRunIdxstats()
66
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.labkey.api.sequenceanalysis.pipeline;
2+
3+
import org.json.JSONObject;
4+
5+
public class PedigreeToolParameterDescriptor extends ToolParameterDescriptor
6+
{
7+
public static String NAME = "pedigreeSource";
8+
9+
public PedigreeToolParameterDescriptor()
10+
{
11+
super(null, NAME, "Pedigree Source", "This is the table used for pedigree data", "laboratory-pedigreeselectorfield", "laboratory.subjects", new JSONObject(){{
12+
put("allowBlank", false);
13+
}});
14+
}
15+
16+
public static String getClientDependencyPath()
17+
{
18+
return "/laboratory/field/PedigreeSelectorField.js";
19+
}
20+
}

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/PipelineStepProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,5 @@ default boolean hasParameter(String name)
9494
* Allows a given step to combine itself w/ a neighboring step to save compute time. Should return a new provider, which will
9595
* replace both original provider. Return null for no changes.
9696
*/
97-
PipelineStepProvider<StepType> combineSteps(int existingStepIdx, PipelineStepCtx toCombine);
97+
PipelineStepProvider<StepType> combineSteps(int existingStepIdx, PipelineStepCtx<StepType> toCombine);
9898
}

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/SequencePipelineService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ static public void setInstance(SequencePipelineService instance)
5353

5454
abstract public void registerPipelineStepType(Class<? extends PipelineStep> clazz, String paramName);
5555

56-
abstract public void registerPipelineStep(PipelineStepProvider provider);
56+
abstract public void registerPipelineStep(PipelineStepProvider<?> provider);
5757

58-
abstract public Set<PipelineStepProvider> getAllProviders();
58+
abstract public Set<PipelineStepProvider<?>> getAllProviders();
5959

6060
abstract public <StepType extends PipelineStep> Set<PipelineStepProvider<StepType>> getProviders(Class<StepType> stepType);
6161

SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/VariantProcessingStep.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717

1818
import htsjdk.samtools.util.Interval;
1919
import org.jetbrains.annotations.Nullable;
20+
import org.labkey.api.laboratory.DemographicsProvider;
21+
import org.labkey.api.laboratory.LaboratoryService;
2022
import org.labkey.api.pipeline.PipelineJob;
2123
import org.labkey.api.pipeline.PipelineJobException;
24+
import org.labkey.api.pipeline.PipelineJobService;
2225
import org.labkey.api.sequenceanalysis.SequenceOutputFile;
2326

2427
import java.io.File;
@@ -70,7 +73,20 @@ interface Output extends PipelineStepOutput
7073

7174
interface RequiresPedigree
7275
{
76+
default String getDemographicsProviderName(PipelineStepProvider<?> provider, PipelineJob job, int stepIdx)
77+
{
78+
return provider.getParameterByName(PedigreeToolParameterDescriptor.NAME).extractValue(job, provider, stepIdx, String.class);
79+
}
7380

81+
default DemographicsProvider getDemographicsProvider(PipelineStepProvider<?> provider, PipelineJob job, int stepIdx)
82+
{
83+
if (PipelineJobService.get().getLocationType() != PipelineJobService.LocationType.WebServer)
84+
{
85+
throw new IllegalStateException("getDemographicsProvider() can only be run from the webserver");
86+
}
87+
88+
return LaboratoryService.get().getDemographicsProviderByName(job.getContainer(), job.getUser(), getDemographicsProviderName(provider, job, stepIdx));
89+
}
7490
}
7591

7692
interface SupportsScatterGather

SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisServiceImpl.java

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
import org.labkey.api.data.CompareType;
1313
import org.labkey.api.data.Container;
1414
import org.labkey.api.data.ContainerManager;
15-
import org.labkey.api.data.Selector;
1615
import org.labkey.api.data.SimpleFilter;
1716
import org.labkey.api.data.TableInfo;
1817
import org.labkey.api.data.TableSelector;
1918
import org.labkey.api.exp.api.ExpData;
2019
import org.labkey.api.exp.api.ExperimentService;
20+
import org.labkey.api.laboratory.DemographicsProvider;
2121
import org.labkey.api.laboratory.NavItem;
2222
import org.labkey.api.module.Module;
2323
import org.labkey.api.module.ModuleLoader;
@@ -57,8 +57,6 @@
5757

5858
import java.io.File;
5959
import java.io.IOException;
60-
import java.sql.ResultSet;
61-
import java.sql.SQLException;
6260
import java.util.ArrayList;
6361
import java.util.Collection;
6462
import java.util.Collections;
@@ -361,25 +359,20 @@ public Integer getExpRunIdForJob(PipelineJob job, boolean throwUnlessFound) thro
361359
}
362360

363361
@Override
364-
public List<PedigreeRecord> generatePedigree(Collection<String> sampleNames, Container c, User u)
362+
public List<PedigreeRecord> generatePedigree(Collection<String> sampleNames, Container c, User u, DemographicsProvider d)
365363
{
366364
final List<PedigreeRecord> pedigreeRecords = new ArrayList<>();
367365

368-
TableInfo subjectTable = QueryService.get().getUserSchema(u, (c.isWorkbook() ? c.getParent() : c), "laboratory").getTable("subjects");
369-
TableSelector ts = new TableSelector(subjectTable, PageFlowUtil.set("subjectname", "mother", "father", "gender"), new SimpleFilter(FieldKey.fromString("subjectname"), sampleNames, CompareType.IN), null);
370-
ts.forEach(new Selector.ForEachBlock<ResultSet>()
371-
{
372-
@Override
373-
public void exec(ResultSet rs) throws SQLException
374-
{
375-
PedigreeRecord pedigree = new PedigreeRecord();
376-
pedigree.setSubjectName(rs.getString("subjectname"));
377-
pedigree.setFather(rs.getString("father"));
378-
pedigree.setMother(rs.getString("mother"));
379-
pedigree.setGender(rs.getString("gender"));
380-
if (!StringUtils.isEmpty(pedigree.getSubjectName()))
381-
pedigreeRecords.add(pedigree);
382-
}
366+
TableInfo subjectTable = QueryService.get().getUserSchema(u, (c.isWorkbook() ? c.getParent() : c), d.getSchema()).getTable(d.getQuery());
367+
TableSelector ts = new TableSelector(subjectTable, PageFlowUtil.set(d.getSubjectField(), d.getMotherField(), d.getFatherField(), "gender"), new SimpleFilter(FieldKey.fromString(d.getSubjectField()), sampleNames, CompareType.IN), null);
368+
ts.forEach(rs -> {
369+
PedigreeRecord pedigree = new PedigreeRecord();
370+
pedigree.setSubjectName(rs.getString(d.getSubjectField()));
371+
pedigree.setFather(rs.getString(d.getFatherField()));
372+
pedigree.setMother(rs.getString(d.getMotherField()));
373+
pedigree.setGender(rs.getString(d.getSexField()));
374+
if (!StringUtils.isEmpty(pedigree.getSubjectName()))
375+
pedigreeRecords.add(pedigree);
383376
});
384377

385378
//insert record for any missing parents:

SequenceAnalysis/src/org/labkey/sequenceanalysis/SequencePipelineServiceImpl.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class SequencePipelineServiceImpl extends SequencePipelineService
5858
private static final SequencePipelineServiceImpl _instance = new SequencePipelineServiceImpl();
5959

6060
private static final Logger _log = LogManager.getLogger(SequencePipelineServiceImpl.class);
61-
private final Set<PipelineStepProvider> _providers = new HashSet<>();
61+
private final Set<PipelineStepProvider<?>> _providers = new HashSet<>();
6262
private final Set<JobResourceSettings> _resourceSettings = new HashSet<>();
6363

6464
private final Map<Class<? extends PipelineStep>, String> _pipelineStepTypeMap = new HashMap<>();
@@ -85,14 +85,14 @@ public void registerPipelineStepType(Class<? extends PipelineStep> clazz, String
8585
}
8686

8787
@Override
88-
public void registerPipelineStep(PipelineStepProvider provider)
88+
public void registerPipelineStep(PipelineStepProvider<?> provider)
8989
{
9090
_log.info("registering sequence pipeline provider: " + provider.getName());
9191
_providers.add(provider);
9292
}
9393

9494
@Override
95-
public Set<PipelineStepProvider> getAllProviders()
95+
public Set<PipelineStepProvider<?>> getAllProviders()
9696
{
9797
return Collections.unmodifiableSet(_providers);
9898
}
@@ -101,19 +101,40 @@ public Set<PipelineStepProvider> getAllProviders()
101101
public <StepType extends PipelineStep> Set<PipelineStepProvider<StepType>> getProviders(Class<StepType> stepType)
102102
{
103103
Set<PipelineStepProvider<StepType>> ret = new HashSet<>();
104-
for (PipelineStepProvider provider : _providers)
104+
for (PipelineStepProvider<?> provider : _providers)
105105
{
106-
ParameterizedType parameterizedType = (ParameterizedType)provider.getClass().getGenericSuperclass();
107-
Class clazz = (Class)parameterizedType.getActualTypeArguments()[0];
106+
Class<?> clazz = findSuperClassParameterType(provider, 0);
107+
if (clazz == null)
108+
{
109+
_log.error("Unable to infer parameter type for provider: " + provider.getName());
110+
continue;
111+
}
112+
108113
if (stepType.isAssignableFrom(clazz))
109114
{
110-
ret.add(provider);
115+
ret.add((PipelineStepProvider<StepType>)provider);
111116
}
112117
}
113118

114119
return ret;
115120
}
116121

122+
// Based on: https://www.javacodegeeks.com/2013/12/advanced-java-generics-retreiving-generic-type-arguments.html
123+
private static Class<?> findSuperClassParameterType(Object instance, int parameterIndex) {
124+
Class<?> clazz = instance.getClass();
125+
while (clazz != clazz.getSuperclass()) {
126+
if (clazz.getGenericSuperclass() instanceof ParameterizedType pt)
127+
{
128+
return (Class<?>) pt.getActualTypeArguments()[parameterIndex];
129+
}
130+
131+
132+
clazz = clazz.getSuperclass();
133+
}
134+
135+
return null;
136+
}
137+
117138
@Override
118139
public <StepType extends PipelineStep> PipelineStepProvider<StepType> getProviderByName(String name, Class<StepType> stepType)
119140
{

0 commit comments

Comments
 (0)