Skip to content

Commit

Permalink
Merge pull request #2872 from wordpress-mobile/analysis/add-missing-n…
Browse files Browse the repository at this point in the history
…ullability-annotations-to-discovery-clients

[Nullability Annotations to Java Classes] Add Missing Nullability Annotations to `Discovery` Network Client Classes (`safe`)
  • Loading branch information
irfano authored Oct 19, 2023
2 parents 263e700 + ee142d1 commit a2bbe1c
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@ public class DiscoveryRequest extends BaseRequest<String> {
private static final String PROTOCOL_CHARSET = "utf-8";
private static final String PROTOCOL_CONTENT_TYPE = String.format("text/xml; charset=%s", PROTOCOL_CHARSET);

private final Listener<String> mListener;
@NonNull private final Listener<String> mListener;

public DiscoveryRequest(String url, Listener<String> listener, BaseErrorListener errorListener) {
public DiscoveryRequest(
@NonNull String url,
@NonNull Listener<String> listener,
@NonNull BaseErrorListener errorListener) {
super(Method.GET, url, errorListener);
mListener = listener;
}

@Override
protected void deliverResponse(String response) {
protected void deliverResponse(@NonNull String response) {
mListener.onResponse(response);
}

@NonNull
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
protected Response<String> parseNetworkResponse(@NonNull NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
Expand All @@ -38,12 +42,14 @@ protected Response<String> parseNetworkResponse(NetworkResponse response) {
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}

@NonNull
@Override
public BaseNetworkError deliverBaseNetworkError(@NonNull BaseNetworkError error) {
// no op
return error;
}

@NonNull
@Override
public String getBodyContentType() {
return PROTOCOL_CONTENT_TYPE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import android.text.TextUtils;
import android.webkit.URLUtil;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.wordpress.android.util.AppLog;

import java.util.regex.Matcher;
Expand All @@ -12,7 +15,8 @@ public class DiscoveryUtils {
/**
* Strip known unnecessary paths from XML-RPC URL and remove trailing slashes
*/
public static String stripKnownPaths(String url) {
@NonNull
public static String stripKnownPaths(@NonNull String url) {
// Remove 'wp-login.php' if available in the URL
String sanitizedURL = truncateUrl(url, "wp-login.php");

Expand All @@ -36,9 +40,10 @@ public static String stripKnownPaths(String url) {
* Truncate a string beginning at the marker
* @param url input string
* @param marker the marker to begin the truncation from
* @return new string truncated to the begining of the marker or the input string if marker is not found
* @return new string truncated to the beginning of the marker or the input string if marker is not found
*/
public static String truncateUrl(String url, String marker) {
@NonNull
public static String truncateUrl(@NonNull String url, @NonNull String marker) {
if (TextUtils.isEmpty(marker) || !url.contains(marker)) {
return url;
}
Expand All @@ -51,7 +56,8 @@ public static String truncateUrl(String url, String marker) {
/**
* Append 'xmlrpc.php' if missing in the URL
*/
public static String appendXMLRPCPath(String url) {
@NonNull
public static String appendXMLRPCPath(@NonNull String url) {
// Don't use 'ends' here! Some hosting wants parameters passed to baseURL/xmlrpc-php?my-authcode=XXX
if (url.contains("xmlrpc.php")) {
return url;
Expand All @@ -63,7 +69,7 @@ public static String appendXMLRPCPath(String url) {
/**
* Verify that the response of system.listMethods matches the expected list of available XML-RPC methods
*/
public static boolean validateListMethodsResponse(Object[] availableMethods) {
public static boolean validateListMethodsResponse(@Nullable Object[] availableMethods) {
if (availableMethods == null) {
AppLog.e(AppLog.T.NUX, "The response of system.listMethods was empty!");
return false;
Expand Down Expand Up @@ -96,7 +102,7 @@ public static boolean validateListMethodsResponse(Object[] availableMethods) {
/**
* Check whether given network error is a 401 Unauthorized HTTP error
*/
public static boolean isHTTPAuthErrorMessage(Exception e) {
public static boolean isHTTPAuthErrorMessage(@Nullable Exception e) {
return e != null && e.getMessage() != null && e.getMessage().contains("401");
}

Expand All @@ -105,7 +111,8 @@ public static boolean isHTTPAuthErrorMessage(Exception e) {
*
* @return XML-RPC endpoint for the specified site, or null if unable to discover endpoint.
*/
public static String getXMLRPCApiLink(String html) {
@Nullable
public static String getXMLRPCApiLink(@Nullable String html) {
Pattern xmlrpcLink = Pattern.compile("<api\\s*?name=\"WordPress\".*?apiLink=\"(.*?)\"",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
if (html != null) {
Expand All @@ -122,7 +129,8 @@ public static String getXMLRPCApiLink(String html) {
*
* @return String XML-RPC url
*/
public static String getXMLRPCPingback(String html) {
@Nullable
public static String getXMLRPCPingback(@Nullable String html) {
Pattern pingbackLink = Pattern.compile(
"<link\\s*?rel=\"pingback\"\\s*?href=\"(.*?)\"",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.wordpress.android.fluxc.network.discovery;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.volley.Request;
import com.android.volley.RequestQueue;

Expand All @@ -11,6 +14,7 @@
import org.wordpress.android.fluxc.network.rest.wpapi.WPAPIGsonRequest;
import org.wordpress.android.util.AppLog;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
Expand All @@ -21,15 +25,18 @@

import static org.wordpress.android.fluxc.network.discovery.SelfHostedEndpointFinder.TIMEOUT_MS;

@SuppressWarnings("CommentedOutCode")
@Singleton
public class DiscoveryWPAPIRestClient extends BaseWPAPIRestClient {
@Inject public DiscoveryWPAPIRestClient(Dispatcher dispatcher,
@Named("custom-ssl") RequestQueue requestQueue,
UserAgent userAgent) {
@Inject public DiscoveryWPAPIRestClient(
Dispatcher dispatcher,
@Named("custom-ssl") RequestQueue requestQueue,
UserAgent userAgent) {
super(dispatcher, requestQueue, userAgent);
}

public String discoverWPAPIBaseURL(String url) throws SelfHostedEndpointFinder.DiscoveryException {
@Nullable
public String discoverWPAPIBaseURL(@NonNull String url) {
BaseRequestFuture<String> future = BaseRequestFuture.newFuture();
WPAPIHeadRequest request = new WPAPIHeadRequest(url, future, future);
add(request);
Expand All @@ -50,18 +57,27 @@ public String discoverWPAPIBaseURL(String url) throws SelfHostedEndpointFinder.D
return null;
}

public String verifyWPAPIV2Support(String wpApiBaseUrl) {
@Nullable
public String verifyWPAPIV2Support(@NonNull String wpApiBaseUrl) {
BaseRequestFuture<RootWPAPIRestResponse> future = BaseRequestFuture.newFuture();
OnWPAPIErrorListener errorListener = future::onErrorResponse;

WPAPIGsonRequest request = new WPAPIGsonRequest<>(Request.Method.GET, wpApiBaseUrl, null, null,
RootWPAPIRestResponse.class, future, errorListener);
WPAPIGsonRequest<RootWPAPIRestResponse> request = new WPAPIGsonRequest<>(
Request.Method.GET,
wpApiBaseUrl,
null,
null,
RootWPAPIRestResponse.class,
future,
errorListener
);
add(request);
try {
RootWPAPIRestResponse response = future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!response.getNamespaces().contains("wp/v2")) {
List<String> namespaces = response.getNamespaces();
if (namespaces != null && !namespaces.contains("wp/v2")) {
AppLog.i(AppLog.T.NUX, "Site does not have the full WP-API available "
+ "(missing wp/v2 namespace)");
+ "(missing wp/v2 namespace)");
return null;
} else {
AppLog.i(AppLog.T.NUX, "Found valid WP-API endpoint! - " + wpApiBaseUrl);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.wordpress.android.fluxc.network.discovery;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.NoConnectionError;
Expand Down Expand Up @@ -31,17 +34,19 @@

@Singleton
public class DiscoveryXMLRPCClient extends BaseXMLRPCClient {
@Inject public DiscoveryXMLRPCClient(Dispatcher dispatcher,
@Named("custom-ssl") RequestQueue requestQueue,
UserAgent userAgent,
HTTPAuthManager httpAuthManager) {
@Inject public DiscoveryXMLRPCClient(
Dispatcher dispatcher,
@Named("custom-ssl") RequestQueue requestQueue,
UserAgent userAgent,
HTTPAuthManager httpAuthManager) {
super(dispatcher, requestQueue, userAgent, httpAuthManager);
}

/**
* Obtain the HTML response from a GET request for the given URL.
*/
public String getResponse(String url) throws DiscoveryException {
@Nullable
public String getResponse(@NonNull String url) throws DiscoveryException {
BaseRequestFuture<String> future = BaseRequestFuture.newFuture();
DiscoveryRequest request = new DiscoveryRequest(url, future, future);
add(request);
Expand All @@ -63,8 +68,8 @@ public String getResponse(String url) throws DiscoveryException {
throw new DiscoveryException(DiscoveryError.XMLRPC_FORBIDDEN, url);
}
} else if (e.getCause() instanceof NoConnectionError
&& e.getCause().getCause() instanceof SSLHandshakeException
&& e.getCause().getCause().getCause() instanceof CertificateException) {
&& e.getCause().getCause() instanceof SSLHandshakeException
&& e.getCause().getCause().getCause() instanceof CertificateException) {
// In the event of an SSL handshake error we should stop attempting discovery
throw new DiscoveryException(DiscoveryError.ERRONEOUS_SSL_CERTIFICATE, url);
}
Expand All @@ -73,9 +78,10 @@ public String getResponse(String url) throws DiscoveryException {
}

/**
* Peform a system.listMethods call on the given URL.
* Perform a system.listMethods call on the given URL.
*/
public Object[] listMethods(String url) throws DiscoveryException {
@Nullable
public Object[] listMethods(@NonNull String url) throws DiscoveryException {
if (!UrlUtils.isValidUrlAndHostNotNull(url)) {
AppLog.e(AppLog.T.NUX, "Invalid URL: " + url);
throw new DiscoveryException(DiscoveryError.INVALID_URL, url);
Expand Down Expand Up @@ -104,8 +110,8 @@ public Object[] listMethods(String url) throws DiscoveryException {
throw new DiscoveryException(DiscoveryError.XMLRPC_FORBIDDEN, url);
}
} else if (e.getCause() instanceof NoConnectionError
&& e.getCause().getCause() instanceof SSLHandshakeException
&& e.getCause().getCause().getCause() instanceof CertificateException) {
&& e.getCause().getCause() instanceof SSLHandshakeException
&& e.getCause().getCause().getCause() instanceof CertificateException) {
// In the event of an SSL handshake error we should stop attempting discovery
throw new DiscoveryException(DiscoveryError.ERRONEOUS_SSL_CERTIFICATE, url);
} else if (e.getCause() instanceof ServerError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
* {@link AuthenticationAction#AUTHENTICATE_ERROR} events.
*/
public class DiscoveryXMLRPCRequest extends XMLRPCRequest {
DiscoveryXMLRPCRequest(String url, XMLRPC method, Listener<? super Object[]> listener,
BaseErrorListener errorListener) {
DiscoveryXMLRPCRequest(
@NonNull String url,
@NonNull XMLRPC method,
@NonNull Listener<? super Object[]> listener,
@NonNull BaseErrorListener errorListener) {
super(url, method, null, listener, errorListener);
}

@NonNull
@Override
public BaseNetworkError deliverBaseNetworkError(@NonNull BaseNetworkError error) {
// no op
Expand Down
Loading

0 comments on commit a2bbe1c

Please sign in to comment.