java rewrite

This commit is contained in:
2022-06-03 23:59:59 +08:00
parent 76608d5713
commit b59dcfd93c
68 changed files with 2218 additions and 1769 deletions

View 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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}