You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/01/05 17:18:36 UTC
[isis] branch dev/2.0.0-M1 updated: ISIS-1809: adds new
implementations of UrlEncodingService
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch dev/2.0.0-M1
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/dev/2.0.0-M1 by this push:
new d727de1 ISIS-1809: adds new implementations of UrlEncodingService
new e97fa3c Merge branch 'ISIS-1809-url-encoding-service' into dev/2.0.0-M1
d727de1 is described below
commit d727de10bfd011e9c1d1a4f835dc6fe0dd381b4c
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Jan 5 17:17:24 2018 +0000
ISIS-1809: adds new implementations of UrlEncodingService
---
.../UrlEncodingServiceUsingBaseEncoding.java | 10 +++-
...aseEncodingWithSupportForLargeUrlsAbstract.java | 69 ++++++++++++++++++++++
.../UrlEncodingServiceWithCompressionAbstract.java | 66 +++++++++++++++++++++
...codingServiceWithCompression_Abstract_Test.java | 35 +++++++++++
4 files changed, 179 insertions(+), 1 deletion(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
index b81e919..6d30288 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
@@ -46,13 +46,21 @@ public class UrlEncodingServiceUsingBaseEncoding implements UrlEncodingService {
@Programmatic
public String encode(final String str) {
byte[] bytes = str.getBytes(charset);
+ return encodeToBase64(bytes);
+ }
+
+ String encodeToBase64(final byte[] bytes) {
return baseEncoding.encode(bytes);
}
@Programmatic
public String decode(String str) {
- final byte[] bytes = baseEncoding.decode(str);
+ final byte[] bytes = decodeBase64(str);
return new String(bytes, Charset.forName("UTF-8"));
}
+ byte[] decodeBase64(final String str) {
+ return baseEncoding.decode(str);
+ }
+
}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncodingWithSupportForLargeUrlsAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncodingWithSupportForLargeUrlsAbstract.java
new file mode 100644
index 0000000..c0d7689
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncodingWithSupportForLargeUrlsAbstract.java
@@ -0,0 +1,69 @@
+package org.apache.isis.applib.services.urlencoding;
+
+import java.util.UUID;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.Maps;
+
+/**
+ * to use, subclass and annotated with:
+ * <pre>
+ * @DomainService(nature=DOMAIN, menuOrder="100")
+ * </pre>
+ */
+public abstract class UrlEncodingServiceUsingBaseEncodingWithSupportForLargeUrlsAbstract extends UrlEncodingServiceUsingBaseEncoding {
+
+ /**
+ * Strings under this length are not cached, just returned as is.
+ */
+ private static final int MIN_LENGTH_TO_CACHE = 500;
+ /**
+ * Used to distinguish which strings represent keys in the cache, versus those not cached.
+ */
+ private static final String KEY_PREFIX = "______";
+
+ private static final int EXPECTED_SIZE = 1000;
+
+ // this is a naive implementation that will leak memory
+ private final BiMap<String, String> cachedValueByKey =
+ Maps.synchronizedBiMap(HashBiMap.<String, String>create(EXPECTED_SIZE));
+
+ @Override
+ public String encode(final String value) {
+ if(!canCache(value)) {
+ return super.encode(value);
+ }
+
+ synchronized (cachedValueByKey) {
+ String key = cachedValueByKey.inverse().get(value);
+ if (key == null) {
+ key = newKey();
+ cachedValueByKey.put(key, value);
+ }
+ return KEY_PREFIX + key;
+ }
+ }
+
+ @Override
+ public String decode(final String key) {
+ if(key == null || !key.startsWith(KEY_PREFIX)) {
+ return super.decode(key);
+ }
+ String keySuffix = key.substring(KEY_PREFIX.length());
+ return cachedValueByKey.get(keySuffix);
+ }
+
+ /**
+ * Factored out to allow easy subclassing.
+ */
+ protected String newKey() {
+ return UUID.randomUUID().toString();
+ }
+
+ private boolean canCache(final String key) {
+ return key != null && key.length() > MIN_LENGTH_TO_CACHE;
+ }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompressionAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompressionAbstract.java
new file mode 100644
index 0000000..892f24d
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompressionAbstract.java
@@ -0,0 +1,66 @@
+package org.apache.isis.applib.services.urlencoding;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.inject.Inject;
+
+/**
+ * to use, subclass and annotated with:
+ * <pre>
+ * @DomainService(nature=DOMAIN, menuOrder="100")
+ * </pre>
+ */
+public abstract class UrlEncodingServiceWithCompressionAbstract implements UrlEncodingService {
+
+ @Override
+ public String encode(final String str) {
+ try {
+ final byte[] compressed = compress(str);
+ return base64Encoder.encodeToBase64(compressed);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ @Override
+ public String decode(final String str) {
+ final byte[] bytes = base64Encoder.decodeBase64(str);
+ try {
+ return decompress(bytes);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private static byte[] compress(String string) throws IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream(string.length());
+ GZIPOutputStream gos = new GZIPOutputStream(os);
+ gos.write(string.getBytes());
+ gos.close();
+ byte[] compressed = os.toByteArray();
+ os.close();
+ return compressed;
+ }
+
+ private static String decompress(byte[] compressed) throws IOException {
+ final int BUFFER_SIZE = 32;
+ ByteArrayInputStream is = new ByteArrayInputStream(compressed);
+ GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] data = new byte[BUFFER_SIZE];
+ int bytesRead;
+ while ((bytesRead = gis.read(data)) != -1) {
+ baos.write(data, 0, bytesRead);
+ }
+ gis.close();
+ return baos.toString("UTF-8");
+ }
+
+ @Inject
+ UrlEncodingServiceUsingBaseEncoding base64Encoder;
+
+}
diff --git a/core/applib/src/test/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompression_Abstract_Test.java b/core/applib/src/test/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompression_Abstract_Test.java
new file mode 100644
index 0000000..1667983
--- /dev/null
+++ b/core/applib/src/test/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceWithCompression_Abstract_Test.java
@@ -0,0 +1,35 @@
+package org.apache.isis.applib.services.urlencoding;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.greaterThan;
+
+public class UrlEncodingServiceWithCompression_Abstract_Test {
+
+ UrlEncodingServiceWithCompressionAbstract service;
+
+ @Before
+ public void setUp() throws Exception {
+ service = new UrlEncodingServiceWithCompressionAbstract(){};
+ service.base64Encoder = new UrlEncodingServiceUsingBaseEncoding();
+ }
+
+ @Test
+ public void roundtrip() throws Exception {
+
+ final String original = "0-theme-entityPageContainer-entity-rows-2-rowContents-1-col-tabGroups-1-panel-tabPanel-rows-1-rowContents-1-col-fieldSets-1-memberGroup-properties-1-property-scalarTypeContainer-scalarIfRegular-associatedActionLinksBelow-additionalLinkList-additionalLinkItem-0-additionalLink";
+
+ final String encoded = service.encode(original);
+ final String decoded = service.decode(encoded);
+
+ Assert.assertThat(decoded, is(equalTo(original)));
+
+ Assert.assertThat(original.length(), is(greaterThan(encoded.length())));
+ }
+
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
['"commits@isis.apache.org" <co...@isis.apache.org>'].