Package org.openbel.framework.ws.utils

Source Code of org.openbel.framework.ws.utils.TestConverter

/**
* Copyright (C) 2012-2013 Selventa, Inc.
*
* This file is part of the OpenBEL Framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The OpenBEL Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the OpenBEL Framework. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms under LGPL v3:
*
* This license does not authorize you and you are prohibited from using the
* name, trademarks, service marks, logos or similar indicia of Selventa, Inc.,
* or, in the discretion of other licensors or authors of the program, the
* name, trademarks, service marks, logos or similar indicia of such authors or
* licensors, in any marketing or advertising materials relating to your
* distribution of the program or any covered product. This restriction does
* not waive or limit your obligation to keep intact all copyright notices set
* forth in the program as delivered to you.
*
* If you distribute the program in whole or in part, or any modified version
* of the program, and you assume contractual liability to the recipient with
* respect to the program or modified version, then you will indemnify the
* authors and licensors of the program for any liabilities that these
* contractual assumptions directly impose on those licensors and authors.
*/
package org.openbel.framework.ws.utils;

import static java.lang.String.format;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Arrays;
import java.util.Random;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openbel.framework.api.KamStoreObject;
import org.openbel.framework.ws.utils.Converter.KamStoreObjectRef;

public class TestConverter {

    private static final long SEED = 71073753702L;
    private static final Random random = new Random(SEED);

    // Reflected from Converter
    private static Charset ASCII;
    private static Method typeEncode;

    // Reflected from Converter.KamStoreObjectType
    private static Class<?> kamStoreObjectTypeClass;
    private static String kamStoreObjectTypeClassName;
    private static Field repField;
    private static Method sortAndCreateIndex, getRepresentation,
            getRepresentedClass;
    private byte[] representations;
    private int[] repIndex;

    // Reflected from Converter.KamStoreObjectRef
    private static Method encode, decode;

    @BeforeClass
    public static void setUpBeforeClass() throws Throwable {

        final Field asciiField = Converter.class.getDeclaredField("ASCII");
        asciiField.setAccessible(true);
        ASCII = (Charset) asciiField.get(null);

        kamStoreObjectTypeClass = null;
        Class<?>[] converterInnerClasses = Converter.class.getDeclaredClasses();
        for (int i = 0; i < converterInnerClasses.length; ++i) {
            final Class<?> converterInnerClass = converterInnerClasses[i];
            if (converterInnerClass.getSimpleName()
                    .equals("KamStoreObjectType")) {
                kamStoreObjectTypeClass = converterInnerClass;
                break;
            }
        }
        assertThat(kamStoreObjectTypeClass, is(not(nullValue())));
        kamStoreObjectTypeClassName = kamStoreObjectTypeClass.getSimpleName();

        repField = kamStoreObjectTypeClass.getDeclaredField("rep");
        repField.setAccessible(true);

        getRepresentation =
                kamStoreObjectTypeClass.getDeclaredMethod("getRepresentation");
        getRepresentedClass =
                kamStoreObjectTypeClass
                        .getDeclaredMethod("getRepresentedClass");

        sortAndCreateIndex = kamStoreObjectTypeClass.getDeclaredMethod(
                "sortAndCreateIndex", byte[].class);
        sortAndCreateIndex.setAccessible(true);

        typeEncode =
                Converter.class.getDeclaredMethod("encode",
                        CharsetEncoder.class, char.class);
        typeEncode.setAccessible(true);

        encode =
                KamStoreObjectRef.class.getDeclaredMethod("encode", int.class,
                        int.class, byte.class);
        encode.setAccessible(true);

        decode =
                KamStoreObjectRef.class.getDeclaredMethod("decode",
                        String.class, kamStoreObjectTypeClass);
        decode.setAccessible(true);
    }

