diff --git a/.gitignore b/.gitignore index 138daa4..628dd88 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea urlencoder.iml -target/ \ No newline at end of file +target/ diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar new file mode 100644 index 0000000..41952ce Binary files /dev/null and b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar differ diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.md5 b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.md5 new file mode 100644 index 0000000..538d135 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.md5 @@ -0,0 +1 @@ +49dc3de2b678cf3e64ee924ceb25459b \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.sha1 b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.sha1 new file mode 100644 index 0000000..1c05e32 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.jar.sha1 @@ -0,0 +1 @@ +d27783f047fb2f74e373c513a4ef22922a58366d \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom new file mode 100644 index 0000000..16d5449 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom @@ -0,0 +1,74 @@ + + + 4.0.0 + + br.com.quintoandar + urlencoder + 1.0.0 + + + + javax.ws.rs + javax.ws.rs-api + ${rs-api.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.jboss.resteasy + resteasy-jaxrs + ${resteasy-jaxrs.version} + + + org.jboss.resteasy + resteasy-client + ${resteasy-client.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + maven-deploy-plugin + 2.8.1 + + internal.repo::default::file://${internal.repo.path} + + + + + + + 2.1 + 3.7 + 4.5.5 + 3.1.4.Final + 3.1.4.Final + 1.16.20 + 1.8 + 1.8 + ${basedir}/mvn-repo/ + + + + + + + + + \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.md5 b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.md5 new file mode 100644 index 0000000..7ada8b3 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.md5 @@ -0,0 +1 @@ +8fec72026ee735be963ed7226cd5f567 \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.sha1 b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.sha1 new file mode 100644 index 0000000..17d73d8 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/1.0.0/urlencoder-1.0.0.pom.sha1 @@ -0,0 +1 @@ +d1c966308a42fd711c44bd0d46fb03a24512068f \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml new file mode 100644 index 0000000..844e430 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml @@ -0,0 +1,12 @@ + + + br.com.quintoandar + urlencoder + + 1.0.0 + + 1.0.0 + + 20180226134832 + + diff --git a/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.md5 b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.md5 new file mode 100644 index 0000000..6272d3a --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.md5 @@ -0,0 +1 @@ +78cdde2bb8a5dfdaa7408bc585f72c06 \ No newline at end of file diff --git a/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.sha1 b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.sha1 new file mode 100644 index 0000000..6633247 --- /dev/null +++ b/mvn-repo/br/com/quintoandar/urlencoder/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +c7e4b8690379b4e32e0a4762c649332fddb081d2 \ No newline at end of file diff --git a/pom.xml b/pom.xml index bd56097..0ada4de 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ br.com.quintoandar urlencoder - 1.0-SNAPSHOT + 1.0.0 @@ -41,6 +41,18 @@ + + + + maven-deploy-plugin + 2.8.1 + + internal.repo::default::file://${internal.repo.path} + + + + + 2.1 3.7 @@ -48,6 +60,9 @@ 3.1.4.Final 3.1.4.Final 1.16.20 + 1.8 + 1.8 + ${basedir}/mvn-repo/ \ No newline at end of file diff --git a/src/main/java/br/com/quintoandar/urlencoder/UrlEncoder.java b/src/main/java/br/com/quintoandar/urlencoder/UrlEncoder.java index ff8d59d..291d290 100644 --- a/src/main/java/br/com/quintoandar/urlencoder/UrlEncoder.java +++ b/src/main/java/br/com/quintoandar/urlencoder/UrlEncoder.java @@ -1,12 +1,17 @@ package br.com.quintoandar.urlencoder; import java.util.Map; +import java.util.Optional; import java.util.Random; +import lombok.Data; import lombok.NonNull; import org.apache.commons.lang3.RandomStringUtils; +@Data public class UrlEncoder { + private static final int SIZE_SHORT_HASH = 6; + private YourlsApiService service; private int keywordLength; private String signature; @@ -25,72 +30,115 @@ public UrlEncoder(String uri, int keywordLength, String signature, @NonNull String environment) { this(uri, keywordLength, signature); this.withEnvironment = true; - this.environment = String.format("%s-", environment); - } - - public String encodeURL(@NonNull String urlToEncode) { - return encodeURL(urlToEncode, null, false); + this.environment = environment; } - public String encodeURLWithSufix(String urlToEncode, @NonNull String keyword) { - return encodeURL(urlToEncode, keyword, true); - } - - private String encodeURL(String urlToEncode, String keyword, boolean overwrite) { - keyword = keyword == null ? generateRandomAlphanumeric() : keyword; - String keywordWithPrefix = this.environment + keyword; - - keywordWithPrefix = keywordWithPrefix.toLowerCase(); - Map map = this.service.getInstance() - .shorturl(signature, "shorturl", "json", urlToEncode, keywordWithPrefix, - "URL Shortned via QuinToUrlEncoder.java"); - - if (map.get("status").equals("fail")) { - if (map.get("message").toString().equalsIgnoreCase( - "Short URL " + keywordWithPrefix + " already exists in database or is reserved")) { - if (overwrite && keyword != null) { - this.service.getInstance() - .delete(signature, YourlsApi.ACTION_DELETE, YourlsApi.FORMAT_JSON, keywordWithPrefix); - return encodeURL(urlToEncode, keyword, overwrite); - } - if (!overwrite && keyword == null) { - return encodeURL(urlToEncode, null, overwrite); - } - } + public String encodeURL(String url) { + String generatedKeyword = generateRandomAlphanumeric(); + String finalKeyword = isWithEnvironment() ? + generateKeywordWithEnvironment(generatedKeyword) + : generatedKeyword; + ShortUrlResponse shortUrlResponse = shortUrlWithKeyword(url, finalKeyword); + if (shortUrlResponse.isFail() && shortUrlResponse.getFailReason().equals(FailReason.KEYWORD_ALREADY_EXIST)) { + return this.encodeURL(url); + } else if (!shortUrlResponse.isFail()) { + return shortUrlResponse.getShortUrl(); } + return null; + } - if (map != null && map.containsKey("shorturl")) { - return map.get("shorturl").toString(); + public String encodeUrlWithKeyword(String url, String keyword) { + String finalKeyword = isWithEnvironment() ? + generateKeywordWithEnvironment(keyword) + : keyword; + ShortUrlResponse shortUrlResponse = shortUrlWithKeyword(url, finalKeyword); + if (shortUrlResponse.isFail() && shortUrlResponse.getFailReason().equals(FailReason.KEYWORD_ALREADY_EXIST)) { + deleteKeyword(finalKeyword); + return this.encodeUrlWithKeyword(url, keyword); + } else if (!shortUrlResponse.isFail()) { + return shortUrlResponse.getShortUrl(); } return null; } - public String encodeURLWithHash(String urlToEncode, String hashLoginBypass, String prefix) { - int tamHashEncurtado = 6; - StringBuilder keyword = new StringBuilder(prefix); - - if (hashLoginBypass != null && hashLoginBypass.length() >= tamHashEncurtado) { - int ini = (new Random()).nextInt(hashLoginBypass.length() - tamHashEncurtado); - keyword.append("-" + hashLoginBypass.substring(ini, ini + tamHashEncurtado)); - } - return encodeURL(urlToEncode, keyword.toString(), true); + public String encodeURLWithHash(String url, @NonNull String hash, String prefix) { + String finalKeyword = hash.length() >= SIZE_SHORT_HASH ? generateShortHash(hash, prefix) : prefix; + return encodeUrlWithKeyword(url, finalKeyword); } - public String encodeWithMultipleTries(String urlToEncode, String hashLoginBypass, String prefix, - int maxTries) { - int tries = 0; - while (tries < maxTries) { + public String encodeWithHashMultipleTries(String url, String hash, String prefix, int maxTries) { + int nTries = maxTries; + while (nTries > 0) { try { - return encodeURLWithHash(urlToEncode, hashLoginBypass, prefix); + return encodeURLWithHash(url, hash, prefix); } catch (Exception e) { - tries++; + nTries--; } } throw new RuntimeException( - String.format("Url shortning unavailable: tried %d", maxTries)); + String.format("Url shortning unavailable: tried %d times.", maxTries)); } + private String generateShortHash(String hash, String prefix) { + int ini = (new Random()).nextInt(hash.length() - SIZE_SHORT_HASH); + return String.format("%s-%s", prefix, hash.substring(ini, ini + SIZE_SHORT_HASH)); + } + + private String generateKeywordWithEnvironment(String generatedKeyword) { + return String.format("%s-%s", getEnvironment(), generatedKeyword); + } + + private void deleteKeyword(String keyword) { + this.service.getInstance() + .delete(signature, YourlsApi.ACTION_DELETE, YourlsApi.FORMAT_JSON, keyword); + } + + private ShortUrlResponse shortUrlWithKeyword(String urlToEncode, String keyword) { + Map result = this.service.getInstance() + .shorturl(signature, "shorturl", "json", urlToEncode, keyword.toLowerCase(), + "URL Shortned via UrlEncoder.java"); + boolean fail = result.get("status").equals("fail"); + String shorturl = Optional.ofNullable(result.get("shorturl")) + .map(o -> o.toString()).orElse(null); + FailReason failReason = Optional.ofNullable(result.get("message")) + .map(m -> { + if (fail) { + if (m.toString().equalsIgnoreCase( + String.format( + "Short URL %s already exists in database or is reserved", + keyword)) + ) { + return FailReason.KEYWORD_ALREADY_EXIST; + } else { + return FailReason.UNKNOWN; + } + } + return null; + }).orElse(null); + + return new ShortUrlResponse(shorturl,fail,failReason); + } + private String generateRandomAlphanumeric() { return RandomStringUtils.randomAlphanumeric(keywordLength).toLowerCase(); } + + protected enum FailReason { + KEYWORD_ALREADY_EXIST, + UNKNOWN, + } + + @Data + protected class ShortUrlResponse { + + private String shortUrl; + private boolean fail; + private FailReason failReason; + + public ShortUrlResponse(String shortUrl, boolean fail, FailReason failReason) { + this.shortUrl = shortUrl; + this.fail = fail; + this.failReason = failReason; + } + } }