Defining also the SPI and providing a test. The integration with java.security is still missing
1.1 --- a/samples/messagedigest/src/META-INF/services/impl.friendapi.DigestProvider Sat Jun 14 09:52:21 2008 +0200
1.2 +++ b/samples/messagedigest/src/META-INF/services/impl.friendapi.DigestProvider Sat Jun 14 09:52:21 2008 +0200
1.3 @@ -1,2 +1,7 @@
1.4 +# this is a provider for the SPI, shall be in the same module as the api & spi
1.5 +impl.spi.DigestorProvider
1.6 +
1.7 +
1.8 # this shall be in a separate module that provides the "bridge"
1.9 impl.independent.module.BridgeToOldAlgorithmsProvider
1.10 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/samples/messagedigest/src/impl/spi/DigestorAccessor.java Sat Jun 14 09:52:21 2008 +0200
2.3 @@ -0,0 +1,35 @@
2.4 +/*
2.5 + * To change this template, choose Tools | Templates
2.6 + * and open the template in the editor.
2.7 + */
2.8 +
2.9 +package impl.spi;
2.10 +
2.11 +import java.nio.ByteBuffer;
2.12 +import spi.Digestor;
2.13 +
2.14 +/**
2.15 + *
2.16 + * @author jarda
2.17 + */
2.18 +public abstract class DigestorAccessor {
2.19 + private static DigestorAccessor INSTANCE;
2.20 +
2.21 + protected DigestorAccessor() {
2.22 + assert INSTANCE == null;
2.23 + INSTANCE = this;
2.24 + }
2.25 +
2.26 + public static DigestorAccessor getDefault() {
2.27 + try {
2.28 + Class.forName(Digestor.class.getName(), true, DigestorAccessor.class.getClassLoader());
2.29 + return INSTANCE;
2.30 + } catch (ClassNotFoundException ex) {
2.31 + throw new IllegalStateException(ex);
2.32 + }
2.33 + }
2.34 +
2.35 + protected abstract <Data> byte[] digest(Digestor<Data> dig, Data data);
2.36 + protected abstract <Data> Data create(Digestor<Data> dig, String algorithm);
2.37 + protected abstract <Data> void update(Digestor<Data> dig, Data data, ByteBuffer input);
2.38 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/samples/messagedigest/src/impl/spi/DigestorProvider.java Sat Jun 14 09:52:21 2008 +0200
3.3 @@ -0,0 +1,61 @@
3.4 +/*
3.5 + * To change this template, choose Tools | Templates
3.6 + * and open the template in the editor.
3.7 + */
3.8 +
3.9 +package impl.spi;
3.10 +
3.11 +import impl.friendapi.DigestImplementation;
3.12 +import impl.friendapi.DigestProvider;
3.13 +import java.nio.ByteBuffer;
3.14 +import java.util.ServiceLoader;
3.15 +import spi.Digestor;
3.16 +
3.17 +/**
3.18 + *
3.19 + * @author Jaroslav Tulach
3.20 + */
3.21 +public class DigestorProvider implements DigestProvider {
3.22 +
3.23 + public DigestImplementation create(String algorithm) {
3.24 + for (Digestor<?> d : ServiceLoader.load(Digestor.class)) {
3.25 + Handler<?> h = create(d, algorithm);
3.26 + if (h != null) {
3.27 + return h;
3.28 + }
3.29 + }
3.30 + return null;
3.31 + }
3.32 +
3.33 + private static <Data> Handler<Data> create(Digestor<Data> dig, String algorithm) {
3.34 + Data d = DigestorAccessor.getDefault().create(dig, algorithm);
3.35 + if (d == null) {
3.36 + return null;
3.37 + } else {
3.38 + return new Handler<Data>(algorithm, dig, d);
3.39 + }
3.40 + }
3.41 +
3.42 + private static final class Handler<Data> extends DigestImplementation {
3.43 + private final Digestor dig;
3.44 + private final Data data;
3.45 +
3.46 + public Handler(String algorithm, Digestor dig, Data data) {
3.47 + super(algorithm);
3.48 + this.dig = dig;
3.49 + this.data = data;
3.50 + }
3.51 +
3.52 +
3.53 + @Override
3.54 + public void update(ByteBuffer bb) {
3.55 + DigestorAccessor.getDefault().update(dig, data, bb);
3.56 + }
3.57 +
3.58 + @Override
3.59 + public byte[] digest() {
3.60 + return DigestorAccessor.getDefault().digest(dig, data);
3.61 + }
3.62 +
3.63 + }
3.64 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/samples/messagedigest/src/spi/Digestor.java Sat Jun 14 09:52:21 2008 +0200
4.3 @@ -0,0 +1,39 @@
4.4 +/*
4.5 + * To change this template, choose Tools | Templates
4.6 + * and open the template in the editor.
4.7 + */
4.8 +
4.9 +package spi;
4.10 +
4.11 +import impl.spi.DigestorAccessor;
4.12 +import java.nio.ByteBuffer;
4.13 +
4.14 +/**
4.15 + *
4.16 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.17 + */
4.18 +public abstract class Digestor<Data> {
4.19 + protected abstract byte[] digest(Data data);
4.20 + protected abstract Data create(String algorithm);
4.21 + protected abstract void update(Data data, ByteBuffer input);
4.22 +
4.23 +
4.24 + static {
4.25 + new DigestorAccessor() {
4.26 + @Override
4.27 + protected <Data> byte[] digest(Digestor<Data> dig, Data data) {
4.28 + return dig.digest(data);
4.29 + }
4.30 +
4.31 + @Override
4.32 + protected <Data> Data create(Digestor<Data> dig, String algorithm) {
4.33 + return dig.create(algorithm);
4.34 + }
4.35 +
4.36 + @Override
4.37 + protected <Data> void update(Digestor<Data> dig, Data data, ByteBuffer input) {
4.38 + dig.update(data, input);
4.39 + }
4.40 + };
4.41 + }
4.42 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/samples/messagedigest/test/META-INF/services/spi.Digestor Sat Jun 14 09:52:21 2008 +0200
5.3 @@ -0,0 +1,3 @@
5.4 +# the provider registered from tests
5.5 +api.CountingDigestor
5.6 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/samples/messagedigest/test/api/CountingDigestor.java Sat Jun 14 09:52:21 2008 +0200
6.3 @@ -0,0 +1,35 @@
6.4 +/*
6.5 + * To change this template, choose Tools | Templates
6.6 + * and open the template in the editor.
6.7 + */
6.8 +
6.9 +package api;
6.10 +
6.11 +import java.nio.ByteBuffer;
6.12 +import spi.Digestor;
6.13 +
6.14 +/**
6.15 + *
6.16 + * @author jarda
6.17 + */
6.18 +public final class CountingDigestor extends Digestor<int[]> {
6.19 +
6.20 + @Override
6.21 + protected byte[] digest(int[] data) {
6.22 + int i = data[0];
6.23 + byte[] arr = { (byte) (i & 255), (byte) ((i >> 8) & 255), (byte) ((i >> 16) & 255), (byte) ((i >> 24) & 255) };
6.24 + return arr;
6.25 + }
6.26 +
6.27 + @Override
6.28 + protected int[] create(String algorithm) {
6.29 + return "cnt".equals(algorithm) ? new int[1] : null; // NOI18N
6.30 + }
6.31 +
6.32 + @Override
6.33 + protected void update(int[] data, ByteBuffer input) {
6.34 + data[0] += input.remaining();
6.35 + input.position(input.position() + input.remaining());
6.36 + }
6.37 +
6.38 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/samples/messagedigest/test/api/DigestorTest.java Sat Jun 14 09:52:21 2008 +0200
7.3 @@ -0,0 +1,64 @@
7.4 +/*
7.5 + * To change this template, choose Tools | Templates
7.6 + * and open the template in the editor.
7.7 + */
7.8 +
7.9 +package api;
7.10 +
7.11 +import java.nio.ByteBuffer;
7.12 +import java.security.MessageDigest;
7.13 +import java.util.Arrays;
7.14 +import java.util.Random;
7.15 +import org.junit.After;
7.16 +import org.junit.BeforeClass;
7.17 +import org.junit.Test;
7.18 +import static org.junit.Assert.*;
7.19 +
7.20 +/** Compares that the MessageDigest and Digest yield the same results for
7.21 + * default provider.
7.22 + *
7.23 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.24 + */
7.25 +public class DigestorTest {
7.26 + private static byte[] arr;
7.27 + private static long time;
7.28 + private static byte[] resOld;
7.29 + private static byte[] resNew;
7.30 +
7.31 + public DigestorTest() {
7.32 + }
7.33 +
7.34 + @BeforeClass
7.35 + public static void setUp() {
7.36 + time = System.currentTimeMillis();
7.37 + Random r = new Random(time);
7.38 + arr = new byte[r.nextInt(1024 * 1024)];
7.39 + r.nextBytes(arr);
7.40 + }
7.41 +
7.42 + @After
7.43 + public void tearDown() {
7.44 + }
7.45 +
7.46 + @Test
7.47 + public void generateHashUsingMessageDigest() throws Exception {
7.48 + MessageDigest md = MessageDigest.getInstance("cnt");
7.49 + byte[] res = md.digest(arr);
7.50 + resOld = res;
7.51 + }
7.52 +
7.53 + @Test
7.54 + public void generateHashUsingNewDigest() throws Exception {
7.55 + Digest d = Digest.getInstance("cnt");
7.56 + ByteBuffer bb = ByteBuffer.wrap(arr);
7.57 + byte[] res = d.digest(bb);
7.58 + resNew = res;
7.59 + }
7.60 +
7.61 + @Test
7.62 + public void compareTheHashes() throws Exception {
7.63 + if (!Arrays.equals(resOld, resNew)) {
7.64 + fail("Arrays are different:\n" + Arrays.toString(resOld) + "\n" + Arrays.toString(resNew));
7.65 + }
7.66 + }
7.67 +}
7.68 \ No newline at end of file