001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.util;
017
018import static org.hamcrest.core.Is.is;
019import static org.hamcrest.core.IsNull.notNullValue;
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertThat;
022import java.io.ByteArrayInputStream;
023import java.io.ByteArrayOutputStream;
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.UnsupportedEncodingException;
027import java.net.URL;
028import javax.xml.bind.DatatypeConverter;
029import org.junit.Test;
030import org.modeshape.common.FixFor;
031
032/**
033 * @author Randall Hauch
034 */
035public class Base64Test {
036
037    // =========================================================================
038    // H E L P E R M E T H O D S
039    // =========================================================================
040
041    // =========================================================================
042    // T E S T C A S E S
043    // =========================================================================
044
045    @Test
046    public void testBasicExamples() throws IOException {
047        // Make up some source objects
048        byte[] originalBytes = {(byte)-2, (byte)-1, (byte)0, (byte)1, (byte)2};
049
050        // Display original array
051        System.out.println("\n\nOriginal array: ");
052        for (int i = 0; i < originalBytes.length; i++)
053            System.out.print(originalBytes[i] + " ");
054        System.out.println();
055
056        // Encode serialized bytes
057        String encBytes = Base64.encodeBytes(originalBytes);
058
059        // Print encoded bytes
060        System.out.println("Bytes, encoded ( " + encBytes.getBytes().length + " bytes):\n" + encBytes);
061
062        // Decode bytes
063        byte[] decBytes = Base64.decode(encBytes);
064
065        // Display decoded bytes
066        System.out.println("Encoded Bytes -> decoded: ");
067        for (int i = 0; i < decBytes.length; i++)
068            System.out.print(decBytes[i] + " ");
069        System.out.println();
070    }
071
072    @Test
073    public void shouldEncodeStringValue() throws UnsupportedEncodingException, IOException {
074        String actualValue = "propertyValue";
075        String encoded = Base64.encodeBytes(actualValue.getBytes("UTF-8"));
076        byte[] decoded = Base64.decode(encoded);
077        String decodedValue = new String(decoded, "UTF-8");
078        assertThat(decodedValue, is(actualValue));
079    }
080
081    @Test
082    public void shouldEncodeStreamableValue() throws IOException {
083        String actualValue = "propertyValue";
084        byte[] actualBytes = actualValue.getBytes();
085        InputStream actualStream = new ByteArrayInputStream(actualBytes);
086        String encoded = Base64.encode(actualStream);
087        String encoded2 = Base64.encodeBytes(actualBytes);
088        assertThat(encoded, is(encoded2));
089        byte[] decoded = Base64.decode(encoded);
090        String decodedValue = new String(decoded);
091        assertThat(decodedValue, is(actualValue));
092    }
093
094    @Test( expected = NullPointerException.class )
095    public void testEncodeNullByteArray() {
096        Base64.encodeBytes(null);
097    }
098
099    @Test
100    public void testEncodeEmptyByteArray() {
101        String result = Base64.encodeBytes(new byte[] {});
102        assertThat(result, is(notNullValue()));
103        assertThat(result.length(), is(0));
104    }
105    
106    @Test
107    @FixFor("MODE-2413")
108    public void shouldSupportReadingFromSelfClosingInputStream() throws Exception {
109        byte[] buffer = new byte[1024];
110        ByteArrayOutputStream bos = new ByteArrayOutputStream();
111        URL resource = getClass().getResource("simple.json");
112        try (Base64.InputStream is = new Base64.InputStream(new SelfClosingInputStream(resource.openStream()), Base64.ENCODE)) {
113            int read;
114            while ((read = is.read(buffer, 0, buffer.length)) != -1) {
115                bos.write(buffer, 0, read);
116            }                        
117        }
118        // until Java 8, use this....
119        String expectedString = DatatypeConverter.printBase64Binary(IoUtil.readBytes(resource.openStream()));
120        assertEquals("Incorrect Base64 encoding", expectedString, new String(bos.toByteArray()));
121    }
122}