    @Before
    public void setup() throws Throwable {
        try {
            final Field representationsField =
                    kamStoreObjectTypeClass.getDeclaredField("representations");
            representationsField.setAccessible(true);
            representations = (byte[]) representationsField.get(null);

            final Field repIndexField =
                    kamStoreObjectTypeClass.getDeclaredField("repIndex");
            repIndexField.setAccessible(true);
            repIndex = (int[]) repIndexField.get(null);
        } catch (ExceptionInInitializerError e) {
            throw e.getCause();
        }
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testThatDecodeEncodeIsIdentity() throws Throwable {

        try {
            for (Object type : kamStoreObjectTypeClass.getEnumConstants()) {
                int kamInfoId = random.nextInt();
                int id = 0;
                // A valid ID is not less than 1
                while ((id = random.nextInt()) < 1) {}
                final byte prefix =
                        ((Byte) getRepresentation.invoke(type)).byteValue();
                final Class<? extends KamStoreObject> typeClass =
                        (Class<? extends KamStoreObject>) getRepresentedClass
                                .invoke(type);

                final String encoded =
                        (String) encode.invoke(null, kamInfoId, id, prefix);

                final KamStoreObjectRef objRef =
                        (KamStoreObjectRef) decode.invoke(
                                null, encoded, type);

                assertTrue(kamInfoId == objRef.getKamInfoId());
                assertTrue(id == objRef.getKamStoreObjectId());
                assertTrue(typeClass.equals(objRef.getKamStoreObjectClass()));
            }
        } catch (InvocationTargetException e) {
            throw e.getCause();
        }
    }

    @Test
    public void testThatKamStoreObjectTypeRepsCanBeEncoded()
            throws IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {

        final CharsetEncoder asciiEncoder = ASCII.newEncoder();

        final int n = kamStoreObjectTypeClass.getEnumConstants().length;
        for (int i = 0; i < n; ++i) {
            Enum<?> type =
                    (Enum<?>) kamStoreObjectTypeClass.getEnumConstants()[i];
            Byte rep =
                    (Byte) typeEncode.invoke(null, asciiEncoder,
                            repField.getChar(type));
            if (rep == null) {
                fail(format(
                        "%s.%s must have a one-byte ASCII character representation!",
                        kamStoreObjectTypeClassName,
                        type.name()));
            }
        }
    }

    @Test
    public void testThatKamStoreObjectTypeRepsAreUnique()
            throws IllegalArgumentException,
            IllegalAccessException {
        final int n = kamStoreObjectTypeClass.getEnumConstants().length;
        for (int i = 1; i < n; ++i) {
            if (representations[i - 1] == representations[i]) {
                final Enum<?> prevType = (Enum<?>) kamStoreObjectTypeClass
                        .getEnumConstants()[repIndex[i - 1]];
                final Enum<?> type = (Enum<?>) kamStoreObjectTypeClass
                        .getEnumConstants()[repIndex[i]];

                fail(format(
                        "%s.%s and %s.%s have the same single character representation '%c'!",
                        kamStoreObjectTypeClassName,
                        prevType.name(),
                        kamStoreObjectTypeClassName,
                        type.name(),
                        repField.getChar(type)));
            }
        }
    }

    @Test
    public void testSortAndCreateIndex() throws IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {

        final int n = kamStoreObjectTypeClass.getEnumConstants().length;

        byte[] bytes = new byte[n];
        random.nextBytes(bytes);
        byte[] copy1 = Arrays.copyOf(bytes, n);
        byte[] copy2 = Arrays.copyOf(bytes, n);

        // Sort with sortAndCreateIndex and Arrays.sort.
        int[] index = (int[]) sortAndCreateIndex.invoke(null, copy1);
        Arrays.sort(copy2);
        assertTrue(Arrays.equals(copy1, copy2));

        // Check the index
        for (int i = 0; i < n; ++i) {
            assertTrue(bytes[index[i]] == copy1[i]);
        }
    }
}
TOP

Related Classes of org.openbel.framework.ws.utils.TestConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.