diff --git a/build.gradle b/build.gradle index 464ed6b..e6cbe6e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,10 @@ plugins { id 'java-library' id 'maven-publish' +} +ext { + versionPrefix = "0.1.0" } repositories { @@ -27,7 +30,7 @@ publishing { var cl = Calendar.instance var day = "${cl.get(cl.YEAR)}.${cl.get(cl.MONTH) + 1}.${cl.get(cl.DATE)}" var time = "${cl.get(cl.HOUR_OF_DAY)}.${cl.get(cl.MINUTE)}.${cl.get(cl.SECOND)}" - version = "0.1.0.$day.$time" + version = "$versionPrefix.$day.$time" from components.java } diff --git a/commons-gson/build.gradle b/commons-gson/build.gradle new file mode 100644 index 0000000..872aebf --- /dev/null +++ b/commons-gson/build.gradle @@ -0,0 +1,61 @@ +plugins { + id 'java-library' + id 'maven-publish' + id 'com.github.johnrengelman.shadow' version '7.1.2' +} + +repositories { + mavenCentral() + maven { + url 'https://gitlab.com/api/v4/projects/35030495/packages/maven' + } +} + +dependencies { + shadow implementation('io.gitlab.jfronny:gson:+') + + implementation project(':') + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' +} + +shadowJar { + configurations = [ project.configurations.shadow ] +} + +test { + useJUnitPlatform() +} + +publishing { + publications { + mavenJava(MavenPublication) { + groupId = 'io.gitlab.jfronny' + artifactId = 'commons-gson' + var cl = Calendar.instance + var day = "${cl.get(cl.YEAR)}.${cl.get(cl.MONTH) + 1}.${cl.get(cl.DATE)}" + var time = "${cl.get(cl.HOUR_OF_DAY)}.${cl.get(cl.MINUTE)}.${cl.get(cl.SECOND)}" + version = "${rootProject.versionPrefix}.$day.$time" + + project.shadow.component(it) + } + } + + def ENV = System.getenv() + if (project.hasProperty("maven")) { + repositories.maven { + url = project.getProperty("maven") + name = "dynamic" + + credentials(HttpHeaderCredentials) { + name = "Job-Token" + value = ENV.CI_JOB_TOKEN + } + authentication { + header(HttpHeaderAuthentication) + } + } + } + repositories.mavenLocal() +} diff --git a/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/ComparableVersionAdapter.java b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/ComparableVersionAdapter.java new file mode 100644 index 0000000..307163b --- /dev/null +++ b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/ComparableVersionAdapter.java @@ -0,0 +1,20 @@ +package io.gitlab.jfronny.commons.serialize.gson; + +import io.gitlab.jfronny.commons.ComparableVersion; +import io.gitlab.jfronny.gson.*; + +import java.lang.reflect.Type; + +public class ComparableVersionAdapter implements JsonDeserializer, JsonSerializer { + @Override + public ComparableVersion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) + return new ComparableVersion(json.getAsString()); + else throw new JsonParseException("Expected Version to be a string"); + } + + @Override + public JsonElement serialize(ComparableVersion src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toString()); + } +} diff --git a/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonHolder.java b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonHolder.java new file mode 100644 index 0000000..ca421d9 --- /dev/null +++ b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonHolder.java @@ -0,0 +1,69 @@ +package io.gitlab.jfronny.commons.serialize.gson; + +import io.gitlab.jfronny.commons.ComparableVersion; +import io.gitlab.jfronny.commons.serialize.Serializer; +import io.gitlab.jfronny.commons.serialize.SerializerHolder; +import io.gitlab.jfronny.gson.Gson; +import io.gitlab.jfronny.gson.GsonBuilder; +import io.gitlab.jfronny.gson.TypeAdapterFactory; + +import java.io.Reader; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.function.Consumer; + +public class GsonHolder { + private static final GsonBuilder builder = new GsonBuilder() + .registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter()) + .excludeFieldsWithModifiers(Modifier.TRANSIENT) + .excludeFieldsWithModifiers(Modifier.PRIVATE) + .addSerializationExclusionStrategy(new GsonIgnoreExclusionStrategy()) + .setPrettyPrinting(); + + private static boolean clean = false; + private static Gson gson; + public static Gson getGson() { + if (!clean) { + gson = builder.create(); + clean = true; + } + return gson; + } + + public static void registerTypeAdapter(Type type, Object typeAdapter) { + builder.registerTypeAdapter(type, typeAdapter); + clean = false; + } + + public static void registerTypeAdapterFactory(TypeAdapterFactory factory) { + builder.registerTypeAdapterFactory(factory); + clean = false; + } + + public static void modifyBuilder(Consumer func) { + func.accept(builder); + clean = false; + } + + /** + * Register this in {@code SerializerHolder} + */ + public static void register() { + SerializerHolder.setInstance(new Serializer() { + @Override + public String serialize(Object o) { + return getGson().toJson(o); + } + + @Override + public T deserialize(Reader reader, Type type) throws SerializeException { + return getGson().fromJson(reader, type); + } + + @Override + public String getFormatMime() { + return "application/json"; + } + }); + } +} diff --git a/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnore.java b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnore.java new file mode 100644 index 0000000..1279ff6 --- /dev/null +++ b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnore.java @@ -0,0 +1,11 @@ +package io.gitlab.jfronny.commons.serialize.gson; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface GsonIgnore { +} diff --git a/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnoreExclusionStrategy.java b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnoreExclusionStrategy.java new file mode 100644 index 0000000..c6b6da9 --- /dev/null +++ b/commons-gson/src/main/java/io/gitlab/jfronny/commons/serialize/gson/GsonIgnoreExclusionStrategy.java @@ -0,0 +1,16 @@ +package io.gitlab.jfronny.commons.serialize.gson; + +import io.gitlab.jfronny.gson.ExclusionStrategy; +import io.gitlab.jfronny.gson.FieldAttributes; + +public class GsonIgnoreExclusionStrategy implements ExclusionStrategy { + @Override + public boolean shouldSkipClass(Class clazz) { + return false; + } + + @Override + public boolean shouldSkipField(FieldAttributes f) { + return f.getAnnotation(GsonIgnore.class) != null; + } +} diff --git a/settings.gradle b/settings.gradle index 51c15da..c722c9f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = 'Commons' +include 'commons-gson' diff --git a/src/main/java/io/gitlab/jfronny/commons/ArgumentsTokenizer.java b/src/main/java/io/gitlab/jfronny/commons/ArgumentsTokenizer.java new file mode 100644 index 0000000..be1b2f3 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/commons/ArgumentsTokenizer.java @@ -0,0 +1,61 @@ +package io.gitlab.jfronny.commons; + +import java.util.ArrayList; +import java.util.List; + +public class ArgumentsTokenizer { + public static String[] tokenize(String toProcess) { + List tokens = new ArrayList<>(); + StringBuilder currentToken = new StringBuilder(); + State state = State.None; + char[] chars = toProcess.toCharArray(); + for (int i = 0; i < chars.length; i++) { + switch (chars[i]) { + case '\'' -> state = switch (state) { + case None -> State.QuoteSingle; + case QuoteSingle -> State.None; + case QuoteDouble -> { + currentToken.append('"'); + yield State.QuoteDouble; + } + }; + case '"' -> state = switch (state) { + case None -> State.QuoteDouble; + case QuoteSingle -> { + currentToken.append('"'); + yield State.QuoteSingle; + } + case QuoteDouble -> State.None; + }; + case '\\' -> { + if (i++ < chars.length) { + currentToken.append(switch (chars[i]) { + case 'b' -> '\b'; + case 'f' -> '\f'; + case 'n' -> '\n'; + case 'r' -> '\r'; + case 't' -> '\t'; + default -> chars[i]; + }); + } else currentToken.append('\\'); + } + case ' ' -> { + if (state == State.None) { + tokens.add(currentToken.toString()); + currentToken = new StringBuilder(); + } + else { + currentToken.append(' '); + } + } + default -> currentToken.append(chars[i]); + } + } + if (!currentToken.isEmpty()) tokens.add(currentToken.toString()); + return tokens.toArray(String[]::new); + } + + private enum State { + None, QuoteSingle, QuoteDouble + } +} diff --git a/src/main/java/io/gitlab/jfronny/commons/OSUtils.java b/src/main/java/io/gitlab/jfronny/commons/OSUtils.java index 1aac009..91d0344 100644 --- a/src/main/java/io/gitlab/jfronny/commons/OSUtils.java +++ b/src/main/java/io/gitlab/jfronny/commons/OSUtils.java @@ -10,6 +10,7 @@ import java.util.stream.Stream; public class OSUtils { public static final Type TYPE; + public static final String USER_DIR; static { String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ROOT); @@ -22,6 +23,7 @@ public class OSUtils { } else { throw new RuntimeException("Unrecognized OS"); } + USER_DIR = System.getProperty("user.home"); } public static boolean executablePathContains(String executableName) {