default TokensAndUrlAuthData refreshTokens(final TokensAndUrlAuthData authData, final AppCredentials appCredentials, Monitor monitor)
        throws CopyExceptionWithFailureReason {

        final String refreshToken = authData.getRefreshToken();
        final String refreshUrlString = authData.getTokenServerEncodedUrl();
        final String clientId = appCredentials.getKey();
        final String clientSecret = appCredentials.getSecret();

        final Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("client_id", clientId);
        parameters.put("client_secret", clientSecret);
        parameters.put("grant_type", "refresh_token");
        parameters.put("refresh_token", refreshToken);

        StringJoiner sj = new StringJoiner("&");
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
            sj.add(entry.getKey() + "=" + entry.getValue());
        }

        final byte[] requestData = sj.toString().getBytes(StandardCharsets.ISO_8859_1);
        try {
            final String responseString = sendPostRequest(refreshUrlString, requestData);
            final JSONParser parser = new JSONParser();
            final JSONObject json = (JSONObject) parser.parse(responseString);
            final String accessToken = (String) json.get("access_token");


            monitor.debug(() -> "Successfully refreshed token");

            return new TokensAndUrlAuthData(accessToken, refreshToken, refreshUrlString);
        } catch (ParseException | IOException | CopyExceptionWithFailureReason e) {
            monitor.debug(() -> "Failed to refresh token", e);
            throw new InvalidTokenException("Unable to refresh token", e);
        }
    }
The Base Interface for all the {@link org.datatransferproject.types.common.models.DataVertical}s
that Apple Supports.
extensions/data-transfer/portability-data-transfer-apple/src/main/java/org/datatransferproject/datatransfer/apple/AppleBaseInterface.java