// SPDX-FileCopyrightText: 2023 Paul Schaub // // SPDX-License-Identifier: Apache-2.0 package sop.external.operation; import sop.external.ExternalSOP; import sop.operation.Version; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Properties; /** * Implementation of the {@link Version} operation using an external SOP binary. */ public class VersionExternal implements Version { private final Runtime runtime = Runtime.getRuntime(); private final String binary; private final Properties environment; public VersionExternal(String binaryName, Properties environment) { this.binary = binaryName; this.environment = environment; } @Override public String getName() { String[] command = new String[] {binary, "version"}; String[] env = ExternalSOP.propertiesToEnv(environment).toArray(new String[0]); try { Process process = runtime.exec(command, env); BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = stdInput.readLine().trim(); ExternalSOP.finish(process); if (line.contains(" ")) { return line.substring(0, line.lastIndexOf(" ")); } return line; } catch (IOException e) { throw new RuntimeException(e); } } @Override public String getVersion() { String[] command = new String[] {binary, "version"}; String[] env = ExternalSOP.propertiesToEnv(environment).toArray(new String[0]); try { Process process = runtime.exec(command, env); BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = stdInput.readLine().trim(); ExternalSOP.finish(process); if (line.contains(" ")) { return line.substring(line.lastIndexOf(" ") + 1); } return line; } catch (IOException e) { throw new RuntimeException(e); } } @Override public String getBackendVersion() { String[] command = new String[] {binary, "version", "--backend"}; String[] env = ExternalSOP.propertiesToEnv(environment).toArray(new String[0]); try { Process process = runtime.exec(command, env); BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = stdInput.readLine()) != null) { sb.append(line).append('\n'); } ExternalSOP.finish(process); return sb.toString(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public String getExtendedVersion() { String[] command = new String[] {binary, "version", "--extended"}; String[] env = ExternalSOP.propertiesToEnv(environment).toArray(new String[0]); try { Process process = runtime.exec(command, env); BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = stdInput.readLine()) != null) { sb.append(line).append('\n'); } ExternalSOP.finish(process); return sb.toString(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public int getSopSpecRevisionNumber() { String revision = getSopSpecVersion(); String firstLine; if (revision.contains("\n")) { firstLine = revision.substring(0, revision.indexOf("\n")); } else { firstLine = revision; } if (!firstLine.contains("-")) { return -1; } return Integer.parseInt(firstLine.substring(firstLine.lastIndexOf("-") + 1)); } @Override public boolean isSopSpecImplementationIncomplete() { String revision = getSopSpecVersion(); return revision.startsWith("~"); } @Override public String getSopSpecImplementationRemarks() { String revision = getSopSpecVersion(); if (revision.contains("\n")) { String tail = revision.substring(revision.indexOf("\n") + 1).trim(); if (!tail.isEmpty()) { return tail; } } return null; } @Override public String getSopSpecVersion() { String[] command = new String[] {binary, "version", "--sop-spec"}; String[] env = ExternalSOP.propertiesToEnv(environment).toArray(new String[0]); try { Process process = runtime.exec(command, env); BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = stdInput.readLine()) != null) { sb.append(line).append('\n'); } ExternalSOP.finish(process); return sb.toString(); } catch (IOException e) { throw new RuntimeException(e); } } }