diff --git a/specimen/api-src/org/labkey/api/specimen/SpecimensPage.java b/specimen/api-src/org/labkey/api/specimen/SpecimensPage.java new file mode 100644 index 00000000..a9ccb116 --- /dev/null +++ b/specimen/api-src/org/labkey/api/specimen/SpecimensPage.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021-2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.api.specimen; + +import org.labkey.api.data.Container; +import org.labkey.api.security.User; +import org.labkey.api.study.Study; +import org.labkey.api.study.StudyService; +import org.labkey.api.view.FolderTab; +import org.labkey.api.view.Portal; +import org.labkey.api.view.ViewContext; +import org.labkey.api.view.WebPartFactory; + +import java.util.ArrayList; +import java.util.List; + +public class SpecimensPage extends FolderTab.PortalPage +{ + public static final String PAGE_ID = "study.SPECIMENS"; + public static final String SPECIMEN_TOOLS_WEBPART_NAME = "Specimen Tools"; // TODO: Move back to SpecimenToolsWebPartFactory + + public SpecimensPage(String caption) + { + super(PAGE_ID, caption); + } + + @Override + public boolean isSelectedPage(ViewContext viewContext) + { + return super.isSelectedPage(viewContext) || + "specimen".equals(viewContext.getActionURL().getController()); + } + + @Override + public boolean isVisible(Container c, User user) + { + Study study = StudyService.get().getStudy(c); + if (study != null) + { + return SpecimenManager.get().isSpecimenModuleActive(c); + } + return false; + } + + @Override + public List createWebParts() + { + List parts = new ArrayList<>(); + parts.add(Portal.getPortalPart(StudyService.SPECIMEN_SEARCH_WEBPART).createWebPart()); + parts.add(Portal.getPortalPart(StudyService.SPECIMEN_BROWSE_WEBPART).createWebPart()); + Portal.WebPart toolsWebPart = Portal.getPortalPart(SPECIMEN_TOOLS_WEBPART_NAME).createWebPart(); + toolsWebPart.setLocation(WebPartFactory.LOCATION_RIGHT); + parts.add(toolsWebPart); + return parts; + } +} diff --git a/specimen/build.gradle b/specimen/build.gradle index c746886c..5430d225 100644 --- a/specimen/build.gradle +++ b/specimen/build.gradle @@ -20,6 +20,7 @@ plugins { } dependencies { + BuildUtils.addLabKeyDependency(project: project, config: "apiImplementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "apiJarFile") BuildUtils.addLabKeyDependency(project: project, config: "implementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "apiJarFile") BuildUtils.addLabKeyDependency(project: project, config: "jspImplementation", depProjectPath: BuildUtils.getPlatformModuleProjectPath(project.gradle, "study"), depProjectConfig: "apiJarFile") diff --git a/specimen/src/org/labkey/specimen/SpecimenManager.java b/specimen/src/org/labkey/specimen/SpecimenManager.java index 8ef913b9..9096d5f1 100644 --- a/specimen/src/org/labkey/specimen/SpecimenManager.java +++ b/specimen/src/org/labkey/specimen/SpecimenManager.java @@ -38,7 +38,6 @@ import org.labkey.api.security.User; import org.labkey.api.specimen.SpecimenEvent; import org.labkey.api.specimen.SpecimenEventManager; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.Vial; import org.labkey.api.specimen.location.LocationImpl; diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index ae064367..045c7589 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -47,7 +47,6 @@ import org.labkey.api.security.permissions.Permission; import org.labkey.api.security.roles.RoleManager; import org.labkey.api.specimen.SpecimenMigrationService; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.SpecimensPage; import org.labkey.api.specimen.model.SpecimenTablesProvider; diff --git a/specimen/src/org/labkey/specimen/SpecimenQuerySchema.java b/specimen/src/org/labkey/specimen/SpecimenQuerySchema.java new file mode 100644 index 00000000..e177d46d --- /dev/null +++ b/specimen/src/org/labkey/specimen/SpecimenQuerySchema.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021-2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.specimen; + +import org.jetbrains.annotations.Nullable; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.TableInfo; +import org.labkey.api.query.UserSchema; +import org.labkey.api.security.User; +import org.labkey.api.study.Study; +import org.labkey.api.study.StudyService; + +import java.util.Set; + +public class SpecimenQuerySchema extends UserSchema +{ + public static final String SCHEMA_NAME = "Study"; + public static final String LOCATION_TABLE_NAME = "Location"; + + private final UserSchema _studySchema; + private final Study _study; + + public SpecimenQuerySchema(Study study, UserSchema studySchema) + { + super(studySchema.getName(), studySchema.getDescription(), studySchema.getUser(), studySchema.getContainer(), studySchema.getDbSchema()); + _study = study; + _studySchema = studySchema; + } + + public static SpecimenQuerySchema get(Study study, User user) + { + return new SpecimenQuerySchema(study, StudyService.get().getStudyQuerySchema(study, user)); + } + + public Study getStudy() + { + return _study; + } + + @Override + public @Nullable TableInfo createTable(String name, ContainerFilter cf) + { + return _studySchema.createTable(name, cf); + } + + @Override + public Set getTableNames() + { + return _studySchema.getTableNames(); + } +} diff --git a/specimen/src/org/labkey/specimen/SpecimenRequestManager.java b/specimen/src/org/labkey/specimen/SpecimenRequestManager.java index d42afd45..4aaa82d7 100644 --- a/specimen/src/org/labkey/specimen/SpecimenRequestManager.java +++ b/specimen/src/org/labkey/specimen/SpecimenRequestManager.java @@ -49,7 +49,6 @@ import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; import org.labkey.api.settings.AppProps; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.Vial; import org.labkey.api.specimen.importer.RollupHelper; diff --git a/specimen/src/org/labkey/specimen/actions/ReportConfigurationBean.java b/specimen/src/org/labkey/specimen/actions/ReportConfigurationBean.java index b943deae..7e43394e 100644 --- a/specimen/src/org/labkey/specimen/actions/ReportConfigurationBean.java +++ b/specimen/src/org/labkey/specimen/actions/ReportConfigurationBean.java @@ -20,7 +20,7 @@ import org.labkey.api.query.QueryService; import org.labkey.api.query.SchemaKey; import org.labkey.api.query.UserSchema; -import org.labkey.api.specimen.SpecimenQuerySchema; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.report.SpecimenVisitReportParameters; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; diff --git a/specimen/src/org/labkey/specimen/actions/SpecimenController.java b/specimen/src/org/labkey/specimen/actions/SpecimenController.java index f46bc978..bd93b6b5 100644 --- a/specimen/src/org/labkey/specimen/actions/SpecimenController.java +++ b/specimen/src/org/labkey/specimen/actions/SpecimenController.java @@ -107,7 +107,6 @@ import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.permissions.ReadPermission; import org.labkey.api.security.permissions.UpdatePermission; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.Vial; import org.labkey.api.specimen.location.LocationImpl; @@ -116,7 +115,6 @@ import org.labkey.api.specimen.model.SpecimenTablesProvider; import org.labkey.api.study.CohortFilter; import org.labkey.api.study.Dataset; -import org.labkey.api.study.MapArrayExcelWriter; import org.labkey.api.study.SpecimenService; import org.labkey.api.study.SpecimenTransform; import org.labkey.api.study.SpecimenUrls; @@ -168,6 +166,7 @@ import org.labkey.specimen.RequestedSpecimens; import org.labkey.specimen.SpecimenManager; import org.labkey.specimen.SpecimenModule; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.SpecimenRequestException; import org.labkey.specimen.SpecimenRequestManager; import org.labkey.specimen.SpecimenRequestStatus; @@ -206,6 +205,7 @@ import org.labkey.specimen.settings.RequestNotificationSettings; import org.labkey.specimen.settings.SettingsManager; import org.labkey.specimen.settings.StatusSettings; +import org.labkey.specimen.study.MapArrayExcelWriter; import org.labkey.specimen.view.NotificationBean; import org.labkey.specimen.view.SpecimenRequestNotificationEmailTemplate; import org.labkey.specimen.view.SpecimenSearchWebPart; diff --git a/specimen/src/org/labkey/specimen/actions/SpecimenHeaderBean.java b/specimen/src/org/labkey/specimen/actions/SpecimenHeaderBean.java index 91d0f3f1..6b4b782b 100644 --- a/specimen/src/org/labkey/specimen/actions/SpecimenHeaderBean.java +++ b/specimen/src/org/labkey/specimen/actions/SpecimenHeaderBean.java @@ -19,12 +19,12 @@ import org.labkey.api.data.TableInfo; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryService; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; import org.labkey.api.view.ActionURL; import org.labkey.api.view.NotFoundException; import org.labkey.api.view.ViewContext; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.actions.SpecimenController.PtidVisit; import org.labkey.specimen.query.SpecimenQueryView; diff --git a/specimen/src/org/labkey/specimen/importer/QueryBasedTransformTask.java b/specimen/src/org/labkey/specimen/importer/QueryBasedTransformTask.java index e05e6341..bc448675 100644 --- a/specimen/src/org/labkey/specimen/importer/QueryBasedTransformTask.java +++ b/specimen/src/org/labkey/specimen/importer/QueryBasedTransformTask.java @@ -18,12 +18,12 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; import org.labkey.api.collections.CaseInsensitiveHashSet; -import org.labkey.api.pipeline.AbstractSpecimenTransformTask; import org.labkey.api.pipeline.PipelineJob; import org.labkey.api.pipeline.PipelineJobException; import org.labkey.api.reader.DataLoader; import org.labkey.api.reader.DataLoaderFactory; import org.labkey.api.writer.PrintWriters; +import org.labkey.specimen.pipeline.AbstractSpecimenTransformTask; import org.labkey.vfs.FileLike; import java.io.IOException; diff --git a/specimen/src/org/labkey/specimen/pipeline/AbstractSpecimenTransformTask.java b/specimen/src/org/labkey/specimen/pipeline/AbstractSpecimenTransformTask.java new file mode 100644 index 00000000..eda3b25f --- /dev/null +++ b/specimen/src/org/labkey/specimen/pipeline/AbstractSpecimenTransformTask.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2013-2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.specimen.pipeline; + +import org.apache.commons.beanutils.ConversionException; +import org.jetbrains.annotations.Nullable; +import org.labkey.api.collections.ArrayListMap; +import org.labkey.api.data.TSVMapWriter; +import org.labkey.api.pipeline.PipelineJob; +import org.labkey.api.util.DateUtil; +import org.labkey.api.util.FileUtil; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static org.labkey.api.util.IntegerUtils.asIntegerElseNull; + +public abstract class AbstractSpecimenTransformTask +{ + protected final PipelineJob _job; + + public AbstractSpecimenTransformTask(PipelineJob job) + { + _job = job; + } + + /** + * Transform a row of data from the parsed input data file the transformed specimen row + * During the transform, it's expected that any lab, primary, derivative and additive + * information would be extracted. + * + * @return the transformed specimen row + */ + protected abstract Map transformRow(Map inputRow, int rowIndex, Map labIds, Map primaryIds, Map derivativeIds); + + protected abstract Set getIgnoredHashColumns(); + protected abstract Map getLabIds(); + protected abstract Map getPrimaryIds(); + protected abstract Map getDerivativeIds(); + protected abstract Map getAdditiveIds(); + private int rowIndex = 0; + private final Set hashes = new HashSet<>(); + + protected List> transformRows(List> inputRows) + { + return inputRows + .stream() + .filter(MapFilter.getMapFilter(this)) + .map(MapTransformer.getMapTransformer(this, getLabIds(), getPrimaryIds(), getDerivativeIds())) + .collect(Collectors.toList()); + } + + protected interface MapFilter extends Predicate> + { + static MapFilter getMapFilter(AbstractSpecimenTransformTask task) + { + return row -> { + try + { + return task.hashes.add(task.hashRow(row)); + } + catch (IOException e) + { + return true; // Keep row + } + }; + } + } + + protected interface MapTransformer extends UnaryOperator> + { + static MapTransformer getMapTransformer(AbstractSpecimenTransformTask task, Map labIds, Map primaryIds, Map derivativeIds) + { + return row -> task.transformRow(row, task.rowIndex++, labIds, primaryIds, derivativeIds); + } + } + + /** Write out an empty additives.tsv, since we aren't using them */ + protected void writeAdditives(Map additiveIds, ZipOutputStream file) throws IOException + { + if (additiveIds.isEmpty()) + { + file.putNextEntry(new ZipEntry("additives.tsv")); + + try (PrintWriter writer = new PrintWriter(file)) + { + writer.write("# additives\n"); + writer.write("additive_id\tldms_additive_code\tlabware_additive_code\tadditive\n"); + } + } + else + { + List> rows = new ArrayList<>(); + for (Map.Entry entry : additiveIds.entrySet()) + { + Map row = new HashMap<>(); + + // We know the id and the type name + row.put("additive_id", entry.getValue()); + row.put("additive", entry.getKey()); + // All the other columns are blank + row.put("ldms_additive_code", null); + row.put("labware_additive_code", null); + + rows.add(row); + } + writeTSV(file, rows, "additives"); + } + } + + protected void writePrimaries(Map primaryIds, ZipOutputStream file) throws IOException + { + List> rows = new ArrayList<>(); + for (Map.Entry entry : primaryIds.entrySet()) + { + Map row = new HashMap<>(); + // We know the id and the type name + row.put("primary_type_id", entry.getValue()); + row.put("primary_type", entry.getKey()); + // All the other columns are blank + row.put("primary_type_ldms_code", null); + row.put("primary_type_labware_code", null); + rows.add(row); + } + + writeTSV(file, rows, "primary_types"); + } + + protected void writeDerivatives(Map derivatives, ZipOutputStream file) throws IOException + { + List> rows = new ArrayList<>(); + for (Map.Entry entry : derivatives.entrySet()) + { + Map row = new HashMap<>(); + // We know the id and the name + row.put("derivative_id", entry.getValue()); + row.put("derivative", entry.getKey()); + // Everything else is left blank + row.put("ldms_derivative_code", null); + row.put("labware_derivative_code", null); + rows.add(row); + } + + writeTSV(file, rows, "derivatives"); + } + + protected void writeLabs(Map labIds, ZipOutputStream file) throws IOException + { + List> rows = new ArrayList<>(); + for (Map.Entry entry : labIds.entrySet()) + { + Map row = new HashMap<>(); + // We know the id and the name + row.put("lab_id", entry.getValue()); + row.put("lab_name", entry.getKey()); + row.put("ldms_lab_code", -1); // ldms code required : issue #22217 + // Everything else is left blank + row.put("lab_upload_code", null); + row.put("is_sal", null); + row.put("is_repository", null); + row.put("is_clinic", null); + row.put("is_endpoint", null); + rows.add(row); + } + + writeTSV(file, rows, "labs"); + } + + protected String hashRow(Map inputRow) throws IOException + { + // Check that Map is a type that has consistent key ordering + if (!(inputRow instanceof ArrayListMap)) + throw new IllegalStateException(); + + StringBuilder sb = new StringBuilder(); + for (String key : inputRow.keySet()) + { + if (!getIgnoredHashColumns().contains(key)) + { + sb.append(key); + sb.append(": "); + sb.append(String.valueOf(inputRow.get(key))); + sb.append(";"); + } + } + + // Hash the row to reduce the size in memory + return FileUtil.sha1sum(sb.toString().getBytes()); + } + + protected void writeTSV(ZipOutputStream zOut, List> outputRows, String baseName) throws IOException + { + // Add a new file to the ZIP + zOut.putNextEntry(new ZipEntry(baseName + ".tsv")); + PrintWriter writer = new PrintWriter(zOut); + try + { + TSVMapWriter tsvWriter = new TSVMapWriter(outputRows); + // Write a comment into the header + tsvWriter.setFileHeader(Collections.singletonList("# " + baseName)); + // Set the writer separately from the call to write() so that the underlying stream doesn't get closed + // when it's finished writing the TSV - we need to keep writing to the ZIP + if (!outputRows.isEmpty()) + { + tsvWriter.setPrintWriter(writer); + tsvWriter.write(); + } + } + finally + { + writer.flush(); + zOut.closeEntry(); + } + } + + protected static class SpecimenTransformTSVWriter extends TSVMapWriter + { + private int _rowCount; + public SpecimenTransformTSVWriter(Iterable> rows) + { + super(new ArrayList<>(), rows); // start with empty column list + } + + @Override + public void writeRow(Map row) + { + if (null != row) + { + if (_rowCount == 0) + { + writeFileHeader(); + setColumns(row.keySet()); + writeColumnHeaders(); + + } + super.writeRow(row); + _rowCount++; + } + } + + public int getRowCount() + { + return _rowCount; + } + } + + protected void toDate(String key, Map row) + { + Object d = row.get(key); + if (null == d || d instanceof Date) + return; + try + { + Date date = new Date(DateUtil.parseDateTime(String.valueOf(d))); + row.put(key,date); + } + catch (ConversionException x) + { + /* */ + } + } + + @Nullable + protected Date parseDateTime(String keyDate, @Nullable String keyTime, Map row) + { + Object d = row.get(keyDate); + if (null == d) + return null; + try + { + Date date = d instanceof Date ? (Date)d : new Date(DateUtil.parseDateTime(String.valueOf(d))); + if (keyTime != null) + { + Object t = row.get(keyTime); + if (t != null) + { + long time = DateUtil.parseTimeToMillis(String.valueOf(t)); + date = new Date(date.getTime() + time); + } + } + return date; + } + catch (ConversionException x) + { + /* */ + } + return null; + } + + protected Date parseDate(String keyDate, Map row) + { + Object d = row.get(keyDate); + if (null == d) + return null; + try + { + Date date = d instanceof Date ? (Date)d : new Date(DateUtil.parseDateTime(String.valueOf(d))); + return date; + } + catch (ConversionException x) + { + /* */ + } + return null; + } + + protected void toInt(String key, Map row) + { + Object o = row.get(key); + if (null == o || o instanceof Integer) + return; + try + { + if (asIntegerElseNull(o) instanceof Integer i) + o = i; + else + o = Integer.parseInt(String.valueOf(o)); + row.put(key,o); + } + catch (NumberFormatException x) + { + /* */ + } + } + + protected String getNonNullValue(Map inputRow, String name) + { + return inputRow.get(name) == null ? "" : inputRow.get(name).toString(); + } + + protected String removeNonNullValue(Map inputRow, String name) + { + Object o = inputRow.remove(name); + return o == null ? "" : o.toString(); + } + + protected void debug(String msg) + { + if (null != _job) + _job.debug(msg); + } + + + protected void info(String msg) + { + if (null != _job) + _job.info(msg); + } + + + protected void warn(String msg) + { + if (null != _job) + _job.warn(msg); + } + + protected void error(String msg) + { + if (null != _job) + _job.error(msg); + } +} diff --git a/specimen/src/org/labkey/specimen/query/SpecimenEventQueryView.java b/specimen/src/org/labkey/specimen/query/SpecimenEventQueryView.java index 09e25233..206c068e 100644 --- a/specimen/src/org/labkey/specimen/query/SpecimenEventQueryView.java +++ b/specimen/src/org/labkey/specimen/query/SpecimenEventQueryView.java @@ -21,11 +21,11 @@ import org.labkey.api.query.FieldKey; import org.labkey.api.query.QuerySettings; import org.labkey.api.query.UserSchema; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.Vial; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; import org.labkey.api.view.ViewContext; +import org.labkey.specimen.SpecimenQuerySchema; /** * User: brittp diff --git a/specimen/src/org/labkey/specimen/query/SpecimenQueryView.java b/specimen/src/org/labkey/specimen/query/SpecimenQueryView.java index 22903bfc..873b9661 100644 --- a/specimen/src/org/labkey/specimen/query/SpecimenQueryView.java +++ b/specimen/src/org/labkey/specimen/query/SpecimenQueryView.java @@ -46,7 +46,6 @@ import org.labkey.api.query.UserSchema; import org.labkey.api.reports.report.ReportUrls; import org.labkey.api.security.User; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.Vial; import org.labkey.api.specimen.model.SpecimenTablesProvider; @@ -63,6 +62,7 @@ import org.labkey.api.view.DataView; import org.labkey.api.view.ViewContext; import org.labkey.api.writer.HtmlWriter; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.actions.SpecimenController; import org.labkey.specimen.security.permissions.EditSpecimenDataPermission; import org.labkey.specimen.security.permissions.RequestSpecimensPermission; diff --git a/specimen/src/org/labkey/specimen/query/SpecimenRequestQueryView.java b/specimen/src/org/labkey/specimen/query/SpecimenRequestQueryView.java index 851d0c9b..44d5c5a0 100644 --- a/specimen/src/org/labkey/specimen/query/SpecimenRequestQueryView.java +++ b/specimen/src/org/labkey/specimen/query/SpecimenRequestQueryView.java @@ -28,7 +28,6 @@ import org.labkey.api.query.QuerySettings; import org.labkey.api.query.UserSchema; import org.labkey.api.security.User; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; import org.labkey.api.study.StudyUtils; @@ -37,6 +36,7 @@ import org.labkey.api.view.NavTree; import org.labkey.api.view.ViewContext; import org.labkey.api.writer.HtmlWriter; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.SpecimenRequestManager; import org.labkey.specimen.SpecimenRequestStatus; import org.labkey.specimen.actions.SpecimenController.DeleteRequestAction; diff --git a/specimen/src/org/labkey/specimen/report/SpecimenReportManager.java b/specimen/src/org/labkey/specimen/report/SpecimenReportManager.java index 3e127c7d..b485ffed 100644 --- a/specimen/src/org/labkey/specimen/report/SpecimenReportManager.java +++ b/specimen/src/org/labkey/specimen/report/SpecimenReportManager.java @@ -30,12 +30,12 @@ import org.labkey.api.query.QueryService; import org.labkey.api.query.UserSchema; import org.labkey.api.security.User; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.model.SpecimenTablesProvider; import org.labkey.api.study.CohortFilter; import org.labkey.api.study.StudyService; import org.labkey.api.view.ActionURL; +import org.labkey.specimen.SpecimenQuerySchema; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; diff --git a/specimen/src/org/labkey/specimen/report/SpecimenVisitReport.java b/specimen/src/org/labkey/specimen/report/SpecimenVisitReport.java index 52530500..e84f82f3 100644 --- a/specimen/src/org/labkey/specimen/report/SpecimenVisitReport.java +++ b/specimen/src/org/labkey/specimen/report/SpecimenVisitReport.java @@ -24,7 +24,6 @@ import org.labkey.api.query.QueryService; import org.labkey.api.query.UserSchema; import org.labkey.api.security.User; -import org.labkey.api.specimen.SpecimenQuerySchema; import org.labkey.api.study.CohortFilter; import org.labkey.api.study.Study; import org.labkey.api.study.StudyService; @@ -34,6 +33,7 @@ import org.labkey.api.util.PageFlowUtil; import org.labkey.api.view.ActionURL; import org.labkey.api.view.NotFoundException; +import org.labkey.specimen.SpecimenQuerySchema; import org.labkey.specimen.query.SpecimenQueryView; import java.util.ArrayList; diff --git a/specimen/src/org/labkey/specimen/study/MapArrayExcelWriter.java b/specimen/src/org/labkey/specimen/study/MapArrayExcelWriter.java new file mode 100644 index 00000000..649cdb91 --- /dev/null +++ b/specimen/src/org/labkey/specimen/study/MapArrayExcelWriter.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008-2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.labkey.specimen.study; + +import org.apache.poi.ss.usermodel.Sheet; +import org.labkey.api.data.AbstractExcelDisplayColumn; +import org.labkey.api.data.DisplayColumn; +import org.labkey.api.data.ExcelColumn; +import org.labkey.api.data.ExcelWriter; +import org.labkey.api.data.RenderContext; +import org.labkey.api.reader.ColumnDescriptor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class MapArrayExcelWriter extends ExcelWriter +{ + private final List> maps; + private int currentRow = 0; + + public MapArrayExcelWriter(List> maps, ColumnDescriptor[] cols) + { + super(ExcelDocumentType.xls); + this.maps = maps; + List xlcols = new ArrayList<>(); + for (ColumnDescriptor col : cols) + xlcols.add(new MapArrayDisplayColumn(col.name, col.clazz)); + + setDisplayColumns(xlcols); + } + + @Override + public void renderGrid(RenderContext ctx, Sheet sheet, List visibleColumns) throws MaxRowsExceededException + { + for (currentRow = 0; currentRow < maps.size(); currentRow++) + { + renderGridRow(sheet, ctx, visibleColumns); + } + } + + public class MapArrayDisplayColumn extends AbstractExcelDisplayColumn + { + public MapArrayDisplayColumn(String name, Class valueClass) + { + super(name, name, valueClass); + } + + @Override + public Object getValue(RenderContext ctx) + { + //Ignore the context. + return maps.get(currentRow).get(getName()); + } + } +} diff --git a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java b/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java index ca01ff54..271ead5f 100644 --- a/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java +++ b/studydesign/src/org/labkey/studydesign/model/AssaySpecimenVisitImpl.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import org.labkey.api.data.Container; -import org.labkey.api.study.AssaySpecimenVisit; +import org.labkey.studydesign.study.AssaySpecimenVisit; import java.util.HashMap; import java.util.Map; diff --git a/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java b/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java index 2285c472..ba08e0e9 100644 --- a/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java +++ b/studydesign/src/org/labkey/studydesign/model/ProductAntigenImpl.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import org.labkey.api.data.Container; -import org.labkey.api.study.ProductAntigen; +import org.labkey.studydesign.study.ProductAntigen; import java.util.HashMap; import java.util.Map; diff --git a/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java b/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java index ab1c3496..d2a9260b 100644 --- a/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java +++ b/studydesign/src/org/labkey/studydesign/model/TreatmentProductImpl.java @@ -18,8 +18,8 @@ import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import org.labkey.api.data.Container; -import org.labkey.api.study.TreatmentProduct; import org.labkey.api.util.Pair; +import org.labkey.studydesign.study.TreatmentProduct; import java.util.HashMap; import java.util.Map; diff --git a/studydesign/src/org/labkey/studydesign/study/AssaySpecimenVisit.java b/studydesign/src/org/labkey/studydesign/study/AssaySpecimenVisit.java new file mode 100644 index 00000000..ae63193e --- /dev/null +++ b/studydesign/src/org/labkey/studydesign/study/AssaySpecimenVisit.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.studydesign.study; + +/** + * Created by cnathe on 2/3/14. + */ +public interface AssaySpecimenVisit +{ + int getAssaySpecimenId(); + int getVisitId(); +} \ No newline at end of file diff --git a/studydesign/src/org/labkey/studydesign/study/ProductAntigen.java b/studydesign/src/org/labkey/studydesign/study/ProductAntigen.java new file mode 100644 index 00000000..4f209f2a --- /dev/null +++ b/studydesign/src/org/labkey/studydesign/study/ProductAntigen.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.studydesign.study; + +/** + * User: cnathe + * Date: 12/26/13 + */ +public interface ProductAntigen +{ + int getRowId(); + int getProductId(); + String getGene(); + String getSubType(); + String getGenBankId(); + String getSequence(); +} diff --git a/studydesign/src/org/labkey/studydesign/study/TreatmentProduct.java b/studydesign/src/org/labkey/studydesign/study/TreatmentProduct.java new file mode 100644 index 00000000..5d717d00 --- /dev/null +++ b/studydesign/src/org/labkey/studydesign/study/TreatmentProduct.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.studydesign.study; + +/** + * User: cnathe + * Date: 12/27/13 + */ +public interface TreatmentProduct +{ + int getRowId(); + int getTreatmentId(); + int getProductId(); + String getDose(); + String getRoute(); +}