diff --git a/src/main/java/com/bc/zarr/CompressorFactory.java b/src/main/java/com/bc/zarr/CompressorFactory.java index d32a29a..e9be86f 100644 --- a/src/main/java/com/bc/zarr/CompressorFactory.java +++ b/src/main/java/com/bc/zarr/CompressorFactory.java @@ -49,8 +49,25 @@ public class CompressorFactory { + private static final Map> registeredCompressors = defaultCompressors(); + + private static Map> defaultCompressors() { + Map> compressors = new HashMap>(); + compressors.put("null", NullCompressor.class); + compressors.put("zlib", ZlibCompressor.class); + compressors.put("blosc", BloscCompressor.class); + return compressors; + } + public final static Compressor nullCompressor = new NullCompressor(); + + public static void registerCompressor(String id, Class compressor) { + if (id != null && !registeredCompressors.containsKey(id)) { + registeredCompressors.put(id, compressor); + } + } + /** * @return the properties of the default compressor as a key/value map. */ @@ -111,14 +128,20 @@ public static Compressor create(String id, Object... keyValuePair) { * @throws IllegalArgumentException If it is not able to create a Compressor. */ public static Compressor create(String id, Map properties) { - if ("null".equals(id)) { - return nullCompressor; - } - if ("zlib".equals(id)) { - return new ZlibCompressor(properties); + try { + if (registeredCompressors.containsKey(id)) { + Class c = registeredCompressors.get(id); + if (c.equals(NullCompressor.class)) { + return nullCompressor; + } + return c.getDeclaredConstructor(Map.class).newInstance(properties); + } } - if ("blosc".equals(id)) { - return new BloscCompressor(properties); + catch (ReflectiveOperationException e) { + if (e.getCause() instanceof IllegalArgumentException) { + throw (IllegalArgumentException) e.getCause(); + } + throw new IllegalArgumentException("Could not get compressor for id:'" + id + "'", e); } throw new IllegalArgumentException("Compressor id:'" + id + "' not supported."); } @@ -159,7 +182,7 @@ public void uncompress(InputStream is, OutputStream os) throws IOException { private static class ZlibCompressor extends Compressor { private final int level; - private ZlibCompressor(Map map) { + protected ZlibCompressor(Map map) { final Object levelObj = map.get("level"); if (levelObj == null) { this.level = 1; //default value @@ -242,7 +265,7 @@ public static class BloscCompressor extends Compressor { private final String cname; private final int nthreads; - private BloscCompressor(Map map) { + protected BloscCompressor(Map map) { final Object cnameObj = map.get(keyCname); if (cnameObj == null) { cname = defaultCname; diff --git a/src/test/java/com/bc/zarr/CompressorFactoryTest.java b/src/test/java/com/bc/zarr/CompressorFactoryTest.java index fcca49e..8494f2f 100644 --- a/src/test/java/com/bc/zarr/CompressorFactoryTest.java +++ b/src/test/java/com/bc/zarr/CompressorFactoryTest.java @@ -28,6 +28,9 @@ import org.junit.Test; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.Map; import static org.junit.Assert.assertEquals; @@ -119,4 +122,32 @@ public void create_compressor_not_supported() { assertEquals("Compressor id:'kkkkkkk' not supported.", expected.getMessage()); } } -} \ No newline at end of file + + @Test + public void registerNewCompressor() { + final String id = "test"; + CompressorFactory.registerCompressor(id, TestCompressor.class); + final Compressor compressor = CompressorFactory.create(id, TestUtils.createMap("level", 1)); + assertNotNull(compressor); + assertEquals(id, compressor.getId()); + } + + static class TestCompressor extends Compressor { + public TestCompressor(Map properties) { + } + + public String getId() { + return "test"; + } + + public String toString() { + return getId(); + } + + public void compress(InputStream is, OutputStream os) throws IOException { + } + + public void uncompress(InputStream is, OutputStream os) throws IOException { + } + } +}