Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/schemas/expTypes.xsd
Original file line numberDiff line numberDiff line change
Expand Up@@ -230,6 +230,18 @@
<xs:attribute ref="rdf:parseType" fixed="Collection"/>
</xs:complexType>
</xs:element>
<xs:element name="ProvenanceMap" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="ObjectRefs" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="from" type="string" use="optional"/>
<xs:attribute name="to" type="string" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Properties" type="exp:PropertyCollectionType" minOccurs="0"/>
</xs:sequence>
<xs:attribute ref="rdf:about" use="required"/>
Expand Down
48 changes: 47 additions & 1 deletion api/src/org/labkey/api/assay/AbstractAssayProvider.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -1533,10 +1533,56 @@ public String getRunLSIDPrefix()
return "urn:lsid:" + Lsid.encodePart(AppProps.getInstance().getDefaultLsidAuthority()) + ":" + Lsid.encodePart(getResultRowLSIDPrefix());
}

@Override
public Pair<ExpProtocol, Integer> getAssayResultRowIdFromLsid(Container container, Lsid assayResultRowLsid)
{
assert getResultRowLSIDPrefix().equals(assayResultRowLsid.getNamespacePrefix());
String namespaceSuffix = assayResultRowLsid.getNamespaceSuffix();

// LSID namespace suffix format expected to be: "Protocol-" + <protocol-row-id>
ExpProtocol protocol = null;
if (namespaceSuffix.startsWith("Protocol-"))
{
try
{
int protocolId = Integer.parseInt(namespaceSuffix.substring("Protocol-".length()));
if (protocolId > 0)
protocol = ExperimentService.get().getExpProtocol(protocolId);
}
catch (NumberFormatException ex)
{
// ignore
}
}

if (protocol == null)
return null;

// LSID object id expected to be rowId
int rowId = -1;
try
{
rowId = Integer.parseInt(assayResultRowLsid.getObjectId());
}
catch (NumberFormatException ex)
{
// ignore
}

if (rowId <= 0)
return null;

return Pair.of(protocol, rowId);
}

@Override
public @Nullable ActionURL getResultRowURL(Container container, Lsid lsid)
{
return PageFlowUtil.urlProvider(AssayUrls.class).getAssayResultRowURL(this, container, lsid);
var pair = getAssayResultRowIdFromLsid(container, lsid);
if (pair == null)
return null;

return PageFlowUtil.urlProvider(AssayUrls.class).getAssayResultRowURL(this, container, pair.first, pair.second);
}

