/* * Copyright 2011 b1.org * * 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 org.b1.pack.standard.common; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.primitives.Ints; import org.b1.pack.api.builder.*; import org.b1.pack.api.common.*; import org.b1.pack.api.reader.PackReader; import org.b1.pack.api.reader.ReaderProvider; import org.b1.pack.api.reader.ReaderVolume; import org.b1.pack.api.writer.PackWriter; import org.b1.pack.api.writer.WriterProvider; import org.b1.pack.api.writer.WriterVolume; import org.junit.Test; import java.io.*; import java.util.List; import java.util.Map; import static com.google.common.base.Charsets.UTF_8; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.getOnlyElement; import static java.util.Arrays.asList; import static java.util.logging.Logger.getLogger; import static org.b1.pack.api.common.PackFormat.B1; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class IntegrationTest { @Test public void testBuilder() throws IOException { final String folderName = "builderFolder"; final String fileName = "builderFile.txt"; final long fileTime = System.currentTimeMillis(); final byte[] fileContentBytes = "Hello, World!".getBytes(UTF_8.name()); final String packName = "builderTest"; String volumeName = packName + ".b1"; // START SNIPPET: builder final BuilderFolder builderFolder = createBuilderFolder(folderName, fileTime); final BuilderFile builderFile = createBuilderFile(folderName, fileName, fileTime, fileContentBytes); List<BuilderVolume> volumes = PackBuilder.getInstance(B1).build(new BuilderProvider(), new BuilderCommand() { @Override public void execute(BuilderPack pack) { pack.addFolder(builderFolder); pack.addFile(builderFile); } }); BuilderVolume builderVolume = getOnlyElement(volumes); byte[] volumeContent = getBuilderVolumeContent(builderVolume); // END SNIPPET: builder assertEquals(1, builderVolume.getNumber()); verifyVolumeWithReader(folderName, fileName, fileTime, fileContentBytes, volumeName, volumeContent); } @Test public void testWriter() throws IOException { String folderName = "writerFolder"; String fileName = "writerFile.txt"; long fileTime = System.currentTimeMillis(); byte[] fileContentBytes = "Hello, test!".getBytes(UTF_8.name()); String packName = "writerTest"; String volumeName = packName + ".b1"; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); // START SNIPPET: writer WriterVolume writerVolume = createWriterVolume(buffer); final PackEntry folderEntry = createPackEntry(folderName, fileTime); final PackEntry fileEntry = createPackEntry(fileName, fileTime); final long fileSize = fileContentBytes.length; final FileContent fileContent = createFileContent(fileContentBytes); WriterProvider provider = createWriterProvider(new FolderContent() { @Override public void writeTo(FolderBuilder builder) throws IOException { builder.addFolder(folderEntry).addFile(fileEntry, fileSize).setContent(fileContent); } }, writerVolume); PackWriter.getInstance(B1).write(provider); // END SNIPPET: writer byte[] volumeContent = buffer.toByteArray(); verifyVolumeWithReader(folderName, fileName, fileTime, fileContentBytes, volumeName, volumeContent); } private void verifyVolumeWithReader(String folderName, String fileName, long fileTime, byte[] fileContentBytes, String volumeName, byte[] volumeContentBytes) throws IOException { // START SNIPPET: reader ReaderVolume readerVolume = createReaderVolume(volumeName, volumeContentBytes); List<String> folderList = Lists.newArrayList(); Map<String, byte[]> fileMap = Maps.newHashMap(); final FolderBuilder builder = createFolderBuilder("", fileTime, folderList, fileMap); ReaderProvider readerProvider = createReaderProvider(builder, readerVolume); PackReader.getInstance(B1).read(readerProvider); assertEquals(folderName, getOnlyElement(folderList)); Map.Entry<String, byte[]> fileEntry = getOnlyElement(fileMap.entrySet()); assertEquals(folderName + "/" + fileName, fileEntry.getKey()); assertArrayEquals(fileContentBytes, fileEntry.getValue()); // END SNIPPET: reader } private static BuilderFolder createBuilderFolder(final String folderName, final long lastModifiedTime) { return new BuilderFolder() { public List<String> getPath() { return asList(folderName); } public Long getLastModifiedTime() { return lastModifiedTime; } public void beforeAdd() { getLogger(getClass().getName()).fine("Adding " + getPath()); } }; } private static BuilderFile createBuilderFile(final String folderName, final String fileName, final long lastModifiedTime, final byte[] content) { return new BuilderFile() { public List<String> getPath() { return asList(folderName, fileName); } public Long getLastModifiedTime() { return lastModifiedTime; } public void beforeAdd() { getLogger(getClass().getName()).fine("Adding " + getPath()); } public long getSize() { return content.length; } public void writeTo(OutputStream stream, long start, long end) throws IOException { stream.write(content, Ints.checkedCast(start), Ints.checkedCast(end - start)); } }; } private static byte[] getBuilderVolumeContent(BuilderVolume builderVolume) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); builderVolume.writeTo(stream, 0, Ints.checkedCast(builderVolume.getSize())); return stream.toByteArray(); } private static WriterVolume createWriterVolume(final ByteArrayOutputStream buffer) { return new WriterVolume() { @Override public OutputStream getOutputStream() throws IOException { return buffer; } }; } private static WriterProvider createWriterProvider(final FolderContent folderContent, final WriterVolume writerVolume) { return new WriterProvider() { @Override public FolderContent getFolderContent() { return folderContent; } @Override public boolean isSeekable() { return false; } @Override public WriterVolume getVolume(long number) throws IOException { assertEquals(1, number); return writerVolume; } }; } private static PackEntry createPackEntry(final String fileName, final long fileTime) { return new PackEntry() { @Override public String getName() { return fileName; } @Override public Long getLastModifiedTime() { return fileTime; } }; } private static FileContent createFileContent(final byte[] fileContent) { return new FileContent() { @Override public void writeTo(OutputStream stream, long start, Long end) throws IOException { long length = (end != null ? end : fileContent.length) - start; stream.write(fileContent, Ints.checkedCast(start), Ints.checkedCast(length)); } }; } private static ReaderVolume createReaderVolume(final String name, final byte[] packContent) { return new ReaderVolume() { @Override public String getName() { return name; } @Override public Long getSize() { return (long) packContent.length; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(packContent); } }; } private static ReaderProvider createReaderProvider(final FolderBuilder builder, final ReaderVolume readerVolume) { return new ReaderProvider() { @Override public FolderBuilder getFolderBuilder() { return builder; } @Override public ReaderVolume getVolume(long number) { checkArgument(number == 1); return readerVolume; } @Override public long getVolumeCount() { return 1; } }; } private static FolderBuilder createFolderBuilder(final String prefix, final long fileTime, final List<String> folderList, final Map<String, byte[]> fileMap) { return new FolderBuilder() { @Override public FileBuilder addFile(final PackEntry entry, final Long size) { Preconditions.checkState(entry.getLastModifiedTime() == fileTime); return createFileBuilder(prefix, entry, size, fileMap); } @Override public FolderBuilder addFolder(PackEntry entry) { Preconditions.checkState(entry.getLastModifiedTime() == fileTime); folderList.add(prefix + entry.getName()); return createFolderBuilder(prefix + entry.getName() + "/", fileTime, folderList, fileMap); } @Override public void save() throws IOException { //no-op } }; } private static FileBuilder createFileBuilder(final String prefix, final PackEntry entry, final Long size, final Map<String, byte[]> fileMap) { return new FileBuilder() { @Override public void setContent(FileContent content) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); content.writeTo(stream, 0, null); Preconditions.checkState(stream.size() == size); fileMap.put(prefix + entry.getName(), stream.toByteArray()); } @Override public void save() throws IOException { //no-op } }; } }