Skip to content

Commit 251a4e4

Browse files
Merge remote-tracking branch 'origin/develop' into fb_sql_experiment
2 parents f60e6fe + 55d86a9 commit 251a4e4

27 files changed

Lines changed: 248 additions & 96 deletions

File tree

api/src/org/labkey/api/exp/api/ExpLineage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ else if ((clazz == ExpMaterial.class && target instanceof ExpMaterial) ||
384384
}
385385
else // ExpMaterial or generic Identifiable
386386
{
387-
if (!seen.contains(target))
387+
if (!seen.contains(target) && target != null)
388388
{
389389
stack.add(target);
390390
seen.add(target);

api/src/org/labkey/api/module/DefaultModule.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,13 @@ public void dispatch(HttpServletRequest request, HttpServletResponse response, A
11091109

11101110
ViewContext rootContext = new ViewContext(request, response, url);
11111111

1112+
Container container = rootContext.getContainer();
1113+
if (container != null && !isAvailable(container))
1114+
{
1115+
ExceptionUtil.handleException(request, response, new NotFoundException("Module " + getName() + " is not active in " + container.getPath()), null, false);
1116+
return;
1117+
}
1118+
11121119
try (var ignored =HttpView.initForRequest(rootContext, request, response))
11131120
{
11141121
response.setContentType("text/html;charset=UTF-8");
@@ -1125,8 +1132,8 @@ public void dispatch(HttpServletRequest request, HttpServletResponse response, A
11251132
}
11261133
request.setAttribute(ViewServlet.REQUEST_ACTION_URL, url);
11271134

1128-
if (controller instanceof HasViewContext)
1129-
((HasViewContext)controller).setViewContext(rootContext);
1135+
if (controller instanceof HasViewContext hvc)
1136+
hvc.setViewContext(rootContext);
11301137
controller.handleRequest(request, response);
11311138
}
11321139
catch (ServletException | IOException x)

api/src/org/labkey/api/module/Module.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ default void registerFilters(ServletContext servletCtx) {}
6969

7070
default boolean isUnderResourcesDirectory(java.nio.file.Path path) { return false; }
7171

72+
/**
73+
* If true, unreachable in the container. More modules should respect whether they're active in the container,
74+
* but historically we haven't been especially mindful of service-type modules
75+
* (such as query or pipeline) being active in all containers where they're being used.
76+
*/
77+
default boolean isAvailable(Container container) { return true; }
78+
7279
enum TabDisplayMode
7380
{
7481
DISPLAY_NEVER,

api/src/org/labkey/api/query/UserIdForeignKey.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616

1717
package org.labkey.api.query;
1818

19-
import org.labkey.api.data.ColumnInfo;
2019
import org.labkey.api.data.CoreSchema;
21-
import org.labkey.api.data.DisplayColumn;
22-
import org.labkey.api.data.DisplayColumnFactory;
2320
import org.labkey.api.data.MutableColumnInfo;
2421
import org.labkey.api.data.TableInfo;
2522

@@ -30,14 +27,7 @@ public class UserIdForeignKey extends LookupForeignKey
3027
static public <COL extends MutableColumnInfo> COL initColumn(COL column)
3128
{
3229
column.setFk(new UserIdForeignKey(column.getParentTable().getUserSchema()));
33-
column.setDisplayColumnFactory(new DisplayColumnFactory()
34-
{
35-
@Override
36-
public DisplayColumn createRenderer(ColumnInfo colInfo)
37-
{
38-
return new UserIdRenderer(colInfo);
39-
}
40-
});
30+
column.setDisplayColumnFactory(UserIdRenderer::new);
4131
return column;
4232
}
4333

api/src/org/labkey/api/reports/report/view/ReportDesignBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public void setCached(boolean cached)
204204
_cached = cached;
205205
}
206206

207-
public R getReport(ContainerUser cu) throws Exception
207+
public R getReport(ContainerUser cu)
208208
{
209209
R report = null;
210210
if (null != getReportId())

api/src/org/labkey/api/reports/report/view/ScriptReportDesignBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public List<String> getIncludedReports()
108108
}
109109

110110
@Override
111-
public ScriptReport getReport(ContainerUser cu) throws Exception
111+
public ScriptReport getReport(ContainerUser cu)
112112
{
113113
Report report = super.getReport(cu);
114114

api/src/org/labkey/api/security/AuthFilter.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@
5353
public class AuthFilter implements Filter
5454
{
5555
private static final Object FIRST_REQUEST_LOCK = new Object();
56+
57+
public static final String STRICT_TRANSPORT_SECURITY_HEADER_NAME = "Strict-Transport-Security";
58+
public static final String X_FRAME_OPTIONS_HEADER_NAME = "X-Frame-Options";
59+
public static final String X_CONTENT_TYPE_OPTIONS_HEADER_NAME = "X-Content-Type-Options";
60+
public static final String REFERRER_POLICY_HEADER_NAME = "Referrer-Policy";
61+
public static final String SERVER_HEADER_NAME = "Server";
62+
5663
private static boolean _firstRequestHandled = false;
5764
private static volatile boolean _sslChecked = false;
5865
private static SecurityPointcutService _securityPointcut = null;
@@ -81,17 +88,17 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
8188
if (ModuleLoader.getInstance().isStartupComplete())
8289
{
8390
if (!"ALLOW".equals(AppProps.getInstance().getXFrameOption()))
84-
resp.setHeader("X-Frame-Options", AppProps.getInstance().getXFrameOption());
85-
resp.setHeader("X-Content-Type-Options", "nosniff");
86-
resp.setHeader("Referrer-Policy", "origin-when-cross-origin" );
91+
resp.setHeader(X_FRAME_OPTIONS_HEADER_NAME, AppProps.getInstance().getXFrameOption());
92+
resp.setHeader(X_CONTENT_TYPE_OPTIONS_HEADER_NAME, "nosniff");
93+
resp.setHeader(REFERRER_POLICY_HEADER_NAME, "origin-when-cross-origin" );
8794

8895
if (AppProps.getInstance().isIncludeServerHttpHeader())
8996
{
9097
if (_serverHeader == null)
9198
{
9299
_serverHeader = "LabKey/" + AppProps.getInstance().getReleaseVersion();
93100
}
94-
resp.setHeader("Server", _serverHeader);
101+
resp.setHeader(SERVER_HEADER_NAME, _serverHeader);
95102
}
96103
}
97104

@@ -168,7 +175,7 @@ else if (!AppProps.getInstance().isDevMode())
168175
{
169176
// Issue 51904: Strict-Transport-Security header when HTTPS is required
170177
// Avoid setting when in dev mode to make it easier to toggle HTTPS on and off again for local deployments
171-
resp.setHeader("Strict-Transport-Security", "max-age=31536000;includeSubdomains");
178+
resp.setHeader(STRICT_TRANSPORT_SECURITY_HEADER_NAME, "max-age=31536000;includeSubdomains");
172179
}
173180
}
174181

api/src/org/labkey/api/study/reports/CrosstabReport.java

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,28 @@
2020
import org.labkey.api.data.ExcelWriter;
2121
import org.labkey.api.data.RenderContext;
2222
import org.labkey.api.data.Results;
23+
import org.labkey.api.data.RuntimeSQLException;
2324
import org.labkey.api.data.Table;
2425
import org.labkey.api.query.FieldKey;
2526
import org.labkey.api.query.QueryParam;
2627
import org.labkey.api.query.QueryService;
2728
import org.labkey.api.query.QuerySettings;
2829
import org.labkey.api.query.UserSchema;
30+
import org.labkey.api.query.ValidationException;
2931
import org.labkey.api.reports.Report;
3032
import org.labkey.api.reports.report.AbstractReport;
3133
import org.labkey.api.reports.report.ReportDescriptor;
3234
import org.labkey.api.reports.report.ReportUrls;
3335
import org.labkey.api.reports.report.view.ReportQueryView;
3436
import org.labkey.api.util.PageFlowUtil;
37+
import org.labkey.api.util.ResultSetUtil;
3538
import org.labkey.api.view.ActionURL;
3639
import org.labkey.api.view.DataView;
3740
import org.labkey.api.view.HttpView;
3841
import org.labkey.api.view.Stats;
3942
import org.labkey.api.view.ViewContext;
4043

44+
import java.sql.SQLException;
4145
import java.util.LinkedHashSet;
4246
import java.util.Set;
4347

@@ -67,7 +71,7 @@ public String getDescriptorType()
6771
return CrosstabReportDescriptor.TYPE;
6872
}
6973

70-
protected ReportQueryView createQueryView(ViewContext context, ReportDescriptor descriptor) throws Exception
74+
protected ReportQueryView createQueryView(ViewContext context, ReportDescriptor descriptor)
7175
{
7276
final String queryName = descriptor.getProperty(QueryParam.queryName.toString());
7377
final String viewName = descriptor.getProperty(QueryParam.viewName.toString());
@@ -111,7 +115,11 @@ public HttpView<?> renderReport(ViewContext context)
111115
return new CrosstabView(crosstab, exportAction);
112116
}
113117
}
114-
catch (Exception e)
118+
catch (SQLException e)
119+
{
120+
throw new RuntimeSQLException(e);
121+
}
122+
catch (ValidationException e)
115123
{
116124
throw new RuntimeException(e);
117125
}
@@ -124,7 +132,7 @@ public HttpView<?> renderReport(ViewContext context)
124132
}
125133

126134
@Override
127-
public Results generateResults(ViewContext context, boolean allowAsyncQuery) throws Exception
135+
public Results generateResults(ViewContext context, boolean allowAsyncQuery) throws SQLException, ValidationException
128136
{
129137
ReportQueryView view = createQueryView(context, getDescriptor());
130138
validateQueryView(view);
@@ -141,37 +149,33 @@ public Results generateResults(ViewContext context, boolean allowAsyncQuery) thr
141149
return null;
142150
}
143151

144-
protected Crosstab createCrosstab(ViewContext context, boolean allowAsyncQuery) throws Exception
152+
protected Crosstab createCrosstab(ViewContext context, boolean allowAsyncQuery) throws SQLException, ValidationException
145153
{
146154
CrosstabReportDescriptor descriptor = (CrosstabReportDescriptor)getDescriptor();
147155
Results results = generateResults(context, allowAsyncQuery);
148156
if (results != null)
149157
{
150-
FieldKey rowFieldKey = FieldKey.decode(descriptor.getProperty("rowField"));
151-
FieldKey colFieldKey = FieldKey.decode(descriptor.getProperty("colField"));
152-
FieldKey statFieldKey = FieldKey.decode(descriptor.getProperty("statField"));
158+
try
159+
{
160+
FieldKey rowFieldKey = FieldKey.decode(descriptor.getProperty("rowField"));
161+
FieldKey colFieldKey = FieldKey.decode(descriptor.getProperty("colField"));
162+
FieldKey statFieldKey = FieldKey.decode(descriptor.getProperty("statField"));
153163

154-
Set<Stats.StatDefinition> statSet = new LinkedHashSet<>();
155-
for (String stat : descriptor.getStats())
164+
Set<Stats.StatDefinition> statSet = new LinkedHashSet<>();
165+
for (String stat : descriptor.getStats())
166+
{
167+
try
168+
{
169+
statSet.add(Stats.getStatFromString(stat));
170+
}
171+
catch (IllegalArgumentException _) {}
172+
}
173+
return new Crosstab(results, rowFieldKey, colFieldKey, statFieldKey, statSet);
174+
}
175+
finally
156176
{
157-
if ("Count".equals(stat))
158-
statSet.add(Stats.COUNT);
159-
else if ("Sum".equals(stat))
160-
statSet.add(Stats.SUM);
161-
else if ("Mean".equals(stat))
162-
statSet.add(Stats.MEAN);
163-
else if ("Min".equals(stat))
164-
statSet.add(Stats.MIN);
165-
else if ("Max".equals(stat))
166-
statSet.add(Stats.MAX);
167-
else if ("StdDev".equals(stat))
168-
statSet.add(Stats.STDDEV);
169-
else if ("Var".equals(stat))
170-
statSet.add(Stats.VAR);
171-
else if ("Median".equals(stat))
172-
statSet.add(Stats.MEDIAN);
177+
ResultSetUtil.close(results);
173178
}
174-
return new Crosstab(results, rowFieldKey, colFieldKey, statFieldKey, statSet);
175179
}
176180
return null;
177181
}

api/src/org/labkey/api/study/reports/CrosstabReportDescriptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ public String[] getStats()
4343
final Object stats = _props.get(STATS);
4444
if (stats instanceof List)
4545
return ((List<String>)stats).toArray(new String[0]);
46-
else if (stats instanceof String)
47-
return new String[]{(String)stats};
46+
else if (stats instanceof String s)
47+
return new String[]{s};
4848

4949
return new String[]{""};
5050
}

0 commit comments

Comments
 (0)