Java tutorial
/* * Forge SDK * The Forge Platform contains an expanding collection of web service components that can be used with Autodesk cloud-based products or your own technologies. Take advantage of Autodesks expertise in design and engineering. * * OpenAPI spec version: 0.1.0 * Contact: forge.help@autodesk.com * * NOTE: This class is auto generated by the swagger code generator program. * https://github.com/swagger-api/swagger-codegen.git * Do not edit the class manually. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.autodesk.client; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.datatype.joda.*; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.GenericType; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.client.filter.LoggingFilter; import com.sun.jersey.api.client.WebResource.Builder; import com.sun.jersey.multipart.FormDataMultiPart; import com.sun.jersey.multipart.file.FileDataBodyPart; import javax.ws.rs.core.Response.Status.Family; import javax.ws.rs.core.MediaType; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Date; import java.util.TimeZone; import java.net.URLEncoder; import java.io.File; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.io.IOException; import java.nio.file.Files; import com.autodesk.client.auth.*; public class ApiClient { private Map<String, String> defaultHeaderMap = new HashMap<String, String>(); private String basePath = "https://developer.api.autodesk.com/"; private boolean debugging = false; private int connectionTimeout = 0; private Client httpClient; private ObjectMapper objectMapper; private int statusCode; private Map<String, List<String>> responseHeaders; private DateFormat dateFormat; public ApiClient() { objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); objectMapper.registerModule(new JodaModule()); objectMapper.setDateFormat(ApiClient.buildDefaultDateFormat()); dateFormat = ApiClient.buildDefaultDateFormat(); rebuildHttpClient(); } public static DateFormat buildDefaultDateFormat() { return new RFC3339DateFormat(); } /** * Build the Client used to make HTTP requests with the latest settings, * i.e. objectMapper and debugging. * TODO: better to use the Builder Pattern? */ public ApiClient rebuildHttpClient() { // Add the JSON serialization support to Jersey JacksonJsonProvider jsonProvider = new JacksonJsonProvider(objectMapper); DefaultClientConfig conf = new DefaultClientConfig(); conf.getSingletons().add(jsonProvider); Client client = Client.create(conf); if (debugging) { client.addFilter(new LoggingFilter()); } this.httpClient = client; return this; } /** * Returns the current object mapper used for JSON serialization/deserialization. * <p> * Note: If you make changes to the object mapper, remember to set it back via * <code>setObjectMapper</code> in order to trigger HTTP client rebuilding. * </p> */ public ObjectMapper getObjectMapper() { return objectMapper; } public ApiClient setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; // Need to rebuild the Client as it depends on object mapper. rebuildHttpClient(); return this; } public Client getHttpClient() { return httpClient; } public ApiClient setHttpClient(Client httpClient) { this.httpClient = httpClient; return this; } public String getBasePath() { return basePath; } public ApiClient setBasePath(String basePath) { this.basePath = basePath; return this; } /** * Gets the status code of the previous request */ public int getStatusCode() { return statusCode; } /** * Gets the response headers of the previous request */ public Map<String, List<String>> getResponseHeaders() { return responseHeaders; } /** * Set the User-Agent header's value (by adding to the default header map). */ public ApiClient setUserAgent(String userAgent) { addDefaultHeader("User-Agent", userAgent); return this; } /** * Add a default header. * * @param key The header's key * @param value The header's value */ public ApiClient addDefaultHeader(String key, String value) { defaultHeaderMap.put(key, value); return this; } /** * Check that whether debugging is enabled for this API client. */ public boolean isDebugging() { return debugging; } /** * Enable/disable debugging for this API client. * * @param debugging To enable (true) or disable (false) debugging */ public ApiClient setDebugging(boolean debugging) { this.debugging = debugging; // Need to rebuild the Client as it depends on the value of debugging. rebuildHttpClient(); return this; } /** * Connect timeout (in milliseconds). */ public int getConnectTimeout() { return connectionTimeout; } /** * Set the connect timeout (in milliseconds). * A value of 0 means no timeout, otherwise values must be between 1 and * {@link Integer#MAX_VALUE}. */ public ApiClient setConnectTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; httpClient.setConnectTimeout(connectionTimeout); return this; } /** * Get the date format used to parse/format date parameters. */ public DateFormat getDateFormat() { return dateFormat; } /** * Set the date format used to parse/format date parameters. */ public ApiClient setDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; // Also set the date format for model (de)serialization with Date properties. this.objectMapper.setDateFormat((DateFormat) dateFormat.clone()); // Need to rebuild the Client as objectMapper changes. rebuildHttpClient(); return this; } /** * Parse the given string into Date object. */ public Date parseDate(String str) { try { return dateFormat.parse(str); } catch (java.text.ParseException e) { throw new RuntimeException(e); } } /** * Format the given Date object into string. */ public String formatDate(Date date) { return dateFormat.format(date); } /** * Format the given parameter object into string. */ public String parameterToString(Object param) { if (param == null) { return ""; } else if (param instanceof Date) { return formatDate((Date) param); } else if (param instanceof Collection) { StringBuilder b = new StringBuilder(); for (Object o : (Collection<?>) param) { if (b.length() > 0) { b.append(","); } b.append(String.valueOf(o)); } return b.toString(); } else { return String.valueOf(param); } } /* Format to {@code Pair} objects. */ public List<Pair> parameterToPairs(String collectionFormat, String name, Object value) { List<Pair> params = new ArrayList<Pair>(); // preconditions if (name == null || name.isEmpty() || value == null) return params; Collection<?> valueCollection = null; if (value instanceof Collection<?>) { valueCollection = (Collection<?>) value; } else { params.add(new Pair(name, parameterToString(value))); return params; } if (valueCollection.isEmpty()) { return params; } // get the collection format collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv // create the params based on the collection format if (collectionFormat.equals("multi")) { for (Object item : valueCollection) { params.add(new Pair(name, parameterToString(item))); } return params; } String delimiter = ","; if (collectionFormat.equals("csv")) { delimiter = ","; } else if (collectionFormat.equals("ssv")) { delimiter = " "; } else if (collectionFormat.equals("tsv")) { delimiter = "\t"; } else if (collectionFormat.equals("pipes")) { delimiter = "|"; } StringBuilder sb = new StringBuilder(); for (Object item : valueCollection) { sb.append(delimiter); sb.append(parameterToString(item)); } params.add(new Pair(name, sb.substring(1))); return params; } /** * Check if the given MIME is a JSON MIME. * JSON MIME examples: * application/json * application/json; charset=UTF8 * APPLICATION/JSON */ public boolean isJsonMime(String mime) { return mime != null && mime.matches("(?i)application\\/json(;.*)?"); } /** * Select the Accept header's value from the given accepts array: * if JSON exists in the given array, use it; * otherwise use all of them (joining into a string) * * @param accepts The accepts array to select from * @return The Accept header to use. If the given array is empty, * null will be returned (not to set the Accept header explicitly). */ public String selectHeaderAccept(String[] accepts) { if (accepts.length == 0) { return null; } for (String accept : accepts) { if (isJsonMime(accept)) { return accept; } } return StringUtil.join(accepts, ","); } /** * Select the Content-Type header's value from the given array: * if JSON exists in the given array, use it; * otherwise use the first one of the array. * * @param contentTypes The Content-Type array to select from * @return The Content-Type header to use. If the given array is empty, * JSON will be used. */ public String selectHeaderContentType(String[] contentTypes) { if (contentTypes.length == 0) { return "application/json"; } for (String contentType : contentTypes) { if (isJsonMime(contentType)) { return contentType; } } return contentTypes[0]; } /** * Escape the given string to be used as URL query value. */ public String escapeString(String str) { try { return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); } catch (UnsupportedEncodingException e) { return str; } } /** * Serialize the given Java object into string according the given * Content-Type (only JSON is supported for now). */ public Object serialize(Object obj, String contentType, Map<String, Object> formParams) throws ApiException { if (contentType.startsWith("multipart/form-data")) { FormDataMultiPart mp = new FormDataMultiPart(); for (Entry<String, Object> param : formParams.entrySet()) { if (param.getValue() instanceof File) { File file = (File) param.getValue(); mp.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.MULTIPART_FORM_DATA_TYPE)); } else { mp.field(param.getKey(), parameterToString(param.getValue()), MediaType.MULTIPART_FORM_DATA_TYPE); } } return mp; } else if (contentType.startsWith("application/x-www-form-urlencoded")) { return this.getXWWWFormUrlencodedParams(formParams); } else { // We let Jersey attempt to serialize the body return obj; } } /** * Build full URL by concatenating base path, the given sub path and query parameters. * * @param path The sub path * @param queryParams The query parameters * @return The full URL */ private String buildUrl(String path, List<Pair> queryParams) { final StringBuilder url = new StringBuilder(); url.append(basePath).append(path); if (queryParams != null && !queryParams.isEmpty()) { // support (constant) query string in `path`, e.g. "/posts?draft=1" String prefix = path.contains("?") ? "&" : "?"; for (Pair param : queryParams) { if (param.getValue() != null) { if (prefix != null) { url.append(prefix); prefix = null; } else { url.append("&"); } String value = parameterToString(param.getValue()); url.append(escapeString(param.getName())).append("=").append(escapeString(value)); } } } return url.toString(); } private ClientResponse getAPIResponse(Credentials credentials, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType) throws ApiException { if (body != null && !formParams.isEmpty()) { throw new ApiException(500, "Cannot have body and form params"); } if (body != null && body.getClass().equals(File.class)) { try { byte[] data = Files.readAllBytes(((File) body).toPath()); body = data; headerParams.put("Content-Length", (new Integer(data.length)).toString()); contentType = "application/octet-stream"; } catch (IOException e) { throw new ApiException(400, "There was a problem reading the file: " + e.getMessage()); } } updateParamsForAuth(credentials, headerParams); final String url = buildUrl(path, queryParams); Builder builder; if (accept == null) { builder = httpClient.resource(url).getRequestBuilder(); } else { builder = httpClient.resource(url).accept(accept); } for (String key : headerParams.keySet()) { builder = builder.header(key, headerParams.get(key)); } for (String key : defaultHeaderMap.keySet()) { if (!headerParams.containsKey(key)) { builder = builder.header(key, defaultHeaderMap.get(key)); } } ClientResponse response = null; if ("GET".equals(method)) { response = (ClientResponse) builder.get(ClientResponse.class); } else if ("POST".equals(method)) { response = builder.type(contentType).post(ClientResponse.class, serialize(body, contentType, formParams)); } else if ("PUT".equals(method)) { response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType, formParams)); } else if ("DELETE".equals(method)) { response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType, formParams)); } else if ("PATCH".equals(method)) { response = builder.type(contentType).header("X-HTTP-Method-Override", "PATCH") .post(ClientResponse.class, serialize(body, contentType, formParams)); } else { throw new ApiException(500, "unknown method type " + method); } return response; } /** * Invoke API by sending HTTP request with the given options. * * @param oauth2 The oauth object used to send secure requests * @param credentials The credentials containing the access token used to send secure requests * @param path The sub-path of the HTTP URL * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" * @param queryParams The query parameters * @param body The request body object - if it is not binary, otherwise null * @param headerParams The header parameters * @param formParams The form parameters * @param accept The request's Accept header * @param contentType The request's Content-Type header * @return The response body in type of string */ public <T> ApiResponse<T> invokeAPI(Authentication oauth2, Credentials credentials, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, GenericType<T> returnType) throws ApiException, Exception { //try to auto refresh 2-legged/3-legged access token if (oauth2 instanceof OAuth2TwoLegged) { OAuth2TwoLegged oauth2TwoLegged = (OAuth2TwoLegged) oauth2; if (oauth2TwoLegged.isAutoRefresh() && oauth2TwoLegged.isAccessTokenExpired()) { credentials = oauth2TwoLegged.authenticate(); } } else if (oauth2 instanceof OAuth2ThreeLegged && credentials instanceof ThreeLeggedCredentials) { OAuth2ThreeLegged oauth2ThreeLegged = (OAuth2ThreeLegged) oauth2; if (oauth2ThreeLegged.isAutoRefresh() && !oauth2ThreeLegged.isAuthorized((ThreeLeggedCredentials) credentials)) { credentials = oauth2ThreeLegged .refreshAccessToken(((ThreeLeggedCredentials) credentials).getRefreshToken()); } } ClientResponse response = getAPIResponse(credentials, path, method, queryParams, body, headerParams, formParams, accept, contentType); statusCode = response.getStatusInfo().getStatusCode(); responseHeaders = response.getHeaders(); if (response.getStatusInfo().getStatusCode() == ClientResponse.Status.NO_CONTENT.getStatusCode()) { return null; } else if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) { if (returnType == null || statusCode == 202) return new ApiResponse<T>(statusCode, responseHeaders, null); else return new ApiResponse<T>(statusCode, responseHeaders, response.getEntity(returnType)); } else { String message = "error"; String respBody = null; if (response.hasEntity()) { try { respBody = response.getEntity(String.class); message = respBody; } catch (RuntimeException e) { // e.printStackTrace(); } } throw new ApiException(response.getStatusInfo().getStatusCode(), message, response.getHeaders(), respBody); } } /** * Add Authorization header parameters. */ private void updateParamsForAuth(Credentials credentials, Map<String, String> headerParams) { if (credentials != null && credentials.getAccessToken() != null) { headerParams.put("Authorization", "Bearer " + credentials.getAccessToken()); } } /** * Encode the given form parameters as request body. */ private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) { StringBuilder formParamBuilder = new StringBuilder(); for (Entry<String, Object> param : formParams.entrySet()) { String valueStr = parameterToString(param.getValue()); try { formParamBuilder.append(URLEncoder.encode(param.getKey(), "utf8")).append("=") .append(URLEncoder.encode(valueStr, "utf8")); formParamBuilder.append("&"); } catch (UnsupportedEncodingException e) { // move on to next } } String encodedFormParams = formParamBuilder.toString(); if (encodedFormParams.endsWith("&")) { encodedFormParams = encodedFormParams.substring(0, encodedFormParams.length() - 1); } return encodedFormParams; } }