diff --git a/.travis.yml b/.travis.yml
index 510d55ae..8a1fec22 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,10 +18,7 @@ jdk:
env:
- MODULE=core
- - MODULE=http42
- - MODULE=http43
- - MODULE=http44
- - MODULE=http45
+ - MODULE=http5
branches:
except:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dce59e1a..ba03059e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,52 @@
+2.2.0 / 2025-02-02
+==================
+
+* Fix Uploader strategy
+* Add restore assets by asset ids
+* Add allow dynamic list parameter
+* Add delete resources by asset ids
+
+2.1.0 / 2025-01-20
+==================
+
+* Fix Http client proxy
+* Fix Http client system properties support
+* Add Cloudinary constructor for `Configuration`
+* Fix Register strategy functions
+
+2.0.0 / 2024-09-29
+==================
+
+* Bump minimum Java version to 8
+* Secure true by default
+* Add `auto_chaptering` and `auto_transcription` to upload API
+* New Http client
+* Add support for update metadata field set default disabled
+
+1.39.0 / 2024-07-14
+===================
+
+* Add conditional metadata rules api
+* Fix rename folder endpoint
+* Add config api call
+* Add delete backup asset version support
+* Add rename folder api support
+* Add analyze api
+* Add selective response support
+* Add access key management
+* Add restrictions field to metadata
+
+1.38.0 / 2024-02-18
+===================
+
+* Add `notification_url` support to rename and destroy
+
+1.37.0 / 2024-01-14
+===================
+
+* Update analytics token
+* Add missing display name parameter
+
1.36.0 / 2023-12-04
===================
diff --git a/README.md b/README.md
index c40b5901..f5659de0 100644
--- a/README.md
+++ b/README.md
@@ -25,9 +25,12 @@ For the complete documentation, see the [Java SDK Guide](https://cloudinary.com/
- [Upload assets to cloud](https://cloudinary.com/documentation/java_image_and_video_upload)
## Version Support
-| SDK Version | Java 6+ |
-|----------------|---------|
-| 1.1.0 - 1.36.0 | V |
+| SDK Version | Java 6+ | Java 8 |
+|----------------|---------|--------|
+| 1.1.0 - 1.39.0 | V | |
+| 2.0.0+ | | V |
+
+
## Installation
The cloudinary_java library is available in [Maven Central](https://mvnrepository.com/artifact/com.cloudinary/cloudinary-core). To use it, add the following dependency to your pom.xml :
@@ -35,8 +38,8 @@ The cloudinary_java library is available in [Maven Central](https://mvnrepositor
```xml
com.cloudinary
- cloudinary-http44
- 1.36.0
+ cloudinary-http45
+ 2.2.0
```
diff --git a/build.gradle b/build.gradle
index ebe374c8..5b9d6f04 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,8 +20,8 @@ nexusPublishing {
}
repositories {
sonatype {
- username = project.hasProperty("ossrhUsername") ? project.ext["ossrhUsername"] : ""
- password = project.hasProperty("ossrhPassword") ? project.ext["ossrhPassword"] : ""
+ username = project.hasProperty("ossrhToken") ? project.ext["ossrhToken"] : ""
+ password = project.hasProperty("ossrhTokenPassword") ? project.ext["ossrhTokenPassword"] : ""
}
}
}
diff --git a/cloudinary-core/build.gradle b/cloudinary-core/build.gradle
index 37246e23..01ac348b 100644
--- a/cloudinary-core/build.gradle
+++ b/cloudinary-core/build.gradle
@@ -23,8 +23,8 @@ if (hasProperty("ossrhPassword")) {
nexusStaging {
packageGroup = group
- username = project.hasProperty("ossrhUsername") ? project.ext["ossrhUsername"] : ""
- password = project.hasProperty("ossrhPassword") ? project.ext["ossrhPassword"] : ""
+ username = project.hasProperty("ossrhToken") ? project.ext["ossrhToken"] : ""
+ password = project.hasProperty("ossrhTokenPassword") ? project.ext["ossrhTokenPassword"] : ""
}
publishing {
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Api.java b/cloudinary-core/src/main/java/com/cloudinary/Api.java
index 828b821b..c84be0d6 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Api.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Api.java
@@ -7,7 +7,9 @@
import com.cloudinary.api.exceptions.*;
import com.cloudinary.metadata.MetadataField;
import com.cloudinary.metadata.MetadataDataSource;
+import com.cloudinary.metadata.MetadataRule;
import com.cloudinary.strategies.AbstractApiStrategy;
+import com.cloudinary.utils.Base64Coder;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;
import org.cloudinary.json.JSONArray;
@@ -39,7 +41,19 @@ public enum HttpMethod {GET, POST, PUT, DELETE;}
private AbstractApiStrategy strategy;
protected ApiResponse callApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception {
- return this.strategy.callApi(method, uri, params, options);
+ if (options == null)
+ options = ObjectUtils.emptyMap();
+
+ String apiKey = ObjectUtils.asString(options.get("api_key"), this.cloudinary.config.apiKey);
+ String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.cloudinary.config.apiSecret);
+ String oauthToken = ObjectUtils.asString(options.get("oauth_token"), this.cloudinary.config.oauthToken);
+
+ validateAuthorization(apiKey, apiSecret, oauthToken);
+
+
+ String authorizationHeader = getAuthorizationHeaderValue(apiKey, apiSecret, oauthToken);
+ String apiUrl = createApiUrl(uri, options);
+ return this.strategy.callApi(method, apiUrl, params, options, authorizationHeader);
}
public Api(Cloudinary cloudinary, AbstractApiStrategy strategy) {
@@ -72,6 +86,16 @@ public ApiResponse usage(Map options) throws Exception {
return callApi(HttpMethod.GET, uri, ObjectUtils.emptyMap(), options);
}
+ public ApiResponse configuration(Map options) throws Exception {
+ if(options == null) options = ObjectUtils.emptyMap();
+
+ final List uri = new ArrayList();
+ uri.add("config");
+
+ Map params = ObjectUtils.only(options, "settings");
+
+ return callApi(HttpMethod.GET, uri, params, options);
+ }
public ApiResponse resourceTypes(Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
@@ -87,8 +111,10 @@ public ApiResponse resources(Map options) throws Exception {
uri.add(resourceType);
if (type != null)
uri.add(type);
-
- ApiResponse response = callApi(HttpMethod.GET, uri, ObjectUtils.only(options, "next_cursor", "direction", "max_results", "prefix", "tags", "context", "moderations", "start_at", "metadata"), options);
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ ApiResponse response = callApi(HttpMethod.GET, uri, ObjectUtils.only(options, "next_cursor", "direction", "max_results", "prefix", "tags", "context", "moderations", "start_at", "metadata", "fields"), options);
return response;
}
@@ -106,8 +132,10 @@ public ApiResponse visualSearch(Map options) throws Exception {
public ApiResponse resourcesByTag(String tag, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
-
- ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "tags", tag), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata"), options);
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "tags", tag), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields"), options);
return response;
}
@@ -118,7 +146,10 @@ public ApiResponse resourcesByContext(String key, Map options) throws Exception
public ApiResponse resourcesByContext(String key, String value, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
- Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata");
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields");
params.put("key", key);
if (StringUtils.isNotBlank(value)) {
params.put("value", value);
@@ -128,7 +159,10 @@ public ApiResponse resourcesByContext(String key, String value, Map options) thr
public ApiResponse resourceByAssetID(String assetId, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
- Map params = ObjectUtils.only(options, "tags", "context", "moderations");
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ Map params = buildResourceDetailParams(options);
ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", assetId), params, options);
return response;
}
@@ -142,7 +176,10 @@ public ApiResponse resourcesByAssetIDs(Iterable assetIds, Map options) t
public ApiResponse resourcesByAssetFolder(String assetFolder, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
- Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations");
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "fields");
params.put("asset_folder", assetFolder);
ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources/by_asset_folder"), params, options);
return response;
@@ -161,8 +198,10 @@ public ApiResponse resourcesByIds(Iterable publicIds, Map options) throw
public ApiResponse resourcesByModeration(String kind, String status, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
-
- ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "moderations", kind, status), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata"), options);
+ if(options.get("fields") != null) {
+ options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
+ }
+ ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "moderations", kind, status), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields"), options);
return response;
}
@@ -170,15 +209,19 @@ public ApiResponse resource(String public_id, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
String type = ObjectUtils.asString(options.get("type"), "upload");
+ Map params = buildResourceDetailParams(options);
- ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, type, public_id),
- ObjectUtils.only(options, "exif", "colors", "faces", "coordinates",
- "image_metadata", "pages", "phash", "max_results", "quality_analysis", "cinemagraph_analysis",
- "accessibility_analysis", "versions", "media_metadata"), options);
+ ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, type, public_id), params, options);
return response;
}
+ private Map buildResourceDetailParams(Map options) {
+ return ObjectUtils.only(options, "exif", "colors", "faces", "coordinates",
+ "image_metadata", "pages", "phash", "max_results", "quality_analysis", "cinemagraph_analysis",
+ "accessibility_analysis", "versions", "media_metadata", "derived_next_cursor");
+ }
+
public ApiResponse update(String public_id, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
@@ -201,6 +244,13 @@ public ApiResponse deleteResources(Iterable publicIds, Map options) thro
return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, type), params, options);
}
+ public ApiResponse deleteResourcesByAssetIds(Iterable assetIds, Map options) throws Exception {
+ if (options == null) options = ObjectUtils.emptyMap();
+ Map params = ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor", "transformations");
+ params.put("asset_ids", assetIds);
+ return callApi(HttpMethod.DELETE, Arrays.asList("resources"), params, options);
+ }
+
public ApiResponse deleteDerivedByTransformation(Iterable publicIds, List transformations, Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
@@ -299,7 +349,7 @@ public ApiResponse updateUploadPreset(String name, Map options) throws Exception
if (options == null) options = ObjectUtils.emptyMap();
Map params = Util.buildUploadParams(options);
Util.clearEmpty(params);
- params.putAll(ObjectUtils.only(options, "unsigned", "disallow_public_id", "live"));
+ params.putAll(ObjectUtils.only(options, "unsigned", "disallow_public_id"));
return callApi(HttpMethod.PUT, Arrays.asList("upload_presets", name), params, options);
}
@@ -307,7 +357,7 @@ public ApiResponse createUploadPreset(Map options) throws Exception {
if (options == null) options = ObjectUtils.emptyMap();
Map params = Util.buildUploadParams(options);
Util.clearEmpty(params);
- params.putAll(ObjectUtils.only(options, "name", "unsigned", "disallow_public_id", "live"));
+ params.putAll(ObjectUtils.only(options, "name", "unsigned", "disallow_public_id"));
return callApi(HttpMethod.POST, Arrays.asList("upload_presets"), params, options);
}
@@ -347,6 +397,14 @@ public ApiResponse restore(Iterable publicIds, Map options) throws Excep
return response;
}
+ public ApiResponse restoreByAssetIds(Iterable assetIds, Map options) throws Exception {
+ if (options == null)
+ options = ObjectUtils.emptyMap();
+ Map params = new HashMap();
+ params.put("asset_ids", assetIds);
+ return callApi(HttpMethod.POST, Arrays.asList("resources", "restore"), params, options);
+ }
+
public ApiResponse uploadMappings(Map options) throws Exception {
if (options == null)
options = ObjectUtils.emptyMap();
@@ -606,8 +664,10 @@ public ApiResponse updateResourcesAccessModeByTag(String accessMode, String tag,
* @throws Exception When the folder isn't empty or doesn't exist.
*/
public ApiResponse deleteFolder(String folder, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
List uri = Arrays.asList("folders", folder);
- return callApi(HttpMethod.DELETE, uri, Collections.emptyMap(), options);
+ Map params = ObjectUtils.only(options, "skip_backup");
+ return callApi(HttpMethod.DELETE, uri, params, options);
}
/**
@@ -764,6 +824,76 @@ public ApiResponse reorderMetadataFields(String orderBy, String direction, Map o
return callApi(HttpMethod.PUT, uri, map, options);
}
+ public ApiResponse listMetadataRules(Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ final Map params = new HashMap();
+ List uri = Arrays.asList("metadata_rules");
+ return callApi(HttpMethod.GET, uri, params, options);
+ }
+
+ public ApiResponse addMetadataRule(MetadataRule rule, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ options.put("content_type", "json");
+ final Map params = rule.asMap();
+ List uri = Arrays.asList("metadata_rules");
+ return callApi(HttpMethod.POST, uri, params, options);
+ }
+
+ public ApiResponse updateMetadataRule(String externalId, MetadataRule rule, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ options.put("content_type", "json");
+ final Map params = rule.asMap();
+ List uri = Arrays.asList("metadata_rules", externalId);
+ return callApi(HttpMethod.PUT, uri, params, options);
+ }
+
+ public ApiResponse deleteMetadataRule(String externalId, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ List uri = Arrays.asList("metadata_rules", externalId);
+ return callApi(HttpMethod.DELETE, uri, ObjectUtils.emptyMap(), options);
+ }
+
+ public ApiResponse analyze(String inputType, String analysisType, String uri, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ List url = Arrays.asList("analysis", "analyze", inputType);
+ options.put("api_version", "v2");
+ options.put("content_type", "json");
+ final Map params = new HashMap();
+ params.put("analysis_type", analysisType);
+ params.put("uri", uri);
+ return callApi(HttpMethod.POST, url, params, options);
+ }
+
+ public ApiResponse renameFolder(String path, String toPath, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ List url = Arrays.asList("folders", path);
+
+ final Map params = new HashMap();
+ params.put("to_folder", toPath);
+
+ return callApi(HttpMethod.PUT, url, params, options);
+
+ }
+
+ public ApiResponse deleteBackedUpAssets(String assetId, String[] versionIds, Map options) throws Exception {
+ if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
+ if (StringUtils.isEmpty(assetId)) {
+ throw new IllegalArgumentException("AssetId parameter is required");
+ }
+
+ if (versionIds == null || versionIds.length == 0) {
+ throw new IllegalArgumentException("VersionIds parameter is required");
+ }
+
+ List url = Arrays.asList("resources", "backup", assetId);
+
+ Map params = new HashMap();
+ params.put("version_ids[]", StringUtils.join(versionIds, "&"));
+
+ return callApi(HttpMethod.DELETE, url, params, options);
+
+ }
+
private Map extractParams(Map options, List keys) {
Map result = new HashMap();
for (String key : keys) {
@@ -775,4 +905,33 @@ public ApiResponse reorderMetadataFields(String orderBy, String direction, Map o
}
return result;
}
+
+ protected void validateAuthorization(String apiKey, String apiSecret, String oauthToken) {
+ if (oauthToken == null) {
+ if (apiKey == null) throw new IllegalArgumentException("Must supply api_key");
+ if (apiSecret == null) throw new IllegalArgumentException("Must supply api_secret");
+ }
+ }
+
+ protected String getAuthorizationHeaderValue(String apiKey, String apiSecret, String oauthToken) {
+ if (oauthToken != null){
+ return "Bearer " + oauthToken;
+ } else {
+ return "Basic " + Base64Coder.encodeString(apiKey + ":" + apiSecret);
+ }
+ }
+
+ protected String createApiUrl (Iterable uri, Map options){
+ String version = ObjectUtils.asString(options.get("api_version"), "v1_1");
+ String prefix = ObjectUtils.asString(options.get("upload_prefix"), ObjectUtils.asString(this.cloudinary.config.uploadPrefix, "https://api.cloudinary.com"));
+ String cloudName = ObjectUtils.asString(options.get("cloud_name"), this.cloudinary.config.cloudName);
+ if (cloudName == null) throw new IllegalArgumentException("Must supply cloud_name");
+ String apiUrl = StringUtils.join(Arrays.asList(prefix, version, cloudName), "/");
+ for (String component : uri) {
+ component = SmartUrlEncoder.encode(component);
+ apiUrl = apiUrl + "/" + component;
+
+ }
+ return apiUrl;
+ }
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/AuthToken.java b/cloudinary-core/src/main/java/com/cloudinary/AuthToken.java
index aa8cf213..a5114dd3 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/AuthToken.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/AuthToken.java
@@ -5,13 +5,10 @@
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java b/cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java
index a35bdc2b..19c0c3b8 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java
@@ -20,25 +20,19 @@
@SuppressWarnings({"rawtypes", "unchecked"})
public class Cloudinary {
- private static List UPLOAD_STRATEGIES = new ArrayList(Arrays.asList(
+ public static List UPLOAD_STRATEGIES = new ArrayList(Arrays.asList(
"com.cloudinary.android.UploaderStrategy",
- "com.cloudinary.http42.UploaderStrategy",
- "com.cloudinary.http43.UploaderStrategy",
- "com.cloudinary.http44.UploaderStrategy",
- "com.cloudinary.http45.UploaderStrategy"));
+ "com.cloudinary.http5.UploaderStrategy"));
public static List API_STRATEGIES = new ArrayList(Arrays.asList(
"com.cloudinary.android.ApiStrategy",
- "com.cloudinary.http42.ApiStrategy",
- "com.cloudinary.http43.ApiStrategy",
- "com.cloudinary.http44.ApiStrategy",
- "com.cloudinary.http45.ApiStrategy"));
+ "com.cloudinary.http5.ApiStrategy"));
public final static String CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
public final static String OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
public final static String AKAMAI_SHARED_CDN = "res.cloudinary.com";
public final static String SHARED_CDN = AKAMAI_SHARED_CDN;
- public final static String VERSION = "1.36.0";
+ public final static String VERSION = "2.2.0";
static String USER_AGENT_PREFIX = "CloudinaryJava";
public final static String USER_AGENT_JAVA_VERSION = "(Java " + System.getProperty("java.version") + ")";
@@ -65,14 +59,14 @@ public SearchFolders searchFolders() {
public static void registerUploaderStrategy(String className) {
if (!UPLOAD_STRATEGIES.contains(className)) {
- UPLOAD_STRATEGIES.add(className);
+ UPLOAD_STRATEGIES.add(0, className);
}
}
public static void registerAPIStrategy(String className) {
if (!API_STRATEGIES.contains(className)) {
- API_STRATEGIES.add(className);
+ API_STRATEGIES.add(0, className);
}
}
@@ -91,22 +85,21 @@ private void loadStrategies() {
}
public Cloudinary(Map config) {
- this.config = new Configuration(config);
- loadStrategies();
+ this(new Configuration(config));
}
public Cloudinary(String cloudinaryUrl) {
- this.config = Configuration.from(cloudinaryUrl);
- loadStrategies();
+ this(Configuration.from(cloudinaryUrl));
}
public Cloudinary() {
- String cloudinaryUrl = System.getProperty("CLOUDINARY_URL", System.getenv("CLOUDINARY_URL"));
- if (cloudinaryUrl != null) {
- this.config = Configuration.from(cloudinaryUrl);
- } else {
- this.config = new Configuration();
- }
+ this(System.getProperty("CLOUDINARY_URL", System.getenv("CLOUDINARY_URL")) != null
+ ? Configuration.from(System.getProperty("CLOUDINARY_URL", System.getenv("CLOUDINARY_URL")))
+ : new Configuration());
+ }
+
+ public Cloudinary(Configuration config) {
+ this.config = config;
loadStrategies();
}
@@ -401,9 +394,4 @@ private String buildUrl(String base, Map params) throws Unsuppor
}
return urlBuilder.toString();
}
-
- @Deprecated
- public static Map asMap(Object... values) {
- return ObjectUtils.asMap(values);
- }
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Configuration.java b/cloudinary-core/src/main/java/com/cloudinary/Configuration.java
index b0dcc41f..07280d89 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Configuration.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Configuration.java
@@ -114,7 +114,7 @@ public void update(Map config) {
this.apiSecret = (String) config.get("api_secret");
this.secureDistribution = (String) config.get("secure_distribution");
this.cname = (String) config.get("cname");
- this.secure = ObjectUtils.asBoolean(config.get("secure"), false);
+ this.secure = ObjectUtils.asBoolean(config.get("secure"), true);
this.privateCdn = ObjectUtils.asBoolean(config.get("private_cdn"), false);
this.cdnSubdomain = ObjectUtils.asBoolean(config.get("cdn_subdomain"), false);
this.shorten = ObjectUtils.asBoolean(config.get("shorten"), false);
@@ -128,7 +128,7 @@ public void update(Map config) {
this.loadStrategies = ObjectUtils.asBoolean(config.get("load_strategies"), true);
this.timeout = ObjectUtils.asInteger(config.get("timeout"), 0);
this.clientHints = ObjectUtils.asBoolean(config.get("client_hints"), false);
- this.analytics = ObjectUtils.asBoolean(config.get("analytics"), null);
+ this.analytics = ObjectUtils.asBoolean(config.get("analytics"), true);
Map tokenMap = (Map) config.get("auth_token");
if (tokenMap != null) {
this.authToken = new AuthToken(tokenMap);
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Search.java b/cloudinary-core/src/main/java/com/cloudinary/Search.java
index 652e2cda..369830c6 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Search.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Search.java
@@ -6,7 +6,6 @@
import com.cloudinary.utils.StringUtils;
import org.cloudinary.json.JSONObject;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -19,6 +18,7 @@ public class Search {
private ArrayList aggregateParam;
private ArrayList withFieldParam;
private HashMap params;
+ private ArrayList fields;
private int ttl = 300;
@@ -28,6 +28,7 @@ public class Search {
this.sortByParam = new ArrayList>();
this.aggregateParam = new ArrayList();
this.withFieldParam = new ArrayList();
+ this.fields = new ArrayList();
}
public Search ttl(int ttl) {
@@ -76,6 +77,13 @@ public Search sortBy(String field, String dir) {
return this;
}
+ public Search fields(String field) {
+ if (!fields.contains(field)) {
+ fields.add(field);
+ }
+ return this;
+ }
+
public HashMap toQuery() {
HashMap queryParams = new HashMap(this.params);
if (withFieldParam.size() > 0) {
@@ -87,6 +95,9 @@ public HashMap toQuery() {
if(aggregateParam.size() > 0) {
queryParams.put("aggregate", aggregateParam);
}
+ if(fields.size() > 0) {
+ queryParams.put("fields", fields);
+ }
return queryParams;
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java b/cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java
index bcd8f654..2f20414f 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java
@@ -3,7 +3,9 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-public class SmartUrlEncoder {
+public final class SmartUrlEncoder {
+ private SmartUrlEncoder() {}
+
public static String encode(String input) {
try {
return URLEncoder.encode(input, "UTF-8").replace("%2F", "/").replace("%3A", ":").replace("+", "%20");
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Uploader.java b/cloudinary-core/src/main/java/com/cloudinary/Uploader.java
index e9a6909a..39b21950 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Uploader.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Uploader.java
@@ -234,6 +234,7 @@ public Map destroy(String publicId, Map options) throws IOException {
params.put("type", (String) options.get("type"));
params.put("public_id", publicId);
params.put("invalidate", ObjectUtils.asBoolean(options.get("invalidate"), false).toString());
+ params.put("notification_url", (String) options.get("notification_url"));
return callApi("destroy", params, options, null);
}
@@ -249,6 +250,7 @@ public Map rename(String fromPublicId, String toPublicId, Map options) throws IO
params.put("to_type", options.get("to_type"));
params.put("context", ObjectUtils.asBoolean(options.get("context"), false).toString());
params.put("metadata", ObjectUtils.asBoolean(options.get("metadata"), false).toString());
+ params.put("notification_url", (String) options.get("notification_url"));
return callApi("rename", params, options, null);
}
@@ -261,11 +263,6 @@ public Map explicit(String publicId, Map options) throws IOException {
return callApi("explicit", params, options, null);
}
- @Deprecated
- public Map generate_sprite(String tag, Map options) throws IOException {
- return generateSprite(tag, options);
- }
-
public Map generateSprite(String tag, Map options) throws IOException {
if (options == null)
options = Collections.singletonMap("tag", tag);
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Url.java b/cloudinary-core/src/main/java/com/cloudinary/Url.java
index 6517bd28..5365c996 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Url.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Url.java
@@ -13,7 +13,6 @@
import java.util.regex.Pattern;
import java.util.zip.CRC32;
-import com.cloudinary.utils.Analytics;
import com.cloudinary.utils.Base64Coder;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;
diff --git a/cloudinary-core/src/main/java/com/cloudinary/Util.java b/cloudinary-core/src/main/java/com/cloudinary/Util.java
index 19ae2c71..f81da3cc 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/Util.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/Util.java
@@ -8,10 +8,13 @@
import java.security.NoSuchAlgorithmException;
import java.util.*;
-public class Util {
+public final class Util {
+ private Util() {}
+
static final String[] BOOLEAN_UPLOAD_OPTIONS = new String[]{"backup", "exif", "faces", "colors", "image_metadata", "use_filename", "unique_filename",
"eager_async", "invalidate", "discard_original_filename", "overwrite", "phash", "return_delete_token", "async", "quality_analysis", "cinemagraph_analysis",
- "accessibility_analysis", "use_filename_as_display_name", "use_asset_folder_as_public_id_prefix", "unique_display_name", "media_metadata", "visual_search"};
+ "accessibility_analysis", "use_filename_as_display_name", "use_asset_folder_as_public_id_prefix", "unique_display_name", "media_metadata", "visual_search",
+ "auto_chaptering", "auto_transcription"};
@SuppressWarnings({"rawtypes", "unchecked"})
public static final Map buildUploadParams(Map options) {
@@ -166,6 +169,9 @@ public static final void processWriteParameters(Map options, Map
if (options.get("unique_display_name") != null) {
params.put("unique_display_name", options.get("unique_display_name"));
}
+ if (options.get("display_name") != null) {
+ params.put("display_name", options.get("display_name"));
+ }
putObject("ocr", options, params);
putObject("raw_convert", options, params);
putObject("categorization", options, params);
@@ -181,6 +187,12 @@ public static final void processWriteParameters(Map options, Map
if(options.get("visual_search") != null) {
params.put("visual_search", options.get("visual_search"));
}
+ if(options.get("auto_chaptering") != null) {
+ params.put("auto_chaptering", options.get("auto_chaptering"));
+ }
+ if(options.get("auto_transcription") != null) {
+ params.put("auto_transcription", options.get("auto_transcription"));
+ }
}
protected static String encodeAccessControl(Object accessControl) {
diff --git a/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java
index bae2b6c7..7fe81c43 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java
@@ -16,6 +16,9 @@ public class MetadataField extends JSONObject {
public static final String MANDATORY = "mandatory";
public static final String TYPE = "type";
public static final String VALIDATION = "validation";
+ public static final String RESTRICTIONS = "restrictions";
+ public static final String DEFAULT_DISABLED = "default_disabled";
+ public static final String ALLOW_DYNAMIC_LIST_VALUES = "allow_dynamic_list_values";
public MetadataField(MetadataFieldType type) {
put(TYPE, type.toString());
@@ -130,4 +133,26 @@ public MetadataDataSource getDataSource() {
public void setDataSource(MetadataDataSource dataSource) {
put("datasource", dataSource);
}
+
+ /**
+ * Set the restrictions rules of this field.
+ * @param restrictions The rules to set.
+ */
+ public void setRestrictions(Restrictions restrictions) {
+ put(RESTRICTIONS, restrictions.toHash());
+ }
+
+ /**
+ * Set the value indicating whether the field should be disabled by default
+ * @param disabled The value to set.
+ */
+ public void setDefaultDisabled(Boolean disabled) {
+ put(DEFAULT_DISABLED, disabled);
+ }
+
+ /**
+ * Set the value indicating whether the dynamic list values should allow
+ * @param allowDynamicListValues The value to set.
+ */
+ public void setAllowDynamicListValues(Boolean allowDynamicListValues) {put(ALLOW_DYNAMIC_LIST_VALUES, allowDynamicListValues);}
}
\ No newline at end of file
diff --git a/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRule.java b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRule.java
new file mode 100644
index 00000000..4df82ded
--- /dev/null
+++ b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRule.java
@@ -0,0 +1,65 @@
+package com.cloudinary.metadata;
+
+import com.cloudinary.utils.ObjectUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MetadataRule {
+ String metadataFieldId;
+ String name;
+ MetadataRuleCondition condition;
+ MetadataRuleResult result;
+
+ public MetadataRule(String metadataFieldId, String name, MetadataRuleCondition condition, MetadataRuleResult result) {
+ this.metadataFieldId = metadataFieldId;
+ this.name = name;
+ this.condition = condition;
+ this.result = result;
+ }
+
+ public String getMetadataFieldId() {
+ return metadataFieldId;
+ }
+
+ public void setMetadataFieldId(String metadataFieldId) {
+ this.metadataFieldId = metadataFieldId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public MetadataRuleCondition getCondition() {
+ return condition;
+ }
+
+ public void setCondition(MetadataRuleCondition condition) {
+ this.condition = condition;
+ }
+
+ public MetadataRuleResult getResult() {
+ return result;
+ }
+
+ public void setResult(MetadataRuleResult result) {
+ this.result = result;
+ }
+
+ public Map asMap() {
+ Map map = new HashMap();
+ map.put("metadata_field_id", getMetadataFieldId());
+ map.put("name", getName());
+ if (getCondition() != null) {
+ map.put("condition", ObjectUtils.toJSON(getCondition().asMap()));
+ }
+ if(getResult() != null) {
+ map.put("result", ObjectUtils.toJSON(getResult().asMap()));
+ }
+ return map;
+ }
+}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleCondition.java b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleCondition.java
new file mode 100644
index 00000000..55e3a714
--- /dev/null
+++ b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleCondition.java
@@ -0,0 +1,58 @@
+package com.cloudinary.metadata;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MetadataRuleCondition {
+ String metadata_field_id;
+ Boolean populated;
+ Map includes;
+ String equals;
+
+ public MetadataRuleCondition(String metadata_field_id, Boolean populated, Map includes, String equals) {
+ this.metadata_field_id = metadata_field_id;
+ this.populated = populated;
+ this.includes = includes;
+ this.equals = equals;
+ }
+
+ public String getMetadata_field_id() {
+ return metadata_field_id;
+ }
+
+ public void setMetadata_field_id(String metadata_field_id) {
+ this.metadata_field_id = metadata_field_id;
+ }
+
+ public Boolean getPopulated() {
+ return populated;
+ }
+
+ public void setPopulated(Boolean populated) {
+ this.populated = populated;
+ }
+
+ public Map getIncludes() {
+ return includes;
+ }
+
+ public void setIncludes(Map includes) {
+ this.includes = includes;
+ }
+
+ public String getEquals() {
+ return equals;
+ }
+
+ public void setEquals(String equals) {
+ this.equals = equals;
+ }
+
+ public Map asMap() {
+ Map result = new HashMap(4);
+ result.put("metadata_field_id", metadata_field_id);
+ result.put("populated", populated);
+ result.put("includes", includes);
+ result.put("equals", equals);
+ return result;
+ }
+}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleResult.java b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleResult.java
new file mode 100644
index 00000000..2d4efff0
--- /dev/null
+++ b/cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleResult.java
@@ -0,0 +1,58 @@
+package com.cloudinary.metadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MetadataRuleResult {
+ Boolean enabled;
+ String activateValues;
+ String applyValues;
+ Boolean setMandatory;
+
+ public MetadataRuleResult(Boolean enabled, String activateValues, String applyValues, Boolean setMandatory) {
+ this.enabled = enabled;
+ this.activateValues = activateValues;
+ this.applyValues = applyValues;
+ this.setMandatory = setMandatory;
+ }
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getActivateValues() {
+ return activateValues;
+ }
+
+ public void setActivateValues(String activateValues) {
+ this.activateValues = activateValues;
+ }
+
+ public String getApplyValues() {
+ return applyValues;
+ }
+
+ public void setApplyValues(String applyValues) {
+ this.applyValues = applyValues;
+ }
+
+ public Boolean getSetMandatory() {
+ return setMandatory;
+ }
+
+ public void setSetMandatory(Boolean setMandatory) {
+ this.setMandatory = setMandatory;
+ }
+ public Map asMap() {
+ Map result = new HashMap(4);
+ result.put("enable", enabled);
+ result.put("activate_values", activateValues);
+ result.put("apply_values", applyValues);
+ result.put("mandatory", setMandatory);
+ return result;
+ }
+}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/metadata/Restrictions.java b/cloudinary-core/src/main/java/com/cloudinary/metadata/Restrictions.java
new file mode 100644
index 00000000..25d80d12
--- /dev/null
+++ b/cloudinary-core/src/main/java/com/cloudinary/metadata/Restrictions.java
@@ -0,0 +1,40 @@
+package com.cloudinary.metadata;
+
+import java.util.HashMap;
+
+/**
+ * Represents the restrictions metadata field.
+ */
+public class Restrictions {
+
+ private final HashMap restrictions = new HashMap();
+
+ /**
+ * Set the custom field into restrictions.
+ * @param key The key of the field.
+ * @param value The value of the field.
+ */
+ public Restrictions setRestriction(String key, Object value) {
+ restrictions.put(key, value);
+ return this;
+ }
+
+ /**
+ * Set the read only ui field.
+ * @param value The read only ui value.
+ */
+ public Restrictions setReadOnlyUI(Boolean value) {
+ return setRestriction("readonly_ui", value);
+ }
+
+ /**
+ * Set the read only ui field to true.
+ */
+ public Restrictions setReadOnlyUI() {
+ return this.setReadOnlyUI(true);
+ }
+
+ public HashMap toHash() {
+ return restrictions;
+ }
+}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java b/cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java
index 55860aa5..1c545345 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java
@@ -4,7 +4,10 @@
import com.cloudinary.Cloudinary;
import com.cloudinary.Util;
import com.cloudinary.api.ApiResponse;
+import com.cloudinary.utils.Base64Coder;
import com.cloudinary.utils.ObjectUtils;
+import com.cloudinary.utils.StringUtils;
+
import java.util.*;
/**
@@ -14,8 +17,10 @@ public class Account {
private static final String CLOUDINARY_ACCOUNT_URL = "CLOUDINARY_ACCOUNT_URL";
public static final String PROVISIONING = "provisioning";
public static final String ACCOUNTS = "accounts";
+ public static final String SUB_ACCOUNTS = "sub_accounts";
public static final String USERS = "users";
public static final String USER_GROUPS = "user_groups";
+ public static final String ACCESS_KEYS = "access_keys";
private final AccountConfiguration configuration;
private final String accountId;
@@ -74,7 +79,25 @@ private ApiResponse callAccountApi(Api.HttpMethod method, List uri, Map<
}
Util.clearEmpty(params);
- return api.getStrategy().callAccountApi(method, uri, params, options);
+
+ if (options == null) {
+ options = ObjectUtils.emptyMap();
+ }
+
+ String prefix = ObjectUtils.asString(options.get("upload_prefix"), "https://api.cloudinary.com");
+ String apiKey = ObjectUtils.asString(options.get("provisioning_api_key"));
+ if (apiKey == null) throw new IllegalArgumentException("Must supply provisioning_api_key");
+ String apiSecret = ObjectUtils.asString(options.get("provisioning_api_secret"));
+ if (apiSecret == null) throw new IllegalArgumentException("Must supply provisioning_api_secret");
+
+ String apiUrl = StringUtils.join(Arrays.asList(prefix, "v1_1"), "/");
+ for (String component : uri) {
+ apiUrl = apiUrl + "/" + component;
+ }
+
+ String authorizationHeader = getAuthorizationHeaderValue(apiKey, apiSecret, null);
+
+ return api.getStrategy().callAccountApi(method, apiUrl, params, options, authorizationHeader);
}
/**
@@ -619,6 +642,60 @@ public ApiResponse userGroupUsers(String groupId, Map options) t
return callAccountApi(Api.HttpMethod.GET, uri, Collections.emptyMap(), options);
}
+ /**
+ * Lists the access keys belonging to this sub account id.
+ * @param subAccountId The id of the user group.
+ * @param options Generic advanced options map, see online documentation.
+ * @return The list of access keys in that sub account id.
+ * @throws Exception If the request fails.
+ */
+ public ApiResponse getAccessKeys(String subAccountId, Map options) throws Exception {
+ List uri = Arrays.asList(PROVISIONING, ACCOUNTS, accountId, SUB_ACCOUNTS, subAccountId);
+ return callAccountApi(Api.HttpMethod.GET, uri, Collections.emptyMap(), options);
+ }
+
+ /**
+ * Creates a new access key for this sub account id.
+ * @param subAccountId The id of the user group.
+ * @param name The name for the access key.
+ * @param enabled Access key's status (enabled or disabled).
+ * @param options Generic advanced options map, see online documentation.
+ * @return The created access key.
+ * @throws Exception If the request fails.
+ */
+ public ApiResponse createAccessKey(String subAccountId, String name, Boolean enabled, Map options) throws Exception {
+ List uri = Arrays.asList(PROVISIONING, ACCOUNTS, accountId, SUB_ACCOUNTS, subAccountId, ACCESS_KEYS);
+ return callAccountApi(Api.HttpMethod.POST, uri, ObjectUtils.asMap("name", name, "enabled", enabled), options);
+ }
+
+ /**
+ * Updates an existing access key for this sub account id.
+ * @param subAccountId The id of the user group.
+ * @param accessKey The key of the access key.
+ * @param name The name for the access key.
+ * @param enabled Access key's status (enabled or disabled).
+ * @param options Generic advanced options map, see online documentation.
+ * @return The updated access key.
+ * @throws Exception If the request fails.
+ */
+ public ApiResponse updateAccessKey(String subAccountId, String accessKey, String name, Boolean enabled, Map options) throws Exception {
+ List uri = Arrays.asList(PROVISIONING, ACCOUNTS, accountId, SUB_ACCOUNTS, subAccountId, ACCESS_KEYS, accessKey);
+ return callAccountApi(Api.HttpMethod.PUT, uri, ObjectUtils.asMap("name", name, "enabled", enabled), options);
+ }
+
+ /**
+ * Deletes an existing access key for this sub account id.
+ * @param subAccountId The id of the user group.
+ * @param accessKey The key of the access key.
+ * @param options Generic advanced options map, see online documentation.
+ * @return "message": "ok".
+ * @throws Exception If the request fails.
+ */
+ public ApiResponse deleteAccessKey(String subAccountId, String accessKey, Map options) throws Exception {
+ List uri = Arrays.asList(PROVISIONING, ACCOUNTS, accountId, SUB_ACCOUNTS, subAccountId, ACCESS_KEYS, accessKey);
+ return callAccountApi(Api.HttpMethod.DELETE, uri, Collections.emptyMap(), options);
+ }
+
/**
* Private helper method for users api calls
* @param method Http method
@@ -651,4 +728,12 @@ private Map verifyOptions(Map options) {
return options;
}
+
+ protected String getAuthorizationHeaderValue(String apiKey, String apiSecret, String oauthToken) {
+ if (oauthToken != null){
+ return "Bearer " + oauthToken;
+ } else {
+ return "Basic " + Base64Coder.encodeString(apiKey + ":" + apiSecret);
+ }
+ }
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java b/cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java
index 9e427c4a..0342f5bc 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java
@@ -2,11 +2,7 @@
import com.cloudinary.Api;
import com.cloudinary.Api.HttpMethod;
-import com.cloudinary.SmartUrlEncoder;
import com.cloudinary.api.ApiResponse;
-import com.cloudinary.utils.Base64Coder;
-import com.cloudinary.utils.StringUtils;
-import java.util.Arrays;
import java.util.Map;
@@ -17,34 +13,8 @@ public void init(Api api) {
this.api = api;
}
- protected String createApiUrl (Iterable uri, String prefix, String cloudName){
-
- String apiUrl = StringUtils.join(Arrays.asList(prefix, "v1_1", cloudName), "/");
- for (String component : uri) {
- component = SmartUrlEncoder.encode(component);
- apiUrl = apiUrl + "/" + component;
-
- }
- return apiUrl;
- }
-
@SuppressWarnings("rawtypes")
- public abstract ApiResponse callApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception;
+ public abstract ApiResponse callApi(HttpMethod method, String apiUrl, Map params, Map options, String authorizationHeader) throws Exception;
- public abstract ApiResponse callAccountApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception;
-
- protected String getAuthorizationHeaderValue(String apiKey, String apiSecret, String oauthToken) {
- if (oauthToken != null){
- return "Bearer " + oauthToken;
- } else {
- return "Basic " + Base64Coder.encodeString(apiKey + ":" + apiSecret);
- }
- }
-
- protected void validateAuthorization(String apiKey, String apiSecret, String oauthToken) {
- if (oauthToken == null) {
- if (apiKey == null) throw new IllegalArgumentException("Must supply api_key");
- if (apiSecret == null) throw new IllegalArgumentException("Must supply api_secret");
- }
- }
+ public abstract ApiResponse callAccountApi(HttpMethod method, String apiUrl, Map params, Map options, String authorizationHeader) throws Exception;
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/AbstractLayerBuilder.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/AbstractLayerBuilder.java
deleted file mode 100644
index bcc2cfea..00000000
--- a/cloudinary-core/src/main/java/com/cloudinary/transformation/AbstractLayerBuilder.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.cloudinary.transformation;
-
-/**
- * @deprecated
- */
-public abstract class AbstractLayerBuilder extends AbstractLayer {
-}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java
index 35613813..234fd477 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java
@@ -65,27 +65,10 @@ public Condition initialDuration(String operator, Object value) {
return predicate("idu", operator, value);
}
-
- /**
- * @deprecated Use {@link #faceCount(String, Object)} instead
- */
- @Deprecated
- public Condition faces(String operator, Object value) {
- return faceCount(operator, value);
- }
-
public Condition faceCount(String operator, Object value) {
return predicate("fc", operator, value);
}
- /**
- * @deprecated Use {@link #pageCount(String, Object)} instead
- */
- @Deprecated
- public Condition pages(String operator, Object value) {
- return pageCount(operator, value);
- }
-
public Condition pageCount(String operator, Object value) {
return predicate("pc", operator, value);
}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/LayerBuilder.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/LayerBuilder.java
deleted file mode 100644
index 5a4ea9df..00000000
--- a/cloudinary-core/src/main/java/com/cloudinary/transformation/LayerBuilder.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.cloudinary.transformation;
-
-/**
- * @deprecated Use {@link Layer} instead
- */
-public class LayerBuilder extends Layer {
-}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/SubtitlesLayerBuilder.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/SubtitlesLayerBuilder.java
deleted file mode 100644
index 22a78625..00000000
--- a/cloudinary-core/src/main/java/com/cloudinary/transformation/SubtitlesLayerBuilder.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.cloudinary.transformation;
-
-/**
- * @deprecated Use {@link SubtitlesLayer} instead
- */
-public class SubtitlesLayerBuilder extends SubtitlesLayer {
-}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/TextLayerBuilder.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/TextLayerBuilder.java
deleted file mode 100644
index 0db485ce..00000000
--- a/cloudinary-core/src/main/java/com/cloudinary/transformation/TextLayerBuilder.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.cloudinary.transformation;
-
-/**
- * @deprecated Use {@link TextLayer} instead
- */
-public class TextLayerBuilder extends TextLayer {
-}
diff --git a/cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java b/cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java
index b0027889..55001eb2 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java
@@ -8,7 +8,7 @@
public class Analytics {
private String sdkTokenQueryKey = "_a"; //sdkTokenQueryKey
private String sdkQueryDelimiter = "=";
- public String algoVersion = "C";
+ public String algoVersion = "D";
public String prodcut = "A";
public String SDKCode = ""; // Java = G, Android = F
public String SDKSemver = ""; // Calculate the SDK version .
@@ -16,15 +16,18 @@ public class Analytics {
public String osType;
public String osVersion;
+ public String featureFlag = "0";
+
public Analytics() {
- this("G", Cloudinary.VERSION,System.getProperty("java.version"), "Z", "0.0");
+ this("G", Cloudinary.VERSION,System.getProperty("java.version"), "Z", "0.0", "0");
}
- public Analytics(String sdkCode, String sdkVersion, String techVersion, String osType, String osVersion) {
+ public Analytics(String sdkCode, String sdkVersion, String techVersion, String osType, String osVersion, String featureFlag) {
this.SDKCode = sdkCode;
this.SDKSemver = sdkVersion;
this.techVersion = techVersion;
this.osType = osType;
this.osVersion = osVersion;
+ this.featureFlag = featureFlag;
}
public Analytics setSDKCode(String SDKCode) {
@@ -42,13 +45,18 @@ public Analytics setTechVersion(String techVersion) {
return this;
}
+ public Analytics setFeatureFlag(String flag) {
+ this.featureFlag = flag;
+ return this;
+ }
+
/**
* Function turn analytics variables into viable query parameter.
* @return query param with analytics values.
*/
public String toQueryParam() {
try {
- return sdkTokenQueryKey + sdkQueryDelimiter + getAlgorithmVersion() + prodcut + getSDKType() + getSDKVersion() + getTechVersion() + getOsType() + getOsVersion() + getSDKFeatureCode();
+ return sdkTokenQueryKey + sdkQueryDelimiter + getAlgorithmVersion() + prodcut + getSDKType() + getSDKVersion() + getTechVersion() + getOsType() + getOsVersion() + getSDKFeatureFlag();
} catch (Exception e) {
return sdkTokenQueryKey + sdkQueryDelimiter + "E";
}
@@ -67,12 +75,19 @@ private String versionArrayToString(String[] versions) throws Exception {
return getPaddedString(StringUtils.join(versions, "."));
}
+ private String versionArrayToOsString(String[] versions) throws Exception {
+ if (versions.length > 2) {
+ versions = Arrays.copyOf(versions, versions.length - 1);
+ }
+ return getOsVersionString(StringUtils.join(versions, "."));
+ }
+
private String getOsType() {
return (osType != null) ? osType : "Z"; //System.getProperty("os.name");
}
private String getOsVersion() throws Exception {
- return (osVersion != null) ? versionArrayToString(osVersion.split("\\.")) : versionArrayToString(System.getProperty("os.version").split("\\."));
+ return (osVersion != null) ? versionArrayToOsString(osVersion.split("\\.")) : versionArrayToString(System.getProperty("os.version").split("\\."));
}
private String getSDKType() {
@@ -83,14 +98,26 @@ private String getAlgorithmVersion() {
return algoVersion;
}
- private String getSDKFeatureCode() {
- return "0";
+ private String getSDKFeatureFlag() {
+ return featureFlag;
}
private String getSDKVersion() throws Exception {
return getPaddedString(SDKSemver);
}
+ private String getOsVersionString(String string) throws Exception {
+ String[] parts = string.split("\\.");
+ String result = "";
+ for(int i = 0 ; i < parts.length ; i++) {
+ int num = Integer.parseInt(parts[i]);
+ String binaryString = Integer.toBinaryString(num);
+ binaryString = StringUtils.padStart(binaryString, 6, '0');
+ result = result + Base64Map.values.get(binaryString);
+ }
+ return result;
+ }
+
private String getPaddedString(String string) throws Exception {
String paddedReversedSemver = "";
int parts = string.split("\\.").length;
diff --git a/cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java b/cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java
index d5e755f9..f9948974 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java
@@ -3,7 +3,9 @@
import java.util.HashMap;
import java.util.Map;
-public class Base64Map {
+public final class Base64Map {
+ private Base64Map() {}
+
public static Map values;
static {
diff --git a/cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java b/cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java
index 2be36583..39ba901e 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java
@@ -16,7 +16,8 @@
* this program code.
*/
-public class HtmlEscape {
+public final class HtmlEscape {
+ private HtmlEscape() {}
private static char[] hex = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
diff --git a/cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java b/cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java
index 437c04db..2dc607f6 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java
@@ -11,7 +11,9 @@
import java.util.*;
-public class ObjectUtils {
+public final class ObjectUtils {
+ private ObjectUtils() {}
+
/**
* Formats a Date as an ISO-8601 string representation.
* @param date Date to format
diff --git a/cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java b/cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java
index 0d25bacb..f8a21231 100644
--- a/cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java
+++ b/cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java
@@ -8,7 +8,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class StringUtils {
+public final class StringUtils {
+ private StringUtils() {}
+
public static final String EMPTY = "";
/**
diff --git a/cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java b/cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java
index ca30479e..49fd8d35 100644
--- a/cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java
+++ b/cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java
@@ -1,6 +1,5 @@
package com.cloudinary;
-import com.cloudinary.utils.Analytics;
import com.cloudinary.utils.ObjectUtils;
import org.hamcrest.CoreMatchers;
@@ -11,7 +10,6 @@
import org.junit.Test;
import org.junit.rules.TestName;
-import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Map;
@@ -32,7 +30,7 @@ public class AuthTokenTest {
@Before
public void setUp() {
System.out.println("Running " + this.getClass().getName() + "." + currentTest.getMethodName());
- this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false");
+ this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false&analytics=false");
final AuthToken authToken = new AuthToken(KEY).duration(300);
authToken.startTime(11111111); // start time is set for test purposes
cloudinary.config.authToken = authToken;
@@ -74,28 +72,28 @@ public void testAuthenticatedUrl() {
String message = "should add token if authToken is globally set and signed = true";
String url = cloudinary.url().signed(true).resourceType("image").type("authenticated").version("1486020273").generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=8db0d753ee7bbb9e2eaf8698ca3797436ba4c20e31f44527e43b6a6e995cfdb3", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=8db0d753ee7bbb9e2eaf8698ca3797436ba4c20e31f44527e43b6a6e995cfdb3", url);
message = "should add token for 'public' resource";
url = cloudinary.url().signed(true).resourceType("image").type("public").version("1486020273").generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/public/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=c2b77d9f81be6d89b5d0ebc67b671557e88a40bcf03dd4a6997ff4b994ceb80e", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/public/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=c2b77d9f81be6d89b5d0ebc67b671557e88a40bcf03dd4a6997ff4b994ceb80e", url);
message = "should not add token if signed is false";
url = cloudinary.url().resourceType("image").type("authenticated").version("1486020273").generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg", url);
message = "should not add token if authToken is globally set but null auth token is explicitly set and signed = true";
url = cloudinary.url().authToken(AuthToken.NULL_AUTH_TOKEN).signed(true).resourceType("image").type("authenticated").version("1486020273").generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/authenticated/s--v2fTPYTu--/v1486020273/sample.jpg", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/authenticated/s--v2fTPYTu--/v1486020273/sample.jpg", url);
message = "explicit authToken should override global setting";
url = cloudinary.url().signed(true).authToken(new AuthToken(ALT_KEY).startTime(222222222).duration(100)).resourceType("image").type("authenticated").transformation(new Transformation().crop("scale").width(300)).generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/authenticated/c_scale,w_300/sample.jpg?__cld_token__=st=222222222~exp=222222322~hmac=55cfe516530461213fe3b3606014533b1eca8ff60aeab79d1bb84c9322eebc1f", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/authenticated/c_scale,w_300/sample.jpg?__cld_token__=st=222222222~exp=222222322~hmac=55cfe516530461213fe3b3606014533b1eca8ff60aeab79d1bb84c9322eebc1f", url);
message = "should compute expiration as start time + duration";
url = cloudinary.url().signed(true).authToken(new AuthToken().startTime(11111111).duration(300))
.type("authenticated").version("1486020273").generate("sample.jpg");
- assertEquals(message,"http://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=8db0d753ee7bbb9e2eaf8698ca3797436ba4c20e31f44527e43b6a6e995cfdb3", url);
+ assertEquals(message,"https://test123-res.cloudinary.com/image/authenticated/v1486020273/sample.jpg?__cld_token__=st=11111111~exp=11111411~hmac=8db0d753ee7bbb9e2eaf8698ca3797436ba4c20e31f44527e43b6a6e995cfdb3", url);
}
@@ -120,7 +118,7 @@ public void testTokenGeneration(){
public void testUrlInTag() {
String message = "should add token to an image tag url";
String url = cloudinary.url().signed(true).resourceType("image").type("authenticated").version("1486020273").imageTag("sample.jpg");
- assertThat(url, Matchers.matchesPattern(""));
}
diff --git a/cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java b/cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java
index fa277c15..e87143c6 100644
--- a/cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java
+++ b/cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java
@@ -29,19 +29,19 @@ public void testEncodeVersion() {
analytics.setSDKSemver("1.24.0");
analytics.setTechVersion("12.0.0");
String result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAGAlhAMZAA0");
+ Assert.assertEquals(result, "_a=DAGAlhAMZAA0");
analytics.setSDKSemver("12.0");
result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAGAMAMZAA0");
+ Assert.assertEquals(result, "_a=DAGAMAMZAA0");
analytics.setSDKSemver("43.21.26");
result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAG///AMZAA0");
+ Assert.assertEquals(result, "_a=DAG///AMZAA0");
analytics.setSDKSemver("0.0.0");
result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAGAAAAMZAA0");
+ Assert.assertEquals(result, "_a=DAGAAAAMZAA0");
analytics.setSDKSemver("43.21.27");
result = analytics.toQueryParam();
@@ -51,36 +51,42 @@ public void testEncodeVersion() {
@Test
public void testToQueryParam() {
- Analytics analytics = new Analytics("F", "2.0.0", "1.8.0", "Z", "1.34.0");
+ Analytics analytics = new Analytics("F", "2.0.0", "1.8.0", "Z", "1.34.0", "0");
String result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAFAACMhZ1J0");
+ Assert.assertEquals(result, "_a=DAFAACMhZBi0");
+
+ analytics = new Analytics("F", "2.0.0", "1.8.0", "Z", "16.3", "0");
+ result = analytics.toQueryParam();
+ Assert.assertEquals(result, "_a=DAFAACMhZQD0");
}
@Test
public void testUrlWithAnalytics() {
cloudinary.config.analytics = true;
- cloudinary.setAnalytics(new Analytics("F", "2.0.0", "1.8.0", "Z", "1.34.0"));
+ cloudinary.setAnalytics(new Analytics("F", "2.0.0", "1.8.0", "Z", "1.34.0", "0"));
String url = cloudinary.url().generate("test");
- Assert.assertEquals(url, "http://res.cloudinary.com/test123/image/upload/test?_a=CAFAACMhZ1J0");
+ Assert.assertEquals(url, "https://res.cloudinary.com/test123/image/upload/test?_a=DAFAACMhZBi0");
}
@Test
public void testUrlWithNoAnalytics() {
- String url = cloudinary.url().generate("test");
- Assert.assertEquals(url, "http://res.cloudinary.com/test123/image/upload/test");
+ cloudinary.config.analytics = false;
+ String url = cloudinary.url().secure(true).generate("test");
+ Assert.assertEquals(url, "https://res.cloudinary.com/test123/image/upload/test");
}
@Test
public void testUrlWithNoAnalyticsDefined() {
cloudinary.config.analytics = false;
String url = cloudinary.url().generate("test");
- Assert.assertEquals(url, "http://res.cloudinary.com/test123/image/upload/test");
+ Assert.assertEquals(url, "https://res.cloudinary.com/test123/image/upload/test");
}
@Test
public void testUrlWithNoAnalyticsNull() {
+ cloudinary.config.analytics = false;
String url = cloudinary.url().generate("test");
- Assert.assertEquals(url, "http://res.cloudinary.com/test123/image/upload/test");
+ Assert.assertEquals(url, "https://res.cloudinary.com/test123/image/upload/test");
}
@Test
@@ -89,21 +95,21 @@ public void testUrlWithNoAnalyticsNullAndTrue() {
cloudinary.analytics.setSDKSemver("1.30.0");
cloudinary.analytics.setTechVersion("12.0.0");
String url = cloudinary.url().generate("test");
- Assert.assertEquals(url, "http://res.cloudinary.com/test123/image/upload/test?_a=CAGAu5AMZAA0");
+ Assert.assertEquals(url, "https://res.cloudinary.com/test123/image/upload/test?_a=DAGAu5AMZAA0");
}
@Test
public void testMiscAnalyticsObject() {
cloudinary.config.analytics = true;
- Analytics analytics = new Analytics("Z", "1.24.0", "12.0.0", "Z", "1.34.0");
+ Analytics analytics = new Analytics("Z", "1.24.0", "12.0.0", "Z", "1.34.0", "0");
String result = analytics.toQueryParam();
- Assert.assertEquals(result, "_a=CAZAlhAMZ1J0");
+ Assert.assertEquals(result, "_a=DAZAlhAMZBi0");
}
@Test
public void testErrorAnalytics() {
cloudinary.config.analytics = true;
- Analytics analytics = new Analytics("Z", "1.24.0", "0", "Z", "1.34.0");
+ Analytics analytics = new Analytics("Z", "1.24.0", "0", "Z", "1.34.0", "0");
String result = analytics.toQueryParam();
Assert.assertEquals(result, "_a=E");
}
@@ -116,13 +122,21 @@ public void testUrlNoAnalyticsWithQueryParams() {
cloudinary.config.cloudName = "test123";
cloudinary.config.analytics = true;
- cloudinary.setAnalytics(new Analytics("F", "2.0.0", System.getProperty("java.version"), "Z", System.getProperty("os.version")));
+ cloudinary.setAnalytics(new Analytics("F", "2.0.0", System.getProperty("java.version"), "Z", System.getProperty("os.version"), "0"));
cloudinary.config.privateCdn = true;
String url = cloudinary.url().signed(true).type("authenticated").generate("test");
- assertEquals(url,"http://test123-res.cloudinary.com/image/authenticated/test?__cld_token__=st=11111111~exp=11111411~hmac=735a49389a72ac0b90d1a84ac5d43facd1a9047f153b39e914747ef6ed195e53");
+ assertEquals(url,"https://test123-res.cloudinary.com/image/authenticated/test?__cld_token__=st=11111111~exp=11111411~hmac=735a49389a72ac0b90d1a84ac5d43facd1a9047f153b39e914747ef6ed195e53");
cloudinary.config.privateCdn = false;
}
+ @Test
+ public void testFeatureFlag() {
+ Analytics analytics = new Analytics("F", "2.0.0", "1.8.0", "Z", "1.34.0", "0");
+ analytics.setFeatureFlag("F");
+ String result = analytics.toQueryParam();
+ Assert.assertEquals(result, "_a=DAFAACMhZBiF");
+ }
+
@After
public void tearDown() {
cloudinary.config.analytics = false;
diff --git a/cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java b/cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java
index f23acd60..18064976 100644
--- a/cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java
+++ b/cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java
@@ -18,7 +18,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
-import java.lang.reflect.ParameterizedType;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
@@ -35,7 +34,7 @@
@RunWith(JUnitParamsRunner.class)
public class CloudinaryTest {
- private static final String DEFAULT_ROOT_PATH = "http://res.cloudinary.com/test123/";
+ private static final String DEFAULT_ROOT_PATH = "https://res.cloudinary.com/test123/";
private static final String DEFAULT_UPLOAD_PATH = DEFAULT_ROOT_PATH + "image/upload/";
private static final String VIDEO_UPLOAD_PATH = DEFAULT_ROOT_PATH + "video/upload/";
private Cloudinary cloudinary;
@@ -46,7 +45,7 @@ public class CloudinaryTest {
@Before
public void setUp() {
System.out.println("Running " + this.getClass().getName() + "." + currentTest.getMethodName());
- this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false");
+ this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false&analytics=false");
}
@Test
@@ -93,13 +92,13 @@ public void testCloudName() {
public void testCloudNameOptions() {
// should allow overriding cloud_name in options
String result = cloudinary.url().cloudName("test321").generate("test");
- assertEquals("http://res.cloudinary.com/test321/image/upload/test", result);
+ assertEquals("https://res.cloudinary.com/test321/image/upload/test", result);
}
@Test
public void testSecureDistribution() {
// should use default secure distribution if secure=TRUE
- String result = cloudinary.url().secure(true).generate("test");
+ String result = cloudinary.url().generate("test");
assertEquals("https://res.cloudinary.com/test123/image/upload/test", result);
}
@@ -113,7 +112,7 @@ public void testTextLayerStyleIdentifierVariables() {
new TextLayer().text("hello-world").textStyle("$style")
)).generate("sample");
- assertEquals("http://res.cloudinary.com/test123/image/upload/$style_!Arial_12!/l_text:$style:hello-world/sample", url);
+ assertEquals("https://res.cloudinary.com/test123/image/upload/$style_!Arial_12!/l_text:$style:hello-world/sample", url);
url = cloudinary.url().transformation(
new Transformation()
@@ -123,14 +122,14 @@ public void testTextLayerStyleIdentifierVariables() {
new TextLayer().text("hello-world").textStyle(new Expression("$style"))
)).generate("sample");
- assertEquals("http://res.cloudinary.com/test123/image/upload/$style_!Arial_12!/l_text:$style:hello-world/sample", url);
+ assertEquals("https://res.cloudinary.com/test123/image/upload/$style_!Arial_12!/l_text:$style:hello-world/sample", url);
}
@Test
public void testSecureDistributionOverwrite() {
// should allow overwriting secure distribution if secure=TRUE
- String result = cloudinary.url().secure(true).secureDistribution("something.else.com").generate("test");
+ String result = cloudinary.url().secureDistribution("something.else.com").generate("test");
assertEquals("https://something.else.com/test123/image/upload/test", result);
}
@@ -168,7 +167,7 @@ public void testHttpPrivateCdn() {
// should not add cloud_name if private_cdn and not secure
cloudinary.config.privateCdn = true;
String result = cloudinary.url().generate("test");
- assertEquals("http://test123-res.cloudinary.com/image/upload/test", result);
+ assertEquals("https://test123-res.cloudinary.com/image/upload/test", result);
}
@Test
@@ -182,14 +181,14 @@ public void testFormat() {
public void testType() {
// should use type from options
String result = cloudinary.url().type("facebook").generate("test");
- assertEquals("http://res.cloudinary.com/test123/image/facebook/test", result);
+ assertEquals("https://res.cloudinary.com/test123/image/facebook/test", result);
}
@Test
public void testResourceType() {
// should use resource_type from options
String result = cloudinary.url().resourcType("raw").generate("test");
- assertEquals("http://res.cloudinary.com/test123/raw/upload/test", result);
+ assertEquals("https://res.cloudinary.com/test123/raw/upload/test", result);
}
@Test
@@ -200,27 +199,27 @@ public void testIgnoreHttp() {
result = cloudinary.url().type("asset").generate("http://test");
assertEquals("http://test", result);
result = cloudinary.url().type("fetch").generate("http://test");
- assertEquals("http://res.cloudinary.com/test123/image/fetch/http://test", result);
+ assertEquals("https://res.cloudinary.com/test123/image/fetch/http://test", result);
}
@Test
public void testFetch() {
// should escape fetch urls
String result = cloudinary.url().type("fetch").generate("http://blah.com/hello?a=b");
- assertEquals("http://res.cloudinary.com/test123/image/fetch/http://blah.com/hello%3Fa%3Db", result);
+ assertEquals("https://res.cloudinary.com/test123/image/fetch/http://blah.com/hello%3Fa%3Db", result);
}
@Test
public void testCname() {
// should support external cname
- String result = cloudinary.url().cname("hello.com").generate("test");
+ String result = cloudinary.url().cname("hello.com").secure(false).generate("test");
assertEquals("http://hello.com/test123/image/upload/test", result);
}
@Test
public void testCnameSubdomain() {
// should support external cname with cdn_subdomain on
- String result = cloudinary.url().cname("hello.com").cdnSubdomain(true).generate("test");
+ String result = cloudinary.url().cname("hello.com").cdnSubdomain(true).secure(false).generate("test");
assertEquals("http://a2.hello.com/test123/image/upload/test", result);
}
@@ -243,17 +242,17 @@ public void testDisallowUrlSuffixWithDot() {
@Test
public void testSupportUrlSuffixForPrivateCdn() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).generate("test");
- assertEquals("http://test123-res.cloudinary.com/images/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/images/test/hello", actual);
actual = cloudinary.url().suffix("hello").privateCdn(true).transformation(new Transformation().angle(0)).generate("test");
- assertEquals("http://test123-res.cloudinary.com/images/a_0/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/images/a_0/test/hello", actual);
}
@Test
public void testPutFormatAfterUrlSuffix() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).format("jpg").generate("test");
- assertEquals("http://test123-res.cloudinary.com/images/test/hello.jpg", actual);
+ assertEquals("https://test123-res.cloudinary.com/images/test/hello.jpg", actual);
}
@Test
@@ -266,7 +265,7 @@ public void testNotSignTheUrlSuffix() {
String expectedSignature = url.substring(matcher.start(), matcher.end());
String actual = cloudinary.url().format("jpg").privateCdn(true).signed(true).suffix("hello").generate("test");
- assertEquals("http://test123-res.cloudinary.com/images/" + expectedSignature + "/test/hello.jpg", actual);
+ assertEquals("https://test123-res.cloudinary.com/images/" + expectedSignature + "/test/hello.jpg", actual);
url = cloudinary.url().format("jpg").signed(true).transformation(new Transformation().angle(0)).generate("test");
matcher = pattern.matcher(url);
@@ -275,56 +274,56 @@ public void testNotSignTheUrlSuffix() {
actual = cloudinary.url().format("jpg").privateCdn(true).signed(true).suffix("hello").transformation(new Transformation().angle(0)).generate("test");
- assertEquals("http://test123-res.cloudinary.com/images/" + expectedSignature + "/a_0/test/hello.jpg", actual);
+ assertEquals("https://test123-res.cloudinary.com/images/" + expectedSignature + "/a_0/test/hello.jpg", actual);
}
@Test
public void testSignatureLength(){
String url = cloudinary.url().signed(true).generate("sample.jpg");
- assertEquals("http://res.cloudinary.com/test123/image/upload/s--v2fTPYTu--/sample.jpg", url);
+ assertEquals("https://res.cloudinary.com/test123/image/upload/s--v2fTPYTu--/sample.jpg", url);
url = cloudinary.url().signed(true).longUrlSignature(true).generate("sample.jpg");
- assertEquals("http://res.cloudinary.com/test123/image/upload/s--2hbrSMPOjj5BJ4xV7SgFbRDevFaQNUFf--/sample.jpg", url);
+ assertEquals("https://res.cloudinary.com/test123/image/upload/s--2hbrSMPOjj5BJ4xV7SgFbRDevFaQNUFf--/sample.jpg", url);
}
@Test
public void testSupportUrlSuffixForRawUploads() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).resourceType("raw").generate("test");
- assertEquals("http://test123-res.cloudinary.com/files/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/files/test/hello", actual);
}
@Test
public void testSupportUrlSuffixForVideoUploads() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).resourceType("video").generate("test");
- assertEquals("http://test123-res.cloudinary.com/videos/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/videos/test/hello", actual);
}
@Test
public void testSupportUrlSuffixForAuthenticatedImages() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).resourceType("image").type("authenticated").generate("test");
- assertEquals("http://test123-res.cloudinary.com/authenticated_images/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/authenticated_images/test/hello", actual);
}
@Test
public void testSupportUrlSuffixForPrivateImages() {
String actual = cloudinary.url().suffix("hello").privateCdn(true).resourceType("image").type("private").generate("test");
- assertEquals("http://test123-res.cloudinary.com/private_images/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/private_images/test/hello", actual);
}
@Test
public void testSupportUseRootPathForPrivateCdn() {
String actual = cloudinary.url().privateCdn(true).useRootPath(true).generate("test");
- assertEquals("http://test123-res.cloudinary.com/test", actual);
+ assertEquals("https://test123-res.cloudinary.com/test", actual);
actual = cloudinary.url().privateCdn(true).transformation(new Transformation().angle(0)).useRootPath(true).generate("test");
- assertEquals("http://test123-res.cloudinary.com/a_0/test", actual);
+ assertEquals("https://test123-res.cloudinary.com/a_0/test", actual);
}
@Test
public void testSupportUseRootPathTogetherWithUrlSuffixForPrivateCdn() {
String actual = cloudinary.url().privateCdn(true).suffix("hello").useRootPath(true).generate("test");
- assertEquals("http://test123-res.cloudinary.com/test/hello", actual);
+ assertEquals("https://test123-res.cloudinary.com/test/hello", actual);
}
@@ -452,7 +451,7 @@ public void testNoEmptyTransformation() {
public void testHttpEscape() {
// should escape http urls
String result = cloudinary.url().type("youtube").generate("http://www.youtube.com/watch?v=d9NF2edxy-M");
- assertEquals("http://res.cloudinary.com/test123/image/youtube/http://www.youtube.com/watch%3Fv%3Dd9NF2edxy-M", result);
+ assertEquals("https://res.cloudinary.com/test123/image/youtube/http://www.youtube.com/watch%3Fv%3Dd9NF2edxy-M", result);
}
@Test
@@ -489,14 +488,14 @@ public void testAngle() {
public void testFetchFormat() {
// should support format for fetch urls
String result = cloudinary.url().format("jpg").type("fetch").generate("http://cloudinary.com/images/old_logo.png");
- assertEquals("http://res.cloudinary.com/test123/image/fetch/f_jpg/http://cloudinary.com/images/old_logo.png", result);
+ assertEquals("https://res.cloudinary.com/test123/image/fetch/f_jpg/http://cloudinary.com/images/old_logo.png", result);
}
@Test
public void testUseFetchFormat() {
// should support use fetch format, adds the format but not an extension
String result = cloudinary.url().format("jpg").useFetchFormat(true).generate("old_logo");
- assertEquals("http://res.cloudinary.com/test123/image/upload/f_jpg/old_logo", result);
+ assertEquals("https://res.cloudinary.com/test123/image/upload/f_jpg/old_logo", result);
}
@Test
@@ -580,24 +579,24 @@ public void testOpacity() {
public void testImageTag() {
Transformation transformation = new Transformation().width(100).height(101).crop("crop");
String result = cloudinary.url().transformation(transformation).imageTag("test", asMap("alt", "my image"));
- assertEquals("
", result);
+ assertEquals("
", result);
transformation = new Transformation().width(0.9).height(0.9).crop("crop").responsiveWidth(true);
result = cloudinary.url().transformation(transformation).imageTag("test", asMap("alt", "my image"));
assertEquals(
- "
",
+ "
",
result);
result = cloudinary.url().transformation(transformation).imageTag("test", asMap("alt", "my image", "class", "extra"));
assertEquals(
- "",
+ "",
result);
transformation = new Transformation().width("auto").crop("crop");
result = cloudinary.url().transformation(transformation).imageTag("test", asMap("alt", "my image", "responsive_placeholder", "blank"));
assertEquals(
- "
",
+ "
",
result);
result = cloudinary.url().transformation(transformation).imageTag("test", asMap("alt", "my image", "responsive_placeholder", "other.gif"));
assertEquals(
- "
",
+ "
",
result);
}
@@ -614,12 +613,12 @@ public void testClientHints() {
assertTrue(testTag.startsWith("
getUrlParameters(URI uri) throws UnsupportedEn
@Test
public void testUrlCloneConfig() {
// verify that secure (from url.config) is cloned as well:
- Url url = cloudinary.url().cloudName("cloud").format("frmt").publicId("123").secure(true);
+ Url url = cloudinary.url().cloudName("cloud").format("frmt").publicId("123");
assertEquals("https://res.cloudinary.com/cloud/image/upload/123.frmt", url.clone().generate());
}
@@ -1465,6 +1464,20 @@ public void testDownloadBackedupAsset() throws UnsupportedEncodingException, URI
assertNotNull(params.get("timestamp"));
}
+ @Test
+ public void testRegisterUploaderStrategy() {
+ String className = "myUploadStrategy";
+ Cloudinary.registerUploaderStrategy(className);
+ assertEquals(className, Cloudinary.UPLOAD_STRATEGIES.get(0));
+ }
+
+ @Test
+ public void testRegisterApiStrategy() {
+ String className = "myApiStrategy";
+ Cloudinary.registerAPIStrategy(className);
+ assertEquals(className, Cloudinary.API_STRATEGIES.get(0));
+ }
+
private void assertFieldsEqual(Object a, Object b) throws IllegalAccessException {
assertEquals("Two objects must be the same class", a.getClass(), b.getClass());
Field[] fields = a.getClass().getFields();
diff --git a/cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java b/cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java
index d801c4dc..ca230f52 100644
--- a/cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java
+++ b/cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java
@@ -12,14 +12,14 @@
* Created by amir on 03/11/2015.
*/
public class LayerTest {
- private static final String DEFAULT_ROOT_PATH = "http://res.cloudinary.com/test123/";
+ private static final String DEFAULT_ROOT_PATH = "https://res.cloudinary.com/test123/";
private static final String DEFAULT_UPLOAD_PATH = DEFAULT_ROOT_PATH + "image/upload/";
private static final String VIDEO_UPLOAD_PATH = DEFAULT_ROOT_PATH + "video/upload/";
private Cloudinary cloudinary;
@Before
public void setUp() {
- this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false");
+ this.cloudinary = new Cloudinary("cloudinary://a:b@test123?load_strategies=false&analytics=false");
}
@After
@@ -46,7 +46,7 @@ public void testOverlay() {
}
@Test
- public void testUnderlay() {
+ public void testUnderlay() {
Transformation transformation = new Transformation().underlay("text:hello");
String result = cloudinary.url().transformation(transformation).generate("test");
assertEquals(DEFAULT_UPLOAD_PATH + "u_text:hello/test", result);
diff --git a/cloudinary-http42/build.gradle b/cloudinary-http42/build.gradle
deleted file mode 100644
index 7c94214b..00000000
--- a/cloudinary-http42/build.gradle
+++ /dev/null
@@ -1,114 +0,0 @@
-plugins {
- id 'java-library'
- id 'signing'
- id 'maven-publish'
- id 'io.codearte.nexus-staging' version '0.21.1'
-}
-
-apply from: "../java_shared.gradle"
-
-task ciTest( type: Test ) {
- useJUnit {
- excludeCategories 'com.cloudinary.test.TimeoutTest'
- if (System.getProperty("CLOUDINARY_ACCOUNT_URL") == "") {
- exclude '**/AccountApiTest.class'
- }
- }
-}
-
-dependencies {
- compile project(':cloudinary-core')
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
- compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.2.1'
- compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.2.1'
- compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.2.1'
- testCompile project(':cloudinary-test-common')
- testCompile group: 'org.hamcrest', name: 'java-hamcrest', version: '2.0.0.0'
- testCompile group: 'pl.pragmatists', name: 'JUnitParams', version: '1.0.5'
- testCompile group: 'junit', name: 'junit', version: '4.12'
-}
-
-if (hasProperty("ossrhPassword")) {
-
- signing {
- sign configurations.archives
- }
-
- nexusStaging {
- packageGroup = group
- username = project.hasProperty("ossrhUsername") ? project.ext["ossrhUsername"] : ""
- password = project.hasProperty("ossrhPassword") ? project.ext["ossrhPassword"] : ""
- }
-
- publishing {
- publications {
- mavenJava(MavenPublication) {
- from components.java
- artifact sourcesJar
- artifact javadocJar
- pom {
- name = 'Cloudinary Apache HTTP 4.2 Library'
- packaging = 'jar'
- groupId = publishGroupId
- artifactId = 'cloudinary-http42'
- description = publishDescription
- url = githubUrl
- licenses {
- license {
- name = licenseName
- url = licenseUrl
- }
- }
-
- developers {
- developer {
- id = developerId
- name = developerName
- email = developerEmail
- }
- }
- scm {
- connection = scmConnection
- developerConnection = scmDeveloperConnection
- url = scmUrl
- }
- }
-
- pom.withXml {
- def pomFile = file("${project.buildDir}/generated-pom.xml")
- writeTo(pomFile)
- def pomAscFile = signing.sign(pomFile).signatureFiles[0]
- artifact(pomAscFile) {
- classifier = null
- extension = 'pom.asc'
- }
- }
-
- // create the signed artifacts
- project.tasks.signArchives.signatureFiles.each {
- artifact(it) {
- def matcher = it.file =~ /-(sources|javadoc)\.jar\.asc$/
- if (matcher.find()) {
- classifier = matcher.group(1)
- } else {
- classifier = null
- }
- extension = 'jar.asc'
- }
- }
- }
- }
-
- model {
- tasks.generatePomFileForMavenJavaPublication {
- destination = file("$buildDir/generated-pom.xml")
- }
- tasks.publishMavenJavaPublicationToMavenLocal {
- dependsOn project.tasks.signArchives
- }
- tasks.publishMavenJavaPublicationToSonatypeRepository {
- dependsOn project.tasks.signArchives
- }
- }
- }
-}
diff --git a/cloudinary-http42/src/main/java/com/cloudinary/http42/ApiStrategy.java b/cloudinary-http42/src/main/java/com/cloudinary/http42/ApiStrategy.java
deleted file mode 100644
index 6703448e..00000000
--- a/cloudinary-http42/src/main/java/com/cloudinary/http42/ApiStrategy.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package com.cloudinary.http42;
-
-import com.cloudinary.Api;
-import com.cloudinary.Api.HttpMethod;
-import com.cloudinary.Cloudinary;
-import com.cloudinary.api.ApiResponse;
-import com.cloudinary.api.exceptions.GeneralError;
-import com.cloudinary.http42.api.Response;
-import com.cloudinary.strategies.AbstractApiStrategy;
-import com.cloudinary.utils.Base64Coder;
-import com.cloudinary.utils.ObjectUtils;
-import com.cloudinary.utils.StringUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.*;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.cloudinary.json.JSONException;
-import org.cloudinary.json.JSONObject;
-
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Map;
-
-public class ApiStrategy extends AbstractApiStrategy {
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- public ApiResponse callApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception {
- if (options == null) options = ObjectUtils.emptyMap();
-
- String prefix = ObjectUtils.asString(options.get("upload_prefix"), ObjectUtils.asString(this.api.cloudinary.config.uploadPrefix, "https://api.cloudinary.com"));
- String cloudName = ObjectUtils.asString(options.get("cloud_name"), this.api.cloudinary.config.cloudName);
- if (cloudName == null) throw new IllegalArgumentException("Must supply cloud_name");
- String apiKey = ObjectUtils.asString(options.get("api_key"), this.api.cloudinary.config.apiKey);
- String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.api.cloudinary.config.apiSecret);
- String oauthToken = ObjectUtils.asString(options.get("oauth_token"), this.api.cloudinary.config.oauthToken);
- String contentType = ObjectUtils.asString(options.get("content_type"), "urlencoded");
- int timeout = ObjectUtils.asInteger(options.get("timeout"), this.api.cloudinary.config.timeout);
- validateAuthorization(apiKey, apiSecret, oauthToken);
-
- String apiUrl = createApiUrl(uri, prefix, cloudName);
-
- return getApiResponse(method, params, apiKey, apiSecret, oauthToken, contentType, timeout, apiUrl);
- }
-
- @Override
- public ApiResponse callAccountApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception {
- String prefix = ObjectUtils.asString(options.get("upload_prefix"), "https://api.cloudinary.com");
- String apiKey = ObjectUtils.asString(options.get("provisioning_api_key"));
- if (apiKey == null) throw new IllegalArgumentException("Must supply provisioning_api_key");
- String apiSecret = ObjectUtils.asString(options.get("provisioning_api_secret"));
- if (apiSecret == null) throw new IllegalArgumentException("Must supply provisioning_api_secret");
- String contentType = ObjectUtils.asString(options.get("content_type"), "urlencoded");
- int timeout = ObjectUtils.asInteger(options.get("timeout"), this.api.cloudinary.config.timeout);
-
- String apiUrl = StringUtils.join(Arrays.asList(prefix, "v1_1"), "/");
- for (String component : uri) {
- apiUrl = apiUrl + "/" + component;
- }
-
- return getApiResponse(method, params, apiKey, apiSecret, null, contentType, timeout, apiUrl);
- }
-
- private ApiResponse getApiResponse(HttpMethod method, Map params, String apiKey, String apiSecret, String oauthToken, String contentType, int timeout, String apiUrl) throws Exception {
- URIBuilder apiUrlBuilder = new URIBuilder(apiUrl);
- if (!contentType.equals("json")) {
- for (Map.Entry param : params.entrySet()) {
- if (param.getValue() instanceof Iterable) {
- for (String single : (Iterable) param.getValue()) {
- apiUrlBuilder.addParameter(param.getKey() + "[]", single);
- }
- } else {
- apiUrlBuilder.addParameter(param.getKey(), ObjectUtils.asString(param.getValue()));
- }
- }
- }
-
- ClientConnectionManager connectionManager = (ClientConnectionManager) this.api.cloudinary.config.properties.get("connectionManager");
-
- DefaultHttpClient client = new DefaultHttpClient(connectionManager);
- if (timeout > 0) {
- HttpParams httpParams = client.getParams();
- HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
- HttpConnectionParams.setSoTimeout(httpParams, timeout);
- }
-
- URI apiUri = apiUrlBuilder.build();
- HttpUriRequest request = null;
- switch (method) {
- case GET:
- request = new HttpGet(apiUri);
- break;
- case PUT:
- request = new HttpPut(apiUri);
- break;
- case POST:
- request = new HttpPost(apiUri);
- break;
- case DELETE:
- request = new HttpDelete(apiUri);
- break;
- }
- request.setHeader("Authorization", getAuthorizationHeaderValue(apiKey, apiSecret, oauthToken));
- request.setHeader("User-Agent", this.api.cloudinary.getUserAgent() + " ApacheHTTPComponents/4.2");
- if (contentType.equals("json")) {
- JSONObject asJSON = ObjectUtils.toJSON(params);
- StringEntity requestEntity = new StringEntity(asJSON.toString(), ContentType.APPLICATION_JSON);
- ((HttpEntityEnclosingRequestBase) request).setEntity(requestEntity);
- }
-
- HttpResponse response = client.execute(request);
-
- int code = response.getStatusLine().getStatusCode();
- InputStream responseStream = response.getEntity().getContent();
- String responseData = StringUtils.read(responseStream);
-
- Class extends Exception> exceptionClass = Api.CLOUDINARY_API_ERROR_CLASSES.get(code);
- if (code != 200 && exceptionClass == null) {
- throw new GeneralError("Server returned unexpected status code - " + code + " - " + responseData);
- }
- Map result;
-
- try {
- JSONObject responseJSON = new JSONObject(responseData);
- result = ObjectUtils.toMap(responseJSON);
- } catch (JSONException e) {
- throw new RuntimeException("Invalid JSON response from server " + e.getMessage());
- }
-
- if (code == 200) {
- return new Response(response, result);
- } else {
- String message = (String) ((Map) result.get("error")).get("message");
- Constructor extends Exception> exceptionConstructor = exceptionClass.getConstructor(String.class);
- throw exceptionConstructor.newInstance(message);
- }
- }
-
-}
diff --git a/cloudinary-http42/src/main/java/com/cloudinary/http42/UploaderStrategy.java b/cloudinary-http42/src/main/java/com/cloudinary/http42/UploaderStrategy.java
deleted file mode 100644
index 0e38365d..00000000
--- a/cloudinary-http42/src/main/java/com/cloudinary/http42/UploaderStrategy.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.cloudinary.http42;
-
-import com.cloudinary.Cloudinary;
-import com.cloudinary.ProgressCallback;
-import com.cloudinary.Util;
-import com.cloudinary.strategies.AbstractUploaderStrategy;
-import com.cloudinary.utils.ObjectUtils;
-import com.cloudinary.utils.StringUtils;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.params.ConnRoutePNames;
-import org.apache.http.entity.mime.HttpMultipartMode;
-import org.apache.http.entity.mime.MultipartEntity;
-import org.apache.http.entity.mime.content.ByteArrayBody;
-import org.apache.http.entity.mime.content.FileBody;
-import org.apache.http.entity.mime.content.StringBody;
-import org.apache.http.impl.client.DefaultHttpClient;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Map;
-
-public class UploaderStrategy extends AbstractUploaderStrategy {
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- @Override
- public Map callApi(String action, Map params, Map options, Object file, ProgressCallback progressCallback) throws IOException {
- if (progressCallback != null){
- throw new IllegalArgumentException("Progress callback is not supported");
- }
-
- // initialize options if passed as null
- if (options == null) {
- options = ObjectUtils.emptyMap();
- }
-
- boolean returnError = ObjectUtils.asBoolean(options.get("return_error"), false);
-
- if (requiresSigning(action, options)) {
- uploader.signRequestParams(params, options);
- } else {
- Util.clearEmpty(params);
- }
-
- String apiUrl = buildUploadUrl(action, options);
-
- ClientConnectionManager connectionManager = (ClientConnectionManager) this.uploader.cloudinary().config.properties.get("connectionManager");
- HttpClient client = new DefaultHttpClient(connectionManager);
-
- // If the configuration specifies a proxy then apply it to the client
- if (uploader.cloudinary().config.proxyHost != null && uploader.cloudinary().config.proxyPort != 0) {
- HttpHost proxy = new HttpHost(uploader.cloudinary().config.proxyHost, uploader.cloudinary().config.proxyPort);
- client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
- }
-
- HttpPost postMethod = new HttpPost(apiUrl);
- postMethod.setHeader("User-Agent", this.cloudinary().getUserAgent() + " ApacheHTTPComponents/4.2");
-
- Map extraHeaders = (Map) options.get("extra_headers");
- if (extraHeaders != null) {
- for (Map.Entry header : extraHeaders.entrySet()) {
- postMethod.setHeader(header.getKey(), header.getValue());
- }
- }
-
- Charset utf8 = Charset.forName("UTF-8");
-
- MultipartEntity multipart = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, StandardCharsets.UTF_8);
- // Remove blank parameters
- for (Map.Entry param : params.entrySet()) {
- if (param.getValue() instanceof Collection) {
- for (Object value : (Collection) param.getValue()) {
- multipart.addPart(param.getKey() + "[]", new StringBody(ObjectUtils.asString(value), utf8));
- }
- } else {
- String value = param.getValue().toString();
- if (StringUtils.isNotBlank(value)) {
- multipart.addPart(param.getKey(), new StringBody(value, utf8));
- }
- }
- }
- if(file instanceof String && !(StringUtils.isRemoteUrl((String)file))){
- File _file = new File((String) file);
- if (!_file.isFile() && !_file.canRead()) {
- throw new IOException("File not found or unreadable: " + file);
- }
- file = _file;
- }
-
- String filename = (String) options.get("filename");
- if (file instanceof File) {
- multipart.addPart("file", new FileBody((File) file, filename, "application/octet-stream", null));
- } else if (file instanceof String) {
- multipart.addPart("file", new StringBody((String) file, utf8));
- } else if (file instanceof byte[]) {
- if (filename == null) filename = "file";
- multipart.addPart("file", new ByteArrayBody((byte[]) file, filename));
- } else if (file == null) {
- // no-problem
- } else {
- throw new IOException("Unrecognized file parameter " + file);
- }
- postMethod.setEntity(multipart);
-
- HttpResponse response = client.execute(postMethod);
- int code = response.getStatusLine().getStatusCode();
- InputStream responseStream = response.getEntity().getContent();
- String responseData = StringUtils.read(responseStream);
-
- return processResponse(returnError, code, responseData);
- }
-
-}
diff --git a/cloudinary-http42/src/test/java/com/cloudinary/test/ApiTest.java b/cloudinary-http42/src/test/java/com/cloudinary/test/ApiTest.java
deleted file mode 100644
index b3fa3556..00000000
--- a/cloudinary-http42/src/test/java/com/cloudinary/test/ApiTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.cloudinary.test;
-
-import org.apache.http.conn.ConnectTimeoutException;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ApiTest extends AbstractApiTest {
- @Category(TimeoutTest.class)
- @Test(expected = ConnectTimeoutException.class)
- public void testTimeoutException() throws Exception {
- // should allow listing resources
- Map options = new HashMap();
- options.put("timeout", Integer.valueOf(1));
-
- Map result = api.resources(options);
- Map resource = findByAttr((List