BasicSourceSource.java
/*-
* #%L
* io.earcam.instrumental.compile
* %%
* Copyright (C) 2018 earcam
* %%
* SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT)
*
* You <b>must</b> choose to accept, in full - any individual or combination of
* the following licenses:
* <ul>
* <li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li>
* <li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li>
* <li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li>
* <li><a href="https://opensource.org/licenses/MIT">MIT</a></li>
* </ul>
* #L%
*/
package io.earcam.instrumental.compile;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import io.earcam.instrumental.fluent.Fluent;
import io.earcam.instrumental.reflect.Resources;
import io.earcam.utilitarian.io.IoStreams;
final class BasicSourceSource {
private BasicSourceSource()
{}
@Fluent
public static SourceSource foundFor(Class<?> type)
{
Path resource = Paths.get(Resources.sourceOfResource(type));
String paquet = type.getPackage().getName().replace('.', File.separatorChar);
Path tail = Paths.get(paquet).resolve(type.getSimpleName() + ".java");
if(resource.toFile().isDirectory()) {
Path middle;
if(resource.endsWith(Paths.get("target", "test-classes"))) {
middle = Paths.get("src", "test", "java");
} else if(resource.endsWith(Paths.get("target", "classes"))) {
middle = Paths.get("src", "main", "java");
} else {
throw new IllegalStateException("Cannot determine source for file " + type.getCanonicalName());
}
Path source = resource.getParent().getParent().resolve(middle).resolve(tail);
requireExistingFile(source);
return s -> s.sink(source);
}
Path sourceJar = resource.getParent().resolve(resource.getFileName().toString().replaceAll("(.*)\\.jar", "$1-sources.jar"));
try(ZipInputStream zip = new ZipInputStream(new FileInputStream(sourceJar.toFile()))) {
ZipEntry entry;
while((entry = zip.getNextEntry()) != null) {
if(tail.toString().equals(entry.getName())) {
String source = new String(IoStreams.readAllBytes(zip), UTF_8);
return s -> s.sink(source);
}
}
} catch(IOException e) {
throw new UncheckedIOException(e);
}
throw new IllegalStateException("Did not find source for " + type + " in " + sourceJar);
}
static void requireExistingFile(Path file)
{
if(!file.toFile().isFile()) {
FileNotFoundException fnfe = new FileNotFoundException(file.toAbsolutePath().toString());
throw new UncheckedIOException(fnfe);
}
}
}