@Override
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -234,8 +234,10 @@ else if (mvIndicatorColumns.contains(column.name))
}
else
{
// It's not an expected column. Is it an MV indicator column?
if (!settings.isAllowUnexpectedColumns() && !mvIndicatorColumns.contains(column.name))
// It's not an expected column. Is it an MV indicator column or prov:objectInput column?
if (!settings.isAllowUnexpectedColumns() &&
!mvIndicatorColumns.contains(column.name) &&
!column.name.equalsIgnoreCase(ProvenanceService.PROVENANCE_INPUT_PROPERTY))
{
column.load = false;
}
Expand Down
6 changes: 6 additions & 0 deletions api/src/org/labkey/api/assay/AssayProvider.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -311,6 +311,12 @@ enum Scope
*/
@Nullable String getResultRowLSIDExpression();

/**
* Extract the ExpProtocol and rowId from an assay result row LSID.
*/
@Nullable
Pair<ExpProtocol, Integer> getAssayResultRowIdFromLsid(Container container, Lsid assayResultRowLsid);

/**
* Get the URL for an assay result row's LSID.
*/
Expand Down
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/assay/AssayUrls.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -55,7 +55,7 @@ public interface AssayUrls extends UrlProvider
ActionURL getAssayResultsURL(Container container, ExpProtocol protocol);
ActionURL getAssayResultsURL(Container container, ExpProtocol protocol, int... runIds);
ActionURL getAssayResultsURL(Container container, ExpProtocol protocol, ContainerFilter containerFilter, int... runIds);
@Nullable ActionURL getAssayResultRowURL(AssayProvider provider, Container container, Lsid assayResultRowLsid);
@Nullable ActionURL getAssayResultRowURL(AssayProvider provider, Container container, ExpProtocol protocol, int rowId);

ActionURL getShowUploadJobsURL(Container container, ExpProtocol protocol, ContainerFilter containerFilter);

Expand Down
18 changes: 18 additions & 0 deletions api/src/org/labkey/api/data/FilterInfo.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,14 @@

package org.labkey.api.data;

import org.json.JSONObject;
import org.labkey.api.query.FieldKey;
import org.labkey.api.util.URLHelper;

import java.io.Serializable;
import java.util.Map;

import static org.labkey.api.util.PageFlowUtil.encode;

/**
* Bean to capture a single filter on a single column.
Expand DownExpand Up@@ -94,4 +98,18 @@ public void applyToURL(URLHelper url, String regionName, FieldKey fieldKey)
String valueStr = value != null ? value : "";
url.addParameter(regionName + "." + fieldKey.toString() + "~" + opStr, valueStr);
}

public Map<String, String> toMap()
{
return Map.of(
"fieldKey", this.field.toString(),
"op", this.op != null ? this.op.getPreferredUrlKey() : "",
"value", this.value
);
}

public String toString()
{
return encode(field.toString()) + "~" + (this.op != null ? this.op.getPreferredUrlKey() : "") + "=" + encode(value);
}
}
13 changes: 13 additions & 0 deletions api/src/org/labkey/api/exp/Identifiable.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
*/
package org.labkey.api.exp;

import org.jetbrains.annotations.Nullable;
import org.labkey.api.data.Container;
import org.labkey.api.query.QueryRowReference;
import org.labkey.api.view.ActionURL;

/**
* Base functionality for objects that have an LSID.
Expand All@@ -34,4 +37,14 @@ default String getLSIDNamespacePrefix()
String getName();

Container getContainer();

default @Nullable ActionURL detailsURL()
{
return null;
}

default @Nullable QueryRowReference getQueryRowReference()
{
return null;
}
}
3 changes: 1 addition & 2 deletions api/src/org/labkey/api/exp/IdentifiableBase.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,13 +39,11 @@ public IdentifiableBase()

public IdentifiableBase(String lsid)
{
this();
_lsid = lsid;
}

public IdentifiableBase(OntologyObject oo)
{
this();
_lsid = oo.getObjectURI();
objectId = oo.getObjectId();
container = oo.getContainer();
Expand DownExpand Up@@ -97,6 +95,7 @@ public void setContainer(Container container)
this.container = container;
}


@Override
public boolean equals(Object o)
{
Expand Down
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/exp/Lsid.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -693,7 +693,7 @@ public void testBuilder()
assertEquals(b.toString(), lsid3.toString());
Lsid lsid4 = b.setObjectId("OBJ").build();

Lsid.LsidBuilder t = new Lsid.LsidBuilder(lsid1);
Lsid.LsidBuilder t = lsid1.edit();
assertEquals(lsid1,t.build());
assertEquals(lsid1.toString(),t.toString());
t.setVersion("3");
Expand Down
91 changes: 70 additions & 21 deletions api/src/org/labkey/api/exp/LsidManager.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.assay.AssayProtocolSchema;
import org.labkey.api.assay.AssayProvider;
import org.labkey.api.assay.AssayUrls;
import org.labkey.api.data.Container;
Expand All@@ -29,11 +30,14 @@
import org.labkey.api.exp.api.ExpProtocol;
import org.labkey.api.exp.api.ExpRun;
import org.labkey.api.exp.api.ExperimentService;
import org.labkey.api.query.FieldKey;
import org.labkey.api.query.QueryRowReference;
import org.labkey.api.security.User;
import org.labkey.api.security.permissions.Permission;
import org.labkey.api.security.permissions.ReadPermission;
import org.labkey.api.settings.AppProps;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.util.Pair;
import org.labkey.api.view.ActionURL;

import java.util.HashMap;
Expand DownExpand Up@@ -67,9 +71,9 @@ public static LsidManager get()
return INSTANCE;
}

public interface LsidHandler
public interface LsidHandler<I extends Identifiable>
{
Identifiable getObject(Lsid lsid);
I getObject(Lsid lsid);

@Nullable
ActionURL getDisplayURL(Lsid lsid);
Expand All@@ -79,13 +83,13 @@ public interface LsidHandler
boolean hasPermission(Lsid lsid, @NotNull User user, @NotNull Class<? extends Permission> perm);
}

public abstract static class ExpObjectLsidHandlerimplements LsidHandler
public abstract static class ExpObjectLsidHandler<I extends ExpObject> implements LsidHandler<I>
{
public abstract ExpObject getObject(Lsid lsid);
public abstract I getObject(Lsid lsid);

public Container getContainer(Lsid lsid)
{
ExpObject run = getObject(lsid);
I run = getObject(lsid);
return run == null ? null : run.getContainer();
}

Expand All@@ -96,7 +100,7 @@ public boolean hasPermission(Lsid lsid, @NotNull User user, @NotNull Class<? ext
}
}

public static class ExpRunLsidHandler extends ExpObjectLsidHandler
public static class ExpRunLsidHandler extends ExpObjectLsidHandler<ExpRun>
{
public ExpRun getObject(Lsid lsid)
{
Expand All@@ -123,22 +127,23 @@ protected ActionURL getDisplayURL(Container c, ExpProtocol protocol, ExpRun run)

// This is different from ExpObjectLsidHandler in that it supports generic
// OntologyObjects that don't fit into the ExpObject class hierarchy.
public static class OntologyObjectLsidHandlerimplements LsidHandler
public static class OntologyObjectLsidHandler<I extends IdentifiableBase> implements LsidHandler<I>
{
@Override
public Identifiable getObject(Lsid lsid)
public I getObject(Lsid lsid)
{
OntologyObject oo = OntologyManager.getOntologyObject(null, lsid.toString());
if (oo == null)
return null;

return new IdentifiableBase(oo);
return (I)new IdentifiableBase(oo);
}

@Override
public @Nullable ActionURL getDisplayURL(Lsid lsid)
public final @Nullable ActionURL getDisplayURL(Lsid lsid)
{
return null;
I obj = getObject(lsid);
return obj == null ? null : obj.detailsURL();
}

@Override
Expand All@@ -159,32 +164,76 @@ public boolean hasPermission(Lsid lsid, @NotNull User user, @NotNull Class<? ext
}
}

public static class AssayResultLsidHandler extends OntologyObjectLsidHandler
/**
* Represents a single row in the assay results table.
*/
public static class AssayResultIdentifiable extends IdentifiableBase
{
private final AssayProvider _provider;
private final ExpProtocol _protocol;
private int _rowId;

public AssayResultLsidHandler(AssayProvider provider)
public AssayResultIdentifiable(AssayProvider provider, OntologyObject oo, ExpProtocol protocol, int rowId)
{
super(oo);
_provider = provider;
assert _provider.getResultRowLSIDPrefix() != null;

Pair<ExpProtocol, Integer> pair = provider.getAssayResultRowIdFromLsid(oo.getContainer(), new Lsid(oo.getObjectURI()));
if (pair != null)
{
_protocol = pair.first;
_rowId = pair.second;
}
else
{
_protocol = null;
_rowId = 0;
}
}

@Override
public Identifiable getObject(Lsid lsid)
public @Nullable ActionURL detailsURL()
{
assert _provider.getResultRowLSIDPrefix().equals(lsid.getNamespacePrefix());
return super.getObject(lsid);
var urls = PageFlowUtil.urlProvider(AssayUrls.class);
if (urls == null)
return null;

return urls.getAssayResultRowURL(_provider, getContainer(), _protocol, _rowId);
}

@Override
public @Nullable ActionURL getDisplayURL(Lsid lsid)
public @Nullable QueryRowReference getQueryRowReference()
{
Container c = getContainer(lsid);
if (c == null)
var schemaKey = AssayProtocolSchema.schemaName(_provider, _protocol);
return new QueryRowReference(getContainer(), schemaKey, AssayProtocolSchema.DATA_TABLE_NAME, FieldKey.fromParts("rowId"), _rowId);
}
}

public static class AssayResultLsidHandler extends OntologyObjectLsidHandler<AssayResultIdentifiable>
{
private final AssayProvider _provider;

public AssayResultLsidHandler(AssayProvider provider)
{
_provider = provider;
assert _provider.getResultRowLSIDPrefix() != null;
}

@Override
public AssayResultIdentifiable getObject(Lsid lsid)
{
assert _provider.getResultRowLSIDPrefix().equals(lsid.getNamespacePrefix());
OntologyObject oo = OntologyManager.getOntologyObject(null, lsid.toString());
if (oo == null)
return null;

Pair<ExpProtocol, Integer> pair = _provider.getAssayResultRowIdFromLsid(oo.getContainer(), lsid);
if (pair == null)
return null;

return PageFlowUtil.urlProvider(AssayUrls.class).getAssayResultRowURL(_provider, c, lsid);
return new AssayResultIdentifiable(_provider, oo, pair.first, pair.second);
}

}

public void registerHandlerFinder(LsidHandlerFinder finder)
Expand Down
Loading