Skip to content
This repository has been archived by the owner on Jul 2, 2023. It is now read-only.

Commit

Permalink
Add ordering to entity converters, and made the manager immutable.
Browse files Browse the repository at this point in the history
  • Loading branch information
bud4453 committed May 9, 2019
1 parent 495454a commit 6659e0f
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2016-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.budjb.httprequests;

public interface Ordered {
/**
* Default priority.
*/
int DEFAULT_PRIORITY = 0;

/**
* Lowest priority.
*/
int LOWEST_PRIORITY = Integer.MIN_VALUE;

/**
* Highest priority.
*/
int HIGHEST_PRIORITY = Integer.MAX_VALUE;

/**
* Returns an order used for comparison and sorting.
*
* @return An order used for comparison and sorting.
*/
default int getOrder() {
return DEFAULT_PRIORITY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@

import com.budjb.httprequests.ConvertingHttpEntity;
import com.budjb.httprequests.HttpEntity;
import com.budjb.httprequests.Ordered;
import com.budjb.httprequests.exception.UnsupportedConversionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -36,15 +37,17 @@ public class EntityConverterManager {
/**
* List of registered entity converters.
*/
private final List<EntityConverter> converters = new ArrayList<>();
private final List<EntityConverter> converters;

/**
* Adds an entity converter to the manager.
*
* @param converter Converter to add to the manager.
*/
public void add(EntityConverter converter) {
converters.add(converter);
public EntityConverterManager(List<EntityConverter> entityConverters) {
Comparator<EntityConverter> comparator = (o1, o2) -> {
int l = (o1 instanceof Ordered) ? ((Ordered) o1).getOrder() : 0;
int r = (o2 instanceof Ordered) ? ((Ordered) o2).getOrder() : 0;

return Integer.compare(r, l);
};

converters = entityConverters.stream().sorted(comparator).collect(Collectors.toList());
}

/**
Expand All @@ -56,22 +59,6 @@ public List<EntityConverter> getAll() {
return converters;
}

/**
* Remove an entity converter.
*
* @param converter Entity converter to remove.
*/
public void remove(EntityConverter converter) {
converters.remove(converter);
}

/**
* Remove all entity converters.
*/
public void clear() {
converters.clear();
}

/**
* Returns the list of all registered entity readers.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.budjb.httprequests.converter.bundled;

import com.budjb.httprequests.Ordered;
import com.budjb.httprequests.StreamUtils;
import com.budjb.httprequests.converter.EntityReader;

Expand All @@ -24,7 +25,7 @@
/**
* An entity reader that converts an entity into a String. The character set of the entity is respected.
*/
public class StringEntityReader implements EntityReader {
public class StringEntityReader implements EntityReader, Ordered {
/**
* Determines if the reader supports converting an entity to the given class type.
*
Expand Down Expand Up @@ -55,4 +56,12 @@ public Object read(InputStream entity, String contentType, String charset) throw

return StreamUtils.readString(entity, charset);
}

/**
* {@inheritDoc}
*/
@Override
public int getOrder() {
return Ordered.LOWEST_PRIORITY + 10;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.budjb.httprequests.converter.bundled;

import com.budjb.httprequests.Ordered;
import com.budjb.httprequests.converter.EntityWriter;

import java.io.ByteArrayInputStream;
Expand All @@ -24,7 +25,7 @@
/**
* An entity writer that converts a String.
*/
public class StringEntityWriter implements EntityWriter {
public class StringEntityWriter implements EntityWriter, Ordered {
/**
* Returns a Content-Type of the converted object that will be set in the HTTP request.
* <p>
Expand Down Expand Up @@ -66,4 +67,12 @@ public InputStream write(Object entity, String characterSet) throws Exception {

return new ByteArrayInputStream(((String) entity).getBytes(characterSet));
}

/**
* {@inheritDoc}
*/
@Override
public int getOrder() {
return Ordered.LOWEST_PRIORITY + 10;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class HttpResponseExceptionSpec extends Specification {
def 'When an HttpResponseException is build with status #status, exception type #type is returned'() {
setup:
HttpResponse response = new MockHttpResponse(
new EntityConverterManager(),
new EntityConverterManager([]),
new HttpRequest(),
status,
new MultiValuedMap(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import spock.lang.Specification
class HttpResponseSpec extends Specification {
def 'When a charset is provided, the resulting string is built using it'() {
setup:
EntityConverterManager converterManager = new EntityConverterManager()
converterManager.add(new StringEntityReader())
EntityConverterManager converterManager = new EntityConverterManager([new StringEntityReader()])

HttpEntity httpEntity = new HttpEntity(new ByteArrayInputStream('åäö'.getBytes()), 'text/plain', 'euc-jp')
HttpResponse response = new MockHttpResponse(
Expand All @@ -50,7 +49,7 @@ class HttpResponseSpec extends Specification {
headers.add("peek", "boo")

HttpResponse response = new MockHttpResponse(
new EntityConverterManager(),
new EntityConverterManager([]),
new HttpRequest(),
200,
headers,
Expand All @@ -74,7 +73,7 @@ class HttpResponseSpec extends Specification {
def 'When the response contains no entity, hasEntity() returns false'() {
setup:
HttpResponse response = new MockHttpResponse(
new EntityConverterManager(),
new EntityConverterManager([]),
new HttpRequest(),
200,
new MultiValuedMap(),
Expand All @@ -90,7 +89,7 @@ class HttpResponseSpec extends Specification {
HttpRequest request = new HttpRequest().setBufferResponseEntity(false)
HttpEntity entity = new HttpEntity(new ByteArrayInputStream([1, 2, 3] as byte[]))
HttpResponse response = new MockHttpResponse(
new EntityConverterManager(),
new EntityConverterManager([]),
request,
200,
new MultiValuedMap(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ class EntityConverterManagerSpec extends Specification {
def 'When an EntityConverter is added, the manager contains it'() {
setup:
EntityConverter converter = Mock(EntityConverter)
EntityConverterManager manager = new EntityConverterManager()
EntityConverterManager manager = new EntityConverterManager([converter])

when:
manager.add(converter)

then:
expect:
manager.getAll().size() == 1
manager.getAll().get(0).is converter
}
Expand All @@ -39,54 +36,18 @@ class EntityConverterManagerSpec extends Specification {
EntityConverter c1 = Mock(EntityConverter)
EntityConverter c2 = Mock(EntityConverter)

EntityConverterManager manager = new EntityConverterManager()
manager.add(c1)
manager.add(c2)
EntityConverterManager manager = new EntityConverterManager([c1, c2])

expect:
manager.getAll() == [c1, c2]
}

def 'After removing a converter, it is no longer contained in the manager'() {
setup:
EntityConverter converter = Mock(EntityConverter)
EntityConverterManager manager = new EntityConverterManager()
manager.add(converter)

expect:
manager.getAll().contains(converter)

when:
manager.remove(converter)

then:
!manager.getAll().contains(converter)
}

def 'After clearing the manager, no converters are contained in the manager'() {
setup:
EntityConverter ec1 = Mock(EntityConverter)
EntityConverter ec2 = Mock(EntityConverter)

EntityConverterManager manager = new EntityConverterManager()
manager.add(ec1)
manager.add(ec2)

when:
manager.clear()

then:
manager.getAll().size() == 0
}

def 'When getting entity readers, only entity converters that are readers are returned'() {
setup:
EntityWriter ec1 = Mock(EntityWriter)
EntityReader ec2 = Mock(EntityReader)

EntityConverterManager manager = new EntityConverterManager()
manager.add(ec1)
manager.add(ec2)
EntityConverterManager manager = new EntityConverterManager([ec1, ec2])

when:
List<EntityReader> readers = manager.getEntityReaders()
Expand All @@ -101,9 +62,7 @@ class EntityConverterManagerSpec extends Specification {
EntityWriter ec1 = Mock(EntityWriter)
EntityReader ec2 = Mock(EntityReader)

EntityConverterManager manager = new EntityConverterManager()
manager.add(ec1)
manager.add(ec2)
EntityConverterManager manager = new EntityConverterManager([ec1, ec2])

when:
List<EntityWriter> writers = manager.getEntityWriters()
Expand All @@ -119,10 +78,7 @@ class EntityConverterManagerSpec extends Specification {
EntityReader bad = Mock(EntityReader)
EntityWriter writer = Mock(EntityWriter)

EntityConverterManager converterManager = new EntityConverterManager()
converterManager.add(bad)
converterManager.add(good)
converterManager.add(writer)
EntityConverterManager converterManager = new EntityConverterManager([bad, good, writer])

good.supports(String) >> true

Expand All @@ -144,10 +100,7 @@ class EntityConverterManagerSpec extends Specification {
EntityWriter bad = Mock(EntityWriter)
EntityReader reader = Mock(EntityReader)

EntityConverterManager converterManager = new EntityConverterManager()
converterManager.add(bad)
converterManager.add(good)
converterManager.add(reader)
EntityConverterManager converterManager = new EntityConverterManager([bad, good, reader])

good.supports(String) >> true

Expand All @@ -165,7 +118,7 @@ class EntityConverterManagerSpec extends Specification {

def 'When no reader is available to perform conversion, an UnsupportedConversionException is thrown'() {
setup:
EntityConverterManager converterManager = new EntityConverterManager()
EntityConverterManager converterManager = new EntityConverterManager([])

HttpEntity entity = new HttpEntity(new ByteArrayInputStream([1, 2, 3] as byte[]), null, null)

Expand All @@ -178,7 +131,7 @@ class EntityConverterManagerSpec extends Specification {

def 'When no writer is available to perform conversion, an UnsupportedConversionException is thrown'() {
setup:
EntityConverterManager converterManager = new EntityConverterManager()
EntityConverterManager converterManager = new EntityConverterManager([])

when:
converterManager.write('Hello!', null, null)
Expand All @@ -192,8 +145,7 @@ class EntityConverterManagerSpec extends Specification {
EntityWriter converter = Mock(EntityWriter)
converter.supports(_) >> true

EntityConverterManager manager = new EntityConverterManager()
manager.add(converter)
EntityConverterManager manager = new EntityConverterManager([converter])

when:
manager.write('foo')
Expand All @@ -213,9 +165,7 @@ class EntityConverterManagerSpec extends Specification {
c2.supports(_) >> true
c2.write(*_) >> inputStream

EntityConverterManager manager = new EntityConverterManager()
manager.add(c1)
manager.add(c2)
EntityConverterManager manager = new EntityConverterManager([c1, c2])

when:
HttpEntity entity = manager.write('foo')
Expand All @@ -236,9 +186,7 @@ class EntityConverterManagerSpec extends Specification {
c2.supports(_) >> true
c2.write(*_) >> inputStream

EntityConverterManager manager = new EntityConverterManager()
manager.add(c1)
manager.add(c2)
EntityConverterManager manager = new EntityConverterManager([c1, c2])

when:
HttpEntity entity = manager.write('foo')
Expand All @@ -257,9 +205,7 @@ class EntityConverterManagerSpec extends Specification {
c2.supports(_) >> true
c2.read(*_) >> 'foo'

EntityConverterManager manager = new EntityConverterManager()
manager.add(c1)
manager.add(c2)
EntityConverterManager manager = new EntityConverterManager([c1, c2])

HttpEntity entity = Mock(HttpEntity)
entity.getInputStream() >> Mock(InputStream)
Expand All @@ -277,8 +223,7 @@ class EntityConverterManagerSpec extends Specification {
c1.supports(_) >> true
c1.read(*_) >> { throw new IOException() }

EntityConverterManager manager = new EntityConverterManager()
manager.add(c1)
EntityConverterManager manager = new EntityConverterManager([c1])

HttpEntity entity = Mock(HttpEntity)
entity.getInputStream() >> Mock(InputStream)
Expand Down
Loading

0 comments on commit 6659e0f

Please sign in to comment.