java rewrite
This commit is contained in:
9
jpacrepo-impl/src/main/java/module-info.java
Normal file
9
jpacrepo-impl/src/main/java/module-info.java
Normal file
@@ -0,0 +1,9 @@
|
||||
module net.woggioni.jpacrepo.impl {
|
||||
requires static lombok;
|
||||
requires net.woggioni.jpacrepo.api;
|
||||
requires net.woggioni.jwo;
|
||||
requires net.woggioni.jzstd;
|
||||
requires org.apache.commons.compress;
|
||||
|
||||
exports net.woggioni.jpacrepo.impl.model;
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
package net.woggioni.jpacrepo.impl.model;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jwo.JWO;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class CompressionFormatImpl {
|
||||
private static final Map<String, CompressionFormat> valueMap;
|
||||
|
||||
static {
|
||||
Map<String, CompressionFormat> result = new TreeMap<>();
|
||||
for(CompressionFormat format : CompressionFormat.values()) {
|
||||
result.put(format.getValue(), format);
|
||||
}
|
||||
valueMap = Collections.unmodifiableMap(result);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static CompressionFormat guess(Path file) {
|
||||
String extension = JWO.splitExtension(file.getFileName())
|
||||
.orElseThrow(() -> JWO.newThrowable(ParseException.class,
|
||||
"Unable to parse file extension for '%s'", file.getFileName()))
|
||||
.get_2().substring(1);
|
||||
|
||||
CompressionFormat result = valueMap.get(extension);
|
||||
if(result == null) {
|
||||
throw JWO.newThrowable(IllegalArgumentException.class,
|
||||
"Unknown compression format for file extension '%s'", extension);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
package net.woggioni.jpacrepo.impl.model;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
import net.woggioni.jwo.CollectionUtils;
|
||||
import net.woggioni.jwo.Fun;
|
||||
import net.woggioni.jwo.Hash;
|
||||
import net.woggioni.jwo.JWO;
|
||||
import net.woggioni.jwo.Tuple2;
|
||||
import net.woggioni.jwo.UncloseableInputStream;
|
||||
import net.woggioni.jzstd.ZstdInputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class PkgDataImpl {
|
||||
|
||||
@SneakyThrows
|
||||
public static PkgData parseFile(Path file, net.woggioni.jpacrepo.api.model.CompressionFormat compressionFormat) {
|
||||
Fun<InputStream, InputStream> decompressorStreamConstructor;
|
||||
switch (compressionFormat) {
|
||||
case XZ:
|
||||
decompressorStreamConstructor = XZCompressorInputStream::new;
|
||||
break;
|
||||
case Z_STANDARD:
|
||||
decompressorStreamConstructor = ZstdInputStream::from;
|
||||
break;
|
||||
case GZIP:
|
||||
decompressorStreamConstructor = GZIPInputStream::new;
|
||||
break;
|
||||
default:
|
||||
throw JWO.newThrowable(ParseException.class,
|
||||
"Unsupported compression format '%s'", compressionFormat);
|
||||
}
|
||||
try(TarArchiveInputStream is = new TarArchiveInputStream(
|
||||
decompressorStreamConstructor.apply(
|
||||
new BufferedInputStream(
|
||||
Files.newInputStream(file))))) {
|
||||
var archiveEntry = is.getNextEntry();
|
||||
while (archiveEntry != null) {
|
||||
if (Objects.equals(".PKGINFO", archiveEntry.getName())) {
|
||||
try(BufferedReader reader =
|
||||
new BufferedReader(
|
||||
new InputStreamReader(
|
||||
new UncloseableInputStream(is)))) {
|
||||
Map<String, List<String>> metadata = reader.lines().map(String::trim)
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.filter(line -> !line.startsWith("#"))
|
||||
.map((Fun<String, Tuple2<String, String>>) line -> {
|
||||
int equals = line.indexOf("=");
|
||||
if (equals < 0) {
|
||||
throw JWO.newThrowable(ParseException.class,
|
||||
"Error parsing .PKGINFO file in '%s'", file);
|
||||
} else {
|
||||
return Tuple2.newInstance(
|
||||
line.substring(0, equals).trim(),
|
||||
line.substring(equals + 1).trim());
|
||||
}
|
||||
}).collect(
|
||||
Collectors.groupingBy(
|
||||
Tuple2<String, String>::get_1,
|
||||
TreeMap::new,
|
||||
Collectors.mapping(Tuple2<String, String>::get_2,
|
||||
Collectors.toUnmodifiableList())));
|
||||
PkgData data = new PkgData();
|
||||
data.setId(new PkgId());
|
||||
data.getId().setCompressionFormat(compressionFormat);
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : metadata.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
switch (key) {
|
||||
case "size":
|
||||
data.setSize(Long.parseLong(value.get(0)));
|
||||
break;
|
||||
case "arch":
|
||||
data.getId().setArch(value.get(0));
|
||||
break;
|
||||
case "replaces":
|
||||
data.setReplaces(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "packager":
|
||||
data.setPackager(value.get(0));
|
||||
break;
|
||||
case "url":
|
||||
data.setUrl(value.get(0));
|
||||
break;
|
||||
case "pkgname":
|
||||
data.getId().setName(value.get(0));
|
||||
break;
|
||||
case "builddate":
|
||||
data.setBuildDate(OffsetDateTime.ofInstant(
|
||||
Instant.ofEpochSecond(Long.parseLong(value.get(0))), ZoneOffset.UTC));
|
||||
break;
|
||||
case "license":
|
||||
data.setLicense(value.get(0));
|
||||
break;
|
||||
case "pkgver":
|
||||
data.getId().setVersion(value.get(0));
|
||||
break;
|
||||
case "pkgdesc":
|
||||
data.setDescription(value.get(0));
|
||||
break;
|
||||
case "provides":
|
||||
data.setProvides(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "conflict":
|
||||
data.setConflict(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "backup":
|
||||
data.setBackup(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "optdepend":
|
||||
data.setOptdepend(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "depend":
|
||||
data.setDepend(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "makedepend":
|
||||
data.setMakedepend(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "makepkgopt":
|
||||
data.setMakeopkgopt(value.stream().collect(CollectionUtils.toUnmodifiableTreeSet()));
|
||||
break;
|
||||
case "pkgbase":
|
||||
data.setBase(value.get(0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
try(InputStream fis = Files.newInputStream(file)) {
|
||||
data.setMd5sum(Hash.hash(Hash.Algorithm.MD5, fis).toString());
|
||||
}
|
||||
data.setFileName(file.getFileName().toString());
|
||||
return data;
|
||||
}
|
||||
} else {
|
||||
archiveEntry = is.getNextEntry();
|
||||
}
|
||||
}
|
||||
throw JWO.newThrowable(ParseException.class, ".PKGINFO file not found in '%s'", file);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user