diff --git a/pkgs/by-name/an/anyk/package.nix b/pkgs/by-name/an/anyk/package.nix new file mode 100644 index 000000000000..dfd97fd62273 --- /dev/null +++ b/pkgs/by-name/an/anyk/package.nix @@ -0,0 +1,145 @@ +{ stdenv +, lib +, fetchurl +, fetchzip +, openjdk +, writeScript +, runCommandLocal +, bash +, unzip +, makeWrapper +, libredirect +, xsettingsd +, makeDesktopItem +, copyDesktopItems +, python3 +}: +let + # Downloads can be found here: https://nav.gov.hu/nyomtatvanyok/letoltesek/nyomtatvanykitolto_programok/nyomtatvany_apeh/keretprogramok/AbevJava + # There are no versioned download URLs but archive.org can be used to preserve them. + # The original download URL is: https://nav.gov.hu/pfile/programFile?path=/nyomtatvanyok/letoltesek/nyomtatvanykitolto_programok/nyomtatvany_apeh/keretprogramok/AbevJava + # You can put the URL here to create a fresh archive URL: https://web.archive.org/save + abevjavaSrc = fetchzip { + url = "https://web.archive.org/web/20231106112510if_/https://nav.gov.hu/pfile/programFile?path=/nyomtatvanyok/letoltesek/nyomtatvanykitolto_programok/nyomtatvany_apeh/keretprogramok/AbevJava"; + sha256 = "sha256-qt0mHv3HI6C8OltFjSR47+RLSnmB2Si5U8rXEvdN4/c="; + extension = "zip"; + stripRoot = false; + }; + + # ÁNYK uses some SOAP stuff that's not shipped with OpenJDK any more. + # We don't really want to use openjdk8 because it's unusable on HiDPI + # and people are more likely to have a modern OpenJDK installed. + extraClasspath = [ + (fetchurl { + url = "mirror://maven/org/glassfish/metro/webservices-rt/2.4.10/webservices-rt-2.4.10.jar"; + sha256 = "sha256-lHclIZn3HR2B2lMttmmQGIV67qJi5KhL5jT2WNUQpPI="; + }) + + (fetchurl { + url = "mirror://maven/org/glassfish/metro/webservices-api/2.4.10/webservices-api-2.4.10.jar"; + sha256 = "sha256-1jiabjPkRnh+l/fmTt8aKE5hpeLreYOiLH9sVIcLUQE="; + }) + + (fetchurl { + url = "mirror://maven/com/sun/activation/jakarta.activation/2.0.1/jakarta.activation-2.0.1.jar"; + sha256 = "sha256-ueJLfdbgdJVWLqllMb4xMMltuk144d/Yitu96/QzKHE="; + }) + + # Patch one of the classes so it works with the packages above by removing .internal. from the package names. + (runCommandLocal "anyk-patch" {} '' + mkdir $out + cd $out + ${unzip}/bin/unzip ${abevjavaSrc}/application/abevjava.jar hu/piller/enykp/niszws/ClientStubBuilder.class + ${python3}/bin/python ${./patch_paths.py} hu/piller/enykp/niszws/ClientStubBuilder.class + '') + ]; + + # This script can be used to run template installation jars (or use the Szervíz -> Telepítés menu) + anyk-java = writeScript "anyk-java" '' + if [ -f ~/.abevjava/abevjavapath.cfg ] + then + if ABEVJAVA_PATH_CFG=$(grep abevjava.path ~/.abevjava/abevjavapath.cfg) + then + ABEVJAVA_PATH=''${ABEVJAVA_PATH_CFG#abevjava.path = } + echo "Determined abevjava path as $ABEVJAVA_PATH" + else + echo "Could not determine abevjava path from ~/.abevjava/abevjavapath.cfg" + exit 1 + fi + else + ABEVJAVA_PATH=~/abevjava + mkdir -p ~/.abevjava + echo "abevjava.path = $ABEVJAVA_PATH" > ~/.abevjava/abevjavapath.cfg + echo "Initialized abevjava path as $ABEVJAVA_PATH" + fi + + # Sync help files. + mkdir -p "$ABEVJAVA_PATH/segitseg/" + cp -sRf --no-preserve=all @out@/opt/segitseg/. "$ABEVJAVA_PATH/segitseg" + + export LD_PRELOAD=${libredirect}/lib/libredirect.so:$LD_PRELOAD + # Look for form templates in ABEVJAVA_PATH instead of the install dir. + export NIX_REDIRECTS=@out@/opt/nyomtatvanyok=$ABEVJAVA_PATH/nyomtatvanyok:@out@/opt/segitseg=$ABEVJAVA_PATH/segitseg:@out@/opt/setenv=$ABEVJAVA_PATH/setenv:/bin/bash=${bash}/bin/bash:$NIX_REDIRECTS + if WINDOW_SCALING_FACTOR=$(${xsettingsd}/bin/dump_xsettings | awk '/Gdk\/WindowScalingFactor/{print $NF}' | grep .); then + # Fix scaling on HiDPI. + SCALING_PROP="-Dsun.java2d.uiScale=''${WINDOW_SCALING_FACTOR}" + fi + # ÁNYK crashes with NullPointerException with the GTK look and feel so use the cross-platform one. + exec ${openjdk}/bin/java -Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel $SCALING_PROP "$@" + ''; +in stdenv.mkDerivation { + pname = "anyk"; + version = "3.26.0"; + + src = abevjavaSrc; + + dontConfigure = true; + dontBuild = true; + + nativeBuildInputs = [ makeWrapper copyDesktopItems ]; + + desktopItems = [ + (makeDesktopItem rec { + desktopName = "ÁNYK"; + name = "anyk"; + exec = "anyk"; + icon = "anyk"; + categories = [ "Office" ]; + }) + ]; + + installPhase = '' + mkdir $out + cp -r application $out/opt + + mkdir $out/bin + substituteAll ${anyk-java} $out/bin/anyk-java + chmod +x $out/bin/anyk-java + + # ÁNYK has some old school dependencies that are no longer bundled with Java, put them on the classpath. + makeWrapper $out/bin/anyk-java $out/bin/anyk --add-flags "-cp ${lib.concatStringsSep ":" extraClasspath}:$out/opt/abevjava.jar hu.piller.enykp.gui.framework.MainFrame" + + mkdir -p $out/share/applications $out/share/pixmaps $out/share/icons + + copyDesktopItems + + ln -s $out/opt/abevjava.png $out/share/pixmaps/anyk.png + ln -s $out/opt/abevjava.png $out/share/icons/anyk.png + ''; + + meta = with lib; { + description = "Tool for filling forms for the Hungarian government,"; + longDescription = '' + Official tool for filling Hungarian government forms. + + Use `anyk-java` to install form templates/help files like this: `anyk-java -jar NAV_IGAZOL.jar` + ''; + homepage = "https://nav.gov.hu/nyomtatvanyok/letoltesek/nyomtatvanykitolto_programok/nyomtatvany_apeh/keretprogramok/javakitolto"; + license = licenses.unfree; + maintainers = with maintainers; [ chpatrick ]; + platforms = openjdk.meta.platforms; + sourceProvenance = [ sourceTypes.binaryBytecode ]; + mainProgram = "anyk"; + }; +} + diff --git a/pkgs/by-name/an/anyk/patch_paths.py b/pkgs/by-name/an/anyk/patch_paths.py new file mode 100644 index 000000000000..5e2306bd3c9a --- /dev/null +++ b/pkgs/by-name/an/anyk/patch_paths.py @@ -0,0 +1,35 @@ +from pathlib import Path +from struct import pack +import sys + +def to_java_string(string) -> bytes: + string_bytes = string.encode("utf-8") + # Java constant pool string entries are prefixed by 0x01 and 16-bit big-endian string length. + return pack(">BH", 1, len(string_bytes)) + string_bytes + +class_file = Path(sys.argv[1]) + +clazz = class_file.read_bytes() + +# We want to fix these package names so they work with the open-source Java EE releases instead of OpenJDK 8. +patches = [ + ( "com/sun/xml/internal/ws/developer/WSBindingProvider", "com/sun/xml/ws/developer/WSBindingProvider" ), + ( "com/sun/xml/internal/ws/api/message/Header", "com/sun/xml/ws/api/message/Header" ), + ( "com.sun.xml.internal.ws.transport.http.client.streaming.chunk.size", "com.sun.xml.ws.transport.http.client.streaming.chunk.size" ), + ( "com/sun/xml/internal/ws/api/message/Headers", "com/sun/xml/ws/api/message/Headers" ), + ( "(Lorg/w3c/dom/Element;)Lcom/sun/xml/internal/ws/api/message/Header;", "(Lorg/w3c/dom/Element;)Lcom/sun/xml/ws/api/message/Header;" ), + ( "([Lcom/sun/xml/internal/ws/api/message/Header;)V", "([Lcom/sun/xml/ws/api/message/Header;)V" ), +] + +for old, new in patches: + old_java = to_java_string(old) + new_java = to_java_string(new) + assert old_java in clazz + clazz = clazz.replace(old_java, new_java) + assert old_java not in clazz + assert new_java in clazz + +assert b".internal." not in clazz + +class_file.write_bytes(clazz) +