/*
* Copyright 2012-2017 the original author or authors.
*
* 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.springframework.boot.loader.jar;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.boot.loader.TestJarCreator;
import org.springframework.boot.loader.data.RandomAccessData;
import org.springframework.boot.loader.data.RandomAccessDataFile;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CentralDirectoryParser}.
*
* @author Phillip Webb
*/
public class CentralDirectoryParserTests {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private File jarFile;
private RandomAccessData jarData;
@Before
public void setup() throws Exception {
this.jarFile = this.temporaryFolder.newFile();
TestJarCreator.createTestJar(this.jarFile);
this.jarData = new RandomAccessDataFile(this.jarFile);
}
@Test
public void visitsInOrder() throws Exception {
MockCentralDirectoryVisitor visitor = new MockCentralDirectoryVisitor();
CentralDirectoryParser parser = new CentralDirectoryParser();
parser.addVisitor(visitor);
parser.parse(this.jarData, false);
List<String> invocations = visitor.getInvocations();
assertThat(invocations).startsWith("visitStart").endsWith("visitEnd")
.contains("visitFileHeader");
}
@Test
public void visitRecords() throws Exception {
Collector collector = new Collector();
CentralDirectoryParser parser = new CentralDirectoryParser();
parser.addVisitor(collector);
parser.parse(this.jarData, false);
Iterator<CentralDirectoryFileHeader> headers = collector.getHeaders().iterator();
assertThat(headers.next().getName().toString()).isEqualTo("META-INF/");
assertThat(headers.next().getName().toString()).isEqualTo("META-INF/MANIFEST.MF");
assertThat(headers.next().getName().toString()).isEqualTo("1.dat");
assertThat(headers.next().getName().toString()).isEqualTo("2.dat");
assertThat(headers.next().getName().toString()).isEqualTo("d/");
assertThat(headers.next().getName().toString()).isEqualTo("d/9.dat");
assertThat(headers.next().getName().toString()).isEqualTo("special/");
assertThat(headers.next().getName().toString()).isEqualTo("special/\u00EB.dat");
assertThat(headers.next().getName().toString()).isEqualTo("nested.jar");
assertThat(headers.next().getName().toString()).isEqualTo("another-nested.jar");
assertThat(headers.hasNext()).isFalse();
}
private static class Collector implements CentralDirectoryVisitor {
private List<CentralDirectoryFileHeader> headers = new ArrayList<>();
@Override
public void visitStart(CentralDirectoryEndRecord endRecord,
RandomAccessData centralDirectoryData) {
}
@Override
public void visitFileHeader(CentralDirectoryFileHeader fileHeader,
int dataOffset) {
this.headers.add(fileHeader.clone());
}
@Override
public void visitEnd() {
}
public List<CentralDirectoryFileHeader> getHeaders() {
return this.headers;
}
}
private static class MockCentralDirectoryVisitor implements CentralDirectoryVisitor {
private final List<String> invocations = new ArrayList<>();
@Override
public void visitStart(CentralDirectoryEndRecord endRecord,
RandomAccessData centralDirectoryData) {
this.invocations.add("visitStart");
}
@Override
public void visitFileHeader(CentralDirectoryFileHeader fileHeader,
int dataOffset) {
this.invocations.add("visitFileHeader");
}
@Override
public void visitEnd() {
this.invocations.add("visitEnd");
}
public List<String> getInvocations() {
return this.invocations;
}
}
}