commit bac7809f3c7adcaf8e24d0e379e4b87018f44771 Author: TudbuT Date: Fri Jul 1 18:59:27 2022 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e488659 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/lib/ +/build/ +/javadoc/ +/run.sh diff --git a/build.isbpl b/build.isbpl new file mode 100644 index 0000000..a44956f --- /dev/null +++ b/build.isbpl @@ -0,0 +1,10 @@ +"builder.isbpl" include + +func dependencies { + "https://github.com/TudbuT/tuddylib/raw/master/TuddyLIB.jar" download + "https://github.com/TudbuT/tuddylib/raw/master/TuddyLIB-javadoc.zip" download + "https://github.com/TudbuT/isbpl-random-stuff/raw/master/ISBPL.jar" download +} + +"Tryumph" =name +"de.tudbut.tryumph.Launch" =mainClass diff --git a/builder.isbpl b/builder.isbpl new file mode 100644 index 0000000..7b5d6b6 --- /dev/null +++ b/builder.isbpl @@ -0,0 +1,280 @@ +"#stream.isbpl" include +"#time.isbpl" include + +def ProcessBuilder "java.lang.ProcessBuilder" JIO class =ProcessBuilder +def URL "java.net.URL" JIO class =URL +def String "java.lang.String" JIO class =String +def File "java.io.File" JIO class =File +def Files "java.nio.file.Files" JIO class =Files +def System "java.lang.System" JIO class =System + +def deps + +func ensureDepsExist { + ("lib" File°new1)°exists0 not if { + [ dependencies ] =deps + } +} + +func file { + with path ; + ("lib" File°new1)°mkdir0 pop + def file (path File°new1) =file + def name file°getName0 =name + def newfile (("lib/" name)°strconcat File°new1) =newfile + "\n> Using " puts + name puts + "..." puts + newfile°exists0 if { + "\n: Skipped. (Force by deleting lib/" puts name puts ")" puts + name + 2 stop + } + file°exists0 not if { + "\n: Ignored. File " puts + path puts + " does not exist!" puts + name + 2 stop + } + "Java" try { + file°toPath0 newfile°toPath0 0 anew Files°copy3 pop + } { + pop pop pop printStackTrace0 + } + name +} + +func download { + with url ; + ("lib" File°new1)°mkdir0 pop + (url URL)°new1 =url + def name (url°getPath0 "/" )°strsplit =name + (name (name°alen 1 -))°aget =name + def newfile (("lib/" name)°strconcat File°new1) =newfile + "\n> Downloading " puts + name puts + "..." puts + newfile°exists0 if { + "\n: Skipped. (Force by deleting lib/" puts name puts ")" puts + name + 2 stop + } + def ms getms =ms + def inp + "Java" try { + url°openStream0 =inp + } { + pop pop pop printStackTrace0 + "\n: Download failed." puts + name + 2 stop + } + def file ("lib/" name)°strconcat STREAM.create.file.out stream =file + while { inp°read0 dup -1 eq not } { + file STREAM.write stream + } + pop + file STREAM.close stream + "\n: Took " puts + ((getms ms -) (1000 _long) / dup =ms) ltos puts + "s (" puts + ((newfile°length0 ms /) (1000 _long) /) ltos puts + "Kbps)" puts + name +} + +func build { + def script "build.sh" STREAM.create.file.out stream =script + "\n> Generating javac command..." puts + "rm build.sh\n" script stream.write + "mkdir build > /dev/null 2>&1\n" script stream.write + "mkdir src > /dev/null 2>&1\n" script stream.write + "mkdir -p res/META-INF > /dev/null 2>&1\n" script stream.write + "mkdir lib > /dev/null 2>&1\n" script stream.write + "cd src ; find . | grep '\\.java$' | sed 's/^\\.\\/\\(.*\\)$/\\1/g' > ../build/buildfiles.txt\n" script stream.write + "javac -d ../build " script stream.write + deps°alen if { + "-cp " script stream.write + { + with dep ; + "'../lib/" script stream.write + dep script stream.write + "':" script stream.write + } deps foreach + } + " @../build/buildfiles.txt\n" script stream.write + "E=$?\n" script stream.write + "cd .. ; rm build/buildfiles.txt\n" script stream.write + "exit $E\n" script stream.write + script STREAM.close stream + "\n> Running javac...\n" puts + ([ "bash" "build.sh" ] ProcessBuilder°new1)°inheritIO0°start0°waitFor0 + 0 eq not if { + ": javac failed!" puts + } +} + +func javadoc { + def script "javadoc.sh" STREAM.create.file.out stream =script + "\n> Generating javadoc command..." puts + "rm javadoc.sh\n" script stream.write + "mkdir javadoc > /dev/null 2>&1\n" script stream.write + "mkdir src > /dev/null 2>&1\n" script stream.write + "cd src ; find . | grep '\\.java$' | sed 's/^\\.\\/\\(.*\\)$/\\1/g' > ../javadoc/files.txt\n" script stream.write + "javadoc -d ../javadoc " script stream.write + deps°alen if { + "-cp " script stream.write + { + with dep ; + "'../lib/" script stream.write + dep script stream.write + "':" script stream.write + } deps foreach + } + " @../javadoc/files.txt\n" script stream.write + "E=$?\n" script stream.write + "cd ../javadoc\n" script stream.write + "rm files.txt\n" script stream.write + "rm ../'" script stream.write + name script stream.write + "'-javadoc.zip\n" script stream.write + "zip -r ../'" script stream.write + name script stream.write + "'-javadoc.zip *\n" script stream.write + "exit $E\n" script stream.write + script STREAM.close stream + "\n> Running javadoc...\n" puts + ([ "bash" "javadoc.sh" ] ProcessBuilder°new1)°inheritIO0°start0°waitFor0 + 0 eq not if { + ": javadoc failed!" puts + } +} + +func run { + def script "run.sh" STREAM.create.file.out stream =script + "\n> Generating run command..." puts + "java -cp res:build:" script stream.write + { + with dep ; + "'lib/" script stream.write + dep script stream.write + "':" script stream.write + } deps foreach + " " script stream.write + mainClass script stream.write + " " script stream.write + "ARGS" System°getenv1 dup if { dup script stream.write } pop + "\n" script stream.write + "exit $?\n" script stream.write + script STREAM.close stream + "\n> Running\n" puts + ([ "bash" "run.sh" ] ProcessBuilder°new1)°inheritIO0°start0°waitFor0 + 0 eq not if { + ": Run failed!\n" puts + 1 exit + } +} + +func jar { + def script "jar.sh" STREAM.create.file.out stream =script + "\n> Generating jar builder..." puts + "rm jar.sh\n" script stream.write + "mkdir jar > /dev/null 2>&1\n" script stream.write + { + with dep ; + "cp 'lib/" script stream.write + dep script stream.write + "' jar\n" script stream.write + "cd jar ; unzip -o '" script stream.write + dep script stream.write + "' ; rm '" script stream.write + dep script stream.write + "' ; cd ..\n" script stream.write + } deps foreach + "cp -r build/* jar\n" script stream.write + "cp -r res/* jar\n" script stream.write + "rm '" script stream.write + name script stream.write + ".jar'\n" script stream.write + "cd jar\n" script stream.write + "zip -r ../'" script stream.write + name script stream.write + ".jar' *\n" script stream.write + "cd .. ; rm -rf jar\n" script stream.write + script STREAM.close stream + "\n> Building jarfile...\n" puts + ([ "bash" "jar.sh" ] ProcessBuilder°new1)°inheritIO0°start0°waitFor0 pop +} + +func makeManifest { + def file "res/META-INF/MANIFEST.MF" STREAM.create.file.out stream =file + "\n> Generating manifest..." puts + "Manifest-Version: 1.0\n" file stream.write + "Main-Class: " file stream.write + mainClass file stream.write + "\n" file stream.write + file STREAM.close stream +} + +def extraToClean 0 anew =extraToClean + +func toClean { [ + "build" + "lib" + name ".jar" strconcat + "run.sh" + "javadoc" + name "-javadoc.zip" strconcat +] extraToClean aadd } + +func clean { + def script "clean.sh" STREAM.create.file.out stream =script + "\n> Cleaning..." puts + "rm clean.sh\n" script stream.write + { + with file ; + "rm -rf '" script stream.write + file script stream.write + "'\n" script stream.write + } toClean foreach + script STREAM.close stream + ([ "bash" "clean.sh" ] ProcessBuilder°new1)°inheritIO0°start0°waitFor0 pop +} + +def tasks [ "javadoc" "clean" "build" "makeManifest" "run" "jar" ] =tasks + +func task { + [ swap ] tasks aadd =tasks +} + +func isATask { + task +} + +func isToClean { + [ swap ] extraToClean aadd =extraToClean +} + +"Placeholders begin" # +def mainClass "Main" =mainClass +def name "placeholder" =name +func dependencies { } +"Placeholders end" # + +func main { + with args ; + [ dependencies ] =deps + { + with arg ; + { + with task ; + arg task eq if { + ensureDepsExist + task 0 _layer_call + } + } tasks foreach + } args foreach + "\n" puts + 0 +} diff --git a/res/META-INF/MANIFEST.MF b/res/META-INF/MANIFEST.MF new file mode 100644 index 0000000..4225b09 --- /dev/null +++ b/res/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Main-Class: de.tudbut.tryumph.Entry diff --git a/res/config.try b/res/config.try new file mode 100644 index 0000000..e52b065 --- /dev/null +++ b/res/config.try @@ -0,0 +1,7 @@ + +example { + main class: de.tudbut.tryumph.example.Main + defaults { + port: 8080 + } +} diff --git a/src/de/tudbut/tryumph/Launch.java b/src/de/tudbut/tryumph/Launch.java new file mode 100644 index 0000000..3a211cb --- /dev/null +++ b/src/de/tudbut/tryumph/Launch.java @@ -0,0 +1,22 @@ +package de.tudbut.tryumph; + +import java.util.Arrays; + +import de.tudbut.tryumph.config.TryConfig; +import de.tudbut.tryumph.err.ProjectException; + +public class Launch { + + public static void main(String[] args) throws ProjectException, InterruptedException { + try { + TryConfig config = new TryConfig(args, Launch.class.getClassLoader().getResourceAsStream("config.try")); + config.getCatchers().then(resp -> { + System.out.println(Arrays.toString(resp)); + }).ok(); + } catch(Exception e) { + throw new ProjectException("Error loading project", e); + } + Thread.sleep(1000); + System.exit(0); + } +} diff --git a/src/de/tudbut/tryumph/config/RequestCatcherConfig.java b/src/de/tudbut/tryumph/config/RequestCatcherConfig.java new file mode 100644 index 0000000..af5daed --- /dev/null +++ b/src/de/tudbut/tryumph/config/RequestCatcherConfig.java @@ -0,0 +1,52 @@ +package de.tudbut.tryumph.config; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; + +import tudbut.parsing.TCN; +import tudbut.parsing.JSON; +import de.tudbut.async.*; +import static de.tudbut.async.Async.*; + +import de.tudbut.tryumph.util.Compose; + +public class RequestCatcherConfig { + + private TCN configHolder; + private String name; + + private RequestCatcherConfig() {} + + public static Task make(String name, TCN parentConfig) { + return Async.t((res, rej) -> { + res.call(parentConfig); + }) + .compose(Compose.tcnGetNonNull(name)) + .compose((resp, res, rej) -> { + RequestCatcherConfig r = new RequestCatcherConfig(); + r.name = name; + r.configHolder = resp; + r.build().err(rej).ok().await(); + res.call(r); + }); + } + + private Task build() { + return t((res, rej) -> { + res.call(null); + }); + } + + public Task getName() { + return t((res, rej) -> { + if(name == null) + rej.call(new IllegalStateException("RequestCatcherConfig is not initialized but was used")); + res.call(name); + }); + } + + public String toString() { + return "RequestCatcherConfig{name=" + name + ",configHolder=" + JSON.write(configHolder) + "}"; + } +} diff --git a/src/de/tudbut/tryumph/config/TryConfig.java b/src/de/tudbut/tryumph/config/TryConfig.java new file mode 100644 index 0000000..028961e --- /dev/null +++ b/src/de/tudbut/tryumph/config/TryConfig.java @@ -0,0 +1,49 @@ +package de.tudbut.tryumph.config; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; + +import tudbut.parsing.TCN; +import de.tudbut.async.*; +import static de.tudbut.async.Async.*; + +import de.tudbut.tryumph.err.ProjectException; + +public class TryConfig { + + private TCN configHolder; + private String[] arguments; + + public TryConfig(String[] appArguments, InputStream config) throws IOException, ProjectException { + String file = ""; + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(config)); + String line; + while((line = reader.readLine()) != null) { + file += line + "\n"; + } + } catch(Exception e) { + throw new IOException("Error reading config", e); + } + try { + configHolder = TCN.read(file); + } catch(Exception e) { + throw new ProjectException("Error reading config: Config formatting is invalid", e); + } + arguments = appArguments; + } + + public Task getCatchers() { + return t((res, rej) -> { + String[] catcherNames = configHolder.map.keys().toArray(new String[0]); + RequestCatcherConfig[] catchers = new RequestCatcherConfig[catcherNames.length]; + for(int i = 0; i < catcherNames.length; i++) { + catchers[i] = RequestCatcherConfig.make(catcherNames[i], configHolder).err(rej).ok().await(); + unblockQueue(); + } + res.call(catchers); + }); + } +} diff --git a/src/de/tudbut/tryumph/err/ProjectException.java b/src/de/tudbut/tryumph/err/ProjectException.java new file mode 100644 index 0000000..a2acb1c --- /dev/null +++ b/src/de/tudbut/tryumph/err/ProjectException.java @@ -0,0 +1,8 @@ +package de.tudbut.tryumph.err; + +public class ProjectException extends Exception { + + public ProjectException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/de/tudbut/tryumph/util/Compose.java b/src/de/tudbut/tryumph/util/Compose.java new file mode 100644 index 0000000..ca62e72 --- /dev/null +++ b/src/de/tudbut/tryumph/util/Compose.java @@ -0,0 +1,49 @@ +package de.tudbut.tryumph.util; + +import de.tudbut.async.ComposeCallback; +import tudbut.parsing.TCN; +import tudbut.parsing.TCNArray; + +import java.lang.reflect.Array; + +public class Compose { + + public static ComposeCallback tcnArrayToArray(Class clazz) { + return (resp, res, rej) -> { + T[] array = (T[]) Array.newInstance(clazz, resp.size()); + for (int i = 0 ; i < resp.size() ; i++) { + try { + array[i] = (T) resp.get(i); + } catch (ClassCastException e) { + rej.call(new IllegalArgumentException("Element " + i + " of input TCNArray is not of type " + clazz.getName() + " but of type " + resp.get(i).getClass().getName(), e)); + } + } + res.call(array); + }; + } + + public static ComposeCallback tcnGet(String name) { + return (resp, res, rej) -> { + Object o = resp.get(name); + try { + res.call((T) o); + } catch (ClassCastException e) { + rej.call(new IllegalArgumentException(name + " is not of type T but of type " + o.getClass().getName(), e)); + } + }; + } + public static ComposeCallback tcnGetNonNull(String name) { + return (resp, res, rej) -> { + Object o = resp.get(name); + if(o == null) { + rej.call(new NullPointerException(name + " is null but was passed to tcnGetNonNull")); + } + try { + res.call((T) o); + } catch (ClassCastException e) { + rej.call(new IllegalArgumentException(name + " is not of type T but of type " + o.getClass().getName(), e)); + } + }; + } +} +