Skip to content

Commit 4dc2b2d

Browse files
authored
Clean up base Command and CommandResponse APIs (#41)
* Remove `Command.copy` and unnecessary copy constructors * Make Response constructors more consistent * Make `ResponseObject` properties immutable * Remove long unused `org.labkey.remoteapi.security.ACL` * Chip away at missing JavaDoc
1 parent f608469 commit 4dc2b2d

File tree

137 files changed

+1137
-1541
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1137
-1541
lines changed

labkey-client-api/CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# The LabKey Remote API Library for Java - Change Log
22

33
## version 4.0.0
4-
*Released*: TBD
5-
* Replace the internal JSON library with [JSON-java](https://github.com/stleary/JSON-java). The previous library,
4+
*Released*: 26 October 2022
5+
* Migrate to a new JSON library: [JSON-java](https://github.com/stleary/JSON-java). The previous library,
66
[json-simple](https://github.com/fangyidong/json-simple) is no longer maintained (last released in early 2012) and
77
lacks support for basic features like generics. This is an incompatible API change for developers who *write* their own
88
Command classes; they will need to update their Command classes if/when they upgrade to v4.0.0. Developers who simply
99
*use* Command classes should be able to upgrade without changes.
10+
* API changes:
11+
* Remove `copy` method from Commands. _It was inconsistently implemented and served little purpose._
12+
* Remove `CommandResponse.getSourceCommand`. _Functionality would vary wildly because of inconsistent `Command.copy` implementations._
13+
* Make the properties stashed by `ResponseObject` immutable.
1014
* Issue 46321: Remove `lib` directory from `fatJar` in favor of pulling dependencies via the published pom files when needed
1115
* Remove artifactory plugin since we use the maven `publish` command now
1216

labkey-client-api/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ repositories {
4848

4949
group "org.labkey.api"
5050

51-
version "4.0.0-SNAPSHOT"
51+
version "4.1.0-SNAPSHOT"
5252

5353
dependencies {
5454
api "org.json:json:${jsonObjectVersion}"

labkey-client-api/gradle.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ hamcrestVersion=1.3
1717
httpclient5Version=5.1.3
1818
httpcore5Version=5.1.4
1919

20-
jsonSimpleVersion=1.1.1
2120
jsonObjectVersion=20220924
2221

2322
junitVersion=4.13.2

labkey-client-api/src/org/labkey/remoteapi/ApiKeyCredentialsProvider.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,11 @@
1515
*/
1616
package org.labkey.remoteapi;
1717

18-
import org.apache.hc.client5.http.auth.AuthenticationException;
1918
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
2019
import org.apache.hc.client5.http.protocol.HttpClientContext;
2120

2221
import java.net.URI;
2322

24-
/**
25-
* Created by adam on 4/15/2016.
26-
*/
2723
public class ApiKeyCredentialsProvider implements CredentialsProvider
2824
{
2925
private final String _apiKey;
@@ -34,7 +30,7 @@ public ApiKeyCredentialsProvider(String apiKey)
3430
}
3531

3632
@Override
37-
public void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext) throws AuthenticationException
33+
public void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext)
3834
{
3935
request.setHeader("apikey", _apiKey);
4036
}

labkey-client-api/src/org/labkey/remoteapi/ApiVersionException.java

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

1818
import org.json.JSONObject;
1919

20-
/**
21-
* User: adam
22-
* Date: Feb 23, 2009
23-
* Time: 1:13:26 PM
24-
*/
2520
public class ApiVersionException extends CommandException
2621
{
2722
ApiVersionException(String message, int statusCode, JSONObject jsonProperties, String responseText, String contentType)

labkey-client-api/src/org/labkey/remoteapi/BasicAuthCredentialsProvider.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,14 @@
1616
package org.labkey.remoteapi;
1717

1818
import org.apache.hc.client5.http.auth.AuthScope;
19-
import org.apache.hc.client5.http.auth.AuthenticationException;
2019
import org.apache.hc.client5.http.auth.Credentials;
2120
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
2221
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
2322
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
24-
import org.apache.hc.client5.http.impl.auth.BasicScheme;
2523
import org.apache.hc.client5.http.protocol.HttpClientContext;
2624

2725
import java.net.URI;
2826

29-
/**
30-
* Created by adam on 4/15/2016.
31-
*/
3227
public class BasicAuthCredentialsProvider implements CredentialsProvider
3328
{
3429
private final String _email;
@@ -41,7 +36,7 @@ public BasicAuthCredentialsProvider(String email, String password)
4136
}
4237

4338
@Override
44-
public void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext) throws AuthenticationException
39+
public void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext)
4540
{
4641
BasicCredentialsProvider provider = new BasicCredentialsProvider();
4742
AuthScope scope = new AuthScope(baseURI.getHost(), -1);

labkey-client-api/src/org/labkey/remoteapi/Command.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@
2525
import org.json.JSONObject;
2626
import org.json.JSONTokener;
2727

28-
import java.io.*;
28+
import java.io.BufferedReader;
29+
import java.io.ByteArrayInputStream;
30+
import java.io.Closeable;
31+
import java.io.IOException;
32+
import java.io.InputStream;
33+
import java.io.InputStreamReader;
34+
import java.io.Reader;
35+
import java.io.StringReader;
2936
import java.net.URI;
3037
import java.net.URISyntaxException;
3138
import java.nio.charset.StandardCharsets;
@@ -45,16 +52,13 @@
4552
* However, if future versions of the LabKey Server expose new HTTP APIs
4653
* that are not yet supported with a specialized class in this library,
4754
* the developer may still invoke these APIs by creating an instance of the
48-
* Command object directly, providing the controller and action name for
49-
* the new API. Parameters may then be specified by calling the <code>setParameters()</code>
55+
* {@link Command} class directly, providing the controller and action name for
56+
* the new API. Parameters may then be specified by calling the {@link #setParameters(Map)}
5057
* method, passing a populated parameter <code>Map&lt;String, Object&gt;</code>
5158
* <p>
5259
* Note that this class is not thread-safe. Do not share instances of this class
5360
* or its descendants between threads, unless the descendant declares explicitly that
5461
* it is thread-safe.
55-
*
56-
* @author Dave Stearns, LabKey Corporation
57-
* @version 1.0
5862
*/
5963
public class Command<ResponseType extends CommandResponse>
6064
{
@@ -386,7 +390,7 @@ private void throwError(Response r, boolean throwByDefault) throws IOException,
386390
json = new JSONObject(responseText);
387391
if (json.has("exception"))
388392
{
389-
message = (String)json.get("exception");
393+
message = json.getString("exception");
390394

391395
if ("org.labkey.api.action.ApiVersionException".equals(json.opt("exceptionClass")))
392396
throw new ApiVersionException(message, r.getStatusCode(), json, responseText, contentType);
@@ -419,7 +423,7 @@ private void throwError(Response r, boolean throwByDefault) throws IOException,
419423
*/
420424
protected ResponseType createResponse(String text, int status, String contentType, JSONObject json)
421425
{
422-
return (ResponseType)new CommandResponse(text, status, contentType, json, this.copy());
426+
return (ResponseType)new CommandResponse(text, status, contentType, json, this);
423427
}
424428

425429
/**
@@ -570,14 +574,4 @@ public void setRequiredVersion(double requiredVersion)
570574
_requiredVersion = requiredVersion;
571575
}
572576

573-
/**
574-
* Returns a copy of this object. Derived classes should override this
575-
* to copy their own data members
576-
* @return A copy of this object
577-
*/
578-
// TODO: For next major release, genericize this return value (Command<ResponseType>)
579-
public Command copy()
580-
{
581-
return new Command<>(this);
582-
}
583577
}

labkey-client-api/src/org/labkey/remoteapi/CommandResponse.java

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@
2222
import java.util.regex.Matcher;
2323
import java.util.regex.Pattern;
2424

25-
/*
26-
* User: Dave
27-
* Date: Jul 10, 2008
28-
* Time: 1:21:24 PM
29-
*/
30-
3125
/**
3226
* Represents the details of a response returned from the LabKey Server.
3327
* <p>
@@ -36,16 +30,13 @@
3630
* SelectRowsResponse). However, if you are using the Command class directly to
3731
* call an HTTP API that does not yet have a specialized command class,
3832
* you would use this object to obtain the response details.
39-
*
40-
* @author Dave Stearns, LabKey Corporation
41-
* @version 1.0
4233
*/
4334
public class CommandResponse
4435
{
4536
private final String _text;
4637
private final int _statusCode;
4738
private final String _contentType;
48-
private final Command _sourceCommand;
39+
private final double _requiredVersion;
4940

5041
private Map<String, Object> _data;
5142

@@ -58,13 +49,13 @@ public class CommandResponse
5849
* @param json The parsed JSONObject (or null if JSON was not returned).
5950
* @param sourceCommand A copy of the command that created this response
6051
*/
61-
public CommandResponse(String text, int statusCode, String contentType, JSONObject json, Command sourceCommand)
52+
public CommandResponse(String text, int statusCode, String contentType, JSONObject json, Command<?> sourceCommand)
6253
{
6354
_text = text;
6455
_statusCode = statusCode;
6556
_contentType = contentType;
6657
_data = null != json ? json.toMap() : null;
67-
_sourceCommand = sourceCommand;
58+
_requiredVersion = sourceCommand != null ? sourceCommand.getRequiredVersion() : 0.0;
6859
}
6960

7061
/**
@@ -110,16 +101,7 @@ public String getContentType()
110101
*/
111102
public double getRequiredVersion()
112103
{
113-
return _sourceCommand.getRequiredVersion();
114-
}
115-
116-
/**
117-
* Returns a reference to a copy of the command that created this response
118-
* @return The command that created this response
119-
*/
120-
public Command getSourceCommand()
121-
{
122-
return _sourceCommand;
104+
return _requiredVersion;
123105
}
124106

125107
/**
@@ -131,7 +113,6 @@ public Command getSourceCommand()
131113
* Lists, or Maps.
132114
* @return The parsed data as a property map.
133115
*/
134-
@SuppressWarnings("unchecked")
135116
public Map<String, Object> getParsedData()
136117
{
137118
if (null == _data && null != getText()
@@ -153,7 +134,6 @@ public Map<String, Object> getParsedData()
153134
* @param <T> the type of the property.
154135
* @return The property value, or null if the property was not found.
155136
*/
156-
@SuppressWarnings("unchecked")
157137
public <T> T getProperty(String path)
158138
{
159139
assert null != path;
@@ -192,8 +172,8 @@ protected <T> T getProperty(String[] path, int pathIndex, Map<String, Object> pa
192172
Object prop = parent.get(key);
193173
if (arrayIndex != null)
194174
{
195-
if (prop instanceof List && ((List) prop).size() > arrayIndex)
196-
prop = ((List)prop).get(arrayIndex);
175+
if (prop instanceof List<?> list && list.size() > arrayIndex)
176+
prop = list.get(arrayIndex);
197177
else
198178
return null;
199179
}

labkey-client-api/src/org/labkey/remoteapi/Connection.java

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@
9494
* Note that this class is not thread-safe. Do not share instances of Connection
9595
* between threads.
9696
* </p>
97-
*
98-
* @author Dave Stearns, LabKey Corporation
99-
* @version 1.0
10097
*/
10198
public class Connection
10299
{
@@ -318,35 +315,29 @@ protected void afterExecute()
318315

319316
/**
320317
* Ensures that the credentials have been used to authenticate the users and returns a client that can be used for other requests
321-
* @return an HTTP client
322-
* @throws IOException if there is an IO problem executing the command to ensure login
318+
*
319+
* @throws IOException if there is an IO problem executing the command to ensure login
323320
* @throws CommandException if the server returned a non-success status code.
324321
*/
325-
// TODO: For next major release, stop returning CloseableHttpClient?
326-
public CloseableHttpClient ensureAuthenticated() throws IOException, CommandException
322+
public void ensureAuthenticated() throws IOException, CommandException
327323
{
328-
EnsureLoginCommand command = new EnsureLoginCommand();
329-
CommandResponse response = command.execute(this, "/home");
330-
return getHttpClient();
324+
new EnsureLoginCommand().execute(this, "/home");
331325
}
332326

333327
/**
334328
* Invalidates the current HTTP session on the server, if any
335-
* @return an HTTP client
329+
*
336330
* @throws IOException if there is an IO problem executing the command to ensure logout
337331
* @throws CommandException if the server returned a non-success status code.
338332
*/
339-
// TODO: For next major release, stop returning CloseableHttpClient?
340-
public CloseableHttpClient logout() throws IOException, CommandException
333+
public void logout() throws IOException, CommandException
341334
{
342-
LogoutCommand command = new LogoutCommand();
343-
CommandResponse response = command.execute(this, "/home");
344-
return getHttpClient();
335+
new LogoutCommand().execute(this, "/home");
345336
}
346337

347338
/**
348339
* For site-admins only, start impersonating a user.
349-
*
340+
* <p>
350341
* Admins may impersonate other users to perform actions on their behalf.
351342
* Site admins may impersonate any user in any project. Project admins must
352343
* provide a <code>projectPath</code> and may only impersonate within the
@@ -365,7 +356,7 @@ public Connection impersonate(/*@NotNull*/ String email) throws IOException, Com
365356

366357
/**
367358
* For site-admins or project-admins only, start impersonating a user.
368-
*
359+
* <p>
369360
* Admins may impersonate other users to perform actions on their behalf.
370361
* Site admins may impersonate any user in any project. Project admins must
371362
* provide a <code>projectPath</code> and may only impersonate within the
@@ -420,7 +411,7 @@ public Connection stopImpersonate() throws IOException, CommandException
420411
return stopImpersonating();
421412
}
422413

423-
CloseableHttpResponse executeRequest(HttpUriRequest request, Integer timeout) throws IOException, URISyntaxException, AuthenticationException
414+
CloseableHttpResponse executeRequest(HttpUriRequest request, Integer timeout) throws IOException, AuthenticationException
424415
{
425416
// Delegate authentication setup to CredentialsProvider
426417
_credentialsProvider.configureRequest(getBaseURI(), request, _httpClientContext);
@@ -468,8 +459,8 @@ public int getTimeout()
468459
}
469460

470461
/**
471-
* Sets the proxy host and port for this Connection.
472-
* NOTE: Changing this setting will force the underlying http client to be recreated.
462+
* Sets the proxy host and port for this Connection.<br>
463+
* <i>NOTE: Changing this setting will force the underlying http client to be recreated.</i>
473464
* @param host the proxy host
474465
* @param port the proxy port
475466
* @return this connection
@@ -496,8 +487,8 @@ public boolean isAcceptSelfSignedCerts()
496487
/**
497488
* Sets the accept-self-signed certificates option. Set to false
498489
* to disable automatic acceptance of self-signed SSL certificates
499-
* when using HTTPS.
500-
* NOTE: Changing this setting will force the underlying http client to be recreated.
490+
* when using HTTPS.<br>
491+
* <i>NOTE: Changing this setting will force the underlying http client to be recreated.</i>
501492
*
502493
* @param acceptSelfSignedCerts set to false to not accept self-signed certificates
503494
* @return this connection

labkey-client-api/src/org/labkey/remoteapi/CredentialsProvider.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121

2222
import java.net.URI;
2323

24-
/**
25-
* Created by adam on 4/15/2016.
26-
*/
2724
public interface CredentialsProvider
2825
{
2926
void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext) throws AuthenticationException;

labkey-client-api/src/org/labkey/remoteapi/GuestCredentialsProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import java.net.URI;
2222

2323
/**
24-
* Created by adam on 4/15/2016.
25-
*
2624
* A credentials provider that provides no credentials. Connections using
2725
* this provider will be granted guest access only.
2826
*/

labkey-client-api/src/org/labkey/remoteapi/NetrcCredentialsProvider.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@
2222
import java.io.IOException;
2323
import java.net.URI;
2424

25-
2625
/**
27-
* Created by adam on 4/15/2016.
28-
*
2926
* Attempts to find a .netrc or _netrc file and entry for the given host. If found, it will attempt basic auth using
3027
* the email and password in the entry. If file or entry are not found, it connects as guest.
3128
*/

0 commit comments

Comments
 (0)